Send analog values using espnow
-
- Posts: 32
- Joined: Sun Nov 25, 2018 10:05 pm
- Contact:
Send analog values using espnow
Is there sample code anywhere to send analog values between two esp32s using the espnow function?
Free CAD files for hobby and engineering projects:
https://grabcad.com/has-2
https://grabcad.com/has-2
Re: Send analog values using espnow
The code is not different than sending integer value or string. Its at all just a bunch of bytes.
-
- Posts: 32
- Joined: Sun Nov 25, 2018 10:05 pm
- Contact:
Re: Send analog values using espnow
Hi I used this website:
https://www.instructables.com/id/ESP32- ... -Protocol/
His code is not complete on instructables but it seems to be complete on his website:
https://www.fernandok.com/2018/03/esp32 ... p-now.html
I'm not using pushbuttons like him to active the led on the esp32.
I'm using 4 photoresistors, but my array is not transferring those values to the slave.
I'm not getting anything on my serial output on the slave side.
I tried to change this to:
analogWrite below on the slave side but I got an error.
Any thoughts? Thanks.
Master side:
Slave side:
https://www.instructables.com/id/ESP32- ... -Protocol/
His code is not complete on instructables but it seems to be complete on his website:
https://www.fernandok.com/2018/03/esp32 ... p-now.html
I'm not using pushbuttons like him to active the led on the esp32.
I'm using 4 photoresistors, but my array is not transferring those values to the slave.
I'm not getting anything on my serial output on the slave side.
I tried to change this to:
analogWrite below on the slave side but I got an error.
Any thoughts? Thanks.
Code: Select all
//Sets its output to match the received value
digitalWrite(gpios[i], data[i]);
Code: Select all
//allows you to communicate with I2C
#include<Wire.h>
//Libs for espnow and wifi
#include <esp_now.h>
#include <WiFi.h>
//Channel used in the connection
#define CHANNEL 1
const int MPU_addr = 0x68;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
int minVal = 85;
int maxVal = 402;
double x;
int EA; //elevation angle
double z;
//top left sensor pin = PinTL
const int PinTL = 33;
const int PinBL = 35;
const int PinTR = 32;
const int PinBRT = 34;
// The sensor value
int TL = 0;
int BL = 0;
int TR = 0;
int BRT = 0;
// As photoresistor approaches minimum sensor value more light is seen by it
int MinTL = 0;
int MinBL = 0;
int MinTR = 0;
int MinBRT = 0;
int MaxTL = 4096;
int MaxBL = 4096;
int MaxTR = 4096;
int MaxBRT = 4096;
//Gpios that we are going to read (analogRead) and send to the Slaves
//It's important that the Slave source code has this same array
//with the same gpios in the same order
uint8_t gpios[] = {TL,BL,TR,BRT};
//In the setup function we'll calculate the gpio count and put in this variable,
//so we don't need to change this variable everytime we change
//the gpios array total size, everything will be calculated automatically
//on setup function
int gpioCount;
//Slaves Mac Addresses that will receive data from the Master
//If you want to send data to all Slaves, use only the broadcast address {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
//If you want to send data to specific Slaves, put their Mac Addresses separeted with comma (use WiFi.macAddress())
//to find out the Mac Address of the ESPs while in STATION MODE)
uint8_t macSlaves[][6] = {
//To send to specific Slaves
//{0x24, 0x0A, 0xC4, 0x0E, 0x3F, 0xD1}, {0x24, 0x0A, 0xC4, 0x0E, 0x4E, 0xC3}
//Or to send to all Slaves
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
};
void setup() {
Wire.begin();
Wire.beginTransmission(MPU_addr);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(115200);
//Calculation of gpio array size:
//sizeof(gpios) returns how many bytes "gpios" array points to.
//Elements in this array are of type uint8_t.
//sizeof(uint8_t) return how many bytes uint8_t type has.
//Therefore if we want to know how many gpios there are,
//we divide the total byte count of the array by how many bytes
//each element has.
gpioCount = sizeof(gpios)/sizeof(uint8_t);
//Puts ESP in STATION MODE
WiFi.mode(WIFI_STA);
//Shows on the Serial Monitor the STATION MODE Mac Address of this ESP
Serial.print("Mac Address in Station: ");
Serial.println(WiFi.macAddress());
//Calls the function that will initialize the ESP-NOW protocol
InitESPNow();
//Calculation of the size of the slaves array:
//sizeof(macSlaves) returns how many bytes the macSlaves array points to.
//Each Slave Mac Address is an array with 6 elements.
//If each element is sizeof(uint8_t) bytes
//then the total of slaves is the division of the total amount of bytes
//by how many elements each MAc Address has
//by how much bytes each element has.
int slavesCount = sizeof(macSlaves)/6/sizeof(uint8_t);
//For each Slave
for(int i=0; i<slavesCount; i++){
//We create a variable that will store the slave information
esp_now_peer_info_t slave;
//We inform the channel
slave.channel = CHANNEL;
//0 not to use encryption or 1 to use
slave.encrypt = 0;
//Copies the array address to the structure
memcpy(slave.peer_addr, macSlaves[i], sizeof(macSlaves[i]));
//Add the slave
esp_now_add_peer(&slave);
}
//Registers the callback that will give us feedback about the sent data
//The function that will be executed is called OnDataSent
esp_now_register_send_cb(OnDataSent);
//For each gpio
//For each GPIO pin in array
for(int i=0; i<gpioCount; i++){
//We put in read mode
pinMode(gpios[i], INPUT);
}
//Calls the send function
send();
}
void InitESPNow() {
//If the initialization was successful
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
//If there was an error
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
//Function that will read the gpios and send
//the read values to the others ESPs
void send(){
//Array that will store the read values
uint8_t values[gpioCount];
//For each gpio
for(int i=0; i<gpioCount; i++){
//Reads the value (HIGH or LOW) of the gpio
//and stores the value on the array
values[i] = analogRead(gpios[i]);
}
//In this example we are going to use the broadcast address {0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF}
//to send the values to all Slaves.
//If you want to send to a specific Slave, you have to put its Mac Address on macAddr.
//If you want to send to more then one specific Slave you will need to create
//a "for loop" and call esp_now_send for each mac address on the macSlaves array
uint8_t macAddr[] = {0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF};
esp_err_t result = esp_now_send(macAddr, (uint8_t*) &values, sizeof(values));
Serial.print("Send Status: ");
//If it was successful
if (result == ESP_OK) {
Serial.println("Success");
}
//if it failed
else {
Serial.println("Error");
}
}
//Callback function that gives us feedback about the sent data
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
char macStr[18];
//Copies the receiver Mac Address to a string
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]);
//Prints it on Serial Monitor
Serial.print("Sent to: ");
Serial.println(macStr);
//Prints if it was successful or not
Serial.print("Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
//Sends again
send();
}
//We don't do anything on the loop.
//Every time we receive feedback about the last sent data,
//we'll be calling the send function again,
//therefore the data is always being sent
void loop() {
Wire.beginTransmission(MPU_addr);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_addr, 14, true);
AcX = Wire.read() << 8 | Wire.read();
AcY = Wire.read() << 8 | Wire.read();
AcZ = Wire.read() << 8 | Wire.read();
int xAng = map(AcX, minVal, maxVal, -180, 180);
int yAng = map(AcY, minVal, maxVal, -180, 180);
int zAng = map(AcZ, minVal, maxVal, -180, 180);
EA = RAD_TO_DEG * (atan2(xAng, zAng));
// Calibrate during the first five seconds
while (millis() < 5000) {
TL = analogRead(PinTL);
BL = analogRead(PinBL);
TR = analogRead(PinTR);
BRT = analogRead(PinBRT);
// Record the maximum sensor value
if (TL > MaxTL) {
MaxTL = TL;
}
if (BL > MaxBL) {
MaxBL = BL;
}
if (TR > MaxTR) {
MaxTR = TR;
}
if (BRT > MaxBRT) {
MaxBRT = BRT;
}
if (TL < MinTL) {
MinTL = TL;
}
if (BL < MinBL) {
MinBL = BL;
}
if (TR < MinTR) {
MinTR = TR;
}
if (BRT < MinBRT) {
MinBRT = BRT;
}
}
// Signal the end of the calibration period
// Read the sensor
TL = analogRead(PinTL); // Top left sensor
BL = analogRead(PinBL); // Bottom left sensor
TR = analogRead(PinTR); // Top right sensor
BRT = analogRead(PinBRT); // Bottom right sensor
// Apply the calibration to the sensor reading
TL = map(TL, MinTL, MaxTL, 0, 1023);
BL = map(BL, MinBL, MaxBL, 0, 1023);
TR = map(TR, MinTR, MaxTR, 0, 1023);
BRT = map(BRT, MinBRT, MaxBRT, 0, 1023);
// In case the sensor value is outside the range seen during calibration
TL = constrain(TL, 0, 1023);
BL = constrain(BL, 0, 1023);
TR = constrain(TR, 0, 1023);
BRT = constrain(BRT, 0, 1023);
//Sends analog values in this format: i.e. <380,148,224,260,45>
Serial.print("<");
Serial.print(TL);
Serial.print(",");
Serial.print(BL);
Serial.print(",");
Serial.print(TR);
Serial.print(",");
Serial.print(BRT);
Serial.print(",");
Serial.print(EA);
Serial.print(">");
Serial.println();
delay(5000);
}
Code: Select all
//Libs for espnow e wifi
#include <esp_now.h>
#include <WiFi.h>
//Gpios we'll write the values received from the Master
//It's important that the Master source code has this same array
//with the same gpios in the same order
uint8_t gpios[] = {33,35,32,34};
//In the setup function we'll calculate the gpio count and put in this variable,
//so we don't need to change this variable everytime we change
//the gpios array total size, everything will be calculated automatically
//on setup function
int gpioCount;
void setup() {
Serial.begin(115200);
//Calculation of gpio array size:
//sizeof(gpios) returns how many bytes "gpios" array points to.
//Elements in this array are of type uint8_t.
//sizeof(uint8_t) return how many bytes uint8_t type has.
//Therefore if we want to know how many gpios there are,
//we divide the total byte count of the array by how many bytes
//each element has.
gpioCount = sizeof(gpios)/sizeof(uint8_t);
//Puts ESP in STATION MODE
WiFi.mode(WIFI_STA);
//Shows on the Serial Monitor the STATION MODE Mac Address of this ESP
Serial.print("Mac Address in Station: ");
Serial.println(WiFi.macAddress());
//Calls the function that will initialize the ESP-NOW protocol
InitESPNow();
//Registers the callback function that will be executed when
//this Slave receives data from the Master.
//The function in this case is called OnDataRecv
esp_now_register_recv_cb(OnDataRecv);
//For each gpio on gpios array
for(int i=0; i<gpioCount; i++){
//We put in read mode
pinMode(gpios[i], OUTPUT);
}
}
void InitESPNow() {
//If the initialization was successful
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
//If there was an error
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
//Callback function that tells us when data from Master is received
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
char macStr[18];
//Copies the sender Mac Address to a string
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]);
//Prints it on Serial Monitor
Serial.print("Received from: ");
Serial.println(macStr);
Serial.println("");
//For each gpio
for(int i=0; i<gpioCount; i++){
//Sets its output to match the received value
digitalWrite(gpios[i], data[i]);
}
}
//We don't do anything on the loop.
//Everytime something comes from Master
//the OnDataRecv function is executed automatically
//because we added it as callback using esp_now_register_recv_cb
void loop() {}
Free CAD files for hobby and engineering projects:
https://grabcad.com/has-2
https://grabcad.com/has-2
Re: Send analog values using espnow
Couple thoughts:
https://github.com/espressif/arduino-esp32
Some pins you are using as output are input only.
https://github.com/espressif/arduino-esp32
Most of the framework is implemented. Most noticable is the missing analogWrite. While analogWrite is on it's way, there are a few other options that you can use:
- 16 channels LEDC which is PWM
- 8 channels SigmaDelta which uses SigmaDelta modulation
- 2 channels DAC which gives real analog output
Some pins you are using as output are input only.
-
- Posts: 32
- Joined: Sun Nov 25, 2018 10:05 pm
- Contact:
Re: Send analog values using espnow
hi I am using this library example on git hub
ESPNow Master
https://github.com/espressif/arduino-es ... Master.ino
ESPNow Slave
https://github.com/espressif/arduino-es ... /Slave.ino
For the master code i'm trying to send these values in the void sendData() function, but they are not transmitting successfully to the slave side can you please advise?:
MASTER SERIAL RESULTS:
SLAVE SERIAL RESULTS:
ESPNow Master
https://github.com/espressif/arduino-es ... Master.ino
ESPNow Slave
https://github.com/espressif/arduino-es ... /Slave.ino
For the master code i'm trying to send these values in the void sendData() function, but they are not transmitting successfully to the slave side can you please advise?:
Code: Select all
uint8_t data = 0;
// send data
void sendData() {
//Sends analog values in this format: i.e. <380,148,224,260,45>
Serial.print("<");
Serial.print(TL);
Serial.print(",");
Serial.print(BL);
Serial.print(",");
Serial.print(TR);
Serial.print(",");
Serial.print(BRT);
Serial.print(",");
Serial.print(EA);
Serial.print(">");
Serial.println();
data++;
const uint8_t *peer_addr = slave.peer_addr;
Serial.print("Sending: "); Serial.println(data);
esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));
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");
}
}
Code: Select all
Found 12 devices
Found a Slave.
1: Slave_1 [30:AE:A4:F3:14:95] (-49)
Slave Found, processing..
Slave Status: Already Paired
<49,59,97,91,-135>
Sending: 2
Send Status: Success
Last Packet Sent to: 30:ae:a4:f3:14:95
Last Packet Send Status: Delivery Success
Code: Select all
Last Packet Recv from: 30:ae:a4:ef:bf:1c
Last Packet Recv Data: 103
Free CAD files for hobby and engineering projects:
https://grabcad.com/has-2
https://grabcad.com/has-2
-
- Posts: 32
- Joined: Sun Nov 25, 2018 10:05 pm
- Contact:
Re: Send analog values using espnow
I'm going to try to send 4 analog values (from photoresistors) and one i2c value (accelerometer measuring angle) and put these all in an int array.
This is different than what I was trying before. Can someone advise how I can send it using the espnow master example and receive it in the espnow receive example mentioned in previous posts.
I see the int data=0 variable, and how it sends data.
But get confused with the rest of the syntax in the void send and void recv functions.
Can someone please give an example?
Thanks.
This is different than what I was trying before. Can someone advise how I can send it using the espnow master example and receive it in the espnow receive example mentioned in previous posts.
I see the int data=0 variable, and how it sends data.
But get confused with the rest of the syntax in the void send and void recv functions.
Can someone please give an example?
Thanks.
Free CAD files for hobby and engineering projects:
https://grabcad.com/has-2
https://grabcad.com/has-2
-
- Posts: 32
- Joined: Sun Nov 25, 2018 10:05 pm
- Contact:
Re: Send analog values using espnow
I've been able to make some progress in putting in the analog values on the transmitter side,
but on the receiver side I'm still not receiving the data.
I did map my 12 bit analog values but they are not uint8_t since they are bigger than 255.
They are mapped to 0-3300 mV because my analog inputs are being read via a voltage divider.
For the receiver side I'm using the code that is on the github site for esp now slave.
Am I missing something?
but on the receiver side I'm still not receiving the data.
I did map my 12 bit analog values but they are not uint8_t since they are bigger than 255.
They are mapped to 0-3300 mV because my analog inputs are being read via a voltage divider.
Code: Select all
/*
ESPNOW - Basic communication - Master
Date: 26th September 2017
Author: Arvind Ravulavaru <https://github.com/arvindr21>
Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32
Description: This sketch consists of the code for the Master module.
Resources: (A bit outdated)
a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
b. http://www.esploradores.com/practica-6-conexion-esp-now/
<< This Device Master >>
Flow: Master
Step 1 : ESPNow Init on Master and set it in STA mode
Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup)
Step 3 : Once found, add Slave as peer
Step 4 : Register for send callback
Step 5 : Start Transmitting data from Master to Slave
Flow: Slave
Step 1 : ESPNow Init on Slave
Step 2 : Update the SSID of Slave with a prefix of `slave`
Step 3 : Set Slave in AP mode
Step 4 : Register for receive callback and wait for data
Step 5 : Once data arrives, print it in the serial monitor
Note: Master and Slave have been defined to easily understand the setup.
Based on the ESPNOW API, there is no concept of Master and Slave.
Any devices can act as master or slave.
*/
/*
Smoothing
Reads repeatedly from an analog input, calculating a running average and
printing it to the computer. Keeps ten readings in an array and continually
averages them.
created 22 Apr 2007
by David A. Mellis <dam@mellis.org>
modified 9 Apr 2012
by Tom Igoe
This example code is in the public domain.
http://www.arduino.cc/en/Tutorial/Smoothing
*/
//Libs for espnow and wifi
#include <esp_now.h>
#include <WiFi.h>
// Global copy of slave
esp_now_peer_info_t slave;
#define CHANNEL 3
#define PRINTSCANRESULTS 0
#define DELETEBEFOREPAIR 0
#include <driver/adc.h>
// Define the number of samples to keep track of. The higher the number, the
// more the readings will be smoothed, but the slower the output will respond to
// the input. Using a constant rather than a normal variable lets us use this
// value to determine the size of the readings array.
const int numReadings = 64;
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
long total = 0; // the running total
long average = 0; // the average
unsigned long delay_time = 5000; //Earth rotates .25 degrees/minute. In 4 minutes Earth rotates 1 degree.
unsigned long time_now = 0;
int Azimuth = 0;
int Elevation = 0;
int AzimuthVoltage = 0;
int ElevationVoltage = 0;
/***************************Void functions**********************************/
// 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");
// Retry InitESPNow, add a counte and then restart?
// InitESPNow();
// or Simply Restart
ESP.restart();
}
}
// Scan for slaves in AP mode
void ScanForSlave() {
int8_t scanResults = WiFi.scanNetworks();
// reset on each scan
bool slaveFound = 0;
memset(&slave, 0, sizeof(slave));
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(RSSI);
Serial.print(")");
Serial.println("");
}
delay(10);
// Check if the current device starts with `Slave`
if (SSID.indexOf("Slave") == 0) {
// SSID of interest
Serial.println("Found a Slave.");
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 ii = 0; ii < 6; ++ii ) {
slave.peer_addr[ii] = (uint8_t) mac[ii];
}
}
slave.channel = CHANNEL; // pick a channel
slave.encrypt = 0; // no encryption
slaveFound = 1;
// we are planning to have only one slave in this example;
// Hence, break after we find one, to be a bit efficient
break;
}
}
}
if (slaveFound) {
Serial.println("Slave Found, processing..");
} else {
Serial.println("Slave Not 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
bool manageSlave() {
if (slave.channel == CHANNEL) {
if (DELETEBEFOREPAIR) {
deletePeer();
}
Serial.print("Slave Status: ");
const esp_now_peer_info_t *peer = &slave;
const uint8_t *peer_addr = slave.peer_addr;
// check if the peer exists
bool exists = esp_now_is_peer_exist(peer_addr);
if ( exists) {
// Slave already paired.
Serial.println("Already Paired");
return true;
} 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");
return true;
} else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW Not Init");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_FULL) {
Serial.println("Peer list full");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
Serial.println("Out of memory");
return false;
} else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
Serial.println("Peer Exists");
return true;
} else {
Serial.println("Not sure what happened");
return false;
}
}
} else {
// No slave found to process
Serial.println("No Slave found to process");
return false;
}
}
void deletePeer() {
const esp_now_peer_info_t *peer = &slave;
const uint8_t *peer_addr = slave.peer_addr;
esp_err_t delStatus = esp_now_del_peer(peer_addr);
Serial.print("Slave Delete Status: ");
if (delStatus == ESP_OK) {
// Delete success
Serial.println("Success");
} else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) {
// How did we get so far!!
Serial.println("ESPNOW Not Init");
} else if (delStatus == ESP_ERR_ESPNOW_ARG) {
Serial.println("Invalid Argument");
} else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) {
Serial.println("Peer not found.");
} else {
Serial.println("Not sure what happened");
}
}
uint8_t data = 0;
// send data
void sendData() {
time_now = millis();
data++;
const uint8_t *peer_addr = slave.peer_addr;
Serial.print("Sending: "); Serial.println(data);
esp_err_t result = esp_now_send(peer_addr, &data, sizeof(data));
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");
}
//Voltage divider analog in pins
// https://dl.espressif.com/doc/esp-idf/latest/api-reference/peripherals/adc.html
// set up A:D channels
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11); //Pin34
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(ADC1_CHANNEL_7, ADC_ATTEN_DB_11); //Pin35
// Read the sensor
Azimuth = adc1_get_raw(ADC1_CHANNEL_7);
Elevation = adc1_get_raw(ADC1_CHANNEL_6);
int inputPin[2] = {Azimuth, Elevation};
uint8_t ai;
for (ai = 0; ai < 2; ai++) {
// subtract the last reading:
total = total - readings[readIndex];
// read from the sensor:
readings[readIndex] = inputPin[ai];
// add the reading to the total:
total = total + readings[readIndex];
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
}
// Apply the calibration to the sensor reading
AzimuthVoltage = map(Azimuth, 0, 4096, 0, 3300);
ElevationVoltage = map(Elevation, 0, 4096, 0, 3300);
//Sends analog values in this format: i.e. {1800,2100}
int data[2] = {AzimuthVoltage, ElevationVoltage};
uint8_t i;
Serial.println(" ");
for (i = 0; i < 2; i++) {
Serial.print(data[i]);
Serial.println(" ");
}
Serial.println(" ");
//wait approx. [period] ms}
while (millis() < time_now + delay_time) {}
}
// 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];
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");
}
/***************************End of Void functions**********************************/
void setup() {
//Set device in STA mode to begin with
Serial.begin(115200);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
WiFi.mode(WIFI_STA);
Serial.println("ESPNow/Basic/Master Example");
// 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 Transmitted packet
esp_now_register_send_cb(OnDataSent);
}
void loop() {
// In the loop we scan for slave
ScanForSlave();
// If Slave is found, it would be populate in `slave` variable
// We will check if `slave` is defined and then we proceed further
if (slave.channel == CHANNEL) { // check if slave channel is defined
// `slave` is defined
// Add slave as peer if it has not been added already
bool isPaired = manageSlave();
if (isPaired) {
// pair success or already paired
// Send data to device
sendData();
} else {
// slave pair failed
Serial.println("Slave pair failed!");
}
}
else {
// No slave found to process
}
}
Am I missing something?
Code: Select all
/*
ESPNOW - Basic communication - Slave
Date: 26th September 2017
Author: Arvind Ravulavaru <https://github.com/arvindr21>
Purpose: ESPNow Communication between a Master ESP32 and a Slave ESP32
Description: This sketch consists of the code for the Slave module.
Resources: (A bit outdated)
a. https://espressif.com/sites/default/files/documentation/esp-now_user_guide_en.pdf
b. http://www.esploradores.com/practica-6-conexion-esp-now/
<< This Device Slave >>
Flow: Master
Step 1 : ESPNow Init on Master and set it in STA mode
Step 2 : Start scanning for Slave ESP32 (we have added a prefix of `slave` to the SSID of slave for an easy setup)
Step 3 : Once found, add Slave as peer
Step 4 : Register for send callback
Step 5 : Start Transmitting data from Master to Slave
Flow: Slave
Step 1 : ESPNow Init on Slave
Step 2 : Update the SSID of Slave with a prefix of `slave`
Step 3 : Set Slave in AP mode
Step 4 : Register for receive callback and wait for data
Step 5 : Once data arrives, print it in the serial monitor
Note: Master and Slave have been defined to easily understand the setup.
Based on the ESPNOW API, there is no concept of Master and Slave.
Any devices can act as master or salve.
*/
#include <esp_now.h>
#include <WiFi.h>
#define CHANNEL 1
// 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");
// Retry InitESPNow, add a counte and then restart?
// InitESPNow();
// or Simply Restart
ESP.restart();
}
}
// config AP SSID
void configDeviceAP() {
char* SSID = "Slave_1";
bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0);
if (!result) {
Serial.println("AP Config failed.");
} else {
Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
}
}
void setup() {
Serial.begin(115200);
Serial.println("ESPNow/Basic/Slave Example");
//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_recv_cb(OnDataRecv);
}
// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
char macStr[18];
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 Recv from: "); Serial.println(macStr);
Serial.print("Last Packet Recv Data: "); Serial.println(*data);
}
void loop() {
// Chill
}
Free CAD files for hobby and engineering projects:
https://grabcad.com/has-2
https://grabcad.com/has-2
Re: Send analog values using espnow
Hello knightridar,
The last post on this thread has been quite a while ago and I wish I could help you but I'm getting started on microcontrollers programing and Esp_now and I was looking to send analog values as well, from an analog stick and a potentiometer and I was reading your post and saw you were having some progress and would love to know if you did manage to do it. I wanted to ask you as well if you tried converting the numbers from the voltage to under 255 (dividing by a constant) so you could use uint8_t. I'll keep my fingers crossed for a reply
The last post on this thread has been quite a while ago and I wish I could help you but I'm getting started on microcontrollers programing and Esp_now and I was looking to send analog values as well, from an analog stick and a potentiometer and I was reading your post and saw you were having some progress and would love to know if you did manage to do it. I wanted to ask you as well if you tried converting the numbers from the voltage to under 255 (dividing by a constant) so you could use uint8_t. I'll keep my fingers crossed for a reply
-
- Posts: 32
- Joined: Sun Nov 25, 2018 10:05 pm
- Contact:
Re: Send analog values using espnow
Hi this is the closest I've gotten so far:
https://esp32.com/viewtopic.php?f=19&t=13054
I have another example too that I'll look for but had trouble assigning it on receiving side.
https://esp32.com/viewtopic.php?f=19&t=13054
I have another example too that I'll look for but had trouble assigning it on receiving side.
Free CAD files for hobby and engineering projects:
https://grabcad.com/has-2
https://grabcad.com/has-2
Re: Send analog values using espnow
Hello knightridar,
I would like to let you know that I was able to make what I meant to do work. I checked the link you provided and there are a lot of things I don't fully grasp yet. I dunno if it will help you or not but I'm gonna share you how I did (could be a noob way to go about it but if it works it works :p)
Master code
Slave code
I would like to let you know that I was able to make what I meant to do work. I checked the link you provided and there are a lot of things I don't fully grasp yet. I dunno if it will help you or not but I'm gonna share you how I did (could be a noob way to go about it but if it works it works :p)
Master code
Code: Select all
//#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`
#include <esp_now.h>
#include <WiFi.h>
#include <Wire.h>
#include "heltec.h"
#include <esp_wifi_internal.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#define CHANNEL 1
#define DATARATE WIFI_PHY_RATE_24M
#define PRINTSCANRESULTS 0
#define DELETEBEFOREPAIR 0
//#define RST_OLED 16 //OLED Reset引脚,需要手动Reset,否则不显示
#define OLED_UPDATE_INTERVAL 500 //OLED屏幕刷新间隔ms
//SSD1306 display(0x3C, 4, 15);
//dados de autenticação
const char* ssid = "";
const char* password = "";
//esp_now_peer_info_t slave;
char* readController();
//int But0, But1, But2, But3, But4, But5, But6, But7, But8, But9, But10, But11, joyXL, joyYL, joyXR, joyYR;
//SSD1306 display(0x3c, 21, 22);
int butSpeed = 0;
//pino do potenciometro
int potPin1 = 22;
//ADC max on ESP32 (12bit ADC width)
int ADC_Max = 4095;
//Pinos que iremos ler (digitalRead) e enviar para os Slaves
//É importante que o código fonte dos Slaves tenha este mesmo array com os mesmos gpios
//na mesma ordem
uint8_t gpios[] = {2, 22, 23, 17, 12, 25, 39, 38, 37, 36, 13};
//No setup iremos calcular a quantidade de pinos e colocar nesta variável,
//assim não precisamos trocar aqui toda vez que mudarmos a quantidade de pinos,
//tudo é calculado no setup
int gpioCount;
//Mac Address dos slaves para os quais iremos enviar a leitura
//Se quiser enviar para todos os Slaves utilize apenas o endereço de broadcast {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}.
//Se quiser enviar para ESPs específicos coloque o Mac Address (obtido através da função WiFi.macAddress())
uint8_t macSlaves[][6] = {
//Se for enviar para ESPs específicos, coloque cada endereço separado por vírgula
// {0x24, 0x0A, 0xC4, 0x0E, 0x3F, 0xD1}, {0x24, 0x0A, 0xC4, 0x0E, 0x4E, 0xC3}
//Se for enviar para todos, apenas deixe o endereço de broadcast {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
};
void setup() {
Serial.begin(115200);
Heltec.begin(true, false, true);
Heltec.display->flipScreenVertically();
Heltec.display->setFont(ArialMT_Plain_10);
//Cálculo do tamanho do array de gpios que serão lidos com o digitalRead
//sizeof(gpios) retorna a quantidade de bytes que o array gpios aponta
//Sabemos que todos os elementos do array são do tipo uint8_t
//sizeof(uint8_t) retorna a quantidade de bytes que o tipo uint8_t possui
//Sendo assim para saber quantos elementos o array possui
//fazemos a divisão entre a quantidade total de bytes do array e quantos
//bytes cada elemento possui
gpioCount = sizeof(gpios) / sizeof(uint8_t);
//Coloca o ESP em modo station
WiFi.mode(WIFI_STA);
//Desligar o WiFi para iniciar ESPNow
WiFi.disconnect();
//Chama a função que inicializa o ESPNow
InitESPNow();
//Cálculo do tamanho do array com os mac address dos slaves
//sizeof(macSlaves) retorna a quantidade de bytes que o array macSlaves aponta
//Sabemos que cada mac address é um array de 6 posições e
//cada posição possui sizeof(uint8_t) bytes, então
//a quantidade de slaves é a divisão da quantidade de bytes
//total do array pela quantidade de posições e o resultado
//dessa divisão dividimos novamente por quantos bytes cada posição possui
int slavesCount = sizeof(macSlaves) / 6 / sizeof(uint8_t);
//Para cada slave
for (int i = 0; i < slavesCount; i++) {
//Criamos uma variável que irá guardar as informações do slave
esp_now_peer_info_t slave;
//Informamos o canal
slave.channel = CHANNEL;
//0 para não usar criptografia ou 1 para usar
slave.encrypt = 0;
//Copia o endereço do array para a estrutura
memcpy(slave.peer_addr, macSlaves[i], sizeof(macSlaves[i]));
//Adiciona o slave
esp_now_add_peer(&slave);
}
//Registra o callback que nos informará sobre o status do envio
//A função que será executada é OnDataSent e está declarada mais abaixo
esp_now_register_send_cb(OnDataSent);
//Para cada pino que está no array gpios (estava gpioCount em vez do numero 9)
for (int i=0; i < gpioCount; i++){
//Colocamos em modo input até ao analógico
pinMode(gpios[i], INPUT);
}
//Chama a função send
send();
}
void InitESPNow() {
//Se a inicialização foi bem sucedida
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
//Se houve erro na inicialização
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
//Função que irá fazer a leitura dos pinos
//que estão no array gpios e enviar os valores
//lidos para os outros ESPs
void displayshow(){
Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
Heltec.display->setColor(WHITE);
//Heltec.display->clear();
Heltec.display->drawString(0, 0, "BangBang\nController\nwith\nESP-NOW");
}
void send(){
valPot1 = analogRead(potPin1);
valPot1 = map(valPot1, 0, ADC_Max, 0, 180);
Serial.println(valPot1);
//Array que irá armazenar os valores lidos
uint8_t values[gpioCount];
//Para cada pino
for(int i=0; i < gpioCount; i++){
//Lê o estado do pino e armazena no array
values[i] = digitalRead(gpios[i]);
values[1] = valPot1;
Serial.println("gpios");
Serial.println(gpios[i]);
Serial.println("values");
Serial.println(values[i]);
}
//O endereço de broadcast irá enviar as informações para todos os ESPs
//Se quiser que a informação vá para ESPs específicos você deve chamar a função
//esp_now_send para cada Mac Address, passando o Mac Address como primeiro
//parâmetro no lugar do broadcast
uint8_t broadcast[] = {0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF};
esp_err_t result = esp_now_send(broadcast, (uint8_t*) &values, sizeof(values));
Serial.print("Send Status: ");
//Se o envio foi bem sucedido
if (result == ESP_OK) {
Serial.println("Success");
}
//Se aconteceu algum erro no envio
else {
Serial.println("Error");
}
}
//Função que serve de callback para nos avisar
//sobre a situação do envio que fizemos
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
char macStr[18];
//Copiamos o Mac Address destino para uma string
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]);
//Mostramos o Mac Address que foi destino da mensagem
Serial.print("Sent to: ");
Serial.println(macStr);
//Mostramos se o status do envio foi bem sucedido ou não
Serial.print("Status: ");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Success" : "Fail");
//Enviamos novamente os dados
send();
}
void loop() {
Heltec.display->clear();
Heltec.display->setTextAlignment(TEXT_ALIGN_LEFT);
Heltec.display->setFont(ArialMT_Plain_10);
Heltec.display->drawString(0, 0, "pin:" + String(gpios[1]));
Heltec.display->setFont(ArialMT_Plain_10);
Heltec.display->drawString(0, 10, "valor:" + String(values[1]));
Heltec.display->display();
delay(10);
Heltec.display->clear();
Heltec.display->display();
//delay(100);
}
Code: Select all
#include <ESP32Servo.h>
#include <esp_now.h>
#include <WiFi.h>
#define CHANNEL 1
#define DATARATE WIFI_PHY_RATE_24M
#define PRINTSCANRESULTS 0
#define DELETEBEFOREPAIR 0
#define OLED_UPDATE_INTERVAL 500
Servo myservo; // create servo object to control a servo
//dados de autenticação
const char* ssid = "";
const char* password = "";
//Pinos que iremos escrever (digitalWrite) cujos valores são recebios do Master
//É importante que o código fonte do Master tenha este mesmo array com os mesmos gpios
//na mesma ordem
uint8_t gpios[] = {2, 22, 23, 17, 12, 25, 39, 38, 37, 36, 13};
//No setup iremos calcular a quantidade de pinos e colocar nesta variável,
//assim não precisamos trocar aqui toda vez que mudarmos a quantidade de pinos,
//tudo é calculado no setup
int gpioCount;
// Possible PWM GPIO pins on the ESP32: 0(used by on-board button),2,4,5(used by on-board LED),12-19,21-23,25-27,32-33
int servoPin = gpios[0]; // GPIO pin used to connect the servo control (digital out)
void setup()
{
Serial.begin(115200);
//Cálculo do tamanho do array de gpios
//sizeof(gpios) retorna a quantidade de bytes que o array gpios aponta
//Sabemos que todos os elementos do array são do tipo uint8_t
//sizeof(uint8_t) retorna a quantidade de bytes que o tipo uint8_t possui
//Sendo assim para saber quantos elementos o array possui
//fazemos a divisão entre a quantidade total de bytes do array e quantos
//bytes cada elemento possui
gpioCount = sizeof(gpios)/sizeof(uint8_t);
//Colocamos o ESP em modo station
WiFi.mode(WIFI_STA);
//Mostramos no Monitor Serial o Mac Address deste ESP quando em modo station
//Se quiser que o Master mande para ESPs em específico, altere no
//array de slaves (no código fonte do Master) para que ele possua apenas os Mac Addresses printados aqui
Serial.print("Mac Address in Station: ");
Serial.println(WiFi.macAddress());
//Chama a função que inicializa o ESPNow
InitESPNow();
//Registra o callback que nos informará quando o Master enviou algo
//A função que será executada é OnDataRecv e está declarada mais abaixo
esp_now_register_recv_cb(OnDataRecv);
//Para cada pino que está no array gpios (estava gpioCount em vez do numero 9)
for (int i=0; i<gpioCount; i++){
//Colocamos em modo input até ao analógico
pinMode(gpios[i], OUTPUT);
}
myservo.setPeriodHertz(50);// Standard 50hz servo
myservo.attach(servoPin, 500, 2400); // attaches the servo on pin 18 to the servo object
// using SG90 servo min/max of 500us and 2400us
// for MG995 large servo, use 1000us and 2000us,
// which are the defaults, so this line could be
// "myservo.attach(servoPin);"
}
void InitESPNow() {
//Se a inicialização foi bem sucedida
if (esp_now_init() == ESP_OK) {
Serial.println("ESPNow Init Success");
}
//Se houve erro na inicialização
else {
Serial.println("ESPNow Init Failed");
ESP.restart();
}
}
//Função que serve de callback para nos avisar
//quando chegou algo do Master
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
char macStr[18];
//Copiamos o Mac Address origem para uma string
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]);
//Mostramos o Mac Address que foi a origem da mensagem
Serial.print("Received from: ");
Serial.println(macStr);
Serial.println("");
//Para cada pino
for(int i=0; i<gpioCount; i++){
//Colocamos o valor recebido do Master na saída do respectivo pino
digitalWrite(gpios[i], data[i]);
Serial.println(data[i]);
myservo.write(data[0]); // set the servo position according to the scaled value
// wait for the servo to get there
}
}
void loop() {
}
Who is online
Users browsing this forum: No registered users and 77 guests