LoRa.endpacket() freezes for simple data transmitting
Hello Sandeep, I have written a simple code to send data using two NodeMCU and two LoRa Ra-02 modules. My purpose is to control the sending data with a client (using Hercules software to connect) and show it on the other NodeMCU serial monitor. For instance, if I send 'a' in Hercules, the sender must send the message: "Toggle switch is off" through Lora and the receiver must print is. Also, sending 'b' would mean toggle switch in on.
The problem occurs when I try to send the packets in the while loop used for receiving data from the client. To be more specific, it hangs when it reaches LoRa.endpacket(); - nothing showed afterward in the receiver serial monitor even when I disconnect the client.
I've read about other similar issues but mine was a different situation so I couldn't relate. I also do not know how to attach any capacitor for power controling. (anyone can help with that if it's helpful?)
ps1. I attached my sender and my receiver code down below. ps2. I am not using any antenna. ps3. I also attach my hardware picture. (sender and receiver are the same) issue1.zip
Nothing super stands out but I have a couple suggestions (and a warning....) First, it's a bad idea to not use an antenna, the datasheet warns this can cause damage to the device.
In the code I noticed you have this LoRa.endPacket() call at the end of your loop, this could be prematurely clearing the TX_DONE flag causing the real endPacket() calls to loop forever. Try removing that and see if it helps.
About start_stop_sender.ino:
- As @morganrallen says, you have a spurious
endPacket()at the end of the code that doesn't serve any purpose. It could be even messing up with the chip's settings, as it puts it in Tx mode and clears IRQs. - Your delays for the LED blinks are way too short. 30, 40, 50 milliseconds is literally a blink of an eye. Consider making them longer. Add a zero. Oh and the
for (int i = 0; i < 2; i++) {part will blink the LED twice, not 3 times. - The double
whileis superfluous. The second one,while (client.available()) {is enough for your purposes. Which makes theif (server.hasClient()) {part unneeded. - I don't think the
delay(4000);are needed here. You seem to be sending small packets at the default BW/SF settings. Your airtime is going to be negligible. Probably around a millisecond. OTOH, you can't be sure what these parameters are now, so you could make sure by setting them insetup(), just to be sure they are what you want. I have seen SX1276/8 chips freeze because of incorrect SF/BW settings. - Again, as @morganrallen says, DO NOT USE A LORA CHIP WITHOUT AN ANTENNA. You are going to fry it. Get yourself a spiral antenna. Doesn't look like you can solder a wire antenna on this one.
About start_stop_receiver.ino
You commented out the code in loop() but I uncommented it and had a look at it:
if (packetSize) {
Serial.print("Receiving Data: ");
while (LoRa.available()) {
String data = LoRa.readString();
Serial.println(data);
for (int i = 0; i < packetSize; i++) {
Serial.print((char)LoRa.read());
}
}
}
This won't work. You are trying to read the packet twice: once with String data = LoRa.readString(); and a second time with the LoRa.read() loop. Drop the String data = LoRa.readString(); it is not a great idea. Rather, keep your read loop, and instead of printing it char by char, store it in a buffer and print it when done. Eg:
char msgBuf[256];
memset(msgBuf, 0x00, 256);
int ix = 0;
while (LoRa.available()) {
char c = (char)LoRa.read();
msgBuf[ix++] = c;
}
Serial.println(msgBuf);
This way, later on, when your code base grows, you could enhance things by adding filters (removing characters you don't want), process the line for commands before display, etc.
@morganrallen Thank you for your response. I recently bought an antenna and I'll try again with that and another code to see how it'll change.
@Kongduino Wow thank you for your thorough answer.
I must read more about Tx/Rx mode of LoRa modul and also the clearance of IRQ as you mentioned. (any helpful links?)
I still don't know how to send packets in this code and moreover, where to put the endpacket().
As for the part 3, I tried to remove while() loop, but the connection of the client would've stopped (didn't understand why.) In the Hercules monitor, after one loop the connection would've stopped. I realized maybe the 2nd loop is required to keep the connection on going.
For the receiver, you're absolutely right. I'll remove that part.
My final purpose is to connect this modules to a LabView project (which here I replaced it with Hercules software as my client) and to send some simple data through LoRa module. I'd appreciate for any further recommendations or links.
Your LoRa.endPacket(); should come right after LoRa.print(off_lora); – that's the part that will actually send the packet. LoRa.print() just buffers the data to send until you're ready (so you can have several LoRa.print() statements in a row).
The LoRa.endPacket(); at the end of the loop() should be deleted.
Both while()are actually unneeded. The while(1) is essentially what loop() does. Here is a rewrite of the code, streamlined and making more sense:
#include <ESP8266WiFi.h>
#include <LoRa.h>
#define SERVER_PORT 8000 // Set the port used here is 8000. Set to match both NodeMCU and LabVIEW.
const char* ssid = "Helia"; // The name of the WiFi band that will allow NodeMCU to login.
const char* password = "helia1111"; // Enter the password of the WiFi band that will allow NodeMCU to login.
#define SS 15
#define RST 16
#define DIO0 2
WiFiServer server(SERVER_PORT); // Create an object named server and define a port which uses 8000.
String off_lora = " Toggle switch is off";
String on_lora = " Toggle switch started!";
void setup() {
pinMode(16, OUTPUT); // Assign Pin 16 Output to be LED display on NodeMCU.
Serial.begin(9600); // Enable Serial Communication
Serial.println("");
Serial.println("");
WiFi.begin(ssid, password); // Login in WiFi with the name and password given above.
while (WiFi.status() != WL_CONNECTED) {
// Wait for Login where Serial Monitor will show -> Run until login is successful.
Serial.print("->\n");
delay(200);
}
Serial.println("");
Serial.println("WiFi Successfully Connected"); // Show message when login to WiFi band successfully.
Serial.print("NodeMCU IP address: ");
Serial.println(WiFi.localIP()); // Displays the IP address that the NodeMCU receives from the WiFi Router.
server.begin(); // Start TCP as NodeMCU as Server and LabVIEW as Client.
Serial.println("NodeMCU as a Server Role Started"); // start working
for (int i = 0; i < 25; i++) {
// If connected successfully, you will see a blinking light that NodeMCU uses to see the status when NodeMCU is not connected to Computer.
digitalWrite(16, HIGH);
delay(40);
digitalWrite(16, LOW);
delay(40);
}
Serial.println("Sender Host");
LoRa.setPins(SS, RST, DIO0);
if (!LoRa.begin(433E6)) {
Serial.println("LoRa Error");
delay(100);
while (1);
}
}
void loop() {
WiFiClient client = server.available(); // Wait to connect to Hercules as a client.
if (!client) return;
// If LabVIEW is contacted as a Client, the if statement is true.
while (!client.available()) {
delay(10); // wait until the connection has been established
}
Serial.println("Hi... New Client");
// Display a welcome message to the Client at Serial Communication.
for (int i = 0; i < 2; i++) {
// will see LED blinking at NodeMCU 3 times to see status when NodeMCU is not connected to Computer
digitalWrite(16, HIGH);
delay(250);
digitalWrite(16, LOW);
delay(250);
}
// Check the data sent from client. If there is data sent, it will be done in the loop.
digitalWrite(16, HIGH); // When data is sent, the LED on the NodeMCU will flash (lit and off).
delay(250);
uint8_t data = client.read(); // read the information sent
Serial.write(data); // Displays the received data via Serial Communication.
Serial.print(" is \n");
client.flush(); // get rid of any other incoming characters
switch (data) {
// Take the data variable to check.
case 'a':
Serial.println("Sending that toggle is off:");
LoRa.beginPacket();
LoRa.print(off_lora);
LoRa.endPacket();
break;
case 'b':
Serial.println("Sending that toggle has started:");
LoRa.beginPacket();
LoRa.print(on_lora);
LoRa.endPacket();
break;
}
digitalWrite(16, LOW);
// client goes out of scope. You're ready for another round.
}
Now whether sending works or not, that's something you'll have to check – but at least now you should have a sketch that functions as intended.