Skip to content

Commit

Permalink
Main loop functionality with shake trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramenisneat committed Jul 13, 2023
1 parent 0206f9f commit 2f2787c
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 28 deletions.
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,20 @@ Using an Internet connected ESP-32 and some other electronics, we can record a v
- [X] Able to record audio
- [X] Connect to the Internet and send HTTP requests
- [X] Make requests with OpenAI's API
- [ ] Use a shake sensor to trigger audio recording.
- [X] Use a shake sensor to trigger audio recording.
- [ ] Display info onto a screen.
- [ ] Able to customize the configuration of the environmental variables using WAP portal. (WiFi SSID, API keys)
- [ ] Add haptics.
- [ ] Make 8-ball enclosure.
- [X] Make 8-ball enclosure.
- [ ] Make all necessary attributions.
- [ ] Make a step by step guide with all parts.

### **Team**
- **Rahul Myana** : [Github](https://github.com/Ramenisneat) - [rahulmyana42@gmail.com](mailto:rahulmyana42@gmail.com)

### Logs
### **Parts list**
TODO

### **Logs**

I will update on my progress and working on this [logs](https://makerspace-fri-utaustin.github.io/GPT-8ball/docs/logs.html) site.
10 changes: 9 additions & 1 deletion docs/logs.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,12 @@
- ChatGPT is successfully answering the prompt.
- There were problems with memory because Arduino `String` were being used.
- After switching to C based strings,Iencountered Stack and buffer based overflows.
- Switching all C string functions such as `strcpy` to their counterpart `strncpy` fixed the errors.
- Switching all C string functions such as `strcpy` to their counterpart `strncpy` fixed the errors.

### Thursday - 07/13/23
- Ordered a Shake Sensor.
- Using an interrupt handler the sensor is able to switch on the procedure.
- Moved the main code to loop() so it can be continously ran.
- The main functionality of the code is functioning properly and stress testing reveals no discernable major errors.
- I find that the mic is not as reliable as I like it to be. To be clear, it is recording poorer quality, sped up audio, but to overcome that you would need to speak pretty loud but not too close to the mic. The best fix (and frankly what should be done) is adding an SD card for the audio to be saved on but I don't want to add more chaos to the less number of headers the ESP-32 has.
- After many failed 3D prints, the 8ball enclosure is now complete. It is a modified version of open8ball.com's Arduino Uno version. I will attribute them later in the repo docs soon.
89 changes: 65 additions & 24 deletions src/testing/testing.ino
Original file line number Diff line number Diff line change
Expand Up @@ -50,41 +50,53 @@ char* cert =
"R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp\n"
"-----END CERTIFICATE-----\n";

unsigned char shakenFlag = 0;
unsigned long timepoint = 0;

//Callback for Gravity: Shake Sensor
void IRAM_ATTR isr(){
if (millis() - timepoint > 50U && shakenFlag == 0){
shakenFlag = 1;

}
}

void setup(void) {
Serial.begin(115200);

//Mic setup
auto cfg = adc.defaultConfig(RX_MODE);
cfg.copyFrom(info);
adc.begin(cfg);

//FS setup; Can be substituted for SD card if needed
if (!LittleFS.begin(true)) {
Serial.println("LittleFS Mount Failed");
return;
}

recordClip();
wifiSetup();
//Interrupt handling for the shake sensor
pinMode(4, INPUT_PULLUP);
attachInterrupt(4, isr, FALLING);
timepoint = millis();

char prompt[200];
char answer[500];
wifiSetup();

int start = millis();
sendAudio(prompt);
Serial.println(prompt);
if (strcmp(prompt, "InvalidInput") == 0) {
Serial.println("Couldn't transcribe audio");
stop();
}
Serial.printf("Time taken for audio %d s \n", (millis() - start) / 1000);

start = millis();
sendPrompt(prompt, answer);
Serial.println(answer);
Serial.printf("Time taken for response %d s \n", (millis() - start) / 1000);

}

//Sanity check for API responses
bool checkChars(char* str){
for (int i = 0; i < strlen(str); i++){
if (!isAscii(str[i])){
return false;
}
}
return true;
}

//Setup file and encoder
void recordSetup() {
//Initialize the file
LittleFS.remove(filename);
Expand All @@ -111,14 +123,14 @@ void recordClip() {
copier.copy(scaler);
}

Serial.print("time taken: ");
Serial.print((millis() - start) / 1000);
Serial.println("s");
Serial.printf("time taken: %d seconds\n", (millis() - start) / 1000);

audioFile.close();
}


//Audio file -> text transcribtion
// Sadly manually printing the raw HTTP request to server
void sendAudio(char* prompt) {
Serial.println("Sending audio");
audioFile = LittleFS.open(filename, FILE_READ);
Expand Down Expand Up @@ -152,7 +164,6 @@ void sendAudio(char* prompt) {
int contentLength = boundaryLength + strlen(fileDisposition) + newlineLength + strlen(fileType) + newlineLength + newlineLength + audioFile.size() + newlineLength
+ boundaryLength + strlen(modelDisposition) + newlineLength + newlineLength + strlen(model) + boundaryLength + strlen(twohyphens) + newlineLength;


client.print("POST ");
client.print(endpoint);
client.println(" HTTP/1.1");
Expand All @@ -174,13 +185,19 @@ void sendAudio(char* prompt) {
client.println(fileDisposition);
client.println(fileType);
client.println();

int start = millis();

uint8_t buffer[1600];
while (audioFile.available()) {
size_t readBytes = audioFile.readBytes((char*)buffer, 1600);
client.write(buffer, readBytes);
}
client.flush();
audioFile.close();
Serial.printf("raw sending audio bytes: %d s \n", (millis() - start)/1000);


client.println();
client.print(twohyphens);
client.println(boundary);
Expand Down Expand Up @@ -211,7 +228,7 @@ void sendAudio(char* prompt) {
DeserializationError error = deserializeJson(doc, response, 100);

if (error) {
Serial.print("deserialize error");
Serial.println("deserialize error");
strncpy(prompt, error.c_str(), strlen(error.c_str()) + 1);
return;
}
Expand All @@ -222,6 +239,7 @@ void sendAudio(char* prompt) {

void sendPrompt(char* prompt, char* answer) {
Serial.println("Sending prompt");

//information of the API to connect to
int port = 443;
char* host = "api.openai.com";
Expand All @@ -232,7 +250,7 @@ void sendPrompt(char* prompt, char* answer) {
client.setCACert(cert);
client.connect(host, port);

char* payload1 = "{\"model\": \"gpt-3.5-turbo\", \"messages\": [{\"role\": \"system\", \"content\": \"You are an AI powered Magic 8 Ball, your answers should resemble a typical 8 Ball's response but can be adapted to fit the needs of the prompt.\"}, {\"role\": \"user\", \"content\": \"";
char* payload1 = "{\"model\": \"gpt-3.5-turbo\", \"max_tokens\": 45, \"messages\": [{\"role\": \"system\", \"content\": \"You are an AI powered Magic 8 Ball, your answers should resemble a typical 8 Ball's response but can be adapted to fit the needs of the prompt.\"}, {\"role\": \"user\", \"content\": \"";
char* payload2 = "\"}]}";
int payloadLength = strlen(payload1) + strlen(payload2) + strlen(prompt);

Expand Down Expand Up @@ -262,7 +280,7 @@ void sendPrompt(char* prompt, char* answer) {
break;
}
}
char response[1000];
char response[800];
response[0] = '\0';
while (client.available()) {
char c = (char)client.read();
Expand All @@ -273,7 +291,7 @@ void sendPrompt(char* prompt, char* answer) {
StaticJsonDocument<512> doc;
DeserializationError error = deserializeJson(doc, response);
if (error) {
Serial.print("deserialize error");
Serial.println("deserialize error");
strncpy(answer, error.c_str(), strlen(error.c_str()) + 1);
}

Expand All @@ -294,4 +312,27 @@ void wifiSetup() {
}

void loop() {
if (shakenFlag){
recordClip();

char prompt[200];
char answer[300];

int start = millis();
sendAudio(prompt);
Serial.println(prompt);
if (strcmp(prompt, "InvalidInput") == 0 || strlen(prompt) == 0 || !checkChars(prompt)) {
Serial.println("Couldn't transcribe audio");
stop();
}
Serial.printf("Time taken for audio %d s \n", (millis() - start) / 1000);

start = millis();
sendPrompt(prompt, answer);
Serial.println(answer);
Serial.printf("Time taken for response %d s \n", (millis() - start) / 1000);

shakenFlag = 0;

}
}

0 comments on commit 2f2787c

Please sign in to comment.