sandeepmistry / arduino-LoRa

An Arduino library for sending and receiving data using LoRa radios.
MIT License
1.61k stars 620 forks source link

Can't call a simple MCP23017 i2c relay function from onReceive(int packetSize)? #464

Closed paulrose71 closed 3 years ago

paulrose71 commented 3 years ago

Hi all, I give up!! I can call a simple MCP23017 i2c relay function from within void loop(). And the simple code works within void setup(). But I can't get it to work when calling it from onReceive(int packetSize)? I've looked at everything but can't work it out? Any help would be much appreciated! Thanks in advance. Paul

Here's my sketch......

include // RECEIVER, RECEIVER, RECEIVER.

include

include //iic relay board

include

Adafruit_MCP23017 mcp;

byte localAddress = 0xFF;
byte destination = 0xBB;
String outgoing;
String incoming = "";

void setup() {
Serial.begin(9600); mcp.begin(); // use default address 0 mcp.pinMode(0, OUTPUT); mcp.digitalWrite(0, LOW); delay(1000); mcp.digitalWrite(0, HIGH); delay(1000); mcp.digitalWrite(0, LOW); delay(1000); mcp.digitalWrite(0, HIGH); delay(1000); mcp.digitalWrite(0, LOW); delay(1000);

while (!Serial); Serial.println("Melville Retic - LoRa Receiver Unit"); LoRa.setSPIFrequency(8E6);
LoRa.setPins(10, 9, 2);
if (!LoRa.begin(433E6)) {
Serial.println("Starting LoRa failed!"); while (1); } Serial.println("LoRa init succeeded."); Serial.println(); LoRa.setSyncWord(0x34);
LoRa.setTxPower(20);
LoRa.setSpreadingFactor(11);
LoRa.setSignalBandwidth(250E3);
LoRa.setCodingRate4(5);
LoRa.onReceive(onReceive);
LoRa.receive();

outgoing = "R";
LoRa.beginPacket();
LoRa.write(destination);
LoRa.write(localAddress);
LoRa.write(outgoing.length());
LoRa.print(outgoing);
LoRa.endPacket(); LoRa.receive(); Serial.println("Sent a letter R to clear the LCD screen."); Serial.println("Message: " + outgoing); Serial.println();

}

void loop() {
callTest(); }

void onReceive(int packetSize) { if (packetSize == 0) return;

int recipient = LoRa.read();
byte sender = LoRa.read();
byte incomingLength = LoRa.read();
incoming = "";

while (LoRa.available()) {
incoming += (char)LoRa.read();
}

Serial.println("Received a packet.........."); Serial.println("Packet size: "+(String)packetSize);
Serial.println("Sender: " + String(sender, HEX)); Serial.println("Recipient: " + String(recipient, HEX)); Serial.println("Message length: " + String(incomingLength)); Serial.println("incoming.length: " + String(incoming.length()));
Serial.println("Message: " + incoming); Serial.println("RSSI: " + String(LoRa.packetRssi())); Serial.println("Snr: " + String(LoRa.packetSnr())); Serial.println("Packet frequency error: " + String(LoRa.packetFrequencyError())); Serial.println();

if (incomingLength != incoming.length()) {
Serial.println("error: message length does not match length"); Serial.println("Received from: 0x" + String(sender, HEX)); Serial.println("Corrupt packet"); Serial.println(); return; // skip rest of function }

if (recipient != localAddress && recipient != 0xFF) {
Serial.println("This message is not for me."); Serial.println("Recipient: " + String(recipient, HEX)); return;
}

//callTest();

}

void callTest(){ delay(100); mcp.digitalWrite(0, HIGH); delay(100); mcp.digitalWrite(0, LOW); return; }

IoTThinks commented 3 years ago

You should try the default examples first.

Normally, something is wrong with your own code.

paulrose71 commented 3 years ago

I've tried using the simple default examples. But still it doesn't work?

IoTThinks commented 3 years ago

You need to provide more information. Physical board? Wiring? Which examples? What errors?

"Not working" is not informative.

paulrose71 commented 3 years ago

OK, this is what I've got.....

Hardware: My laptop with Arduino IDE Arduino UNO R3 with a Lora shield on top of it (Dragino, 433MHz), receiver unit Arduino UNO R3 with a Lora shield on top of it (Dragino, 433MHz), transmitter unit, with its keypad and 1.3" OLED. KRIDA Electronics 16 channel solid state i2c relay board (MCP23017), attached to receiver unit

Power: Arduino receiver: USB cable from laptop Arduino transmitter: 12VDC cord from a 240VAC to 12VDC transformer, which is powered from main house supply (240VAC). Relay board: 5VDC supplied from a small converter (24VAC to 5VDC). The converter is supplied from a transformer (240VAC to 24VAC). The transformer is supplied from main house supply (240 VAC).

Receiver end wiring: Lora shield SCL to relay board SCL Lora shield SDA to relay board SDA Lora shield GND to relay board GND Relay board VCC to small converter +DC Relay board GND to small converter -DC

Receiver Lora shield jumpers: Three jumpers at antenna end of shield are off. Three jumpers at opposite end of shield are on the innermost two pins (ie: three lots of three pins, the outermost three pins have air around them, the innermost two pins of each of the three rows are connected with the jumper).

When receiver does work: Simple Lora example sketches alone work fine. Detailed Lora example sketches alone work fine. My own Lora sending and receiving sketches alone work fine. Adafruit MCP23017 example sketches alone for operating relay board work fine. Wolfgang (Wolle) Ewald MCP23017_WE example sketches alone for operating relay board work fine. Simple Lora example sketch with simple MCP23017 example sketch together- when relay board is told to turn on pins from setup() and loop()- work fine.

When receiver doesn't work: Simple Lora example sketch with simple MCP23017 example sketch together- when relay board is told to turn on pins from within Lora.onReceive()- doesn't work. My Arduino freezes mid way through Lora.onReceive(), and never gets to the stage of turning on the relay board pins. It executes to half way through my Lora.onReceive() code. But then stops? Then it doesn't respond to a second (or anymore) incoming signals from my transmitting Lora?

IoTThinks commented 3 years ago

Yes, much clearer now. :)

From your comments, this library works fine for the board. What you say "doesnt work" is actually working as expected.

onReceive() is an ISR. Inside an ISR, "delay" does not works and many things do not work, too. You need to put a flag inside an ISR and process such things outside an ISR.

Of course, this is not relevant to the correctness of this library. Google more what you can not do inside an ISR in Arduino.

IoTThinks commented 3 years ago

It is not relevant too. Why you need "return" at the back of the function?

void callTest(){ delay(100); mcp.digitalWrite(0, HIGH); delay(100); mcp.digitalWrite(0, LOW); return; }

paulrose71 commented 3 years ago

OK, thanks very much. Appreciated! I'll start googling about ISR in Arduino. And what can and can't go inside them? Thanks. Paul

IoTThinks commented 3 years ago

Try to set a flag (volatile boolean variable) inside ISR. And check the flag in the main loop.

And search for "volatile" variable in Arduino, too. The flag needs to be "volatile".

paulrose71 commented 3 years ago

Yep I just read an article on setting a volatile flag. I put it in and my code works! Amazing!!!!! I would never have known that! Much appreciated! Paul