Using ESP_NOW to sendstrings
Posted: Sun Aug 04, 2024 8:02 pm
I am building a sip & puff control system so that a quadriplegic can control a RC boat or car. I had it working with Arduino Nanos and NRF24L Wi-Fi modules. Now I am converting it to use a ESP32 and ESP_NOW for communications, the NRF24L's give me troubles now and then plus it reduces the hardware I need.
I have the ESP_NOW working if I send static text, "TEXT", but I have two variables that give me direction, (Foward, Idle & Reverse), and steering, (Left & Right). I am also trying to put those variables in a structure text message. I've tried a few ways but none of them are working, or I wouldn't be asking.
So my two questions are, how do I get my variables into the structure text elements, and how do I send it via ESP_NOW/
Code is show below, these are both ESP32 DEV Modules and I'm programming them with the Arduino IDE rev 2.3.2
Thanks
John
I have the ESP_NOW working if I send static text, "TEXT", but I have two variables that give me direction, (Foward, Idle & Reverse), and steering, (Left & Right). I am also trying to put those variables in a structure text message. I've tried a few ways but none of them are working, or I wouldn't be asking.
So my two questions are, how do I get my variables into the structure text elements, and how do I send it via ESP_NOW/
Code is show below, these are both ESP32 DEV Modules and I'm programming them with the Arduino IDE rev 2.3.2
Thanks
John
Code: Select all
/* Started with sipPuffToyCar_Mod example
added NRF24L01 communications
with corrections from forum
Rev 3 added steering state to receiver
Rev 4 Added sip/puff delay on steering
Rev 5 Replaced UNO and NRF24L with a ESP32 using ESP_NOW
*/
#include <esp_now.h>
#include <WiFi.h>
#include <SafeString.h>
// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0x34, 0x86, 0x5D, 0x45, 0x9D, 0x7C};
esp_now_peer_info_t peerInfo;
// Structure text to send data
typedef struct struct_message {
char drive[32];
char steering[32];
} struct_message;
// Create a struct_message called myData
struct_message myData;
// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" :
"Delivery Fail");
}
cSF(drvText_SS, 24);
cSF(strText_SS, 24);
#define SENSOR_PIN 34
#define SIP_THRESHOLD 2400 //analog val, 450
#define PUFF_THRESHOLD 3000 //analog val, 550
#define POLL_INTERVAL 10 //ms
#define SHORT_ACTION_MIN 100 //ms
#define SHORT_ACTION_MAX 750 //ms
#define ACTION_SPACE_MIN 50 //ms
#define ACTION_SPACE_MAX 750 //ms
uint32_t sipStartTime;
uint8_t sipStarted = 0;
uint32_t lastSipTime;
uint32_t lastSipDuration;
uint32_t puffStartTime;
uint8_t puffStarted = 0;
uint32_t lastPuffTime;
uint32_t lastPuffDuration;
uint8_t ThrottleOutValue = 0;
uint8_t ThrottleTrimValue = 0;
uint8_t SteeringOutValue = 135;
uint8_t SteeringTrimValue = 0;
uint32_t SteeringDelay = 0;
uint32_t previousMillis = 0;
uint32_t StartSteeringDelay = 50;
uint8_t SteeringPause = 0;
uint32_t SteeringPauseDelay = 500;
uint32_t SteeringPauseStart = 0;
enum DRIVE_STATE {FORWARD, REVERSE, IDLE}; // Enumeration, FORWARD - 1, REVERSE = 2, IDLE = 3
char *DRIVE_STATE_STRS[] = {"forward", "reverse", "idle"}; // ? Defines words so that when Drive state = 1 Serial monitor will display Forward, etc
uint8_t driveState = IDLE;
void setDrive(uint8_t state) {
if (driveState == state)
return;
if (state == FORWARD) {
}
else if (state == REVERSE) {
}
else {
}
driveState = state;
}
//
void toggleReverse() {
if (driveState == REVERSE)
return;
else if (driveState == IDLE)
setDrive(REVERSE);
else
setDrive(IDLE);
}
void toggleForward() {
if (driveState == FORWARD)
return;
else if (driveState == IDLE)
setDrive(FORWARD);
else
setDrive(IDLE);
}
enum STEERING_STATE {LEFT, RIGHT, CENTER};
char *STEERING_STATE_STRS[] = {"left", "right", "center"};
uint8_t steeringState = CENTER;
void setSteering(uint8_t state) {
if (steeringState == state)
return;
if (state == LEFT) {
}
else if (state == RIGHT) {
}
else {
SteeringPauseStart = millis();
SteeringPause = 0;
}
steeringState = state;
} // end void setSteering(uint8_t state)
void setup() {
Serial.begin(115299);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
} // End ot Setup Loop
void loop() {
int16_t val = analogRead(SENSOR_PIN); // Read Pressure Switch < 2000 = SIP, > 3000 = Puff
if (!sipStarted && val < SIP_THRESHOLD) {
SteeringPause = 1;
sipStarted = 1;
sipStartTime = millis(); //Store Sip Start Time
}
else if (sipStarted && val > SIP_THRESHOLD) {// SIP has Stopped
sipStarted = 0;
uint32_t duration = millis() - sipStartTime;
if (duration > SHORT_ACTION_MIN) {
uint32_t prevLastSipTime = lastSipTime;
uint32_t prevLastSipDuration = lastSipDuration;
lastSipTime = millis();
lastSipDuration = duration;
uint32_t space = sipStartTime - prevLastSipTime;
//two shorts in a row
if (prevLastSipDuration < SHORT_ACTION_MAX &&
lastSipDuration < SHORT_ACTION_MAX &&
space > ACTION_SPACE_MIN && space < ACTION_SPACE_MAX) {
toggleReverse();
}
}
}
if (!puffStarted && val > PUFF_THRESHOLD) {
SteeringPause = 1;
puffStarted = 1;
puffStartTime = millis();
}
else if (puffStarted && val < PUFF_THRESHOLD) {
puffStarted = 0;
uint32_t duration = millis() - puffStartTime;
if (duration > SHORT_ACTION_MIN) {
uint32_t prevLastPuffTime = lastPuffTime;
uint32_t prevLastPuffDuration = lastPuffDuration;
lastPuffTime = millis();
lastPuffDuration = duration;
uint32_t space = puffStartTime - prevLastPuffTime;
//two shorts in a row
if (prevLastPuffDuration < SHORT_ACTION_MAX &&
lastPuffDuration < SHORT_ACTION_MAX &&
space > ACTION_SPACE_MIN && space < ACTION_SPACE_MAX) {
toggleForward();
}
}
}
//update steering
if (sipStarted && (millis() > (sipStartTime + SteeringPauseDelay)))
setSteering(LEFT);
else if (puffStarted && (millis() > (puffStartTime + SteeringPauseDelay)))
setSteering(RIGHT);
else
setSteering(CENTER);
if (DRIVE_STATE_STRS[driveState] == "forward") {
}
else if (DRIVE_STATE_STRS[driveState] == "reverse") {
}
else {
}
unsigned long currentmillis = millis();
int CenterStop ;
if (currentmillis - previousMillis > StartSteeringDelay) {
previousMillis = currentmillis;
CenterStop = (135 + SteeringTrimValue);
if ((STEERING_STATE_STRS[steeringState] == "right") && (SteeringOutValue < 230)) {
SteeringOutValue = ((SteeringOutValue + 10) );
}
if ((STEERING_STATE_STRS[steeringState] == "left") && (SteeringOutValue > 40)) {
SteeringOutValue = ((SteeringOutValue - 10) );
}
if (STEERING_STATE_STRS[steeringState] == "center") {
if (SteeringOutValue - CenterStop > 2) {
SteeringOutValue = ((SteeringOutValue) - 5);
}
if (SteeringOutValue - CenterStop < -2) {
SteeringOutValue = ((SteeringOutValue) + 5);
}
} // End of CENTER if
} // End of Main Steering If loop
drvText_SS = DRIVE_STATE_STRS[driveState];
Serial.print(" Steering State = ");
Serial.print(STEERING_STATE_STRS[steeringState]);
Serial.print("\t");
Serial.print(" Drive State = ");
Serial.println(DRIVE_STATE_STRS[driveState]);
strText_SS = STEERING_STATE_STRS[steeringState];
delay(POLL_INTERVAL);
// Set values to send
strcpy(myData.drive, "driveState");
strcpy(myData.steering, "steeringState");
// myData.drive = (drvText_SS.c_str(), drvText_SS.length() )
// myData.steering = (strText_SS.c_str(), strText_SS.length() );
// strcpy(myData.a, drvText_SS);
// strcpy(myData.b, strText_SS);
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData,
sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
// delay(2000);
}