Created
April 11, 2018 16:13
-
-
Save wero1414/f0420dc118d8bd5dd07b85bcc2b4ff94 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************* | |
Created by Eduardo Contreras @ Electronic Cats 2016 | |
Based on Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman | |
PLEASE REFER TO THIS LMIC LIBRARY https://github.com/things-nyc/arduino-lmic | |
LoRaShield | |
In this example you can send GPS information (Compatible with the L80) | |
or a temperature read by the ADC | |
Example | |
*******************************************************************************/ | |
#include <lmic.h> | |
#include <hal/hal.h> | |
#include <SPI.h> | |
#include <math.h> | |
#include <SoftwareSerial.h> | |
//#define _USE_GPS_ | |
#define _USE_TEMP_ | |
//#define _USE_ULTRASONIC_ | |
#ifdef _USE_GPS_ | |
#include <TinyGPS++.h> | |
SoftwareSerial ss(6, 5); | |
TinyGPSPlus gps; | |
double gps_lat = 0; | |
double gps_lng = 0; | |
double gps_alt = 0; | |
bool gpsEncoded = false; | |
#endif | |
#ifdef _USE_ULTRASONIC_ | |
const int trigPin = 7; | |
const int echoPin = 8; | |
#endif | |
#define debugSerial Serial | |
unsigned long previousMillis = 0; | |
static const PROGMEM u1_t NWKSKEY[16] = { 0x41, 0xe2, 0xc1, 0x11, 0xcf, 0x0b, 0xfb, 0x8d, 0x1d, 0x08, 0x98, 0xf0, 0xca, 0xa8, 0x77, 0x62 }; | |
static const u1_t PROGMEM APPSKEY[16] = { 0x6e, 0x9b, 0x51, 0x67, 0x09, 0x92, 0xc2, 0x40, 0xac, 0x1c, 0xf4, 0xe2, 0x38, 0x9c, 0x8d, 0xf2 }; | |
static const u4_t DEVADDR =0x07000007; | |
void os_getArtEui (u1_t* buf) { } | |
void os_getDevEui (u1_t* buf) { } | |
void os_getDevKey (u1_t* buf) { } | |
// We will be using Cayenne Payload Format | |
// For one sensor, | |
// the general format is channel | type | payload | |
// payload size depends on type | |
// here we are using temperature, GPS and customised PM25, | |
// temperature - 2, GPS - 9, PM25 - 2 | |
static osjob_t sendjob; | |
// Schedule TX every this many seconds (might become longer due to duty | |
// cycle limitations). | |
const unsigned TX_INTERVAL = 20; | |
// Pin mapping for RFM9X | |
const lmic_pinmap lmic_pins = { | |
.nss = 10, | |
.rxtx = LMIC_UNUSED_PIN, | |
.rst = 9, | |
.dio = {2, 3, 4}, | |
}; | |
void debug_char(u1_t b) { | |
debugSerial.write(b); | |
} | |
void debug_hex (u1_t b) { | |
debug_char("0123456789ABCDEF"[b >> 4]); | |
debug_char("0123456789ABCDEF"[b & 0xF]); | |
} | |
void debug_buf (const u1_t* buf, u2_t len) { | |
while (len--) { | |
debug_hex(*buf++); | |
debug_char(' '); | |
} | |
debug_char('\r'); | |
debug_char('\n'); | |
} | |
void onEvent (ev_t ev) { | |
switch (ev) { | |
case EV_TXCOMPLETE: | |
// indicating radio TX complete | |
digitalWrite(A1, LOW); | |
debugSerial.println(F("[LMIC] Radio TX complete (included RX windows)")); | |
if (LMIC.txrxFlags & TXRX_ACK) | |
debugSerial.println(F("[LMIC] Received ack")); | |
if (LMIC.dataLen) { | |
debugSerial.print(F("[LMIC] Received ")); | |
debugSerial.print(LMIC.dataLen); | |
debugSerial.println(F(" bytes of payload")); | |
debug_buf(LMIC.frame + LMIC.dataBeg, LMIC.dataLen); | |
} | |
break; | |
default: | |
debugSerial.println(F("[LMIC] Unknown event")); | |
break; | |
} | |
} | |
void do_send(osjob_t* j, uint8_t *mydata1, uint16_t len) { | |
// Check if there is not a current TX/RX job running | |
if (LMIC.opmode & OP_TXRXPEND) { | |
debugSerial.println(F("[LMIC] OP_TXRXPEND, not sending")); | |
} else { | |
// Prepare upstream data transmission at the next possible time | |
LMIC_setTxData2(1, mydata1, len, 0); | |
} | |
} | |
void setup() { | |
debugSerial.begin(115200); | |
debugSerial.println(F("[INFO] LoRa Demo Node 1 Demonstration")); | |
// start GPS object | |
#ifdef _USE_GPS_ | |
ss.begin(9600); | |
#endif | |
#ifdef _USE_ULTRASONIC_ | |
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output | |
pinMode(echoPin, INPUT); // Sets the echoPin as an Input | |
#endif | |
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 (0x1, DEVADDR, nwkskey, appskey); | |
//LMIC_selectSubBand(2); | |
for (int channel=0; channel<72; ++channel) { | |
LMIC_disableChannel(channel); | |
} | |
//SF TTN | |
/* | |
LMIC_enableChannel(8); | |
LMIC_enableChannel(9); | |
LMIC_enableChannel(10); //904.3Mhz | |
LMIC_enableChannel(11); | |
LMIC_enableChannel(12); | |
LMIC_enableChannel(13); | |
LMIC_enableChannel(14); | |
LMIC_enableChannel(15); | |
LMIC_enableChannel(65); | |
*/ | |
//Home | |
LMIC_enableChannel(48); | |
LMIC_enableChannel(49); | |
LMIC_enableChannel(50); | |
LMIC_enableChannel(51); | |
LMIC_enableChannel(52); | |
LMIC_enableChannel(53); | |
LMIC_enableChannel(54); | |
LMIC_enableChannel(55); | |
LMIC_enableChannel(70); | |
LMIC_setLinkCheckMode(0); | |
LMIC_setAdrMode(false); | |
LMIC_setDrTxpow(DR_SF7, 14); //SF7 | |
previousMillis = millis(); | |
} | |
void loop() { | |
if (millis() > previousMillis + TX_INTERVAL * 1000) { //Start Job at every TX_INTERVAL*1000 | |
getInfoAndSend(); | |
previousMillis = millis(); | |
} | |
os_runloop_once(); | |
} | |
void getInfoAndSend() { | |
uint8_t len = 4; //Bug of len | |
uint8_t mydata[len]; | |
uint8_t cnt = 0; | |
uint8_t ch = 0; | |
debugSerial.println(F("[INFO] Collecting info")); | |
#ifdef _USE_ULTRASONIC_ | |
//len+=4; | |
uint16_t distance = readDistance(); | |
uint8_t Percent = map(distance,1,150,100,0); | |
debugSerial.print(F("[INFO] Distance:")); debugSerial.println(distance); | |
debugSerial.print(F("[INFO] Distance (%):")); debugSerial.println(Percent); | |
mydata[cnt++] = 0x01; | |
mydata[cnt++] = (distance>>8)&0xFF; | |
mydata[cnt++] = distance&0xFF; | |
mydata[cnt++] = Percent; | |
#endif | |
#ifdef _USE_TEMP_// Temperature | |
//len += 4; // temperature | |
//float temp = readTemperature(); | |
float temp = 10; | |
debugSerial.print(F("[INFO] Temperature:")); debugSerial.println(temp); | |
int val = round(temp * 10); | |
mydata[cnt++] = ch; | |
mydata[cnt++] = 0x67; | |
mydata[cnt++] = highByte(val); | |
mydata[cnt++] = lowByte(val); | |
#endif | |
// GPS | |
#ifdef _USE_GPS_// Temperature | |
//len += 11; // GPS | |
if (gpsEncoded) { | |
digitalWrite(A0, LOW); | |
debugSerial.println(F("[INFO] Collecting GPS info")); | |
debugSerial.print(F("[INFO] Lat:")); debugSerial.println(String(gps_lat, 6)); | |
debugSerial.print(F("[INFO] Lng:")); debugSerial.println(String(gps_lng, 6)); | |
debugSerial.print(F("[INFO] Alt:")); debugSerial.println(gps_alt); | |
long lat = round(gps_lat * 10000); | |
long lng = round(gps_lng * -10000); | |
long alt = round(gps_alt * 100); | |
ch = ch + 1; | |
mydata[cnt++] = ch; | |
mydata[cnt++] = 0x88; | |
mydata[cnt++] = lat >> 16; | |
mydata[cnt++] = lat >> 8; | |
mydata[cnt++] = lat; | |
mydata[cnt++] = lng >> 16; | |
mydata[cnt++] = lng >> 8; | |
mydata[cnt++] = lng; | |
mydata[cnt++] = alt >> 16; | |
mydata[cnt++] = alt >> 8; | |
mydata[cnt++] = alt; | |
} | |
else{ | |
digitalWrite(A0, HIGH); | |
ch = ch + 1; | |
mydata[cnt++] = ch; | |
mydata[cnt++] = 0x88; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
mydata[cnt++] = 0; | |
} | |
#endif | |
if (cnt == len) { | |
debugSerial.println(F("[LMIC] Start Radio TX")); | |
// indicating start radio TX | |
digitalWrite(A1, HIGH); | |
for(int i;i<sizeof(mydata);i++){ | |
debugSerial.print(mydata[i]); | |
} | |
debugSerial.println(); | |
do_send(&sendjob, mydata, sizeof(mydata)); | |
} | |
else | |
debugSerial.println(F("[ERROR] Data stack incorrect")); | |
} | |
#ifdef _USE_TEMP_// Temperature | |
float readTemperature() { | |
int a = analogRead(A0); | |
float R = 1023.0 / ((float)a) - 1.0; | |
R = 100000.0 * R; | |
float temperature = 1.0 / (log(R / 100000.0) / 4275 + 1 / 298.15) - 273.15; //convert to temperature via datasheet ; | |
return temperature; | |
} | |
#endif | |
#ifdef _USE_ULTRASONIC_ | |
uint16_t readDistance(void){ | |
long duration; | |
uint16_t distance; | |
digitalWrite(trigPin, LOW); | |
delayMicroseconds(2); | |
// Sets the trigPin on HIGH state for 10 micro seconds | |
digitalWrite(trigPin, HIGH); | |
delayMicroseconds(10); | |
digitalWrite(trigPin, LOW); | |
// Reads the echoPin, returns the sound wave travel time in microseconds | |
duration = pulseIn(echoPin, HIGH); | |
// Calculating the distance | |
distance= duration*0.034/2; | |
return distance; | |
} | |
#endif | |
#ifdef _USE_GPS_ | |
void GPS_loop() { | |
if (!ss.isListening()) { | |
ss.listen(); | |
} | |
while (ss.available() > 0) { | |
if (gps.encode(ss.read())) { | |
if (gps.location.isValid() && gps.altitude.isValid()) { | |
// indicating GPS is successfully obtained | |
gpsEncoded = true; | |
// update the locations | |
gps_lat = gps.location.lat(); | |
gps_lng = gps.location.lng(); | |
gps_alt = gps.altitude.meters(); | |
} | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment