New developement.
Setting up the two Wemos units I currently have to talk to each other.
Each has an external LED & a sensor attached,
one is a PIR & the other is a vibration sensor.
We will not be including the vibration sensor in the code at this point.
Same for the LED in the transmitter, both are null but I have still declared the LED in this transmitter code for later on as a power indicator.
The Goal - to set off the PIR in one unit (transmitter) & make the LED flash in the recieving unit.
So I set about copying & modifying some code to make it happen.
This is where I'm at ATM with the transmitter unit.
#include <ESP8266WiFi.h>
#include <espnow.h>
uint8_t receiverMac[] = {"c8:c9:a3:14:5c:f5"}; // CHANGE THIS
const int PIRPin = D2;
const int LEDPin = D6;
int motionStatus = 0;
int PIRState = 0;
void setup() {
pinMode(PIRPin, INPUT);
WiFi.mode(WIFI_STA);
Serial.begin (9600);
if (esp_now_init() != 0) {
Serial.println("ESP-NOW init failed");
return;
}
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
esp_now_add_peer(receiverMac, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop() {
uint8_t value = digitalRead(PIRPin);
if (PIRPin == 1);
esp_now_send ("Motion detected"); //Error here somewhere
Serial.println ("Motion detected");
delay(50);
}
I'm getting this error message that I dont understand
Compilation error: invalid conversion from 'const char*' to 'u8*' {aka 'unsigned char*'} [-fpermissive]
What the hell is a char?
I wasnt planning on a BBQ?
In this sketch, the error is in the sketch_feb8a.ino file, on line 4 column 3, where "x" is used, but not previously declared.
C:\Users\user\AppData\Local\Temp\.arduinoIDE-unsaved202618-16224-172ufjt.78mo\sketch_feb8a\sketch_feb8a.ino: In function 'void setup()':
C:\Users\user\AppData\Local\Temp\.arduinoIDE-unsaved202618-16224-172ufjt.78mo\sketch_feb8a\sketch_feb8a.ino:4:3: error: 'x' was not declared in this scope
x=1;
^
exit status 1
Compilation error: 'x' was not declared in this scope
It sets up a couple of variables here.
The id is obvious.
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
int id;
int x;
int y;
} struct_message;
// Create a struct_message called test to store variables to be sent
struct_message myData;
Variables shown as X & Y
I have only one variable to be sent - Sensor = HIGH/LOW.
Does this mean I should remove the ( int y; ) variable?
The only function it has to transmit is the PIRState.
Using a struct to hold the data is useful when you want to send multiple variables, even variables of different types, but if you want to send only a single value then the struct is not required. Simple send that variable.
If you want to make as few changes to the example code as possible then you can still use a struct by deleting any unused variables from it at both ends of the link
If you want more help then please post the full sketches here, using code tags when you do
Current code, compiling without error (so far)
Ive changed a couple of variables, added in my pinmodes for the PIR & LED indicator light with the digitalWrite for this at the end.
Added in a few Questions in areas Im still unsure of ATM.
Board 1 Sender
#include <ESP8266WiFi.h>
#include <espnow.h>
// REPLACE WITH RECEIVER MAC Address
uint8_t broadcastAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //Do not have this board yet.
// Set your Board ID (ESP32 Sender #1 = BOARD_ID 1, ESP32 Sender #2 = BOARD_ID 2, etc)
#define BOARD_ID 1
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
int id;
int x;
int y; // Remove this line?
} struct_message;
// Create a struct_message called test to store variables to be sent
struct_message myData;
unsigned long lastTime = 0;
unsigned long timerDelay = 10000;
const int PIRPin = D2;
const int LEDPin = D6;
// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus) {
Serial.print("\r\nLast Packet Send Status: ");
if (sendStatus == 0){
Serial.println("Delivery success");
}
else{
Serial.println("Delivery fail");
}
}
void setup() {
// Init Serial Monitor
Serial.begin(9600);
pinMode(D2, INPUT); // Captures signal from the PIR sensor
pinMode(D6, OUTPUT); //LED output for the "power on" indicator LED
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Init ESP-NOW
if (esp_now_init() != 0) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Set ESP-NOW role
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
// 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
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop() {
//Should there be a digitalRead line here - digitalRead (PIRPin)?
if ((millis() - lastTime) > timerDelay)
//Should there be a "PIRPin == HIGH" command line here?
{
// Set values to send
myData.id = BOARD_ID;
myData.x = random(1, 50); //Is this similar to a didgitaWrite line? Should this be "mydata.x = PIRState"
myData.y = random(1, 50); // Do I remove this one?
// Send message via ESP-NOW
esp_now_send(0, (uint8_t *) &myData, sizeof(myData));
lastTime = millis();
}
{ digitalWrite(D6, HIGH); // turn the LED on (HIGH is the voltage level)
delay(500); // wait for a half second
digitalWrite(D6, LOW); // turn the LED off by making the voltage LOW
delay(2000); // wait for 2 seconds}
}
}
In order to answer the questions in your code please explain what you want to transmit and what triggers the transmission
I assume that you want to transmit something to indicate that the PIR has been triggered rather than constantly transmitting the PIR state. Is that correct ?
Yes.
If I were to do it as if it were hard wired to a UNO or similar, I would be picking up the digitalRead from the PIR sensor & using that as a digitalWrite on the slave board.
In laymans terms -
If
PIR = HIGH
Send
Else
Do nothing.
(excluding the LED power Indicator which is just a constant Loop, locally. ie not sent over the WiFi)
Here is a version of the code with minimal changes that still uses a struct even though there is only a single data item. I cannot test it but it compiles OK
#include <ESP8266WiFi.h>
#include <espnow.h>
// REPLACE WITH RECEIVER MAC Address
uint8_t broadcastAddress[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; //Do not have this board yet.
// Set your Board ID (ESP32 Sender #1 = BOARD_ID 1, ESP32 Sender #2 = BOARD_ID 2, etc)
#define BOARD_ID 1
// Structure example to send data
// Must match the receiver structure
struct struct_message
{
int PIRState;
} message;
// Create a struct_message called test to store variables to be sent
struct_message myData;
unsigned long lastTime = 0;
unsigned long timerDelay = 10000;
const int PIRPin = D2;
const int LEDPin = D6;
// Callback when data is sent
void OnDataSent(uint8_t *mac_addr, uint8_t sendStatus)
{
Serial.print("\r\nLast Packet Send Status: ");
if (sendStatus == 0)
{
Serial.println("Delivery success");
}
else
{
Serial.println("Delivery fail");
}
}
void setup()
{
// Init Serial Monitor
Serial.begin(9600);
pinMode(D2, INPUT); // Captures signal from the PIR sensor
pinMode(D6, OUTPUT); //LED output for the "power on" indicator LED
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
WiFi.disconnect();
// Init ESP-NOW
if (esp_now_init() != 0)
{
Serial.println("Error initializing ESP-NOW");
return;
}
// Set ESP-NOW role
esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER);
// 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
esp_now_add_peer(broadcastAddress, ESP_NOW_ROLE_SLAVE, 1, NULL, 0);
}
void loop()
{
static byte prevPirState = LOW;
byte currentPirState = digitalRead(PIRPin); //get current PIR state
if (currentPirState != prevPirState && currentPirState == HIGH) //PIR state has changed and become triggered
{
message.PIRState = currentPirState;
esp_now_send(0, (uint8_t *)&message, sizeof(message));
}
prevPirState = currentPirState;
}
Obviously you need to make corresponding changes to the receiver code to match the data being sent
As I said before, for a single data item you do not need to use a struct but maybe try this first
Thx, & yeah, Id like to simplify it as much as possible but I'll come back to that once I/we have it working.
So we are reading the state change & only sending once it changes from Low to High.
Then the message to be sent is the current state which should show up at the other end as "HIGH"
Then the last bit - "prevPirState = currentPirState;" Shuts it down again, yeah?
I did look at the reciever code earlier & begin to add in my variables.......Holy Crap! That one is going to be a challenge.
Two Masters into the one slave, & the slave is going to have to assign different tracks on an Mp3 player depending on which master it is recieving from.
Anyway, Thx for your help thus far, it has been very helpful after a fortnight tearing my hair out with misguided info prior.
No. The message struct has an int variable named PIRState so what you will get at the receiver is an int variable with a value of 1 when the PIR becomes triggered. This is much easier to detect than a string
Nothing is actually shut down as such. By setting the prevPirState to the current state we are preventing detection of the PIR being triggered until it happens again
The reason that I queried your previous statement about what was received was because you said that it would be "HIGH", which to me is a string, not an integer, and I didn't want there to be any confusion