matthijskooijman / arduino-lmic

:warning: This library is deprecated, see the README for alternatives.
705 stars 651 forks source link

Custom Loop Possible? #204

Open idevwebs opened 5 years ago

idevwebs commented 5 years ago

Hello, I've used this library for my sensor node, but I would like to know if it is possible to take control of the loop? What I'm trying to achieve is is something like this:

loop() {
readsensor

if sensor data matches condition A, transmit=false; // no send
if sensor data matches condition B, transmit=true; when=now; // send immediate
if sensor data matches condition C, transmit=true; when=30min;

if transmit==true

schedule transmission with $data in $when time ... do_send/sendjob

then transmit=false
delay(1)
}

Is this possible? I am very new to arduino/c coding (coming from web) so if this is doable any examples would be very much appreciated.

Thank you.

cyberman54 commented 5 years ago

If you're on a single core system, without RTos, you may use the lmic scheduler to execute your sensor read & send job, using lmic functions:

os_setCallback (osjob_t* job, osjobcb_t cb)
os_setTimedCallback (osjob_t* job, ostime_t time, osjobcb_t cb)

If you're on a multitasking system, e.g. a ESP32 with 2 cores, you may put your sensor job in a separate task which is controlled by the RTos.

idevwebs commented 5 years ago

This is on lora32u4 board. The issue I am wondering about is doesn't this library impose a min time like 15sec?

matthijskooijman commented 5 years ago

You can just not use the entire osjob stuff. It's just a basic scheduler that LMIC needs for internal scheduling and is exposed to the sketch. It would be good if there was an example that does not use the scheduling...

In any case, you can just do your own scheduling using millis() or whatever you want, and use the transmit functions from the loop (e.g. LMIC_setTxData()) to transmit a packet ASAP. You'll also have to do your own "in 30 minutes" scheduling, though. You can use the events (e.g. EV_TXCOMPLETE) to detect when a transmission has completed.

The issue I am wondering about is doesn't this library impose a min time like 15sec?

The library adheres to the duty cycle limits, so if it is not allowed to transmit, a packet is queued until airtime is available. This means LMIC_setTxData() does not transmit immediately, but ASAP. Note that this is only about EU duty cycle limits, but when using TTN, you additionally need to comply with the TTN fair access policy.

idevwebs commented 5 years ago

@matthijskooijman

Thank you for taking the time to reply with the information. There's some good to know. Unfortunately, I'm not familiar enough at this point to accomplish a without scheduling using this library. I wish I was! Any idea when a no scheduling example might be added? Or even some pseudocode?

Jeroen88 commented 5 years ago

Take the example ttn-otaa.ino and just remove the call to do_send(&sendjob) in line 168 and os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send) in line 115

Call do_send(&sendjob) whenever you want to schedule it. Beware though, it is not sent inmediately but as soon as possible, taking into account the duty cycle. Also beware that when you send a job while another unfinished job is still pending, the new job overwrites the old one. If you want to know that your job has finished, use the EV_TXCOMPLETE event starting at line 115