Thanks! I don't know why I didn't see that right away. Such a nooby mistake.
Also, thank you all for the help so far! its really appreciated!
it's working now and converted the serial mode selection to espnow with no problems so far.
The next thing to do is select if the mode select needs to be activated. that would be simple. (last famous words)
basic explanation about the code.
Do whatever you want to do with this code but please reference the original creator of the code [urhttps://github.com/Diod-dev/New_Visualizer_Skeleton[/url]
Sender:
-Search on its own for receivers and add then to the send list.
-send the struct data every few seconds.
Receiver:
- setup as a receiver and receive data and process this.
here below are the sender and receiver codes.
sender:
Code: Select all
//the original creator of this code: https://github.com/Diod-dev/New_Visualizer_Skeleton
// Import required libraries//
#include <esp_now.h>
#include <WiFi.h>
#define CHANNEL 3
#define NUM_SLAVES 3 // ESP-Now can handle a maximum of 20 slaves
#define PRINTSCANRESULTS 0
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 sendData();//to send the mode data
// Stores LED state
uint8_t currentBrightness;
int currentMode;
int currentPattern;
int inputAudioMultiplier;
int inputHue = 0;
int inputSat = 255;
int inputVal = 255;
int inputMasterBrightness;
int sendAnimation;
//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"};
int number(int a, int b) {
int n = random(a, b);
return n;
}
// Structure example to send data
// Must match the receiver structure
typedef struct sendModestruct {
char b[4];
char Mode[4];
int Value;
char e[4];
} sendModestruct;
// Create a struct_message called sendMode
sendModestruct sendMode;
void setup() {
// Serial port for debugging purposes
Serial.begin(115200); // Serial monitor output
//Set device in STA mode to begin with
WiFi.mode(WIFI_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);
scanForSlaves();
manageSlaves();
}
void loop() {
if (slaveCount > 0)
{
inputVal = random(0, 360);
inputSat = random(0, 255);
inputHue = random(0, 255);
inputAudioMultiplier = random(0, 255);
currentBrightness = random(0, 255);
for (int i = 0; i < 35; i++) {
Serial.println(i);
sendRequest(i);
delay(1000);
}
} else {
scanForSlaves();
manageSlaves();
delay(2000);
}
}
/*
void fillRandom() {
//sendModestruct sendMode;
Serial.println("picking random number and letter");
int i = number(0, 26);
strcpy(sendMode.Mode, alphabet[i]);
sendMode.Value = number(0, 255);
Serial.println("done picking random number letter");
Serial.println("");
}
*/
void printStruct()
{
Serial.println("printing values");
// Serial.println(sizeof(sendModestruct));
Serial.print("char 1: ");
Serial.println(sendMode.b);
Serial.print("char 2: ");
Serial.println(sendMode.Mode);
Serial.print("int: ");
Serial.println(sendMode.Value);
Serial.print("char 3: ");
Serial.println(sendMode.e);
Serial.println("");
Serial.println("done printing values");
}
int updateCurrentBrightness() {
currentBrightness = inputMasterBrightness;
return currentBrightness;
}
void sendRequest(int req) {
switch (req) {
case 0:
currentMode = req;//off command Also sets GPIO to LOW (blue light turns off)
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "f");
sendMode.Value = 000;
strcpy(sendMode.e, ">");
sendData();
break;
case 1: // on command Also sets GPIO to HIGH (blue light turns on)
currentMode = req;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "o");
sendMode.Value = 000;
strcpy(sendMode.e, ">");
sendData();
break;
case 2: //send solidcolor and so a hue value
currentMode = req;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "s");
sendMode.Value = inputHue;
strcpy(sendMode.e, ">");
sendData();
break;
case 3:// Send the Saturation
currentMode = req;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "t");
sendMode.Value = inputSat;
strcpy(sendMode.e, ">");
sendData();
break;
case 4: // Send a GET request for the Brightness
currentMode = req;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "b");
sendMode.Value = inputVal;
strcpy(sendMode.e, ">");
sendData();
break;
case 5: //music parttern 1
currentMode = req;
sendMVMode(req);
break;
case 6://music parttern 2
currentMode = req;
sendMVMode(req);
break;
case 7://music parttern 3
currentMode = req;
sendMVMode(req);
break;
case 8://music parttern 4
currentMode = req;
sendMVMode(req);
break;
case 9://music parttern 5
currentMode = req;
sendMVMode(req);
break;
case 10://music parttern 6
currentMode = req;
sendMVMode(req);
break;
case 11://music parttern 7
currentMode = req;
sendMVMode(req);
break;
case 12://music parttern 8
currentMode = req;
sendMVMode(req);
break;
case 13://music parttern 9
currentMode = req;
sendMVMode(req);
break;
case 14://music parttern 10
currentMode = req;
sendMVMode(req);
break;
case 15://music parttern 11
currentMode = req;
sendMVMode(req);
break;
case 17://demo parttern 1
currentMode = req;
sendAmbMode(req);
break;
case 18://demo parttern 2
currentMode = req;
sendAmbMode(req);
break;
case 19://demo parttern 3
currentMode = req;
sendAmbMode(req);
break;
case 20://demo parttern 4
currentMode = req;
sendAmbMode(req);
break;
case 21://demo parttern 5
currentMode = req;
sendAmbMode(req);
break;
case 22://demo parttern 6
currentMode = req;
sendAmbMode(req);
break;
case 23://demo parttern 7
currentMode = req;
sendAmbMode(req);
break;
case 24://demo parttern 8
currentMode = req;
sendAmbMode(req);
break;
case 25://demo parttern 9
currentMode = req;
sendAmbMode(req);
break;
case 26://demo parttern 10
currentMode = req;
sendAmbMode(req);
break;
case 27://demo parttern 11
currentMode = req;
sendAmbMode(req);
break;
case 30: // Send the master brightness to the mothership
//currentMode = req;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "z");
sendMode.Value = inputMasterBrightness;
strcpy(sendMode.e, ">");
sendData();
break;
case 31:// case 98 makes the patterns automatically switching
currentMode = req;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "x");
sendMode.Value = 000;
strcpy(sendMode.e, ">");
sendData();
break;
case 32: // Send the audio sensitivity
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "y");
sendMode.Value = inputAudioMultiplier;
strcpy(sendMode.e, ">");
sendData();
break;
}
}
void sendMVMode(int req) {
currentMode = req;
sendAnimation = currentMode - 4;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "m");
sendMode.Value = sendAnimation;
strcpy(sendMode.e, ">");
sendData();
}
void sendAmbMode(int req) {
currentMode = req;
sendAnimation = currentMode - 16;
strcpy(sendMode.b, "<");
strcpy(sendMode.Mode, "a");
sendMode.Value = sendAnimation;
strcpy(sendMode.e, ">");
sendData();
}
// 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() {
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 *) &sendMode, sizeof(sendMode));
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");
}
Receiver:
Code: Select all
//the original creator of this code: https://github.com/Diod-dev/New_Visualizer_Skeleton
// This file handles all incoming messages from ESP-32
// Reads and acts on incoming messages from ESP - 32 NOW, in the format of '< (letter) (3 digit number) >'. For exmaple, <b200>
/*
<< This Device Slave >>
Sample Serial log:
AP Config Success. Broadcasting with AP: Slave:3C:71:BF:52:D1:14
AP MAC: 3C:71:BF:52:D1:15
ESPNow Init Success
Last Packet Recv from: 24:0a:c4:0a:6f:08
Last Packet Recv Data: 1
*/
#include <esp_now.h>
#include <WiFi.h>
#define CHANNEL 1
#define SENDCHANNEL 1
#define WIFI_DEFAULT_CHANNEL 3
esp_now_peer_info_t peer;
void initESPNow();
void configDeviceAP();
void addPeer(uint8_t *peerMacAddress);
void onDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len);
// Variables for solid color
uint8_t solidHue = 0;
uint8_t solidSat = 255;
uint8_t solidVal = 255;
int patternMode = 1;
int patternModeOld;
int ambPattern;
int MVPattern;
int masterBrightness = 5;
double mult = 1.00;
char receivedChar[4];
char oldMode[4];
int Value;
bool newCommand = false;
typedef struct sendModestruct {
char b[4]; // 10 if you need 9 characters
char Mode[4]; // 21 if you need 20 characters
int Value;
char e[4]; // 5 if you need 4 characters
} sendModestruct;
sendModestruct sendMode;
void onDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
newCommand = true;
Serial.print("Last Packet Recv from: ");
Serial.println(macStr);
// Serial.print("Packet received: ");
// Serial.println(*incomingData);
memcpy(&sendMode, incomingData, sizeof(sendMode));
// Serial.print("Bytes received: ");
// Serial.println(len);
// printStruct();
}
// TODO: use 'categories' instead of letters.
// variables to hold parsed data
//char category[1] = { 0 };
//int instruction = 0;
int audioMultiplier; // temp input variable before recording this input in variable 'mult'
void setup() {
Serial.begin(115200); // Serial monitor output
//Set device in AP mode to begin with
WiFi.mode(WIFI_AP);
// configure device AP mode
configDeviceAP();
// This is the mac address of the Slave in AP Mode
Serial.print("AP MAC: ");
Serial.println(WiFi.softAPmacAddress());
// Init ESPNow with a fallback logic
initESPNow();
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info.
/// esp_now_register_send_cb(onDataSent);
esp_now_register_recv_cb(onDataRecv);
}
void doThingsWithCommands() {
if (receivedChar[0] == 'a') { // Chooses an ambient pattern and displays it
Serial.println("a");
ambPattern = Value;
patternMode = 3; // Used in normalOperation()
Serial.println(ambPattern);
}
else if (receivedChar[0] == 'b') { // Sets the brightness when displaying a solid color
Serial.println("b");
Serial.println(Value);
patternMode = 4; // Used in normalOperation() to display a solid color
solidVal = Value;
}
else if (receivedChar[0] == 'f') { // The off button is set, last pattern mode is saved.
Serial.println("f");
patternModeOld = patternMode;
patternMode = 0; // Used in normalOperation() to turn all LEDs off
}
else if (receivedChar[0] == 'm') { // Chooses a music-visualizing pattern and displays it
Serial.println("m");
Serial.println(Value);
MVPattern = Value;
patternMode = 2; // Used in normalOperation() to display a single music-visualizing pattern
Serial.println(patternMode);
}
else if (receivedChar[0] == 'o') {
Serial.println("o");
Serial.println(patternModeOld);
patternMode = patternModeOld; // Used in normalOperation(), returns to last patternMode
}
else if (receivedChar[0] == 's') {
Serial.println("s");
Serial.println(Value);
patternMode = 4; // Used in normalOperation() to display a solid color
solidHue = Value;
}
else if (receivedChar[0] == 't') {
Serial.println("t");
Serial.println(Value);
patternMode = 4; // Used in normalOperation() to display a solid color
solidSat = Value;
}
else if (receivedChar[0] == 'x') {
Serial.println("x");
patternMode = 1; // Used in normalOperation() to enter mode of changing music-visualization patterns to the music
}
else if (receivedChar[0] == 'y') {
Serial.println("y");
Serial.println(Value);
audioMultiplier = Value;
mult = (double)audioMultiplier / 100;
}
else if (receivedChar[0] == 'z') {
Serial.println("z");
Serial.println(Value);
masterBrightness = Value;
}
else {}
}
void SelectMode() {
if (newCommand == true) {
Serial.println("new Mode beginning");
oldMode[0] = sendMode.Mode[0];
receivedChar[0] = sendMode.Mode[0];
Value = sendMode.Value;
doThingsWithCommands();
newCommand = false;
Serial.println("new Mode ending");
}
}
void talkToESP() {
SelectMode(); // after a message is received, act on it
}
void loop() {
talkToESP();
delay(75); // simulate doing something else
}
void printStruct()
{
Serial.println("printing values");
// Serial.println(sizeof(sendModestruct));
Serial.print("char 1: ");
Serial.println(sendMode.b);
Serial.print("char 2:");
Serial.println(sendMode.Mode);
Serial.print("int: ");
Serial.println(sendMode.Value);
Serial.print("char 3:");
Serial.println(sendMode.e);
Serial.println("");
Serial.println("done printing values");
}
void initESPNow()
{
WiFi.disconnect();
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
else
{
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
// config AP SSID
void configDeviceAP()
{
String Prefix = "Slave:";
String Mac = WiFi.macAddress();
String SSID = Prefix + Mac;
String Password = "123456789";
bool result = WiFi.softAP(SSID.c_str(), Password.c_str(), CHANNEL, 0);
if (!result)
{
Serial.println("AP Config failed.");
}
else
{
Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
}
}
// Add Master as a peer
void addPeer(uint8_t *peerMacAddress)
{
peer.channel = SENDCHANNEL;
peer.ifidx = WIFI_IF_AP;
peer.encrypt = 0;
memcpy(peer.peer_addr, peerMacAddress, 6);
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 WENT WRONG");
}
}