Project 12: Networking and Communications

This week was all about networking and communications. I used Xiao ESP 32c3 wifi functionality. My goal was to be able to make my ADXL343 sensing module wireless with wifi and battery power.

...

My Project

I started by studying Xiao ESP 32c3 wifi funtcionality at https://wiki.seeedstudio.com/XIAO_ESP32C3_WiFi_Usage/. I connected the wifi antenna to the Xiao.

I then used the wifi scanning code to identify available networks.


                                
                                        #include "WiFi.h"

                                        void setup() {
                                          Serial.begin(115200);
                                        
                                          // Set WiFi to station mode and disconnect from an AP if it was previously connected
                                          WiFi.mode(WIFI_STA);
                                          WiFi.disconnect();
                                          delay(100);
                                        
                                          Serial.println("Setup done");
                                        }
                                        
                                        void loop() {
                                          Serial.println("scan start");
                                        
                                          // WiFi.scanNetworks will return the number of networks found
                                          int n = WiFi.scanNetworks();
                                          Serial.println("scan done");
                                          if (n == 0) {
                                            Serial.println("no networks found");
                                          } else {
                                            Serial.print(n);
                                            Serial.println(" networks found");
                                            for (int i = 0; i < n; ++i) {
                                              // Print SSID and RSSI for each network found
                                              Serial.print(i + 1);
                                              Serial.print(": ");
                                              Serial.print(WiFi.SSID(i));
                                              Serial.print(" (");
                                              Serial.print(WiFi.RSSI(i));
                                              Serial.print(")");
                                              Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? " " : "*");
                                              delay(10);
                                            }
                                          }
                                          Serial.println("");
                                        
                                          // Wait a bit before scanning again
                                          delay(5000);
                                        }
                                        
                                        
                                        
                        


This revealed a long list of available networks.
...


Next, I tried connecting to the wifi with the following code


                                   
                                            #include 

                                                const char* ssid = "your-ssid";
                                                const char* password = "your-password";
                                                
                                                void setup() {
                                                  Serial.begin(115200);
                                                  delay(10);
                                                
                                                  // We start by connecting to a WiFi network
                                                  Serial.println();
                                                  Serial.println();
                                                  Serial.print("Connecting to ");
                                                  Serial.println(ssid);
                                                
                                                  WiFi.begin(ssid, password);
                                                
                                                  while (WiFi.status() != WL_CONNECTED) {
                                                    delay(500);
                                                    Serial.print(".");
                                                  }
                                                
                                                  Serial.println("");
                                                  Serial.println("WiFi connected");
                                                  Serial.println("IP address: ");
                                                  Serial.println(WiFi.localIP());
                                                }
                                                void loop() {}
                                        
                                        
                        
However, the dual authentification wifi provided by Harvard "Harvard Secure" isn't really compatible, at least for the simplest case.

Instead, I tried to connect to my hotspot, "David's Brick"

For some reason, this didn't work. I asked Leo, and he suggested removing any special chacaters, like the apostropge and space. I renamed my hotspot "DavidPhone" and retried. This worked.
...
I then wrote a script to connect the ESP32C3 to my ADXL343 accelerometer and save the data as a CSV file. In the csv file, the first column is a time stamp, and the next three columns are x, y, and z acceleration.

Programming was pretty challenging to figure out initially, but essentially, I connect to the Xiao as usual with my usb-c cable. I then program the microcontroller with the following script.

                            #include 

                                const char* ssid = "DavidPhone"; // Replace with your Wi-Fi SSID
                                const char* password = "dpchotspot"; // Replace with your Wi-Fi password
                                
                                WiFiServer server(80); // Wi-Fi server on port 80
                                
                                unsigned long startMillis = 0;
                                unsigned long recordingDuration = 0;
                                
                                void setup() {
                                  Serial.begin(115200); // High baud rate for serial monitor
                                  analogReadResolution(12); // Set ADC resolution to 12 bits
                                
                                  Serial.println("Connecting to Wi-Fi...");
                                  WiFi.begin(ssid, password);
                                
                                  while (WiFi.status() != WL_CONNECTED) {
                                    delay(500);
                                    Serial.print(".");
                                  }
                                
                                  Serial.println("\nWi-Fi connected!");
                                  Serial.print("IP Address: ");
                                  Serial.println(WiFi.localIP());
                                
                                  server.begin(); // Start the server
                                }
                                
                                void loop() {
                                  WiFiClient client = server.available(); // Check for a new client
                                
                                  if (client) {
                                    Serial.println("Client connected!");
                                    client.println("Enter duration in seconds to start recording:");
                                
                                    while (client.connected()) {
                                      if (client.available() > 0) {
                                        String input = client.readStringUntil('\n');
                                        input.trim();
                                
                                        if (input.toInt() > 0) {
                                          recordingDuration = input.toInt() * 1000; // Convert seconds to milliseconds
                                          startMillis = millis();
                                          client.println("Starting data recording...");
                                          Serial.println("Recording started for " + String(recordingDuration / 1000) + " seconds.");
                                
                                          // Prepare buffer for batch data transmission
                                          const int bufferSize = 512; // Define buffer size
                                          char buffer[bufferSize];
                                          int bufferIndex = 0;
                                
                                          // Record and batch send data
                                          while (millis() - startMillis < recordingDuration) {
                                            unsigned long currentTime = micros(); // Timestamp in microseconds
                                            int sensorValue = analogRead(A2);    // Read analog value
                                
                                            // Format data and add to buffer
                                            bufferIndex += snprintf(buffer + bufferIndex, sizeof(buffer) - bufferIndex, "%lu,%d\n", currentTime, sensorValue);
                                
                                            // Check if buffer is nearly full
                                            if (bufferIndex >= bufferSize - 50) {
                                              client.write(buffer, bufferIndex); // Send buffer to client
                                              bufferIndex = 0;                  // Reset buffer index
                                            }
                                          }
                                
                                          // Send any remaining data in buffer
                                          if (bufferIndex > 0) {
                                            client.write(buffer, bufferIndex);
                                          }
                                
                                          client.println("Recording complete.");
                                          Serial.println("Recording complete.");
                                          recordingDuration = 0; // Reset recording duration
                                        }
                                      }
                                    }
                                
                                    client.stop(); // Close connection
                                    Serial.println("Client disconnected.");
                                  }
                                }
                                
                        
                        
Having run that script, I run this python script that communicates over socket (It runs on pyserial, so I needed to install that extension). Importantly, you musty provide the IP address of the Xiao. The above arduino script prints the IP address.

This python script communicates with my Xiao and facilitates wifi control to run the functionality of the arduino script that most recently programmed the ESP32.
 import socket
                            import time
                            import csv
                            import os
                            
                            # Replace with the ESP32's IP address and port
                            esp32_ip = "172.20.10.12"  # ESP32 IP address
                            esp32_port = 80            # ESP32 port
                            
                            # Duration to collect data (in seconds)
                            collection_duration = 10
                            
                            # Buffer size for batch writes
                            buffer_size = 50000  # Number of records to temporarily store in memory
                            
                            # Directory to save data
                            output_dir = "data"
                            os.makedirs(output_dir, exist_ok=True)
                            output_file = os.path.join(output_dir, "accelerometer_data2.csv")
                            
                            # Create a TCP socket
                            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                            
                            # Connect to the ESP32
                            sock.connect((esp32_ip, esp32_port))
                            print("Connected to ESP32")
                            
                            # Prepare variables
                            data_buffer = []
                            start_time = time.time()
                            
                            # Open the CSV file in write mode
                            with open(output_file, "w", newline="") as csvfile:
                                csvwriter = csv.writer(csvfile)
                                # Write the header row
                                csvwriter.writerow(["Timestamp (s)", "X (m/s^2)", "Y (m/s^2)", "Z (m/s^2)"])
                                
                                try:
                                    while time.time() - start_time < collection_duration:
                                        # Receive data from ESP32
                                        data = sock.recv(1024).decode("utf-8")
                                        if not data:
                                            break
                                        
                                        # Process received data
                                        lines = data.strip().split("\n")
                                        for line in lines:
                                            try:
                                                # Example format: "X: 1.234 Y: 2.345 Z: 3.456"
                                                parts = line.split()
                                                x = float(parts[1])  # Extract X value
                                                y = float(parts[3])  # Extract Y value
                                                z = float(parts[5])  # Extract Z value
                                                timestamp = time.time() - start_time
                                                # Append to buffer
                                                data_buffer.append([timestamp, x, y, z])
                                            except (IndexError, ValueError):
                                                print(f"Invalid data format: {line}")
                                        
                                        # Write buffer to file when it reaches the buffer size
                                        if len(data_buffer) >= buffer_size:
                                            csvwriter.writerows(data_buffer)
                                            data_buffer.clear()
                                except Exception as e:
                                    print(f"\nError: {e}")
                                finally:
                                    # Write any remaining data in the buffer to the file
                                    if data_buffer:
                                        csvwriter.writerows(data_buffer)
                                    sock.close()
                                    print(f"\nConnection closed. Data saved to '{output_file}'.")
                            
I used a LiPo battery as a power supply rather than my computer and this allowed me to make the system entirely wireless.

Here's what it looks like Heres's all my files for this week Week 12 Files/a>
...