Hi
Sorry I think that was a paste from while I was troubleshooting, the radio is connected to the digital pins as per
https://www.thethingsnetwork.org/labs/story/build-the-cheapest-possible-node-yourself
And the CT is connected to A5
Below is the code as I’m using it now
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include "DHT.h"
#include <LowPower.h>
#include "EmonLib.h"
EnergyMonitor emon1;
static const PROGMEM u1_t NWKSKEY[16] = { xxx };
static const u1_t PROGMEM APPSKEY[16] = { xxx };
static const u4_t DEVADDR = 0xxxx; // <-- Change this address for every node!
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
static osjob_t sendjob;
const unsigned TX_INTERVAL = 30;
const lmic_pinmap lmic_pins = {
.nss = 6,
.rxtx = LMIC_UNUSED_PIN,
.rst = 5,
.dio = {2, 3, 4},
};
int ANALOGPIN = A5;
void onEvent (ev_t ev) {
Serial.print(os_getTime());
Serial.print(": ");
switch(ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
break;
case EV_RFU1:
Serial.println(F("EV_RFU1"));
break;
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
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 of payload"));
}
for (int i=0; i<int(TX_INTERVAL/8); i++) {
Serial.flush();
LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF);
}
do_send(&sendjob);
break;
// Schedule next transmission
//os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
//break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
default:
Serial.println(F("Unknown event"));
break;
}
}
void do_send(osjob_t* j){
int sensorValue = analogRead(ANALOGPIN);
Serial.print("The analogRead output : - ");
Serial.println(sensorValue);
double Irms = emon1.calcIrms(1480);
double et = emon1.calcIrms(1480);
Serial.print("The Irms calculation output : - ");
Serial.println(Irms);
Serial.print("This is et :- ");
Serial.println(et);
int16_t e = et * 100;
Serial.print("This is e :- ");
Serial.println(e);
float Vcc=readVcc(); //value in mV
Vcc=Vcc/1000;//value in V
int16_t v = Vcc * 100;
Serial.print("Voltage: ");
Serial.print(v);
Serial.println(" Volts");
byte payloadA[2];
payloadA[0] = highByte(e);
payloadA[1] = lowByte(e);
byte payloadB[2];
payloadB[0] = highByte(v);
payloadB[1] = lowByte(v);
int sizeofPayloadA = sizeof(payloadA);
int sizeofPayloadB = sizeof(payloadB);
for (int i=0; i<sizeofPayloadA; i++) {
if (payloadA[i]<0x10) {
Serial.print(F("0"));
Serial.print(payloadA[i],HEX);
} else {
Serial.print(payloadA[i],HEX);
}
}
Serial.println(F(""));
for (int i=0; i<sizeofPayloadB; i++) {
if (payloadB[i]<0x10) {
Serial.print(F("0"));
Serial.print(payloadB[i],HEX);
} else {
Serial.print(payloadB[i],HEX);
}
}
Serial.println(F(""));
byte payload[sizeofPayloadA + sizeofPayloadB];
memcpy(payload, payloadA, sizeofPayloadA);
memcpy(payload + sizeofPayloadA, payloadB, sizeofPayloadB);
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending"));
} else {
LMIC_setTxData2(1, payload, sizeof(payload), 0);
Serial.println(F("Packet queued"));
}
}
void setup() {
Serial.begin(9600);
Serial.println(F("LoRaStarting"));
analogReference(INTERNAL);
emon1.current(5, 115.1);
Serial.println(F("EMON Starting"));
os_init();
LMIC_reset();
#ifdef PROGMEM
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
#else
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif
#if defined(CFG_eu868)
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
#elif defined(CFG_us915)
LMIC_selectSubBand(1);
#endif
LMIC_setLinkCheckMode(0);
LMIC.dn2Dr = DR_SF9;
LMIC_setDrTxpow(DR_SF7,14);
do_send(&sendjob);
}
void loop() {
os_runloop_once();
}
long readVcc() {
// Read 1.1V reference against AVcc
// set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
ADMUX = _BV(MUX5) | _BV(MUX0);
#elif defined (__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
ADMUX = _BV(MUX3) | _BV(MUX2);
#else
ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
delay(2); // Wait for Vref to settle
ADCSRA |= _BV(ADSC); // Start conversion
while (bit_is_set(ADCSRA,ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
long result = (high<<8) | low;
result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000
return result; // Vcc in millivolts
}
And the resulting output
LoRaStarting
EMON Starting
The analogRead output : - 1023
The Irms calculation output : - 107.49
This is et :- 26.80
This is e :- 2680
Voltage: 328 Volts
0A78
0148
Packet queued
176217: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 11.49
This is et :- 10.22
This is e :- 1021
Voltage: 328 Volts
03FD
0148
Packet queued
497653: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.13
This is et :- 10.21
This is e :- 1021
Voltage: 328 Volts
03FD
0148
Packet queued
888938: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.14
This is et :- 10.18
This is e :- 1018
Voltage: 328 Volts
03FA
0148
Packet queued
1300284: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.16
This is et :- 10.19
This is e :- 1018
Voltage: 328 Volts
03FA
0148
Packet queued
1724737: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.08
This is et :- 10.23
This is e :- 1022
Voltage: 328 Volts
03FE
0148
Packet queued
2141547: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.15
This is et :- 10.22
This is e :- 1021
Voltage: 328 Volts
03FD
0148
Packet queued
2510309: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.15
This is et :- 10.21
This is e :- 1021
Voltage: 328 Volts
03FD
0148
Packet queued
2844020: EV_TXCOMPLETE (includes waiting for RX windows)
The analogRead output : - 535
The Irms calculation output : - 10.14
This is et :- 10.20
This is e :- 1020
Voltage: 328 Volts
03FC
0148
Packet queued
3270039: EV_TXCOMPLETE (includes waiting for RX windows)
Apologies for the confusion, If I use the program generator at https://lcd-web.nl/ttngenerator/
And generate a program using a moisture sensor and make some changes, see below
#include <SPI.h>
#define ACT_METHOD_ABP
static const uint8_t PROGMEM NWKSKEY[16] = {xxxxx };
static const uint8_t PROGMEM APPSKEY[16] = { xxxx };
static const uint32_t DEVADDR = 0xxxxxx;
#include <lmic.h>
#include <hal/hal.h>
static osjob_t sendjob;
#ifdef ACT_METHOD_ABP
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }
#else
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
#endif
const lmic_pinmap lmic_pins = {
.nss = 6,
.rxtx = LMIC_UNUSED_PIN,
.rst = 5,
.dio = {2, 3, 4},
};
#ifndef _Sodaq_RN2483_h
#include "LowPower.h"
#endif
#define DEBUG
int ANALOGPIN = A5;
int readVal;
static uint8_t dataTX[3];
unsigned long cycle_length = 30 * 1 * 1000UL; // cycle * mins_or_secs * 1000;
unsigned long sense_every = 1;
unsigned long send_every = 1;
unsigned long cycle = -1; // init at -1, so first cycle starts as cycle 0 for 1st sense/send
unsigned long prevSleep = 0;
void setup() {
while ((!Serial) && (millis() < 10000)){ }
Serial.begin(9600);
Serial.println(F("emon (template version: 13Jan2017 generated: 10Jul2018)"));
init_node();
init_sensor();
}
void loop() {
cycle += 1;
if ( (cycle % sense_every) == 0 ) { do_sense(); }
if ( (cycle % send_every) == 0 ) { build_data(); do_send(); }
unsigned long current = millis();
do_sleep(cycle_length - (current - prevSleep)); // sleep minus elapsed time
prevSleep = current;
#ifdef _Sodaq_RN2483_h
prevSleep += cycle_length;
#endif
}
void init_sensor() {
Serial.println("");
pinMode(ANALOGPIN, INPUT);
}
void do_sense() {
delay(1000);
readVal = analogRead(ANALOGPIN);
#ifdef DEBUG
Serial.print(F(" readVal: "));
Serial.print(readVal);
Serial.println();
#endif
}
/* **************************************************************
* build data to transmit in dataTX
* *************************************************************/
void build_data() {
#ifdef DEBUG
Serial.print(F("Time:"));
Serial.print(millis());
Serial.print(F(" Send Value:"));
Serial.print(readVal);
Serial.println();
#endif
// map it to dataTX; 1 leading byte (0x01) plus 2 data bytes
/* *************************************************
* Suggested payload function for this data
*
* if (bytes[0] == 0x01) {
* var moisture = (bytes[1] << 8) | bytes[2];
* return { payload: moisture };
* }
*
* ************************************************/
dataTX[0] = 0x01; //first byte is send as 00 to recognise this is a temperature in our dashboard
dataTX[1] = readVal >> 8;
dataTX[2] = readVal & 0xFF;
}
/* **************************************************************
* sleep
* *************************************************************/
void do_sleep(float sleepTime) {
#ifdef DEBUG
Serial.print(F("Sleep for "));
Serial.print(sleepTime/1000, 3);
Serial.println(F(" seconds"));
#endif
Serial.flush();
#ifndef _Sodaq_RN2483_h
// sleep logic using LowPower library
int delays[] = {8000, 4000, 2000, 1000, 500, 250, 120, 60, 30};
period_t sleep[] = {SLEEP_8S, SLEEP_4S, SLEEP_2S, SLEEP_1S, SLEEP_500MS, SLEEP_250MS, SLEEP_120MS, SLEEP_60MS, SLEEP_30MS};
// correction for overhead in this routine
sleepTime = sleepTime * 0.93;
float x;
unsigned int i;
for (i=0; i<=9; i++) {
for (x=sleepTime; x>=delays[i]; x-=delays[i]) {
LowPower.powerDown(sleep[i], ADC_OFF, BOD_OFF);
sleepTime -= delays[i];
}
}
#else
// no LowPower implemented yet, so just a delay
delay(sleepTime);
#endif
}
/* **************************************************************
* radio code, typical would be init_node(), do_send(), etc
* *************************************************************/
/* **************************************************************
* init the Node
* *************************************************************/
void init_node() {
#ifdef VCC_ENABLE
// For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH);
delay(1000);
#endif
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
#ifdef ACT_METHOD_ABP
// Set static session parameters. Instead of dynamically establishing a session
// by joining the network, precomputed session parameters are be provided.
#ifdef PROGMEM
// On AVR, these values are stored in flash and only copied to RAM
// once. Copy them to a temporary buffer here, LMIC_setSession will
// copy them into a buffer of its own again.
uint8_t appskey[sizeof(APPSKEY)];
uint8_t nwkskey[sizeof(NWKSKEY)];
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
#else
// If not running an AVR with PROGMEM, just use the arrays directly
LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);
#endif
#if defined(CFG_eu868)
// Set up the channels used by the Things Network, which corresponds
// to the defaults of most gateways. Without this, only three base
// channels from the LoRaWAN specification are used, which certainly
// works, so it is good for debugging, but can overload those
// frequencies, so be sure to configure the full frequency range of
// your network here (unless your network autoconfigures them).
// Setting up channels should happen after LMIC_setSession, as that
// configures the minimal channel set.
// NA-US channels 0-71 are configured automatically
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
// TTN defines an additional channel at 869.525Mhz using SF9 for class B
// devices' ping slots. LMIC does not have an easy way to define set this
// frequency and support for class B is spotty and untested, so this
// frequency is not configured here.
#elif defined(CFG_us915)
// NA-US channels 0-71 are configured automatically
// but only one group of 8 should (a subband) should be active
// TTN recommends the second sub band, 1 in a zero based count.
// https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json
LMIC_selectSubBand(1);
#endif
// Disable link check validation
LMIC_setLinkCheckMode(0);
// TTN uses SF9 for its RX2 window.
LMIC.dn2Dr = DR_SF9;
// Set data rate and transmit power (note: txpow seems to be ignored by the library)
LMIC_setDrTxpow(DR_SF7,14);
#endif
#ifdef ACT_METHOD_OTAA
// got this fix from forum: https://www.thethingsnetwork.org/forum/t/over-the-air-activation-otaa-with-lmic/1921/36
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
#endif
}
/* **************************************************************
* send the message
* *************************************************************/
void do_send() {
Serial.print(millis());
Serial.print(F(" Sending.. "));
send_message(&sendjob);
// wait for send to complete
Serial.print(millis());
Serial.print(F(" Waiting.. "));
while ( (LMIC.opmode & OP_JOINING) or (LMIC.opmode & OP_TXRXPEND) ) { os_runloop_once(); }
Serial.print(millis());
Serial.println(F(" TX_COMPLETE"));
}
/* *****************************************************************************
* send_message
* ****************************************************************************/
void send_message(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 {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, dataTX, sizeof(dataTX), 0);
Serial.println(F("Packet queued"));
}
}
/*******************************************************************************/
void onEvent (ev_t ev) {
switch (ev) {
case EV_SCAN_TIMEOUT:
Serial.println(F("EV_SCAN_TIMEOUT"));
break;
case EV_BEACON_FOUND:
Serial.println(F("EV_BEACON_FOUND"));
break;
case EV_BEACON_MISSED:
Serial.println(F("EV_BEACON_MISSED"));
break;
case EV_BEACON_TRACKED:
Serial.println(F("EV_BEACON_TRACKED"));
break;
case EV_JOINING:
Serial.println(F("EV_JOINING"));
break;
case EV_JOINED:
Serial.println(F("EV_JOINED"));
// Disable link check validation (automatically enabled
// during join, but not supported by TTN at this time).
LMIC_setLinkCheckMode(0);
break;
case EV_RFU1:
Serial.println(F("EV_RFU1"));
break;
case EV_JOIN_FAILED:
Serial.println(F("EV_JOIN_FAILED"));
break;
case EV_REJOIN_FAILED:
Serial.println(F("EV_REJOIN_FAILED"));
break;
case EV_TXCOMPLETE:
Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
if (LMIC.dataLen) {
// data received in rx slot after tx
Serial.print(F("Data Received: "));
Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);
Serial.println();
}
// schedule next transmission
// os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), send_message);
break;
case EV_LOST_TSYNC:
Serial.println(F("EV_LOST_TSYNC"));
break;
case EV_RESET:
Serial.println(F("EV_RESET"));
break;
case EV_RXCOMPLETE:
// data received in ping slot
Serial.println(F("EV_RXCOMPLETE"));
break;
case EV_LINK_DEAD:
Serial.println(F("EV_LINK_DEAD"));
break;
case EV_LINK_ALIVE:
Serial.println(F("EV_LINK_ALIVE"));
break;
default:
Serial.println(F("Unknown event"));
break;
}
}
It works for a while and then I get a failure
emon (template version: 13Jan2017 generated: 10Jul2018)
readVal: 513
Time:1007 Send Value:513
1007 Sending.. Packet queued
1019 Waiting.. EV_TXCOMPLETE (includes waiting for RX windows)
3098 TX_COMPLETE
Sleep for 26.900 seconds
readVal: 513
Time:4196 Send Value:513
4198 Sending.. Packet queued
4202 Waiting.. 4218 TX_COMPLETE
Sleep for 28.863 seconds
readVal: 513
Time:5332 Send Value:513
5332 Sending.. Packet queued
5339 Waiting.. 5353 TX_COMPLETE
Sleep for 28.864 seconds
readVal: 513
Time:6469 Send Value:513
6469 Sending.. Packet queued
6475 Waiting.. 6490 TX_COMPLETE
Sleep for 28.865 seconds
readVal: 513
Time:7606 Send Value:513
7606 Sending.. Packet queued
7618 Waiting.. FAILURE
C:\Users\xxx\Documents\Arduino\libraries\arduino-lmic-master\src\lmic\radio.c:660
I’m starting to pull my hair out… Please any suggestions will be appreciated!