senddata restructured

This commit is contained in:
Klaus K Wilting 2018-07-14 20:07:33 +02:00
parent f0cf08bd75
commit 786714d69a
18 changed files with 129 additions and 77 deletions

View File

@ -16,9 +16,11 @@
#include <TinyGPS++.h>
#endif
#ifdef HAS_LORA
// LMIC-Arduino LoRaWAN Stack
#include <lmic.h>
#include <hal/hal.h>
#endif
// LED controls
#ifdef HAS_RGB_LED
@ -31,9 +33,8 @@
#include "payload.h"
extern configData_t cfg;
extern char display_line6[], display_line7[];
extern uint64_t uptimecounter;
extern osjob_t sendjob, rcmdjob;
extern char display_lora[], display_lmic[];
extern int countermode, screensaver, adrmode, lorasf, txpower, rlim;
extern uint16_t macs_total, macs_wifi, macs_ble; // MAC counters
extern std::set<uint16_t> macs;

View File

@ -1,20 +1,23 @@
// Hardware related definitions for Pycom FiPy Board
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1272_radio 1
#define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM
#define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM
// Hardware pin definitions for Pycom FiPy board
#define PIN_SPI_SS GPIO_NUM_18
#define PIN_SPI_MOSI GPIO_NUM_27
#define PIN_SPI_MISO GPIO_NUM_19
#define PIN_SPI_SCK GPIO_NUM_5
#define RST LMIC_UNUSED_PIN
#define DIO0 GPIO_NUM_23 // LoRa IRQ
#define DIO1 GPIO_NUM_23 // workaround
#define DIO2 LMIC_UNUSED_PIN
#define PIN_SPI_SS GPIO_NUM_18
#define PIN_SPI_MOSI GPIO_NUM_27
#define PIN_SPI_MISO GPIO_NUM_19
#define PIN_SPI_SCK GPIO_NUM_5
#define RST LMIC_UNUSED_PIN
#define DIO0 GPIO_NUM_23 // LoRa IRQ
#define DIO1 GPIO_NUM_23 // workaround
#define DIO2 LMIC_UNUSED_PIN
// select WIFI antenna (internal = onboard / external = u.fl socket)
#define HAS_ANTENNA_SWITCH GPIO_NUM_21 // pin for switching wifi antenna
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external
#define HAS_ANTENNA_SWITCH GPIO_NUM_21 // pin for switching wifi antenna
#define WIFI_ANTENNA 0 // 0 = internal, 1 = external

View File

@ -1,5 +1,7 @@
// Hardware related definitions for Heltec LoRa-32 Board
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board

View File

@ -13,6 +13,8 @@
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1 // RFM95 module
// re-define pin definitions of pins_arduino.h

View File

@ -12,6 +12,8 @@
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1 // RFM95 module
// re-define pin definitions of pins_arduino.h

View File

@ -1,5 +1,7 @@
// Hardware related definitions for Pycom LoPy Board (not: LoPy4)
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1272_radio 1
#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

View File

@ -1,5 +1,7 @@
// Hardware related definitions for Pycom LoPy Board (not: LoPy4)
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1
#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

View File

@ -1,5 +1,7 @@
// Hardware related definitions for TTGO T-Beam board
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM

View File

@ -1,5 +1,7 @@
// Hardware related definitions for TTGOv1 board
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C // OLED-Display on board

View File

@ -1,5 +1,7 @@
// Hardware related definitions for TTGO V2 Board
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C

View File

@ -6,7 +6,8 @@
/ - labelled v1.6 on pcb -> "new"
*/
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C

View File

@ -1,3 +1,5 @@
#ifdef HAS_LORA
/************************************************************
* LMIC LoRaWAN configuration
*
@ -29,3 +31,5 @@ static const u1_t APPEUI[8] = {0x70, 0xB3, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00};
static const u1_t APPKEY[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#endif // HAS_LORA

View File

@ -1,3 +1,5 @@
#ifdef HAS_LORA
// Basic Config
#include "globals.h"
@ -152,7 +154,7 @@ void onEvent(ev_t ev) {
case EV_JOINED:
strcpy_P(buff, PSTR("JOINED"));
sprintf(display_lora, " "); // clear previous lmic status
sprintf(display_line6, " "); // clear previous lmic status
// set data rate adaptation
LMIC_setAdrMode(cfg.adrmode);
@ -169,14 +171,14 @@ void onEvent(ev_t ev) {
strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK")
: PSTR("TX COMPLETE"));
sprintf(display_lora, " "); // clear previous lmic status
sprintf(display_line6, " "); // clear previous lmic status
if (LMIC.dataLen) {
ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d",
LMIC.dataLen, LMIC.rssi, (signed char)LMIC.snr / 4);
// LMIC.snr = SNR twos compliment [dB] * 4
// LMIC.rssi = RSSI [dBm] (-196...+63)
sprintf(display_lora, "RSSI %d SNR %d", LMIC.rssi,
sprintf(display_line6, "RSSI %d SNR %d", LMIC.rssi,
(signed char)LMIC.snr / 4);
// check if payload received on command port, then call remote command
@ -205,7 +207,9 @@ void onEvent(ev_t ev) {
// Log & Display if asked
if (*buff) {
ESP_LOGI(TAG, "EV_%s", buff);
sprintf(display_lmic, buff);
sprintf(display_line7, buff);
}
} // onEvent()
#endif // HAS_LORA

View File

@ -1,3 +1,5 @@
#ifdef HAS_LORA
#ifndef LORAWAN_H
#define LORAWAN_H
@ -7,3 +9,5 @@ void RevBytes(unsigned char *b, size_t c);
void get_hard_deveui(uint8_t *pdeveui);
#endif
#endif // HAS_LORA

View File

@ -28,10 +28,12 @@ licenses. Refer to LICENSE.txt file in repository for more details.
// Does nothing and avoid any compilation error with I2C
#include <Wire.h>
#ifdef HAS_LORA
// LMIC-Arduino LoRaWAN Stack
#include "loraconf.h"
#include <hal/hal.h>
#include <lmic.h>
#endif
// ESP32 lib Functions
#include <esp32-hal-log.h> // needed for ESP_LOGx on arduino framework
@ -39,15 +41,14 @@ licenses. Refer to LICENSE.txt file in repository for more details.
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
// Initialize global variables
configData_t cfg; // struct holds current device configuration
osjob_t sendjob, rcmdjob; // LMIC job handler
uint64_t uptimecounter = 0; // timer global for uptime counter
uint8_t DisplayState = 0; // globals for state machine
configData_t cfg; // struct holds current device configuration
char display_line6[16], display_line7[16]; // display buffers
uint64_t uptimecounter = 0; // timer global for uptime counter
uint8_t DisplayState = 0; // globals for state machine
uint16_t macs_total = 0, macs_wifi = 0,
macs_ble = 0; // MAC counters globals for display
uint8_t channel = 0; // wifi channel rotation counter global for display
char display_lora[16], display_lmic[16]; // display buffers
led_states LEDState = LED_OFF; // LED state global for state machine
led_states LEDState = LED_OFF; // LED state global for state machine
led_states previousLEDState =
LED_ON; // This will force LED to be off at boot since State is OFF
unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started)
@ -105,6 +106,8 @@ void reset_counters() {
/* begin LMIC specific parts
* ------------------------------------------------------------ */
#ifdef HAS_LORA
#ifdef VERBOSE
void printKeys(void);
#endif // VERBOSE
@ -156,6 +159,8 @@ void lorawan_loop(void *pvParameters) {
}
}
#endif // HAS_LORA
/* end LMIC specific parts
* --------------------------------------------------------------- */
@ -238,6 +243,7 @@ uint64_t uptime() {
#ifdef HAS_DISPLAY
#ifdef HAS_LORA
// Print a key on display
void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) {
const uint8_t *p;
@ -247,6 +253,7 @@ void DisplayKey(const uint8_t *key, uint8_t len, bool lsb) {
}
u8x8.printf("\n");
}
#endif // HAS_LORA
void init_display(const char *Productname, const char *Version) {
uint8_t buf[32];
@ -289,9 +296,13 @@ void init_display(const char *Productname, const char *Version) {
u8x8.print(Productname);
u8x8.print(" v");
u8x8.println(PROGVERSION);
#ifdef HAS_LORA
u8x8.println("DEVEUI:");
os_getDevEui((u1_t *)buf);
DisplayKey(buf, 8, true);
#endif // HAS_LORA
delay(5000);
u8x8.clear();
}
@ -325,6 +336,8 @@ void refreshDisplay() {
else
u8x8.printf("%s", "BLTH:off");
#endif
#ifdef HAS_LORA
u8x8.setCursor(11, 3);
u8x8.printf("SF:");
if (cfg.adrmode) // if ADR=on then display SF value inverse
@ -333,6 +346,7 @@ void refreshDisplay() {
lora_datarate[LMIC.datarate * 2 + 1]);
if (cfg.adrmode) // switch off inverse if it was turned on
u8x8.setInverseFont(0);
#endif // HAS_LORA
// update wifi counter + channel display (line 4)
u8x8.setCursor(0, 4);
@ -346,13 +360,15 @@ void refreshDisplay() {
u8x8.setCursor(10, 5);
u8x8.printf("%4dKB", ESP.getFreeHeap() / 1024);
#ifdef HAS_LORA
// update LoRa status display (line 6)
u8x8.setCursor(0, 6);
u8x8.printf("%-16s", display_lora);
u8x8.printf("%-16s", display_line6);
// update LMiC event display (line 7)
u8x8.setCursor(0, 7);
u8x8.printf("%-16s", display_lmic);
u8x8.printf("%-16s", display_line7);
#endif // HAS_LORA
}
void updateDisplay() {
@ -417,6 +433,7 @@ void led_loop() {
// No custom blink, check LoRaWAN state
} else {
#ifdef HAS_LORA
// LED indicators for viusalizing LoRaWAN state
if (LMIC.opmode & (OP_JOINING | OP_REJOIN)) {
LEDColor = COLOR_YELLOW;
@ -425,7 +442,7 @@ void led_loop() {
} else if (LMIC.opmode & (OP_TXDATA | OP_TXRXPEND)) {
LEDColor = COLOR_BLUE;
// small blink 10ms on each 1/2sec (not when joining)
LEDState = ((millis() % 500) < 20) ? LED_ON : LED_OFF;
LEDState = ((millis() % 500) < 10) ? LED_ON : LED_OFF;
// This should not happen so indicate a problem
} else if (LMIC.opmode &
((OP_TXDATA | OP_TXRXPEND | OP_JOINING | OP_REJOIN) == 0)) {
@ -433,6 +450,7 @@ void led_loop() {
// heartbeat long blink 200ms on each 2 seconds
LEDState = ((millis() % 2000) < 200) ? LED_ON : LED_OFF;
} else {
#endif // HAS_LORA
// led off
LEDColor = COLOR_NONE;
LEDState = LED_OFF;
@ -448,14 +466,14 @@ void led_loop() {
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, LOW);
#else
digitalWrite(HAS_LED, HIGH);
digitalWrite(HAS_LED, HIGH);
#endif
} else {
rgb_set_color(COLOR_NONE);
#ifdef LED_ACTIVE_LOW
digitalWrite(HAS_LED, HIGH);
#else
digitalWrite(HAS_LED, LOW);
digitalWrite(HAS_LED, LOW);
#endif
}
previousLEDState = LEDState;
@ -571,7 +589,9 @@ void setup() {
u8x8.setCursor(0, 5);
u8x8.printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%d", cfg.rssilimit);
sprintf(display_lora, "Join wait");
#ifdef HAS_LORA
sprintf(display_line6, "Join wait");
#endif // HAS_LORA
// setup display refresh trigger IRQ using esp32 hardware timer 0
// for explanation see
@ -604,7 +624,9 @@ void setup() {
// show compiled features
ESP_LOGI(TAG, "Features: %s", features);
// output LoRaWAN keys to console
#ifdef HAS_LORA
// output LoRaWAN keys to console
#ifdef VERBOSE
printKeys();
#endif
@ -624,6 +646,7 @@ void setup() {
ESP_LOGI(TAG, "Starting Lora task on core 1");
xTaskCreatePinnedToCore(lorawan_loop, "loratask", 2048, (void *)1,
(5 | portPRIVILEGE_BIT), NULL, 1);
#endif
// start wifi in monitor mode and start channel rotation task on core 0
ESP_LOGI(TAG, "Starting Wifi task on core 0");
@ -672,7 +695,7 @@ void loop() {
uptimecounter = uptime() / 1000; // counts uptime in seconds (64bit)
// send data every x seconds, x/2 is configured in cfg.sendcycle
if (uptime() % (cfg.sendcycle * 20000) == 0)
if (uptime() % (cfg.sendcycle * 20000) < cfg.sendcycle * 2)
senddata(PAYLOADPORT);
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
@ -694,13 +717,13 @@ void loop() {
"free heap = %d bytes)",
esp_get_minimum_free_heap_size(), ESP.getFreeHeap());
senddata(PAYLOADPORT); // send data before clearing counters
reset_counters(); // clear macs container and reset all counters
reset_salt(); // get new salt for salting hashes
reset_counters(); // clear macs container and reset all counters
reset_salt(); // get new salt for salting hashes
}
#ifdef HAS_GPS
// log NMEA status every 60 seconds, useful for debugging GPS connection
if ((uptime() % 60000) == 0) {
if ((uptime() % 60000) < 60) {
ESP_LOGI(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d",
gps.passedChecksum(), gps.failedChecksum(),
gps.sentencesWithFix());

View File

@ -4,10 +4,6 @@
//
// Note: After editing, before "build", use "clean" button in PlatformIO!
//
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
#define HAS_SPI 1 // comment out if device shall not send data via SPI
// Verbose enables serial output
#define VERBOSE 1 // comment out to silence the device, for mute use build option
@ -51,6 +47,8 @@
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
#define RCMDPORT 2 // LoRaWAN Port on which device listenes for remote commands
#define PAYLOADPORT 1 // LoRaWAN Port on which device sends counts
#define STATUSPORT 2 // LoRaWAN Port on which device sends status query results
#define GPSPORT 3 // LoRaWAN Port on which device sends gps query results
// Default RGB LED luminosity (in %)
#define RGBLUMINOSITY 30 // 30%

View File

@ -7,8 +7,8 @@
#include "globals.h"
// LMIC-Arduino LoRaWAN Stack
#include <lmic.h>
#include <hal/hal.h>
//#include <lmic.h>
//#include <hal/hal.h>
// Local logging tag
static const char TAG[] = "main";
@ -30,23 +30,7 @@ void antenna_select(const uint8_t _ant);
uint16_t read_voltage(void);
#endif
// function sends result of get commands to LoRaWAN network
void do_transmit(osjob_t *j) {
// check if there is a pending TX/RX job running, if yes then reschedule
// transmission
if (LMIC.opmode & OP_TXRXPEND) {
ESP_LOGI(TAG, "LoRa busy, rescheduling");
sprintf(display_lmic, "LORA BUSY");
os_setTimedCallback(&rcmdjob, os_getTime() + sec2osticks(RETRANSMIT_RCMD),
do_transmit);
}
// send payload
LMIC_setTxData2(RCMDPORT, payload.getBuffer(), payload.getSize(),
(cfg.countermode & 0x02));
ESP_LOGI(TAG, "%d bytes queued to send", payload.getSize());
sprintf(display_lmic, "PACKET QUEUED");
}
#ifdef HAS_LORA
// help function to assign LoRa datarates to numeric spreadfactor values
void switch_lora(uint8_t sf, uint8_t tx) {
if (tx > 20)
@ -93,13 +77,14 @@ void switch_lora(uint8_t sf, uint8_t tx) {
break;
}
}
#endif // HAS_LORA
// set of functions that can be triggered by remote commands
void set_reset(uint8_t val) {
switch (val) {
case 0: // restart device
ESP_LOGI(TAG, "Remote command: restart device");
sprintf(display_lora, "Reset pending");
sprintf(display_line6, "Reset pending");
vTaskDelay(
10000 /
portTICK_PERIOD_MS); // wait for LMIC to confirm LoRa downlink to server
@ -109,11 +94,11 @@ void set_reset(uint8_t val) {
ESP_LOGI(TAG, "Remote command: reset MAC counter");
reset_counters(); // clear macs
reset_salt(); // get new salt
sprintf(display_lora, "Reset counter");
sprintf(display_line6, "Reset counter");
break;
case 2: // reset device to factory settings
ESP_LOGI(TAG, "Remote command: reset device to factory settings");
sprintf(display_lora, "Factory reset");
sprintf(display_line6, "Factory reset");
eraseConfig();
break;
}
@ -208,11 +193,16 @@ void set_gps(uint8_t val) {
};
void set_lorasf(uint8_t val) {
#ifdef HAS_LORA
ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val);
switch_lora(val, cfg.txpower);
#else
ESP_LOGW(TAG, "Remote command: LoRa not implemented");
#endif // HAS_LORA
};
void set_loraadr(uint8_t val) {
#ifdef HAS_LORA
ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s", val ? "on" : "off");
switch (val) {
case 1:
@ -224,6 +214,9 @@ void set_loraadr(uint8_t val) {
}
LMIC_setAdrMode(cfg.adrmode);
};
#else
ESP_LOGW(TAG, "Remote command: LoRa not implemented");
#endif // HAS_LORA
void set_blescan(uint8_t val) {
ESP_LOGI(TAG, "Remote command: set BLE scanner to %s", val ? "on" : "off");
@ -280,15 +273,19 @@ void set_rgblum(uint8_t val) {
};
void set_lorapower(uint8_t val) {
#ifdef HAS_LORA
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val);
switch_lora(cfg.lorasf, val);
#else
ESP_LOGW(TAG, "Remote command: LoRa not implemented");
#endif // HAS_LORA
};
void get_config(uint8_t val) {
ESP_LOGI(TAG, "Remote command: get device configuration");
payload.reset();
payload.addConfig(cfg);
do_transmit(&rcmdjob);
senddata(STATUSPORT);
};
void get_status(uint8_t val) {
@ -296,11 +293,11 @@ void get_status(uint8_t val) {
#ifdef HAS_BATTERY_PROBE
uint16_t voltage = read_voltage();
#else
uint16_t voltage = 0;
uint16_t voltage = 0;
#endif
payload.reset();
payload.addStatus(voltage, uptimecounter, temperatureRead());
do_transmit(&rcmdjob);
senddata(STATUSPORT);
};
void get_gps(uint8_t val) {
@ -309,9 +306,9 @@ void get_gps(uint8_t val) {
gps_read();
payload.reset();
payload.addGPS(gps_status);
do_transmit(&rcmdjob);
senddata(GPSPORT);
#else
ESP_LOGW(TAG, "GPS function not supported");
ESP_LOGW(TAG, "GPS function not supported");
#endif
};

View File

@ -18,19 +18,20 @@ void senddata(uint8_t port) {
#ifdef HAS_LORA
// Check if there is a pending TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
ESP_LOGI(TAG, "LoRa busy, rescheduling");
sprintf(display_lmic, "LORA BUSY");
ESP_LOGI(TAG, "LoRa busy, data not sent");
sprintf(display_line7, "LORA BUSY");
} else {
// send payload via LoRa
LMIC_setTxData2(PAYLOADPORT, payload.getBuffer(), payload.getSize(), (cfg.countermode & 0x02));
LMIC_setTxData2(PAYLOADPORT, payload.getBuffer(), payload.getSize(),
(cfg.countermode & 0x02));
ESP_LOGI(TAG, "%d bytes queued to send on LoRa", payload.getSize());
sprintf(display_lmic, "PACKET QUEUED");
sprintf(display_line7, "PACKET QUEUED");
}
#endif
#ifdef HAS_SPI
// code for sending payload via SPI to come
ESP_LOGI(TAG, "%d bytes sent on SPI", payload.getSize());
// code for sending payload via SPI to come
ESP_LOGI(TAG, "%d bytes sent on SPI", payload.getSize());
#endif
// clear counter if not in cumulative counter mode