d
Dependencies: BME280 DOGS102 DS1820 MMA845x_timmeh MTS-Serial libmDot_Australia915Mhz mbed-rtos mbed
Fork of mDot_TTN_OTAA_Node by
Revision 17:55ea4f38710b, committed 2017-01-11
- Comitter:
- 1994timmeh
- Date:
- Wed Jan 11 04:12:39 2017 +0000
- Parent:
- 16:290c505e3851
- Commit message:
- Thing
Changed in this revision
diff -r 290c505e3851 -r 55ea4f38710b DOGS102.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DOGS102.lib Wed Jan 11 04:12:39 2017 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/teams/Multi-Hackers/code/DOGS102/#e66152f036d9
diff -r 290c505e3851 -r 55ea4f38710b GPS/GPSPARSER.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPS/GPSPARSER.cpp Wed Jan 11 04:12:39 2017 +0000 @@ -0,0 +1,483 @@ +/** + * @file NemaParser.cpp + * @brief NEMA String to Packet Parser - NEMA strings to compact packet data + * @author Tim Barr + * @version 1.01 + * @see http://www.kh-gps.de/nmea.faq + * @see http://www.catb.org/gpsd/NMEA.html + * + * Copyright (c) 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * 09/16/15 TAB V1.01 Changed report rate of GGA and GSA NEMA sentences + * 09/22/15 TAB V1.02 Fixed status value for no GPS detected. Increased report rate + * of GSV, GGA, and GSA NEMA Sentences + * + * TODO: Add speed, compass direction, error (DOP) data. Make init more generic + */ + +#include "GPSPARSER.h" + +using namespace mts; + +GPSPARSER::GPSPARSER(MTSSerial *uart):_getSentenceThread(&GPSPARSER::startSentenceThread,this), + _led_state(0), + _tick_running(false) +{ + _gps_uart = uart; + _gps_uart->baud(9600); //set GPS baud rate here + + _gps_latitude.degrees = 0; + _gps_longitude.degrees = 0; + _timestamp.tm_sec = 0; + _timestamp.tm_min = 0; + _timestamp.tm_hour = 0; + _timestamp.tm_mday = 0; + _timestamp.tm_mon = 0; + _timestamp.tm_year = 0; + _timestamp.tm_wday = 0; + _timestamp.tm_yday = 0; + _timestamp.tm_isdst = -1; // time is UTC so no Daylight savings time + + _gps_status = false; + _fix_status = 1; + _num_satellites =0; + _gps_detected = false; + + return; +} + +GPSPARSER::~GPSPARSER(void) +{ + if (_gps_detected) + _getSentenceThread.terminate(); +} + +void GPSPARSER::startSentenceThread(void const *p) +{ + GPSPARSER *instance = (GPSPARSER*)p; + instance->readNemaSentence(); +} + +int GPSPARSER::readNemaSentence (void) { +// logInfo("===== READING GPS ======\n\r"); + // this code is specific to the Skytraq Venus GPS chip. This code could be re-written to detect another type of + // GPS device. Maybe read serial port for a specific time and detect $GP from NEMA string + + // Sets Skytraq Venus GPS to output GGA,GSA,GSV every 10 seconds, and RMC every second, no ZDA,GLL,VTG + // setup string for GPS GGA GSA GSV GLL RMC VTG ZDA cksum + char init_gps[16] = {0xA0,0xA1,0x00,0x09,0x08,0x0A,0x0A,0x0A,0x00,0x01,0x00,0x00,0x00,0x03,0x0D,0x0A}; + char chk_char; + uint8_t calc_cksum; + uint8_t nema_cksum; + char nema_id[2]; + char nema_str[80]; + char cksum_str[2]; + +// _getSentenceThread.signal_wait(START_THREAD); +// logInfo("GPS starting\r\n"); + + _gps_uart->rxClear(); + _gps_uart->write(init_gps, sizeof(init_gps)); + + while (! _gps_uart->readable()) { +// logInfo("GPS UART NOT READABLE\n\r"); + osDelay(1000); + } + + do { + _gps_uart->read(chk_char); + } while ((chk_char != 0xA0) && (!_gps_uart->rxEmpty())); + + if (chk_char == 0xA0) { + _gps_uart->read(chk_char); +// logInfo("read char %#X\r\n", chk_char); + if (chk_char == 0xA1) { + _gps_uart->read(chk_char); + //logInfo("read char %#X\r\n", chk_char); + _gps_uart->read(chk_char); + //logInfo("read char %#X\r\n", chk_char); + _gps_uart->read(chk_char); + //logInfo("read char %#X\r\n", chk_char); + if (chk_char == 0x83) { + _gps_detected = true; + } + } + } + +// logInfo("GPS detected %s\r\n", _gps_detected ? "true" : "false"); + + if (! _gps_detected) { + _fix_status = 0; + return; + } + + if (_gps_uart->readable() > 80) { + do { + _gps_uart->read(chk_char); +// logInfo("read char %#X\r\n", chk_char); + } while ((chk_char != '$') && (!_gps_uart->rxEmpty())); + + if (chk_char == '$') { + _gps_uart->read(nema_id,2); + if (strpbrk(nema_id,"GP") != NULL) { + uint8_t i = 0; + calc_cksum = 0x17; // 8 bit XOR of G and P checksum seed + nema_cksum = 0; // initialize nema string checksum + memset(nema_str,0x00,80); // clear nema_str array + do { + _gps_uart->read(chk_char); + if ((chk_char != 0x0D) && (chk_char != '*')) { + nema_str[i++] = chk_char; + calc_cksum ^= chk_char; // 8 bit XOR checksum + } + if (chk_char == '*') { + _gps_uart->read(cksum_str,2); + nema_cksum = (uint8_t)strtoul(cksum_str,NULL,16); + } + } while (( chk_char != 0x0D) && !_gps_uart->rxEmpty()); + +// logInfo("STR %s\n", nema_str); + + if (nema_cksum == calc_cksum) { + if (strncmp (nema_str,"GGA",3) == 0) { + parseGGA(nema_str); + } else if (strncmp (nema_str,"GSA",3) == 0) { + parseGSA(nema_str); + } else if (strncmp (nema_str,"GSV",3) == 0) { + parseGSV(nema_str); + } else if (strncmp (nema_str,"GLL",3) == 0) { + parseGLL(nema_str); + } else if (strncmp (nema_str,"RMC",3) == 0) { + parseRMC(nema_str); + } else if (strncmp (nema_str,"VTG",3) == 0) { + parseVTG(nema_str); + } else if (strncmp (nema_str,"ZDA",3) == 0) { + parseZDA(nema_str); + } else { +// logInfo("Unknown NEMA String Type\r\n"); + } + + return 1; + } else { +// logInfo("NEMA String checksum error %x != %x\r\n",nema_cksum,calc_cksum); + return 0; + } + } + } else +// logInfo("RX empty before all data read\r\n"); + return 0; + } + return 0; + +// if (_led) { +// if (_fix_status >= 2) { +// if (_tick_running) { +// _tick.detach(); +// _tick_running = false; +// } +//// _led->setPWM(NCP5623B::LED_3, 8); +// } else { +// if (! _tick_running) { +// _tick.attach(this, &GPSPARSER::blinker, 0.5); +// _tick_running = true; +// } +// } +// } + +} + +uint8_t GPSPARSER::parseGGA(char *nema_buf) +{ + char* token_str; + uint8_t ret = 0; + + _mutex.lock(); + + token_str = strtok(nema_buf, ","); +// skip timestamp + token_str = strtok(NULL, ","); +// skip latitude degrees minutes + token_str = strtok(NULL, ","); + token_str = strtok(NULL, ","); +// skip longitude degree minutes + token_str = strtok(NULL, ","); + token_str = strtok(NULL, ","); +// read fix quality + token_str = strtok(NULL, ","); + _fix_quality = atoi(token_str); +// skip number of satellites and horizontal dilution + token_str = strtok(NULL, ","); + token_str = strtok(NULL, ","); +// read msl altitude in meters + token_str = strtok(NULL, ","); + _msl_altitude = atoi(token_str); + + _mutex.unlock(); + + return ret; +} + +uint8_t GPSPARSER::parseGSA(char *nema_buf) +{ + char* token_str; + uint8_t ret = 0; + + _mutex.lock(); + + token_str = strtok(nema_buf, ","); + token_str = strtok(NULL, ","); +// read fix status + token_str = strtok(NULL, ","); + _fix_status = atoi(token_str); +// read satellite PRNs + for (uint8_t i=0; i<12; i++) { + token_str = strtok(NULL, ","); + _satellite_prn[i] = atoi(token_str); + } + + _mutex.unlock(); + + return ret; +} + +uint8_t GPSPARSER::parseGSV(char *nema_buf) +{ + char* token_str; + uint8_t ret = 0; + + _mutex.lock(); + + token_str = strtok(nema_buf, ","); +// skip number of sentences and sentence number for now + token_str = strtok(NULL, ","); + token_str = strtok(NULL, ","); +// read Number of satellites + token_str = strtok(NULL, ","); + _num_satellites = atoi(token_str); +// add code to read satellite specs if needed + + _mutex.unlock(); + + return ret; +} + +uint8_t GPSPARSER::parseRMC(char *nema_buf) +{ + char* token_str; + char temp_str[6]; + uint8_t ret = 0; + + _mutex.lock(); + + token_str = strtok(nema_buf, ","); +// read timestamp + token_str = strtok(NULL, ","); + strncpy(temp_str,token_str,2); + _timestamp.tm_hour = atoi(temp_str); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str+2,2); + _timestamp.tm_min = atoi(temp_str); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str+4,2); + _timestamp.tm_sec = atoi(temp_str); +// set gps_status true = active + token_str = strtok(NULL, ","); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str,1); + if (temp_str[0] == 'A') + _gps_status = true; + else + _gps_status = false; +// read latitude degrees minutes + token_str = strtok(NULL, "."); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str,2); + _gps_latitude.degrees = atoi(temp_str); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str+2,2); + _gps_latitude.minutes = atoi(temp_str); +// read fractional minutes + token_str = strtok(NULL, ","); + _gps_latitude.seconds = atoi(token_str); +// read latitude hemisphere change sign if 'S' + token_str = strtok(NULL, ","); + if (token_str[0] == 'S') + _gps_latitude.degrees *= -1; +// read longitude degree minutes + token_str = strtok(NULL, "."); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str,3); + _gps_longitude.degrees = atoi(temp_str); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str+3,2); + _gps_longitude.minutes = atoi(temp_str); +// read fractional minutes + token_str = strtok(NULL, ","); + _gps_longitude.seconds = atoi(token_str); +// read longitude hemisphere change sign if 'W' + token_str = strtok(NULL, ","); + if (token_str[0] == 'W') + _gps_longitude.degrees *= -1; +// skip speed and track angle + token_str = strtok(NULL, ","); + token_str = strtok(NULL, ","); +// read date + token_str = strtok(NULL, ","); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str,2); + _timestamp.tm_mday = atoi(temp_str); + memset(temp_str,0x00,6); + strncpy(temp_str,token_str+2,2); + _timestamp.tm_mon = atoi(temp_str) - 1; + memset(temp_str,0x00,6); + strncpy(temp_str,token_str+4,2); + _timestamp.tm_year = atoi(temp_str) + 100; + + _mutex.unlock(); + + return ret; +} + +uint8_t GPSPARSER::parseVTG(char *nema_buf) +{ + uint8_t ret = 0; + //logInfo("ParseVTG****\r\n"); + //logInfo(nema_buf); + //logInfo("\r\n"); + return ret; +} + +uint8_t GPSPARSER::parseGLL(char *nema_buf) +{ + uint8_t ret = 0; + //logInfo("ParseGLL*****\r\n"); + //logInfo(nema_buf); + //logInfo("\r\n"); + return ret; +} + +uint8_t GPSPARSER::parseZDA(char *nema_buf) +{ + uint8_t ret = 0; + //logInfo("ParseZDA******\r\n"); + //logInfo(nema_buf); + //logInfo("\r\n"); + return ret; +} + +bool GPSPARSER::gpsDetected(void) +{ + bool detected; + + _mutex.lock(); + detected = _gps_detected; + _mutex.unlock(); + + return detected; +} + +GPSPARSER::longitude GPSPARSER::getLongitude(void) +{ + longitude lon; + + _mutex.lock(); + lon = _gps_longitude; + _mutex.unlock(); + + return lon; +} + +GPSPARSER::latitude GPSPARSER::getLatitude(void) +{ + latitude lat; + + _mutex.lock(); + lat = _gps_latitude; + _mutex.unlock(); + + return lat; +} + +struct tm GPSPARSER::getTimestamp(void) { + struct tm time; + + _mutex.lock(); + time = _timestamp; + _mutex.unlock(); + + return time; +} + +bool GPSPARSER::getLockStatus(void) +{ + bool status; + + _mutex.lock(); + status = _gps_status; + _mutex.unlock(); + + return status; +} + +uint8_t GPSPARSER::getFixStatus(void) +{ + uint8_t fix; + + _mutex.lock(); + fix = _fix_status; + _mutex.unlock(); + + return fix; +} + +uint8_t GPSPARSER::getFixQuality(void) +{ + uint8_t fix; + + _mutex.lock(); + fix = _fix_quality; + _mutex.unlock(); + + return fix; +} + +uint8_t GPSPARSER::getNumSatellites(void) +{ + uint8_t sats; + + _mutex.lock(); + sats = _num_satellites; + _mutex.unlock(); + + return sats; +} + +int16_t GPSPARSER::getAltitude(void) +{ + int16_t alt; + + _mutex.lock(); + alt = _msl_altitude; + _mutex.unlock(); + + return alt; +} + +void GPSPARSER::blinker() +{ + _led_state = (_led_state == 0) ? 8 : 0; +// _led->setPWM(NCP5623B::LED_3, _led_state); +} +
diff -r 290c505e3851 -r 55ea4f38710b GPS/GPSPARSER.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPS/GPSPARSER.h Wed Jan 11 04:12:39 2017 +0000 @@ -0,0 +1,209 @@ +/** + * @file GpsParser.h + * @brief NEMA String to Packet Parser - NEMA strings to compact packet data + * @author Tim Barr + * @version 1.0 + * @see http://www.kh-gps.de/nmea.faq + * @see http://www.catb.org/gpsd/NMEA.html + * @see http://www.skytraq.com.tw/products/Venus638LPx_PB_v3.pdf + * + * Copyright (c) 2015 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GPSPARSER_H +#define GPSPARSER_H + +#include "mbed.h" +#include "rtos.h" +#include "MTSSerial.h" +#include <string> +#include <vector> +#include <ctime> +#include "MTSLog.h" +#define START_THREAD 1 + +using namespace mts; + +class GPSPARSER +{ +public: + + /** + * @typedef struct latitude + * @brief latitude degrees, minutes, seconds structure + * range of degrees : 0 to 90 signed (negative degrees is South) + * range of minutes : 0 to 60 unsigned + * Range of seconds : 0-9999 unsigned or 1/10000 of a minute. + * Multiply by 6 and divide or modulus by 1000 to get seconds and fractional seconds + */ + typedef struct{int8_t degrees; uint8_t minutes; uint16_t seconds;} latitude; + + /** + * @typedef struct longitude + * @brief longitude degrees, minutes, seconds structure negative degrees is West + * range of degrees : 0 to 180 signed (negative degrees is West) + * range of minutes : 0 to 60 unsigned + * Range of seconds : 0-9999 unsigned or 1/10000 of a minute. + * Multiply by 6 and divide or modulus by 1000 to get seconds and fractional seconds + */ + typedef struct{int16_t degrees; uint8_t minutes; uint16_t seconds;} longitude; + + /** + * @typdef satellite_prn + * @brief satellite prn list, up to 12 valid + */ + typedef uint8_t satellite_prn[12]; + + /** Create the GPSPARSER object + * @param uart - an MTSSerial object + * @param led - an NCP5623B led controller object + */ + GPSPARSER(MTSSerial *uart); + + /** destroy the GPSPARSER object + */ + ~GPSPARSER(void); + + /** GPS device detected + * @return boolean whether GPS device detected + */ + bool gpsDetected(void); + + /** get longitude structure + * @return last valid NEMA string longitude data + */ + longitude getLongitude(void); + + /** get latitude structure + * @return last valid NEMA string latitude data + */ + latitude getLatitude(void); + + /** get timestamp structure + * @return last valid NEMA string time and date data + * uses tm struc from ctime standard library + */ + struct tm getTimestamp(void); + + /** get GPS Lock status + * @return boolean of last valid NEMA string lock status data + */ + bool getLockStatus(void); + + /** get GPS Fix status + * @return last valid NEMA Fix status data + * 1 = no fix + * 2 = 2D fix - latitude, longitude, time only valid + * 3 = 3D fix - all data valid + */ + uint8_t getFixStatus(void); + + /** get GPS Fix qualty + * @return last valid NEMA string Fix Quality data + * 0 = invalid + * 1 = GPS fix (SPS) + * 2 = DGPS fix + * 3 = PPS fix + * 4 = Real Time Kinematic + * 5 = Float RTK + * 6 = estimated (dead reckoning) (2.3 feature) + * 7 = Manual input mode + * 8 = Simulation mode + */ + uint8_t getFixQuality(void); + + /** get number of visible satellites + * @return last valid NEMA string number of satellites visible + */ + uint8_t getNumSatellites(void); + + /** get calculated altitude + * @return last valid NEMA string altitude data in meters + */ + int16_t getAltitude(void); + + /** Read NEMA sentences from specified serial port and call specific sentence parser + */ + int readNemaSentence (void); + + char rmc_buf[100]; + +private: + + std::string _nema_buff; + bool _gps_detected; + latitude _gps_latitude; + longitude _gps_longitude; + struct tm _timestamp; + bool _gps_status; + uint8_t _fix_status; + uint8_t _fix_quality; + uint8_t _num_satellites; + satellite_prn _satellite_prn; + int16_t _msl_altitude; + + MTSSerial *_gps_uart; + Thread _getSentenceThread; +// NCP5623B* _led; + int8_t _led_state; + Ticker _tick; + bool _tick_running; + Mutex _mutex; + + /** Start sentence parser thread + * + */ + static void startSentenceThread (void const *p); + + /** Parse GGA NEMA sentence + * @return status of parser attempt + */ + uint8_t parseGGA(char *nema_buf); + + /** Parse GSA NEMA sentence + * @return status of parser attempt + */ + uint8_t parseGSA(char *nema_buf); + + /** Parse GSV NEMA sentence + * @return status of parser attempt + */ + uint8_t parseGSV(char *nema_buf); + + /** Parse RMC NEMA sentence + * @return status of parser attempt + */ + uint8_t parseRMC(char *nema_buf); + + /** Parse VTG NEMA sentence + * @return status of parser attempt + */ + uint8_t parseVTG(char *nema_buf); + + /** Parse GLL NEMA sentence + * @return status of parser attempt + */ + uint8_t parseGLL(char *nema_buff); + + /** Parse ZDA NEMA sentence + * @return status of parser attempt + */ + uint8_t parseZDA(char *nema_buff); + + void blinker(); + +}; +#endif
diff -r 290c505e3851 -r 55ea4f38710b MMA845x.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MMA845x.lib Wed Jan 11 04:12:39 2017 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/1994timmeh/code/MMA845x_timmeh/#555f8ba0c959
diff -r 290c505e3851 -r 55ea4f38710b MTS-Serial.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MTS-Serial.lib Wed Jan 11 04:12:39 2017 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/MultiTech/code/MTS-Serial/#4afbbafcd6b3
diff -r 290c505e3851 -r 55ea4f38710b main.cpp --- a/main.cpp Thu Jan 05 05:55:42 2017 +0000 +++ b/main.cpp Wed Jan 11 04:12:39 2017 +0000 @@ -11,7 +11,7 @@ * (You need to use your own device IDs, the ones shown here are examples only) * *./ttnctl devices register 0080000000000000 - * INFO Generating random AppKey... + * INFO Generating random AppKey... * INFO Registered device AppKey=000102030405060708090A0B0C0D0E0F DevEUI=0080000000000000 * * or to specify the same AppKey for a new device or to reregister the same device again: @@ -43,16 +43,36 @@ #include "MTSText.h" #include <string> #include <vector> +#include "MMA845x.h" +#include "GPSPARSER.h" +#include "DOGS102.h" +#include "font_6x8.h" using namespace mts; #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) +#define NUMSAMPLES 1000 + + + +typedef struct { + int lat_d; + int lat_m; + int lat_s; + int lng_d; + int lng_m; + int lng_s; + int x; + int y; + int z; +} Coordinate; + // AppEUI -uint8_t AppEUI[8]={0x02, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xFF, 0xC0}; +uint8_t AppEUI[8]= {0x02, 0x00, 0x00, 0x00, 0x00, 0xEE, 0xFF, 0xC0}; // AppKey -uint8_t AppKey[16]={0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16}; +uint8_t AppKey[16]= {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16}; // Some defines for the LoRa configuration /* @@ -74,30 +94,59 @@ * DR3 - SF7BW125 * DR4 - SF8BW500 */ -#define LORA_SF mDot::DR5 +#define LORA_SF mDot::DR4 #define LORA_ACK 0 -#define LORA_TXPOWER 14 +#define LORA_TXPOWER 20 // Ignoring sub band for EU modules. static uint8_t config_frequency_sub_band = 1; +volatile int stoppls = 0; -// DS18B20 OneWire pin -// D13 on Dev Board, pin 18 on mDot, Compatible with Oxford Flood Network PCB temperature sensor. -//#define DATA_PIN PA_5 -// A1 on Dev Board, pin 19 on mDot -#define DATA_PIN PC_13 - -// Temperature sensor object -DS1820 probe(DATA_PIN); - -// BME280 Temperature/Humidity/Pressure sensor -//BME280 sensor(I2C_SDA, I2C_SCL); +SPI lcd_spi(SPI1_MOSI, SPI1_MISO, SPI1_SCK); +DigitalOut lcd_spi_cs(SPI1_CS, 1); +DigitalOut lcd_cd(XBEE_ON_SLEEP, 1); // Serial via USB for debugging only Serial pc(USBTX,USBRX); -int main() +MMA845x_DATA accldata; + +void gpsthread(void const *args) { + while(1) { + GPSPARSER *instance = (GPSPARSER*)args; + instance->readNemaSentence(); + } +} + +void acclthread(void const *args) { + + /* Create global i2c handle */ + I2C i2chandle = I2C(PC_9, PA_8); + + MMA845x instance = MMA845x(i2chandle, MMA845x::SA0_VSS); + + instance.setCommonParameters(MMA845x::RANGE_8g,MMA845x::RES_MAX,MMA845x::LN_OFF, + MMA845x::DR_50,MMA845x::OS_NORMAL,MMA845x::HPF_OFF ); + + instance.activeMode(); + + /* Accelerometer testing code */ + while(1) { + + if (!stoppls) { + int result = instance.getStatus(); + if((result & MMA845x::XYZDR) != 0 ) { + accldata = instance.getXYZ(); + + logInfo("Accl: %d %d %d\n\r", instance.getXYZ()._x, instance.getXYZ()._y, instance.getXYZ()._z); + } + } + + } +} + +int main() { int32_t ret; mDot* dot; std::vector<uint8_t> send_data; @@ -105,25 +154,29 @@ std::vector<uint8_t> nwkId; std::vector<uint8_t> nwkKey; - float temperature = 0.0; - float humidity = 0.0; - float pressure = 0.0; + dot = mDot::getInstance(); + dot->setLogLevel(MTSLog::INFO_LEVEL); + logInfo("Starting...\n\r"); - pc.baud(115200); - pc.printf("TTN OTAA mDot LoRa Temperature sensor\n\r"); + GPSPARSER* gps; + MTSSerial gps_serial(XBEE_DOUT, XBEE_DIN, 256, 2048); + gps = new GPSPARSER(&gps_serial); + Thread gpst(gpsthread, gps); - // get a mDot handle - dot = mDot::getInstance(); + Thread acclt(acclthread); -// dot->setLogLevel(MTSLog::WARNING_LEVEL); - dot->setLogLevel(MTSLog::TRACE_LEVEL); + DOGS102* lcd = new DOGS102(lcd_spi, lcd_spi_cs, lcd_cd); + + DigitalIn button(PA_11); + button.mode(PullUp); +#ifdef ENABLE_LORA logInfo("Checking Config"); uint8_t *it = AppEUI; for (uint8_t i = 0; i<8; i++) nwkId.push_back((uint8_t) *it++); - + it = AppKey; for (uint8_t i = 0; i<16; i++) nwkKey.push_back((uint8_t) *it++); @@ -209,21 +262,21 @@ // Display LoRa parameters // Display label and values in different colours, show pretty values not numeric values where applicable -/* - pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") ); - pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() ); - pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() ); - pc.printf("Join Mode: %s\r\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() ); - pc.printf("Join Retries: %d\r\n", dot->getJoinRetries() ); - pc.printf("Join Byte Order: %s\r\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") ); - pc.printf("Link Check Count: %d\r\n", dot->getLinkCheckCount() ); - pc.printf("Link Check Thold: %d\r\n", dot->getLinkCheckThreshold() ); - pc.printf("Tx Data Rate: %s\r\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() ); - pc.printf("Tx Power: %d\r\n", dot->getTxPower() ); - pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" )); - pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") ); - pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N") ); -*/ + /* + pc.printf("Public Network: %s\r\n", (char*)(dot->getPublicNetwork() ? "Yes" : "No") ); + pc.printf("Frequency: %s\r\n", (char*)mDot::FrequencyBandStr(dot->getFrequencyBand()).c_str() ); + pc.printf("Sub Band: %s\r\n", (char*)mDot::FrequencySubBandStr(dot->getFrequencySubBand()).c_str() ); + pc.printf("Join Mode: %s\r\n", (char*)mDot::JoinModeStr(dot->getJoinMode()).c_str() ); + pc.printf("Join Retries: %d\r\n", dot->getJoinRetries() ); + pc.printf("Join Byte Order: %s\r\n", (char*)(dot->getJoinByteOrder() == 0 ? "LSB" : "MSB") ); + pc.printf("Link Check Count: %d\r\n", dot->getLinkCheckCount() ); + pc.printf("Link Check Thold: %d\r\n", dot->getLinkCheckThreshold() ); + pc.printf("Tx Data Rate: %s\r\n", (char*)mDot::DataRateStr(dot->getTxDataRate()).c_str() ); + pc.printf("Tx Power: %d\r\n", dot->getTxPower() ); + pc.printf("TxWait: %s, ", (dot->getTxWait() ? "Y" : "N" )); + pc.printf("CRC: %s, ", (dot->getCrc() ? "Y" : "N") ); + pc.printf("Ack: %s\r\n", (dot->getAck() ? "Y" : "N") ); + */ logInfo("Joining Network"); while ((ret = dot->joinNetwork()) != mDot::MDOT_OK) { @@ -234,49 +287,98 @@ logInfo("Joined Network"); // Display Network session key and data session key from Join command -/* - std::vector<uint8_t> tmp = dot->getNetworkSessionKey(); - pc.printf("Network Session Key: "); - pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str()); + /* + std::vector<uint8_t> tmp = dot->getNetworkSessionKey(); + pc.printf("Network Session Key: "); + pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str()); - tmp = dot->getDataSessionKey(); - pc.printf("Data Session Key: "); - pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str()); -*/ - // Set the Temperature sesnor resolution, 9 bits is enough and makes it faster to provide a reading. - probe.setResolution(9); + tmp = dot->getDataSessionKey(); + pc.printf("Data Session Key: "); + pc.printf("%s\r\n", mts::Text::bin2hexString(tmp, " ").c_str()); + */ +#endif /* ENABLE_LORA */ char dataBuf[50]; + uint16_t count = 0; + Coordinate points[NUMSAMPLES]; + int mode = 0; while( 1 ) { - // Output data as JSON e.g. {"t":21.3} -// temperature = sensor.getTemperature(); -// humidity = sensor.getHumidity(); -// pressure = sensor.getPressure(); + + lcd->writeText(0, 0, font_6x8, "Not saving", 10); + + if (!button.read()) { + count = 0; + mode = 1; + } + + if (mode) { + + lcd->writeText(0, 0, font_6x8, "Saving ", 10); + + Coordinate a = { gps->getLongitude().degrees, gps->getLongitude().minutes, gps->getLongitude().seconds, gps->getLatitude().degrees, gps->getLatitude().minutes, gps->getLatitude().seconds , accldata._x, accldata._y, accldata._z}; + points[count] = a; + count++; + } + + lcd->writeText(0, 1, font_6x8, (gps->getLockStatus() ? "GPS Locked " : "No GPS Lock"), 11); + + if (gps->getLockStatus()) { + + sprintf(dataBuf, "Lat: %d,%d,%d", gps->getLatitude().degrees, gps->getLatitude().minutes, gps->getLatitude().seconds); + lcd->writeText(0, 2, font_6x8, dataBuf, strlen(dataBuf)); + + sprintf(dataBuf, "Long: %d,%d,%d", gps->getLongitude().degrees, gps->getLongitude().minutes, gps->getLongitude().seconds); + lcd->writeText(0, 3, font_6x8, dataBuf, strlen(dataBuf)); + + sprintf(dataBuf, "Sat: %d", gps->getNumSatellites()); + lcd->writeText(0, 4, font_6x8, dataBuf, strlen(dataBuf)); + + } + + sprintf(dataBuf, "%04d,%04d,%04d ", accldata._x, accldata._y, accldata._z); + lcd->writeText(0, 5, font_6x8, dataBuf, strlen(dataBuf)); + + sprintf(dataBuf, "Time: %02d", gps->getTimestamp().tm_sec); + lcd->writeText(0, 6, font_6x8, dataBuf, strlen(dataBuf)); - //Start temperature conversion, wait until ready - probe.convertTemperature(true, DS1820::all_devices); - // Output data as JSON e.g. {"t":21.3} - temperature = probe.temperature(); - sprintf(dataBuf, "{\"t\":%3.1f}", temperature ); -// sprintf(dataBuf, "%3.1f,%3.1f,%04.2f", temperature,humidity,pressure ); - pc.printf("%s\n",dataBuf); - send_data.clear(); - // probably not the most efficent way to do this - for( int i=0; i< strlen(dataBuf); i++ ) - send_data.push_back( dataBuf[i] ); + +#ifdef ENABLE_LORA + send_data.clear(); + // probably not the most efficent way to do this + for( int i=0; i< strlen(dataBuf); i++ ) { + send_data.push_back( dataBuf[i] ); + } + + if ((ret = dot->send(send_data)) != mDot::MDOT_OK) { + logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str()); + } else { + logInfo("send data: %s", Text::bin2hexString(send_data).c_str()); + } +#endif /* ENABLE_LORA */ + + sprintf(dataBuf, "C: %03d B: %d", count, button.read()); + lcd->writeText(0, 7, font_6x8, dataBuf, strlen(dataBuf)); - if ((ret = dot->send(send_data)) != mDot::MDOT_OK) { - logError("failed to send: [%d][%s]", ret, mDot::getReturnCodeString(ret).c_str()); - } else { - logInfo("send data: %s", Text::bin2hexString(send_data).c_str()); - } - - // Should sleep here and wakeup after a set 5 minute interval. - // in the 868 (EU) frequency band, we need to wait until another channel is available before transmitting again - uint32_t sleep_time = std::max((uint32_t)1000, (uint32_t)dot->getNextTxMs()) / 1000; -//wait_ms(2000); - // go to sleep and wake up automatically sleep_time seconds later - dot->sleep(sleep_time, mDot::RTC_ALARM); + osDelay(1000/50); + + if (count == NUMSAMPLES && mode) { + // Stop sampling + stoppls = 1; + while (1) { + sprintf(dataBuf, "C: %03d B: %d", count, button.read()); + lcd->writeText(0, 7, font_6x8, dataBuf, strlen(dataBuf)); + + if (!button.read()) { + logInfo("Starting..."); + for (int i = 0; i < NUMSAMPLES; i++) { + logInfo("%d,%d,%d,%d,%d,%d,%d,%d,%d", points[i].lat_d, points[i].lat_m, points[i].lat_s, points[i].lng_d, points[i].lng_m, points[i].lng_s, points[i].x, points[i].y, points[i].z); + osDelay(1); + } + logInfo("DONE"); + } + + osDelay(100); + } + } } - }