GPS testing
This commit is contained in:
parent
1850f94f71
commit
aa1b4172fe
68
README.md
68
README.md
@ -102,50 +102,43 @@ Legend for RGB LED (LoPy/LoPy4/FiPy/Lolin32 only):
|
||||
|
||||
# Payload
|
||||
|
||||
LoRaWAN Port #1: Counter data
|
||||
LoRaWAN Port #1:
|
||||
|
||||
byte 1: WiFi counter, MSB
|
||||
byte 2: WiFi counter, LSB
|
||||
byte 3: BLE counter, MSB
|
||||
byte 4: BLE counter, LSB
|
||||
byte 1: Paxcount Wifi, MSB
|
||||
byte 2: Paxcount WiFi, LSB
|
||||
byte 3: Paxcount Bluetooth, MSB
|
||||
byte 4: Paxcount Bluetooth, LSB
|
||||
bytes 5-8: GPS latitude
|
||||
bytes 9-12: GPS longitude
|
||||
bytes 13-14: GPS satellites
|
||||
bytes 15-16: GPS HDOP
|
||||
bytes 17-18: GPS altitude
|
||||
|
||||
LoRaWAN Port #2: Remote commands
|
||||
LoRaWAN Port #2:
|
||||
|
||||
see remote control
|
||||
|
||||
LoRaWAN Port #3: GPS data
|
||||
|
||||
bytes 1-4: Latitude
|
||||
bytes 4-8: Longitude
|
||||
bytes 9-10: Satellites
|
||||
bytes 11-12: HDOP
|
||||
bytes 13-14: Altitude
|
||||
|
||||
If you're using [TheThingsNetwork](https://www.thethingsnetwork.org/) you may want to use a payload converter. Go to TTN Console - Application - Payload Formats and paste the code example below in tabs Decoder and Converter. Make sure that your application parses the fields `pax`, `ble` and `wifi`.
|
||||
|
||||
Decoder:
|
||||
|
||||
```javascript
|
||||
function Decoder(bytes, port) {
|
||||
// decode counter messages
|
||||
var decoded = {};
|
||||
|
||||
if (port === 1) {
|
||||
decoded.wifi = (bytes[0] << 8) | bytes[1];
|
||||
decoded.ble = (bytes[2] << 8) | bytes[3];
|
||||
}
|
||||
|
||||
// decode GPS messages
|
||||
if (port === 3) {
|
||||
decoded.latitude = (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
|
||||
decoded.longitude = (bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4];
|
||||
decoded.satellites = (bytes[9] << 8) | bytes[8];
|
||||
decoded.hdop = (bytes[11] << 8) | bytes[10];
|
||||
decoded.altitude = (bytes[13] << 8) | bytes[12];
|
||||
decoded.latitude = ((bytes[7] << 24) | (bytes[6] << 16) | (bytes[5] << 8) | bytes[4]);
|
||||
decoded.longitude = ((bytes[11] << 24) | (bytes[10] << 16) | (bytes[9] << 8) | bytes[8]);
|
||||
decoded.satellites = (bytes[13] << 8) | bytes[12];
|
||||
decoded.hdop = (bytes[15] << 8) | bytes[14];
|
||||
decoded.altitude = (bytes[17] << 8) | bytes[16];
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Converter:
|
||||
@ -153,24 +146,24 @@ Converter:
|
||||
```javascript
|
||||
function Converter(decoded, port) {
|
||||
var converted = decoded;
|
||||
// sum up ble + wifi counters
|
||||
|
||||
if (port === 1) {
|
||||
converted.pax = converted.ble + converted.wifi;
|
||||
converted.hdop /= 100;
|
||||
converted.latitude /= 1000000;
|
||||
converted.longitude /= 1000000;
|
||||
}
|
||||
// convert some GPS values
|
||||
if (port === 3) {
|
||||
converted.latitude = converted.latitude / 100000;
|
||||
converted.longitude = converted.longitude / 100000;
|
||||
converted.hdop = converted.hdop / 100;
|
||||
|
||||
return converted;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
# Remote control
|
||||
# Remote command set
|
||||
|
||||
The device listenes for remote control commands on LoRaWAN Port 2.
|
||||
Each command is followed by exactly one parameter.
|
||||
For "set" commands, multiple command/parameter pairs can be concatenated and sent in one downlink, all commands are executed. For "get" commands, only one command/parameter pair per downlink is processed.
|
||||
Multiple command/parameter pairs can be concatenated and sent in one single payload downlink.
|
||||
|
||||
Note: all settings are stored in NVRAM and will be reloaded when device starts. To reset device to factory settings press button (if device has one), or send remote command 09 02 09 00 unconfirmed(!) once.
|
||||
|
||||
@ -185,10 +178,10 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
||||
1 = cumulative counter, mac counter is never reset
|
||||
2 = cyclic confirmed, like 0 but data is resent until confirmation by network received
|
||||
|
||||
0x03 set GPS on/off (NOT YET IMPLEMENTED)
|
||||
0x03 (NOT YET IMPLEMENTED) set screen saver mode
|
||||
|
||||
0 = GPS off [default]
|
||||
1 = GPS on, GPS data set (if present) is added to payload
|
||||
0 = screen saver off [default]
|
||||
1 = screen saver on
|
||||
|
||||
0x04 set display on/off
|
||||
|
||||
@ -258,7 +251,7 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
||||
|
||||
0x80 get device configuration
|
||||
|
||||
device answers with it's current configuration. The configuration is a C structure declared in file [globals.h](src/globals.h#L32-L50) with the following definition:
|
||||
device answers with it's current configuration. The configuration is a C structure declared in file [globals.h](src/globals.h#L27-L44) with the following definition:
|
||||
|
||||
byte 1: Lora SF (7..12)
|
||||
byte 2: Lora TXpower (2..15)
|
||||
@ -274,8 +267,7 @@ device answers with it's current configuration. The configuration is a C structu
|
||||
byte 13: Wifi antenna switch (0=internal, 1=external)
|
||||
byte 14: Vendorfilter mode (0=disabled, 1=enabled)
|
||||
byte 15: RGB LED luminosity (0..100 %)
|
||||
byte 16: GPS status (1=on, 0=off)
|
||||
bytes 17-27: Software version (ASCII format, terminating with zero)
|
||||
bytes 16-26: Software version (ASCII format, terminating with zero)
|
||||
|
||||
0x81 get device uptime
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
static const char TAG[] = "main";
|
||||
|
||||
// read GPS data and cast to global struct
|
||||
void gps_read(){
|
||||
void gps_read() {
|
||||
gps_status.latitude = (uint32_t) (gps.location.lat() * 1000000);
|
||||
gps_status.longitude = (uint32_t) (gps.location.lng() * 1000000);
|
||||
gps_status.satellites = (uint8_t) gps.satellites.value();
|
||||
@ -19,11 +19,10 @@ void gps_loop(void * pvParameters) {
|
||||
|
||||
configASSERT( ( ( uint32_t ) pvParameters ) == 1 ); // FreeRTOS check
|
||||
|
||||
#ifdef GPS_SERIAL
|
||||
// initialize and, if needed, configure, GPS
|
||||
#if defined GPS_SERIAL
|
||||
HardwareSerial GPS_Serial(1);
|
||||
#endif
|
||||
|
||||
#ifdef GPS_I2C
|
||||
#elif defined GPS_I2C
|
||||
// to be done
|
||||
#endif
|
||||
|
||||
@ -31,7 +30,8 @@ void gps_loop(void * pvParameters) {
|
||||
|
||||
if (cfg.gpsmode)
|
||||
{
|
||||
#ifdef GPS_SERIAL
|
||||
#if defined GPS_SERIAL
|
||||
|
||||
// serial connect to GPS device
|
||||
GPS_Serial.begin(GPS_SERIAL);
|
||||
|
||||
@ -39,19 +39,34 @@ void gps_loop(void * pvParameters) {
|
||||
// feed GPS decoder with serial NMEA data from GPS device
|
||||
while (GPS_Serial.available()) {
|
||||
gps.encode(GPS_Serial.read());
|
||||
}
|
||||
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
||||
}
|
||||
// after GPS function was disabled, close connect to GPS device
|
||||
GPS_Serial.end();
|
||||
|
||||
#elif defined GPS_I2C
|
||||
|
||||
// I2C connect to GPS device with 100 kHz
|
||||
Wire.begin(GPS_I2C_PINS, 100000);
|
||||
Wire.beginTransmission(GPS_I2C_ADDRESS_WRITE);
|
||||
Wire.write(0x00);
|
||||
|
||||
i2c_ret == Wire.beginTransmission(GPS_I2C_ADDRESS_READ);
|
||||
if (i2c_ret == 0) { // check if device seen on i2c bus
|
||||
while(cfg.gpsmode) {
|
||||
// feed GPS decoder with serial NMEA data from GPS device
|
||||
while (Wire.available()) {
|
||||
Wire.requestFrom(GPS_I2C_ADDRESS_READ, 255);
|
||||
gps.encode(Wire.read());
|
||||
vTaskDelay(1/portTICK_PERIOD_MS); // reset watchdog
|
||||
}
|
||||
}
|
||||
// after GPS function was disabled, close connect to GPS device
|
||||
GPS_Serial.end();
|
||||
#endif
|
||||
|
||||
#ifdef GPS_I2C
|
||||
// I2C connect to GPS device
|
||||
|
||||
/*
|
||||
to be done
|
||||
*/
|
||||
Wire.endTransmission();
|
||||
Wire.setClock(400000); // Set back to 400KHz to speed up OLED
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
@ -4,9 +4,13 @@
|
||||
#define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4
|
||||
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
||||
|
||||
// use only if your LoPy lives on a Pytrack expansion board
|
||||
// !!EXPERIMENTAL - not tested yet!!
|
||||
// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS
|
||||
// see http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf
|
||||
//#define HAS_GPS 1
|
||||
//#define GPS_I2C GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
||||
//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
||||
//#define GPS_I2C_ADDRESS_READ 0x21
|
||||
//#define GPS_I2C_ADDRESS_WRITE 0x20
|
||||
//#define HAS_BUTTON GPIO_NUM_4
|
||||
|
||||
// Hardware pin definitions for Pycom LoPy board
|
||||
|
@ -4,9 +4,13 @@
|
||||
#define HAS_LED NOT_A_PIN // LoPy4 has no on board LED, so we use RGB LED on LoPy4
|
||||
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
||||
|
||||
// use only if your LoPy lives on a Pytrack expansion board
|
||||
// !!EXPERIMENTAL - not tested yet!!f
|
||||
// uncomment this only if your LoPy lives on a Pytrack expansion board with GPS
|
||||
// see http://www.quectel.com/UploadImage/Downlad/Quectel_L76-L_I2C_Application_Note_V1.0.pdf
|
||||
//#define HAS_GPS 1
|
||||
//#define GPS_I2C GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
||||
//#define GPS_I2C_PINS GPIO_NUM_9, GPIO_NUM_8 // SDA, SCL
|
||||
//#define GPS_I2C_ADDRESS_READ 0x21
|
||||
//#define GPS_I2C_ADDRESS_WRITE 0x20
|
||||
//#define HAS_BUTTON GPIO_NUM_4
|
||||
|
||||
// Hardware pin definitions for Pycom LoPy4 board
|
||||
|
@ -129,16 +129,23 @@ void do_send(osjob_t* j){
|
||||
mydata[3] = 0;
|
||||
}
|
||||
|
||||
// Prepare upstream data transmission at the next possible time.
|
||||
#ifdef HAS_GPS
|
||||
static uint8_t gpsdata[18];
|
||||
if (cfg.gpsmode && gps.location.isValid()) {
|
||||
gps_read();
|
||||
memcpy (gpsdata+4, &gps_status, sizeof(gps_status));
|
||||
memcpy (gpsdata, mydata, 4);
|
||||
ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude);
|
||||
LMIC_setTxData2(COUNTERPORT, gpsdata, sizeof(gpsdata), (cfg.countermode & 0x02));
|
||||
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(gpsdata));
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
LMIC_setTxData2(COUNTERPORT, mydata, sizeof(mydata), (cfg.countermode & 0x02));
|
||||
ESP_LOGI(TAG, "%d bytes queued to send", sizeof(mydata));
|
||||
sprintf(display_lmic, "PACKET QUEUED");
|
||||
|
||||
#ifdef HAS_GPS
|
||||
if (cfg.gpsmode && gps.location.isValid()) {
|
||||
gps_read();
|
||||
LMIC_setTxData2(GPSPORT, (byte*)&gps_status, sizeof(gps_status), (cfg.countermode & 0x02));
|
||||
ESP_LOGI(TAG, "lat=%f / lon=%f | Sats=%u | HDOP=%u | Alti=%u", gps_status.latitude / 1000000, gps_status.longitude / 1000000, gps_status.satellites, gps_status.hdop, gps_status.altitude);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -178,10 +185,6 @@ void onEvent (ev_t ev) {
|
||||
strcpy_P(buff, PSTR("JOINED"));
|
||||
sprintf(display_lora, " "); // clear previous lmic status message from display
|
||||
|
||||
// Disable link check validation (automatically enabled
|
||||
// during join, but not supported by TTN at this time). -> do we need this?
|
||||
// LMIC_setLinkCheckMode(0);
|
||||
|
||||
// set data rate adaptation
|
||||
LMIC_setAdrMode(cfg.adrmode);
|
||||
// Set data rate and transmit power (note: txpower seems to be ignored by the library)
|
||||
|
Loading…
Reference in New Issue
Block a user