mode selector convert espNOW

sebasdt
Posts: 3
Joined: Fri Jul 24, 2020 8:18 am

mode selector convert espNOW

Postby sebasdt » Sat Oct 17, 2020 2:05 pm

The idea behind this is:
I have made a Led matrix and want to "easily" change modes or set a value something, another person has done this(diod-dev https://github.com/Diod-dev/New_Visualizer_Skeleton) but it's done with serial communication and not espnow

The slave esp32 reads and acts on incoming messages from the master esp32, in the format of '< (letter) (3 digit number) >'.
For example, I would like to set the brightness to 50% then would send <B128>.

here are the example codes:
master

Code: Select all

void setup{
Serial.begin(115200); // Serial monitor output
  Serial2.begin(115200);
  pinMode(ledPin, OUTPUT);
}
void loop() {

}

int updateCurrentBrightness() {
  currentBrightness = inputMasterBrightness.toInt();
  return currentBrightness;
}

void sendRequest(int req) {
  switch (req) {
  case 0:
    currentMode = req;
    Serial2.write('<');
    Serial2.write('f');
    Serial2.write('0');
    Serial2.write('0');
    Serial2.write('0');
    Serial2.write('>');
    break;
  case 1:
    currentMode = req;
    Serial2.write('<');
    Serial2.write('o');
    Serial2.write('0');
    Serial2.write('0');
    Serial2.write('0');
    Serial2.write('>');
    break;
  case 2:
    currentMode = req;
    Serial2.write('<');
    Serial2.write('s');
    for (int i = 0; i < inputHue.length(); i++) {
      Serial2.write(inputHue[i]);
    }
    Serial2.write('>');
    break;
  case 3:
    currentMode = req;
    Serial2.write('<');
    Serial2.write('t');
    for (int i = 0; i < inputSat.length(); i++) {
      Serial2.write(inputSat[i]);
    }
    Serial2.write('>');
    break;
  case 4:
    currentMode = req;
    Serial2.write('<');
    Serial2.write('b');
    for (int i = 0; i < inputVal.length(); i++) {
      Serial2.write(inputVal[i]);
    }
    Serial2.write('>');
    break;
  case 5:
    currentMode = req;
    sendMVMode(req);
    break;
  case 6:
    currentMode = req;
    sendMVMode(req);
    break;
  case 7:
    currentMode = req;
    sendMVMode(req);
    break;
  case 8:
    currentMode = req;
    sendMVMode(req);
    break;
  case 9:
    currentMode = req;
    sendMVMode(req);
    break;
  case 10:
    currentMode = req;
    sendMVMode(req);
    break;
  case 11:
    currentMode = req;
    sendMVMode(req);
    break;
  case 12:
    currentMode = req;
    sendMVMode(req);
    break;
  case 13:
    currentMode = req;
    sendMVMode(req);
    break;
  case 14:
    currentMode = req;
    sendMVMode(req);
    break;
  case 15:
    currentMode = req;
    sendMVMode(req);
    break;
  case 16:
    currentMode = req;
    sendMVMode(req);
    break;
  case 17:
    currentMode = req;
    sendAmbMode(req);
    break;
  case 18:
    currentMode = req;
    sendAmbMode(req);
    break;
  case 19:
    currentMode = req;
    sendAmbMode(req);
    break;
  case 20:
    currentMode = req;
    sendAmbMode(req);
    break;
  case 21:
    currentMode = req;
    sendAmbMode(req);
    break;
  case 22:
    currentMode = req;
    sendAmbMode(req);
    break;
  case 23:
    //currentMode = req;
    Serial2.write('<');
    Serial2.write('z');
    for (int i = 0; i < inputMasterBrightness.length(); i++) {
      Serial2.write(inputMasterBrightness[i]);
    }
    Serial2.write('>');
    break;
  case 98:
    currentMode = req;
    Serial2.write('<');
    Serial2.write('x');
    Serial2.write('0');
    Serial2.write('0');
    Serial2.write('0');
    Serial2.write('>');
    break;
  case 99:
    Serial2.write('<');
    Serial2.write('y');
    for (int i = 0; i < inputAudioMultiplier.length(); i++) {
      Serial2.write(inputAudioMultiplier[i]);
    }
    Serial2.write('>');
    break;
  }
}

void sendMVMode(int req) {
  currentMode = req;
  Serial2.write('<');
  Serial2.write('m');
  sendMode = currentMode - 4;
  sendModeStr = (String)sendMode;
  for (int i = 0; i < sendModeStr.length(); i++) {
    Serial2.write(sendModeStr[i]);
  }
  Serial2.write('>');
}

void sendAmbMode(int req) {
  currentMode = req;
  Serial2.write('<');
  Serial2.write('a');
  sendMode = currentMode - 16;
  sendModeStr = (String)sendMode;
  for (int i = 0; i < sendModeStr.length(); i++) {
    Serial2.write(sendModeStr[i]);
  }
  Serial2.write('>');
}
slave

Code: Select all

// This file handles all incoming messages from ESP-32
// Reads and acts on incoming messages from ESP - 32, in the format of '< (letter) (3 digit number) >'. For exmaple, <b200>

// Variables for solid color
uint8_t solidHue = 0;
uint8_t solidSat = 255;
uint8_t solidVal = 255;

const byte numChars = 10;
char receivedChars[10];
char tempChars[3];

// TODO: use 'categories' instead of letters. 
// variables to hold parsed data
//char category[1] = { 0 };
//int instruction = 0;

bool newCommand = false;

int audioMultiplier; // temp input variable before recording this input in variable 'mult'

void setup{
Serial.begin(115200); // Serial monitor output
  Serial2.begin(115200); 
  pinMode(ledPin, OUTPUT);
}

void doThingsWithCommands() {
  if (receivedChars[0] == 'a') { // Chooses an ambient pattern and displays it
    for (int i = 0; i < 3; i++) // Record the next 3 characters (numbers) to a holding string 'tempChars'
      tempChars[i] = receivedChars[i + 1];
    ambPattern = atoi(tempChars); // convert 'tempChars' to integer.
    patternMode = 3; // Used in normalOperation()
    Serial.println(ambPattern);
  }
  else if (receivedChars[0] == 'b') {  // Sets the brightness when displaying a solid color
    patternMode = 4; // Used in normalOperation() to display a solid color
    for (int i = 0; i < 3; i++)
      tempChars[i] = receivedChars[i + 1];
    solidVal = atoi(tempChars); // 'atoi' converts string of characters to integer
  }
  else if (receivedChars[0] == 'f') { // The off button is set, last pattern mode is saved.
    patternModeOld = patternMode;
    patternMode = 0; // Used in normalOperation() to turn all LEDs off
  }
  else if (receivedChars[0] == 'm') { // Chooses a music-visualizing pattern and displays it
    for (int i = 0; i < 3; i++)
      tempChars[i] = receivedChars[i + 1];
    MVPattern = atoi(tempChars);
    patternMode = 2; // Used in normalOperation() to display a single music-visualizing pattern
    Serial.println(patternMode);
  }
  if (receivedChars[0] == 'o') {
    Serial.println(patternModeOld);
    patternMode = patternModeOld; // Used in normalOperation(), returns to last patternMode
  }
  else if (receivedChars[0] == 's') {
    patternMode = 4; // Used in normalOperation() to display a solid color
    for (int i = 0; i < 3; i++)
      tempChars[i] = receivedChars[i + 1];
    solidHue = atoi(tempChars); 
  }
  else if (receivedChars[0] == 't') {
    patternMode = 4; // Used in normalOperation() to display a solid color
    for (int i = 0; i < 3; i++)
      tempChars[i] = receivedChars[i + 1];
    solidSat = atoi(tempChars);
  }
  else if (receivedChars[0] == 'x') {
    patternMode = 1; // Used in normalOperation() to enter mode of changing music-visualization patterns to the music
  }
  else if (receivedChars[0] == 'y') {
    for (int i = 0; i < 3; i++)
      tempChars[i] = receivedChars[i + 1];
    audioMultiplier = atoi(tempChars);
    mult = (double)audioMultiplier / 100;
  }
  else if (receivedChars[0] == 'z') {
    for (int i = 0; i < 3; i++)
      tempChars[i] = receivedChars[i + 1];
    masterBrightness = atoi(tempChars);
  }
  else {}
}

// Reads incoming message from ESP-32, in the format of '< (letter) (3 digit number) >'. For exmaple, (<b200>)
void recWithStartEndMarkers() {
  static boolean recInProgress = false; // is a message currently being received?
  static byte ndx = 0; // index variable as receivedChars[] array populates
  char startMarker = '<'; // the first character sent by ESP-32 in a message
  char endMarker = '>'; // the last character sent by ESP-32 in a message
  char rc; // rc = each character as it comes in

  // While serial1 data is available and newCommand == false (the endMarker '>' hasn't been received yet)
  while (Serial1.available() && newCommand == false) {
    rc = Serial1.read(); // rc = new incoming character
    if (recInProgress == true) {
      if (rc != endMarker) {
        receivedChars[ndx] = rc;
        ndx++;
        //if (ndx >= numChars) // THESE 2 LINES FUCK UP THE LEDS
        //  ndx = numChars - 1;
      }
      else {
        receivedChars[ndx] = '\0';
        recInProgress = false;
        ndx = 0;
        newCommand = true;
      }
    }
    else if (rc == startMarker)
      recInProgress = true;
    else {}
  }
}

void parseData() {
  if (newCommand == true) {
    for (int i = 0; i < 4; i++) 
      Serial.print(receivedChars[i]);
    
    Serial.println();

    doThingsWithCommands();

    newCommand = false;
  }
}

void talkToESP() {
  recWithStartEndMarkers(); // constantly looking out for new messages
  parseData(); // after a message is received, act on it
}

ESP_Sprite
Posts: 4011
Joined: Thu Nov 26, 2015 4:08 am

Re: mode selector convert espNOW

Postby ESP_Sprite » Sun Oct 18, 2020 3:00 am

Okay; do you have a question?

sebasdt
Posts: 3
Joined: Fri Jul 24, 2020 8:18 am

Re: mode selector convert espNOW

Postby sebasdt » Sun Oct 18, 2020 9:35 am

oh sorry, I thought that I added the questions.

but anyway, I want to convert the code I provided from serial communication to espNOW.
what need to know if it's possible to send the format or characters (<b000>) via espNOW and how.
what would be the max number that I could send with espnow?

an idea I had was that you put the "ready to send format" in a char or string array and somehow send it over espnow

ESP_Sprite
Posts: 4011
Joined: Thu Nov 26, 2015 4:08 am

Re: mode selector convert espNOW

Postby ESP_Sprite » Tue Oct 20, 2020 1:55 am

Yes, that's perfectly possible. Per here you can send 250 bytes at a time; to send more, you'd need to implement some kind of fragmentation scheme.

sebasdt
Posts: 3
Joined: Fri Jul 24, 2020 8:18 am

Re: mode selector convert espNOW

Postby sebasdt » Fri Oct 23, 2020 1:08 pm

sorry for the long wait.
But in the meanwhile, I have found working codes for sending and receiving https://techtutorialsx.com/2019/10/27/e ... w-message/ also tried to learn how structs work and how to put data in them. searched it up and found this video about this topic. https://www.youtube.com/watch?v=1fi2CPGcdA8


I started to make code of what I have learned from the video and stumbled upon a compiler error. while trying to send the struct via espnow

This is al new for me, don't know what it really means.
I think that the way I'm trying to send the struct variable is causing problems.

Code: Select all

Arduino\simple_mode_espnow_struct\simple_mode_espnow_struct.ino: In function 'void sendData()':
simple_mode_espnow_struct:296:78: error: expected primary-expression before ',' token
      esp_err_t result = esp_now_send(peer_addr, (uint8_t *) &send_Mode_struct, sizeof(send_Mode_struct));
                                                                              ^
exit status 1
expected primary-expression before ',' token
here is the code I made and where the problem is.

Code: Select all

// Import required libraries//

#include <esp_now.h>
#include <WiFi.h>

#define CHANNEL 3
#define NUM_SLAVES 20                   // ESP-Now can handle a maximum of 20 slaves
#define PRINTSCANRESULTS 0
const int DATASIZE = 48;
String modes;

int slaveCount = 0;                     // Keeps count of no. of slaves with the defined prefix
esp_now_peer_info_t slaves[NUM_SLAVES]; // Stores the information of each of the slave that is added as a peer

void initESPNow();
void manageSlaves();
void scanForSlaves();
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status);
void onDataRecv(const uint8_t *mac_add, const uint8_t *data, int data_len);
void sendData();//to send the "normal" data

int number(int a, int b) {
  int n = random(a, b);
  return n;
}
char *alphabet[26] = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "L", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};

typedef struct {
  char *b;//begin character <
  char *Mode; //mode letter (alphabet)
  int Value; // value for the mode 0-255
  char *e; //end character >
} send_Mode_struct;

send_Mode_struct sendMode;
void setup() {

  // Serial port for debugging purposes
  Serial.begin(115200); // Serial monitor output
  pinMode(2, OUTPUT);

  //Set device in STA mode to begin with
  WiFi.mode(WIFI_MODE_STA);

  // This is the mac address of the Master in Station Mode
  Serial.print("STA MAC: ");
  Serial.println(WiFi.macAddress());

  // Init ESPNow with a fallback logic
  initESPNow();

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(onDataSent);
  esp_now_register_recv_cb(onDataRecv);

  scanForSlaves();
  manageSlaves();

  // send_Mode_struct sendMode;
  int i = number(0, 26);
  sendMode.b = "<";
  sendMode.Mode = alphabet[i];
  sendMode.Value = number(0, 255);
  sendMode.e = ">";

  // put your setup code here, to run once:
  delay(500);
  printStruct();
  Serial.println("setup done");
}

void loop() {
  // put your main code here, to run repeatedly:
  sendRandom();
  delay(500);
  printStruct();
  delay(1000);
}

void sendRandom() {

  //send_Mode_struct sendMode;
  Serial.println("picking random number and letter");
  int i = number(0, 26);
  sendMode.Mode = alphabet[i];
  sendMode.Value = number(0, 255);
  Serial.println("done picking random number letter");
}

void printStruct()
{
  //send_Mode_struct sendMode;
  Serial.println("sending mode");
  Serial.printf(sendMode.b);
  Serial.printf(sendMode.Mode);
  Serial.print(sendMode.Value);
  Serial.printf(sendMode.e);
  Serial.println("");
  Serial.println("done sending modes");
}
// Init ESP Now with fallback
void initESPNow()
{
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK)
  {
    Serial.println("ESPNow Init Success");
  }
  else
  {
    Serial.println("ESPNow Init Failed");
    ESP.restart();
  }
}

// Scan for slaves in AP mode
void scanForSlaves()
{
  int8_t scanResults = WiFi.scanNetworks();

  //reset slaves
  memset(slaves, 0, sizeof(slaves));
  slaveCount = 0;

  Serial.println("");

  if (scanResults == 0)
  {
    Serial.println("No WiFi devices in AP Mode found");
  }
  else
  {
    Serial.print("Found ");
    Serial.print(scanResults);
    Serial.println(" devices ");

    for (int i = 0; i < scanResults; i++)
    {
      // Print SSID and RSSI for each device found
      String SSID = WiFi.SSID(i);
      int32_t RSSI = WiFi.RSSI(i);
      String BSSIDstr = WiFi.BSSIDstr(i);

      if (PRINTSCANRESULTS)
      {
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(SSID);
        Serial.print(" [");
        Serial.print(BSSIDstr);
        Serial.print("]");
        Serial.print(" (");
        Serial.print(RSSI);
        Serial.print(")");
        Serial.println("");
      }

      delay(10);

      // Check if the current device starts with `Slave`
      if (SSID.indexOf("Slave") == 0)
      {
        // SSID of interest
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(SSID);
        Serial.print(" [");
        Serial.print(BSSIDstr);
        Serial.print("]");
        Serial.print(" (");
        Serial.print(RSSI);
        Serial.print(")");
        Serial.println("");

        // Get BSSID => Mac Address of the Slave
        int mac[6];

        if (6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x%c",  &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5]))
        {
          for (int j = 0; j < 6; j++)
          {
            slaves[slaveCount].peer_addr[j] = (uint8_t)mac[j];
          }
        }

        slaves[slaveCount].channel = CHANNEL; // pick a channel
        slaves[slaveCount].encrypt = 0; // no encryption
        slaveCount++;
      }
    }
  }

  if (slaveCount > 0)
  {
    Serial.print(slaveCount); Serial.println(" Slave(s) found, processing..");
  }
  else
  {
    Serial.println("No Slave Found, trying again.");
  }

  // clean up ram
  WiFi.scanDelete();
}

// Check if the slave is already paired with the master.
// If not, pair the slave with master
void manageSlaves()
{
  if (slaveCount > 0)
  {
    for (int i = 0; i < slaveCount; i++)
    {
      const esp_now_peer_info_t *peer = &slaves[i];
      const uint8_t *peer_addr = slaves[i].peer_addr;
      Serial.print("Processing: ");

      for (int j = 0; j < 6; j++)
      {
        Serial.print((uint8_t) slaves[i].peer_addr[j], HEX);
        if (j != 5)
        {
          Serial.print(":");
        }
      }

      Serial.print(" Status: ");

      // check if the peer exists
      bool exists = esp_now_is_peer_exist(peer_addr);
      if (exists)
      {
        // Slave already paired.
        Serial.println("Already Paired");
      }
      else
      {
        // Slave not paired, attempt pair
        esp_err_t addStatus = esp_now_add_peer(peer);
        if (addStatus == ESP_OK)
        {
          // Pair success
          Serial.println("Pair success");
        }
        else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT)
        {
          // How did we get so far!!
          Serial.println("ESPNOW Not Init");
        }
        else if (addStatus == ESP_ERR_ESPNOW_ARG)
        {
          Serial.println("Add Peer - Invalid Argument");
        }
        else if (addStatus == ESP_ERR_ESPNOW_FULL)
        {
          Serial.println("Peer list full");
        }
        else if (addStatus == ESP_ERR_ESPNOW_NO_MEM)
        {
          Serial.println("Out of memory");
        }
        else if (addStatus == ESP_ERR_ESPNOW_EXIST)
        {
          Serial.println("Peer Exists");
        }
        else
        {
          Serial.println("Not sure what happened");
        }
        delay(1000);
      }
    }
  }
  else
  {
    // No slave found to process
    Serial.println("No Slave found to process");
  }
}




// send data
void sendData() {
  // pos++;

  for (int i = 0; i < slaveCount; i++) {
    const uint8_t *peer_addr = slaves[i].peer_addr;
    if (i == 0) { // print only for first slave
      Serial.print("Sending: ");
      printStruct();
    }

     esp_err_t result = esp_now_send(peer_addr, (uint8_t *) &send_Mode_struct, sizeof(send_Mode_struct));
    Serial.print("Send Status: ");
    if (result == ESP_OK) {
      Serial.println("Success");
    } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
      // How did we get so far!!
      Serial.println("ESPNOW not Init.");
    } else if (result == ESP_ERR_ESPNOW_ARG) {
      Serial.println("Invalid Argument");
    } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
      Serial.println("Internal Error");
    } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
      Serial.println("ESP_ERR_ESPNOW_NO_MEM");
    } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
      Serial.println("Peer not found.");
    } else {
      Serial.println("Not sure what happened");
    }
    delay(100);
  }
}

// callback when data is sent from Master to Slave
void onDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
  char macStr[18];
  // sendTime = millis();
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);

  Serial.print("Last Packet Sent to: ");
  Serial.println(macStr);
  Serial.print("Last Packet Send Status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");


}

// callback when data is received from Slave to Master
void onDataRecv(const uint8_t *mac_add, const uint8_t *data, int data_len)
{
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_add[0], mac_add[1], mac_add[2], mac_add[3], mac_add[4], mac_add[5]);

  Serial.print("Last Packet Recv from: ");
  Serial.println(macStr);
  Serial.print("Last Packet Recv Data: ");
  Serial.println(*data);
  Serial.println("");
}

Who is online

Users browsing this forum: Baidu [Spider] and 33 guests