Merge pull request #666 from cyberman54/development

v2.0.3
This commit is contained in:
Verkehrsrot 2020-10-31 12:29:11 +01:00 committed by GitHub
commit 8e188f3178
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 140 additions and 104 deletions

View File

@ -175,7 +175,7 @@ by pressing the button of the device.
# Sensors and Peripherals
You can add up to 3 user defined sensors. Insert sensor's payload scheme in [*sensor.cpp*](src/sensor.cpp). Bosch BMP180 / BME280 / BME680 environment sensors are supported. Enable flag *lib_deps_sensors* for your board in `platformio.ini` and configure BME in board's hal file before build. If you need Bosch's proprietary BSEC libraray (e.g. to get indoor air quality value from BME680) further enable *build_flags_sensors*, which comes on the price of reduced RAM and increased build size. Furthermore, SDS011, RTC DS3231, generic serial NMEA GPS, I2C LoPy GPS are supported, and to be configured in board's hal file. See [*generic.h*](src/hal/generic.h) for all options and for proper configuration of BME280/BME680.
You can add up to 3 user defined sensors. Insert your sensor's payload scheme in [*sensor.cpp*](src/sensor.cpp). Bosch BMP180 / BME280 / BME680 environment sensors are supported, to activate configure BME in board's hal file before build. If you need Bosch's proprietary BSEC libraray (e.g. to get indoor air quality value from BME680) further enable *build_flags_sensors*, which comes on the price of reduced RAM and increased build size. Furthermore, SDS011, RTC DS3231, generic serial NMEA GPS, I2C LoPy GPS are supported, and to be configured in board's hal file. See [*generic.h*](src/hal/generic.h) for all options and for proper configuration of BME280/BME680.
Output of user sensor data can be switched by user remote control command 0x14 sent to Port 2.

View File

@ -24,7 +24,7 @@
#else
#define OLED_ADDR -1
#endif
#ifndef USW_HW_I2C
#ifndef USE_HW_I2C
#define USE_HW_I2C 1
#endif
#ifndef OLED_FREQUENCY

View File

@ -1,5 +1,6 @@
#ifndef _GLOBALS_H
#define _GLOBALS_H
#endif
// The mother of all embedded development...
#include <Arduino.h>
@ -49,6 +50,16 @@
(xSemaphoreTake(I2Caccess, pdMS_TO_TICKS(DISPLAYREFRESH_MS)) == pdTRUE)
#define I2C_MUTEX_UNLOCK() (xSemaphoreGive(I2Caccess))
// pseudo system halt function, useful to prevent writeloops to NVRAM
#ifndef _ASSERT
#define _ASSERT(cond) \
if ((cond) == 0) { \
ESP_LOGE(TAG, "FAILURE in %s:%d", __FILE__, __LINE__); \
mask_user_IRQ(); \
for (;;) \
; \
}
enum sendprio_t { prio_low, prio_normal, prio_high };
enum timesource_t { _gps, _rtc, _lora, _unsynced };

View File

@ -2,6 +2,7 @@
#define _I2C_H
#include <Arduino.h>
#include <BitBang_I2C.h>
#define SSD1306_PRIMARY_ADDRESS (0x3D)
#define SSD1306_SECONDARY_ADDRESS (0x3C)
@ -22,7 +23,7 @@
void i2c_init(void);
void i2c_deinit(void);
int i2c_scan(void);
void i2c_scan(void);
uint8_t i2c_readBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len);
uint8_t i2c_writeBytes(uint8_t addr, uint8_t reg, uint8_t *data, uint8_t len);

View File

@ -35,6 +35,25 @@
#define SDCARD_SCLK SCK
#endif
// Default config for SDMMC_HOST_DEFAULT (4-bit bus width, slot 1)
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html
#ifndef SDCARD_DATA0
#define SDCARD_DATA0 2
#endif
#ifndef SDCARD_DATA1
#define SDCARD_DATA1 4
#endif
#ifndef SDCARD_DATA2
#define SDCARD_DATA2 12
#endif
#ifndef SDCARD_DATA3
#define SDCARD_DATA3 13
#endif
#define SDCARD_FILE_NAME "/paxcount.%02d"
#define SDCARD_FILE_HEADER "date, time, wifi, bluet"

View File

@ -46,7 +46,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 = 2.0.2
release_version = 2.0.3
; 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
@ -61,7 +61,8 @@ display_library = ; set by build.py and taken from hal file
lib_deps_lora =
mcci-catena/MCCI LoRaWAN LMIC library @ ^3.2.0
lib_deps_display =
bitbank2/OneBitDisplay @ 1.7.2
bitbank2/OneBitDisplay @ 1.9.0
bitbank2/BitBang_I2C @ ^2.1.3
ricmoo/QRCode @ ^0.0.1
bodmer/TFT_eSPI @ ^2.2.20
lib_deps_ledmatrix =

View File

@ -46,7 +46,7 @@ Adafruit_BMP085 bmp; // I2C
void setBMEIRQ() { xTaskNotify(irqHandlerTask, BME_IRQ, eSetBits); }
// initialize BME680 sensor
// initialize MEMS sensor
int bme_init(void) {
// return = 0 -> error / return = 1 -> success

View File

@ -67,7 +67,7 @@ void dp_setup(int contrast) {
MY_DISPLAY_INVERT, USE_HW_I2C, MY_DISPLAY_SDA,
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
obdSetBackBuffer(&ssoled, displaybuf);
@ -281,8 +281,7 @@ void dp_drawPage(time_t t, bool nextpage) {
dp_printf("BLTH:%-5d", macs_ble);
if (cfg.enscount)
dp_printf("(CWA:%d)", cwa_report());
}
else
} else
dp_printf("BLTH:off");
#else
dp_printf("Sniffer disabled");

View File

@ -150,7 +150,7 @@ time_t get_gpstime(void) {
// GPS serial feed FreeRTos Task
void gps_loop(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
_ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
while (1) {

View File

@ -16,7 +16,7 @@
#define CFG_sx1276_radio 1 // HPD13A LoRa SoC
// enable only if you want to store a local paxcount table on the device
#define HAS_SDCARD 1 // this board has an SD-card-reader/writer
#define HAS_SDCARD 2 // // this board has a SDMMC card-reader/writer
#define HAS_DISPLAY 1
#define HAS_LED (25) // green on board LED

View File

@ -5,7 +5,7 @@
// Local logging tag
static const char TAG[] = __FILE__;
void i2c_init(void) { Wire.begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL, 400000); }
void i2c_init(void) { Wire.begin(MY_DISPLAY_SDA, MY_DISPLAY_SCL, 100000); }
void i2c_deinit(void) {
Wire.~TwoWire(); // shutdown/power off I2C hardware
@ -14,73 +14,75 @@ void i2c_deinit(void) {
pinMode(MY_DISPLAY_SCL, INPUT);
}
int i2c_scan(void) {
void i2c_scan(void) {
int i2c_ret, addr;
int devices = 0;
// parts of the code in this function were taken from:
//
// Copyright (c) 2019 BitBank Software, Inc.
// Written by Larry Bank
// email: bitbank@pobox.com
// Project started 25/02/2019
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
BBI2C bbi2c;
const char *szNames[] = {"Unknown","SSD1306","SH1106","VL53L0X","BMP180", "BMP280","BME280",
"MPU-60x0", "MPU-9250", "MCP9808","LSM6DS3", "ADXL345", "ADS1115","MAX44009",
"MAG3110", "CCS811", "HTS221", "LPS25H", "LSM9DS1","LM8330", "DS3231", "LIS3DH",
"LIS3DSH","INA219","SHT3X","HDC1080","MPU6886","BME680", "AXP202", "AXP192", "24AA02XEXX", "DS1307"};
ESP_LOGI(TAG, "Starting I2C bus scan...");
// block i2c bus access
if (I2C_MUTEX_LOCK()) {
// Scan at 100KHz low speed
Wire.setClock(100000);
memset(&bbi2c, 0, sizeof(bbi2c));
bbi2c.bWire = 1; // use wire library, no bitbanging
bbi2c.iSDA = MY_DISPLAY_SDA;
bbi2c.iSCL = MY_DISPLAY_SCL;
I2CInit(&bbi2c, 100000L); // Scan at 100KHz low speed
delay(100); // allow devices to power up
for (addr = 8; addr <= 119; addr++) {
uint8_t map[16];
uint8_t i;
int iDevice, iCount;
Wire.beginTransmission(addr);
Wire.write(addr);
i2c_ret = Wire.endTransmission();
if (i2c_ret == 0) {
devices++;
switch (addr) {
case SSD1306_PRIMARY_ADDRESS:
case SSD1306_SECONDARY_ADDRESS:
ESP_LOGI(TAG, "0x%X: SSD1306 Display controller", addr);
break;
case BME_PRIMARY_ADDRESS:
case BME_SECONDARY_ADDRESS:
ESP_LOGI(TAG, "0x%X: Bosch BME MEMS", addr);
break;
case AXP192_PRIMARY_ADDRESS:
ESP_LOGI(TAG, "0x%X: AXP192 power management", addr);
break;
case IP5306_PRIMARY_ADDRESS:
ESP_LOGI(TAG, "0x%X: IP5306 power management", addr);
break;
case QUECTEL_GPS_PRIMARY_ADDRESS:
ESP_LOGI(TAG, "0x%X: Quectel GPS", addr);
break;
case MCP_24AA02E64_PRIMARY_ADDRESS:
ESP_LOGI(TAG, "0x%X: 24AA02E64 serial EEPROM", addr);
break;
default:
ESP_LOGI(TAG, "0x%X: Unknown device", addr);
break;
I2CScan(&bbi2c, map); // get bitmap of connected I2C devices
if (map[0] == 0xfe) // something is wrong with the I2C bus
{
ESP_LOGI(TAG, "I2C pins are not correct or the bus is being pulled low "
"by a bad device; unable to run scan");
} else {
iCount = 0;
for (i = 1; i < 128; i++) // skip address 0 (general call address) since
// more than 1 device can respond
{
if (map[i >> 3] & (1 << (i & 7))) // device found
{
iCount++;
iDevice = I2CDiscoverDevice(&bbi2c, i);
ESP_LOGI(TAG, "Device found at 0x%X, type = %s", i,
szNames[iDevice]); // show the device name as a string
}
} // for i
ESP_LOGI(TAG, "%u I2C device(s) found", iCount);
}
} // switch
} // for loop
ESP_LOGI(TAG, "I2C scan done, %u devices found.", devices);
// Set back to 400KHz
Wire.setClock(400000);
I2C_MUTEX_UNLOCK(); // release i2c bus access
} else
ESP_LOGE(TAG, "I2c bus busy - scan error");
return devices;
ESP_LOGE(TAG, "I2C bus busy - scan error");
}
// mutexed functions for i2c r/w access

View File

@ -6,7 +6,7 @@ static const char TAG[] = __FILE__;
// irq handler task, handles all our application level interrupts
void irqHandler(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
_ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
uint32_t InterruptStatus;

View File

@ -22,8 +22,7 @@
#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
// avoid lmic warning if we don't configure radio in case we haven't one
#if !(defined(CFG_sx1272_radio) || defined(CFG_sx1276_radio))
#define CFG_sx1276_radio 1
#endif

View File

@ -227,7 +227,7 @@ void showLoraKeys(void) {
// LMIC send task
void lora_send(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
_ASSERT((uint32_t)pvParameters == 1); // FreeRTOS check
MessageBuffer_t SendBuffer;
@ -292,7 +292,7 @@ void lora_stack_reset() {
}
esp_err_t lora_stack_init(bool do_join) {
assert(SEND_QUEUE_SIZE);
_ASSERT(SEND_QUEUE_SIZE > 0);
LoraSendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(MessageBuffer_t));
if (LoraSendQueue == 0) {
ESP_LOGE(TAG, "Could not create LORA send queue. Aborting.");
@ -382,7 +382,7 @@ void lora_queuereset(void) { xQueueReset(LoraSendQueue); }
// LMIC lorawan stack task
void lmictask(void *pvParameters) {
configASSERT(((uint32_t)pvParameters) == 1);
_ASSERT((uint32_t)pvParameters == 1);
// setup LMIC stack
os_init_ex(&myPinmap); // initialize lmic run-time environment

View File

@ -118,7 +118,7 @@ void setup() {
// create some semaphores for syncing / mutexing tasks
I2Caccess = xSemaphoreCreateMutex(); // for access management of i2c bus
assert(I2Caccess != NULL);
_ASSERT(I2Caccess != NULL);
I2C_MUTEX_UNLOCK();
// disable brownout detection
@ -203,7 +203,7 @@ void setup() {
#endif
// read (and initialize on first run) runtime settings from NVRAM
assert(loadConfig()); // includes initialize if necessary
_ASSERT(loadConfig()); // includes initialize if necessary
// now that we are powered, we scan i2c bus for devices
i2c_scan();
@ -217,7 +217,7 @@ void setup() {
#endif
#ifdef BOARD_HAS_PSRAM
assert(psramFound());
_ASSERT(psramFound());
ESP_LOGI(TAG, "PSRAM found and initialized");
strcat_P(features, " PSRAM");
#endif
@ -343,20 +343,20 @@ void setup() {
#if (HAS_LORA)
strcat_P(features, " LORA");
// kick off join, except we come from sleep
assert(lora_stack_init(RTC_runmode == RUNMODE_WAKEUP ? false : true) ==
_ASSERT(lora_stack_init(RTC_runmode == RUNMODE_WAKEUP ? false : true) ==
ESP_OK);
#endif
// initialize SPI
#ifdef HAS_SPI
strcat_P(features, " SPI");
assert(spi_init() == ESP_OK);
_ASSERT(spi_init() == ESP_OK);
#endif
// initialize MQTT
#ifdef HAS_MQTT
strcat_P(features, " MQTT");
assert(mqtt_init() == ESP_OK);
_ASSERT(mqtt_init() == ESP_OK);
#endif
#if (HAS_SDCARD)
@ -395,7 +395,7 @@ void setup() {
// initialize RTC
#ifdef HAS_RTC
strcat_P(features, " RTC");
assert(rtc_init());
_ASSERT(rtc_init());
#endif
#if defined HAS_DCF77
@ -446,11 +446,13 @@ void setup() {
strcat_P(features, " BMP180");
#endif
if (bme_init())
ESP_LOGI(TAG, "Starting BME sensor...");
ESP_LOGI(TAG, "BME sensor initialized");
else
ESP_LOGE(TAG, "BME sensor could not be initialized");
#endif
// starting timers and interrupts
assert(irqHandlerTask != NULL); // has interrupt handler task started?
_ASSERT(irqHandlerTask != NULL); // has interrupt handler task started?
ESP_LOGI(TAG, "Starting Timers...");
// display interrupt
@ -505,7 +507,7 @@ void setup() {
#endif
ESP_LOGI(TAG, "Starting Timekeeper...");
assert(timepulse_init()); // setup pps timepulse
_ASSERT(timepulse_init()); // setup pps timepulse
timepulse_start(); // starts pps and cyclic time sync
#endif // TIME_SYNC_INTERVAL

View File

@ -23,7 +23,7 @@ esp_err_t mqtt_init(void) {
mqttClient.begin(MQTT_SERVER, MQTT_PORT, netClient);
mqttClient.onMessageAdvanced(mqtt_callback);
assert(SEND_QUEUE_SIZE);
_ASSERT(SEND_QUEUE_SIZE > 0);
MQTTSendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(MessageBuffer_t));
if (MQTTSendQueue == 0) {
ESP_LOGE(TAG, "Could not create MQTT send queue. Aborting.");

View File

@ -22,11 +22,12 @@ bool sdcard_init() {
#if HAS_SDCARD == 1 // use SD SPI host driver
useSDCard = SD.begin(SDCARD_CS, SDCARD_MOSI, SDCARD_MISO, SDCARD_SCLK);
//SPI.begin(SDCARD_SCLK, SDCARD_MSO, SDCARD_MOSI, SDCARD_CS);
//delay(10);
//useSDCard = SD.begin(SDCARD_CS, SPI, 40000000, "/sd");
#elif HAS_SDCARD == 2 // use SD MMC host driver
// enable internal pullups of sd-data lines
gpio_set_pull_mode(gpio_num_t(SDCARD_DATA0), GPIO_PULLUP_ONLY);
gpio_set_pull_mode(gpio_num_t(SDCARD_DATA1), GPIO_PULLUP_ONLY);
gpio_set_pull_mode(gpio_num_t(SDCARD_DATA2), GPIO_PULLUP_ONLY);
gpio_set_pull_mode(gpio_num_t(SDCARD_DATA3), GPIO_PULLUP_ONLY);
useSDCard = SD_MMC.begin();
#endif
@ -38,7 +39,8 @@ bool sdcard_init() {
return useSDCard;
}
void sdcardWriteData(uint16_t noWifi, uint16_t noBle, __attribute__((unused)) uint16_t noBleCWA) {
void sdcardWriteData(uint16_t noWifi, uint16_t noBle,
__attribute__((unused)) uint16_t noBleCWA) {
static int counterWrites = 0;
char tempBuffer[12 + 1];
time_t t = now();

View File

@ -104,7 +104,7 @@ void spi_slave_task(void *param) {
}
esp_err_t spi_init() {
assert(SEND_QUEUE_SIZE);
_ASSERT(SEND_QUEUE_SIZE > 0);
SPISendQueue = xQueueCreate(SEND_QUEUE_SIZE, sizeof(MessageBuffer_t));
if (SPISendQueue == 0) {
ESP_LOGE(TAG, "Could not create SPI send queue. Aborting.");

View File

@ -245,7 +245,7 @@ void clock_init(void) {
&ClockTask, // task handle
1); // CPU core
assert(ClockTask); // has clock task started?
_ASSERT(ClockTask != NULL); // has clock task started?
} // clock_init
void clock_loop(void *taskparameter) { // ClockTask

View File

@ -45,7 +45,7 @@ IRAM_ATTR void wifi_sniffer_packet_handler(void *buff,
// Software-timer driven Wifi channel rotation callback function
void switchWifiChannel(TimerHandle_t xTimer) {
configASSERT(xTimer);
_ASSERT(xTimer != NULL);
channel =
(channel % WIFI_CHANNEL_MAX) + 1; // rotate channel 1..WIFI_CHANNEL_MAX
esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
@ -82,7 +82,7 @@ void wifi_sniffer_init(void) {
}
void switch_wifi_sniffer(uint8_t state) {
assert(WifiChanTimer);
_ASSERT(WifiChanTimer != NULL);
if (state) {
// switch wifi sniffer on
ESP_ERROR_CHECK(esp_wifi_start());