I have a lora system talking to each other to control a gate out front. What I can't get is when the radio link is working, I would like a led to show that with a led turned on, and when the link is down, the led goes out. Here is what I have so far
unsigned long currentTime = 0;
unsigned long previousLed = 0;
unsigned long workLedInterval = 10000;
void setup() {
Serial.begin(115200); // initialize serial
while (!Serial);
pinMode(workLed, OUTPUT);
digitalWrite(workLed, LOW);
}
void loop() {
sendPacket();
workingLed();
currentTime = millis();
}
//####LORA incoming
void onReceive(int packetSize) {
if (packetSize == 0) {
workState = 0;
return; // if there's no packet, return
}
// read packet header bytes:
String incoming = "";
workState = 1;
etc
}
void workingLed() {
if (workState == 1) {
if (currentTime - previousLed > workLedInterval) {
digitalWrite(workLed, HIGH);
Serial.print("workState = "); Serial.println(workState);
digitalWrite(workLed, workState);
previousLed = currentTime;
}
Serial.print("workState "), Serial.println(workState);
} else if (workState == 0) {
if (currentTime - previousLed > workLedInterval) {
digitalWrite(workLed, LOW);
Serial.print("workState = "); Serial.println(workState);
previousLed = currentTime;
}
}
}
The monitor prints out workState = 1, but the led does not light.
What am I doing wrong?
Without looking at your code, how often does your "link" test itself by sending messages back and forth?
Hello mrmike88
Try this small sketch - check the comments first.
/* BLOCK COMMENT
- This sketch may contain traces of C++.
- In case of indisposition:
- https://www.learncpp.com/
- Hardware:
- Thanks to LarryD
- https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
- https://forum.arduino.cc/t/beginners-software-needs-hardware/1066703
- Tested @ Arduino: Mega[X] - UNO [ ] - Nano [ ]
*/
#define ProjectName "rxLed"
// make structures
struct RXLED
{
byte pin;
unsigned long Interval;
unsigned long stamp;
void begin (const byte LedPin, const unsigned long TimeOut)
{
pin = LedPin;
pinMode (pin, OUTPUT);
Interval = TimeOut;
};
void run(void)
{
if (millis() - stamp >= Interval)
{
stamp = millis();
digitalWrite(pin, LOW);
}
};
void on(void)
{
stamp = millis();
digitalWrite(pin, HIGH);
};
};
RXLED rxLed;
void setup()
{
Serial.begin(115200);
Serial.print(ProjectName), Serial.print(" in "), Serial.println(__FILE__);
// port pin address used - timeout in msec
rxLed.begin(9, 10000);
// call when a new character has been received inside the rx() function
rxLed.on();
}
void loop()
{
// call inside the loop
rxLed.run();
}
I send a message of some time every second
Good. Then if you do not get a response, then the link is broken.
The LED flickers on message receipts
Yes, but I am trying to get an indicator of that. I get a message on the serial monitor to that effect now, just not getting a led indication of that.
Is your LED turned the right way around?
Yes. Even if I change the HIGH and LOW statements, the led flickers. If I program the blink without delay program, the led work as it is supposed to. The led is flickering in response to the incoming message, not staying on.
Well, how long did you program to leave it on? What code turns the LED off?
I assumed the sketch would replace the loop I enclosed. I just inserted this, changing the pin number to a spare pin I had. I have never worked with this type of program, therefore I am confused (nothing all that new).
mrmike88:
void workingLed() {
Do you mean this function? IF so, where in the code did you "call" this function to be executed?
srnet
January 12, 2023, 9:59pm
13
Seems very wasteful.
When the state of the gate needs to be changed, open\closed, send a message that needs an acknowledge, as in a conformation that the gate has received the message, no conformation and you know the links has failed.
Appart from that a keep alive message sent every hour, that also needs and acknowledgement, ought to be plenty.
I tried with and without the else function
void workingLed() {
if (workState == 1) {
if (currentTime - previousLed > workLedInterval) {
//digitalWrite(workLed, HIGH);
//Serial.print("workState = "); Serial.println(workState);
//digitalWrite(workLed, workState);*/
rxLed.run();
previousLed = currentTime;
}
//Serial.print("workState "), Serial.println(workState);
} /*else if (workState == 0) {
if (currentTime - previousLed > workLedInterval) {
digitalWrite(workLed, LOW);
Serial.print("workState = "); Serial.println(workState);
previousLed = currentTime;
}
}*/
}
I will try again,
where in the code did you "call" this function to be executed?
void workingLed() is called from the main void loop() function.
Where is the sendpacket() code?
void sendPacket() {
if (currentTime - lastSendTime > interval) {
if (gateState == 1) {
String message = "1";
sendMessage(message);
// Serial.println("Sending " + message);
} else {
String message = "0";
sendMessage(message);
//Serial.println("Sending " + message);
}
lastSendTime = currentTime; // timestamp the message
}
// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
currentTime = millis();
}
void sendMessage(String outgoing) {
LoRa.beginPacket(); // start packet
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
void onReceive(int packetSize) {
if (packetSize == 0) {
workState = 0;
return; // if there's no packet, return
}
// read packet header bytes:
String incoming = "";
workState = 1;
while (LoRa.available()) {
incoming += (char)LoRa.read();Serial.println(incoming);
}
//Serial.println("Message: " + incoming);
//Serial.println("RSSI: " + String(LoRa.packetRssi()));
//Serial.println("Snr: " + String(LoRa.packetSnr()));
//Serial.println();
int numb = incoming.toInt();
if (numb == 2) {
} else if (numb == 3) {
gateOpen();
} else if (numb == 4) {
gateClosed();
}
}
oid workingLed() {
if (workState == 1) {
if (currentTime - previousLed > workLedInterval) {
//digitalWrite(workLed, HIGH);
//Serial.print("workState = "); Serial.println(workState);
//digitalWrite(workLed, workState);*/
rxLed.run();
previousLed = currentTime;
}
//Serial.print("workState "), Serial.println(workState);
} /*else if (workState == 0) {
if (currentTime - previousLed > workLedInterval) {
digitalWrite(workLed, LOW);
Serial.print("workState = "); Serial.println(workState);
previousLed = currentTime;
}
}*/
}
void gateOpen() {
if (currentTime - openMillis > openInterval) {
digitalWrite(openLed, HIGH);
digitalWrite(closedLed, LOW);
openMillis = currentTime;
Serial.println("open ");//Serial.println(workState);
}
}
void gateClosed() {
if (currentTime - closedMillis > closedInterval) {
digitalWrite(closedLed, HIGH);
digitalWrite(openLed, LOW);
closedMillis = currentTime;Serial.print("close ");
//Serial.println(workState);
}
}
Oh, HOW I hate snippits. Good by.
My apologies, I did not mean to frustrate anyone. I now realize it is easier when you see the whole program.
#include <SPI.h> // include libraries
#include <LoRa.h>
#define csPin 5 // LoRa radio chip select
#define resetPin 14 // LoRa radio reset
#define irqPin 2 // change for your board; must be a hardware interrupt pin
#define pushButton 25
#define workLed 17
#define openLed 4
#define closedLed 16
#define ProjectName "rxLed" //#####
// make structures
struct RXLED
{
byte pin;
unsigned long Interval;
unsigned long stamp;
void begin (const byte LedPin, const unsigned long TimeOut)
{
pin = LedPin;
pinMode (pin, OUTPUT);
Interval = TimeOut;
};
void run(void)
{
if (millis() - stamp >= Interval)
{
stamp = millis();
digitalWrite(pin, HIGH);
}
};
void on(void)
{
stamp = millis();
digitalWrite(pin, LOW);
};
};
RXLED rxLed;
byte msgCount = 0; // count of outgoing messages
int gateState = LOW; // the current state of LED
int button_state; // the current state of button
int workState = 0;
int last_button_state = LOW; // the previous state of button
int reading;
unsigned long currentTime = 0;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
unsigned long buttonMillis = 0;
unsigned long buttonInterval = 5000;
unsigned long previousLed = 0;
unsigned long workLedInterval = 10000;
unsigned long openMillis = 0;
unsigned long openInterval = 4000;
unsigned long closedMillis = 0;
unsigned long closedInterval = 4000;
unsigned long TimerStart = 0;
const unsigned long TimeIntervalY = 3000; // Three Seconds
long lastSendTime = 0; // last send time
int interval = 1200; // interval between sends
String outgoing; // outgoing message
int val;
void setup() {
Serial.begin(115200); // initialize serial
while (!Serial);
Serial.print(ProjectName), Serial.print(" in "), Serial.println(__FILE__);
rxLed.begin(17, 10000);
rxLed.on();
pinMode(workLed, OUTPUT);
//digitalWrite(workLed, LOW);
pinMode(openLed, OUTPUT);
pinMode(closedLed, OUTPUT);
digitalWrite(openLed, LOW);
digitalWrite(closedLed, LOW);
pinMode(pushButton, INPUT);
Serial.println("LoRa Duplex - Set spreading factor");
LoRa.setPins(csPin, resetPin, irqPin); // set CS, reset, IRQ pin
if (!LoRa.begin(915E6)) { // initialize ratio at 915 MHz
Serial.println("LoRa init failed. Check your connections.");
while (true); // if failed, do nothing
}
LoRa.setSpreadingFactor(9); // ranges from 6-12,default 7 see API docs
Serial.println("LoRa init succeeded.");
}
void loop() {
sendPacket();
button_3();
buttonTime();
//workingLed();
currentTime = millis();
}
void button_3() {
reading = digitalRead(pushButton);
if (reading != last_button_state) {
lastDebounceTime = currentTime;
}
if ((currentTime - lastDebounceTime) > debounceDelay) {
if (reading != button_state) {
button_state = reading;
if (button_state == HIGH) {
gateState = !gateState;
}
}
}
//digitalWrite(gateLed, gateState);
last_button_state = reading;
//buttonTime();
}
void buttonTime() {
if (currentTime - buttonMillis > buttonInterval) {
buttonMillis = currentTime;
if (gateState == 1) {
gateState = 0;
}
}
}
/*void workingLed()
{
//if (Z)
TimerStart = millis();
if (TimerStart != 0 && millis() - TimerStart < TimeIntervalY)
{
digitalWrite(workLed, HIGH);
}
else
{
TimerStart = 0;
digitalWrite(workLed, LOW);
}
}*/
void workingLed() {
if (workState == 1) {
if (currentTime - previousLed > workLedInterval) {
//digitalWrite(workLed, HIGH);
//Serial.print("workState = "); Serial.println(workState);
//digitalWrite(workLed, workState);*/
rxLed.run();
previousLed = currentTime;
}
//Serial.print("workState "), Serial.println(workState);
}
}
void gateOpen() {
if (currentTime - openMillis > openInterval) {
digitalWrite(openLed, HIGH);
digitalWrite(closedLed, LOW);
openMillis = currentTime;
Serial.println("open ");//Serial.println(workState);
}
}
void gateClosed() {
if (currentTime - closedMillis > closedInterval) {
digitalWrite(closedLed, HIGH);
digitalWrite(openLed, LOW);
closedMillis = currentTime;Serial.print("close ");
//Serial.println(workState);
}
}
void sendPacket() {
if (currentTime - lastSendTime > interval) {
if (gateState == 1) {
String message = "1";
sendMessage(message);
// Serial.println("Sending " + message);
} else {
String message = "0";
sendMessage(message);
//Serial.println("Sending " + message);
}
lastSendTime = currentTime; // timestamp the message
}
// parse for a packet, and call onReceive with the result:
onReceive(LoRa.parsePacket());
currentTime = millis();
}
void sendMessage(String outgoing) {
LoRa.beginPacket(); // start packet
LoRa.print(outgoing); // add payload
LoRa.endPacket(); // finish packet and send it
msgCount++; // increment message ID
}
void onReceive(int packetSize) {
if (packetSize == 0) {
workState = 0;
rxLed.run();
return; // if there's no packet, return
}
// read packet header bytes:
String incoming = "";
workState = 1;
while (LoRa.available()) {
incoming += (char)LoRa.read();Serial.println(incoming);
}
//Serial.println("Message: " + incoming);
//Serial.println("RSSI: " + String(LoRa.packetRssi()));
//Serial.println("Snr: " + String(LoRa.packetSnr()));
//Serial.println();
int numb = incoming.toInt();
if (numb == 2) {
} else if (numb == 3) {
gateOpen();
} else if (numb == 4) {
gateClosed();
}
}