/*******************************************************************************
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
* Copyright (c) 2018 Terry Moore, MCCI
* Copyright (c) 2018 Betina Wendel and Thomas Laurenson
*
* 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.
*
* Sketch Summary:
* Target device: Dragino LoRa Shield (US900) with Arduino Uno
* Target frequency: AU915 sub-band 2 (916.8 to 918.2 uplink)
* Authentication mode: Over the Air Authentication (OTAA)
*
* This example requires the following modification before upload:
* 1) Enter a valid Application EUI (APPEUI)
* For example: { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
* 2) Enter a valid Device EUI (DEVEUI)
* For example: { 0x33, 0x22, 0x11, 0x11, 0x88, 0x88, 0x11, 0x22 };
* This is little endian format, so it is in reverse order that the server
* provides. In the example above, the original value was: 2211888811112233
* 3) Enter a valid Application Key (APPKEY)
* For example: { 0xe4, 0x17, 0xd3, 0x3b, 0xef, 0xf3, 0x80, 0x7c, 0x7c, 0x6e, 0x42, 0x43, 0x56, 0x7c, 0x21, 0xa7 };
*
* The DEVEUI and APPKEY values should be obtained from your LoRaWAN server
* (e.g., TTN or any private LoRa provider). APPEUI is set to zeroes as
* the LoRa Server project does not requre this value.
*
*******************************************************************************/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <string.h>
/************************************************************************************
*
* My Mods to get thr ultrasonic sensor to read the tank level and then send it to ttn
* 30/04/2022 greg O.
*************************************************************************************/
#include <SoftwareSerial.h>
SoftwareSerial mySerial(11,12); // RX, TX
unsigned char data[4]={};
unsigned char dat_to_send[4]={};
int distance;
//
// For normal use, we require that you edit the sketch to replace FILLMEIN
// with values assigned by the TTN console. However, for regression tests,
// we want to be able to compile these scripts. The regression tests define
// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non-
// working but innocuous value.
//
#ifdef COMPILE_REGRESSION_TEST
# define FILLMEIN 0
#else
# warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!"
# define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN)
#endif
// This EUI must be in little-endian format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
static const u1_t PROGMEM APPEUI[8]= {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
// This should also be in little endian format, see above.
static const u1_t PROGMEM DEVEUI[8]= { Blagh Blagh};
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from the TTN console can be copied as-is.
static const u1_t PROGMEM APPKEY[16] = { Blagh Blagh };
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
//static uint8_t mydata[]; // = "GDay Num Nuts";
static uint8_t payload[5];
static osjob_t sendjob;
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 60;
// Pin mapping for Dragino Lorashield
const lmic_pinmap lmic_pins = {
.nss = 10,
.rxtx = LMIC_UNUSED_PIN,
.rst = 9,
.dio = {2, 6, 7},
};
/*********************************************************
*
* Read ultrasonic sensor data and format it.
*
**********************************************************/
int read_sonde()
{
do{
for(int i=0;i<4;i++)
{
data[i]=mySerial.read();
}
}while(mySerial.read()==0xff);
mySerial.flush();
if(data[0]==0xff)
{
int sum;
sum=(data[0]+data[1]+data[2])&0x00FF;
if(sum==data[3])
{
distance=(data[1]<<8)+data[2];
if(distance>280)
{
// strncpy(mydata,distance,sizeof(distance));
Serial.print("distance=");
Serial.print(distance);
Serial.println("mm");
}else
{
Serial.println("Below the lower limit");
}
}else Serial.println("ERROR");
}
return(distance);
}
/* End */
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"));
{
u4_t netid = 0;
devaddr_t devaddr = 0;
u1_t nwkKey[16];
u1_t artKey[16];
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
Serial.print("netid: ");
Serial.println(netid, DEC);
Serial.print("devaddr: ");
Serial.println(devaddr, HEX);
Serial.print("artKey: ");
for (int i=0; i<sizeof(artKey); ++i) {
Serial.print(artKey[i], HEX);
}
Serial.println("");
Serial.print("nwkKey: ");
for (int i=0; i<sizeof(nwkKey); ++i) {
Serial.print(nwkKey[i], HEX);
}
Serial.println("");
}
Serial.println(F("Successful OTAA Join..."));
// Disable link check validation (automatically enabled
// during join, but because slow data rates change max TX
// size, we don't use it in this example.
LMIC_setLinkCheckMode(0);
break;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| 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;
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.print(F("Received "));
Serial.print(LMIC.dataLen);
Serial.println(F(" bytes of payload"));
}
// 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;
/*
|| This event is defined but not used in the code. No
|| point in wasting codespace on it.
||
|| case EV_SCAN_FOUND:
|| Serial.println(F("EV_SCAN_FOUND"));
|| break;
*/
case EV_TXSTART:
Serial.println(F("EV_TXSTART"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
}
}
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 {
// Prepare upstream data transmission at the next possible time.
//LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
itoa(distance,dat_to_send,10);
Serial.print(distance);
LMIC_setTxData2(1, dat_to_send, sizeof(dat_to_send)-1, 0);
Serial.println(F("Packet queued"));
Serial.print(F("Sending packet on frequency: "));
Serial.println(LMIC.freq);
}
// Next TX is scheduled after TX_COMPLETE event.
}
void setup() {
LMIC_setAdrMode(1);
LMIC_setLinkCheckMode(1);
Serial.begin(115200); /* For arduino debugging info */
mySerial.begin(9600); /* For Ultrasonic sensor serial port */
Serial.println(F("Starting"));
#ifdef VCC_ENABLE
// For Pinoccio Scout boards
pinMode(VCC_ENABLE, OUTPUT);
digitalWrite(VCC_ENABLE, HIGH);
delay(1000);
#endif
#if defined(CFG_au921)
Serial.println(F("Loading AU915/AU921 Configuration..."));
#endif
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
LMIC_setDrTxpow(DR_SF7, 14);
LMIC_selectSubBand(1);
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
}
void loop() {
os_runloop_once();
}