-
Notifications
You must be signed in to change notification settings - Fork 0
Home
OVERVIEW Communication between ESP32's, using ESP-NOW.
sequenceDiagram
participant VPN-GATEWAY
participant ESPNOW-GATEWAY-DAEMON
participant SENSOR-DATA_ACQUISITION
VPN-GATEWAY-->>ESPNOW-GATEWAY-DAEMON: It's time to get measure: "measXX"
ESPNOW-GATEWAY-DAEMON-->>SENSOR-DATA_ACQUISITION: Take a measure: "request 0xXX"
SENSOR-DATA_ACQUISITION-->>SENSOR-DATA_ACQUISITION: Data Acquisition
ESPNOW-GATEWAY-DAEMON-->>SENSOR-DATA_ACQUISITION: Send me a measure: "request 0xXX"
ESPNOW-GATEWAY-DAEMON-->>ESPNOW-GATEWAY-DAEMON: Save Data
VPN-GATEWAY-->>ESPNOW-GATEWAY-DAEMON: Send a Data {JSON}
VPN-GATEWAY-->>VPN-GATEWAY: Write in CVS file.
As in many companies it is difficult to obtain access to a WiFi network, although a possibility of install a self owned network it could incurs in a new hardware installation and maintenance.
We use a ESP-NOW, to solve the problem of communications as with this protocol, NO routers are needed.
FALTA !!! y tiene su propio repo (hace Link!!!)
An ESP32 connected to a Computer via USB, via this interface peripheral an API request the measures from sensors. The code gateway should upload to this ESP32.
An ESP32 located in sensors is controlling the peripherals used for data acquisition, this data is store fist in the internal memory and then transmitted to GATEWAY - ESP32, in order to accomplish the requests made by the Computer.
Note that in this protocol does not exits something like MASTER-SLAVE roles, any role mentioned do not escape of the inner scope proyect.
As the ESP-NOW protocol uses a payload up to a 250-byte, data structures are limited to this size. Therefore, if you need to modify this structure make a payload test before implement it. All data structures used to interchange data should have code global scope.
This is the structure in charge of asking for measures.
typedef struct struct_message2 {
byte request; // request needed
}struct_message2;
The request are dealing with binary mask at de sensor-side, clearing bit to bit request, in this way any combination of measure is possible.
Hex | Binary | Request |
---|---|---|
0x00 | b00000000 | The request is clear |
0x01 | b00000001 | Take acceleration data in 3 axis |
0x02 | b00000010 | Send acceleration 3 axis data |
0x04 | b00000100 | Pairing request |
0x08 | b00001000 | |
0x10 | b00010000 | |
0x20 | b00100000 | |
0x40 | b01000000 | Take temperature form ADC |
0x80 | b10000000 | Send temperature |
**Example given: ** From a Gateway ESP32
This is the structure which transport the data, form measures.
typedef struct struct_message {
char id[12]; // Name + identification
byte s2write; // s2write flag
int variable; // Variable to be affected
int tsample, nsamples; // en-lapsed time of the measure ad number of samples
int pos[2]; // Positions to be affected
float datos[50]; // data itself
} struct_message;
This variable
is a pointer to allocate the data in the inner memory of receiver/sender.
Hex | Binary | Variable | Description |
---|---|---|---|
0x0000 | b0000000000000000 | Clear | Indicates that there is not variables to be sent |
0x0001 | b0000000000000001 | accx | Vector points of acceleration in x axis |
0x0002 | b0000000000000010 | accy | Vector points of acceleration in y axis |
0x0004 | b0000000000000100 | accz | Vector points of acceleration in z axis |
0x0008 | b0000000000001000 | temp | Temperature form ADC - termocouple |
0x0010 | b0000000000010000 | MAC Senders | Save a MAC Sender to a caheAddress |
0x0020 | b0000000000100000 | N/A | No assigned |
0x0040 | b0000000001000000 | N/A | No assigned |
0x0080 | b0000000010000000 | N/A | No assigned |
0x0100 | b0000000100000000 | N/A | No assigned |
0x0200 | b0000001000000000 | N/A | No assigned |
0x0400 | b0000010000000000 | N/A | No assigned |
0x0800 | b0000100000000000 | N/A | No assigned |
0x1000 | b0001000000000000 | N/A | No assigned |
0x2000 | b0010000000000000 | N/A | No assigned |
0x4000 | b0100000000000000 | N/A | No assigned |
0x8000 | b1000000000000000 | N/A | No assigned |
Callback functions are register in both peers of the communication, in this case (GATEWAY - SENSOR). This force us to have different callbacks at both peers.
This generic function in placed at both peers sides.
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");
}
As the pay load of a ESP-NOW API is limited, we need to slice the long measures in a 50 dots pack. That is why we use enviopack
function. Note that this wrapper is synchronized with recepack
at the GATEWAY peer side.
void enviopack(float medida[1750], int lon){
int ini;
while( ini <= lon ){
data2send.pos[0] = ini;
data2send.pos[1] = ini + 50;
for(int y = data2send.pos[0]; y < data2send.pos[1]; y++){
data2send.datos[y-ini] = medida[y];
}
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &data2send, sizeof(data2send));
if (result == ESP_OK) {Serial.println("Sending confirmed");
}else {Serial.println("Sending error");
}
delay(10);
ini=ini+50;
}
}
This OnDataOnRecv
function is invoked every time a registered is sending data. At this side (Gateway) is in-charge of register sensor data in a internal memory to be used later.
void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) {
memcpy(&myData, incomingData, sizeof(myData));
if (myData.variable == 0x0001){`
recepack(accx, myData.pos);`
}else if(myData.variable == 0x0002){
recepack(accy, myData.pos);`
}else if(myData.variable == 0x0004){
recepack(accz, myData.pos);
}
}
As we can see the call this callback-function invoke a recepack
function with two parameters (measure, position), these are pointers:
- measure: points to a variable to be affected
- position: points to the positions in the vector to be affected
void recepack(float medida[1750], int ind[2]){
for (int x = ind[0]; x < ind[1]; x++){
medida[x] = myData.datos[x-ind[0]];
}
}
Note that this wrapper is synchronized with enviopack
at the SENSOR peer side.
When the GATEWAY is required by the CAJA_SERVER for a specific measure, a message requesting this information in needed.