commit
956ea2f879
10
README.md
10
README.md
@ -63,7 +63,8 @@ Depending on board hardware following features are supported:
|
|||||||
- IF482 (serial) and DCF77 (gpio) time telegram generator
|
- IF482 (serial) and DCF77 (gpio) time telegram generator
|
||||||
- Switch external power / battery
|
- Switch external power / battery
|
||||||
- LED Matrix display (similar to [this 64x16 model](https://www.instructables.com/id/64x16-RED-LED-Marquee/), can be ordered on [Aliexpress](https://www.aliexpress.com/item/P3-75-dot-matrix-led-module-3-75mm-high-clear-top1-for-text-display-304-60mm/32616683948.html))
|
- LED Matrix display (similar to [this 64x16 model](https://www.instructables.com/id/64x16-RED-LED-Marquee/), can be ordered on [Aliexpress](https://www.aliexpress.com/item/P3-75-dot-matrix-led-module-3-75mm-high-clear-top1-for-text-display-304-60mm/32616683948.html))
|
||||||
- SD-card (see section SD-card here)
|
- SD-card (see section SD-card here) for logging pax data
|
||||||
|
- Ethernet interface for MQTT communication via TCP/IP
|
||||||
|
|
||||||
Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).<br>
|
Target platform must be selected in [platformio.ini](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/platformio.ini).<br>
|
||||||
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory. If you want to use a ESP32 board which is not yet supported, use hal file generic.h and tailor pin mappings to your needs. Pull requests for new boards welcome.<br>
|
Hardware dependent settings (pinout etc.) are stored in board files in /hal directory. If you want to use a ESP32 board which is not yet supported, use hal file generic.h and tailor pin mappings to your needs. Pull requests for new boards welcome.<br>
|
||||||
@ -207,8 +208,11 @@ There in the sensor configuration select "TheThingsNetwork" and set Decoding Pro
|
|||||||
# SD-card
|
# SD-card
|
||||||
Data can be stored on an SD-card if one is availabe. Simply choose the file in src/hal and add the following lines to your hal-file:
|
Data can be stored on an SD-card if one is availabe. Simply choose the file in src/hal and add the following lines to your hal-file:
|
||||||
|
|
||||||
#define HAS_SDCARD 1 // this board has an SD-card-reader/writer
|
#define HAS_SDCARD 1 // SD-card-reader/writer, using SPI interface
|
||||||
// Pins for SD-card
|
OR
|
||||||
|
#define HAS_SDCARD 2 // SD-card-reader/writer, using SDMMC interface
|
||||||
|
|
||||||
|
// Pins for SPI interface
|
||||||
#define SDCARD_CS (13) // fill in the correct numbers for your board
|
#define SDCARD_CS (13) // fill in the correct numbers for your board
|
||||||
#define SDCARD_MOSI (15)
|
#define SDCARD_MOSI (15)
|
||||||
#define SDCARD_MISO (2)
|
#define SDCARD_MISO (2)
|
||||||
|
10
build.py
10
build.py
@ -66,16 +66,20 @@ myboard = mykeys["board"]
|
|||||||
myuploadspeed = mykeys["upload_speed"]
|
myuploadspeed = mykeys["upload_speed"]
|
||||||
env.Replace(BOARD=myboard)
|
env.Replace(BOARD=myboard)
|
||||||
env.Replace(UPLOAD_SPEED=myuploadspeed)
|
env.Replace(UPLOAD_SPEED=myuploadspeed)
|
||||||
|
print('\033[94m' + "Target board: " + myboard + " @ " + myuploadspeed + "bps" + '\033[0m')
|
||||||
|
|
||||||
# re-set partition table
|
# re-set partition table
|
||||||
mypartitiontable = config.get("env", "board_build.partitions")
|
mypartitiontable = config.get("env", "board_build.partitions")
|
||||||
board = env.BoardConfig(myboard)
|
board = env.BoardConfig(myboard)
|
||||||
board.manifest['build']['partitions'] = mypartitiontable
|
board.manifest['build']['partitions'] = mypartitiontable
|
||||||
|
|
||||||
# display target
|
|
||||||
print('\033[94m' + "TARGET BOARD: " + myboard + " @ " + myuploadspeed + "bps" + '\033[0m')
|
|
||||||
print('\033[94m' + "Partition table: " + mypartitiontable + '\033[0m')
|
print('\033[94m' + "Partition table: " + mypartitiontable + '\033[0m')
|
||||||
|
|
||||||
|
# set display library
|
||||||
|
if "display_library" in mykeys:
|
||||||
|
mydisplay = mykeys["display_library"]
|
||||||
|
env.Append(display_library=mydisplay)
|
||||||
|
print('\033[94m' + "Display library: " + mydisplay + '\033[0m')
|
||||||
|
|
||||||
# parse ota key file
|
# parse ota key file
|
||||||
with open(otakeyfile) as myfile:
|
with open(otakeyfile) as myfile:
|
||||||
for line in myfile:
|
for line in myfile:
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "senddata.h"
|
#include "senddata.h"
|
||||||
#include "rcommand.h"
|
#include "rcommand.h"
|
||||||
#include "spislave.h"
|
#include "spislave.h"
|
||||||
|
#include "mqttclient.h"
|
||||||
#include "bmesensor.h"
|
#include "bmesensor.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "sds011read.h"
|
#include "sds011read.h"
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include "qrcode.h"
|
#include "qrcode.h"
|
||||||
|
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
#include <ss_oled.h>
|
#include <OneBitDisplay.h>
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
#include <TFT_eSPI.h>
|
#include <TFT_eSPI.h>
|
||||||
#endif
|
#endif
|
||||||
|
26
include/mqttclient.h
Normal file
26
include/mqttclient.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _MQTTCLIENT_H
|
||||||
|
#define _MQTTCLIENT_H
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
#include "rcommand.h"
|
||||||
|
#include <ETH.h>
|
||||||
|
#include <PubSubClient.h>
|
||||||
|
|
||||||
|
#define MQTT_INTOPIC "paxcounter_in/"
|
||||||
|
#define MQTT_OUTTOPIC "paxcounter_out/"
|
||||||
|
#define MQTT_PORT 1883
|
||||||
|
#define MQTT_SERVER "broker.hivemq.com"
|
||||||
|
#define MQTT_RETRYSEC 10 // retry reconnect every 10 seconds
|
||||||
|
|
||||||
|
extern TaskHandle_t mqttTask;
|
||||||
|
extern PubSubClient mqttClient;
|
||||||
|
|
||||||
|
void mqtt_enqueuedata(MessageBuffer_t *message);
|
||||||
|
void mqtt_queuereset(void);
|
||||||
|
void mqtt_client_task(void *param);
|
||||||
|
int mqtt_connect(const char *my_host, const uint16_t my_port);
|
||||||
|
void mqtt_callback(char *topic, byte *payload, unsigned int length);
|
||||||
|
void NetworkEvent(WiFiEvent_t event);
|
||||||
|
esp_err_t mqtt_init(void);
|
||||||
|
|
||||||
|
#endif // _MQTTCLIENT_H
|
@ -18,6 +18,22 @@
|
|||||||
#define BAT_MIN_VOLTAGE 3100 // millivolts
|
#define BAT_MIN_VOLTAGE 3100 // millivolts
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PMU_CHG_CUTOFF
|
||||||
|
#ifdef HAS_PMU
|
||||||
|
#define PMU_CHG_CUTOFF AXP202_TARGET_VOL_4_2V
|
||||||
|
#elif defined HAS_IP5306
|
||||||
|
#define PMU_CHG_CUTOFF 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PMU_CHG_CURRENT
|
||||||
|
#ifdef HAS_PMU
|
||||||
|
#define PMU_CHG_CURRENT AXP1XX_CHARGE_CUR_450MA
|
||||||
|
#elif defined HAS_IP5306
|
||||||
|
#define PMU_CHG_CURRENT 2
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef uint8_t (*mapFn_t)(uint16_t, uint16_t, uint16_t);
|
typedef uint8_t (*mapFn_t)(uint16_t, uint16_t, uint16_t);
|
||||||
|
|
||||||
uint16_t read_voltage(void);
|
uint16_t read_voltage(void);
|
||||||
@ -37,10 +53,14 @@ void AXP192_showstatus(void);
|
|||||||
#endif // HAS_PMU
|
#endif // HAS_PMU
|
||||||
|
|
||||||
#ifdef HAS_IP5306
|
#ifdef HAS_IP5306
|
||||||
|
void IP5306_init(void);
|
||||||
void printIP5306Stats(void);
|
void printIP5306Stats(void);
|
||||||
uint8_t IP5306_GetPowerSource(void);
|
uint8_t IP5306_GetPowerSource(void);
|
||||||
uint8_t IP5306_GetBatteryLevel(void);
|
uint8_t IP5306_GetBatteryLevel(void);
|
||||||
uint8_t IP5306_GetBatteryFull(void);
|
uint8_t IP5306_GetBatteryFull(void);
|
||||||
|
void IP5306_SetChargerEnabled(uint8_t v);
|
||||||
|
void IP5306_SetChargeCutoffVoltage(uint8_t v);
|
||||||
|
void IP5306_SetEndChargeCurrentDetection(uint8_t v);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// The following map functions were taken from
|
// The following map functions were taken from
|
||||||
|
@ -4,14 +4,42 @@
|
|||||||
#include <globals.h>
|
#include <globals.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
|
|
||||||
|
#ifdef HAS_SDCARD
|
||||||
|
#if HAS_SDCARD == 1
|
||||||
#include <mySD.h>
|
#include <mySD.h>
|
||||||
|
#elif HAS_SDCARD == 2
|
||||||
|
#include <SD_MMC.h>
|
||||||
|
#else
|
||||||
|
#error HAS_SDCARD unknown card reader value, must be either 1 or 2
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAS_SDS011
|
||||||
#include "sds011read.h"
|
#include "sds011read.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SDCARD_FILE_NAME "paxcount.%02d"
|
#ifndef SDCARD_CS
|
||||||
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
#define SDCARD_CS SS
|
||||||
|
#endif
|
||||||
|
|
||||||
bool sdcard_init( void );
|
#ifndef SDCARD_MOSI
|
||||||
void sdcardWriteData( uint16_t, uint16_t);
|
#define SDCARD_MOSI MOSI
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDCARD_MISO
|
||||||
|
#define SDCARD_MISO MISO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SDCARD_SCLK
|
||||||
|
#define SDCARD_SCLK SCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SDCARD_FILE_NAME "/paxcount.%02d"
|
||||||
|
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"
|
||||||
|
|
||||||
|
bool sdcard_init(void);
|
||||||
|
void sdcardWriteData(uint16_t, uint16_t);
|
||||||
|
static void createFile(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define _SENDDATA_H
|
#define _SENDDATA_H
|
||||||
|
|
||||||
#include "spislave.h"
|
#include "spislave.h"
|
||||||
|
#include "mqttclient.h"
|
||||||
#include "cyclic.h"
|
#include "cyclic.h"
|
||||||
#include "sensor.h"
|
#include "sensor.h"
|
||||||
#include "lorawan.h"
|
#include "lorawan.h"
|
||||||
|
@ -33,6 +33,7 @@ halfile = generic.h
|
|||||||
;halfile = tinypicomatrix.h
|
;halfile = tinypicomatrix.h
|
||||||
;halfile = m5core.h
|
;halfile = m5core.h
|
||||||
;halfile = m5fire.h
|
;halfile = m5fire.h
|
||||||
|
;halfile = olimexpoeiso.h
|
||||||
|
|
||||||
[platformio]
|
[platformio]
|
||||||
; upload firmware to board with usb cable
|
; upload firmware to board with usb cable
|
||||||
@ -45,7 +46,7 @@ description = Paxcounter is a device for metering passenger flows in realtime. I
|
|||||||
|
|
||||||
[common]
|
[common]
|
||||||
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
; for release_version use max. 10 chars total, use any decimal format like "a.b.c"
|
||||||
release_version = 1.9.991
|
release_version = 1.9.996
|
||||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
; 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
|
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||||
debug_level = 3
|
debug_level = 3
|
||||||
@ -53,26 +54,28 @@ extra_scripts = pre:build.py
|
|||||||
otakeyfile = ota.conf
|
otakeyfile = ota.conf
|
||||||
lorakeyfile = loraconf.h
|
lorakeyfile = loraconf.h
|
||||||
lmicconfigfile = lmic_config.h
|
lmicconfigfile = lmic_config.h
|
||||||
platform_espressif32 = espressif32@1.12.1
|
platform_espressif32 = espressif32@1.12.2
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
upload_speed = 115200
|
upload_speed = 115200 ; set by build.py and taken from hal file
|
||||||
|
display_library = ; set by build.py and taken from hal file
|
||||||
lib_deps_lora =
|
lib_deps_lora =
|
||||||
MCCI LoRaWAN LMIC library@3.2.0 ; MCCI LMIC by Terrill Moore
|
MCCI LoRaWAN LMIC library@3.2.0 ; MCCI LMIC by Terrill Moore
|
||||||
lib_deps_display =
|
lib_deps_display =
|
||||||
ss_oled@4.1.3 ; fast and small OLED lib by Larry Bank
|
;OneBitDisplay@>1.4.0
|
||||||
BitBang_I2C@2.1.1
|
https://github.com/bitbank2/OneBitDisplay.git
|
||||||
QRCode@0.0.1
|
QRCode@0.0.1
|
||||||
TFT_eSPI@2.2.2
|
BitBang_I2C@2.1.1
|
||||||
lib_deps_matrix_display =
|
TFT_eSPI@>=2.2.8
|
||||||
|
lib_deps_ledmatrix =
|
||||||
Ultrathin_LED_Matrix@>=1.0.0
|
Ultrathin_LED_Matrix@>=1.0.0
|
||||||
lib_deps_rgbled =
|
lib_deps_rgbled =
|
||||||
SmartLeds@>=1.2.0
|
SmartLeds@>=1.2.0
|
||||||
lib_deps_gps =
|
lib_deps_gps =
|
||||||
1655@>=1.0.2 ; #1655 TinyGPSPlus by Mikal Hart
|
1655@>=1.0.2 ; #1655 TinyGPSPlus by Mikal Hart
|
||||||
lib_deps_sensors =
|
lib_deps_sensors =
|
||||||
Adafruit Unified Sensor@>=1.1.2
|
Adafruit Unified Sensor@>=1.1.3
|
||||||
Adafruit BME280 Library@>=2.0.2
|
Adafruit BME280 Library@>=2.0.2
|
||||||
Adafruit BMP085 Library@>=1.0.1
|
Adafruit BMP085 Library@>=1.1.0
|
||||||
BSEC Software Library@1.5.1474
|
BSEC Software Library@1.5.1474
|
||||||
https://github.com/ricki-z/SDS011.git
|
https://github.com/ricki-z/SDS011.git
|
||||||
lib_deps_basic =
|
lib_deps_basic =
|
||||||
@ -80,8 +83,9 @@ lib_deps_basic =
|
|||||||
76@>=1.2.4 ; #76 Timezone by Jack Christensen
|
76@>=1.2.4 ; #76 Timezone by Jack Christensen
|
||||||
274@>=2.3.4 ; #274 RTC by Michael Miller
|
274@>=2.3.4 ; #274 RTC by Michael Miller
|
||||||
SimpleButton
|
SimpleButton
|
||||||
AXP202X_Library@>=1.1.0 ; AXP202 PMU lib by Lewis He
|
AXP202X_Library@>=1.1.1 ; AXP202 PMU lib by Lewis He
|
||||||
esp32-micro-sdcard
|
esp32-micro-sdcard
|
||||||
|
PubSubClient@>=2.8.0
|
||||||
lib_deps_all =
|
lib_deps_all =
|
||||||
${common.lib_deps_basic}
|
${common.lib_deps_basic}
|
||||||
${common.lib_deps_lora}
|
${common.lib_deps_lora}
|
||||||
@ -89,7 +93,7 @@ lib_deps_all =
|
|||||||
${common.lib_deps_rgbled}
|
${common.lib_deps_rgbled}
|
||||||
${common.lib_deps_gps}
|
${common.lib_deps_gps}
|
||||||
${common.lib_deps_sensors}
|
${common.lib_deps_sensors}
|
||||||
${common.lib_deps_matrix_display}
|
${common.lib_deps_ledmatrix}
|
||||||
build_flags_basic =
|
build_flags_basic =
|
||||||
-include "src/hal/${board.halfile}"
|
-include "src/hal/${board.halfile}"
|
||||||
-include "src/paxcounter.conf"
|
-include "src/paxcounter.conf"
|
||||||
@ -110,7 +114,7 @@ framework = arduino
|
|||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = min_spiffs.csv
|
board_build.partitions = min_spiffs.csv
|
||||||
upload_speed = ${common.upload_speed}
|
upload_speed = ${common.upload_speed}
|
||||||
;upload_port = COM5
|
;upload_port = COM7
|
||||||
platform = ${common.platform_espressif32}
|
platform = ${common.platform_espressif32}
|
||||||
lib_deps = ${common.lib_deps_all}
|
lib_deps = ${common.lib_deps_all}
|
||||||
build_flags = ${common.build_flags_all}
|
build_flags = ${common.build_flags_all}
|
||||||
|
@ -52,6 +52,11 @@ void doHousekeeping() {
|
|||||||
ESP_LOGD(TAG, "spiloop %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "spiloop %d bytes left | Taskstate = %d",
|
||||||
uxTaskGetStackHighWaterMark(spiTask), eTaskGetState(spiTask));
|
uxTaskGetStackHighWaterMark(spiTask), eTaskGetState(spiTask));
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_MQTT
|
||||||
|
ESP_LOGD(TAG, "MQTTloop %d bytes left | Taskstate = %d",
|
||||||
|
uxTaskGetStackHighWaterMark(mqttTask), eTaskGetState(mqttTask));
|
||||||
|
mqttClient.loop();
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (defined HAS_DCF77 || defined HAS_IF482)
|
#if (defined HAS_DCF77 || defined HAS_IF482)
|
||||||
ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d",
|
ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d",
|
||||||
|
@ -49,24 +49,29 @@ static int dp_row = 0, dp_col = 0, dp_font = 0;
|
|||||||
|
|
||||||
QRCode qrcode;
|
QRCode qrcode;
|
||||||
|
|
||||||
|
#ifdef HAS_DISPLAY
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
SSOLED ssoled;
|
OBDISP ssoled;
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
TFT_eSPI tft = TFT_eSPI();
|
TFT_eSPI tft = TFT_eSPI();
|
||||||
|
#else
|
||||||
|
#error Unknown display type specified in hal file
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void dp_setup(int contrast) {
|
void dp_setup(int contrast) {
|
||||||
|
|
||||||
#if (HAS_DISPLAY) == 1 // I2C OLED
|
#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,
|
int rc = obdI2CInit(&ssoled, OLED_TYPE, OLED_ADDR, MY_DISPLAY_FLIP,
|
||||||
MY_DISPLAY_SCL, MY_DISPLAY_RST,
|
MY_DISPLAY_INVERT, USE_HW_I2C, MY_DISPLAY_SDA,
|
||||||
OLED_FREQUENCY); // use standard I2C bus at 400Khz
|
MY_DISPLAY_SCL, MY_DISPLAY_RST,
|
||||||
|
OLED_FREQUENCY); // use standard I2C bus at 400Khz
|
||||||
assert(rc != OLED_NOT_FOUND);
|
assert(rc != OLED_NOT_FOUND);
|
||||||
|
|
||||||
// set display buffer
|
// set display buffer
|
||||||
oledSetBackBuffer(&ssoled, displaybuf);
|
obdSetBackBuffer(&ssoled, displaybuf);
|
||||||
oledSetTextWrap(&ssoled, true);
|
obdSetTextWrap(&ssoled, true);
|
||||||
dp_font = MY_FONT_NORMAL;
|
dp_font = MY_FONT_NORMAL;
|
||||||
|
|
||||||
#elif (HAS_DISPLAY) == 2 // SPI TFT
|
#elif (HAS_DISPLAY) == 2 // SPI TFT
|
||||||
@ -466,7 +471,7 @@ void dp_setTextCursor(int x, int y) {
|
|||||||
|
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
dp_row = y;
|
dp_row = y;
|
||||||
oledSetCursor(&ssoled, dp_col, dp_row);
|
obdSetCursor(&ssoled, dp_col, dp_row);
|
||||||
|
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
switch (dp_font >> 1) {
|
switch (dp_font >> 1) {
|
||||||
@ -538,8 +543,8 @@ void dp_printf(const char *format, ...) {
|
|||||||
}
|
}
|
||||||
va_end(arg);
|
va_end(arg);
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
oledWriteString(&ssoled, 0, -1, dp_row, temp, dp_font >> 1, dp_font & 0x01,
|
obdWriteString(&ssoled, 0, -1, dp_row, temp, dp_font >> 1, dp_font & 0x01,
|
||||||
false);
|
false);
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
tft.printf(temp);
|
tft.printf(temp);
|
||||||
#endif
|
#endif
|
||||||
@ -550,7 +555,7 @@ void dp_printf(const char *format, ...) {
|
|||||||
|
|
||||||
void dp_dump(uint8_t *pBuffer) {
|
void dp_dump(uint8_t *pBuffer) {
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
oledDumpBuffer(&ssoled, pBuffer);
|
obdDumpBuffer(&ssoled, pBuffer);
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
// probably oled buffer stucture is not suitable for tft -> to be checked
|
// probably oled buffer stucture is not suitable for tft -> to be checked
|
||||||
tft.drawBitmap(0, 0, pBuffer, MY_DISPLAY_WIDTH, MY_DISPLAY_HEIGHT,
|
tft.drawBitmap(0, 0, pBuffer, MY_DISPLAY_WIDTH, MY_DISPLAY_HEIGHT,
|
||||||
@ -561,7 +566,7 @@ void dp_dump(uint8_t *pBuffer) {
|
|||||||
void dp_clear(void) {
|
void dp_clear(void) {
|
||||||
dp_setTextCursor(0, 0);
|
dp_setTextCursor(0, 0);
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
oledFill(&ssoled, 0, 1);
|
obdFill(&ssoled, 0, 1);
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
tft.fillScreen(MY_DISPLAY_BGCOLOR);
|
tft.fillScreen(MY_DISPLAY_BGCOLOR);
|
||||||
#endif
|
#endif
|
||||||
@ -569,7 +574,7 @@ void dp_clear(void) {
|
|||||||
|
|
||||||
void dp_contrast(uint8_t contrast) {
|
void dp_contrast(uint8_t contrast) {
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
oledSetContrast(&ssoled, contrast);
|
obdSetContrast(&ssoled, contrast);
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
// to do: gamma correction for TFT
|
// to do: gamma correction for TFT
|
||||||
#endif
|
#endif
|
||||||
@ -577,7 +582,7 @@ void dp_contrast(uint8_t contrast) {
|
|||||||
|
|
||||||
void dp_power(uint8_t screenon) {
|
void dp_power(uint8_t screenon) {
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
oledPower(&ssoled, screenon);
|
obdPower(&ssoled, screenon);
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
// to come
|
// to come
|
||||||
#endif
|
#endif
|
||||||
@ -590,7 +595,7 @@ void dp_shutdown(void) {
|
|||||||
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
ESP_LOGV(TAG, "[%0.3f] i2c mutex lock failed", millis() / 1000.0);
|
||||||
else {
|
else {
|
||||||
cfg.screenon = 0;
|
cfg.screenon = 0;
|
||||||
oledPower(&ssoled, false);
|
obdPower(&ssoled, false);
|
||||||
delay(DISPLAYREFRESH_MS / 1000 * 1.1);
|
delay(DISPLAYREFRESH_MS / 1000 * 1.1);
|
||||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||||
}
|
}
|
||||||
@ -630,7 +635,7 @@ void dp_fillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height,
|
|||||||
uint8_t bRender) {
|
uint8_t bRender) {
|
||||||
#if (HAS_DISPLAY) == 1
|
#if (HAS_DISPLAY) == 1
|
||||||
for (uint16_t xi = x; xi < x + width; xi++)
|
for (uint16_t xi = x; xi < x + width; xi++)
|
||||||
oledDrawLine(&ssoled, xi, y, xi, y + height - 1, bRender);
|
obdDrawLine(&ssoled, xi, y, xi, y + height - 1, 1, bRender);
|
||||||
#elif (HAS_DISPLAY) == 2
|
#elif (HAS_DISPLAY) == 2
|
||||||
tft.fillRect(x, y, width, height, MY_DISPLAY_FGCOLOR);
|
tft.fillRect(x, y, width, height, MY_DISPLAY_FGCOLOR);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
// upload_speed 115200
|
// upload_speed 115200
|
||||||
// board esp32dev
|
// board esp32dev
|
||||||
|
// display_library lib_deps_oled_display
|
||||||
|
|
||||||
#ifndef _GENERIC_H
|
#ifndef _GENERIC_H
|
||||||
#define _GENERIC_H
|
#define _GENERIC_H
|
||||||
|
@ -37,7 +37,12 @@
|
|||||||
#define HAS_LED NOT_A_PIN // no on board LED (?)
|
#define HAS_LED NOT_A_PIN // no on board LED (?)
|
||||||
#define HAS_BUTTON (39) // on board button A
|
#define HAS_BUTTON (39) // on board button A
|
||||||
|
|
||||||
#define HAS_IP5306 1
|
// power management settings
|
||||||
|
#define HAS_IP5306 1 // has IP5306 chip
|
||||||
|
#define PMU_CHG_CURRENT 2 // battery charge current
|
||||||
|
// possible values: 0:200mA, 1:400mA, *2:500mA, 3:600mA
|
||||||
|
#define PMU_CHG_CUTOFF 0 // battery charge cutoff
|
||||||
|
// possible values: *0:4.2V, 1:4.3V, 2:4.35V, 3:4.4V
|
||||||
|
|
||||||
// GPS settings
|
// GPS settings
|
||||||
#define HAS_GPS 1 // use on board GPS
|
#define HAS_GPS 1 // use on board GPS
|
||||||
|
@ -41,7 +41,12 @@
|
|||||||
#define HAS_RGB_LED SmartLed rgb_led(LED_SK6812, RGB_LED_COUNT, GPIO_NUM_15) // LED_SK6812 RGB LED on GPIO15
|
#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
|
#define HAS_BUTTON (39) // on board button A
|
||||||
|
|
||||||
#define HAS_IP5306 1
|
// power management settings
|
||||||
|
#define HAS_IP5306 1 // has IP5306 chip
|
||||||
|
#define PMU_CHG_CURRENT 2 // battery charge current
|
||||||
|
// possible values: 0:200mA, 1:400mA, *2:500mA, 3:600mA
|
||||||
|
#define PMU_CHG_CUTOFF 0 // battery charge cutoff
|
||||||
|
// possible values: *0:4.2V, 1:4.3V, 2:4.35V, 3:4.4V
|
||||||
|
|
||||||
// GPS settings
|
// GPS settings
|
||||||
#define HAS_GPS 0 // use on board GPS
|
#define HAS_GPS 0 // use on board GPS
|
||||||
|
24
src/hal/olimexpoeiso.h
Normal file
24
src/hal/olimexpoeiso.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// clang-format off
|
||||||
|
// upload_speed 921600
|
||||||
|
// board esp32-poe-iso
|
||||||
|
|
||||||
|
#ifndef _OLIMEXPOEISO_H
|
||||||
|
#define _OLIMEXPOEISO_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// enable only if you want to store a local paxcount table on the device
|
||||||
|
//#define HAS_SDCARD 2 // this board has a SDMMC card-reader/writer
|
||||||
|
|
||||||
|
// enable only if you want to send paxcount via ethernet port to mqtt server
|
||||||
|
#define HAS_MQTT 1 // use MQTT on ethernet interface
|
||||||
|
|
||||||
|
//#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
||||||
|
//#define BAT_VOLTAGE_DIVIDER 2 // voltage divider 470k/470k on board
|
||||||
|
#define BAT_MEASURE_ADC ADC1_GPIO39_CHANNEL // external power probe GPIO pin
|
||||||
|
#define BAT_VOLTAGE_DIVIDER 2.1277f // voltage divider 47k/442k on board
|
||||||
|
|
||||||
|
#define HAS_BUTTON KEY_BUILTIN // on board button
|
||||||
|
#define HAS_LED NOT_A_PIN // no on board LED
|
||||||
|
|
||||||
|
#endif
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Hardware related definitions for TTGO T-Beam board
|
Hardware related definitions for TTGO T-Beam board
|
||||||
(only) for newer T-Beam version T22_V10
|
for T-Beam versions T22_V10 + T22_V11
|
||||||
pinouts taken from https://github.com/lewisxhe/TTGO-T-Beam
|
pinouts taken from https://github.com/lewisxhe/TTGO-T-Beam
|
||||||
|
|
||||||
/// Button functions: ///
|
/// Button functions: ///
|
||||||
@ -20,7 +20,7 @@ User, long press -> send LORA message
|
|||||||
Reset -> reset device
|
Reset -> reset device
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HAS_DISPLAY 1
|
//#define HAS_DISPLAY 1
|
||||||
#define MY_DISPLAY_SDA SDA
|
#define MY_DISPLAY_SDA SDA
|
||||||
#define MY_DISPLAY_SCL SCL
|
#define MY_DISPLAY_SCL SCL
|
||||||
#define MY_DISPLAY_RST NOT_A_PIN
|
#define MY_DISPLAY_RST NOT_A_PIN
|
||||||
@ -29,11 +29,18 @@ Reset -> reset device
|
|||||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||||
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
|
||||||
#define HAS_BUTTON GPIO_NUM_38 // middle on board button
|
#define HAS_BUTTON GPIO_NUM_38 // middle on board button
|
||||||
#define HAS_PMU 1 // AXP192 power management chip
|
|
||||||
#define PMU_INT GPIO_NUM_35 // AXP192 interrupt
|
|
||||||
|
|
||||||
#define HAS_LED NOT_A_PIN
|
#define HAS_LED NOT_A_PIN
|
||||||
|
|
||||||
|
// power management settings
|
||||||
|
#define HAS_PMU 1 // has AXP192 chip
|
||||||
|
#define PMU_INT GPIO_NUM_35 // battery interrupt
|
||||||
|
#define PMU_CHG_CURRENT AXP1XX_CHARGE_CUR_1000MA // battery charge current
|
||||||
|
// possible values (mA):
|
||||||
|
// 100/190/280/360/450/550/630/700/780/880/960/1000/1080/1160/1240/1320
|
||||||
|
#define PMU_CHG_CUTOFF AXP202_TARGET_VOL_4_2V // battery charge cutoff
|
||||||
|
// possible values (V):
|
||||||
|
// 4_1/4_15/4_2/4_36
|
||||||
|
|
||||||
// GPS settings
|
// GPS settings
|
||||||
#define HAS_GPS 1 // use on board GPS
|
#define HAS_GPS 1 // use on board GPS
|
||||||
#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_34, GPIO_NUM_12 // UBlox NEO 6M
|
#define GPS_SERIAL 9600, SERIAL_8N1, GPIO_NUM_34, GPIO_NUM_12 // UBlox NEO 6M
|
||||||
|
18
src/main.cpp
18
src/main.cpp
@ -29,6 +29,7 @@ Task Core Prio Purpose
|
|||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
ledloop 0 3 blinks LEDs
|
ledloop 0 3 blinks LEDs
|
||||||
spiloop 0 2 reads/writes data on spi interface
|
spiloop 0 2 reads/writes data on spi interface
|
||||||
|
mqttloop 0 2 reads/writes data on ETH interface
|
||||||
IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
||||||
|
|
||||||
lmictask 1 2 MCCI LMiC LORAWAN stack
|
lmictask 1 2 MCCI LMiC LORAWAN stack
|
||||||
@ -185,14 +186,22 @@ void setup() {
|
|||||||
digitalWrite(EXT_POWER_SW, EXT_POWER_ON);
|
digitalWrite(EXT_POWER_SW, EXT_POWER_ON);
|
||||||
strcat_P(features, " VEXT");
|
strcat_P(features, " VEXT");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined HAS_PMU || defined HAS_IP5306
|
||||||
#ifdef HAS_PMU
|
#ifdef HAS_PMU
|
||||||
AXP192_init();
|
AXP192_init();
|
||||||
|
#elif defined HAS_IP5306
|
||||||
|
IP5306_init();
|
||||||
|
#endif
|
||||||
strcat_P(features, " PMU");
|
strcat_P(features, " PMU");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// read (and initialize on first run) runtime settings from NVRAM
|
// read (and initialize on first run) runtime settings from NVRAM
|
||||||
loadConfig(); // includes initialize if necessary
|
loadConfig(); // includes initialize if necessary
|
||||||
|
|
||||||
|
// now that we are powered, we scan i2c bus for devices
|
||||||
|
i2c_scan();
|
||||||
|
|
||||||
// initialize display
|
// initialize display
|
||||||
#ifdef HAS_DISPLAY
|
#ifdef HAS_DISPLAY
|
||||||
strcat_P(features, " OLED");
|
strcat_P(features, " OLED");
|
||||||
@ -201,9 +210,6 @@ void setup() {
|
|||||||
dp_init(RTC_runmode == RUNMODE_POWERCYCLE ? true : false);
|
dp_init(RTC_runmode == RUNMODE_POWERCYCLE ? true : false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// scan i2c bus for devices
|
|
||||||
i2c_scan();
|
|
||||||
|
|
||||||
#ifdef BOARD_HAS_PSRAM
|
#ifdef BOARD_HAS_PSRAM
|
||||||
assert(psramFound());
|
assert(psramFound());
|
||||||
ESP_LOGI(TAG, "PSRAM found and initialized");
|
ESP_LOGI(TAG, "PSRAM found and initialized");
|
||||||
@ -325,6 +331,12 @@ void setup() {
|
|||||||
assert(spi_init() == ESP_OK);
|
assert(spi_init() == ESP_OK);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// initialize MQTT
|
||||||
|
#ifdef HAS_MQTT
|
||||||
|
strcat_P(features, " MQTT");
|
||||||
|
assert(mqtt_init() == ESP_OK);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
if (sdcard_init())
|
if (sdcard_init())
|
||||||
strcat_P(features, " SD");
|
strcat_P(features, " SD");
|
||||||
|
163
src/mqttclient.cpp
Normal file
163
src/mqttclient.cpp
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
#ifdef HAS_MQTT
|
||||||
|
|
||||||
|
#include "mqttclient.h"
|
||||||
|
|
||||||
|
static const char TAG[] = __FILE__;
|
||||||
|
|
||||||
|
QueueHandle_t MQTTSendQueue;
|
||||||
|
TaskHandle_t mqttTask;
|
||||||
|
|
||||||
|
WiFiClient EthClient;
|
||||||
|
PubSubClient mqttClient(EthClient);
|
||||||
|
|
||||||
|
void NetworkEvent(WiFiEvent_t event) {
|
||||||
|
switch (event) {
|
||||||
|
case SYSTEM_EVENT_ETH_START:
|
||||||
|
ESP_LOGI(TAG, "Ethernet link layer started");
|
||||||
|
ETH.setHostname(ETH.macAddress().c_str());
|
||||||
|
break;
|
||||||
|
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||||
|
ESP_LOGI(TAG, "Network link connected");
|
||||||
|
break;
|
||||||
|
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||||
|
ESP_LOGI(TAG, "ETH MAC: %s", ETH.macAddress().c_str());
|
||||||
|
ESP_LOGI(TAG, "IPv4: %s", ETH.localIP().toString().c_str());
|
||||||
|
ESP_LOGI(TAG, "Link Speed: %d Mbps %s", ETH.linkSpeed(),
|
||||||
|
ETH.fullDuplex() ? "full duplex" : "half duplex");
|
||||||
|
mqtt_connect(MQTT_SERVER, MQTT_PORT);
|
||||||
|
break;
|
||||||
|
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||||
|
ESP_LOGI(TAG, "Network link disconnected");
|
||||||
|
break;
|
||||||
|
case SYSTEM_EVENT_ETH_STOP:
|
||||||
|
ESP_LOGI(TAG, "Ethernet link layer stopped");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int mqtt_connect(const char *my_host, const uint16_t my_port) {
|
||||||
|
IPAddress mqtt_server_ip;
|
||||||
|
|
||||||
|
static String clientId = "paxcounter-" + ETH.macAddress();
|
||||||
|
ESP_LOGI(TAG, "MQTT name is %s", clientId.c_str());
|
||||||
|
|
||||||
|
// resolve server
|
||||||
|
if (WiFi.hostByName(my_host, mqtt_server_ip)) {
|
||||||
|
ESP_LOGI(TAG, "Attempting to connect to %s [%s]", my_host,
|
||||||
|
mqtt_server_ip.toString().c_str());
|
||||||
|
} else {
|
||||||
|
ESP_LOGI(TAG, "Could not resolve %s", my_host);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// attempt to connect to MQTT server
|
||||||
|
if (EthClient.connect(mqtt_server_ip, my_port, HOMECYCLE * 2 * 1000)) {
|
||||||
|
mqttClient.setServer(mqtt_server_ip, my_port);
|
||||||
|
mqttClient.setKeepAlive(HOMECYCLE * 2);
|
||||||
|
mqttClient.setCallback(mqtt_callback);
|
||||||
|
|
||||||
|
if (mqttClient.connect(clientId.c_str())) {
|
||||||
|
ESP_LOGI(TAG, "MQTT server connected, subscribing...");
|
||||||
|
mqttClient.publish(MQTT_OUTTOPIC, clientId.c_str());
|
||||||
|
mqttClient.subscribe(MQTT_INTOPIC);
|
||||||
|
ESP_LOGI(TAG, "MQTT topic subscribed");
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "MQTT server not responding, retrying later");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "MQTT server not connected, retrying later");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_client_task(void *param) {
|
||||||
|
|
||||||
|
MessageBuffer_t msg;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
|
||||||
|
// fetch next or wait for payload to send from queue
|
||||||
|
if (xQueueReceive(MQTTSendQueue, &msg, portMAX_DELAY) != pdTRUE) {
|
||||||
|
ESP_LOGE(TAG, "Premature return from xQueueReceive() with no data!");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send data to mqtt server, if we are connected
|
||||||
|
if (mqttClient.connected()) {
|
||||||
|
mqttClient.beginPublish(MQTT_OUTTOPIC, msg.MessageSize + 2, false);
|
||||||
|
mqttClient.write(msg.MessagePort);
|
||||||
|
mqttClient.write('/');
|
||||||
|
mqttClient.write(msg.Message, msg.MessageSize);
|
||||||
|
if (mqttClient.endPublish()) {
|
||||||
|
ESP_LOGI(TAG, "%d byte(s) sent to MQTT", msg.MessageSize + 2);
|
||||||
|
continue; // while(1)
|
||||||
|
} else
|
||||||
|
goto reconnect;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// attempt to reconnect to MQTT server
|
||||||
|
reconnect:
|
||||||
|
mqtt_enqueuedata(&msg); // postpone the undelivered message
|
||||||
|
delay(MQTT_RETRYSEC * 1000);
|
||||||
|
mqtt_connect(MQTT_SERVER, MQTT_PORT);
|
||||||
|
}
|
||||||
|
} // while(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t mqtt_init(void) {
|
||||||
|
assert(SEND_QUEUE_SIZE);
|
||||||
|
MQTTSendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(MessageBuffer_t));
|
||||||
|
if (MQTTSendQueue == 0) {
|
||||||
|
ESP_LOGE(TAG, "Could not create MQTT send queue. Aborting.");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
ESP_LOGI(TAG, "MQTT send queue created, size %d Bytes",
|
||||||
|
SEND_QUEUE_SIZE * PAYLOAD_BUFFER_SIZE);
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Starting MQTTloop...");
|
||||||
|
xTaskCreate(mqtt_client_task, "mqttloop", 4096, (void *)NULL, 2, &mqttTask);
|
||||||
|
|
||||||
|
WiFi.onEvent(NetworkEvent);
|
||||||
|
ETH.begin();
|
||||||
|
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_enqueuedata(MessageBuffer_t *message) {
|
||||||
|
// enqueue message in MQTT send queue
|
||||||
|
BaseType_t ret;
|
||||||
|
MessageBuffer_t DummyBuffer;
|
||||||
|
sendprio_t prio = message->MessagePrio;
|
||||||
|
|
||||||
|
switch (prio) {
|
||||||
|
case prio_high:
|
||||||
|
// clear space in queue if full, then fallthrough to normal
|
||||||
|
if (!uxQueueSpacesAvailable(MQTTSendQueue))
|
||||||
|
xQueueReceive(MQTTSendQueue, &DummyBuffer, (TickType_t)0);
|
||||||
|
case prio_normal:
|
||||||
|
ret = xQueueSendToFront(MQTTSendQueue, (void *)message, (TickType_t)0);
|
||||||
|
break;
|
||||||
|
case prio_low:
|
||||||
|
default:
|
||||||
|
ret = xQueueSendToBack(MQTTSendQueue, (void *)message, (TickType_t)0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret != pdTRUE)
|
||||||
|
ESP_LOGW(TAG, "MQTT sendqueue is full");
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_callback(char *topic, byte *payload, unsigned int length) {
|
||||||
|
String s = "";
|
||||||
|
for (int i = 0; i < length; i++)
|
||||||
|
s += (char)payload[i];
|
||||||
|
ESP_LOGD(TAG, "MQTT: Received %u byte(s) of payload [%s]", length, s);
|
||||||
|
// rcommand(payload, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_queuereset(void) { xQueueReset(MQTTSendQueue); }
|
||||||
|
|
||||||
|
#endif // HAS_MQTT
|
@ -143,6 +143,13 @@ void AXP192_init(void) {
|
|||||||
pmu.clearIRQ();
|
pmu.clearIRQ();
|
||||||
#endif // PMU_INT
|
#endif // PMU_INT
|
||||||
|
|
||||||
|
// set charging parameterss according to user settings if we have (see power.h)
|
||||||
|
#ifdef PMU_CHARGE_CURRENT
|
||||||
|
pmu.setChargeControlCur(PMU_CHARGE_CURRENT);
|
||||||
|
pmu.setChargingTargetVoltage(PMU_CHARGE_CUTOFF);
|
||||||
|
pmu.enableChargeing(true);
|
||||||
|
#endif
|
||||||
|
|
||||||
ESP_LOGI(TAG, "AXP192 PMU initialized");
|
ESP_LOGI(TAG, "AXP192 PMU initialized");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -292,6 +299,20 @@ uint8_t IP5306_GetBatteryLevel(void) {
|
|||||||
return IP5306_LEDS2PCT(state);
|
return IP5306_LEDS2PCT(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IP5306_SetChargerEnabled(uint8_t v) {
|
||||||
|
ip5306_set_bits(IP5306_REG_SYS_0, 4, 1, v); // 0:dis,*1:en
|
||||||
|
}
|
||||||
|
|
||||||
|
void IP5306_SetChargeCutoffVoltage(uint8_t v) {
|
||||||
|
ip5306_set_bits(IP5306_REG_CHG_2, 2, 2,
|
||||||
|
v); //*0:4.2V, 1:4.3V, 2:4.35V, 3:4.4V
|
||||||
|
}
|
||||||
|
|
||||||
|
void IP5306_SetEndChargeCurrentDetection(uint8_t v) {
|
||||||
|
ip5306_set_bits(IP5306_REG_CHG_1, 6, 2,
|
||||||
|
v); // 0:200mA, 1:400mA, *2:500mA, 3:600mA
|
||||||
|
}
|
||||||
|
|
||||||
void printIP5306Stats(void) {
|
void printIP5306Stats(void) {
|
||||||
bool usb = IP5306_GetPowerSource();
|
bool usb = IP5306_GetPowerSource();
|
||||||
bool full = IP5306_GetBatteryFull();
|
bool full = IP5306_GetBatteryFull();
|
||||||
@ -302,4 +323,10 @@ void printIP5306Stats(void) {
|
|||||||
full ? "CHARGED" : (usb ? "CHARGING" : "DISCHARGING"), level);
|
full ? "CHARGED" : (usb ? "CHARGING" : "DISCHARGING"), level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IP5306_init(void) {
|
||||||
|
IP5306_SetChargerEnabled(1);
|
||||||
|
IP5306_SetChargeCutoffVoltage(PMU_CHG_CUTOFF);
|
||||||
|
IP5306_SetEndChargeCurrentDetection(PMU_CHG_CURRENT);
|
||||||
|
}
|
||||||
|
|
||||||
#endif // HAS_IP5306
|
#endif // HAS_IP5306
|
@ -1,25 +1,34 @@
|
|||||||
// routines for writing data to an SD-card, if present
|
// routines for writing data to an SD-card, if present
|
||||||
|
|
||||||
#if (HAS_SDCARD)
|
|
||||||
|
|
||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = __FILE__;
|
static const char TAG[] = __FILE__;
|
||||||
|
|
||||||
#include "sdcard.h"
|
#include "sdcard.h"
|
||||||
|
|
||||||
static bool useSDCard;
|
#ifdef HAS_SDCARD
|
||||||
|
|
||||||
static void createFile(void);
|
static bool useSDCard;
|
||||||
|
|
||||||
File fileSDCard;
|
File fileSDCard;
|
||||||
|
|
||||||
bool sdcard_init() {
|
bool sdcard_init() {
|
||||||
ESP_LOGD(TAG, "looking for SD-card...");
|
ESP_LOGI(TAG, "looking for SD-card...");
|
||||||
|
|
||||||
|
// for usage of SD drivers on ESP32 platform see
|
||||||
|
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdspi_host.html
|
||||||
|
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html
|
||||||
|
|
||||||
|
#if HAS_SDCARD == 1 // use SD SPI host driver
|
||||||
useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK);
|
useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK);
|
||||||
if (useSDCard)
|
#elif HAS_SDCARD == 2 // use SD MMC host driver
|
||||||
|
useSDCard = SD_MMC.begin();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (useSDCard) {
|
||||||
|
ESP_LOGI(TAG, "SD-card found");
|
||||||
createFile();
|
createFile();
|
||||||
else
|
} else
|
||||||
ESP_LOGD(TAG, "SD-card not found");
|
ESP_LOGI(TAG, "SD-card not found");
|
||||||
return useSDCard;
|
return useSDCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,11 +72,23 @@ void createFile(void) {
|
|||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
sprintf(bufferFilename, SDCARD_FILE_NAME, i);
|
sprintf(bufferFilename, SDCARD_FILE_NAME, i);
|
||||||
ESP_LOGD(TAG, "SD: looking for file <%s>", bufferFilename);
|
// ESP_LOGD(TAG, "SD: looking for file <%s>", bufferFilename);
|
||||||
|
|
||||||
|
#if HAS_SDCARD == 1
|
||||||
bool fileExists = SD.exists(bufferFilename);
|
bool fileExists = SD.exists(bufferFilename);
|
||||||
|
#elif HAS_SDCARD == 2
|
||||||
|
bool fileExists = SD_MMC.exists(bufferFilename);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!fileExists) {
|
if (!fileExists) {
|
||||||
ESP_LOGD(TAG, "SD: file does not exist: opening");
|
// ESP_LOGD(TAG, "SD: file does not exist: opening");
|
||||||
|
|
||||||
|
#if HAS_SDCARD == 1
|
||||||
fileSDCard = SD.open(bufferFilename, FILE_WRITE);
|
fileSDCard = SD.open(bufferFilename, FILE_WRITE);
|
||||||
|
#elif HAS_SDCARD == 2
|
||||||
|
fileSDCard = SD_MMC.open(bufferFilename, FILE_WRITE);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (fileSDCard) {
|
if (fileSDCard) {
|
||||||
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
|
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
|
||||||
fileSDCard.print(SDCARD_FILE_HEADER);
|
fileSDCard.print(SDCARD_FILE_HEADER);
|
||||||
|
@ -50,6 +50,9 @@ void SendPayload(uint8_t port, sendprio_t prio) {
|
|||||||
#ifdef HAS_SPI
|
#ifdef HAS_SPI
|
||||||
spi_enqueuedata(&SendBuffer);
|
spi_enqueuedata(&SendBuffer);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_MQTT
|
||||||
|
mqtt_enqueuedata(&SendBuffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
// write data to sdcard, if present
|
// write data to sdcard, if present
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
@ -179,4 +182,7 @@ void flushQueues() {
|
|||||||
#ifdef HAS_SPI
|
#ifdef HAS_SPI
|
||||||
spi_queuereset();
|
spi_queuereset();
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAS_MQTT
|
||||||
|
mqtt_queuereset();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "timekeeper.h"
|
#include "timekeeper.h"
|
||||||
|
|
||||||
|
/*
|
||||||
#if !(HAS_LORA)
|
#if !(HAS_LORA)
|
||||||
#if (TIME_SYNC_LORASERVER)
|
#if (TIME_SYNC_LORASERVER)
|
||||||
#error TIME_SYNC_LORASERVER defined, but device has no LORA configured
|
#error TIME_SYNC_LORASERVER defined, but device has no LORA configured
|
||||||
@ -7,6 +8,7 @@
|
|||||||
#error TIME_SYNC_LORAWAN defined, but device has no LORA configured
|
#error TIME_SYNC_LORAWAN defined, but device has no LORA configured
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
// Local logging tag
|
// Local logging tag
|
||||||
static const char TAG[] = __FILE__;
|
static const char TAG[] = __FILE__;
|
||||||
|
Loading…
Reference in New Issue
Block a user