Merge pull request #861 from cyberman54/development

Development
This commit is contained in:
Verkehrsrot 2022-03-04 18:20:12 +01:00 committed by GitHub
commit 828d0172a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 311 additions and 170 deletions

View File

@ -74,12 +74,6 @@ board = env.BoardConfig(myboard)
board.manifest['build']['partitions'] = mypartitiontable board.manifest['build']['partitions'] = mypartitiontable
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:

View File

@ -1,6 +1,8 @@
#ifndef _BMESENSOR_H #ifndef _BMESENSOR_H
#define _BMESENSOR_H #define _BMESENSOR_H
#if (HAS_BME)
#include <Wire.h> #include <Wire.h>
#include "globals.h" #include "globals.h"
@ -54,3 +56,5 @@ void loadState(void);
void updateState(void); void updateState(void);
#endif #endif
#endif

View File

@ -1,6 +1,8 @@
#ifndef _DCF77_H #ifndef _DCF77_H
#define _DCF77_H #define _DCF77_H
#ifdef HAS_DCF77
#include "globals.h" #include "globals.h"
#include "timekeeper.h" #include "timekeeper.h"
@ -16,3 +18,5 @@ void DCF77_Pulse(uint8_t bit);
uint64_t DCF77_Frame(const struct tm t); uint64_t DCF77_Frame(const struct tm t);
#endif #endif
#endif

View File

@ -1,6 +1,8 @@
#ifndef _GPSREAD_H #ifndef _GPSREAD_H
#define _GPSREAD_H #define _GPSREAD_H
#if (HAS_GPS)
#include <TinyGPS++.h> // library for parsing NMEA data #include <TinyGPS++.h> // library for parsing NMEA data
#include <RtcDateTime.h> #include <RtcDateTime.h>
#include "timekeeper.h" #include "timekeeper.h"
@ -20,3 +22,5 @@ void gps_loop(void *pvParameters);
time_t get_gpstime(uint16_t *msec); time_t get_gpstime(uint16_t *msec);
#endif #endif
#endif

View File

@ -4,6 +4,6 @@
#include <Arduino.h> #include <Arduino.h>
#include <RokkitHash.h> #include <RokkitHash.h>
uint32_t IRAM_ATTR myhash(const char *data, int len); uint32_t myhash(const char *data, int len);
#endif #endif

View File

@ -1,6 +1,8 @@
#ifndef _IF482_H #ifndef _IF482_H
#define _IF482_H #define _IF482_H
#ifdef HAS_IF482
#include "globals.h" #include "globals.h"
#include "timekeeper.h" #include "timekeeper.h"
#include "esp_sntp.h" #include "esp_sntp.h"
@ -11,3 +13,5 @@
String IF482_Frame(time_t t); String IF482_Frame(time_t t);
#endif #endif
#endif

View File

@ -1,6 +1,8 @@
#ifndef _MATRIX_DISPLAY_H #ifndef _MATRIX_DISPLAY_H
#define _MATRIX_DISPLAY_H #define _MATRIX_DISPLAY_H
#ifdef HAS_MATRIX_DISPLAY
#include "LEDMatrix.h" #include "LEDMatrix.h"
#include "ledmatrixfonts.h" #include "ledmatrixfonts.h"
#include "ledmatrixdisplay.h" #include "ledmatrixdisplay.h"
@ -17,3 +19,5 @@ uint8_t GetCharWidth(char cChar);
void ScrollMatrixLeft(uint8_t *buf, const uint16_t cols, const uint16_t rows); void ScrollMatrixLeft(uint8_t *buf, const uint16_t cols, const uint16_t rows);
#endif #endif
#endif

View File

@ -38,10 +38,10 @@ void lora_send(void *pvParameters);
void lora_enqueuedata(MessageBuffer_t *message); void lora_enqueuedata(MessageBuffer_t *message);
void lora_queuereset(void); void lora_queuereset(void);
uint32_t lora_queuewaiting(void); uint32_t lora_queuewaiting(void);
void IRAM_ATTR myEventCallback(void *pUserData, ev_t ev); void myEventCallback(void *pUserData, ev_t ev);
void IRAM_ATTR myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg, void myRxCallback(void *pUserData, uint8_t port, const uint8_t *pMsg,
size_t nMsg); size_t nMsg);
void IRAM_ATTR myTxCallback(void *pUserData, int fSuccess); void myTxCallback(void *pUserData, int fSuccess);
const char *getSfName(rps_t rps); const char *getSfName(rps_t rps);
const char *getBwName(rps_t rps); const char *getBwName(rps_t rps);
const char *getCrName(rps_t rps); const char *getCrName(rps_t rps);

View File

@ -1,6 +1,8 @@
#ifndef _MQTTCLIENT_H #ifndef _MQTTCLIENT_H
#define _MQTTCLIENT_H #define _MQTTCLIENT_H
#ifdef HAS_MQTT
#include "globals.h" #include "globals.h"
#include "rcommand.h" #include "rcommand.h"
#include "hash.h" #include "hash.h"
@ -24,4 +26,6 @@ void NetworkEvent(WiFiEvent_t event);
esp_err_t mqtt_init(void); esp_err_t mqtt_init(void);
void mqtt_deinit(void); void mqtt_deinit(void);
#endif
#endif // _MQTTCLIENT_H #endif // _MQTTCLIENT_H

View File

@ -3,7 +3,6 @@
#include <Arduino.h> #include <Arduino.h>
#include <esp_adc_cal.h> #include <esp_adc_cal.h>
//include <esp32-hal-adc.h>
#include <soc/adc_channel.h> #include <soc/adc_channel.h>
#include "i2c.h" #include "i2c.h"
@ -56,7 +55,6 @@ void calibrate_voltage(void);
bool batt_sufficient(void); bool batt_sufficient(void);
#ifdef HAS_PMU #ifdef HAS_PMU
#include <axp20x.h> #include <axp20x.h>
extern AXP20X_Class pmu; extern AXP20X_Class pmu;
enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep }; enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep };
@ -64,7 +62,6 @@ void AXP192_powerevent_IRQ(void);
void AXP192_power(pmu_power_t powerlevel); void AXP192_power(pmu_power_t powerlevel);
void AXP192_init(void); void AXP192_init(void);
void AXP192_showstatus(void); void AXP192_showstatus(void);
#endif // HAS_PMU #endif // HAS_PMU
#ifdef HAS_IP5306 #ifdef HAS_IP5306

View File

@ -34,7 +34,7 @@ typedef struct {
uint8_t cmdLen; uint8_t cmdLen;
} RcmdBuffer_t; } RcmdBuffer_t;
void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength); void rcommand(const uint8_t *cmd, const size_t cmdlength);
void rcmd_queuereset(void); void rcmd_queuereset(void);
uint32_t rcmd_queuewaiting(void); uint32_t rcmd_queuewaiting(void);
void rcmd_deinit(void); void rcmd_deinit(void);

View File

@ -1,6 +1,8 @@
#ifndef _RTCTIME_H #ifndef _RTCTIME_H
#define _RTCTIME_H #define _RTCTIME_H
#ifdef HAS_RTC
#include <Wire.h> // must be included here so that Arduino library object file references work #include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h> #include <RtcDS3231.h>
@ -15,4 +17,6 @@ void sync_rtctime(void);
time_t get_rtctime(uint16_t *msec); time_t get_rtctime(uint16_t *msec);
float get_rtctemp(void); float get_rtctemp(void);
#endif
#endif // _RTCTIME_H #endif // _RTCTIME_H

View File

@ -1,23 +1,18 @@
#ifndef _SDCARD_H #ifndef _SDCARD_H
#define _SDCARD_H #define _SDCARD_H
#if (HAS_SDCARD)
#include "globals.h" #include "globals.h"
#include <stdio.h> #include <stdio.h>
#include <SPI.h> #include <SPI.h>
#include "esp_vfs_fat.h"
#include "sdmmc_cmd.h"
#if (HAS_SDCARD) #define MOUNT_POINT "/sdcard"
#if HAS_SDCARD == 1
#include <SD.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 #if HAS_SDCARD == 1 // SPI interface
#include "sds011read.h" #include "driver/sdspi_host.h"
#endif
#ifndef SDCARD_CS #ifndef SDCARD_CS
#define SDCARD_CS SS #define SDCARD_CS SS
@ -35,23 +30,23 @@
#define SDCARD_SCLK SCK #define SDCARD_SCLK SCK
#endif #endif
// Default config for SDMMC_HOST_DEFAULT (4-bit bus width, slot 1) #elif HAS_SDCARD == 2 // MMC interface
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html #include "driver/sdmmc_host.h"
#ifndef SDCARD_DATA0 #ifndef SDCARD_SLOTWIDTH
#define SDCARD_DATA0 2 #define SDCARD_SLOTWIDTH 1
#endif #endif
#ifndef SDCARD_DATA1 #ifndef SDCARD_PULLUP
#define SDCARD_DATA1 4 #define SDCARD_PULLUP SDMMC_SLOT_FLAG_INTERNAL_PULLUP
#endif #endif
#ifndef SDCARD_DATA2 #else
#define SDCARD_DATA2 12 #error HAS_SDCARD unknown card reader value, must be either 1 or 2
#endif #endif
#ifndef SDCARD_DATA3 #ifdef HAS_SDS011
#define SDCARD_DATA3 13 #include "sds011read.h"
#endif #endif
#define SDCARD_FILE_NAME clientId #define SDCARD_FILE_NAME clientId
@ -62,7 +57,10 @@
#endif #endif
bool sdcard_init(bool create = true); bool sdcard_init(bool create = true);
void sdcard_flush(void);
void sdcard_close(void); void sdcard_close(void);
void sdcardWriteData(uint16_t, uint16_t, uint16_t = 0); void sdcardWriteData(uint16_t, uint16_t, uint16_t = 0);
#endif
#endif // _SDCARD_H #endif // _SDCARD_H

View File

@ -1,10 +1,12 @@
#ifndef _SDS011READ_H #ifndef _SDS011READ_H
#define _SDS011READ_H #define _SDS011READ_H
#if (HAS_SDS011)
#include <SdsDustSensor.h> #include <SdsDustSensor.h>
#include "globals.h" #include "globals.h"
#define SDCARD_FILE_HEADER_SDS011 ", PM10,PM25" #define SDCARD_FILE_HEADER_SDS011 ", PM10,PM25"
// use original pins from HardwareSerial if none defined // use original pins from HardwareSerial if none defined
#ifndef SDS_TX #ifndef SDS_TX
@ -21,4 +23,7 @@ void sds011_loop();
void sds011_sleep(void); void sds011_sleep(void);
void sds011_wakeup(void); void sds011_wakeup(void);
void sds011_store(sdsStatus_t *sds_store); void sds011_store(sdsStatus_t *sds_store);
#endif
#endif // _SDS011READ_H #endif // _SDS011READ_H

View File

@ -24,6 +24,8 @@ licenses. Refer to LICENSE.txt file in repository for more details.
#ifndef _SPISLAVE_H #ifndef _SPISLAVE_H
#define _SPISLAVE_H #define _SPISLAVE_H
#ifdef HAS_SPI
#include "globals.h" #include "globals.h"
#include "rcommand.h" #include "rcommand.h"
@ -35,4 +37,6 @@ void spi_enqueuedata(MessageBuffer_t *message);
uint32_t spi_queuewaiting(void); uint32_t spi_queuewaiting(void);
void spi_queuereset(void); void spi_queuereset(void);
#endif
#endif // _SPISLAVE_H #endif // _SPISLAVE_H

View File

@ -34,7 +34,7 @@ void setTimeSyncIRQ(void);
uint8_t timepulse_init(void); uint8_t timepulse_init(void);
bool timeIsValid(time_t const t); bool timeIsValid(time_t const t);
void calibrateTime(void); void calibrateTime(void);
bool IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, bool setMyTime(uint32_t t_sec, uint16_t t_msec,
timesource_t mytimesource); timesource_t mytimesource);
time_t compileTime(void); time_t compileTime(void);
time_t mkgmtime(const struct tm *ptm); time_t mkgmtime(const struct tm *ptm);

View File

@ -21,7 +21,7 @@ enum timesync_t {
void timesync_init(void); void timesync_init(void);
void timesync_request(void); void timesync_request(void);
void timesync_store(uint32_t timestamp, timesync_t timestamp_type); void timesync_store(uint32_t timestamp, timesync_t timestamp_type);
void IRAM_ATTR timesync_processReq(void *taskparameter); void timesync_processReq(void *taskparameter);
void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag); void timesync_serverAnswer(void *pUserData, int flag);
#endif #endif

View File

@ -1,10 +1,8 @@
; PlatformIO Project Configuration File ; ---> SELECT ONE TARGET BOARD FROM FOLLOWING ROWS <---
;
; Note: For "LILYGO TTGO ESP32-Paxcounter LoRa32 V2.1 1.6.1" select board ttgov21new.h
;
; ;
; Please visit documentation for the other options and examples
; http://docs.platformio.org/page/projectconf.html
; ---> SELECT THE TARGET PLATFORM HERE! <---
[board] [board]
;halfile = generic.h ;halfile = generic.h
;halfile = ebox.h ;halfile = ebox.h
@ -100,8 +98,6 @@ build_flags_basic =
'-DCORE_DEBUG_LEVEL=${common.debug_level}' '-DCORE_DEBUG_LEVEL=${common.debug_level}'
'-DLOG_LOCAL_LEVEL=${common.debug_level}' '-DLOG_LOCAL_LEVEL=${common.debug_level}'
'-DPROGVERSION="${common.release_version}"' '-DPROGVERSION="${common.release_version}"'
'-Wno-unknown-pragmas'
'-Wno-unused-variable'
'-D LIBPAX_WIFI' '-D LIBPAX_WIFI'
'-D LIBPAX_BLE' '-D LIBPAX_BLE'
'-D LIBPAX_ARDUINO' '-D LIBPAX_ARDUINO'
@ -113,6 +109,7 @@ build_flags_all =
framework = arduino framework = arduino
board = esp32dev board = esp32dev
board_build.partitions = min_spiffs.csv board_build.partitions = min_spiffs.csv
build_type = release
upload_speed = ${common.upload_speed} upload_speed = ${common.upload_speed}
;upload_port = COM12 ;upload_port = COM12
platform = ${common.platform_espressif32} platform = ${common.platform_espressif32}

View File

@ -5,7 +5,7 @@
#include <Arduino.h> #include <Arduino.h>
// Local logging tag // Local logging tag
static const char TAG[] = "wifi"; static const char TAG[] = __FILE__;
typedef enum { ANTENNA_INT = 0, ANTENNA_EXT } antenna_type_t; typedef enum { ANTENNA_INT = 0, ANTENNA_EXT } antenna_type_t;

View File

@ -126,6 +126,10 @@ void doHousekeeping() {
} }
#endif #endif
#if (HAS_SDCARD)
sdcard_flush();
#endif
} // doHousekeeping() } // doHousekeeping()
uint32_t getFreeRAM() { uint32_t getFreeRAM() {

View File

@ -9,14 +9,15 @@
/* Hardware related definitions for TTGO V2.1 Board /* Hardware related definitions for TTGO V2.1 Board
// ATTENTION: check your board version! // ATTENTION: check your board version!
// This settings are for boards labeled v1.6 on pcb, NOT for v1.5 or older // This settings are for boards labeled v1.6 or v1.6.1 on pcb, NOT for v1.5 or older
*/ */
#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
// enable only if you want to store a local paxcount table on the device // 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 #define HAS_SDCARD 2 // this board has a SD MMC card-reader/writer
#define SDCARD_SLOTWIDTH 4 // 4-line interface
#define HAS_DISPLAY 1 #define HAS_DISPLAY 1
#define HAS_LED (25) // green on board LED #define HAS_LED (25) // green on board LED

View File

@ -40,6 +40,6 @@
#undef ROKKIT_ENABLE_8BIT_OPTIMIZATIONS #undef ROKKIT_ENABLE_8BIT_OPTIMIZATIONS
#endif #endif
uint32_t IRAM_ATTR myhash(const char *data, int len) { uint32_t myhash(const char *data, int len) {
return rokkit(data, len); return rokkit(data, len);
} }

View File

@ -53,7 +53,7 @@ void i2c_scan(void) {
if (I2C_MUTEX_LOCK()) { if (I2C_MUTEX_LOCK()) {
memset(&bbi2c, 0, sizeof(bbi2c)); memset(&bbi2c, 0, sizeof(bbi2c));
bbi2c.bWire = 1; // use wire library, no bitbanging bbi2c.bWire = 0;
bbi2c.iSDA = MY_DISPLAY_SDA; bbi2c.iSDA = MY_DISPLAY_SDA;
bbi2c.iSCL = MY_DISPLAY_SCL; bbi2c.iSCL = MY_DISPLAY_SCL;
I2CInit(&bbi2c, 100000L); // Scan at 100KHz low speed I2CInit(&bbi2c, 100000L); // Scan at 100KHz low speed

View File

@ -4,7 +4,7 @@
#include "lorawan.h" #include "lorawan.h"
// Local logging Tag // Local logging Tag
static const char TAG[] = "lora"; static const char TAG[] = __FILE__;
#if CLOCK_ERROR_PROCENTAGE > 7 #if CLOCK_ERROR_PROCENTAGE > 7
#warning CLOCK_ERROR_PROCENTAGE value in lmic_config.h is too high; values > 7 will cause side effects #warning CLOCK_ERROR_PROCENTAGE value in lmic_config.h is too high; values > 7 will cause side effects

View File

@ -84,8 +84,7 @@ void set_sendcycle(uint8_t val[]) {
void set_sleepcycle(uint8_t val[]) { void set_sleepcycle(uint8_t val[]) {
// swap byte order from msb to lsb, note: this is a platform dependent hack // swap byte order from msb to lsb, note: this is a platform dependent hack
uint16_t t = __builtin_bswap16(*(uint16_t *)(val)); cfg.sleepcycle = __builtin_bswap16(*(uint16_t *)(val));
cfg.sleepcycle = t;
ESP_LOGI(TAG, "Remote command: set sleep cycle to %d seconds", ESP_LOGI(TAG, "Remote command: set sleep cycle to %d seconds",
cfg.sleepcycle * 10); cfg.sleepcycle * 10);
} }
@ -485,7 +484,7 @@ void rcmd_process(void *pvParameters) {
} // rcmd_process() } // rcmd_process()
// enqueue remote command // enqueue remote command
void IRAM_ATTR rcommand(const uint8_t *cmd, const size_t cmdlength) { void rcommand(const uint8_t *cmd, const size_t cmdlength) {
RcmdBuffer_t rcmd = {0}; RcmdBuffer_t rcmd = {0};

View File

@ -1,10 +1,10 @@
#ifdef HAS_RTC // we have hardware RTC
#include "rtctime.h" #include "rtctime.h"
// Local logging tag // Local logging tag
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
#ifdef HAS_RTC // we have hardware RTC
RtcDS3231<TwoWire> Rtc(Wire); // RTC hardware i2c interface RtcDS3231<TwoWire> Rtc(Wire); // RTC hardware i2c interface
// initialize RTC // initialize RTC

View File

@ -1,156 +1,267 @@
#ifdef HAS_SDCARD
// routines for writing data to an SD-card, if present // routines for writing data to an SD-card, if present
// use FAT32 formatted card // use FAT32 formatted card
// check whether your card reader supports SPI oder SDMMC and select appropriate // check whether your card reader supports SPI oder SDMMC and select appropriate
// SD low level driver in board hal file // SD interface in board hal file
// Local logging tag // Local logging tag
static const char TAG[] = __FILE__; static const char TAG[] = __FILE__;
#include "sdcard.h" #include "sdcard.h"
#ifdef HAS_SDCARD sdmmc_card_t *card;
static bool useSDCard; const char mount_point[] = MOUNT_POINT;
static void openFile(void); static bool useSDCard = false;
File fileSDCard; // This file stream will be used for payload logging
static FILE *data_file;
// This file stream will be used for system logging
#if HAS_SDCARD == 1 #ifdef SD_LOGGING
SPIClass sd_spi; static FILE *log_file;
// Save UART stdout stream
static FILE *uart_stdout = stdout;
// This function will be called by the ESP log library every time ESP_LOG needs
// to be performed.
// @important Do NOT use the ESP_LOG* macro's in this function ELSE
// recursive loop and stack overflow! So use printf() instead for debug
// messages.
// CURRENTLY NOT WORKING DUE TO AN ISSUE IN ARDUINO-ESP32
int print_to_sd_card(const char *fmt, va_list args) {
static bool static_fatal_error = false;
static const uint32_t WRITE_CACHE_CYCLE = 5;
static uint32_t counter_write = 0;
int iresult;
// #1 Write to file
if (log_file == NULL) {
printf("%s() ABORT. file handle log_file is NULL\n", __FUNCTION__);
return -1;
}
if (static_fatal_error == false) {
iresult = vfprintf(log_file, fmt, args);
if (iresult < 0) {
printf("%s() ABORT. failed vfprintf() -> logging disabled \n",
__FUNCTION__);
// MARK FATAL
static_fatal_error = true;
return iresult;
}
// #2 Smart commit after x writes
counter_write++;
if (counter_write % WRITE_CACHE_CYCLE == 0) {
printf("%s() fsync'ing log file (WRITE_CACHE_CYCLE=%u)\n",
WRITE_CACHE_CYCLE);
fsync(fileno(log_file));
}
}
// #3 ALWAYS Write to stdout!
return vprintf(fmt, args);
}
#endif #endif
bool openFile(FILE **fd, const char *filename) {
char _filename[50];
sprintf(_filename, "%s%s", MOUNT_POINT, filename);
if ((*fd = fopen(_filename, "a")) == NULL) {
ESP_LOGE(TAG, "file <%s> open error", _filename);
return false;
} else {
ESP_LOGI(TAG, "file <%s> opened", _filename);
return true;
}
} // openfile
bool sdcard_init(bool create) { bool sdcard_init(bool create) {
esp_err_t ret;
// for usage of SD drivers on ESP32 platform see // 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/sdspi_host.html
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html // https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdmmc_host.html
ESP_LOGI(TAG, "looking for SD-card..."); // Options for mounting the filesystem.
#if HAS_SDCARD == 1 // use SD SPI host driver // If format_if_mount_failed is set to true, SD card will be partitioned and
digitalWrite(SDCARD_CS, HIGH); // formatted in case when mounting fails.
sd_spi.begin(SDCARD_SCLK, SDCARD_MISO, SDCARD_MOSI, SDCARD_CS); esp_vfs_fat_mount_config_t mount_config = {.format_if_mount_failed = false,
digitalWrite(SDCARD_CS, LOW); .max_files = 5};
useSDCard = SD.begin(SDCARD_CS, sd_spi);
#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
if (useSDCard) { ESP_LOGI(TAG, "looking for SD-card...");
ESP_LOGI(TAG, "SD-card found");
openFile(); #if (HAS_SDCARD == 1) // use SD interface in SPI host mode
return true;
} else { sdmmc_host_t host = SDSPI_HOST_DEFAULT();
ESP_LOGI(TAG, "SD-card not found");
spi_bus_config_t bus_cfg = {
.mosi_io_num = (gpio_num_t)SDCARD_MOSI,
.miso_io_num = (gpio_num_t)SDCARD_MISO,
.sclk_io_num = (gpio_num_t)SDCARD_SCLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 4000,
};
// This initializes the slot without card detect (CD) and write protect (WP)
// signals. Modify slot_config.gpio_cd and slot_config.gpio_wp if you want
// to use these signals (if your board has them)
sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
slot_config.gpio_cs = (gpio_num_t)SDCARD_CS;
ret = spi_bus_initialize(SPI_HOST, &bus_cfg, 1);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "failed to initialize SPI bus");
return false; return false;
} }
// Use settings defined above to initialize SD card and mount FAT filesystem.
ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config,
&card);
#elif (HAS_SDCARD == 2) // use SD interface in MMC host mode
sdmmc_host_t host = SDMMC_HOST_DEFAULT();
// This initializes the slot without card detect (CD) and write protect (WP)
// signals. Modify slot_config.gpio_cd and slot_config.gpio_wp if your board
// has these signals.
// 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
sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT();
// Set 1-line or 4-line SD mode (default is 1-line)
slot_config.width = SDCARD_SLOTWIDTH;
// Enable internal pullups on enabled pins. The internal pullups
// are insufficient however, please make sure 10k external pullups are
// connected on the bus. This is for debug / example purpose only.
slot_config.flags |= SDCARD_PULLUP;
// Use settings defined above to initialize SD card and mount FAT filesystem.
ret = esp_vfs_fat_sdmmc_mount(mount_point, &host, &slot_config, &mount_config,
&card);
#endif
// mount error handling
if (ret != ESP_OK) {
if (ret == ESP_FAIL) {
ESP_LOGE(TAG, "failed to mount filesystem");
} else {
ESP_LOGE(TAG, "SD-card not found (%d)", ret);
}
return false;
}
// SD card is now initialized
useSDCard = true;
ESP_LOGI(TAG, "filesystem mounted");
sdmmc_card_print_info(stdout, card);
// open files for data and, optional, system logging
char bufferFilename[50];
snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME);
if (openFile(&data_file, bufferFilename)) {
fpos_t position;
fgetpos(data_file, &position);
// empty file? then we write a header line
if (position == 0) {
fprintf(data_file, "%s", SDCARD_FILE_HEADER);
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
fprintf(data_file, "%s", SDCARD_FILE_HEADER_VOLTAGE);
#endif
#if (HAS_SDS011)
fprintf(data_file, "%s", SDCARD_FILE_HEADER_SDS011);
#endif
}
fprintf(data_file, "\n");
} else {
useSDCard = false;
}
#ifdef SD_LOGGING
snprintf(bufferFilename, sizeof(bufferFilename), "/%s.log", SDCARD_FILE_NAME);
if (openFile(&log_file, bufferFilename)) {
ESP_LOGI(TAG, "redirecting serial output to SD-card");
esp_log_set_vprintf(&print_to_sd_card);
// Change stdout for THIS TASK ONLY
// stdout = log_file;
// Change stdout for all new tasks which will be created
//_GLOBAL_REENT->_stdout = log_file;
} else {
useSDCard = false;
}
#endif
return useSDCard;
} // sdcard_init
void sdcard_flush(void) {
if (data_file)
fsync(fileno(data_file));
#ifdef SD_LOGGING
if (log_file)
fsync(fileno(log_file));
#endif
} }
void sdcard_close(void) { void sdcard_close(void) {
ESP_LOGI(TAG, "closing SD-card"); ESP_LOGI(TAG, "closing SD-card");
fileSDCard.flush(); sdcard_flush();
fileSDCard.close(); #ifdef SD_LOGGING
// Reset logging output back to normal
ESP_LOGI(TAG, "redirect console back to serial output");
// stdout = uart_stdout;
//_GLOBAL_REENT->_stdout = uart_stdout;
esp_log_set_vprintf(&vprintf);
#endif
fcloseall();
esp_vfs_fat_sdcard_unmount(mount_point, card);
ESP_LOGI(TAG, "SD-card unmounted");
} }
void sdcardWriteData(uint16_t noWifi, uint16_t noBle, void sdcardWriteData(uint16_t noWifi, uint16_t noBle,
__attribute__((unused)) uint16_t voltage) { __attribute__((unused)) uint16_t voltage) {
static int counterWrites = 0;
char tempBuffer[20 + 1]; if (!useSDCard)
return;
char timeBuffer[20 + 1];
time_t t = time(NULL); time_t t = time(NULL);
struct tm tt; struct tm tt;
gmtime_r(&t, &tt); // make UTC timestamp gmtime_r(&t, &tt); // make UTC timestamp
strftime(timeBuffer, sizeof(timeBuffer), "%FT%TZ", &tt);
#if (HAS_SDS011) #if (HAS_SDS011)
sdsStatus_t sds; sdsStatus_t sds;
#endif #endif
if (!useSDCard) ESP_LOGI(TAG, "writing data to SD-card");
return;
ESP_LOGI(TAG, "SD: writing data"); fprintf(data_file, "%s", timeBuffer);
strftime(tempBuffer, sizeof(tempBuffer), "%FT%TZ", &tt); fprintf(data_file, ",%d,%d", noWifi, noBle);
fileSDCard.print(tempBuffer);
snprintf(tempBuffer, sizeof(tempBuffer), ",%d,%d", noWifi, noBle);
fileSDCard.print(tempBuffer);
#if (defined BAT_MEASURE_ADC || defined HAS_PMU) #if (defined BAT_MEASURE_ADC || defined HAS_PMU)
snprintf(tempBuffer, sizeof(tempBuffer), ",%d", voltage); fprintf(data_file, ",%d", voltage);
fileSDCard.print(tempBuffer);
#endif #endif
#if (HAS_SDS011) #if (HAS_SDS011)
sds011_store(&sds); sds011_store(&sds);
snprintf(tempBuffer, sizeof(tempBuffer), ",%5.1f,%4.1f", sds.pm10 / 10, fprintf(data_file, ",%5.1f,%4.1f", sds.pm10 / 10, sds.pm25 / 10);
sds.pm25 / 10);
fileSDCard.print(tempBuffer);
#endif #endif
fileSDCard.println(); fprintf(data_file, "\n");
if (++counterWrites > 2) {
// force writing to SD-card
ESP_LOGI(TAG, "SD: flushing data");
fileSDCard.flush();
counterWrites = 0;
}
}
void openFile(void) {
char bufferFilename[30];
useSDCard = false;
snprintf(bufferFilename, sizeof(bufferFilename), "/%s.csv", SDCARD_FILE_NAME);
ESP_LOGI(TAG, "SD: looking for file <%s>", bufferFilename);
#if HAS_SDCARD == 1
bool fileExists = SD.exists(bufferFilename);
#elif HAS_SDCARD == 2
bool fileExists = SD_MMC.exists(bufferFilename);
#endif
// file not exists, create it
if (!fileExists) {
ESP_LOGD(TAG, "SD: file not found, creating...");
#if HAS_SDCARD == 1
fileSDCard = SD.open(bufferFilename, FILE_WRITE);
#elif HAS_SDCARD == 2
fileSDCard = SD_MMC.open(bufferFilename, FILE_WRITE);
#endif
if (fileSDCard) {
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
fileSDCard.print(SDCARD_FILE_HEADER);
#if (defined BAT_MEASURE_ADC || defined HAS_PMU)
fileSDCard.print(SDCARD_FILE_HEADER_VOLTAGE); // for battery level data
#endif
#if (HAS_SDS011)
fileSDCard.print(SDCARD_FILE_HEADER_SDS011);
#endif
fileSDCard.println();
useSDCard = true;
}
}
// file exists, append data
else {
ESP_LOGD(TAG, "SD: file found, opening...");
#if HAS_SDCARD == 1
fileSDCard = SD.open(bufferFilename, FILE_APPEND);
#elif HAS_SDCARD == 2
fileSDCard = SD_MMC.open(bufferFilename, FILE_APPEND);
#endif
if (fileSDCard) {
ESP_LOGD(TAG, "SD: name opened: <%s>", bufferFilename);
useSDCard = true;
}
}
return;
} }
#endif // (HAS_SDCARD) #endif // (HAS_SDCARD)

View File

@ -1,6 +1,9 @@
// Basic Config // Basic Config
#include "senddata.h" #include "senddata.h"
// Local logging tag
static const char TAG[] = __FILE__;
void setSendIRQ(TimerHandle_t xTimer) { void setSendIRQ(TimerHandle_t xTimer) {
xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits); xTaskNotify(irqHandlerTask, SENDCYCLE_IRQ, eSetBits);
} }

View File

@ -63,7 +63,7 @@ void calibrateTime(void) {
} // calibrateTime() } // calibrateTime()
// set system time (UTC), calibrate RTC and RTC_INT pps // set system time (UTC), calibrate RTC and RTC_INT pps
bool IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, bool setMyTime(uint32_t t_sec, uint16_t t_msec,
timesource_t mytimesource) { timesource_t mytimesource) {
struct timeval tv = {0}; struct timeval tv = {0};

View File

@ -55,7 +55,7 @@ void timesync_request(void) {
} }
// task for processing time sync request // task for processing time sync request
void IRAM_ATTR timesync_processReq(void *taskparameter) { void timesync_processReq(void *taskparameter) {
uint32_t rcv_seqNo = TIME_SYNC_END_FLAG; uint32_t rcv_seqNo = TIME_SYNC_END_FLAG;
uint32_t time_offset_sec = 0, time_offset_ms = 0; uint32_t time_offset_sec = 0, time_offset_ms = 0;
@ -173,7 +173,7 @@ void timesync_store(uint32_t timestamp, timesync_t timestamp_type) {
} }
// callback function to receive time answer from network or answer // callback function to receive time answer from network or answer
void IRAM_ATTR timesync_serverAnswer(void *pUserData, int flag) { void timesync_serverAnswer(void *pUserData, int flag) {
#if (HAS_LORA_TIME) #if (HAS_LORA_TIME)