I created a camera system using a Raspberry Pi using the circular buffer feature. Then I have an ESP-32 board that reads the light of a stack light in order to send the paired ESP-32 board attached to the Pi to record the last however many seconds of video captured. I have a current problem that if the stack was not solid but flashing, it would send the capture signal everytime it flashed. I am trying to make it to where it can read if the input is high for a specified time (3 seconds or so) and then send the capture signal only once. Then maybe resets after the state of the stack light input is no longer on. I have tried the code below but the time being printed in the serial monitor is very odd. It is not really counting up and then also, when I turn the input off, the time is not zero'd out.
#include <esp_now.h>
#include <WiFi.h>
const int sensorPin = 4;
int val = 0;
boolean counting;
unsigned long starttime; //some global variables available anywhere in the program
unsigned long total_time;
unsigned long elapsed_time;
// REPLACE WITH YOUR RECEIVER MAC Address
uint8_t broadcastAddress[] = {0x9C, 0x9C, 0x1F, 0xC9, 0x58, 0x84};
// Structure example to send data
// Must match the receiver structure
typedef struct struct_message {
char a[32];
} struct_message;
// Create a struct_message called myData
struct_message myData;
// callback when data is sent
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");
}
void setup() {
// Init Serial Monitor
Serial.begin(115200);
pinMode(sensorPin, INPUT_PULLUP);
// Set device as a Wi-Fi Station
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
counting = false;
starttime = millis();
// 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_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
}
void loop() {
// Set values to send
val = digitalRead(sensorPin);
if (val == 0 && counting==false) {
starttime = millis();
counting = true;
}
if (val == 0 && counting==true) {
counting = false;
elapsed_time = millis()- starttime;
total_time = total_time + elapsed_time;
Serial.println(total_time);
elapsed_time = 0;
}
if (val == 1 && elapsed_time > 3) {
strcpy(myData.a, "Now");
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
}
//delay(3000);
}
One obvious problem I see is that the only time you set elapsed_time you reset it to 0 a few lines later. Therefore the following conditional will NEVER be true:
Try this. I can't compile or test. The idea is that every time the sensor transitions from LOW to HIGH the timer is re-started. If the the signal remains HIGH and the timer exceeds 3 seconds then the capture signal is sent. While the signal is LOW nothing happens. If the signal were to go HIGH for less than 3 seconds and then go LOW it would never send the capture signal.
void loop()
{
// I am trying to make it to where it can read if the input is high for a specified time (3 seconds or so)
// and then send the capture signal only once. Then maybe resets after the state of the stack light input
// is no longer on.
static int sensorLastVal = digitalRead(sensorPin);
int sensorVal = digitalRead(sensorPin);
// Check to see if sensor value has changed
if (sensorVal != sensorLastVal)
{
sensorLastVal = sensorVal;
if (sensorVal == HIGH)
{
// Sensor is triggered so start the timer
starttime = millis();
}
}
if (sensorVal == HIGH && millis() - starttime > 3000)
{
strcpy(myData.a, "Now");
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
sent = true;
}
}
This seems to work other than once the time has exceeded the three seconds, it repeatedly sends the message. Is that where your sent = true; was going to come in? Thanks for the help by the way.
This what happens when you code quickly and can't test!
void loop()
{
// I am trying to make it to where it can read if the input is high for a specified time (3 seconds or so)
// and then send the capture signal only once. Then maybe resets after the state of the stack light input
// is no longer on.
static bool sent = false;
static int sensorLastVal = digitalRead(sensorPin);
int sensorVal = digitalRead(sensorPin);
// Check to see if sensor value has changed
if (sensorVal != sensorLastVal)
{
sensorLastVal = sensorVal;
if (sensorVal == HIGH)
{
// Sensor is triggered so start the timer
sent = false;
starttime = millis();
}
}
if (sensorVal == HIGH && !sent && millis() - starttime > 3)
{
strcpy(myData.a, "Now");
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK)
{
Serial.println("Sent with success");
sent = true;
}
}
}
Yeah I think I figured it out before. It is similar to what you have here. Thanks again!! FYI I put the bool sent = false at the very beginning so it works either way I guess.
void loop() {
// Set values to send
//val = digitalRead(sensorPin);
static int sensorLastVal = digitalRead(sensorPin);
int sensorVal = digitalRead(sensorPin);
// Check to see if sensor value has changed
if (sensorVal != sensorLastVal)
{
sensorLastVal = sensorVal;
sent = false;
if (sensorVal == LOW)
{
// Sensor is triggered so start the timer
starttime = millis();
}
}
if (sensorVal == LOW && (sent == false) && millis() - starttime > 3000)
{
strcpy(myData.a, "Now");
sent = true;
// Send message via ESP-NOW
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
}
}