11. Networking: Cooper, Noah¶
This weeks task for the group work was to send a message between 2 projects.
Theory¶
We worked together as we were both using a esp32-c3. The advantage of this is that it had wifi, and allowed us to easily communicate. On top of the standard wifi, Noah pointed out that we could use MDNS. MDNS essentially allows for wifi on arduino not to connect 2 via ips, but instead through hostnames like we are so familiar with. Basically, to connect to google you type google.com, but you could also type 172.217.19.164 to get to the same place. MDNS allows for arduinos to locally host a website that can be found through the “google” instead of “172.217.19.164”
Also, for the communication we decided on: 1. a computer sends a message to coopers board, which spins the stepper on Noah’s board and sends a message to Cooper’s board 2. Coopers’s board receives a message, and sweeps a servo
This ensured that we were able to both communicate between computer and chip, as well as chip to chip.
Code¶
The code itself was generated with AI, but required major changes because 1. the AI we used (chatgpt) uses servo.h for the library for servo control. the problem with this is that servo.h does not work with esp32 series devices, so we had to manually substitute it with the ESP32Servo library. 2. It did not understand Noah’s custom stepper at all. Noah made a custom driver using a really non standard chip, and the AI was unable to wrap its head around how to make it spin. It tried using a library that also didn’t work on a esp32, and also was made for a drv8825, which is the higher power, more popular, and easier to use version of the driver Noah uses (drv8835) 3. As with everything, we never fed it any identifying information to start it off. This basically boiled down to us inputting our wifi’s networkname and password, ensuring that the AI never got a hold of it
Stepper Code¶
The code used on the Noah’s project/stepper motor/primary receiver
// Stepper Board (Server)
// Connects to Wi-Fi, uses mDNS, sends commands to servo, steps after confirmation
#include <WiFi.h>
#include <HTTPClient.h>
#include <ESPmDNS.h>
#include <WebServer.h>
// WiFi credentials
const char* WIFI_SSID = "";
const char* WIFI_PASSWORD = "";
// mDNS hostnames
const char* SERVO_HOSTNAME = "servo"; // Servo board's mDNS name
const char* STEPPER_HOSTNAME = "stepper"; // This board's mDNS name
// --- Pin Definitions
#define PHASE_A_PIN 2
#define ENABLE_A_PIN 3
#define PHASE_B_PIN 4
#define ENABLE_B_PIN 5
WebServer server(80);
// Function to step the stepper motor
void stepStepper() {
Serial.println("Stepper: Stepping motor now!");
digitalWrite(ENABLE_A_PIN, COIL_ENABLE); // Enable driver A
digitalWrite(ENABLE_B_PIN, COIL_ENABLE); // Enable driver B
int step = 100; //amount of steps to do
int phase = 25;
if (phase < 0) {
phase += 4;
}
switch (phase) {
case 0:
digitalWrite(PHASE_A_PIN, HIGH);
digitalWrite(PHASE_B_PIN, LOW);
break;
case 1:
digitalWrite(PHASE_A_PIN, LOW);
digitalWrite(PHASE_B_PIN, LOW);
break;
case 2:
digitalWrite(PHASE_A_PIN, LOW);
digitalWrite(PHASE_B_PIN, HIGH);
break;
case 3:
digitalWrite(PHASE_A_PIN, HIGH);
digitalWrite(PHASE_B_PIN, HIGH);
break;
}
}
void setup() {
Serial.begin(115200);
// Connect to Wi-Fi
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to Wi-Fi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWi-Fi connected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
// --- Setup Stepper Pins ---
pinMode(PHASE_A_PIN, OUTPUT);
pinMode(ENABLE_A_PIN, OUTPUT);
pinMode(PHASE_B_PIN, OUTPUT);
pinMode(ENABLE_B_PIN, OUTPUT);
// --- Initialize Motor Driver as Disabled ---
digitalWrite(ENABLE_A_PIN, LOW); // Disable driver A
digitalWrite(ENABLE_B_PIN, LOW); // Disable driver B
// Start mDNS
if (!MDNS.begin(STEPPER_HOSTNAME)) {
Serial.println("Error setting up mDNS responder!");
while (true) {
delay(1000);
}
}
Serial.println("mDNS responder started as 'stepper.local'");
// Handle incoming HTTP request to /start
server.on("/start", HTTP_GET, []() {
Serial.println("Received /start command!");
if (contactServo()) {
Serial.println("Servo confirmed move. Now stepping the stepper...");
stepStepper();
server.send(200, "text/plain", "Stepper moved after servo confirmation");
} else {
Serial.println("Failed to contact servo. Stepper will not move.");
server.send(500, "text/plain", "Failed to confirm servo movement");
}
});
server.begin();
Serial.println("HTTP server started. Waiting for /start...");
}
void loop() {
server.handleClient();
}
// Function to contact the servo board
bool contactServo() {
HTTPClient http;
String url = "http://" + String(SERVO_HOSTNAME) + ".local/move_servo";
Serial.print("Trying to contact Servo at: ");
Serial.println(url);
http.begin(url);
int httpCode = http.GET();
if (httpCode == 200) {
Serial.println("Servo responded successfully (HTTP 200)!");
http.end();
return true;
} else {
Serial.print("Servo contact failed! HTTP code: ");
Serial.println(httpCode);
http.end();
return false;
}
}
Servo Code¶
// Servo Board (Client)
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WebServer.h>
#include <HTTPClient.h>
#include <ESP32Servo.h>
const char* WIFI_SSID = "";
const char* WIFI_PASSWORD = "";
// mDNS Hostnames
const char* SERVO_HOSTNAME = "servo"; // This board
const char* STEPPER_HOSTNAME = "stepper"; // Stepper server hostname
const int SERVO_PIN = 7; // Servo connected to GPIO 7
WebServer server(80);
Servo myServo;
void setup() {
Serial.begin(115200);
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nConnected!");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
if (!MDNS.begin(SERVO_HOSTNAME)) {
Serial.println("Error starting mDNS!");
while (1) delay(1000);
}
Serial.println("mDNS responder started (servo.local)");
// Attach servo
myServo.attach(SERVO_PIN);
myServo.write(90); // center to be safe
server.on("/move_servo", HTTP_GET, []() {
Serial.println("Received move_servo command!");
moveServo();
server.send(200, "text/plain", "Servo moved successfully");
});
server.begin();
}
void loop() {
server.handleClient();
}
void moveServo() {
Serial.println("Moving servo...");
myServo.write(0);
delay(1500);
myServo.write(180);
delay(1500);
myServo.write(90); //center
Serial.println("Servo movement complete");
}
Video¶
Download¶
The sketches for the 2 projects can be found here