Closed Wirux closed 4 years ago
You're using Serial.print from interrupt service routine setFlag
- that's a bad idea, Serial needs interrupts to work, so calling it from interrupt context can and will break things.
Next, as is written in the SX127x_Receive_Interrupt example:
When you call lora.readData()
, the module will be set to standby mode to read the received data. You have to call lora.startReceive()
again after that to re-enable Rx mode.
Thank you for respond My code now is working fine :) If you have some suggestions on how to improve him I will be grateful
I'm not sure if I correct know how "void setFlag(void)" works This function will be called when:
Great work :) Working code:
// include the libraries
#include <RadioLib.h>
// declared byteArrs
byte byteArrTran[18];
byte byteArrRec[18];
// declared device ID and preset mode
byte deviceAddress = 11;
char selectMode = 'T';
// declared object LoRa
SX1278 lora = new Module(10, 2, 9, 3);
// declared variables states of communication
int tranState = ERR_NONE;
int recState = ERR_NONE;
// declared interrupts flags
volatile bool enableInterrupt = true;
volatile bool endFlag = true;
void setup()
{
Serial.begin(9600);
// set at start 0x00 every byte in arrays
for (int i = 0; i < 18; i++)
byteArrTran[i] = 0;
for (int i = 0; i < 18; i++)
byteArrRec[i] = 0;
// initialize SX1278 with default settings
Serial.print(F("[SX1278] Initializing ... "));
// start LoRa
int state = lora.begin();
if (state == ERR_NONE)
{
Serial.println(F("success!"));
}
else
{
Serial.print(F("failed, code "));
Serial.println(state);
while (true)
;
}
// set the function that will be called interrupt
lora.setDio0Action(setFlag);
}
// interrupts function
void setFlag(void)
{
if (!enableInterrupt)
{
return;
}
// we sent or get a packet, set the flag
endFlag = true;
}
void transmit()
{
// reset flags
enableInterrupt = false;
endFlag = false;
// the print sending byte array
Serial.print(F("[SX1278] Sending byteArrTran: "));
for (int i = 0; i < 18; i++)
{
Serial.print(byteArrTran[i]);
Serial.print(" ");
}
Serial.println();
// send printed byte array
// need to use start Transmit because this function give us interrupt
tranState = lora.startTransmit(byteArrTran, 18);
// enable the interrupt
enableInterrupt = true;
// check transmission
if (tranState == ERR_NONE)
{
// packet was successfully sent
Serial.println(F("transmission finished!"));
}
else
{
Serial.print(F("failed, code "));
Serial.println(tranState);
}
// wait a second before transmitting again
}
void receive()
{
// reset flags
enableInterrupt = false;
// clear byteArr
for (int i = 0; i < 18; i++)
byteArrRec[i] = 0;
// read incomming data
recState = lora.readData(byteArrRec, 18);
if (recState == ERR_NONE)
{
// packet was successfully received
Serial.println(F("[SX1278] Received packet!"));
Serial.print(F("[SX1278] Data:\t\t"));
for (int i = 0; i < 18; i++)
{
Serial.print(byteArrRec[i]);
Serial.print(" ");
}
Serial.println();
}
else if (recState == ERR_CRC_MISMATCH)
{
// packet was received, but is malformed
Serial.println(F("[SX1278] CRC error!"));
}
else
{
// some other error occurred
Serial.print(F("[SX1278] Failed, code "));
Serial.println(recState);
}
// enable the interrupt
enableInterrupt = true;
}
// random numbers in byteArr for tests
void randomAll()
{
for (int i = 0; i < 18; i++)
byteArrTran[i] = random(0, 200);
}
void loop()
{
switch (selectMode)
{
case 'O':
Serial.println("Init");
selectMode = 'T';
break;
case 'T':
if (endFlag)
{
Serial.println("Transmit");
randomAll();
transmit();
delay(1000);
selectMode = 'r'; // go to start listen mode
}
break;
// use this mode to start to listen to incoming data
case 'r':
recState = lora.startReceive();
endFlag = false; // change endFlag to false
delay(500); // this flag will be changed for true
selectMode = 'R'; // when incoming packet will be detected
break;
// we started listen mode, wait for a packet
case 'R':
if (endFlag)
{
Serial.println("Received");
receive();
delay(2000);
selectMode = 'T';
}
break;
}
}
Regarding setFlag(): that funcion is an ISR - interrupt service routine. The purpose is to quickly execute some short piece of code when triggered by an interrupt. ISRs aren't called - the processor "jumps" to them when some interrupt is triggered.
In the context of SX1278, when the Arduino sees a rising edge on its external interrupt 0 (pin 2, which is connected to SX1278's DIO0), it will jump to that function, execute it, and then jump back to where it was before the interrupt. Therefore, setFlag()
isn't called after startTransmit(), startReceive() or any other function, rather it will be executed whenever there's a rising edge on Arduino pin D2.
Hello I am starting to work with the SX1272 transceiver with the use of this library, by using the example SX127x_Receive_Interrupt.ino to use the interrupt in DIO0 everything works correctly, but my goal is that the microcontroller is in low power consumption and that interruption will wake up, if I add the lines of code that sleep to the microcontroller and test it, yes it wakes up but I have a very high current consumption, since my idea is to use CR2032 batteries so afterwards I tried to put the SX1272 into sleep mode, but at doing this the DIO0 signal stops appearing as I use an oscilloscope to check the pin. So my question is whether the interrupt used in DIO0 and configured with setDio0Action () only works if the SX1272 is in transmit or receive mode?
@Kyck-02 This is off-topic for this issue. In short, if you put the SX127x chip to sleep mode, it will stop it from receiving data (or doing anything else for that matter). I suggest checking different sleep modes of your microcontroller, using different power source, or having some RTC to periodically wake up the SX127x radio and have short receive windows.
I appreciate your answer, I am sorry I used this problem to ask my question.
Hi, I want to have two-ways communication in my LoRa device, but I can't create a working sketch using interrupts Dio0, have someone sketch with these functions? What I want to do is toggle mode between transmit and receive Simple flow chart
My sketch
SerialPort
As you can see, the transmit work correct, but after receiving the packet from B device endFlag isn't set as true. Device B right now have an example transmit sketch with interrupts. (all time print 0)