Files
Compete_car/Firmware/micro_motors/micro_motors.ino

646 lines
21 KiB
Arduino
Raw Normal View History

2026-02-03 07:07:57 +00:00
#include <WiFi.h>
2026-02-02 20:46:13 +00:00
#include <ArduinoOTA.h>
2026-02-03 07:07:57 +00:00
const char* ssid = "CIA";
const char* password = "hi123456";
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
#define motorAttach ledcAttach // Get more appropriate names
2026-02-02 20:46:13 +00:00
#define motorSpeed ledcWrite // same "
2026-02-03 07:07:57 +00:00
// Motor FR (Front Right)
#define FR_IN1 27
#define FR_IN2 14
#define FR_PWM 0
// Motor FL (Front Left)
#define FL_IN1 12
#define FL_IN2 13
#define FL_PWM 2
// Motor BR (Back Right)
2026-02-06 22:27:26 +00:00
#define BR_IN1 26 // Original: 33
#define BR_IN2 25 // Original: 32
#define BR_PWM 22 // Original: 23
2026-02-03 07:07:57 +00:00
// Motor BL (Back Left)
2026-02-06 22:27:26 +00:00
#define BL_IN1 33 // Original: 26
#define BL_IN2 32 // Original: 25
#define BL_PWM 23 // Original: 22
2026-02-03 07:07:57 +00:00
// PWM settings
#define PWM_FREQ 1000
2026-02-02 20:46:13 +00:00
#define PWM_RESOLUTION 8 // 0-255
#define SERIAL_RX 21
2026-02-03 07:07:57 +00:00
// Sensor data received from micro sensors
int sens_FL = -1;
int sens_FR = -1;
int sens_BL = -1;
int sens_BR = -1;
int sens_LF = -1;
int sens_LB = -1;
int sens_RF = -1;
2026-02-02 20:46:13 +00:00
int sens_RB = -1;
2026-02-06 22:27:26 +00:00
int sens_save = 10;
2026-02-02 20:46:13 +00:00
// Trim values to calibrate wheel speeds
2026-02-03 07:07:57 +00:00
int trimFL = 0;
int trimFR = 0;
int trimBL = 0;
2026-02-02 20:46:13 +00:00
int trimBR = 0;
#define BUFFER_SIZE 7
int buffer_FL[BUFFER_SIZE];
int buffer_FR[BUFFER_SIZE];
int buffer_BL[BUFFER_SIZE];
int buffer_BR[BUFFER_SIZE];
int buffer_LF[BUFFER_SIZE];
int buffer_LB[BUFFER_SIZE];
int buffer_RF[BUFFER_SIZE];
int buffer_RB[BUFFER_SIZE];
int bufferIndex = 0;
bool bufferFilled = false;
2026-02-03 07:07:57 +00:00
bool ph1 = false; // Phase 1 complete flag
2026-02-02 20:46:13 +00:00
bool ph2 = false; //phase 2 complete flag
bool ph3 = false; //phase 3 complete flag
bool p2_stop = false; // Flag when its passed the top of the hill
// Telnet server to watch serial
2026-02-03 07:07:57 +00:00
WiFiServer telnetServer(23);
WiFiClient telnetClient;
2026-02-02 20:46:13 +00:00
// Function declaritons
void otaTask(void *parameter); // Get micro ready for OTA
void logPrint(const char* msg); // Print function for serial and telnet, strings
void logPrint(int val); // Print function for serial and telnet, integers
2026-02-03 07:07:57 +00:00
void logPrint(float val); // Print function for serial and telnet, floats
2026-02-02 20:46:13 +00:00
void logPrintln(const char* msg); // Print line function for serial and telnet
void logPrintln(int val); // Print line function for serial and telnet, integers
2026-02-03 07:07:57 +00:00
void logPrintln(float val); // Print line function for serial and telnet, floats
void telnetTask(void *parameter); // Configure telnet serial
void motorFR(int speed); // Front right motor, speed from -255 to 255, positive goes forward, negative goes backward
void motorFL(int speed); // Front left motor, speed from -255 to 255, positive goes forward, negative goes backward
void motorBR(int speed); // Back right motor, speed from -255 to 255, positive goes forward, negative goes backward
void motorBL(int speed); // Back left motor, speed from -255 to 255, positive goes forward, negative goes backward
2026-02-02 20:46:13 +00:00
void motorsStop(); // Stop all motors
void motorsGo(int speed); // All motors move the same speed, from -255 to 255, positive goes forward, negative goes backward
void Go45right();
void Go45left();
void Go90right();
void Go90left();
2026-02-06 22:27:26 +00:00
void slideRight(int speed);
void slideLeft(int speed);
2026-02-02 20:46:13 +00:00
void receiveSensorData(); // Receive the sensors data from micro sensors
int rollingAverage(int buffer[]); // rollingAverage function call
void sensorsTest();
void motorsTest();
void phaseThree();
2026-02-05 18:05:07 +00:00
void align(int dist);
2026-02-02 20:46:13 +00:00
void setup() {
Serial.begin(115200);
// Configure WIFI
2026-02-03 07:07:57 +00:00
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
int wifiAttempts = 0;
while (WiFi.waitForConnectResult() != WL_CONNECTED && wifiAttempts < 10) {
Serial.println("WiFi connecting...");
wifiAttempts++;
delay(500);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
} else {
Serial.println("WiFi not available - running without network");
}
if (WiFi.status() == WL_CONNECTED) {
ArduinoOTA.setHostname("Motors");
ArduinoOTA.onStart([]() {
Serial.println("OTA Update starting...");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nOTA Update complete!");
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("OTA Error [%u]\n", error);
});
ArduinoOTA.begin();
telnetServer.begin();
2026-02-02 20:46:13 +00:00
}
2026-02-03 07:07:57 +00:00
Serial2.begin(115200, SERIAL_8N1, SERIAL_RX, -1);
// Motor direction pins
pinMode(FR_IN1, OUTPUT);
pinMode(FR_IN2, OUTPUT);
pinMode(FL_IN1, OUTPUT);
pinMode(FL_IN2, OUTPUT);
pinMode(BR_IN1, OUTPUT);
pinMode(BR_IN2, OUTPUT);
pinMode(BL_IN1, OUTPUT);
pinMode(BL_IN2, OUTPUT);
// PWM setup for ESP32
motorAttach(FR_PWM, PWM_FREQ, PWM_RESOLUTION);
2026-02-02 20:46:13 +00:00
motorAttach(FL_PWM, PWM_FREQ, PWM_RESOLUTION);
2026-02-03 07:07:57 +00:00
motorAttach(BR_PWM, PWM_FREQ, PWM_RESOLUTION);
2026-02-02 20:46:13 +00:00
motorAttach(BL_PWM, PWM_FREQ, PWM_RESOLUTION);
2026-02-03 07:07:57 +00:00
// Start with motors stopped
digitalWrite(FR_IN1, LOW);
digitalWrite(FR_IN2, LOW);
digitalWrite(FL_IN1, LOW);
digitalWrite(FL_IN2, LOW);
motorSpeed(FR_PWM, 0);
2026-02-02 20:46:13 +00:00
motorSpeed(FL_PWM, 0);
2026-02-03 07:07:57 +00:00
digitalWrite(BR_IN1, LOW);
digitalWrite(BR_IN2, LOW);
digitalWrite(BL_IN1, LOW);
digitalWrite(BL_IN2, LOW);
motorSpeed(BR_PWM, 0);
2026-02-02 20:46:13 +00:00
motorSpeed(BL_PWM, 0);
// FreeRTOS tasks
2026-02-03 07:07:57 +00:00
if (WiFi.status() == WL_CONNECTED) {
xTaskCreate(otaTask, "OTA", 4096, NULL, 1, NULL);
xTaskCreate(telnetTask, "Telnet", 4096, NULL, 1, NULL);
}
2026-02-02 20:46:13 +00:00
}
void loop() {
2026-02-06 22:27:26 +00:00
// ph1 = true;
2026-02-02 20:46:13 +00:00
// ph2 = true;
2026-02-06 22:27:26 +00:00
// ph3 = true;
2026-02-02 20:46:13 +00:00
if (!ph1) {
phaseOne();
ph1 = true;
}
2026-02-03 07:07:57 +00:00
2026-02-02 20:46:13 +00:00
if (!ph2) {
phaseTwo();
ph2 = true;
}
2026-02-03 07:07:57 +00:00
2026-02-02 20:46:13 +00:00
if (!ph3) {
phaseThree();
ph3 = true;
}
// motorsTest();
2026-02-06 22:27:26 +00:00
// sensorsTest();
2026-02-02 20:46:13 +00:00
}
void phaseOne() {
// Wait for valid sensor readings
2026-02-05 18:05:07 +00:00
while (sens_FL < 20 || sens_FR < 20 || sens_FL > 8000 || sens_FR > 8000) {
2026-02-02 20:46:13 +00:00
receiveSensorData(); // read sensors
delay(10);
}
2026-02-06 22:27:26 +00:00
delay(1000);
while (sens_FL < 20 || sens_FR < 20 || sens_FL > 8000 || sens_FR > 8000) {
receiveSensorData(); // read sensors
delay(10);
}
2026-02-02 20:46:13 +00:00
int distance;
int speed;
receiveSensorData();
2026-02-05 18:05:07 +00:00
while ((distance = (sens_FL + sens_FR) / 2) > 225) {
2026-02-02 20:46:13 +00:00
// Slow down as we approach target
if (distance > 500) {
2026-02-05 18:05:07 +00:00
speed = 120;
} else if (distance > 450) {
2026-02-02 20:46:13 +00:00
speed = 80;
} else {
speed = 40; // Slow down even more
}
motorsGo(speed);
delay(5); // Wait for new sensor data to arrive
receiveSensorData(); // Get fresh reading each iteration
}
motorsStop();
2026-02-05 18:05:07 +00:00
2026-02-02 20:46:13 +00:00
logPrint("Stopped at: "); logPrintln((sens_FL + sens_FR) / 2);
delay(1000);
Go90right();
delay(2000);
motorsGo(80);
delay(1250); // Go into the pit 1800 miliseconds,
motorsStop();
2026-02-03 07:07:57 +00:00
delay(3000); //how long to pick balls? dunno
2026-02-02 20:46:13 +00:00
motorsGo(-150);
delay(1200); // Go out of the pit 1800 miliseconds
2026-02-03 07:07:57 +00:00
motorsStop();
2026-02-02 20:46:13 +00:00
delay(500);
2026-02-06 22:27:26 +00:00
slideLeft(150);
delay(1350); // Sliding time before going up the ramp
2026-02-02 20:46:13 +00:00
motorsStop();
delay(2000);
}
void phaseTwo() {
// Wait for valid sensor readings - ENABLE IF YOU ARE TESTING ONLY THIS PHASE
2026-02-05 18:05:07 +00:00
while (sens_FL < 0 || sens_FR < 0) {
receiveSensorData(); // read sensors
delay(10);
}
receiveSensorData();
2026-02-02 20:46:13 +00:00
2026-02-05 18:05:07 +00:00
delay(1000);
motorsGo(-255);
2026-02-06 22:27:26 +00:00
delay(3000);
while ((sens_FL + sens_FR) / 2 > 320) {
2026-02-05 18:05:07 +00:00
motorsGo(-100);
delay(5); // Wait for new sensor data to arrive
receiveSensorData(); // Get fresh reading each iteration
}
2026-02-02 20:46:13 +00:00
motorsStop();
2026-02-06 22:27:26 +00:00
delay(2000);
2026-02-02 20:46:13 +00:00
}
void phaseThree() {
2026-02-06 22:27:26 +00:00
slideRight(150);
2026-02-06 22:57:54 +00:00
delay(900); // Slide right for 800 miliseconds
2026-02-06 22:27:26 +00:00
motorsStop();
delay(200); // Very small delay between turning and going, optional
motorsGo(-100);
2026-02-06 22:57:54 +00:00
delay(1450); // Go back towards the pin for 1450 miliseconds
2026-02-06 22:27:26 +00:00
motorsStop();
delay(200); // Very small delay between turning and going, optional
Go45right();
motorsGo(-70);
delay(2400);
motorsStop();
delay(200); // Very small delay between turning and going, optional
slideLeft(150);
delay(2500);
motorsStop();
delay(200); // Very small delay between turning and going, optional
Go45left();
delay(200);
motorsGo(-200);
delay(1900);
motorsStop();
2026-02-02 20:46:13 +00:00
}
2026-02-03 07:07:57 +00:00
void otaTask(void *parameter) {
for (;;) {
ArduinoOTA.handle();
vTaskDelay(10 / portTICK_PERIOD_MS);
}
}
void telnetTask(void *parameter) {
for (;;) {
if (telnetServer.hasClient()) {
if (telnetClient && telnetClient.connected()) {
telnetClient.stop();
}
telnetClient = telnetServer.available();
telnetClient.println("Connected to Motors");
}
vTaskDelay(100 / portTICK_PERIOD_MS);
}
}
void logPrint(const char* msg) {
Serial.print(msg);
if (telnetClient && telnetClient.connected()) {
telnetClient.print(msg);
}
}
void logPrint(int val) {
Serial.print(val);
if (telnetClient && telnetClient.connected()) {
telnetClient.print(val);
}
}
void logPrint(float val) {
Serial.print(val);
if (telnetClient && telnetClient.connected()) {
telnetClient.print(val);
}
}
void logPrintln(const char* msg) {
Serial.println(msg);
if (telnetClient && telnetClient.connected()) {
telnetClient.println(msg);
}
}
void logPrintln(int val) {
Serial.println(val);
if (telnetClient && telnetClient.connected()) {
telnetClient.println(val);
}
}
void logPrintln(float val) {
Serial.println(val);
if (telnetClient && telnetClient.connected()) {
telnetClient.println(val);
}
}
void motorFR(int speed) {
if (speed > 0) {
digitalWrite(FR_IN1, HIGH);
digitalWrite(FR_IN2, LOW);
motorSpeed(FR_PWM, constrain(speed + trimFR, 0, 255));
} else if (speed < 0) {
digitalWrite(FR_IN1, LOW);
digitalWrite(FR_IN2, HIGH);
motorSpeed(FR_PWM, constrain(-speed + trimFR, 0, 255));
} else {
digitalWrite(FR_IN1, LOW);
digitalWrite(FR_IN2, LOW);
motorSpeed(FR_PWM, 0);
}
}
void motorFL(int speed) {
if (speed > 0) {
digitalWrite(FL_IN1, HIGH);
digitalWrite(FL_IN2, LOW);
motorSpeed(FL_PWM, constrain(speed + trimFL, 0, 255));
} else if (speed < 0) {
digitalWrite(FL_IN1, LOW);
digitalWrite(FL_IN2, HIGH);
motorSpeed(FL_PWM, constrain(-speed + trimFL, 0, 255));
} else {
digitalWrite(FL_IN1, LOW);
digitalWrite(FL_IN2, LOW);
motorSpeed(FL_PWM, 0);
}
2026-02-02 20:46:13 +00:00
}
2026-02-03 07:07:57 +00:00
void motorBR(int speed) {
if (speed > 0) {
digitalWrite(BR_IN1, HIGH);
digitalWrite(BR_IN2, LOW);
motorSpeed(BR_PWM, constrain(speed + trimBR, 0, 255));
} else if (speed < 0) {
digitalWrite(BR_IN1, LOW);
digitalWrite(BR_IN2, HIGH);
motorSpeed(BR_PWM, constrain(-speed + trimBR, 0, 255));
} else {
digitalWrite(BR_IN1, LOW);
digitalWrite(BR_IN2, LOW);
motorSpeed(BR_PWM, 0);
}
2026-02-02 20:46:13 +00:00
}
2026-02-03 07:07:57 +00:00
void motorBL(int speed) {
if (speed > 0) {
digitalWrite(BL_IN1, HIGH);
digitalWrite(BL_IN2, LOW);
motorSpeed(BL_PWM, constrain(speed + trimBL, 0, 255));
} else if (speed < 0) {
digitalWrite(BL_IN1, LOW);
digitalWrite(BL_IN2, HIGH);
motorSpeed(BL_PWM, constrain(-speed + trimBL, 0, 255));
} else {
digitalWrite(BL_IN1, LOW);
digitalWrite(BL_IN2, LOW);
motorSpeed(BL_PWM, 0);
}
2026-02-02 20:46:13 +00:00
}
2026-02-03 07:07:57 +00:00
void motorsStop() {
motorFR(0);
motorFL(0);
motorBR(0);
motorBL(0);
2026-02-02 20:46:13 +00:00
}
int rollingAverage(int buffer[]) {
int sum = 0;
int count = bufferFilled ? BUFFER_SIZE : (bufferIndex + 1);
2026-02-03 07:07:57 +00:00
2026-02-02 20:46:13 +00:00
for (int i = 0; i < count; i++) {
sum += buffer[i];
}
2026-02-03 07:07:57 +00:00
2026-02-02 20:46:13 +00:00
return sum / count;
}
2026-02-05 18:05:07 +00:00
void receiveSensorData() {
static String data = "";
while (Serial2.available()) {
char c = Serial2.read();
if (c == '\n') {
// Process complete line
int values[8];
int idx = 0;
int start = 0;
for (int i = 0; i <= data.length() && idx < 8; i++) {
if (i == data.length() || data[i] == ',') {
values[idx++] = data.substring(start, i).toInt();
start = i + 1;
}
}
if (idx == 8) {
sens_FL = values[0];
sens_FR = values[1];
sens_BL = values[2];
sens_BR = values[3];
sens_LF = values[4];
sens_LB = values[5];
sens_RF = values[6];
sens_RB = values[7];
}
data = "";
} else if (c != '\r') {
data += c;
}
}
2026-02-02 20:46:13 +00:00
}
void sensorsTest() {
2026-02-03 07:07:57 +00:00
receiveSensorData();
logPrint("FL:"); logPrint(sens_FL);
logPrint(" FR:"); logPrint(sens_FR);
logPrint(" BL:"); logPrint(sens_BL);
logPrint(" BR:"); logPrint(sens_BR);
logPrint(" LF:"); logPrint(sens_LF);
logPrint(" LB:"); logPrint(sens_LB);
logPrint(" RF:"); logPrint(sens_RF);
logPrint(" RB:"); logPrintln(sens_RB);
2026-02-02 20:46:13 +00:00
delay(100);
}
void motorsTest() {
2026-02-03 07:07:57 +00:00
logPrintln("Right forward...");
2026-02-02 20:46:13 +00:00
motorBR(80);
2026-02-03 07:07:57 +00:00
motorFR(80);
delay(2000);
logPrintln("Right stop...");
2026-02-02 20:46:13 +00:00
motorBR(0);
2026-02-03 07:07:57 +00:00
motorFR(0);
delay(1000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Right forward...");
2026-02-02 20:46:13 +00:00
motorBR(250);
2026-02-03 07:07:57 +00:00
motorFR(250);
delay(2000);
logPrintln("Right stop...");
2026-02-02 20:46:13 +00:00
motorBR(0);
2026-02-03 07:07:57 +00:00
motorFR(0);
delay(1000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Left forward...");
2026-02-02 20:46:13 +00:00
motorBL(80);
2026-02-03 07:07:57 +00:00
motorFL(80);
delay(2000);
logPrintln("Left stop...");
motorsStop();
delay(1000);
logPrintln("Left forward...");
2026-02-02 20:46:13 +00:00
motorBL(250);
2026-02-03 07:07:57 +00:00
motorFL(250);
delay(2000);
logPrintln("Left stop...");
motorsStop();
delay(1000);
logPrintln("Front forward...");
2026-02-02 20:46:13 +00:00
motorFR(80);
2026-02-03 07:07:57 +00:00
motorFL(80);
delay(2000);
logPrintln("Front stop...");
2026-02-02 20:46:13 +00:00
motorsStop();
2026-02-03 07:07:57 +00:00
delay(1000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Front forward...");
2026-02-02 20:46:13 +00:00
motorFR(250);
2026-02-03 07:07:57 +00:00
motorFL(250);
delay(2000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Front stop...");
2026-02-02 20:46:13 +00:00
motorsStop();
2026-02-03 07:07:57 +00:00
delay(1000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Back forward...");
2026-02-02 20:46:13 +00:00
motorBR(80);
2026-02-03 07:07:57 +00:00
motorBL(80);
delay(2000);
logPrintln("Back stop...");
2026-02-02 20:46:13 +00:00
motorsStop();
2026-02-03 07:07:57 +00:00
delay(1000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Back forward...");
2026-02-02 20:46:13 +00:00
motorBR(250);
2026-02-03 07:07:57 +00:00
motorBL(250);
delay(2000);
2026-02-02 20:46:13 +00:00
2026-02-03 07:07:57 +00:00
logPrintln("Back stop...");
2026-02-02 20:46:13 +00:00
motorsStop();
2026-02-03 07:07:57 +00:00
delay(1000);
2026-02-02 20:46:13 +00:00
}
void motorsGo(int speed) {
2026-02-03 07:07:57 +00:00
motorFR(speed);
motorFL(speed);
motorBR(speed);
motorBL(speed);
2026-02-02 20:46:13 +00:00
}
void Go45right() {
2026-02-03 07:07:57 +00:00
motorFL(150);
motorFR(-150);
motorBL(150);
2026-02-02 20:46:13 +00:00
motorBR(-150);
2026-02-06 22:27:26 +00:00
delay(490); // Change time here for angle adjustment
2026-02-02 20:46:13 +00:00
motorsStop();
}
void Go45left() {
2026-02-03 07:07:57 +00:00
motorFL(-150);
motorFR(150);
motorBL(-150);
2026-02-02 20:46:13 +00:00
motorBR(150);
2026-02-06 22:27:26 +00:00
delay(490); // Change time here for angle adjustment
2026-02-02 20:46:13 +00:00
motorsStop();
}
void Go90right() {
2026-02-03 07:07:57 +00:00
motorFL(150);
motorFR(-150);
motorBL(150);
2026-02-02 20:46:13 +00:00
motorBR(-150);
2026-02-06 22:27:26 +00:00
delay(1100); // Change time here for angle adjustment
2026-02-02 20:46:13 +00:00
motorsStop();
}
void Go90left() {
2026-02-03 07:07:57 +00:00
motorFL(-150);
motorFR(150);
motorBL(-150);
2026-02-02 20:46:13 +00:00
motorBR(150);
2026-02-06 22:27:26 +00:00
delay(1100); // Change time here for angle adjustment
2026-02-02 20:46:13 +00:00
motorsStop();
}
2026-02-06 22:27:26 +00:00
void slideRight(int speed) {
motorFL(-speed);
motorFR(speed);
motorBL(speed);
motorBR(-speed);
2026-02-02 20:46:13 +00:00
}
2026-02-06 22:27:26 +00:00
void slideLeft(int speed) {
motorFL(speed);
motorFR(-speed);
motorBL(-speed);
motorBR(speed);
2026-02-02 20:46:13 +00:00
}
2026-02-05 18:05:07 +00:00
void align(int dist) {
receiveSensorData();
while ((sens_FL + sens_FR) / 2 > dist) {
if (sens_FL > sens_FR) {
motorFL(50);
} else {
motorFR(50);
}
delay(10);
motorsStop();
receiveSensorData();
}
}