Hello from a newbie,
I am programming a MKR WAN 1310 with a MKR ENV shield and LoRa to create a mobile weather station. For that I need it to send data from time to time, looping forever. It does loop, but only for a random number of times: it starts measuring and everything goes OK (the code does not rise any problems when compiling), but all of a sudden it stops sending data. What is it related to? How can I solve it?
Thank you in advice.
What code?
Welcome to the forum
Please post your sketch, using < CODE/ > tags when you do
#include <SPI.h>
#include <LoRa.h>
#include <Arduino_MKRENV.h>
#include <Arduino_MKRGPS.h>
#include <string.h>
#include <SD.h>
#define PIN_SPI_CS 4
int counter = 0;
int dattime = millis();
String data[9];
File datafile;
void setup() {
Serial.begin(9600);
Serial.println("LoRa Sender. Telemetry Test " + dattime);
if (!LoRa.begin(868E6)) {
Serial.println("Failed to initialize LoRa");
while (1);
}
if (!ENV.begin()) {
Serial.println("Failed to initialize ENV");
while (1);
}
if (!GPS.begin(GPS_MODE_I2C)) {
Serial.println("Failed to initialize GPS");
while(1);
}
if (!SD.begin(PIN_SPI_CS)) {
Serial.println("Failed to connect to the SD card");
while (1);
}
bool ext = 0;
int i = 0;
while (ext == 0) {
String name_of_file = "datafile" + (String)i + ".csv";
if (SD.exists(name_of_file)) {
i++;
}
else if (!SD.exists(name_of_file)) {
datafile = SD.open(name_of_file, FILE_WRITE);
ext = 1;
}
}
datafile = SD.open("datafile.csv", FILE_WRITE);
datafile.println("! " + dattime);
datafile.println("# time,temp,prss,hdty,lght,lat,lon,hght,spd,CRLF");
datafile.close();
}
void loop() {
while (1) {
float proc_time = millis();
// Data taking
data[0] = (millis() - dattime)/1000;
data[0] = (String)data[0];
data[1] = (String)ENV.readTemperature(CELSIUS);
data[2] = (String)ENV.readPressure(MILLIBAR);
data[3] = (String)ENV.readHumidity();
data[4] = (String)ENV.readIlluminance(LUX);
// Position taking
data[5] = (String)GPS.latitude();
data[6] = (String)GPS.longitude();
data[7] = (String)GPS.altitude();
data[8] = (String)GPS.speed();
// Write data to CSV file
String send_data = "" + data[0] + "," + data[1] + "," + data[2] + "," + data[3] + "," + data[4] + "," + data[5] + "," + data[6] + "," + data[7] + "," + data[8] + ",";
datafile = SD.open("datafile.csv", FILE_WRITE);
datafile.println(send_data);
datafile.close();
Serial.println(send_data);
// LoRa Transmission
LoRa.beginPacket();
LoRa.print(send_data);
LoRa.endPacket();
// Integrity check
counter++;
Serial.print("Sending packet: ");
Serial.print(counter);
Serial.print(", done in ");
Serial.println(millis() - proc_time);
while (millis() - proc_time != 1000) {
delay(1);
}
}
}
Sorry I forgot to say that I tried adding the while true to avoid the loop stopping, but it did not work.
Talk us through that.
I need the Arduino to send data each second, so that part of the code stops it until the second has passed
Or forever?
It did work for me as I expected: one data set each second.
Which?
The code sends a data set each second as I wanted it to do. The point is that for no reason it stops sending data. It is as if the Arduino switched off or something like that.
I pretty sure there is a reason.
These things don't happen arbitrarily.
Have you tried some debug prints?
(In case you're wondering, I'm trying not to spoon-feed you)
If the time test for inequality to fails to fail, you get stuck.
The delay(1) makes a rhythm with the while() test, and means you gotta be lucky.
So your runs out. After some success.
Replace the test for inequality with a test for greater than or equal to, or less than or equal to.
You can also lose the delay() call, it is just spinning anyway and it might have made it work a bit better all by itself.
a7
Or keep it, enlarge it, and get rid of the while loop around it...
That was it, now it has sent more than 400 packets. Thank you so much!
@anon56112670 I'm predisposed to not tamper with anything that even looks like it might ever be a good use of millis().
a7
..but not when it is just a delay in a posh frock.
@anon56112670 TBH it was your eye I saw it at all, never occurred to me to notice that it's just a delay.
I did want to see why it was messing things up. Call it peephole optimism.
@ccarl the take away is don't use exact comparisons when you can use an equal to or greater than or more forgiving tests.
Always, even if you "know" something can't happen - you never know what you don't know.
Also, typically since millis() returns an unsigned long, this is the data type of choice for working with it.
float works, but wasn't doing you any favors there.
a7
I tried to leave a trail of hints, but they were missed.
It happens.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.