ChatGPT Recorder & printer(Raspberry Pi Pico & WizFi360)
Print all the conversation process with ChatGPT and store it in the SD card
SSD1306 - 1.3' 12864 OLED
x 1
I want to store ChatGPT conversations to SD card and Print it out.
ChatGPT, as the earliest OPEN AI program open to ordinary users, has been warmly welcomed by everyone since its launch, and currently has more than 100 million users.
At present, ChatGPT also launched an API for users to use, and the information URL is as follows:
I use wizfi360 as http client to send ChatGPT API request and get ChatGPT Answer. WizFi360 is a WiFi module, which can connect to WiFi through commands and perform TCP or TCP (SSL) connections. I have used it many times and it is very convenient.
RP2040 acts as an MCU, after get ChatGPT info from wizfi360, it performs data processing and print it out.
Hardware
I used two PCBs to make 6 surface structures of this shell.
The pcb on the right can be used as a back board, and the middle part can be cut off to be used as a front board.
Soldering the pads of the PCB connection part can connect adjacent PCBs to form a closed shell.
This is what it looks like from the outside.
After the installation is complete, there is a WS2812 RGB lighting effect on the front, and a 12864 OLED to display status and information.
This project is divided into five steps:
Step 1: Create New Account on the ChatGPT website and get API TOKEN;
Step2: Install library files and board support in the Arduino IDE;
Step 3: Submit questions via the built-in web page;
Step 4: Get answersfrom ChatGPT API through WizFi360 and and store in SD;
Step 5: Print the ChatGPT question and answer out;
The following are step by step instructions.
Step 1: Create New Account on the ChatGPT website and get API TOKEN;
After creat account in this website, you can see your API TOKEN on the "My accounts" page. Please record it, because this TOKEN will be required for future page visits.
our API token provides full access to view and modify your account. Please treat this like a password and take care when sharing it.
Step2: Install library files and board support in the Arduino IDE;
Add "WIZnet WizFi360-EVB-PICO" support to Arduino IDE
Open up the Arduino IDE and go to File->Preferences.
In the dialog that pops up, enter the following URL in the "Additional Boards Manager URLs" field:
https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json
Search "WizFi360" and Install Board support by "Board Manager"
"Tools->Board:"***"-> Raspberry Pi RP2040 Boards(2.6.1) " Select “WIZnet WizFi360-EVB-PICO”.
Add “LittleFS” and “SD”, these library support read and write file to the SD card;
Add “WS2812FX” in order to support WS2812;
Add “SoftwareSerial” in order to support thermal printer module;
After initialization, the OLED displays the following:
Step 3: Submit questions via the built-in web page;
Initialize serial port for WizFi360 module and change the baudrate to 2000000bps(MAX baudrate for wizfi360).
The first initialization is 115200, and then setting the baud rate (2000000) is added to the initialization part of the WiZfi360 library, and the second time is changed to 2000000bps.
// initialize serial for WizFi360 module
Serial2.setFIFOSize(4096);
Serial2.begin(2000000);
WiFi.init(&Serial2);
Check the wizfi360 Link status of wifi in the “void setup()”
// check for the presence of the shield
if (WiFi.status() == WL_NO_SHIELD) {
while (true);// don't continue
}
// attempt to connect to WiFi network
while ( status != WL_CONNECTED) {
status = WiFi.begin(ssid, pass);// Connect to WPA/WPA2 network
}
After connecting to the WiFi network, the OLED displays the IP address:
And the printer will also print out a QR code, which can quickly open the WEB connection of the printer by scanning it with the mobile phone.
Because my device doesn't have an input interface, we made an embedded page to input ChatGPT questions that need to be displayed and stored.This process is very simple to use wizfi360.
“void loop()” There are 5 cases in The switch statement.
typedef enum
{
do_webserver_index = 0,
do_webserver_js,
send_chatgpt_request,
get_chatgpt_answer,
do_print_work,
}STATE_;
STATE_ currentState;
We use two Sockets. Among them, Client1 refers to the Socket client after the web server is established, and Client2 refers to the Socket Client that sends data to ChatGPT.
#include "WizFi360.h"
// Wi-Fi info //
char ssid[] = "WIZNET_test"; // your network SSID (name)//
char pass[] = "********"; // your network password//
int status = WL_IDLE_STATUS; // the Wifi radio's status//
// Initialize the Ethernet client object
WiFiClient client1;
WiFiClient client2;
WiFiServer server(80);
The following code is the flow of web server processing:
case do_webserver_index:
{
client1 = server.available();
if (client1)
{
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client1.connected())
{
if (client1.available()) {
char c = client1.read();
json_String += c;
if (c == '\n' && currentLineIsBlank) {
dataStr = json_String.substring(0, 4);
Serial.println(dataStr);
if(dataStr == "GET ")
{
client1.print(html_page);
}
else if(dataStr == "POST")
{
json_String = "";
while(client1.available())
{
json_String += (char)client1.read();
}
Serial.println(json_String);
dataStart = json_String.indexOf("chatgpttext=") + strlen("chatgpttext=");
chatgpt_Q = json_String.substring(dataStart, json_String.length());
client1.print(html_page);
// close the connection:
delay(10);
client1.stop();
currentState = send_chatgpt_request;
}
json_String = "";
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
}
}
break;
After the web server is ready, the RGB of WS2812 lights up, and the OLED displays the following content,The three main icons represent the current processing steps. If the web server is in the process of processing, there will be a white frame around the leftmost icon, indicating that it is in this step.
You could enter the IP address of the WiFi module on the browser to access the embedded WEB page too.
The HTML code of the embedded WEB is as follows:
const char html_page[] PROGMEM = {
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n" // the connection will be closed after completion of the response
//"Refresh: 1\r\n" // refresh the page automatically every n sec
"\r\n"
"<!DOCTYPE HTML>\r\n"
"<html>\r\n"
"<head>\r\n"
"<meta charset=\"UTF-8\">\r\n"
"<title>Cloud Printer: ChatGPT</title>\r\n"
"<link rel=\"icon\" href=\"https://seeklogo.com/images/C/chatgpt-logo-02AFA704B5-seeklogo.com.png\" type=\"image/x-icon\">\r\n"
"</head>\r\n"
"<body>\r\n"
"<p style=\"text-align:center;\">\r\n"
"<img alt=\"ChatGPT\" src=\"https://seeklogo.com/images/C/chatgpt-logo-02AFA704B5-seeklogo.com.png\" height=\"200\" width=\"200\">\r\n"
"<h1 align=\"center\">Cloud Printer</h1>\r\n"
"<h1 align=\"center\">ChatGPT</h1>\r\n"
"<div style=\"text-align:center;vertical-align:middle;\">"
"<form action=\"/\" method=\"post\">"
"<input type=\"text\" placeholder=\"Please enter your question\" size=\"35\" name=\"chatgpttext\" required=\"required\"/><br><br>\r\n"
"<input type=\"submit\" value=\"Submit\" style=\"height:30px; width:80px;\"/>"
"</form>"
"</div>"
"</p>\r\n"
"</body>\r\n"
"<html>\r\n"
};
After entering the question in the text box, click the “Submit” button. Our program gets the question it needs to query.
For example: “Explain in the simplest language how humans find aliens”
According to the documentation of ChatGPT, the format we need to send the request is as follows:
curl https://api.openai.com/v1/completions \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-d '{
"model": "text-davinci-003",
"prompt": "Say this is a test",
"max_tokens": 7,
"temperature": 0
}'
Our code to send this ChatGPT request is as follows:
case send_chatgpt_request:
{
// if you get a connection, report back via serial
if (client2.connectSSL(chatgpt_server,443)){
delay(3000);
// Make a HTTP request
client2.println(String("POST /v1/completions HTTP/1.1"));
client2.println(String("Host: ")+ chatgpt_server);
client2.println(String("Content-Type: application/json"));
client2.println(String("Content-Length: ")+(73+chatgpt_Q.length()));
client2.println(String("Authorization: Bearer ")+ chatgpt_token);
client2.println("Connection: close");
client2.println();
client2.println(String("{\"model\":\"text-davinci-003\",\"prompt\":\"")+ chatgpt_Q + String("\",\"temperature\":0,\"max_tokens\":100}"));
json_String= "";
currentState = get_chatgpt_list;
}
else
{
client2.stop();
delay(1000);
}
}
break;
After a short wait, we will get the answer to the question from Chart GPT's server.
The following is the code that handles the response part of ChatGPT and the storage part.
case get_chatgpt_list:
{
while (client2.available()) {
json_String += (char)client2.read();
data_now =1;
}
if(data_now)
{
//Serial.println(json_String);
dataStart = json_String.indexOf("\"text\":\"") + strlen("\"text\":\"");
dataEnd = json_String.indexOf("\",\"", dataStart);
chatgpt_A = json_String.substring(dataStart+4, dataEnd);
Serial.println(chatgpt_A);
chatgpt_Q.replace("+", " ");
Serial.println(chatgpt_Q);
myFile = SD.open("chatgpt_record.txt", FILE_WRITE);
if (myFile) {
myFile.print("[N]{");
myFile.print(chatgpt_num);
myFile.print("}\r\n[Q]{");
myFile.print(chatgpt_Q);
myFile.print("}\r\n[A]{");
myFile.print(chatgpt_A);
myFile.print("}\r\n");
myFile.close();
}
chatgpt_num++;
SD_str = read_from_sd("chatgpt_record.txt");
json_String = "";
data_now =0;
client2.stop();
delay(1000);
currentState = do_chatgpt_display;
}
}
break;
When in this process, the OLED displays as follows, and the RGB becomes this color:
The files stored in SD are as follows:
We have obtained the content of the ChatGPT conversation before, and put them in the strings chatgpt_Q and chatgpt_A respectively. We need to print them out according to the following format, and then we can print out the conversation between us and ChatGPT.
case do_print_work:
{
display.drawRect(94, 20, 28, 28, SH110X_WHITE);
display.display();
ws2812fx.setColor(ORANGE);
InitializePrint();
Set_Align((byte)0x00);
Set_Bold(0x01);
mySerial.print("[Q]\r\n");
mySerial.print(chatgpt_Q);
mySerial.print("\r\n[A]\r\n");
mySerial.print(chatgpt_A);
select_lines(2);
display.drawRect(94, 20, 28, 28, SH110X_BLACK);
currentState = do_webserver_index;
}
break;
The following is an example of printing out a dialog.
Done!