4

PostSep 03, 2019#11

Hi,

Could you say what Arduino pins the RFM95 pins DIO1 and DIO2 are connected to?

Thanks.

1885
1885

PostDec 08, 2019#12

Just an update if someone is interested in the details how to connect the Whisper Node to the TTN using the TinyLoRa library: https://wisen.com.au/blog/whisper-node- ... n-gateway/

5

PostMar 05, 2021#13

kizniche wrote:
Apr 08, 2019
Upon further testing, I discovered if I remove my sensor code, the sketch runs as expected, and does not reset and run setup() after waking. This was likely due to the large size of the code. I'll report back if I uncover anything else of note.
Hi, I have a similar Problem with the TinyLora Lib and a MPU9250 sensor. were you able to solve the problem?

10

PostSep 26, 2023#14

kizniche wrote:
Apr 08, 2019
I, too, am having the exact same problem as j77swiss. I am running the LoRa Whisper Node with 2xAA batteries, arduino-lmic (https://github.com/mcci-catena/arduino-lmic), and LowPower (https://github.com/LowPowerLab/LowPower). I can confirm only the first transmission is making it to The Things Network (TTN) using ABP.

Powering via USB works for all transmissions, but I had two observations:

1. When the device emerges from sleep, it executes setup() again before entering loop(). I know this because "Starting" is printed.
2. The frame counter that appears on TTN stays at 0.
3. From this, I deduce it's not merely emerging from sleep and continuing in loop(), but appears to be resetting itself.

This is my code:

Code: Select all

/*******************************************************************************
 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 * Copyright (c) 2018 Terry Moore, MCCI
 * Copyright (c) 2019 Kyle T. Gabriel
 *
 * Permission is hereby granted, free of charge, to anyone
 * obtaining a copy of this document and accompanying files,
 * to do whatever they want with them without any restriction,
 * including, but not limited to, copying, modification and redistribution.
 * NO WARRANTY OF ANY KIND IS PROVIDED.
 *******************************************************************************/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_HTU21DF.h>
#include <LowPower.h>
#include <SparkFunTSL2561.h>
#include <T2WhisperNode.h>
#include "Arduino.h"

// Enable (true) or disable (false) Serial
#define DEBUG true

// NPN transistor to power sensors
#define SENSOR_PWR_PIN 4

// Schedule measuring voltage
#define MEASURE_VOLTAGE_INTERVAL 21600  // 21600 seconds = 6 hours

// Schedule TX period (seconds)
#define TX_INTERVAL 600  // 600 seconds = 10 minutes

// LoRaWAN NwkSKey, network session key
static const PROGMEM u1_t NWKSKEY[16] = { REPLACE };
// LoRaWAN AppSKey, application session key
static const u1_t PROGMEM APPSKEY[16] = { REPLACE };
// LoRaWAN end-device address (DevAddr)
static const u4_t DEVADDR = 0x00000000;

T2Flash myFlash;
Adafruit_HTU21DF htu = Adafruit_HTU21DF();
SFE_TSL2561 light;

#define Serial if (DEBUG) Serial 

// Counts how many transmissions to determine when to measure battery voltage
uint8_t TX_COUNT = 255;

// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in arduino-lmic/project_config/lmic_project_config.h,
// otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }

byte TX_COMPLETE = 0;
static uint8_t payload[8];
static osjob_t sendjob;

// Pin mapping
const lmic_pinmap lmic_pins = {
  .nss = 10,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = LMIC_UNUSED_PIN,
  .dio = {2, A2, LMIC_UNUSED_PIN},
};

void onEvent (ev_t ev) {
//    Serial.print(os_getTime());
//    Serial.print(": ");
    switch(ev) {
        case EV_TXSTART:
            Serial.println(F("EV_TXSTART"));
            break;
        case EV_TXCOMPLETE:
            Serial.println(F("EV_TXCOMPLETE"));
            if (LMIC.txrxFlags & TXRX_ACK)
              Serial.println(F("Received ack"));
            if (LMIC.dataLen) {
              Serial.println(F("Received "));
              Serial.println(LMIC.dataLen);
              Serial.println(F(" bytes payload"));
            }
            TX_COMPLETE = 1;
            break;
        case EV_LOST_TSYNC:
        case EV_RESET:
        case EV_RXCOMPLETE:
        case EV_LINK_DEAD:
        case EV_LINK_ALIVE:
        case EV_SCAN_TIMEOUT:
        case EV_BEACON_FOUND:
        case EV_BEACON_MISSED:
        case EV_BEACON_TRACKED:
        case EV_JOINING:
        case EV_JOINED:
        case EV_JOIN_FAILED:
        case EV_REJOIN_FAILED:
        default:
            break;
    }
}

double get_lux(unsigned char time) {
    boolean gain = 0;
    unsigned int ms;
    light.setTiming(gain, time, ms);
    Serial.print("TSLup: "); Serial.println(light.setPowerUp());
    delay(ms);  // Pause to measure light
    unsigned int data0, data1;
    uint8_t data_good = light.getData(data0, data1);
    Serial.print("TSLdn: "); Serial.println(light.setPowerDown());
    if (data_good) {
        double lux;
        boolean good;  // True if neither sensor is saturated
        good = light.getLux(gain, ms, data0, data1, lux);
        if (good) return lux;
        else return -10;
    }
}

void do_send(osjob_t* j){
    // Check if there is not a current TX/RX job running
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
        uint8_t payload_size = 6;

        digitalWrite(SENSOR_PWR_PIN, HIGH);  // Power sensors
        float humidity = htu.readHumidity();
        float temperature = htu.readTemperature();
        uint16_t lux = get_lux(2);
        if (lux < 0) lux = get_lux(1);  // If light sensor saturated, sample time
        if (lux < 0) lux = get_lux(0);
        digitalWrite(SENSOR_PWR_PIN, LOW);  // Depower sensors

        Serial.println(humidity);
        Serial.println(temperature);
        Serial.println(lux);
        
        // adjust for the f2sflt16 range (-1 to 1)
        humidity = humidity / 100;
        // float -> int
        uint16_t payloadHumid = LMIC_f2sflt16(humidity);
        // int -> bytes
        byte humidLow = lowByte(payloadHumid);
        byte humidHigh = highByte(payloadHumid);
        payload[0] = humidLow;
        payload[1] = humidHigh;

        temperature = temperature / 100; 
        uint16_t payloadTemp = LMIC_f2sflt16(temperature);
        byte tempLow = lowByte(payloadTemp);
        byte tempHigh = highByte(payloadTemp);
        payload[2] = tempLow;
        payload[3] = tempHigh;

        payload[4] = lowByte(int(lux));
        payload[5] = highByte(int(lux));

        if (TX_COUNT * TX_INTERVAL >= MEASURE_VOLTAGE_INTERVAL) {
            uint16_t volts_bat = T2Utils::readVoltage(T2_WPN_VBAT_VOLTAGE, T2_WPN_VBAT_CONTROL);
            Serial.println(volts_bat);
            payload[6] = lowByte(int(volts_bat));
            payload[7] = highByte(int(volts_bat));
            payload_size = 8;  // Add voltage to measurement payload
            TX_COUNT = 0;
        }
        ++TX_COUNT;

        for (int i=0; i<sizeof(payload); i++) {
            if (payload[i] < 16) {Serial.print("0");}
            Serial.print(payload[i], HEX);
            Serial.print(" ");
        }
        Serial.println();

        LMIC_setTxData2(1, payload, payload_size, 0);
        Serial.println(F("Packet queued"));
    }
}

void setup() {
    //while (!Serial); // wait for Serial to be initialized
    Serial.begin(115200);
    delay(5000);
    Serial.println(F("Starting"));

    pinMode(SENSOR_PWR_PIN, OUTPUT);

    htu.begin();
    light.begin();

    myFlash.init(T2_WPN_FLASH_SPI_CS);
    myFlash.powerDown();  // Power down Flash to save energy
  
    os_init();
    LMIC_reset();

    uint8_t appskey[sizeof(APPSKEY)];
    uint8_t nwkskey[sizeof(NWKSKEY)];
    memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
    memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
    LMIC_setSession (0x13, DEVADDR, nwkskey, appskey);

    LMIC_selectSubBand(1);
    LMIC_setLinkCheckMode(0);
    LMIC.dn2Dr = DR_SF9;
    LMIC_setDrTxpow(DR_SF7,14);
}

void loop() {
  Serial.println("Send");
  do_send(&sendjob);

  byte TX_TIMEOUT = 0;
  while(TX_COMPLETE != 1) {
      os_runloop_once();
      if (++TX_TIMEOUT > 60000) {
          Serial.println("Event Timeout");
          break;
      }
  }
  TX_COMPLETE = 0;

  Serial.println("Sleep");
  Serial.flush();

  // Using Low-Power library to put the MCU to Sleep
  for (int i = 0; i < TX_INTERVAL; i+=8) {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);             
  }
}
Did you solve the loop problem somehow? I am doing a similar task now, but I am not an expert, I am just learning. I would be glad to have your advice.

PostSep 26, 2023#15

jakob.erber wrote:
Mar 05, 2021
kizniche wrote:
Apr 08, 2019
Upon further testing, I discovered if I remove my sensor code, the sketch runs as expected, and does not reset and run setup() after waking. This was likely due to the large size of the code. I'll report back if I uncover anything else of note.
Hi, I have a similar Problem with the TinyLora Lib and a MPU9250 sensor. were you able to solve the problem?
The problem seems to have been solved, but no one is talking about it🤔

Read more posts (-5 remaining)