Merge pull request #587 from cyberman54/development
New features: - M5 display support - Battery level display in % Bugfixes: - disable lmic interrupts for pycom boards (not supported)
This commit is contained in:
		
						commit
						8a426531b7
					
				@ -1,9 +1,12 @@
 | 
			
		||||
#ifndef _BMESENSOR_H
 | 
			
		||||
#define _BMESENSOR_H
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include <Wire.h>
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "irqhandler.h"
 | 
			
		||||
#include "configmanager.h"
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_BME680
 | 
			
		||||
#include <bsec.h>
 | 
			
		||||
#elif defined HAS_BME280
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,10 @@
 | 
			
		||||
#define _BUTTON_H
 | 
			
		||||
 | 
			
		||||
#include <SimpleButton.h>
 | 
			
		||||
#include "irqhandler.h"
 | 
			
		||||
#include "senddata.h"
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#include "payload.h"
 | 
			
		||||
 | 
			
		||||
void button_init(int pin);
 | 
			
		||||
void readButton();
 | 
			
		||||
 | 
			
		||||
@ -5,27 +5,10 @@
 | 
			
		||||
#include "senddata.h"
 | 
			
		||||
#include "rcommand.h"
 | 
			
		||||
#include "spislave.h"
 | 
			
		||||
 | 
			
		||||
#if(HAS_LORA)
 | 
			
		||||
#include <lmic.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (HAS_BME)
 | 
			
		||||
#include "bmesensor.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_DISPLAY
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (HAS_SDS011)
 | 
			
		||||
#include "sds011read.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (HAS_SDCARD)
 | 
			
		||||
#include "sdcard.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern Ticker housekeeper;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -7,33 +7,55 @@
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
#include <ss_oled.h>
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
#include <bb_spi_lcd.h>
 | 
			
		||||
#else
 | 
			
		||||
#error Unknown display type
 | 
			
		||||
#include <TFT_eSPI.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DISPLAY_PAGES (7) // number of paxcounter display pages
 | 
			
		||||
 | 
			
		||||
// settings for display library
 | 
			
		||||
// settings for OLED display library
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
#define MY_FONT_SMALL FONT_SMALL
 | 
			
		||||
#define MY_FONT_NORMAL FONT_NORMAL
 | 
			
		||||
#define MY_FONT_LARGE FONT_LARGE
 | 
			
		||||
#define MY_FONT_STRETCHED FONT_STRETCHED
 | 
			
		||||
#define USE_BACKBUFFER 1
 | 
			
		||||
 | 
			
		||||
// setup display hardware type, default is OLED 128x64
 | 
			
		||||
#ifndef MY_DISPLAY_TYPE
 | 
			
		||||
#define MY_DISPLAY_TYPE OLED_128x64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MY_DISPLAY_ADDR
 | 
			
		||||
#define OLED_ADDR MY_DISPLAY_ADDR
 | 
			
		||||
#else
 | 
			
		||||
#define OLED_ADDR -1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MY_DISPLAY_INVERT
 | 
			
		||||
#define MY_DISPLAY_INVERT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef USW_HW_I2C
 | 
			
		||||
#define USE_HW_I2C 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef OLED_FREQUENCY
 | 
			
		||||
#define OLED_FREQUENCY 400000L
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// settings for TFT display library
 | 
			
		||||
#elif (HAS_DISPLAY == 2)
 | 
			
		||||
 | 
			
		||||
#define MY_FONT_SMALL 1
 | 
			
		||||
#define MY_FONT_NORMAL 2
 | 
			
		||||
#define MY_FONT_LARGE 4
 | 
			
		||||
#define MY_FONT_STRETCHED 6
 | 
			
		||||
 | 
			
		||||
#ifndef MY_DISPLAY_FGCOLOR
 | 
			
		||||
#define MY_DISPLAY_FGCOLOR TFT_WHITE
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MY_DISPLAY_BGCOLOR
 | 
			
		||||
#define MY_DISPLAY_BGCOLOR TFT_BLACK
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// setup display hardware type, default is OLED 128x64
 | 
			
		||||
#ifndef OLED_TYPE
 | 
			
		||||
#define OLED_TYPE OLED_128x64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef MY_DISPLAY_INVERT
 | 
			
		||||
#define MY_DISPLAY_INVERT 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef MY_DISPLAY_FLIP
 | 
			
		||||
#define MY_DISPLAY_FLIP 0
 | 
			
		||||
@ -46,38 +68,10 @@
 | 
			
		||||
#define MY_DISPLAY_HEIGHT 64 // Height in pixels of OLED-display, must be 64X
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// some RGB color definitions
 | 
			
		||||
#define Black 0x0000       /*   0,   0,   0 */
 | 
			
		||||
#define Navy 0x000F        /*   0,   0, 128 */
 | 
			
		||||
#define DarkGreen 0x03E0   /*   0, 128,   0 */
 | 
			
		||||
#define DarkCyan 0x03EF    /*   0, 128, 128 */
 | 
			
		||||
#define Maroon 0x7800      /* 128,   0,   0 */
 | 
			
		||||
#define Purple 0x780F      /* 128,   0, 128 */
 | 
			
		||||
#define Olive 0x7BE0       /* 128, 128,   0 */
 | 
			
		||||
#define LightGrey 0xC618   /* 192, 192, 192 */
 | 
			
		||||
#define DarkGrey 0x7BEF    /* 128, 128, 128 */
 | 
			
		||||
#define Blue 0x001F        /*   0,   0, 255 */
 | 
			
		||||
#define Green 0x07E0       /*   0, 255,   0 */
 | 
			
		||||
#define Cyan 0x07FF        /*   0, 255, 255 */
 | 
			
		||||
#define Red 0xF800         /* 255,   0,   0 */
 | 
			
		||||
#define Magenta 0xF81F     /* 255,   0, 255 */
 | 
			
		||||
#define Yellow 0xFFE0      /* 255, 255,   0 */
 | 
			
		||||
#define White 0xFFFF       /* 255, 255, 255 */
 | 
			
		||||
#define Orange 0xFD20      /* 255, 165,   0 */
 | 
			
		||||
#define GreenYellow 0xAFE5 /* 173, 255,  47 */
 | 
			
		||||
#define Pink 0xF81F
 | 
			
		||||
 | 
			
		||||
#ifndef MY_DISPLAY_FGCOLOR
 | 
			
		||||
#define MY_DISPLAY_FGCOLOR White
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef MY_DISPLAY_BGCOLOR
 | 
			
		||||
#define MY_DISPLAY_BGCOLOR Black
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// settings for qr code generator
 | 
			
		||||
#define QR_VERSION 3 // 29 x 29px
 | 
			
		||||
#define QR_SCALEFACTOR 2 // 29 -> 58x < 64px
 | 
			
		||||
 | 
			
		||||
const uint8_t QR_SCALEFACTOR = (MY_DISPLAY_HEIGHT - 4) / 29; // 4px borderlines
 | 
			
		||||
extern uint8_t DisplayIsOn, displaybuf[];
 | 
			
		||||
 | 
			
		||||
void dp_setup(int contrast = 0);
 | 
			
		||||
@ -85,9 +79,11 @@ void dp_refresh(bool nextPage = false);
 | 
			
		||||
void dp_init(bool verbose = false);
 | 
			
		||||
void dp_shutdown(void);
 | 
			
		||||
void dp_drawPage(time_t t, bool nextpage);
 | 
			
		||||
void dp_printf(uint16_t x, uint16_t y, uint8_t font, uint8_t inv,
 | 
			
		||||
               const char *format, ...);
 | 
			
		||||
void dp_println(int lines = 1);
 | 
			
		||||
void dp_printf(const char *format, ...);
 | 
			
		||||
void dp_setFont(int font, int inv = 0);
 | 
			
		||||
void dp_dump(uint8_t *pBuffer);
 | 
			
		||||
void dp_setTextCursor(int col, int row);
 | 
			
		||||
void dp_contrast(uint8_t contrast);
 | 
			
		||||
void dp_clear(void);
 | 
			
		||||
void dp_power(uint8_t screenon);
 | 
			
		||||
 | 
			
		||||
@ -123,8 +123,8 @@ extern std::array<uint64_t, 0xff> beacons;
 | 
			
		||||
extern configData_t cfg;                       // current device configuration
 | 
			
		||||
extern char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer
 | 
			
		||||
extern uint8_t volatile channel;               // wifi channel rotation counter
 | 
			
		||||
extern uint16_t volatile macs_total, macs_wifi, macs_ble,
 | 
			
		||||
    batt_voltage;                   // display values
 | 
			
		||||
extern uint8_t batt_level;                     // display value
 | 
			
		||||
extern uint16_t volatile macs_total, macs_wifi, macs_ble; // display values
 | 
			
		||||
extern bool volatile TimePulseTick; // 1sec pps flag set by GPS or RTC
 | 
			
		||||
extern timesource_t timeSource;
 | 
			
		||||
extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ;
 | 
			
		||||
@ -134,42 +134,4 @@ extern TimerHandle_t WifiChanTimer;
 | 
			
		||||
extern Timezone myTZ;
 | 
			
		||||
extern RTC_DATA_ATTR runmode_t RTC_runmode;
 | 
			
		||||
 | 
			
		||||
// application includes
 | 
			
		||||
#include "led.h"
 | 
			
		||||
#include "payload.h"
 | 
			
		||||
#include "blescan.h"
 | 
			
		||||
#include "power.h"
 | 
			
		||||
 | 
			
		||||
#if (HAS_GPS)
 | 
			
		||||
#include "gpsread.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (HAS_LORA)
 | 
			
		||||
#include "lorawan.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_DISPLAY
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_MATRIX_DISPLAY
 | 
			
		||||
#include "ledmatrixdisplay.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_BUTTON
 | 
			
		||||
#include "button.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_ANTENNA_SWITCH
 | 
			
		||||
#include "antenna.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (HAS_SENSORS)
 | 
			
		||||
#include "sensor.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (HAS_BME)
 | 
			
		||||
#include "bmesensor.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -13,11 +13,13 @@
 | 
			
		||||
#define PMU_IRQ 0x200
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "button.h"
 | 
			
		||||
#include "cyclic.h"
 | 
			
		||||
#include "senddata.h"
 | 
			
		||||
#include "timekeeper.h"
 | 
			
		||||
#include "bmesensor.h"
 | 
			
		||||
#include "power.h"
 | 
			
		||||
#include "ledmatrixdisplay.h"
 | 
			
		||||
 | 
			
		||||
void irqHandler(void *pvParameters);
 | 
			
		||||
void mask_user_IRQ();
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,13 @@
 | 
			
		||||
#ifndef _LED_H
 | 
			
		||||
#define _LED_H
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_RGB_LED
 | 
			
		||||
#include <SmartLeds.h>
 | 
			
		||||
#include "lorawan.h"
 | 
			
		||||
 | 
			
		||||
#ifndef RGB_LED_COUNT
 | 
			
		||||
#define RGB_LED_COUNT 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// value for HSL color
 | 
			
		||||
// see http://www.workwithcolor.com/blue-color-hue-range-01.htm
 | 
			
		||||
#define COLOR_RED 0
 | 
			
		||||
 | 
			
		||||
@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
#include "LEDMatrix.h"
 | 
			
		||||
#include "ledmatrixfonts.h"
 | 
			
		||||
#include "ledmatrixdisplay.h"
 | 
			
		||||
 | 
			
		||||
extern uint8_t MatrixDisplayIsOn;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "senddata.h"
 | 
			
		||||
#include "cyclic.h"
 | 
			
		||||
#include "led.h"
 | 
			
		||||
 | 
			
		||||
#define MAC_SNIFF_WIFI 0
 | 
			
		||||
#define MAC_SNIFF_BLE 1
 | 
			
		||||
 | 
			
		||||
@ -17,9 +17,8 @@
 | 
			
		||||
#include "ota.h"
 | 
			
		||||
#include "irqhandler.h"
 | 
			
		||||
#include "spislave.h"
 | 
			
		||||
 | 
			
		||||
#if (HAS_LORA)
 | 
			
		||||
#include "sensor.h"
 | 
			
		||||
#include "lorawan.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "timekeeper.h"
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -4,7 +4,9 @@
 | 
			
		||||
#ifdef USE_OTA
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include <ss_oled.h>
 | 
			
		||||
#include "led.h"
 | 
			
		||||
#include "display.h"
 | 
			
		||||
 | 
			
		||||
#include <Update.h>
 | 
			
		||||
#include <WiFi.h>
 | 
			
		||||
#include <WiFiClientSecure.h>
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,7 @@
 | 
			
		||||
#ifndef _PAYLOAD_H_
 | 
			
		||||
#define _PAYLOAD_H_
 | 
			
		||||
 | 
			
		||||
#include "paxcounter.conf"
 | 
			
		||||
 | 
			
		||||
#if (HAS_SDS011)
 | 
			
		||||
#include "sds011read.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// MyDevices CayenneLPP 1.0 channels for Synamic sensor payload format
 | 
			
		||||
// all payload goes out on LoRa FPort 1
 | 
			
		||||
 | 
			
		||||
@ -4,13 +4,22 @@
 | 
			
		||||
#include <Arduino.h>
 | 
			
		||||
#include <driver/adc.h>
 | 
			
		||||
#include <esp_adc_cal.h>
 | 
			
		||||
 | 
			
		||||
#include "i2c.h"
 | 
			
		||||
#include "reset.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_VREF 1100 // tbd: use adc2_vref_to_gpio() for better estimate
 | 
			
		||||
#define NO_OF_SAMPLES 64  // we do some multisampling to get better values
 | 
			
		||||
 | 
			
		||||
#ifndef BAT_MAX_VOLTAGE
 | 
			
		||||
#define BAT_MAX_VOLTAGE 4300 // millivolts
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef BAT_MIN_VOLTAGE
 | 
			
		||||
#define BAT_MIN_VOLTAGE 3200 // millivolts
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
uint16_t read_voltage(void);
 | 
			
		||||
uint8_t read_battlevel(void);
 | 
			
		||||
void calibrate_voltage(void);
 | 
			
		||||
bool batt_sufficient(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,20 +1,19 @@
 | 
			
		||||
#ifndef _RCOMMAND_H
 | 
			
		||||
#define _RCOMMAND_H
 | 
			
		||||
 | 
			
		||||
#include <rom/rtc.h>
 | 
			
		||||
 | 
			
		||||
#include "senddata.h"
 | 
			
		||||
#include "cyclic.h"
 | 
			
		||||
#include "configmanager.h"
 | 
			
		||||
#if(HAS_LORA)
 | 
			
		||||
#include "lorawan.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "sensor.h"
 | 
			
		||||
#include "macsniff.h"
 | 
			
		||||
#include "wifiscan.h"
 | 
			
		||||
#include <rom/rtc.h>
 | 
			
		||||
#include "cyclic.h"
 | 
			
		||||
#include "timekeeper.h"
 | 
			
		||||
#if(TIME_SYNC_LORASERVER)
 | 
			
		||||
#include "timesync.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "blescan.h"
 | 
			
		||||
 | 
			
		||||
// table of remote commands and assigned functions
 | 
			
		||||
typedef struct {
 | 
			
		||||
 | 
			
		||||
@ -3,7 +3,11 @@
 | 
			
		||||
 | 
			
		||||
#include <driver/rtc_io.h>
 | 
			
		||||
#include <rom/rtc.h>
 | 
			
		||||
 | 
			
		||||
#include "i2c.h"
 | 
			
		||||
#include "lorawan.h"
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#include "power.h"
 | 
			
		||||
 | 
			
		||||
void do_reset(bool warmstart);
 | 
			
		||||
void do_after_reset(int reason);
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
#ifndef _RTCTIME_H
 | 
			
		||||
#define _RTCTIME_H
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "timekeeper.h"
 | 
			
		||||
#include <Wire.h> // must be included here so that Arduino library object file references work
 | 
			
		||||
#include <RtcDS3231.h>
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "timekeeper.h"
 | 
			
		||||
 | 
			
		||||
extern RtcDS3231<TwoWire> Rtc; // make RTC instance globally available
 | 
			
		||||
 | 
			
		||||
uint8_t rtc_init(void);
 | 
			
		||||
 | 
			
		||||
@ -3,10 +3,11 @@
 | 
			
		||||
 | 
			
		||||
#include <globals.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <SPI.h>
 | 
			
		||||
#include <mySD.h>
 | 
			
		||||
 | 
			
		||||
#include "sds011read.h"
 | 
			
		||||
 | 
			
		||||
#define SDCARD_FILE_NAME       "paxcount.%02d"
 | 
			
		||||
#define SDCARD_FILE_HEADER     "date, time, wifi, bluet"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
#ifndef _SDS011READ_H
 | 
			
		||||
#define _SDS011READ_H
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include <SDS011.h>
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
 | 
			
		||||
#define SDCARD_FILE_HEADER_SDS011     ", PM10,PM25"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,18 +3,10 @@
 | 
			
		||||
 | 
			
		||||
#include "spislave.h"
 | 
			
		||||
#include "cyclic.h"
 | 
			
		||||
 | 
			
		||||
#if(HAS_LORA)
 | 
			
		||||
#include "sensor.h"
 | 
			
		||||
#include "lorawan.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_DISPLAY
 | 
			
		||||
#include "display.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_SDCARD
 | 
			
		||||
#include "sdcard.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern Ticker sendcycler;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -25,6 +25,7 @@ licenses. Refer to LICENSE.txt file in repository for more details.
 | 
			
		||||
#define _SPISLAVE_H
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "rcommand.h"
 | 
			
		||||
 | 
			
		||||
esp_err_t spi_init();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,16 +6,9 @@
 | 
			
		||||
#include "TimeLib.h"
 | 
			
		||||
#include "irqhandler.h"
 | 
			
		||||
#include "timesync.h"
 | 
			
		||||
 | 
			
		||||
#if (HAS_GPS)
 | 
			
		||||
#include "gpsread.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_IF482
 | 
			
		||||
#include "if482.h"
 | 
			
		||||
#elif defined HAS_DCF77
 | 
			
		||||
#include "dcf77.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern const char timeSetSymbols[];
 | 
			
		||||
extern Ticker timesyncer;
 | 
			
		||||
 | 
			
		||||
@ -3,13 +3,17 @@
 | 
			
		||||
 | 
			
		||||
// ESP32 Functions
 | 
			
		||||
#include <esp_wifi.h>
 | 
			
		||||
#include <esp_coexist.h>
 | 
			
		||||
#include "coexist_internal.h"
 | 
			
		||||
 | 
			
		||||
// Hash function for scrambling MAC addresses
 | 
			
		||||
#include "hash.h"
 | 
			
		||||
#include "hash.h"    // Hash function for scrambling MAC addresses
 | 
			
		||||
#include "antenna.h" // code for switching wifi antennas
 | 
			
		||||
#include "macsniff.h"
 | 
			
		||||
 | 
			
		||||
void wifi_sniffer_init(void);
 | 
			
		||||
void switch_wifi_sniffer(uint8_t state);
 | 
			
		||||
void IRAM_ATTR wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
 | 
			
		||||
void IRAM_ATTR wifi_sniffer_packet_handler(void *buff,
 | 
			
		||||
                                           wifi_promiscuous_pkt_type_t type);
 | 
			
		||||
void switchWifiChannel(TimerHandle_t xTimer);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -45,7 +45,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I
 | 
			
		||||
 | 
			
		||||
[common]
 | 
			
		||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
 | 
			
		||||
release_version = 1.9.982
 | 
			
		||||
release_version = 1.9.984
 | 
			
		||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
 | 
			
		||||
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
 | 
			
		||||
debug_level = 3
 | 
			
		||||
@ -56,14 +56,13 @@ lmicconfigfile = lmic_config.h
 | 
			
		||||
platform_espressif32 = espressif32@1.12.0
 | 
			
		||||
monitor_speed = 115200
 | 
			
		||||
upload_speed = 115200
 | 
			
		||||
;upload_port = COM9
 | 
			
		||||
lib_deps_lora =
 | 
			
		||||
    MCCI LoRaWAN LMIC library@>=3.1.0 ; MCCI LMIC by Terrill Moore
 | 
			
		||||
lib_deps_display =
 | 
			
		||||
    ss_oled@4.1.2 ; simple and small OLED lib by Larry Bank
 | 
			
		||||
    BitBang_I2C@2.0.2
 | 
			
		||||
    QRCode@>=0.0.1
 | 
			
		||||
    bb_spi_lcd@1.1.0 ; LCD TFT driver lib by Larry Bank
 | 
			
		||||
    TFT_eSPI@>=2.2.0
 | 
			
		||||
lib_deps_matrix_display =
 | 
			
		||||
    Ultrathin_LED_Matrix@>=1.0.0
 | 
			
		||||
lib_deps_rgbled =
 | 
			
		||||
@ -111,7 +110,7 @@ framework = arduino
 | 
			
		||||
board = esp32dev
 | 
			
		||||
board_build.partitions = min_spiffs.csv
 | 
			
		||||
upload_speed = ${common.upload_speed}
 | 
			
		||||
;upload_port = ${common.upload_port}
 | 
			
		||||
;upload_port = COM5
 | 
			
		||||
platform = ${common.platform_espressif32}
 | 
			
		||||
lib_deps = ${common.lib_deps_all}
 | 
			
		||||
build_flags = ${common.build_flags_all}
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
/* code snippets taken from
 | 
			
		||||
https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
 | 
			
		||||
*/
 | 
			
		||||
// some code snippets taken from
 | 
			
		||||
// https://github.com/nkolban/esp32-snippets/tree/master/BLE/scanner
 | 
			
		||||
 | 
			
		||||
#include "blescan.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
/* configmanager persists runtime configuration using NVRAM of ESP32*/
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "configmanager.h"
 | 
			
		||||
 | 
			
		||||
// Local logging tag
 | 
			
		||||
static const char TAG[] = "flash";
 | 
			
		||||
 | 
			
		||||
@ -28,7 +28,7 @@ void doHousekeeping() {
 | 
			
		||||
    if (batt_sufficient()) {
 | 
			
		||||
      do_reset(true); // warmstart to runmode update
 | 
			
		||||
    } else {
 | 
			
		||||
      ESP_LOGE(TAG, "Battery voltage %dmV too low for OTA", batt_voltage);
 | 
			
		||||
      ESP_LOGE(TAG, "Battery level %d%% is too low for OTA", batt_level);
 | 
			
		||||
      RTC_runmode = RUNMODE_NORMAL; // keep running in normal mode
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -66,11 +66,17 @@ void doHousekeeping() {
 | 
			
		||||
 | 
			
		||||
// read battery voltage into global variable
 | 
			
		||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
 | 
			
		||||
  batt_voltage = read_voltage();
 | 
			
		||||
  if (batt_voltage == 0xffff)
 | 
			
		||||
  batt_level = read_battlevel();
 | 
			
		||||
  switch (batt_level) {
 | 
			
		||||
  case MCMD_DEVS_EXT_POWER:
 | 
			
		||||
    ESP_LOGI(TAG, "Battery: external power");
 | 
			
		||||
  else
 | 
			
		||||
    ESP_LOGI(TAG, "Battery: %dmV", batt_voltage);
 | 
			
		||||
    break;
 | 
			
		||||
  case MCMD_DEVS_BATT_NOINFO :
 | 
			
		||||
    ESP_LOGI(TAG, "Battery: unknown state");
 | 
			
		||||
    break;
 | 
			
		||||
  default:
 | 
			
		||||
    ESP_LOGI(TAG, "Battery: %d%%", batt_level);
 | 
			
		||||
  }
 | 
			
		||||
#ifdef HAS_PMU
 | 
			
		||||
  AXP192_showstatus();
 | 
			
		||||
#endif
 | 
			
		||||
@ -119,8 +125,7 @@ void doHousekeeping() {
 | 
			
		||||
  if (isSDS011Active) {
 | 
			
		||||
    ESP_LOGD(TAG, "SDS011: go to sleep");
 | 
			
		||||
    sds011_loop();
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
  } else {
 | 
			
		||||
    ESP_LOGD(TAG, "SDS011: wakeup");
 | 
			
		||||
    sds011_wakeup();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										474
									
								
								src/display.cpp
									
									
									
									
									
								
							
							
						
						
									
										474
									
								
								src/display.cpp
									
									
									
									
									
								
							@ -11,8 +11,8 @@ Display-Mask (128 x 64 pixel):
 | 
			
		||||
0|PAX:aabbccdd      	    STRETCHED
 | 
			
		||||
1|PAX:aabbccdd            STRETCHED
 | 
			
		||||
2|
 | 
			
		||||
3|B:a.bcV Sats:ab ch:ab   SMALL
 | 
			
		||||
4|WIFI:abcde BLTH:abcde   SMALL
 | 
			
		||||
3|WIFI:abcde BLTH:abcde   SMALL
 | 
			
		||||
4|B:a.bcV Sats:ab ch:ab   SMALL
 | 
			
		||||
5|RLIM:abcd  Mem:abcdKB   SMALL
 | 
			
		||||
6|27.Feb 2019 20:27:00*   SMALL
 | 
			
		||||
7|yyyyyyyyyyyyy xx SFab   SMALL
 | 
			
		||||
@ -25,15 +25,16 @@ y = LMIC event message
 | 
			
		||||
xx = payload sendqueue length
 | 
			
		||||
ab = LMIC spread factor
 | 
			
		||||
 | 
			
		||||
FONT_SMALL:     6x8px = 21 chars / line
 | 
			
		||||
FONT_NORMAL:    8x8px = 16 chars / line
 | 
			
		||||
FONT_STRETCHED: 16x32px = 8 chars / line
 | 
			
		||||
MY_FONT_SMALL:     6x8px = 21 chars / line
 | 
			
		||||
MY_FONT_NORMAL:    8x8px = 16 chars / line
 | 
			
		||||
MY_FONT_STRETCHED: 16x32px = 8 chars / line
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// Basic Config
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include <esp_spi_flash.h> // needed for reading ESP32 chip attributes
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "display.h"
 | 
			
		||||
 | 
			
		||||
// local Tag for logging
 | 
			
		||||
static const char TAG[] = __FILE__;
 | 
			
		||||
@ -44,36 +45,36 @@ const char *printmonth[] = {"xxx", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
 | 
			
		||||
uint8_t DisplayIsOn = 0;
 | 
			
		||||
uint8_t displaybuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0};
 | 
			
		||||
static uint8_t plotbuf[MY_DISPLAY_WIDTH * MY_DISPLAY_HEIGHT / 8] = {0};
 | 
			
		||||
static int dp_row = 0, dp_col = 0, dp_font = 0;
 | 
			
		||||
 | 
			
		||||
QRCode qrcode;
 | 
			
		||||
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
SSOLED ssoled;
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
TFT_eSPI tft = TFT_eSPI();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void dp_setup(int contrast) {
 | 
			
		||||
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  int rc = oledInit(&ssoled, MY_DISPLAY_TYPE, OLED_ADDR, MY_DISPLAY_FLIP,
 | 
			
		||||
#if (HAS_DISPLAY) == 1 // I2C OLED
 | 
			
		||||
  int rc = oledInit(&ssoled, OLED_TYPE, OLED_ADDR, MY_DISPLAY_FLIP,
 | 
			
		||||
                    MY_DISPLAY_INVERT, USE_HW_I2C, MY_DISPLAY_SDA,
 | 
			
		||||
                    MY_DISPLAY_SCL, MY_DISPLAY_RST,
 | 
			
		||||
                    400000L); // use standard I2C bus at 400Khz
 | 
			
		||||
                    OLED_FREQUENCY); // use standard I2C bus at 400Khz
 | 
			
		||||
  assert(rc != OLED_NOT_FOUND);
 | 
			
		||||
 | 
			
		||||
  // set display buffer
 | 
			
		||||
  oledSetBackBuffer(&ssoled, displaybuf);
 | 
			
		||||
  oledSetTextWrap(&ssoled, true);
 | 
			
		||||
  dp_font = MY_FONT_NORMAL;
 | 
			
		||||
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
#elif (HAS_DISPLAY) == 2 // SPI TFT
 | 
			
		||||
 | 
			
		||||
  int rc = spilcdInit(MY_DISPLAY_TYPE, 0, MY_DISPLAY_INVERT, MY_DISPLAY_FLIP,
 | 
			
		||||
                      32000000, MY_DISPLAY_CS, MY_DISPLAY_DC, MY_DISPLAY_RST,
 | 
			
		||||
                      MY_DISPLAY_BL, MY_DISPLAY_MISO, MY_DISPLAY_MOSI,
 | 
			
		||||
                      MY_DISPLAY_CLK);
 | 
			
		||||
 | 
			
		||||
  assert(rc == 0);
 | 
			
		||||
 | 
			
		||||
  // set display buffer
 | 
			
		||||
  spilcdAllocBackbuffer();
 | 
			
		||||
  tft.init();
 | 
			
		||||
  tft.setRotation(MY_DISPLAY_FLIP ? 3 : 1);
 | 
			
		||||
  tft.invertDisplay(MY_DISPLAY_INVERT ? true : false);
 | 
			
		||||
  tft.setTextColor(MY_DISPLAY_FGCOLOR, MY_DISPLAY_BGCOLOR);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -85,10 +86,12 @@ void dp_setup(int contrast) {
 | 
			
		||||
 | 
			
		||||
void dp_init(bool verbose) {
 | 
			
		||||
 | 
			
		||||
#if (HAS_DISPLAY) == 1 // i2c
 | 
			
		||||
  // block i2c bus access
 | 
			
		||||
  if (!I2C_MUTEX_LOCK())
 | 
			
		||||
    ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
 | 
			
		||||
  else {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    dp_setup(DISPLAYCONTRAST);
 | 
			
		||||
 | 
			
		||||
@ -101,15 +104,20 @@ void dp_init(bool verbose) {
 | 
			
		||||
#if (VERBOSE)
 | 
			
		||||
      esp_chip_info_t chip_info;
 | 
			
		||||
      esp_chip_info(&chip_info);
 | 
			
		||||
      dp_printf(0, 0, 0, 0, "** PAXCOUNTER **");
 | 
			
		||||
      dp_printf(0, 1, 0, 0, "Software v%s", PROGVERSION);
 | 
			
		||||
      dp_printf(0, 3, 0, 0, "ESP32 %d cores", chip_info.cores);
 | 
			
		||||
      dp_printf(0, 4, 0, 0, "Chip Rev.%d", chip_info.revision);
 | 
			
		||||
      dp_printf(0, 5, 0, 0, "WiFi%s%s",
 | 
			
		||||
                (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
 | 
			
		||||
 | 
			
		||||
      dp_setFont(MY_FONT_NORMAL);
 | 
			
		||||
      dp_printf("** PAXCOUNTER **");
 | 
			
		||||
      dp_println();
 | 
			
		||||
      dp_printf("Software v%s", PROGVERSION);
 | 
			
		||||
      dp_println();
 | 
			
		||||
      dp_printf("ESP32 %d cores", chip_info.cores);
 | 
			
		||||
      dp_println();
 | 
			
		||||
      dp_printf("Chip Rev.%d", chip_info.revision);
 | 
			
		||||
      dp_println();
 | 
			
		||||
      dp_printf("WiFi%s%s", (chip_info.features & CHIP_FEATURE_BT) ? "/BT" : "",
 | 
			
		||||
                (chip_info.features & CHIP_FEATURE_BLE) ? "/BLE" : "");
 | 
			
		||||
      dp_printf(0, 6, 0, 0, "%dMB %s Flash",
 | 
			
		||||
                spi_flash_get_chip_size() / (1024 * 1024),
 | 
			
		||||
      dp_println();
 | 
			
		||||
      dp_printf("%dMB %s Flash", spi_flash_get_chip_size() / (1024 * 1024),
 | 
			
		||||
                (chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "int."
 | 
			
		||||
                                                              : "ext.");
 | 
			
		||||
 | 
			
		||||
@ -131,10 +139,15 @@ void dp_init(bool verbose) {
 | 
			
		||||
      dp_printqr(3, 3, deveui);
 | 
			
		||||
 | 
			
		||||
      // display DEVEUI as plain text on the right
 | 
			
		||||
      dp_printf(72, 0, FONT_NORMAL, 0, "LORAWAN");
 | 
			
		||||
      dp_printf(72, 1, FONT_NORMAL, 0, "DEVEUI:");
 | 
			
		||||
      for (uint8_t i = 0; i <= 3; i++)
 | 
			
		||||
        dp_printf(80, i + 3, FONT_NORMAL, 0, "%4.4s", deveui + i * 4);
 | 
			
		||||
      const int x_offset = QR_SCALEFACTOR * 29 + 14;
 | 
			
		||||
      dp_setTextCursor(x_offset, 0);
 | 
			
		||||
      dp_setFont(MY_FONT_NORMAL);
 | 
			
		||||
      dp_printf("DEVEUI");
 | 
			
		||||
      dp_println();
 | 
			
		||||
      for (uint8_t i = 0; i <= 3; i++) {
 | 
			
		||||
        dp_setTextCursor(x_offset, i + 3);
 | 
			
		||||
        dp_printf("%4.4s", deveui + i * 4);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // give user some time to read or take picture
 | 
			
		||||
      dp_dump(displaybuf);
 | 
			
		||||
@ -147,8 +160,11 @@ void dp_init(bool verbose) {
 | 
			
		||||
 | 
			
		||||
    dp_power(cfg.screenon); // set display off if disabled
 | 
			
		||||
 | 
			
		||||
#if (HAS_DISPLAY) == 1  // i2c
 | 
			
		||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
			
		||||
  }                     // mutex
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
} // dp_init
 | 
			
		||||
 | 
			
		||||
void dp_refresh(bool nextPage) {
 | 
			
		||||
@ -204,207 +220,307 @@ void dp_drawPage(time_t t, bool nextpage) {
 | 
			
		||||
  static bool wasnofix = true;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // line 1/2: pax counter
 | 
			
		||||
  dp_printf(0, 0, FONT_STRETCHED, 0, "PAX:%-4d",
 | 
			
		||||
            macs.size()); // display number of unique macs total Wifi + BLE
 | 
			
		||||
 | 
			
		||||
start:
 | 
			
		||||
 | 
			
		||||
  if (nextpage) {
 | 
			
		||||
    DisplayPage = (DisplayPage >= DISPLAY_PAGES - 1) ? 0 : (DisplayPage + 1);
 | 
			
		||||
    dp_clear();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // cursor home
 | 
			
		||||
  dp_setTextCursor(0, 0);
 | 
			
		||||
 | 
			
		||||
  // line 1/2: pax counter
 | 
			
		||||
  // display number of unique macs total Wifi + BLE
 | 
			
		||||
  if (DisplayPage < 5) {
 | 
			
		||||
    dp_setFont(MY_FONT_STRETCHED);
 | 
			
		||||
    dp_printf("PAX:%-4d", macs.size());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  switch (DisplayPage) {
 | 
			
		||||
 | 
			
		||||
    // page 0: parameters overview
 | 
			
		||||
    // page 1: pax graph
 | 
			
		||||
    // page 1: lorawan parameters
 | 
			
		||||
    // page 2: GPS
 | 
			
		||||
    // page 3: BME280/680
 | 
			
		||||
    // page 4: time
 | 
			
		||||
    // page 5: lorawan parameters
 | 
			
		||||
    // page 5: pax graph
 | 
			
		||||
    // page 6: blank screen
 | 
			
		||||
 | 
			
		||||
    // page 0: parameters overview
 | 
			
		||||
    // ---------- page 0: parameters overview ----------
 | 
			
		||||
  case 0:
 | 
			
		||||
 | 
			
		||||
    dp_setTextCursor(0, 3);
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL);
 | 
			
		||||
 | 
			
		||||
    // line 3: wifi + bluetooth counters
 | 
			
		||||
    // WIFI:abcde BLTH:abcde
 | 
			
		||||
 | 
			
		||||
#if ((WIFICOUNTER) && (BLECOUNTER))
 | 
			
		||||
    if (cfg.wifiscan)
 | 
			
		||||
      dp_printf(0, 3, FONT_SMALL, 0, "WIFI:%-5d", macs_wifi);
 | 
			
		||||
      dp_printf("WIFI:%-5d", macs_wifi);
 | 
			
		||||
    else
 | 
			
		||||
      dp_printf(0, 3, FONT_SMALL, 0, "%s", "WIFI:off");
 | 
			
		||||
      dp_printf("WIFI:off");
 | 
			
		||||
    if (cfg.blescan)
 | 
			
		||||
      dp_printf(66, 3, FONT_SMALL, 0, "BLTH:%-5d", macs_ble);
 | 
			
		||||
      dp_printf(" BLTH:%-5d", macs_ble);
 | 
			
		||||
    else
 | 
			
		||||
      dp_printf(66, 3, FONT_SMALL, 0, "%s", "BLTH:off");
 | 
			
		||||
      dp_printf(" BLTH:off");
 | 
			
		||||
#elif ((WIFICOUNTER) && (!BLECOUNTER))
 | 
			
		||||
    if (cfg.wifiscan)
 | 
			
		||||
      dp_printf(0, 3, FONT_SMALL, 0, "WIFI:%-5d", macs_wifi);
 | 
			
		||||
      dp_printf("WIFI:%-5d", macs_wifi);
 | 
			
		||||
    else
 | 
			
		||||
      dp_printf(0, 3, FONT_SMALL, 0, "%s", "WIFI:off");
 | 
			
		||||
      dp_printf("WIFI:off");
 | 
			
		||||
#elif ((!WIFICOUNTER) && (BLECOUNTER))
 | 
			
		||||
    if (cfg.blescan)
 | 
			
		||||
      dp_printf(0, 3, FONT_SMALL, 0, "BLTH:%-5d", macs_ble);
 | 
			
		||||
      dp_printf("BLTH:%-5d", macs_ble);
 | 
			
		||||
    else
 | 
			
		||||
      dp_printf(0, 3, FONT_SMALL, 0, "%s", "BLTH:off");
 | 
			
		||||
      dp_printf("BLTH:off");
 | 
			
		||||
#else
 | 
			
		||||
    dp_printf(0, 3, FONT_SMALL, 0, "%s", "Sniffer disabled");
 | 
			
		||||
    dp_printf("Sniffer disabled");
 | 
			
		||||
#endif
 | 
			
		||||
    dp_println();
 | 
			
		||||
 | 
			
		||||
    // line 4: Battery + GPS status + Wifi channel
 | 
			
		||||
    // B:a.bcV Sats:ab ch:ab
 | 
			
		||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
 | 
			
		||||
    if (batt_voltage == 0xffff)
 | 
			
		||||
      dp_printf(0, 4, FONT_SMALL, 0, "%s", "USB    ");
 | 
			
		||||
    else if (batt_voltage == 0)
 | 
			
		||||
      dp_printf(0, 4, FONT_SMALL, 0, "%s", "No batt");
 | 
			
		||||
    else
 | 
			
		||||
      dp_printf(0, 4, FONT_SMALL, 0, "B:%.2fV", batt_voltage / 1000.0);
 | 
			
		||||
    switch (batt_level) {
 | 
			
		||||
    case MCMD_DEVS_EXT_POWER:
 | 
			
		||||
      dp_printf("ext.Pwr ");
 | 
			
		||||
      break;
 | 
			
		||||
    case MCMD_DEVS_BATT_NOINFO:
 | 
			
		||||
      dp_printf("No batt ");
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      dp_printf("B:%3d%%  ", batt_level);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    dp_printf("       ");
 | 
			
		||||
#endif
 | 
			
		||||
#if (HAS_GPS)
 | 
			
		||||
    if (gps_hasfix())
 | 
			
		||||
      dp_printf(48, 4, FONT_SMALL, 0, "Sats:%.2d", gps.satellites.value());
 | 
			
		||||
    else // if no fix then display Sats value inverse
 | 
			
		||||
      dp_printf(48, 4, FONT_SMALL, 1, "Sats:%.2d", gps.satellites.value());
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL, !gps_hasfix());
 | 
			
		||||
    dp_printf("Sats:%.2d", gps.satellites.value());
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL);
 | 
			
		||||
#else
 | 
			
		||||
    dp_printf("       ");
 | 
			
		||||
#endif
 | 
			
		||||
    dp_printf(96, 4, FONT_SMALL, 0, "ch:%02d", channel);
 | 
			
		||||
    dp_printf(" ch:%02d", channel);
 | 
			
		||||
    dp_println();
 | 
			
		||||
 | 
			
		||||
    // line 5: RSSI limiter + free memory
 | 
			
		||||
    dp_printf(0, 5, FONT_SMALL, 0, !cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d",
 | 
			
		||||
              cfg.rssilimit);
 | 
			
		||||
    dp_printf(66, 5, FONT_SMALL, 0, "Mem:%4dKB", getFreeRAM() / 1024);
 | 
			
		||||
    // RLIM:abcd  Mem:abcdKB
 | 
			
		||||
    dp_printf(!cfg.rssilimit ? "RLIM:off " : "RLIM:%-4d", cfg.rssilimit);
 | 
			
		||||
    dp_printf("  Mem:%4dKB", getFreeRAM() / 1024);
 | 
			
		||||
    dp_println();
 | 
			
		||||
 | 
			
		||||
    // line 6: time + date
 | 
			
		||||
    // 27.Feb 2019 20:27:00*
 | 
			
		||||
#if (TIME_SYNC_INTERVAL)
 | 
			
		||||
    timeState = TimePulseTick ? ' ' : timeSetSymbols[timeSource];
 | 
			
		||||
    TimePulseTick = false;
 | 
			
		||||
 | 
			
		||||
    dp_printf(0, 6, FONT_SMALL, 0, "%02d.%3s %4d", day(t), printmonth[month(t)],
 | 
			
		||||
              year(t));
 | 
			
		||||
    dp_printf(72, 6, FONT_SMALL, 0, "%02d:%02d:%02d", hour(t), minute(t),
 | 
			
		||||
              second(t));
 | 
			
		||||
    dp_printf("%02d.%3s %4d", day(t), printmonth[month(t)], year(t));
 | 
			
		||||
    dp_printf(" %02d:%02d:%02d", hour(t), minute(t), second(t));
 | 
			
		||||
 | 
			
		||||
// display inverse timeState if clock controller is enabled
 | 
			
		||||
#if (defined HAS_DCF77) || (defined HAS_IF482)
 | 
			
		||||
    dp_printf(120, 6, FONT_SMALL, 1, "%c", timeState);
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL, 1);
 | 
			
		||||
    dp_printf("%c", timeState);
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL, 0);
 | 
			
		||||
#else
 | 
			
		||||
    dp_printf(120, 6, FONT_SMALL, 0, "%c", timeState);
 | 
			
		||||
    dp_printf("%c", timeState);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    dp_println();
 | 
			
		||||
#endif // TIME_SYNC_INTERVAL
 | 
			
		||||
 | 
			
		||||
    // line 7: LORA network status
 | 
			
		||||
    // yyyyyyyyyyyyy xx SFab
 | 
			
		||||
 | 
			
		||||
#if (HAS_LORA)
 | 
			
		||||
    // LMiC event display
 | 
			
		||||
    dp_printf(0, 7, FONT_SMALL, 0, "%-16s", lmic_event_msg);
 | 
			
		||||
    dp_printf("%-16s", lmic_event_msg);
 | 
			
		||||
    // LORA datarate, display inverse if ADR disabled
 | 
			
		||||
    dp_printf(102, 7, FONT_SMALL, !cfg.adrmode, "%-4s",
 | 
			
		||||
              getSfName(updr2rps(LMIC.datarate)));
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL, !cfg.adrmode);
 | 
			
		||||
    dp_printf(" %-4s", getSfName(updr2rps(LMIC.datarate)));
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL, 0);
 | 
			
		||||
    dp_println();
 | 
			
		||||
#endif // HAS_LORA
 | 
			
		||||
    break; // page0
 | 
			
		||||
 | 
			
		||||
    // page 1: pax graph
 | 
			
		||||
  case 1:
 | 
			
		||||
    dp_dump(plotbuf);
 | 
			
		||||
    break; // page1
 | 
			
		||||
 | 
			
		||||
    // page 2: GPS
 | 
			
		||||
  case 2:
 | 
			
		||||
#if (HAS_GPS)
 | 
			
		||||
    if (gps_hasfix()) {
 | 
			
		||||
      // line 5: clear "No fix"
 | 
			
		||||
      if (wasnofix) {
 | 
			
		||||
        dp_printf(16, 5, FONT_STRETCHED, 0, "      ");
 | 
			
		||||
        wasnofix = false;
 | 
			
		||||
      }
 | 
			
		||||
      // line 3-4: GPS latitude
 | 
			
		||||
      dp_printf(0, 3, FONT_STRETCHED, 0, "%c%07.4f",
 | 
			
		||||
                gps.location.rawLat().negative ? 'S' : 'N', gps.location.lat());
 | 
			
		||||
 | 
			
		||||
      // line 6-7: GPS longitude
 | 
			
		||||
      dp_printf(0, 6, FONT_STRETCHED, 0, "%c%07.4f",
 | 
			
		||||
                gps.location.rawLat().negative ? 'W' : 'E', gps.location.lng());
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      dp_printf(16, 5, FONT_STRETCHED, 1, "No fix");
 | 
			
		||||
      wasnofix = true;
 | 
			
		||||
    }
 | 
			
		||||
    break; // page2
 | 
			
		||||
#else
 | 
			
		||||
    DisplayPage++; // next page
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // page 3: BME280/680
 | 
			
		||||
  case 3:
 | 
			
		||||
#if (HAS_BME)
 | 
			
		||||
    // line 2-3: Temp
 | 
			
		||||
    dp_printf(0, 2, FONT_STRETCHED, 0, "TMP:%-2.1f", bme_status.temperature);
 | 
			
		||||
 | 
			
		||||
    // line 4-5: Hum
 | 
			
		||||
    dp_printf(0, 4, FONT_STRETCHED, 0, "HUM:%-2.1f", bme_status.humidity);
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_BME680
 | 
			
		||||
    // line 6-7: IAQ
 | 
			
		||||
    dp_printf(0, 6, FONT_STRETCHED, 0, "IAQ:%-3.0f", bme_status.iaq);
 | 
			
		||||
#else      // is BME280 or BMP180
 | 
			
		||||
    // line 6-7: Pre
 | 
			
		||||
    dp_printf(0, 6, FONT_STRETCHED, 0, "PRE:%-2.1f", bme_status.pressure);
 | 
			
		||||
#endif     // HAS_BME680
 | 
			
		||||
    break; // page 3
 | 
			
		||||
#else
 | 
			
		||||
    DisplayPage++; // next page
 | 
			
		||||
#endif // HAS_BME
 | 
			
		||||
 | 
			
		||||
  // page 4: time
 | 
			
		||||
  case 4:
 | 
			
		||||
    dp_printf(0, 4, FONT_LARGE, 0, "%02d:%02d:%02d", hour(t), minute(t),
 | 
			
		||||
              second(t));
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  // page 5: lorawan parameters
 | 
			
		||||
  case 5:
 | 
			
		||||
  // ---------- page 1: lorawan parameters ----------
 | 
			
		||||
  case 1:
 | 
			
		||||
 | 
			
		||||
#if (HAS_LORA)
 | 
			
		||||
 | 
			
		||||
    // 3|NtwkID:000000 TXpw:aa
 | 
			
		||||
    // 4|DevAdd:00000000  DR:0
 | 
			
		||||
    // 5|CHMsk:0000 Nonce:0000
 | 
			
		||||
    // 6|CUp:000000 CDn:000000
 | 
			
		||||
    // 7|SNR:-0000  RSSI:-0000
 | 
			
		||||
    dp_printf(0, 3, FONT_SMALL, 0, "NetwID:%06X TXpw:%-2d",
 | 
			
		||||
              LMIC.netid & 0x001FFFFF, LMIC.radio_txpow);
 | 
			
		||||
    dp_printf(0, 4, FONT_SMALL, 0, "DevAdd:%08X DR:%1d", LMIC.devaddr,
 | 
			
		||||
              LMIC.datarate);
 | 
			
		||||
    dp_printf(0, 5, FONT_SMALL, 0, "ChMsk:%04X Nonce:%04X", LMIC.channelMap,
 | 
			
		||||
              LMIC.devNonce);
 | 
			
		||||
    dp_printf(0, 6, FONT_SMALL, 0, "fUp:%-6d fDn:%-6d",
 | 
			
		||||
              LMIC.seqnoUp ? LMIC.seqnoUp - 1 : 0,
 | 
			
		||||
 | 
			
		||||
    dp_setFont(MY_FONT_SMALL);
 | 
			
		||||
    dp_setTextCursor(0, 3);
 | 
			
		||||
    dp_printf("NetwID:%06X TXpw:%-2d", LMIC.netid & 0x001FFFFF,
 | 
			
		||||
              LMIC.radio_txpow);
 | 
			
		||||
    dp_println();
 | 
			
		||||
    dp_printf("DevAdd:%08X DR:%1d", LMIC.devaddr, LMIC.datarate);
 | 
			
		||||
    dp_println();
 | 
			
		||||
    dp_printf("ChMsk:%04X Nonce:%04X", LMIC.channelMap, LMIC.devNonce);
 | 
			
		||||
    dp_println();
 | 
			
		||||
    dp_printf("fUp:%-6d fDn:%-6d", LMIC.seqnoUp ? LMIC.seqnoUp - 1 : 0,
 | 
			
		||||
              LMIC.seqnoDn ? LMIC.seqnoDn - 1 : 0);
 | 
			
		||||
    dp_printf(0, 7, FONT_SMALL, 0, "SNR:%-5d  RSSI:%-5d", (LMIC.snr + 2) / 4,
 | 
			
		||||
              LMIC.rssi);
 | 
			
		||||
    break; // page5
 | 
			
		||||
#else      // don't show blank page if we are unattended
 | 
			
		||||
    DisplayPage++; // next page
 | 
			
		||||
    dp_println();
 | 
			
		||||
    dp_printf("SNR:%-5d  RSSI:%-5d", (LMIC.snr + 2) / 4, LMIC.rssi);
 | 
			
		||||
    break;
 | 
			
		||||
#else  // flip page if we are unattended
 | 
			
		||||
    DisplayPage++;
 | 
			
		||||
#endif // HAS_LORA
 | 
			
		||||
 | 
			
		||||
    // page 6: blank screen
 | 
			
		||||
  // ---------- page 2: GPS ----------
 | 
			
		||||
  case 2:
 | 
			
		||||
 | 
			
		||||
#if (HAS_GPS)
 | 
			
		||||
    dp_setFont(MY_FONT_STRETCHED);
 | 
			
		||||
    dp_setTextCursor(0, 3);
 | 
			
		||||
    if (gps_hasfix()) {
 | 
			
		||||
      // line 5: clear "No fix"
 | 
			
		||||
      if (wasnofix) {
 | 
			
		||||
        dp_setTextCursor(2, 4);
 | 
			
		||||
        dp_printf("      ");
 | 
			
		||||
        wasnofix = false;
 | 
			
		||||
      }
 | 
			
		||||
      // line 3-4: GPS latitude
 | 
			
		||||
      dp_printf("%c%07.4f", gps.location.rawLat().negative ? 'S' : 'N',
 | 
			
		||||
                gps.location.lat());
 | 
			
		||||
 | 
			
		||||
      // line 6-7: GPS longitude
 | 
			
		||||
      dp_printf("%c%07.4f", gps.location.rawLat().negative ? 'W' : 'E',
 | 
			
		||||
                gps.location.lng());
 | 
			
		||||
 | 
			
		||||
    } else {
 | 
			
		||||
      dp_setTextCursor(2, 4);
 | 
			
		||||
      dp_setFont(MY_FONT_STRETCHED, 1);
 | 
			
		||||
      dp_printf("No fix");
 | 
			
		||||
      wasnofix = true;
 | 
			
		||||
    }
 | 
			
		||||
    break;
 | 
			
		||||
#else // flip page if we are unattended
 | 
			
		||||
    DisplayPage++;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  // ---------- page 3: BME280/680 ----------
 | 
			
		||||
  case 3:
 | 
			
		||||
 | 
			
		||||
#if (HAS_BME)
 | 
			
		||||
    dp_setFont(MY_FONT_STRETCHED);
 | 
			
		||||
    dp_setTextCursor(0, 2);
 | 
			
		||||
 | 
			
		||||
    // line 2-3: Temp
 | 
			
		||||
    dp_printf("TMP:%-2.1f", bme_status.temperature);
 | 
			
		||||
    dp_println(2);
 | 
			
		||||
 | 
			
		||||
    // line 4-5: Hum
 | 
			
		||||
    dp_printf("HUM:%-2.1f", bme_status.humidity);
 | 
			
		||||
    dp_println(2);
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_BME680
 | 
			
		||||
    // line 6-7: IAQ
 | 
			
		||||
    dp_printf("IAQ:%-3.0f", bme_status.iaq);
 | 
			
		||||
#else      // is BME280 or BMP180
 | 
			
		||||
    // line 6-7: Pre
 | 
			
		||||
    dp_printf("PRE:%-2.1f", bme_status.pressure);
 | 
			
		||||
#endif     // HAS_BME680
 | 
			
		||||
    break; // page 3
 | 
			
		||||
#else      // flip page if we are unattended
 | 
			
		||||
    DisplayPage++;
 | 
			
		||||
#endif     // HAS_BME
 | 
			
		||||
 | 
			
		||||
  // ---------- page 4: time ----------
 | 
			
		||||
  case 4:
 | 
			
		||||
 | 
			
		||||
    dp_setFont(MY_FONT_LARGE);
 | 
			
		||||
    dp_setTextCursor(0, 4);
 | 
			
		||||
    dp_printf("%02d:%02d:%02d", hour(t), minute(t), second(t));
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  // ---------- page 5: pax graph ----------
 | 
			
		||||
  case 5:
 | 
			
		||||
 | 
			
		||||
    dp_setFont(MY_FONT_NORMAL);
 | 
			
		||||
    dp_setTextCursor(0, 0);
 | 
			
		||||
    dp_printf("Pax graph");
 | 
			
		||||
    dp_dump(plotbuf);
 | 
			
		||||
    break;
 | 
			
		||||
 | 
			
		||||
  // ---------- page 6: blank screen ----------
 | 
			
		||||
  case 6:
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_BUTTON
 | 
			
		||||
    dp_clear();
 | 
			
		||||
    break;
 | 
			
		||||
#else // don't show blank page if we are unattended
 | 
			
		||||
    DisplayPage++; // next page
 | 
			
		||||
#else // flip page if we are unattended
 | 
			
		||||
    DisplayPage++;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  default:
 | 
			
		||||
    goto start; // start over
 | 
			
		||||
 | 
			
		||||
  } // switch
 | 
			
		||||
 | 
			
		||||
  } // switch (page)
 | 
			
		||||
} // dp_drawPage
 | 
			
		||||
 | 
			
		||||
// display helper functions
 | 
			
		||||
void dp_printf(uint16_t x, uint16_t y, uint8_t font, uint8_t inv,
 | 
			
		||||
               const char *format, ...) {
 | 
			
		||||
// ------------- display helper functions -----------------
 | 
			
		||||
 | 
			
		||||
void dp_setTextCursor(int x, int y) {
 | 
			
		||||
  // x represents the pixel column
 | 
			
		||||
  // y represents the text row
 | 
			
		||||
  dp_col = x;
 | 
			
		||||
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  dp_row = y;
 | 
			
		||||
  oledSetCursor(&ssoled, dp_col, dp_row);
 | 
			
		||||
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  switch (dp_font >> 1) {
 | 
			
		||||
  case MY_FONT_STRETCHED:
 | 
			
		||||
  case MY_FONT_LARGE:
 | 
			
		||||
    dp_row = y * 26;
 | 
			
		||||
    break;
 | 
			
		||||
  case MY_FONT_SMALL:
 | 
			
		||||
  case MY_FONT_NORMAL:
 | 
			
		||||
  default:
 | 
			
		||||
    dp_row = y * 16;
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  tft.setCursor(dp_col, dp_row);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dp_setFont(int font, int inv) {
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  dp_font = (font << 1) | (inv & 0x01);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  // map font oled -> tft
 | 
			
		||||
  switch (font) {
 | 
			
		||||
  case MY_FONT_STRETCHED: // 16x16 on OLED
 | 
			
		||||
  case MY_FONT_LARGE:     // 16x32 on OLED
 | 
			
		||||
    tft.setTextFont(4);   // 26px
 | 
			
		||||
    break;
 | 
			
		||||
  case MY_FONT_SMALL:  // 6x8 on OLED
 | 
			
		||||
  case MY_FONT_NORMAL: // 8x8 on OLED
 | 
			
		||||
  default:
 | 
			
		||||
    tft.setTextFont(2); // 16px
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  // to do: invers printing
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dp_println(int lines) {
 | 
			
		||||
  dp_col = 0;
 | 
			
		||||
  dp_row += lines;
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  dp_setTextCursor(dp_col, dp_row);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  for (int i = 1; i <= lines; i++)
 | 
			
		||||
    tft.println();
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void dp_printf(const char *format, ...) {
 | 
			
		||||
  char loc_buf[64];
 | 
			
		||||
  char *temp = loc_buf;
 | 
			
		||||
  va_list arg;
 | 
			
		||||
@ -423,20 +539,14 @@ void dp_printf(uint16_t x, uint16_t y, uint8_t font, uint8_t inv,
 | 
			
		||||
      va_end(arg);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    len = vsnprintf(temp, len + 1, format, arg);
 | 
			
		||||
    vsnprintf(temp, len + 1, format, arg);
 | 
			
		||||
  }
 | 
			
		||||
  va_end(arg);
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  oledWriteString(&ssoled, 0, x, y, temp, font, inv, false);
 | 
			
		||||
  oledWriteString(&ssoled, 0, -1, dp_row, temp, dp_font >> 1, dp_font & 0x01,
 | 
			
		||||
                  false);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
                   /*
 | 
			
		||||
                     if (font = 0 || font == 1)
 | 
			
		||||
                       spilcdWriteStringFast(x, y, temp, MY_DISPLAY_FGCOLOR, MY_DISPLAY_BGCOLOR,
 | 
			
		||||
                                             font);
 | 
			
		||||
                     else
 | 
			
		||||
                     */
 | 
			
		||||
  spilcdWriteString(x, y, temp, MY_DISPLAY_BGCOLOR, MY_DISPLAY_FGCOLOR, font,
 | 
			
		||||
                    1);
 | 
			
		||||
  tft.printf(temp);
 | 
			
		||||
#endif
 | 
			
		||||
  if (temp != loc_buf) {
 | 
			
		||||
    free(temp);
 | 
			
		||||
@ -447,16 +557,18 @@ void dp_dump(uint8_t *pBuffer) {
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  oledDumpBuffer(&ssoled, pBuffer);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  spilcdShowBuffer(0, 0, MY_DISPLAY_WIDTH, MY_DISPLAY_HEIGHT);
 | 
			
		||||
  // probably oled buffer stucture is not suitable for tft -> to be checked
 | 
			
		||||
  tft.drawBitmap(0, 0, pBuffer, MY_DISPLAY_WIDTH, MY_DISPLAY_HEIGHT,
 | 
			
		||||
                 MY_DISPLAY_FGCOLOR);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void dp_clear() {
 | 
			
		||||
void dp_clear(void) {
 | 
			
		||||
  dp_setTextCursor(0, 0);
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  oledFill(&ssoled, 0, 1);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  spilcdFill(0, 1);
 | 
			
		||||
  spilcdScrollReset();
 | 
			
		||||
  tft.fillScreen(MY_DISPLAY_BGCOLOR);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -464,7 +576,7 @@ void dp_contrast(uint8_t contrast) {
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  oledSetContrast(&ssoled, contrast);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  // to come
 | 
			
		||||
  // to do: gamma correction for TFT
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -488,18 +600,19 @@ void dp_shutdown(void) {
 | 
			
		||||
    I2C_MUTEX_UNLOCK(); // release i2c bus access
 | 
			
		||||
  }
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  spilcdShutdown();
 | 
			
		||||
  spilcdFreeBackbuffer();
 | 
			
		||||
  // to come
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------- QR code plotter -----------------
 | 
			
		||||
 | 
			
		||||
void dp_printqr(uint16_t offset_x, uint16_t offset_y, const char *Message) {
 | 
			
		||||
  uint8_t qrcodeData[qrcode_getBufferSize(QR_VERSION)];
 | 
			
		||||
  qrcode_initText(&qrcode, qrcodeData, QR_VERSION, ECC_HIGH, Message);
 | 
			
		||||
 | 
			
		||||
  // draw QR code
 | 
			
		||||
  for (uint16_t y = 0; y < qrcode.size; y++)
 | 
			
		||||
    for (uint16_t x = 0; x < qrcode.size; x++)
 | 
			
		||||
  for (uint8_t y = 0; y < qrcode.size; y++)
 | 
			
		||||
    for (uint8_t x = 0; x < qrcode.size; x++)
 | 
			
		||||
      if (!qrcode_getModule(&qrcode, x, y)) // "black"
 | 
			
		||||
        dp_fillRect(x * QR_SCALEFACTOR + offset_x,
 | 
			
		||||
                    y * QR_SCALEFACTOR + offset_y, QR_SCALEFACTOR,
 | 
			
		||||
@ -516,14 +629,15 @@ void dp_printqr(uint16_t offset_x, uint16_t offset_y, const char *Message) {
 | 
			
		||||
              qrcode.size * QR_SCALEFACTOR + 2 * offset_y, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------- graphics primitives -----------------
 | 
			
		||||
 | 
			
		||||
void dp_fillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
 | 
			
		||||
                 uint8_t bRender) {
 | 
			
		||||
#if (HAS_DISPLAY) == 1
 | 
			
		||||
  for (uint16_t xi = x; xi < x + width; xi++)
 | 
			
		||||
    oledDrawLine(&ssoled, xi, y, xi, y + height - 1, bRender);
 | 
			
		||||
#elif (HAS_DISPLAY) == 2
 | 
			
		||||
  spilcdRectangle(x, y, width, height, MY_DISPLAY_BGCOLOR, MY_DISPLAY_FGCOLOR,
 | 
			
		||||
                  1, 1);
 | 
			
		||||
  tft.fillRect(x, y, width, height, MY_DISPLAY_FGCOLOR);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -543,6 +657,8 @@ int dp_drawPixel(uint8_t *buf, const uint16_t x, const uint16_t y,
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------- buffer scroll functions -----------------
 | 
			
		||||
 | 
			
		||||
void dp_scrollHorizontal(uint8_t *buf, const uint16_t width,
 | 
			
		||||
                         const uint16_t height, bool left) {
 | 
			
		||||
 | 
			
		||||
@ -588,6 +704,8 @@ void dp_scrollVertical(uint8_t *buf, const uint16_t width,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ------------- curve plotter -----------------
 | 
			
		||||
 | 
			
		||||
void dp_plotCurve(uint16_t count, bool reset) {
 | 
			
		||||
 | 
			
		||||
  static uint16_t last_count = 0, col = 0, row = 0;
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
#if (HAS_GPS)
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "gpsread.h"
 | 
			
		||||
 | 
			
		||||
// Local logging tag
 | 
			
		||||
static const char TAG[] = __FILE__;
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@
 | 
			
		||||
#define BOARD_HAS_PSRAM // use if board has external PSRAM
 | 
			
		||||
#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | 
			
		||||
 | 
			
		||||
//#define HAS_DISPLAY 2 // TFT-LCD, support work in progess, not ready yet
 | 
			
		||||
#define HAS_DISPLAY 2 // TFT-LCD, support work in progess, not ready yet
 | 
			
		||||
//#define MY_DISPLAY_FLIP  1 // use if display is rotated
 | 
			
		||||
//#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
 | 
			
		||||
//#define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board
 | 
			
		||||
@ -45,13 +45,36 @@
 | 
			
		||||
#define GPS_SERIAL 9600, SERIAL_8N1, RXD2, TXD2 // UBlox NEO 6M RX, TX
 | 
			
		||||
#define GPS_INT GPIO_NUM_35 // 30ns accurary timepulse, to be external wired on pcb: shorten R12!
 | 
			
		||||
 | 
			
		||||
// Pins for interface of LC Display
 | 
			
		||||
#define MY_DISPLAY_CS GPIO_NUM_14
 | 
			
		||||
#define MY_DISPLAY_DC GPIO_NUM_27
 | 
			
		||||
#define MY_DISPLAY_CLK GPIO_NUM_18
 | 
			
		||||
#define MY_DISPLAY_RST GPIO_NUM_33
 | 
			
		||||
#define MY_DISPLAY_BL GPIO_NUM_32
 | 
			
		||||
#define MY_DISPLAY_MOSI GPIO_NUM_23
 | 
			
		||||
#define MY_DISPLAY_MISO GPIO_NUM_19
 | 
			
		||||
// Display Settings
 | 
			
		||||
#define MY_DISPLAY_WIDTH 320
 | 
			
		||||
#define MY_DISPLAY_HEIGHT 240
 | 
			
		||||
#define MY_DISPLAY_INVERT 1
 | 
			
		||||
 | 
			
		||||
// setting for M5 display
 | 
			
		||||
#define USER_SETUP_LOADED 1
 | 
			
		||||
#define ILI9341_DRIVER 1
 | 
			
		||||
#define M5STACK // needed for TFT driver
 | 
			
		||||
 | 
			
		||||
#define TFT_MISO MISO  // SPI
 | 
			
		||||
#define TFT_MOSI MOSI // SPI
 | 
			
		||||
#define TFT_SCLK SCK  // SPI
 | 
			
		||||
#define TFT_CS   GPIO_NUM_14  // Chip select control
 | 
			
		||||
#define TFT_DC   GPIO_NUM_27  // Data Command control
 | 
			
		||||
#define TFT_RST  GPIO_NUM_33  // Reset
 | 
			
		||||
#define TFT_BL   GPIO_NUM_32  // LED back-light
 | 
			
		||||
 | 
			
		||||
#define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
 | 
			
		||||
 | 
			
		||||
//#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
 | 
			
		||||
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
 | 
			
		||||
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
 | 
			
		||||
//#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
 | 
			
		||||
//#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
 | 
			
		||||
//#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
 | 
			
		||||
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
 | 
			
		||||
//#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
 | 
			
		||||
#define SMOOTH_FONT
 | 
			
		||||
 | 
			
		||||
#define SPI_FREQUENCY  40000000
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -32,13 +32,14 @@
 | 
			
		||||
#define BOARD_HAS_PSRAM // use if board has external PSRAM
 | 
			
		||||
#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
 | 
			
		||||
 | 
			
		||||
//#define HAS_DISPLAY 2 // TFT-LCD, support work in progess, not ready yet
 | 
			
		||||
#define HAS_DISPLAY 2 // TFT-LCD, support work in progess, not ready yet
 | 
			
		||||
//#define MY_DISPLAY_FLIP  1 // use if display is rotated
 | 
			
		||||
//#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
 | 
			
		||||
//#define BAT_VOLTAGE_DIVIDER 2 // voltage divider 100k/100k on board
 | 
			
		||||
 | 
			
		||||
#define HAS_LED NOT_A_PIN // no on board LED
 | 
			
		||||
#define RGB_LED_COUNT 5 // we use 5 of 10 LEDs (1 side)
 | 
			
		||||
#define HAS_LED NOT_A_PIN // no on board LED (?)
 | 
			
		||||
#define RGB_LED_COUNT 10
 | 
			
		||||
 | 
			
		||||
#define HAS_RGB_LED SmartLed rgb_led(LED_SK6812, RGB_LED_COUNT, GPIO_NUM_15) // LED_SK6812 RGB LED on GPIO15
 | 
			
		||||
#define HAS_BUTTON (39) // on board button A
 | 
			
		||||
 | 
			
		||||
@ -50,13 +51,33 @@
 | 
			
		||||
// Display Settings
 | 
			
		||||
#define MY_DISPLAY_WIDTH 320
 | 
			
		||||
#define MY_DISPLAY_HEIGHT 240
 | 
			
		||||
#define MY_DISPLAY_TYPE LCD_ILI9341
 | 
			
		||||
#define MY_DISPLAY_CS GPIO_NUM_14 // Display CS pin
 | 
			
		||||
#define MY_DISPLAY_CLK GPIO_NUM_18 // SPI CLOCK pin
 | 
			
		||||
#define MY_DISPLAY_DC GPIO_NUM_27 // Display command/data pin
 | 
			
		||||
#define MY_DISPLAY_MOSI GPIO_NUM_23 // SPI MOSI
 | 
			
		||||
#define MY_DISPLAY_MISO GPIO_NUM_19 // SPI MISO
 | 
			
		||||
#define MY_DISPLAY_BL GPIO_NUM_32 // backlight control
 | 
			
		||||
#define MY_DISPLAY_RST GPIO_NUM_33 // RESET control
 | 
			
		||||
#define MY_DISPLAY_INVERT 1
 | 
			
		||||
 | 
			
		||||
// setting for M5 display
 | 
			
		||||
#define USER_SETUP_LOADED 1
 | 
			
		||||
#define ILI9341_DRIVER 1
 | 
			
		||||
#define M5STACK // needed for TFT driver
 | 
			
		||||
 | 
			
		||||
#define TFT_MISO MISO  // SPI
 | 
			
		||||
#define TFT_MOSI MOSI // SPI
 | 
			
		||||
#define TFT_SCLK SCK  // SPI
 | 
			
		||||
#define TFT_CS   GPIO_NUM_14  // Chip select control
 | 
			
		||||
#define TFT_DC   GPIO_NUM_27  // Data Command control
 | 
			
		||||
#define TFT_RST  GPIO_NUM_33  // Reset
 | 
			
		||||
#define TFT_BL   GPIO_NUM_32  // LED back-light
 | 
			
		||||
 | 
			
		||||
#define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
 | 
			
		||||
 | 
			
		||||
//#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
 | 
			
		||||
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
 | 
			
		||||
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
 | 
			
		||||
//#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
 | 
			
		||||
//#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
 | 
			
		||||
//#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
 | 
			
		||||
//#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
 | 
			
		||||
//#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts
 | 
			
		||||
#define SMOOTH_FONT
 | 
			
		||||
 | 
			
		||||
#define SPI_FREQUENCY  40000000
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -65,8 +65,8 @@ RGBColor rgb_hsl2rgb(float h, float s, float l) {
 | 
			
		||||
void rgb_set_color(uint16_t hue) {
 | 
			
		||||
  int i = RGB_LED_COUNT;
 | 
			
		||||
  if (hue == COLOR_NONE) {
 | 
			
		||||
    // Off
 | 
			
		||||
    while (i--)
 | 
			
		||||
    // set Off
 | 
			
		||||
    for (int i = 0; i < RGB_LED_COUNT; i++)
 | 
			
		||||
      rgb_led[i] = Rgb(0, 0, 0);
 | 
			
		||||
  } else {
 | 
			
		||||
    // see http://www.workwithcolor.com/blue-color-hue-range-01.htm
 | 
			
		||||
@ -76,7 +76,7 @@ void rgb_set_color(uint16_t hue) {
 | 
			
		||||
    // cfg.rgblum is between 0 and 100 (percent)
 | 
			
		||||
    RGBColor target = rgb_hsl2rgb(hue / 360.0f, 1.0f, 0.005f * cfg.rgblum);
 | 
			
		||||
    // uint32_t color = target.R<<16 | target.G<<8 | target.B;
 | 
			
		||||
    while (i--)
 | 
			
		||||
    for (int i = 0; i < RGB_LED_COUNT; i++)
 | 
			
		||||
      rgb_led[i] = Rgb(target.R, target.G, target.B);
 | 
			
		||||
  }
 | 
			
		||||
  // Show
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
#ifdef HAS_MATRIX_DISPLAY
 | 
			
		||||
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "ledmatrixdisplay.h"
 | 
			
		||||
 | 
			
		||||
#define MATRIX_DISPLAY_PAGES (2) // number of display pages
 | 
			
		||||
#define LINE_DIAGRAM_DIVIDER (2) // scales pax numbers to led rows
 | 
			
		||||
@ -205,7 +206,7 @@ uint8_t GetCharWidth(char cChar) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ScrollMatrixLeft(uint8_t *buf, const uint16_t cols, const uint16_t rows) {
 | 
			
		||||
  uint32_t i, k, idx;
 | 
			
		||||
  uint32_t i, k, idx = 0;
 | 
			
		||||
  const uint32_t x = cols / 8;
 | 
			
		||||
 | 
			
		||||
  for (k = 0; k < rows; k++) {
 | 
			
		||||
 | 
			
		||||
@ -17,8 +17,16 @@
 | 
			
		||||
// --> adapt to your device only if necessary
 | 
			
		||||
 | 
			
		||||
// use interrupts only if LORA_IRQ and LORA_DIO are connected to interrupt
 | 
			
		||||
// capable GPIO pins on your board, if not disable interrupts
 | 
			
		||||
// capable and separate GPIO pins on your board, if not don't enable
 | 
			
		||||
#if (LORA_IRQ) != (LORA_IO1)
 | 
			
		||||
#define LMIC_USE_INTERRUPTS 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// avoid lmic warning if we don't configure radio because we don't have one
 | 
			
		||||
#define CFG_sx1276_radio 1
 | 
			
		||||
#if ! (defined(CFG_sx1272_radio) || defined(CFG_sx1276_radio))
 | 
			
		||||
#define CFG_sx1276_radio 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// time sync via LoRaWAN network, note: not supported by TTNv2
 | 
			
		||||
#define LMIC_ENABLE_DeviceTimeReq 1
 | 
			
		||||
@ -96,3 +104,6 @@
 | 
			
		||||
#define USE_IDEETRON_AES
 | 
			
		||||
//
 | 
			
		||||
//#define USE_MBEDTLS_AES
 | 
			
		||||
 | 
			
		||||
// Define this for devices with external power.
 | 
			
		||||
//#define LMIC_MCMD_DEVS_BATT_DEFAULT MCMD_DEVS_EXT_POWER
 | 
			
		||||
@ -538,32 +538,6 @@ const char *getCrName(rps_t rps) {
 | 
			
		||||
  return t[getCr(rps)];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
u1_t os_getBattLevel() {
 | 
			
		||||
 | 
			
		||||
  //return values:
 | 
			
		||||
  //MCMD_DEVS_EXT_POWER   = 0x00, // external power supply
 | 
			
		||||
  //MCMD_DEVS_BATT_MIN    = 0x01, // min battery value
 | 
			
		||||
  //MCMD_DEVS_BATT_MAX    = 0xFE, // max battery value
 | 
			
		||||
  //MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level
 | 
			
		||||
 | 
			
		||||
#if (defined HAS_PMU || defined BAT_MEASURE_ADC)
 | 
			
		||||
  uint16_t voltage = read_voltage();
 | 
			
		||||
 | 
			
		||||
  switch (voltage) {
 | 
			
		||||
  case 0:
 | 
			
		||||
    return MCMD_DEVS_BATT_NOINFO;
 | 
			
		||||
  case 0xffff:
 | 
			
		||||
    return MCMD_DEVS_EXT_POWER;
 | 
			
		||||
  default:
 | 
			
		||||
    return (voltage > OTA_MIN_BATT ? MCMD_DEVS_BATT_MAX : MCMD_DEVS_BATT_MIN);
 | 
			
		||||
  }
 | 
			
		||||
#else // we don't have any info on battery level
 | 
			
		||||
  return MCMD_DEVS_BATT_NOINFO;
 | 
			
		||||
#endif
 | 
			
		||||
} // getBattLevel()
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if (VERBOSE)
 | 
			
		||||
// decode LORAWAN MAC message
 | 
			
		||||
void mac_decode(const uint8_t cmd[], const uint8_t cmdlen, bool is_down) {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
 | 
			
		||||
// Basic Config
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "macsniff.h"
 | 
			
		||||
 | 
			
		||||
#if (VENDORFILTER)
 | 
			
		||||
#include "vendor_array.h"
 | 
			
		||||
 | 
			
		||||
@ -79,8 +79,9 @@ triggers pps 1 sec impulse
 | 
			
		||||
configData_t cfg; // struct holds current device configuration
 | 
			
		||||
char lmic_event_msg[LMIC_EVENTMSG_LEN]; // display buffer for LMIC event message
 | 
			
		||||
uint8_t volatile channel = 0;           // channel rotation counter
 | 
			
		||||
uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
 | 
			
		||||
                  batt_voltage = 0; // globals for display
 | 
			
		||||
uint8_t batt_level = 0;                 // display value
 | 
			
		||||
uint16_t volatile macs_total = 0, macs_wifi = 0,
 | 
			
		||||
                  macs_ble = 0; // globals for display
 | 
			
		||||
 | 
			
		||||
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL;
 | 
			
		||||
 | 
			
		||||
@ -260,7 +261,7 @@ void setup() {
 | 
			
		||||
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
 | 
			
		||||
  strcat_P(features, " BATT");
 | 
			
		||||
  calibrate_voltage();
 | 
			
		||||
  batt_voltage = read_voltage();
 | 
			
		||||
  batt_level = read_battlevel();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (USE_OTA)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										26
									
								
								src/ota.cpp
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/ota.cpp
									
									
									
									
									
								
							@ -47,12 +47,17 @@ void start_ota_update() {
 | 
			
		||||
 | 
			
		||||
  dp_setup();
 | 
			
		||||
 | 
			
		||||
  dp_printf(0, 0, 0, 1, "SOFTWARE UPDATE");
 | 
			
		||||
  dp_printf(0, 1, 0, 0, "WiFi connect  ..");
 | 
			
		||||
  dp_printf(0, 2, 0, 0, "Has Update?   ..");
 | 
			
		||||
  dp_printf(0, 3, 0, 0, "Fetching      ..");
 | 
			
		||||
  dp_printf(0, 4, 0, 0, "Downloading   ..");
 | 
			
		||||
  dp_printf(0, 5, 0, 0, "Rebooting     ..");
 | 
			
		||||
  dp_printf("SOFTWARE UPDATE");
 | 
			
		||||
  dp_println();
 | 
			
		||||
  dp_printf("WiFi connect  ..");
 | 
			
		||||
  dp_println();
 | 
			
		||||
  dp_printf("Has Update?   ..");
 | 
			
		||||
  dp_println();
 | 
			
		||||
  dp_printf("Fetching      ..");
 | 
			
		||||
  dp_println();
 | 
			
		||||
  dp_printf("Downloading   ..");
 | 
			
		||||
  dp_println();
 | 
			
		||||
  dp_printf("Rebooting     ..");
 | 
			
		||||
  dp_dump(displaybuf);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -301,10 +306,13 @@ retry:
 | 
			
		||||
void ota_display(const uint8_t row, const std::string status,
 | 
			
		||||
                 const std::string msg) {
 | 
			
		||||
#ifdef HAS_DISPLAY
 | 
			
		||||
  dp_printf(112, row, 0, 0, status.substr(0, 2).c_str());
 | 
			
		||||
  dp_setFont(MY_FONT_SMALL);
 | 
			
		||||
  dp_setTextCursor(14, row);
 | 
			
		||||
  dp_printf(status.substr(0, 2).c_str());
 | 
			
		||||
  if (!msg.empty()) {
 | 
			
		||||
    dp_printf(0, 7, 0, 0, "                ");
 | 
			
		||||
    dp_printf(0, 7, 0, 0, msg.substr(0, 16).c_str());
 | 
			
		||||
    dp_printf("                ");
 | 
			
		||||
    dp_printf(msg.substr(0, 16).c_str());
 | 
			
		||||
    dp_println();
 | 
			
		||||
  }
 | 
			
		||||
  dp_dump(displaybuf);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -335,14 +335,16 @@ void PayloadConvert::addSDS(sdsStatus_t sds) {
 | 
			
		||||
#if (PAYLOAD_ENCODER == 3) // Cayenne LPP dynamic
 | 
			
		||||
  buffer[cursor++] = LPP_PARTMATTER10_CHANNEL; // for PM10
 | 
			
		||||
#endif
 | 
			
		||||
    buffer[cursor++] = LPP_LUMINOSITY; // workaround since cayenne has no data type meter
 | 
			
		||||
  buffer[cursor++] =
 | 
			
		||||
      LPP_LUMINOSITY; // workaround since cayenne has no data type meter
 | 
			
		||||
  buffer[cursor++] = highByte((uint16_t)(sds.pm10 * 10));
 | 
			
		||||
  buffer[cursor++] = lowByte((uint16_t)(sds.pm10 * 10));
 | 
			
		||||
// value of PM2.5
 | 
			
		||||
#if (PAYLOAD_ENCODER == 3) // Cayenne LPP dynamic
 | 
			
		||||
  buffer[cursor++] = LPP_PARTMATTER25_CHANNEL; // for PM2.5
 | 
			
		||||
#endif
 | 
			
		||||
    buffer[cursor++] = LPP_LUMINOSITY; // workaround since cayenne has no data type meter
 | 
			
		||||
  buffer[cursor++] =
 | 
			
		||||
      LPP_LUMINOSITY; // workaround since cayenne has no data type meter
 | 
			
		||||
  buffer[cursor++] = highByte((uint16_t)(sds.pm25 * 10));
 | 
			
		||||
  buffer[cursor++] = lowByte((uint16_t)(sds.pm25 * 10));
 | 
			
		||||
#endif // HAS_SDS011
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ void AXP192_powerevent_IRQ(void) {
 | 
			
		||||
  pmu.clearIRQ();
 | 
			
		||||
 | 
			
		||||
  // refresh stored voltage value
 | 
			
		||||
  read_voltage();
 | 
			
		||||
  read_battlevel();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AXP192_power(pmu_power_t powerlevel) {
 | 
			
		||||
@ -175,21 +175,11 @@ void calibrate_voltage(void) {
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool batt_sufficient() {
 | 
			
		||||
#if (defined HAS_PMU || defined BAT_MEASURE_ADC)
 | 
			
		||||
  uint16_t volts = read_voltage();
 | 
			
		||||
  return ((volts < 1000) ||
 | 
			
		||||
          (volts > OTA_MIN_BATT)); // no battery or battery sufficient
 | 
			
		||||
#else
 | 
			
		||||
  return true;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint16_t read_voltage() {
 | 
			
		||||
uint16_t read_voltage(void) {
 | 
			
		||||
  uint16_t voltage = 0;
 | 
			
		||||
 | 
			
		||||
#ifdef HAS_PMU
 | 
			
		||||
  voltage = pmu.isVBUSPlug() ? 0xffff : pmu.getBattVoltage();
 | 
			
		||||
  voltage = pmu.getBattVoltage();
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
#ifdef BAT_MEASURE_ADC
 | 
			
		||||
@ -219,3 +209,58 @@ uint16_t read_voltage() {
 | 
			
		||||
 | 
			
		||||
  return voltage;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t read_battlevel() {
 | 
			
		||||
 | 
			
		||||
  // return the battery value as sent in MAC Command
 | 
			
		||||
  // DevStatusAns. Available defines in lorabase.h:
 | 
			
		||||
  //   MCMD_DEVS_EXT_POWER   = 0x00, // external power supply
 | 
			
		||||
  //   MCMD_DEVS_BATT_MIN    = 0x01, // min battery value
 | 
			
		||||
  //   MCMD_DEVS_BATT_MAX    = 0xFE, // max battery value
 | 
			
		||||
  //   MCMD_DEVS_BATT_NOINFO = 0xFF, // unknown battery level
 | 
			
		||||
  // we calculate the applicable value from MCMD_DEVS_BATT_MIN to
 | 
			
		||||
  // MCMD_DEVS_BATT_MAX from bat_percent value
 | 
			
		||||
 | 
			
		||||
  const uint16_t batt_voltage_range = BAT_MAX_VOLTAGE - BAT_MIN_VOLTAGE;
 | 
			
		||||
  const uint8_t batt_level_range = MCMD_DEVS_BATT_MAX - MCMD_DEVS_BATT_MIN + 1;
 | 
			
		||||
  const int batt_voltage = read_voltage() - BAT_MIN_VOLTAGE;
 | 
			
		||||
  const uint8_t batt_percent = (batt_voltage > 0)
 | 
			
		||||
                                   ? (float)batt_voltage / (float)batt_voltage_range * 100.0
 | 
			
		||||
                                   : MCMD_DEVS_BATT_NOINFO;
 | 
			
		||||
  uint8_t lmic_batt_level;
 | 
			
		||||
 | 
			
		||||
  ESP_LOGD(TAG, "batt_voltage = %d mV / batt_level = %u%%", batt_voltage,
 | 
			
		||||
           batt_percent);
 | 
			
		||||
 | 
			
		||||
  if (batt_percent != MCMD_DEVS_BATT_NOINFO)
 | 
			
		||||
#ifdef HAS_PMU
 | 
			
		||||
    lmic_batt_level = pmu.isVBUSPlug() ? MCMD_DEVS_EXT_POWER
 | 
			
		||||
                                       : (float)batt_percent / (float)batt_level_range * 100.0;
 | 
			
		||||
#else
 | 
			
		||||
    lmic_batt_level = (float)batt_percent / (float)batt_level_range * 100.0;
 | 
			
		||||
#endif // HAS_PMU
 | 
			
		||||
  else
 | 
			
		||||
    lmic_batt_level = MCMD_DEVS_BATT_NOINFO;
 | 
			
		||||
 | 
			
		||||
// set battery level value for lmic stack
 | 
			
		||||
#if (HAS_LORA)
 | 
			
		||||
    // LMIC_setBattLevel(lmic_batt_level);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  return batt_percent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool batt_sufficient() {
 | 
			
		||||
#if (defined HAS_PMU || defined BAT_MEASURE_ADC)
 | 
			
		||||
  switch (batt_level) {
 | 
			
		||||
  case MCMD_DEVS_EXT_POWER:
 | 
			
		||||
    return true;
 | 
			
		||||
  case MCMD_DEVS_BATT_NOINFO:
 | 
			
		||||
    return true;
 | 
			
		||||
  default:
 | 
			
		||||
    return (batt_level > OTA_MIN_BATT);
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
  return true; // we don't know batt level
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
// Basic Config
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "sensor.h"
 | 
			
		||||
 | 
			
		||||
// Local logging tag
 | 
			
		||||
static const char TAG[] = __FILE__;
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,4 @@
 | 
			
		||||
#include "timekeeper.h"
 | 
			
		||||
#include "paxcounter.conf"
 | 
			
		||||
 | 
			
		||||
#if !(HAS_LORA)
 | 
			
		||||
#if (TIME_SYNC_LORASERVER)
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,6 @@ accept this.
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#if (HAS_LORA)
 | 
			
		||||
 | 
			
		||||
#if (TIME_SYNC_LORASERVER) && (TIME_SYNC_LORAWAN)
 | 
			
		||||
#error Duplicate timesync method selected. You must select either LORASERVER or LORAWAN timesync.
 | 
			
		||||
#endif
 | 
			
		||||
@ -48,7 +46,7 @@ void timesync_request(void) {
 | 
			
		||||
    return;
 | 
			
		||||
  // start timesync handshake
 | 
			
		||||
  else {
 | 
			
		||||
    ESP_LOGI(TAG, "[%0.3f] Timeserver sync request seqNo#%d started",
 | 
			
		||||
    ESP_LOGI(TAG, "[%0.3f] Timeserver sync request started, seqNo#%d",
 | 
			
		||||
             millis() / 1000.0, time_sync_seqNo);
 | 
			
		||||
    xTaskNotifyGive(timeSyncProcTask); // unblock timesync task
 | 
			
		||||
  }
 | 
			
		||||
@ -172,13 +170,12 @@ void timesync_store(uint32_t timestamp, timesync_t timestamp_type) {
 | 
			
		||||
// callback function to receive time answer from network or answer
 | 
			
		||||
void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) {
 | 
			
		||||
 | 
			
		||||
#if (TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)
 | 
			
		||||
 | 
			
		||||
  // if no timesync handshake is pending then exit
 | 
			
		||||
  if (!timeSyncPending)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  // store LMIC time when we received the timesync answer
 | 
			
		||||
  ostime_t rxTime = osticks2ms(os_getTime());
 | 
			
		||||
 | 
			
		||||
  // mask application irq to ensure accurate timing
 | 
			
		||||
  mask_user_IRQ();
 | 
			
		||||
 | 
			
		||||
@ -194,7 +191,7 @@ void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) {
 | 
			
		||||
  // flag: length of buffer
 | 
			
		||||
 | 
			
		||||
  // Store the instant the time request of the node was received on the gateway
 | 
			
		||||
  timesync_store(rxTime, timesync_rx);
 | 
			
		||||
  timesync_store(osticks2ms(os_getTime(), timesync_rx);
 | 
			
		||||
 | 
			
		||||
  //  parse pUserData:
 | 
			
		||||
  //  p       type      meaning
 | 
			
		||||
@ -274,6 +271,6 @@ Exit:
 | 
			
		||||
  // inform processing task
 | 
			
		||||
  xTaskNotify(timeSyncProcTask, (rc ? rcv_seqNo : TIME_SYNC_END_FLAG),
 | 
			
		||||
              eSetBits);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif // HAS_LORA
 | 
			
		||||
#endif // (TIME_SYNC_LORASERVER) || (TIME_SYNC_LORAWAN)
 | 
			
		||||
}
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
// Basic Config
 | 
			
		||||
#include "globals.h"
 | 
			
		||||
#include "wifiscan.h"
 | 
			
		||||
#include <esp_coexist.h>
 | 
			
		||||
#include "coexist_internal.h"
 | 
			
		||||
 | 
			
		||||
// Local logging tag
 | 
			
		||||
static const char TAG[] = "wifi";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user