commit
737df716b4
@ -44,6 +44,7 @@ LoLin32lite + [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-L
|
||||
|
||||
- Pyom: WiPy
|
||||
- WeMos: LoLin32, LoLin32 Lite, WeMos D32, [Wemos32 Oled](https://www.instructables.com/id/ESP32-With-Integrated-OLED-WEMOSLolin-Getting-Star/)
|
||||
- Crowdsupply: [TinyPICO](https://www.crowdsupply.com/unexpected-maker/tinypico)
|
||||
- Generic ESP32
|
||||
|
||||
Depending on board hardware following features are supported:
|
||||
@ -58,7 +59,7 @@ Depending on board hardware following features are supported:
|
||||
- Real Time Clock (Maxim DS3231 I2C)
|
||||
- IF482 (serial) and DCF77 (gpio) time telegram generator
|
||||
- Switch external power / battery
|
||||
- 64x16 pixel LED Matrix display (similar to [this 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))
|
||||
|
||||
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>
|
||||
@ -405,11 +406,11 @@ Note: all settings are stored in NVRAM and will be reloaded when device starts.
|
||||
bytes 1..4 = time/date in UTC epoch seconds (LSB)
|
||||
byte 5 = time source & status, see below
|
||||
|
||||
bits 0..3 time source
|
||||
bits 0..3 last seen time source
|
||||
0x00 = GPS
|
||||
0x01 = RTC
|
||||
0x02 = LORA
|
||||
0x03 = unsynched
|
||||
0x03 = unsynched (never synched)
|
||||
|
||||
bits 4..7 time status
|
||||
0x00 = timeNotSet (never synched)
|
||||
|
@ -11,14 +11,16 @@
|
||||
#include <Adafruit_BME280.h>
|
||||
#endif
|
||||
|
||||
extern Ticker bmecycler;
|
||||
|
||||
extern bmeStatus_t
|
||||
bme_status; // Make struct for storing gps data globally available
|
||||
extern TaskHandle_t BmeTask;
|
||||
|
||||
// --- Bosch BSEC v1.4.7.4 library configuration ---
|
||||
// 3,3V supply voltage; 3s max time between sensor_control calls; 4 days
|
||||
// calibration. Change this const if not applicable for your application (see
|
||||
// BME680 datasheet)
|
||||
// Note: 3s max time not exceed BMECYCLE frequency set in paxcounter.conf!
|
||||
const uint8_t bsec_config_iaq[454] = {
|
||||
4, 7, 4, 1, 61, 0, 0, 0, 0, 0, 0, 0, 174, 1, 0,
|
||||
0, 48, 0, 1, 0, 0, 192, 168, 71, 64, 49, 119, 76, 0, 0,
|
||||
@ -54,7 +56,8 @@ const uint8_t bsec_config_iaq[454] = {
|
||||
|
||||
// Helper functions declarations
|
||||
int bme_init();
|
||||
void bme_loop(void *pvParameters);
|
||||
void bmecycle(void);
|
||||
void bme_storedata(bmeStatus_t *bme_store);
|
||||
int checkIaqSensorStatus(void);
|
||||
void loadState(void);
|
||||
void updateState(void);
|
||||
|
@ -82,8 +82,6 @@ typedef struct {
|
||||
uint8_t satellites;
|
||||
uint16_t hdop;
|
||||
int16_t altitude;
|
||||
uint32_t time_age;
|
||||
tmElements_t timedate;
|
||||
} gpsStatus_t;
|
||||
|
||||
typedef struct {
|
||||
@ -99,7 +97,6 @@ typedef struct {
|
||||
|
||||
enum sendprio_t { prio_low, prio_normal, prio_high };
|
||||
enum timesource_t { _gps, _rtc, _lora, _unsynced };
|
||||
enum mutexselect_t { no_mutex, do_mutex };
|
||||
|
||||
extern std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
|
||||
extern std::array<uint64_t, 0xff>::iterator it;
|
||||
@ -112,13 +109,12 @@ extern uint16_t volatile macs_total, macs_wifi, macs_ble,
|
||||
batt_voltage; // 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, *gpsIRQ;
|
||||
extern hw_timer_t *displayIRQ, *matrixDisplayIRQ, *ppsIRQ;
|
||||
extern SemaphoreHandle_t I2Caccess;
|
||||
extern TaskHandle_t irqHandlerTask, ClockTask;
|
||||
extern TimerHandle_t WifiChanTimer;
|
||||
extern Timezone myTZ;
|
||||
extern time_t userUTCTime;
|
||||
extern time_t volatile gps_pps_time;
|
||||
|
||||
// application includes
|
||||
#include "led.h"
|
||||
|
@ -10,18 +10,16 @@
|
||||
#endif
|
||||
|
||||
#define NMEA_FRAME_SIZE 82 // NEMA has a maxium of 82 bytes per record
|
||||
#define NMEA_BUFFERTIME 50 // 50ms safety time regardless
|
||||
#define NMEA_COMPENSATION_FACTOR 480 // empiric for Ublox Neo 6M
|
||||
|
||||
extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe
|
||||
extern gpsStatus_t
|
||||
gps_status; // Make struct for storing gps data globally available
|
||||
extern TaskHandle_t GpsTask;
|
||||
|
||||
int gps_init(void);
|
||||
void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store);
|
||||
int gps_config();
|
||||
void gps_storelocation(gpsStatus_t *gps_store);
|
||||
void gps_loop(void *pvParameters);
|
||||
time_t fetch_gpsTime(gpsStatus_t value);
|
||||
int gps_config();
|
||||
time_t fetch_gpsTime(uint16_t *msec);
|
||||
time_t fetch_gpsTime(void);
|
||||
|
||||
#endif
|
@ -8,13 +8,14 @@
|
||||
#define TIMESYNC_IRQ 0x010
|
||||
#define MASK_IRQ 0x020
|
||||
#define UNMASK_IRQ 0x040
|
||||
#define GPS_IRQ 0x080
|
||||
#define BME_IRQ 0x080
|
||||
#define MATRIX_DISPLAY_IRQ 0x100
|
||||
|
||||
#include "globals.h"
|
||||
#include "cyclic.h"
|
||||
#include "senddata.h"
|
||||
#include "timekeeper.h"
|
||||
#include "bmesensor.h"
|
||||
|
||||
void irqHandler(void *pvParameters);
|
||||
void mask_user_IRQ();
|
||||
@ -32,8 +33,5 @@ void IRAM_ATTR MatrixDisplayIRQ();
|
||||
void IRAM_ATTR ButtonIRQ();
|
||||
#endif
|
||||
|
||||
#if (HAS_GPS)
|
||||
void IRAM_ATTR GpsIRQ();
|
||||
#endif
|
||||
|
||||
#endif
|
@ -13,5 +13,6 @@ void refreshTheMatrixDisplay(bool nextPage = false);
|
||||
void DrawNumber(String strNum, uint8_t iDotPos = 0);
|
||||
uint8_t GetCharFromFont(char cChar);
|
||||
uint8_t GetCharWidth(char cChar);
|
||||
void ShiftLeft(uint8_t *arr, uint32_t len);
|
||||
|
||||
#endif
|
@ -21,8 +21,10 @@
|
||||
#endif
|
||||
|
||||
extern QueueHandle_t LoraSendQueue;
|
||||
extern TaskHandle_t lmicTask;
|
||||
|
||||
esp_err_t lora_stack_init();
|
||||
void lmictask(void *pvParameters);
|
||||
void onEvent(ev_t ev);
|
||||
void gen_lora_deveui(uint8_t *pdeveui);
|
||||
void RevBytes(unsigned char *b, size_t c);
|
||||
@ -35,7 +37,6 @@ void switch_lora(uint8_t sf, uint8_t tx);
|
||||
void lora_send(osjob_t *job);
|
||||
void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio);
|
||||
void lora_queuereset(void);
|
||||
void lora_housekeeping(void);
|
||||
#if (TIME_SYNC_LORAWAN)
|
||||
void user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||
int flagSuccess);
|
||||
|
@ -9,7 +9,7 @@
|
||||
extern RtcDS3231<TwoWire> Rtc; // make RTC instance globally available
|
||||
|
||||
uint8_t rtc_init(void);
|
||||
uint8_t set_rtctime(time_t t, mutexselect_t mutex);
|
||||
uint8_t set_rtctime(time_t t);
|
||||
void sync_rtctime(void);
|
||||
time_t get_rtctime(void);
|
||||
float get_rtctemp(void);
|
||||
|
@ -31,6 +31,4 @@ esp_err_t spi_init();
|
||||
void spi_enqueuedata(MessageBuffer_t *message, sendprio_t prio);
|
||||
void spi_queuereset();
|
||||
|
||||
void spi_housekeeping();
|
||||
|
||||
#endif // _SPISLAVE_H
|
||||
|
@ -26,7 +26,8 @@ void timepulse_start(void);
|
||||
void timeSync(void);
|
||||
uint8_t timepulse_init(void);
|
||||
time_t timeIsValid(time_t const t);
|
||||
time_t timeProvider(void);
|
||||
void calibrateTime(void);
|
||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec, timesource_t mytimesource);
|
||||
time_t compiledUTC(void);
|
||||
TickType_t tx_Ticks(uint32_t framesize, unsigned long baud, uint32_t config,
|
||||
int8_t rxPin, int8_t txPins);
|
||||
|
@ -15,6 +15,5 @@ void send_timesync_req(void);
|
||||
int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len);
|
||||
void process_timesync_req(void *taskparameter);
|
||||
void store_time_sync_req(uint32_t t_millisec);
|
||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec);
|
||||
|
||||
#endif
|
@ -1,233 +1,243 @@
|
||||
std::array<uint32_t, 1617> vendors = {
|
||||
0x38f23e, 0x807abf, 0x90e7c4, 0x7c6193, 0x485073, 0x74e28c, 0x8463d6,
|
||||
0xd48f33, 0x2c8a72, 0x980d2e, 0xa826d9, 0xd4206d, 0x00155d, 0x806c1b,
|
||||
0xa470d6, 0x985fd3, 0x1c69a5, 0x382de8, 0xd087e2, 0x205531, 0x5440ad,
|
||||
0x842e27, 0x50f0d3, 0x84119e, 0x08eca9, 0x10d38a, 0x382dd1, 0xe0cbee,
|
||||
0x64b853, 0xf4428f, 0x188331, 0x8455a5, 0xa87c01, 0xc01173, 0xbce63f,
|
||||
0xb857d8, 0x94b10a, 0xe458b8, 0x088c2c, 0xb86ce8, 0x9c65b0, 0xc8a823,
|
||||
0xc44202, 0xd059e4, 0x64b310, 0x9476b7, 0x8c1abf, 0xb47443, 0x30cbf8,
|
||||
0x182195, 0xa88195, 0x88add2, 0xd0fccc, 0x14c913, 0x4c6641, 0x3cbdd8,
|
||||
0x38256b, 0x849866, 0xe89309, 0x0016db, 0x5c3c27, 0x10d542, 0xa0821f,
|
||||
0xc45006, 0x88329b, 0xbc8ccd, 0x400e85, 0xec9bf3, 0xf8042e, 0x843838,
|
||||
0x54880e, 0xbc79ad, 0x30d6c9, 0xb0df3a, 0x805719, 0x78a873, 0x041bba,
|
||||
0x08fd0e, 0x08d42b, 0x00e3b2, 0xc81479, 0xf0728c, 0x94350a, 0x001fcd,
|
||||
0xd0dfc7, 0x1c62b8, 0x18e2c2, 0x001a8a, 0x002567, 0xa8f274, 0x001599,
|
||||
0x0012fb, 0x7cf854, 0x8cc8cd, 0xe81132, 0xa02195, 0x8c71f8, 0x04180f,
|
||||
0x9463d1, 0x0cdfa4, 0xcc051b, 0x68ebae, 0x60d0a9, 0x60a10a, 0xa07591,
|
||||
0x001fcc, 0xec107b, 0xa01081, 0xf4f524, 0xbc8385, 0x900628, 0xd4ae05,
|
||||
0x3c0518, 0xe8bba8, 0xbc3aea, 0x8c0ee3, 0x6c5c14, 0x78abbb, 0x1816c9,
|
||||
0xfc8f90, 0x244b03, 0x988389, 0x14bb6e, 0x1c3ade, 0xf83f51, 0xd8e0e1,
|
||||
0xecf342, 0x5092b9, 0xb4bff6, 0xc8d7b0, 0x982d68, 0xd80831, 0xdc5583,
|
||||
0x2c54cf, 0x001fe3, 0x0026e2, 0x001e75, 0x6cd68a, 0x2021a5, 0x0c4885,
|
||||
0xdc0b34, 0xac0d1b, 0x60e3ac, 0xf895c7, 0xc4438f, 0xa816b2, 0xe892a4,
|
||||
0x700514, 0x88c9d0, 0x2c598a, 0xec8350, 0x4cdd31, 0x705aac, 0xfc643a,
|
||||
0xd4e6b7, 0x2802d8, 0x48605f, 0xf0766f, 0x40cbc0, 0x4098ad, 0x6c4d73,
|
||||
0xc48466, 0xb8634d, 0x503237, 0xd4619d, 0xb0481a, 0x989e63, 0xdca904,
|
||||
0x48a195, 0x6cab31, 0x7c5049, 0xe42b34, 0x1c36bb, 0x3c2eff, 0x6c96cf,
|
||||
0x3035ad, 0xa8be27, 0x70a2b3, 0x4c57ca, 0x68fb7e, 0x90c1c6, 0xa4f1e8,
|
||||
0xac61ea, 0x38b54d, 0x00cdfe, 0x18af61, 0xcc4463, 0x34159e, 0x58b035,
|
||||
0xf0b479, 0x109add, 0x40a6d9, 0x7cf05f, 0xa4b197, 0x0c74c2, 0x403004,
|
||||
0x4860bc, 0xd02b20, 0x9ce33f, 0xf0989d, 0xace4b5, 0x6c72e7, 0x60fec5,
|
||||
0x00a040, 0x000d93, 0xacbc32, 0x30d9d9, 0x6030d4, 0x94bf2d, 0xc49880,
|
||||
0xe0338e, 0x68fef7, 0xbce143, 0x645aed, 0xc0b658, 0x881908, 0xfc2a9c,
|
||||
0x44d884, 0xec852f, 0x286aba, 0x705681, 0x7cd1c3, 0xf0dce2, 0xb065bd,
|
||||
0xa82066, 0xbc6778, 0x68967b, 0x848506, 0x54ae27, 0x6476ba, 0x84b153,
|
||||
0x783a84, 0x2cbe08, 0x24e314, 0x68d93c, 0x2cf0ee, 0x84788b, 0x6c94f8,
|
||||
0x703eac, 0xb4f0ab, 0x10ddb1, 0x04f7e4, 0x34c059, 0xf0d1a9, 0xbc3baf,
|
||||
0x786c1c, 0x041552, 0x38484c, 0x701124, 0xc86f1d, 0x685b35, 0x380f4a,
|
||||
0x3010e4, 0x04db56, 0x881fa1, 0x04e536, 0xf82793, 0xacfdec, 0xd0e140,
|
||||
0x8c7c92, 0x7831c1, 0xf437b7, 0x50ead6, 0x28e02c, 0x60c547, 0x7c11be,
|
||||
0x003ee1, 0xc01ada, 0x34363b, 0xc81ee7, 0x9cfc01, 0xccc760, 0x087402,
|
||||
0x285aeb, 0x28f076, 0x70700d, 0x9cf48e, 0xfcd848, 0x001cb3, 0x64b9e8,
|
||||
0xf8e94e, 0xf40616, 0xbcb863, 0x885a06, 0xc08c71, 0x108ee0, 0x68e7c2,
|
||||
0x3c576c, 0x0ce0dc, 0x702ad5, 0x889f6f, 0x1c427d, 0x5029f5, 0x4c569d,
|
||||
0x14c213, 0x38539c, 0x58e6ba, 0xb831b5, 0x90633b, 0x782327, 0xf8a45f,
|
||||
0x8cbebe, 0x640980, 0x98fae3, 0x185936, 0x9c99a0, 0xc40bcb, 0xecd09f,
|
||||
0xf4f5db, 0xe446da, 0x18f0e4, 0x9c2ea1, 0x50a009, 0x20a60c, 0x20326c,
|
||||
0xa8346a, 0xb06fe0, 0x98460a, 0xac88fd, 0x149d99, 0x846fce, 0xe0dcff,
|
||||
0x60ab67, 0x188796, 0x002376, 0x84100d, 0x04c23e, 0x5c5188, 0xe89120,
|
||||
0x9c6c15, 0x4886e8, 0x2c2997, 0x102f6b, 0x00eebd, 0x281878, 0x6045bd,
|
||||
0x7ced8d, 0xe85b5b, 0x000d3a, 0xe09861, 0xf4f1e1, 0x60beb5, 0xb4e1c4,
|
||||
0x70aab2, 0x0026ff, 0x406f2a, 0x002557, 0xf05a09, 0x503275, 0x28cc01,
|
||||
0xb46293, 0x04fe31, 0x845181, 0xd831cf, 0xf8d0bd, 0xfcc734, 0xe4b021,
|
||||
0xb0ec71, 0x3cbbfd, 0x2cae2b, 0xc488e5, 0x7c9122, 0xe8b4c8, 0x18895b,
|
||||
0xe0db10, 0xe09971, 0x6077e2, 0x680571, 0x6c2f2c, 0x300d43, 0x6c2779,
|
||||
0x607edd, 0x9c2a83, 0xe45d75, 0xe4faed, 0xc83f26, 0x54f201, 0xa06090,
|
||||
0xac3743, 0x141f78, 0x006f64, 0xdc6672, 0x001e7d, 0x3c6200, 0x0024e9,
|
||||
0x002399, 0xe4e0c5, 0xe8039a, 0xc4731e, 0x8c7712, 0x2013e0, 0x0007ab,
|
||||
0x0021d2, 0xbc4760, 0xd0176a, 0x2cbaba, 0x24920e, 0x40d3ae, 0xf01dbc,
|
||||
0x24dbed, 0xac3613, 0x1449e0, 0xc0bdd1, 0xe8508b, 0xf025b7, 0xc8ba94,
|
||||
0xec1f72, 0x9852b1, 0x1489fd, 0xccfe3c, 0x789ed0, 0xe440e2, 0x1caf05,
|
||||
0xe492fb, 0x0073e0, 0xbc4486, 0x380b40, 0x002490, 0x0023d7, 0xfca13e,
|
||||
0xa00798, 0x945103, 0xc819f7, 0x2c4401, 0xec51bc, 0xf079e8, 0x887598,
|
||||
0xd0b128, 0xd00401, 0xf06d78, 0x10683f, 0x74a722, 0x58a2b5, 0x64899a,
|
||||
0x88074b, 0x64bc0c, 0xa039f7, 0x041b6d, 0x001f6b, 0x30b4b8, 0x503cea,
|
||||
0x54fcf0, 0x08aed6, 0xa816d0, 0x88bd45, 0x641cb0, 0x3cdcbc, 0xf47190,
|
||||
0x587a6a, 0xe4c483, 0xfcaab6, 0xc0bdc8, 0xa887b3, 0x742344, 0xd832e3,
|
||||
0xe06267, 0x482ca0, 0x1801f1, 0x70bbe9, 0xf0b429, 0x0c9838, 0x0c1daf,
|
||||
0x28e31f, 0x14f65a, 0xd4c94b, 0x703a51, 0xdc080f, 0xf82d7c, 0x9c648b,
|
||||
0x14d00d, 0xd467d3, 0x58c6f0, 0xc02e25, 0x804a14, 0xb85d0a, 0x941625,
|
||||
0x34a8eb, 0x4883b4, 0xa8db03, 0x2479f3, 0x98b8ba, 0xd49dc0, 0x8cf5a3,
|
||||
0x14568e, 0x8058f8, 0xf0d7aa, 0xc49ded, 0xb0aa36, 0x2c5bb8, 0x1c48ce,
|
||||
0x24f5aa, 0xf877b8, 0x682737, 0x5056bf, 0x9097f3, 0x58c5cb, 0xacafb9,
|
||||
0x30074d, 0x5c5181, 0x389af6, 0xe0aa96, 0x507705, 0x2c4053, 0x084acf,
|
||||
0x1cddea, 0x08152f, 0xb8c111, 0x3408bc, 0x844167, 0xb4f61c, 0x68ab1e,
|
||||
0x2c61f6, 0xe49adc, 0xd0817a, 0xc4618b, 0x3451c9, 0xe0b9ba, 0xd023db,
|
||||
0xb88d12, 0xb817c2, 0x68a86d, 0x78a3e4, 0x680927, 0x60facd, 0x1caba7,
|
||||
0x784f43, 0x404d7f, 0x7c04d0, 0xbc9fef, 0x8866a5, 0x88e87f, 0xb853ac,
|
||||
0x2c3361, 0xa860b6, 0x24f094, 0x90b0ed, 0xc4b301, 0xe05f45, 0x483b38,
|
||||
0xe0c767, 0x1c9e46, 0x0cd746, 0x440010, 0xe498d6, 0x606944, 0x0452f3,
|
||||
0x241eeb, 0xf431c3, 0x64a5c3, 0xbc926b, 0x0050e4, 0x003065, 0x000a27,
|
||||
0x001451, 0x8c7b9d, 0x88c663, 0xc82a14, 0x9803d8, 0x8c5877, 0x0019e3,
|
||||
0x002312, 0x002332, 0x002436, 0x00254b, 0x0026bb, 0x70f087, 0x886b6e,
|
||||
0x4c74bf, 0xe80688, 0xcc08e0, 0x5855ca, 0x5c0947, 0x38892c, 0x40831d,
|
||||
0x50bc96, 0x985aeb, 0x2078f0, 0x78d75f, 0xe0accb, 0x98e0d9, 0xc0cecd,
|
||||
0x70e72c, 0xd03311, 0x5cadcf, 0x006d52, 0x48437c, 0x34a395, 0x9cf387,
|
||||
0xa85b78, 0x908d6c, 0x0c1539, 0xbc4cc4, 0x0cbc9f, 0xa45e60, 0x544e90,
|
||||
0x9ce65e, 0x90dd5d, 0x08f69c, 0xd461da, 0xc8d083, 0x88e9fe, 0x88ae07,
|
||||
0x18af8f, 0xc8b5b7, 0xa8bbcf, 0x90b21f, 0xb8e856, 0x1499e2, 0xb418d1,
|
||||
0x80006e, 0x60d9c7, 0xc8f650, 0x1c1ac0, 0xe06678, 0x5c8d4e, 0xc0f2fb,
|
||||
0x00f76f, 0xac87a3, 0x542696, 0xd8d1cb, 0x64a3cb, 0x44fb42, 0xf41ba1,
|
||||
0x3ce072, 0xe88d28, 0xcc785f, 0xac3c0b, 0x88cb87, 0xec3586, 0xf0c1f1,
|
||||
0xf4f951, 0x8cfaba, 0x5c95ae, 0xe0c97a, 0xbc52b7, 0x14109f, 0x00c3f4,
|
||||
0x74eb80, 0xa82bb9, 0x7c6b9c, 0x1cc3eb, 0xbca58b, 0x70fd46, 0xd07fa0,
|
||||
0x9caa1b, 0x18d717, 0xb4cb57, 0x74b587, 0xd81c79, 0x8cfe57, 0xc0a600,
|
||||
0xa823fe, 0x00092d, 0xf8db7f, 0xe899c4, 0x24da9b, 0x1c56fe, 0xe4907e,
|
||||
0x80c5e6, 0x800184, 0xf8cfc5, 0xc808e9, 0x206274, 0x30d587, 0xc0eefb,
|
||||
0x502e5c, 0x847a88, 0x0025ae, 0x002538, 0x0022a1, 0x00125a, 0x9cd917,
|
||||
0x9068c3, 0x408805, 0xf8f1b6, 0x001ccc, 0x94ebcd, 0xa4e4b8, 0x389496,
|
||||
0x0cb319, 0x08ee8b, 0xa89fba, 0xfc1910, 0x083d88, 0x5c2e59, 0x646cb2,
|
||||
0xf884f2, 0x14b484, 0x608f5c, 0x4cbca5, 0x78595e, 0xb0d09c, 0x4ca56d,
|
||||
0xa48431, 0xe4f8ef, 0x1432d1, 0xe458e7, 0x8cbfa6, 0x7840e4, 0x9000db,
|
||||
0x183a2d, 0x08373d, 0x50f520, 0xa4ebd3, 0x28987b, 0xf40e22, 0x9c3aaf,
|
||||
0x0821ef, 0xa0cbfd, 0x34145f, 0x6c8fb5, 0xac5f3e, 0x509ea7, 0xdccf96,
|
||||
0x6c2483, 0xc09727, 0xd85b2a, 0xacc33a, 0x88797e, 0x00e091, 0x6cd032,
|
||||
0xc041f6, 0x0017d5, 0x001247, 0xe4121d, 0x684898, 0xf409d8, 0xb479a7,
|
||||
0x002339, 0xd487d8, 0x184617, 0x5001bb, 0x380a94, 0xd857ef, 0x1c66aa,
|
||||
0x58c38b, 0x001ee2, 0x001c43, 0x001d25, 0x3c5a37, 0x549b12, 0x3c8bfe,
|
||||
0x00265d, 0xd4e8b2, 0x0808c2, 0xb0c4e7, 0xd890e8, 0x34aa8b, 0x24c696,
|
||||
0x181eb0, 0x20d390, 0x343111, 0x34be00, 0x78521a, 0x7825ad, 0xf4d9fb,
|
||||
0x0017c9, 0x00166b, 0x00166c, 0xe47cf9, 0x002454, 0x20d5bf, 0x30cda7,
|
||||
0xc87e75, 0x00233a, 0x60a4d0, 0x2c0e3d, 0x7c787e, 0xc0d3c0, 0x440444,
|
||||
0xc09f05, 0xcc2d83, 0x38295a, 0x4c1a3d, 0xa81b5a, 0xdc6dcd, 0x54fa3e,
|
||||
0x0c8910, 0xfcf136, 0x981dfa, 0x84a466, 0x1867b0, 0xccb11a, 0xb8bbaf,
|
||||
0x60c5ad, 0x28395e, 0xc4ae12, 0xdc74a8, 0xc087eb, 0x74f61c, 0x986f60,
|
||||
0x4c189a, 0x3cf591, 0x602101, 0xa89675, 0x608e08, 0x7c2edd, 0x3cf7a4,
|
||||
0x342d0d, 0x94d029, 0x308454, 0x087808, 0xd03169, 0xbc5451, 0x641cae,
|
||||
0xa4e975, 0xc0a53e, 0x9800c6, 0x787b8a, 0x3866f0, 0x20ee28, 0x08f4ab,
|
||||
0x8c8590, 0x68ef43, 0xcc2db7, 0xd4a33d, 0xe4e0a6, 0x70ef00, 0xb0ca68,
|
||||
0x9810e8, 0xb49cdf, 0xdca4ca, 0x8c8fe9, 0x98ca33, 0xfc253f, 0x183451,
|
||||
0xc0847a, 0x64200c, 0x74e1b6, 0x0c771a, 0x00f4b9, 0xc8334b, 0xb8f6b1,
|
||||
0xc09f42, 0x189efc, 0x6c3e6d, 0x8c2daa, 0xe4e4ab, 0x58404e, 0xdc0c5c,
|
||||
0x2c200b, 0x609ac1, 0xf07960, 0x9c8ba0, 0x28a02b, 0xb44bd2, 0x9c4fda,
|
||||
0x1c5cf2, 0x3871de, 0xbc5436, 0x5cf938, 0x4c3275, 0x2cf0a2, 0xecadb8,
|
||||
0x9801a7, 0xb48b19, 0xe49a79, 0x406c8f, 0x00c610, 0x70dee2, 0x182032,
|
||||
0x6cc26b, 0x1040f3, 0x001d4f, 0x001e52, 0x001f5b, 0x001ff3, 0x0021e9,
|
||||
0x00236c, 0x002500, 0x60fb42, 0xf81edf, 0x90840d, 0xd8a25e, 0xc8bcc8,
|
||||
0x28e7cf, 0xd89e3f, 0x040cce, 0xa4d1d2, 0x7cfadf, 0x101c0c, 0x001124,
|
||||
0x6c709f, 0x0c3e9f, 0x34e2fd, 0x609217, 0x8863df, 0x80e650, 0x006171,
|
||||
0x90fd61, 0x5c97f3, 0x6c4008, 0x24a074, 0xf02475, 0x20a2e4, 0x5cf5da,
|
||||
0x649abe, 0x94e96a, 0xac293a, 0x10417f, 0xb844d9, 0xdc2b2a, 0x14205e,
|
||||
0x5c1dd9, 0x18f1d8, 0xf86fc1, 0xf099b6, 0x907240, 0x0c4de9, 0xd89695,
|
||||
0x0c3021, 0xf0f61c, 0xb03495, 0x848e0c, 0x949426, 0xe0f5c6, 0x28e14c,
|
||||
0x54e43a, 0xc8e0eb, 0xa88808, 0x444c0c, 0x84fcfe, 0xe48b7f, 0x5c969d,
|
||||
0xa8fad8, 0x7014a6, 0xa8667f, 0xd02598, 0xcc29f5, 0xdcd3a2, 0x08c5e1,
|
||||
0x00bf61, 0xf80cf3, 0x30766f, 0x8c3ae3, 0x78f882, 0xb4f1da, 0x0021fb,
|
||||
0xd013fd, 0xa8b86e, 0xdcbfe9, 0x306a85, 0x4466fc, 0xfca621, 0x0ccb85,
|
||||
0xa4d990, 0xd003df, 0x24fce5, 0xe4b2fb, 0xf83880, 0x241b7a, 0x402619,
|
||||
0xbcfed9, 0x808223, 0x3830f9, 0x6c006b, 0x38a4ed, 0xb0e235, 0x64cc2e,
|
||||
0xd86375, 0x80ad16, 0x2047da, 0x8035c1, 0x9487e0, 0x7c03ab, 0xd4970b,
|
||||
0xf48b32, 0x4c49e3, 0x04b167, 0xd8ce3a, 0xb8c74a, 0xfc183c, 0xc0e862,
|
||||
0xec2ce2, 0x64c753, 0x48fda3, 0x7c035e, 0x70bc10, 0x2c5d34, 0x64c2de,
|
||||
0x58d9c3, 0x489dd1, 0xd81edd, 0x2034fb, 0xf4afe7, 0x7c9a1d, 0xa483e7,
|
||||
0xc4e39f, 0x7cd661, 0x70dda8, 0xbc98df, 0x38e7d8, 0xd8b377, 0xb4cef6,
|
||||
0xd40b1a, 0x5882a8, 0xb4ae2b, 0x0c413e, 0xd0929e, 0x4480eb, 0xb84fd5,
|
||||
0xec59e7, 0x3059b7, 0x501ac5, 0x1cb094, 0xa0f450, 0x002248, 0xec8892,
|
||||
0xb07994, 0x141aa3, 0xccc3ea, 0x34bb26, 0x40786a, 0xf40b93, 0x68ed43,
|
||||
0x34bb1f, 0x489d24, 0x000f86, 0xacee9e, 0xc08997, 0x2827bf, 0xf05b7b,
|
||||
0x7cf90e, 0xac5a14, 0xb0c559, 0xbcd11f, 0xa0b4a5, 0x80656d, 0x48137e,
|
||||
0xe83a12, 0x9c0298, 0x6c8336, 0xb8c68e, 0x74458a, 0xa49a58, 0xb4ef39,
|
||||
0x14a364, 0x3ca10d, 0x206e9c, 0x183f47, 0x0c715d, 0x0c1420, 0xa80600,
|
||||
0x6cf373, 0x78c3e9, 0xc83870, 0x288335, 0x44783e, 0x202d07, 0x98398e,
|
||||
0x348a7b, 0xbc765e, 0x78009e, 0x68c44d, 0xf8e61a, 0x888322, 0x84b541,
|
||||
0x0015b9, 0x001df6, 0xece09b, 0x606bbd, 0x0000f0, 0x4844f7, 0x1c5a3e,
|
||||
0xf47b5e, 0x008701, 0xfc4203, 0x1c232c, 0xcc61e5, 0x404e36, 0x9893cc,
|
||||
0x3ccd93, 0xf06bca, 0x3423ba, 0xd022be, 0xd02544, 0xbc20a4, 0x14f42a,
|
||||
0xbc851f, 0xb85e7b, 0xc462ea, 0x0023d6, 0x002491, 0x001b98, 0x44f459,
|
||||
0x34c3ac, 0x94d771, 0x4c3c16, 0x9401c2, 0xb43a28, 0xd0c1b1, 0xf008f1,
|
||||
0x78471d, 0x3816d1, 0xd48890, 0x002566, 0x00265f, 0x5cba37, 0x3096fb,
|
||||
0xf0ee10, 0xa43d78, 0xec01ee, 0xb83765, 0xc4576e, 0x90f1aa, 0x78bdbc,
|
||||
0xd47ae2, 0x84c0ef, 0x7c1c68, 0xd463c6, 0x7c6456, 0x448f17, 0x04d6aa,
|
||||
0x9ce063, 0xf06e0b, 0x5c865c, 0x003de8, 0x08e689, 0x7836cc, 0x08d46a,
|
||||
0x485929, 0x34fcef, 0x002483, 0x001c62, 0x583f54, 0x40b0fa, 0xa8922c,
|
||||
0x98d6f7, 0x505527, 0x0034da, 0xa09169, 0x88365f, 0x9c8c6e, 0xbcffeb,
|
||||
0x685acf, 0xb4f7a1, 0x785dc8, 0x48c796, 0x804e70, 0x3880df, 0xdc415f,
|
||||
0x30636b, 0xf45c89, 0x68dbca, 0x044bed, 0x6c8dc1, 0x38cada, 0xa4d18c,
|
||||
0x186590, 0x64b0a6, 0x84fcac, 0x6c19c0, 0x20ab37, 0x203cae, 0x748d08,
|
||||
0xa03be3, 0x7c6d62, 0x40d32d, 0xd83062, 0xc42c03, 0x7cc537, 0x70cd60,
|
||||
0xc0d012, 0xd4dccd, 0x484baa, 0xf80377, 0x14bd61, 0xcc25ef, 0xb8782e,
|
||||
0x000502, 0x0010fa, 0x000393, 0x0016cb, 0x409c28, 0x78886d, 0xa85c2c,
|
||||
0x00db70, 0x0c5101, 0x086d41, 0x04d3cf, 0xbcec5d, 0x80b03d, 0xc83c85,
|
||||
0xa04ea7, 0x0017f2, 0x001b63, 0x001ec2, 0x002608, 0xa4c361, 0xac7f3e,
|
||||
0x280b5c, 0x90b931, 0x24a2e1, 0x80ea96, 0x600308, 0x04f13e, 0x54724f,
|
||||
0x48746e, 0xd4f46f, 0x787e61, 0x60f81d, 0x4c7c5f, 0x48e9f1, 0xfce998,
|
||||
0xf099bf, 0x68644b, 0x789f70, 0x24ab81, 0x581faa, 0xa46706, 0x3c0754,
|
||||
0xe4ce8f, 0xe8040b, 0xb8c75d, 0x403cfc, 0x98fe94, 0xd8004d, 0x98b8e3,
|
||||
0x80929f, 0x885395, 0x9c04eb, 0xa8968a, 0xdc3714, 0x40331a, 0x94f6a3,
|
||||
0xd81d72, 0x70ece4, 0x38c986, 0xfcfc48, 0x4c8d79, 0x207d74, 0xf4f15a,
|
||||
0x042665, 0x2cb43a, 0x689c70, 0x087045, 0x3cab8e, 0x7c6df8, 0x48d705,
|
||||
0x78fd94, 0xc88550, 0x286ab8, 0x7cc3a1, 0x3cd0f8, 0x98d6bb, 0x4cb199,
|
||||
0x64e682, 0x804971, 0xcc20e8, 0x209bcd, 0xf0b0e7, 0xa056f3, 0x549963,
|
||||
0x28ff3c, 0x1094bb, 0xf01898, 0x48a91c, 0x58b10f, 0x304b07, 0x1496e5,
|
||||
0x80ceb9, 0xcc2119, 0x0057c1, 0x14c697, 0xfc039f, 0x9c0cdf, 0x007204,
|
||||
0x90e17b, 0x18810e, 0x608c4a, 0xa4d931, 0x6cc7ec, 0x647bce, 0x584498,
|
||||
0xacc1ee, 0x7802f8, 0x508f4c, 0x04d13a, 0x0cf346, 0x082525, 0xf460e2,
|
||||
0xa45046, 0x009ec8, 0x7c1dd9, 0xa086c6, 0x102ab3, 0xacf7f3, 0x601d91,
|
||||
0x38f9d3, 0x44e66e, 0xe83617, 0x344262, 0xc09ad0, 0xa41232, 0xb8bc5b,
|
||||
0xacf6f7, 0x7c38ad, 0x3c20f6, 0x703c69, 0xb8b2f8, 0x005b94, 0x88b291,
|
||||
0x5462e2, 0x4418fd, 0xccd281, 0xd09c7a, 0x4c6f9c, 0x201742, 0x902155,
|
||||
0x64a769, 0xbccfcc, 0xa4516f, 0x3c8375, 0x149a10, 0x0ce725, 0xc0335e,
|
||||
0x20a99b, 0x4c0bbe, 0x7c1e52, 0xdcb4c4, 0x7c6f06, 0x001dd8, 0x0017fa,
|
||||
0x000a75, 0x0003ff, 0xf8e079, 0x1430c6, 0xe0757d, 0x9cd35b, 0x60af6d,
|
||||
0xb85a73, 0x103047, 0x109266, 0xb047bf, 0x7c0bc6, 0x804e81, 0x244b81,
|
||||
0x50a4c8, 0x8425db, 0xd8c4e9, 0x50c8e5, 0x446d6c, 0x38d40b, 0x647791,
|
||||
0x781fdb, 0x08fc88, 0x30c7ae, 0x18227e, 0x00f46f, 0x9ce6e7, 0xe498d1,
|
||||
0x5cca1a, 0x70288b, 0x4849c7, 0x205ef7, 0x182666, 0xc06599, 0xcc07ab,
|
||||
0xe84e84, 0x50fc9f, 0xe432cb, 0x889b39, 0xbcb1f3, 0x38ece4, 0xccf9e8,
|
||||
0xf0e77e, 0x5ce8eb, 0xb8d9ce, 0x70f927, 0x301966, 0x28bab5, 0x103b59,
|
||||
0x6cb7f4, 0x001ee1, 0x0018af, 0xbc72b1, 0x78f7be, 0xf49f54, 0x00214c,
|
||||
0x001632, 0xd0667b, 0x001377, 0x50b7c3, 0x8018a7, 0x444e1a, 0xe8e5d6,
|
||||
0x5492be, 0x101dc0, 0x0021d1, 0xcc2d8c, 0x949aa9, 0x20dbab, 0x5c9960,
|
||||
0x88b4a6, 0x2c5491, 0x5c70a3, 0x10f96f, 0xf01c13, 0x00aa70, 0xbcf5ac,
|
||||
0xccfa00, 0xf8a9d0, 0x805a04, 0x5caf06, 0xb81daa, 0x10f1f2, 0x0025e5,
|
||||
0x0022a9, 0xc49a02, 0x344df7, 0xd41a3f, 0xcc6ea4, 0xa46cf1, 0x0ca8a7,
|
||||
0x54b802, 0x24181d, 0xf4c248, 0xa8515b, 0xc048e6, 0xd07714, 0x2816a8,
|
||||
0x84a134, 0x1c9148, 0xc0ccf8, 0x80ed2c, 0xe8b2ac, 0x8489ad, 0x20768f,
|
||||
0x28ed6a, 0x34ab37, 0x60a37d, 0x0056cd, 0xbca920, 0x5082d5, 0x9c84bf,
|
||||
0x00b362, 0xf86214, 0xb0702d, 0xd0c5f3, 0x0023df, 0x0025bc, 0x00264a,
|
||||
0x0026b0, 0x041e64, 0xd49a20, 0x9027e4, 0x60334b, 0x5c5948, 0x60f445,
|
||||
0x5cf7e6, 0xa0d795, 0xcc088d, 0x8c8ef2, 0xf40f24, 0x24f677, 0x7867d7,
|
||||
0x5433cb, 0xd0d2b0, 0xd88f76, 0x3c2ef9, 0x7081eb, 0x086698, 0x9060f1,
|
||||
0x741bb2, 0x28cfe9, 0xe425e7, 0xb019c6, 0x58e28f, 0xac1f74, 0x48bf6b,
|
||||
0x245ba7, 0xdc56e7, 0x347c25, 0xd4909c, 0x080007, 0x000a95, 0x002241,
|
||||
0x18ee69, 0x748114, 0x18f643, 0xd0a637, 0xa01828, 0xd0034b, 0xa43135,
|
||||
0x9c35eb, 0x507a55, 0xa0999b, 0x24240e, 0x903c92, 0xa88e24, 0xe8802e,
|
||||
0x68ae20, 0xe0b52d, 0x80be05, 0xd8bb2c, 0xd04f7e, 0x2c1f23, 0x549f13,
|
||||
0xb8098a, 0xf0dbe2, 0x8c2937, 0xdc9b9c, 0x98f0ab, 0xf0dbf8, 0xaccf5c,
|
||||
0x3c15c2, 0x04489a, 0xd8cf9c, 0xa886dd, 0x54eaa8, 0xe4c63d, 0x843835,
|
||||
0xc06394, 0x8c006d, 0xb09fba, 0xdc86d8, 0x78ca39, 0x18e7f4, 0xb8ff61,
|
||||
0xdc2b61, 0x1093e9, 0x442a60, 0xe0f847, 0x145a05, 0x28cfda, 0x148fc6,
|
||||
0x283737, 0x045453, 0xf0cba1, 0x30f7c5, 0x008865, 0x40b395, 0x3090ab,
|
||||
0x1ce62b, 0xa0edcd, 0x842999, 0x74e2f5, 0x20c9d0, 0x7073cb, 0x9c207b,
|
||||
0x341298, 0x9c293f, 0x7c0191, 0x70480f, 0xa4b805, 0x587f57, 0x80d605,
|
||||
0xc869cd, 0xbc6c21, 0x0469f8, 0x749eaf, 0xb841a4, 0xf895ea, 0x50a67f,
|
||||
0x647033, 0x846878, 0x948bc1, 0x4827ea, 0x388c50, 0xa09347, 0xc8f230,
|
||||
0x1c77f6, 0xe44790, 0xd4503f, 0x40163b, 0x5c497d, 0xe47dbd, 0x503da1,
|
||||
0x508569, 0x1077b1, 0x5cf6dc, 0x380195, 0xbc1485, 0x88d50c, 0x947be7,
|
||||
0x54bd79, 0xdc44b6, 0x1007b6, 0xc0174d, 0xa407b6, 0x149f3c, 0xd868c3,
|
||||
0xc493d9, 0x00b5d0, 0x8c83e1, 0xfcb6d8, 0x6ce85c, 0x007c2d, 0xf47def,
|
||||
0x7c8bb5, 0xdcf756, 0x68dfdd, 0x64b473, 0x7451ba, 0x3480b3, 0x2082c0,
|
||||
0xfc64ba, 0xc46ab7, 0x00ec0a, 0x38e60a, 0x04e598, 0x2ca9f0, 0x586b14,
|
||||
0x94b01f, 0x94f6d6, 0x40bc60, 0xd85575, 0xd411a3, 0x6489f1, 0x04ba8d,
|
||||
0x489507, 0xa89ced, 0xc42ad0, 0xe0897e, 0x103025, 0x8c79f5, 0x90735a,
|
||||
};
|
||||
std::array<uint32_t, 1683> vendors = {
|
||||
0xa44519, 0x2446c8, 0xd0d003, 0x8cb84a, 0x608b0e, 0x88299c, 0x7c8956,
|
||||
0x201742, 0xd09c7a, 0xc4e39f, 0x2479f3, 0x8c79f5, 0xccd281, 0x88b291,
|
||||
0xc42ad0, 0xd81edd, 0xacf6f7, 0xc02e25, 0x64c2de, 0x58c6f0, 0x70bc10,
|
||||
0x2ca9f0, 0x586b14, 0xbcb863, 0x1040f3, 0x44e66e, 0xc0e862, 0xf40616,
|
||||
0x601d91, 0xd4c94b, 0x70bbe9, 0xf83880, 0x4c569d, 0x38539c, 0x402619,
|
||||
0x6ce85c, 0xe4b2fb, 0xd003df, 0xb4cb57, 0xfc039f, 0x18d717, 0x0057c1,
|
||||
0xa4d990, 0x20a60c, 0x08c5e1, 0x3c576c, 0xe4b021, 0x28ff3c, 0xf099b6,
|
||||
0x1094bb, 0x88e9fe, 0x94bf2d, 0xf86fc1, 0x38892c, 0x749eaf, 0x8035c1,
|
||||
0x2047da, 0xe4c483, 0xc048e6, 0x785dc8, 0x40cbc0, 0xc4618b, 0x08e689,
|
||||
0xdc56e7, 0x38e60a, 0xdcbfe9, 0xcc6ea4, 0xa46cf1, 0x08aed6, 0xa816d0,
|
||||
0x3408bc, 0x1c36bb, 0x3c2eff, 0xf06e0b, 0x24f677, 0xb0ca68, 0xc83c85,
|
||||
0x5433cb, 0x149f3c, 0x9ce063, 0xd03169, 0x7c6456, 0x084acf, 0xb8634d,
|
||||
0xa4e975, 0x3035ad, 0x844167, 0x9800c6, 0xac1f74, 0xa85c2c, 0x00db70,
|
||||
0x4c49e3, 0x389af6, 0xe0aa96, 0x507705, 0xa89675, 0x00ec0a, 0xc8d7b0,
|
||||
0x9097f3, 0x7c1c68, 0xc087eb, 0x388c50, 0xd4503f, 0x245ba7, 0x70f087,
|
||||
0xf0d7aa, 0x3096fb, 0x4827ea, 0x7c787e, 0x28395e, 0x38295a, 0x8cf5a3,
|
||||
0xd47ae2, 0xd8e0e1, 0xe44790, 0xb0702d, 0x6c19c0, 0xf01dbc, 0xf83f51,
|
||||
0x404e36, 0xdc0b34, 0x60a4d0, 0x008701, 0x5c9960, 0x2c3361, 0x101dc0,
|
||||
0x78471d, 0xa07591, 0x0cdfa4, 0x68ebae, 0x444e1a, 0x4844f7, 0x001377,
|
||||
0x002454, 0xe81132, 0x50b7c3, 0x1c5a3e, 0xa02195, 0xf4d9fb, 0x3c6200,
|
||||
0x00e3b2, 0x301966, 0x94350a, 0x0017d5, 0x001e7d, 0x001df6, 0xc06599,
|
||||
0xbc79ad, 0xf0e77e, 0xf008f1, 0xe47cf9, 0x58c38b, 0x001d25, 0x08fd0e,
|
||||
0x041bba, 0x889b39, 0xe432cb, 0x10d542, 0xa0821f, 0xf06bca, 0xac3613,
|
||||
0xbc8ccd, 0xd022be, 0xec9bf3, 0xf409d8, 0x4c3c16, 0x0073e0, 0x343111,
|
||||
0x4849c7, 0x849866, 0x9476b7, 0xc4438f, 0xa09169, 0x9893cc, 0x3ccd93,
|
||||
0x2021a5, 0x6cd68a, 0x002483, 0x001fe3, 0x2c54cf, 0x485929, 0x58a2b5,
|
||||
0x10f96f, 0x4c6641, 0xac3743, 0x28e31f, 0xecadb8, 0x9801a7, 0xb8bbaf,
|
||||
0x60c5ad, 0x24f094, 0x086d41, 0xe4faed, 0x288335, 0xdccf96, 0xccb11a,
|
||||
0xac61ea, 0x38b54d, 0x1c5cf2, 0xe0c767, 0x80ed2c, 0xa80600, 0xf05a09,
|
||||
0x503275, 0x08fc88, 0xf8d0bd, 0x94b10a, 0x3cbbfd, 0xa48431, 0xa0b4a5,
|
||||
0xe4f8ef, 0x78595e, 0x0c1420, 0x24f5aa, 0x988389, 0x84a466, 0xc4576e,
|
||||
0x508569, 0x489d24, 0xb07994, 0xa470d6, 0xc8f230, 0x8c0ee3, 0x28ed6a,
|
||||
0x38f23e, 0x902155, 0xd8b377, 0xa09347, 0xe8bba8, 0xb0aa36, 0xa4d18c,
|
||||
0x241eeb, 0xcc25ef, 0x28cfe9, 0x00a040, 0x003065, 0x3cd0f8, 0x680927,
|
||||
0x1093e9, 0x442a60, 0xc82a14, 0x3c0754, 0xa4b197, 0xa4d1d2, 0x28cfda,
|
||||
0x6cc26b, 0x44d884, 0x64200c, 0x001451, 0x001e52, 0x0021e9, 0x002608,
|
||||
0x0026b0, 0x0026bb, 0xd49a20, 0xf81edf, 0xcc08e0, 0xf0b479, 0x045453,
|
||||
0xe88d28, 0x949426, 0x207d74, 0xf4f15a, 0xc86f1d, 0x18af8f, 0xc8b5b7,
|
||||
0x90b21f, 0xb8e856, 0xd89695, 0x64a3cb, 0x30f7c5, 0x40b395, 0x44fb42,
|
||||
0x98fe94, 0xd8004d, 0x542696, 0xc8334b, 0x64e682, 0x9c207b, 0xb065bd,
|
||||
0x8c2daa, 0x848506, 0xf4f951, 0xc06394, 0x3090ab, 0x1499e2, 0xfce998,
|
||||
0x0cbc9f, 0x34363b, 0xd0a637, 0x789f70, 0xe0accb, 0xa0999b, 0x24240e,
|
||||
0x903c92, 0xd81d72, 0xd8bb2c, 0xd04f7e, 0x9cf387, 0xa85b78, 0xb418d1,
|
||||
0xf0dbf8, 0x48746e, 0x341298, 0x70e72c, 0x70ece4, 0x54ae27, 0xc8f650,
|
||||
0x68ae20, 0xac87a3, 0xa88e24, 0x2078f0, 0x70480f, 0xcc20e8, 0xf0b0e7,
|
||||
0x0469f8, 0x205531, 0xe8b4c8, 0xd087e2, 0xf05b7b, 0xb047bf, 0x7c0bc6,
|
||||
0x80c5e6, 0x5440ad, 0x804e81, 0xfc8f90, 0xe89120, 0x4480eb, 0x9cd35b,
|
||||
0xa89fba, 0x4886e8, 0x30d587, 0xec59e7, 0x2c2997, 0xd059e4, 0x14a364,
|
||||
0x7ced8d, 0x002538, 0x0022a1, 0x7cf31b, 0x0c2fb0, 0xf4d620, 0x8cf112,
|
||||
0x44aeab, 0xa4f05e, 0x28167f, 0xf887f1, 0x305714, 0xc8b1cd, 0x1460cb,
|
||||
0xb8f12a, 0x04c807, 0x20f478, 0x90735a, 0x00fa21, 0x7c2302, 0xd49dc0,
|
||||
0xe0dcff, 0x846fce, 0x804a14, 0x703c69, 0x489dd1, 0xb06fe0, 0xc08c71,
|
||||
0x60d0a9, 0x48fda3, 0xa45046, 0x007c2d, 0xb831b5, 0x14c213, 0xa4d931,
|
||||
0xbcfed9, 0x808223, 0x5029f5, 0x007204, 0xbca58b, 0x80ceb9, 0xe06267,
|
||||
0x082525, 0xf460e2, 0x1cc3eb, 0x00c3f4, 0x7836cc, 0x48605f, 0x2816a8,
|
||||
0x9c2ea1, 0xbce143, 0x647033, 0x846878, 0xc8d083, 0x6030d4, 0xf895ea,
|
||||
0x18f1d8, 0x30d9d9, 0x0cf346, 0x80ad16, 0xfc643a, 0xa8515b, 0xb4f7a1,
|
||||
0x88bd45, 0x54fcf0, 0x306a85, 0x4cdd31, 0xd0817a, 0x98ca33, 0x68ab1e,
|
||||
0x70ef00, 0xbcffeb, 0x0c1539, 0x88b4a6, 0x2c8a72, 0xd88f76, 0x409c28,
|
||||
0xd0b128, 0xbc5451, 0xec51bc, 0xf079e8, 0x58e28f, 0x787b8a, 0x88365f,
|
||||
0x2c4053, 0x3cf591, 0x602101, 0xacafb9, 0x041b6d, 0xecf342, 0x503da1,
|
||||
0x4c1a3d, 0x503237, 0xb0481a, 0xb49cdf, 0x48bf6b, 0x3c0518, 0x900628,
|
||||
0x9c84bf, 0x00b362, 0xe4e4ab, 0x60334b, 0xf4f524, 0xcc2d83, 0xfcd848,
|
||||
0xec107b, 0x1c232c, 0x0021d1, 0x001fcc, 0xec8892, 0x60a10a, 0x8c71f8,
|
||||
0xcc051b, 0x8c7712, 0x9463d1, 0x0021d2, 0x5c497d, 0x7825ad, 0xece09b,
|
||||
0xbc20a4, 0x08d42b, 0x789ed0, 0xb0c4e7, 0xa00798, 0x001fcd, 0x38ece4,
|
||||
0x945103, 0x002490, 0x0023d7, 0x549b12, 0xfca13e, 0x24c696, 0x94d771,
|
||||
0xe84e84, 0x001632, 0xe4e0c5, 0xc81479, 0x1caf05, 0x0016db, 0x001ee2,
|
||||
0x20d5bf, 0x5ce8eb, 0xc0bdd1, 0xb479a7, 0xb0df3a, 0x805719, 0x34be00,
|
||||
0x78521a, 0x38256b, 0x205ef7, 0x141f78, 0xb47443, 0x30766f, 0xa8922c,
|
||||
0xf80cf3, 0xc49a02, 0x001f6b, 0x0026e2, 0xa860b6, 0xc4b301, 0xe05f45,
|
||||
0x483b38, 0x1c9148, 0x5c70a3, 0x64cc2e, 0xf877b8, 0x182195, 0x44783e,
|
||||
0x30636b, 0xa4f1e8, 0x14bb6e, 0xe498d1, 0x6c2779, 0x28cc01, 0x6cf373,
|
||||
0x9c3aaf, 0x781fdb, 0x4ca56d, 0xb86ce8, 0x0cb319, 0x183f47, 0xb46293,
|
||||
0x50a4c8, 0x1867b0, 0x6c8336, 0x002557, 0x001ccc, 0xb4e1c4, 0xe0757d,
|
||||
0x34bb26, 0x806c1b, 0x2082c0, 0xdc6dcd, 0x440010, 0x0056cd, 0x00cdfe,
|
||||
0xe498d6, 0xf8db7f, 0x64a769, 0xe899c4, 0xbccfcc, 0xf431c3, 0x64a5c3,
|
||||
0xbc3aea, 0x7c1dd9, 0xa086c6, 0x9c99a0, 0x584498, 0x002332, 0x00236c,
|
||||
0x0023df, 0x002500, 0x0025bc, 0x0019e3, 0x001b63, 0x001ec2, 0x001ff3,
|
||||
0x0010fa, 0x0050e4, 0x000d93, 0x7cfadf, 0x78a3e4, 0x148fc6, 0x286ab8,
|
||||
0x28e02c, 0xe0b9ba, 0x00c610, 0xb8f6b1, 0x8cfaba, 0x7cd1c3, 0xf0dce2,
|
||||
0x24ab81, 0xe0f847, 0x28e7cf, 0xe4ce8f, 0xa82066, 0xbc52b7, 0x5c5948,
|
||||
0xc8bcc8, 0xe8040b, 0x145a05, 0x1caba7, 0xc0847a, 0x34159e, 0x58b035,
|
||||
0xdc86d8, 0x90b931, 0xd0e140, 0x24a2e1, 0x80ea96, 0x600308, 0x04f13e,
|
||||
0x98f0ab, 0x7831c1, 0x783a84, 0x5c8d4e, 0x8863df, 0x881fa1, 0xc8e0eb,
|
||||
0x98b8e3, 0x885395, 0x786c1c, 0x4c8d79, 0x1ce62b, 0x0c3021, 0x0c3e9f,
|
||||
0xfcfc48, 0x9c293f, 0x087402, 0x94f6a3, 0x98e0d9, 0xcc29f5, 0x285aeb,
|
||||
0xf02475, 0x2c1f23, 0x549f13, 0xf0dbe2, 0x748114, 0x18f643, 0xa45e60,
|
||||
0xa01828, 0xd0034b, 0x10417f, 0xa8667f, 0xd02598, 0x80be05, 0x24a074,
|
||||
0x84788b, 0x587f57, 0x006d52, 0xacee9e, 0xb857d8, 0xb844d9, 0x1c56fe,
|
||||
0xac5a14, 0x08eca9, 0xf8cfc5, 0x7840e4, 0xe09971, 0x10d38a, 0x206274,
|
||||
0xd48f33, 0x20a99b, 0x6077e2, 0xfc1910, 0x3ca10d, 0x646cb2, 0x680571,
|
||||
0x14b484, 0x3059b7, 0xa43d78, 0x00eebd, 0x502e5c, 0x980d2e, 0xd4206d,
|
||||
0x7c1e52, 0xdcb4c4, 0x7c6f06, 0x749ef5, 0x68bfc4, 0x04b1a1, 0xcc464e,
|
||||
0x507ac5, 0x6cd71f, 0x4c6be8, 0x8c861e, 0x542b8d, 0x8ce5c0, 0xf08a76,
|
||||
0xecaa25, 0x9078b2, 0xbc7fa4, 0x687d6b, 0x485169, 0xa8db03, 0x60ab67,
|
||||
0x4418fd, 0x005b94, 0xe0897e, 0xa8346a, 0x3c20f6, 0x7c38ad, 0x885a06,
|
||||
0x2c5d34, 0x7c035e, 0xd467d3, 0xa41232, 0x64c753, 0x38f9d3, 0xfc183c,
|
||||
0xf47def, 0x7c8bb5, 0x3830f9, 0x90e17b, 0xd81c79, 0x58e6ba, 0x1801f1,
|
||||
0x9c0cdf, 0x14c697, 0x7c03ab, 0x00b5d0, 0x1496e5, 0xd07fa0, 0x7c6b9c,
|
||||
0x108ee0, 0xfca621, 0xd832e3, 0x9487e0, 0x4466fc, 0x50a009, 0x50a67f,
|
||||
0xd461da, 0xb841a4, 0x9ce65e, 0xc49880, 0xe0338e, 0xf01898, 0x881908,
|
||||
0x5c0947, 0x14205e, 0x08f69c, 0x641cae, 0x003de8, 0x48c796, 0xf4c248,
|
||||
0xf47190, 0x2802d8, 0x24181d, 0x641cb0, 0x54b802, 0xd4909c, 0xe4e0a6,
|
||||
0x00e091, 0x503cea, 0xb4f1da, 0x80b03d, 0xe49adc, 0xace4b5, 0xf06d78,
|
||||
0xd0d2b0, 0x448f17, 0x1cddea, 0x78886d, 0x20ee28, 0xb4f61c, 0x08f4ab,
|
||||
0x8c8590, 0x6c96cf, 0x508f4c, 0xd463c6, 0xdc44b6, 0x1007b6, 0x342d0d,
|
||||
0x54bd79, 0x30074d, 0x947be7, 0x5092b9, 0xdc74a8, 0x88d50c, 0xc4ae12,
|
||||
0x989e63, 0x886b6e, 0xd4dccd, 0x484baa, 0xd4ae05, 0xdca904, 0x6cab31,
|
||||
0x4c74bf, 0x5082d5, 0xf0ee10, 0xb81daa, 0x5caf06, 0x64b0a6, 0x7c04d0,
|
||||
0x84fcac, 0xdc0c5c, 0x70700d, 0x186590, 0xf86214, 0x784f43, 0x404d7f,
|
||||
0x1c48ce, 0x6c5c14, 0xcc61e5, 0x609ac1, 0x20dbab, 0x748d08, 0x9c8ba0,
|
||||
0xcc088d, 0x38a4ed, 0x0007ab, 0xe8e5d6, 0xc87e75, 0x00265f, 0x00233a,
|
||||
0x382dd1, 0x10ddb1, 0x00166c, 0x001599, 0x0012fb, 0xd0667b, 0x1c66aa,
|
||||
0x1489fd, 0xbc851f, 0x002491, 0x3c8bfe, 0xd4e8b2, 0xe8039a, 0x30cda7,
|
||||
0x2c4401, 0xb8d9ce, 0x002339, 0x5001bb, 0x001247, 0x0015b9, 0xb85e7b,
|
||||
0x1c77f6, 0x742344, 0xc8ba94, 0x843838, 0x54880e, 0xf025b7, 0xe492fb,
|
||||
0x6cb7f4, 0x181eb0, 0x5c3c27, 0xbc72b1, 0x78f7be, 0x684898, 0x3423ba,
|
||||
0x400e85, 0x88797e, 0xd013fd, 0x888322, 0xe89309, 0x6cd032, 0x3cbdd8,
|
||||
0x78c3e9, 0x64899a, 0xf8a9d0, 0xccfa00, 0xa816b2, 0x64bc0c, 0x74a722,
|
||||
0xf01c13, 0x344df7, 0x583f54, 0xc01ada, 0x8c1abf, 0x30cbf8, 0xa0cbfd,
|
||||
0xe45d75, 0x408805, 0x98398e, 0xd0fccc, 0xc09727, 0x84a134, 0x0c5101,
|
||||
0x2cf0a2, 0x68fb7e, 0x6c2483, 0x5cca1a, 0xac0d1b, 0x0034da, 0x202d07,
|
||||
0xb44bd2, 0xdc415f, 0x102ab3, 0xe8b2ac, 0xe49a79, 0xf45c89, 0x20768f,
|
||||
0x300d43, 0x607edd, 0x08373d, 0xc488e5, 0x1077b1, 0x64b853, 0x389496,
|
||||
0x5056bf, 0x90f1aa, 0x74458a, 0xfcc734, 0x8425db, 0xb0ec71, 0xe458b8,
|
||||
0x088c2c, 0xa49a58, 0x08ee8b, 0x68ed43, 0x70aab2, 0x000f86, 0xf8e079,
|
||||
0xccc3ea, 0x40786a, 0x38cada, 0x34ab37, 0x18af61, 0x5cf938, 0x002376,
|
||||
0x38e7d8, 0x188796, 0xb4cef6, 0xcc4463, 0x6c72e7, 0x741bb2, 0xf8a45f,
|
||||
0x640980, 0x185936, 0x60fec5, 0xe425e7, 0x7c6d62, 0x40d32d, 0xc42c03,
|
||||
0x9027e4, 0xbc926b, 0x101c0c, 0x080007, 0x0016cb, 0x0017f2, 0x001f5b,
|
||||
0x002436, 0x00254b, 0x6c3e6d, 0xbc6778, 0x20c9d0, 0x68967b, 0x581faa,
|
||||
0x88c663, 0xa46706, 0x8c5877, 0xa8fad8, 0x008865, 0xbc3baf, 0x3ce072,
|
||||
0x84fcfe, 0xe48b7f, 0xd8d1cb, 0xb817c2, 0x7c11be, 0x98d6bb, 0x283737,
|
||||
0x50ead6, 0x189efc, 0x804971, 0x7cf05f, 0x109add, 0x848e0c, 0x3c15c2,
|
||||
0x6c709f, 0x6476ba, 0x34e2fd, 0x04489a, 0x80e650, 0x90fd61, 0x2cf0ee,
|
||||
0x5c97f3, 0x8c2937, 0xaccf5c, 0x80006e, 0xa4c361, 0xb09fba, 0x0c4de9,
|
||||
0xe0f5c6, 0xa0edcd, 0x087045, 0xa88808, 0xc0f2fb, 0x24e314, 0xf0f61c,
|
||||
0x38484c, 0x38c986, 0xd03311, 0xd4f46f, 0x48437c, 0x34a395, 0x787e61,
|
||||
0x60f81d, 0x5cf5da, 0x18ee69, 0x649abe, 0xac293a, 0x9cfc01, 0x9c35eb,
|
||||
0xf099bf, 0x94e96a, 0x507a55, 0x5882a8, 0x24da9b, 0xe83a12, 0x80656d,
|
||||
0x38d40b, 0x209bcd, 0xfcf136, 0x18895b, 0x7cf90e, 0x50f0d3, 0x78bdbc,
|
||||
0x84119e, 0xe4907e, 0x149a10, 0x485073, 0x244b03, 0x74e28c, 0x244b81,
|
||||
0x60af6d, 0xb85a73, 0x981dfa, 0x102f6b, 0xc44202, 0x103047, 0xf884f2,
|
||||
0x5c2e59, 0xe0cbee, 0x002248, 0x8031f0, 0xe0d083, 0xd80b9a, 0x5c666c,
|
||||
0xc4e1a1, 0x1855e3, 0xe450eb, 0x886440, 0x6070c0, 0xf0c371, 0x987a14,
|
||||
0xc83ddc, 0x845733, 0x1819d6, 0xbc98df, 0x70dda8, 0x4c6f9c, 0x4883b4,
|
||||
0x0017fa, 0x941625, 0x34a8eb, 0xa483e7, 0xf4afe7, 0xac88fd, 0x20326c,
|
||||
0x6489f1, 0x2034fb, 0xa89ced, 0xe458e7, 0xdc080f, 0xf8e94e, 0xec2ce2,
|
||||
0x40bc60, 0xe83617, 0x9c648b, 0x344262, 0x14d00d, 0x703a51, 0x04e598,
|
||||
0x6cc7ec, 0xc0bdc8, 0x647bce, 0xa887b3, 0x6c006b, 0x24fce5, 0x9caa1b,
|
||||
0x70fd46, 0x8c83e1, 0x889f6f, 0x482ca0, 0x0ccb85, 0x08d46a, 0x68e7c2,
|
||||
0x58b10f, 0x645aed, 0xc0b658, 0x48a91c, 0x50bc96, 0xfc2a9c, 0xa056f3,
|
||||
0x549963, 0x90dd5d, 0xc819f7, 0x3880df, 0x3cdcbc, 0x804e70, 0xd4e6b7,
|
||||
0x04d13a, 0xc48466, 0x347c25, 0xcc2db7, 0x0c9838, 0xd41a3f, 0x5c865c,
|
||||
0x04b167, 0xec8350, 0x2c5491, 0xe42b34, 0x3c2ef9, 0xa04ea7, 0xf0989d,
|
||||
0xd80831, 0x10f1f2, 0x982d68, 0xb019c6, 0x3866f0, 0x703eac, 0x7c2edd,
|
||||
0x3cf7a4, 0x986f60, 0xc49ded, 0x9810e8, 0xc0d012, 0xbca920, 0x48a195,
|
||||
0xf80377, 0x8058f8, 0xdca4ca, 0x8c8fe9, 0x5cba37, 0x2c200b, 0x8866a5,
|
||||
0xacc1ee, 0x805a04, 0xbc8385, 0x2c598a, 0xe47dbd, 0x001cb3, 0x24920e,
|
||||
0xfc4203, 0xa01081, 0xf07960, 0xa0d795, 0xbc4760, 0x04180f, 0x2013e0,
|
||||
0x002566, 0xc09f05, 0x606bbd, 0x00214c, 0x0018af, 0x001ee1, 0x00166b,
|
||||
0x0000f0, 0x8cc8cd, 0xa8f274, 0xd487d8, 0x184617, 0x380a94, 0xd0dfc7,
|
||||
0xd0c1b1, 0x8018a7, 0xf47b5e, 0x70f927, 0xc45006, 0x88329b, 0x1449e0,
|
||||
0xd02544, 0xbc4486, 0x20d390, 0x9401c2, 0x50fc9f, 0x380b40, 0xb8ff61,
|
||||
0xf0728c, 0x34aa8b, 0x24dbed, 0x68c44d, 0x440444, 0x84b541, 0x006f64,
|
||||
0xdc6672, 0xf8e61a, 0xcc2d8c, 0x98d6f7, 0x700514, 0xe892a4, 0x10683f,
|
||||
0x40b0fa, 0x0025e5, 0x0021fb, 0x34fcef, 0xbcf5ac, 0x0c4885, 0x0022a9,
|
||||
0x9c2a83, 0xa039f7, 0xb0e235, 0x14c913, 0xe09861, 0xa06090, 0xbc765e,
|
||||
0xd85b2a, 0x90c1c6, 0x70a2b3, 0xf40f24, 0x4c57ca, 0xc46ab7, 0x48e9f1,
|
||||
0xc83f26, 0x40163b, 0xc83870, 0x6c8fb5, 0x1c9e46, 0xc0ccf8, 0x9c4fda,
|
||||
0x8489ad, 0x647791, 0x9ce6e7, 0x9c0298, 0x28987b, 0x54fa3e, 0x0c8910,
|
||||
0x78abbb, 0xd8c4e9, 0xbcd11f, 0xf4428f, 0x446d6c, 0x00f46f, 0x0c715d,
|
||||
0x34bb1f, 0x406f2a, 0x985fd3, 0x60beb5, 0xf8f1b6, 0xf4f1e1, 0x9cd917,
|
||||
0x9068c3, 0x68dbca, 0x086698, 0xbc5436, 0x044bed, 0x6c8dc1, 0x0cd746,
|
||||
0x60a37d, 0xd40b1a, 0xfc64ba, 0x9060f1, 0xa4516f, 0x68dfdd, 0x98fae3,
|
||||
0xf0b429, 0xb8782e, 0x000502, 0x000a95, 0x00264a, 0x041e64, 0x001124,
|
||||
0x002241, 0x7cc537, 0x78ca39, 0x18e7f4, 0x70cd60, 0x8c7b9d, 0xd89e3f,
|
||||
0xb8c75d, 0x0c74c2, 0x403004, 0x842999, 0x74e2f5, 0xe0c97a, 0x68a86d,
|
||||
0x7cc3a1, 0x7073cb, 0x90840d, 0xe80688, 0xec852f, 0x00f4b9, 0x5c95ae,
|
||||
0x9803d8, 0x60c547, 0x685b35, 0x2cb43a, 0x689c70, 0x380f4a, 0x3010e4,
|
||||
0xa886dd, 0x444c0c, 0xb4f0ab, 0x80929f, 0x9c04eb, 0x5c969d, 0x609217,
|
||||
0x84b153, 0xe06678, 0x48d705, 0x041552, 0xcc785f, 0x88cb87, 0xf0c1f1,
|
||||
0x843835, 0x8c006d, 0xa8968a, 0xf41ba1, 0x60d9c7, 0x3cab8e, 0xf82793,
|
||||
0x907240, 0x908d6c, 0xb8098a, 0x4c7c5f, 0x68644b, 0xc81ee7, 0xa43135,
|
||||
0x68d93c, 0x00f76f, 0xc88550, 0x7014a6, 0x985aeb, 0x78d75f, 0xe0b52d,
|
||||
0x6c94f8, 0xc0cecd, 0x2cae2b, 0xc869cd, 0xa4b805, 0x5cadcf, 0xbc6c21,
|
||||
0xf40e22, 0x544e90, 0xc01173, 0xbce63f, 0x7c9122, 0xacbc32, 0x2827bf,
|
||||
0x800184, 0x8cbfa6, 0xc8a823, 0xb0c559, 0xbc1485, 0x9c6c15, 0xc0335e,
|
||||
0xd0929e, 0x083d88, 0x608f5c, 0x109266, 0x281878, 0x847a88, 0xa0f450,
|
||||
0xa826d9, 0x00155d, 0x00125a, 0x000d3a, 0x0003ff, 0x18d0c5, 0x1cccd6,
|
||||
0x582059, 0x74e1b6, 0xf40e01, 0x1495ce, 0x50de06, 0xcc660a, 0xfc1d43,
|
||||
0x0024e9, 0xb4c4fc, 0x7cd661, 0x98b8ba, 0x103025, 0xb8b2f8, 0x98460a,
|
||||
0xb85d0a, 0x7c9a1d, 0x5462e2, 0x149d99, 0x489507, 0xd85575, 0xd411a3,
|
||||
0x04ba8d, 0xe446da, 0x58d9c3, 0x3c8375, 0xb8bc5b, 0xd8ce3a, 0xb8c74a,
|
||||
0x94f6d6, 0xf82d7c, 0xc09ad0, 0x94b01f, 0x90633b, 0xfcaab6, 0x782327,
|
||||
0xdcf756, 0x74b587, 0xfcb6d8, 0x18810e, 0x608c4a, 0x241b7a, 0x8cfe57,
|
||||
0xc0a600, 0xa823fe, 0x1c427d, 0xcc2119, 0x304b07, 0x000393, 0x702ad5,
|
||||
0x74eb80, 0x0ce0dc, 0xd868c3, 0xc493d9, 0xa82bb9, 0x1c1ac0, 0x88ae07,
|
||||
0x40831d, 0xdcd3a2, 0x5c1dd9, 0x68fef7, 0xd07714, 0x587a6a, 0x705aac,
|
||||
0x685acf, 0x0ca8a7, 0x2c61f6, 0xd4a33d, 0xf0766f, 0x4098ad, 0x6c4d73,
|
||||
0x68ef43, 0xd02b20, 0xd86375, 0x30b4b8, 0x9c8c6e, 0x18f0e4, 0x00bf61,
|
||||
0xd00401, 0xdc5583, 0xb8c111, 0x9ce33f, 0x7867d7, 0x087808, 0x887598,
|
||||
0xc0174d, 0xa407b6, 0x04d6aa, 0x08152f, 0xf4f5db, 0xc0a53e, 0xecd09f,
|
||||
0xa8be27, 0x94d029, 0x308454, 0x5c5181, 0x608e08, 0x4c189a, 0x58c5cb,
|
||||
0xb4bff6, 0x74f61c, 0x84c0ef, 0xa8b86e, 0xc40bcb, 0xb83765, 0x14bd61,
|
||||
0xc0d3c0, 0x948bc1, 0x14568e, 0xd4619d, 0x7c5049, 0x64b473, 0x7451ba,
|
||||
0x7802f8, 0xec01ee, 0x682737, 0x58404e, 0xd0c5f3, 0xbc9fef, 0x20ab37,
|
||||
0x60f445, 0x2c0e3d, 0x88e87f, 0x9cf48e, 0x5cf7e6, 0xb853ac, 0x203cae,
|
||||
0x2cbaba, 0x40d3ae, 0xa03be3, 0x4c3275, 0x3816d1, 0xd0176a, 0xd48890,
|
||||
0x5492be, 0x949aa9, 0x001c43, 0x002399, 0x0017c9, 0x7cf854, 0xc4731e,
|
||||
0xec1f72, 0xe4121d, 0xe8508b, 0xf8042e, 0x0023d6, 0x001b98, 0x001a8a,
|
||||
0x3c5a37, 0xf49f54, 0x34c3ac, 0x44f459, 0x00265d, 0x002567, 0xbcb1f3,
|
||||
0xc462ea, 0x182666, 0x30d6c9, 0xcc07ab, 0x1c62b8, 0xccf9e8, 0xd857ef,
|
||||
0x18e2c2, 0x28bab5, 0xe440e2, 0x103b59, 0xd890e8, 0x9852b1, 0x14f42a,
|
||||
0x0808c2, 0xccfe3c, 0xb43a28, 0x78a873, 0xd83062, 0xc041f6, 0x001e75,
|
||||
0x001c62, 0xf895c7, 0x34145f, 0x0821ef, 0x505527, 0x88c9d0, 0x8c3ae3,
|
||||
0x00aa70, 0x60e3ac, 0x4c0bbe, 0xb88d12, 0x845181, 0x348a7b, 0x78009e,
|
||||
0xacc33a, 0x54f201, 0x70288b, 0x8c8ef2, 0x90b0ed, 0x04d3cf, 0x1c3ade,
|
||||
0x509ea7, 0xa88195, 0x88add2, 0xac5f3e, 0xb48b19, 0xbcec5d, 0x28a02b,
|
||||
0xb8c68e, 0x04fe31, 0x4cbca5, 0xd831cf, 0x188331, 0x9c65b0, 0x8455a5,
|
||||
0xa87c01, 0x50f520, 0x64b310, 0xa4ebd3, 0xb0d09c, 0x50c8e5, 0x5cf6dc,
|
||||
0x0026ff, 0xa4e4b8, 0xf40b93, 0x1c69a5, 0x94ebcd, 0x141aa3, 0x1430c6,
|
||||
0x88074b, 0x3871de, 0x7081eb, 0x78f882, 0x606944, 0x807abf, 0x00092d,
|
||||
0x7c6193, 0x0452f3, 0x90e7c4, 0xa81b5a, 0x2c5bb8, 0xacf7f3, 0xd4970b,
|
||||
0x8cbebe, 0x14f65a, 0x009ec8, 0x0c1daf, 0x3480b3, 0xf48b32, 0x60fb42,
|
||||
0x64b9e8, 0xd8a25e, 0x000a27, 0x001d4f, 0x002312, 0x60facd, 0x003ee1,
|
||||
0xfc253f, 0x183451, 0x0c771a, 0x286aba, 0x3451c9, 0x406c8f, 0xd023db,
|
||||
0x70dee2, 0x5855ca, 0xdc2b61, 0x40a6d9, 0x4cb199, 0xc09f42, 0x705681,
|
||||
0x040cce, 0x403cfc, 0x4860bc, 0xf0cba1, 0x182032, 0x34c059, 0xf0d1a9,
|
||||
0x14109f, 0x04f7e4, 0xdc9b9c, 0x54724f, 0x8c7c92, 0xb03495, 0x042665,
|
||||
0xec3586, 0x54eaa8, 0x28e14c, 0xe4c63d, 0x54e43a, 0x04db56, 0x04e536,
|
||||
0xe8802e, 0x006171, 0x6c4008, 0x7c6df8, 0x78fd94, 0x2cbe08, 0xac3c0b,
|
||||
0x701124, 0xf437b7, 0xd8cf9c, 0xa8bbcf, 0xac7f3e, 0x280b5c, 0xacfdec,
|
||||
0x28f076, 0x20a2e4, 0xbc4cc4, 0xdc3714, 0x40331a, 0xccc760, 0x7c0191,
|
||||
0x84100d, 0x80d605, 0xdc2b2a, 0x48137e, 0x382de8, 0xc08997, 0x04c23e,
|
||||
0x380195, 0xb4ae2b, 0x5c5188, 0x0ce725, 0xe0db10, 0x1432d1, 0x1816c9,
|
||||
0x842e27, 0x0c413e, 0x9000db, 0xb4ef39, 0xc808e9, 0x183a2d, 0x8463d6,
|
||||
0xb84fd5, 0xc0eefb, 0x206e9c, 0x6c2f2c, 0x18227e, 0x30c7ae, 0x501ac5,
|
||||
0x6045bd, 0x1cb094, 0xe85b5b, 0x0025ae, 0x001dd8, 0x000a75, 0xa4c939,
|
||||
0xc0dcda, 0x04b429, 0x48794d,
|
||||
};
|
||||
|
@ -28,6 +28,8 @@ halfile = generic.h
|
||||
;halfile = wemos32oled.h
|
||||
;halfile = wemos32matrix.h
|
||||
;halfile = octopus32.h
|
||||
;halfile = tinypico.h
|
||||
;halfile = tinypicomatrix.h
|
||||
|
||||
[platformio]
|
||||
; upload firmware to board with usb cable
|
||||
@ -40,7 +42,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.7.841
|
||||
release_version = 1.7.93
|
||||
; 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
|
||||
|
@ -5,8 +5,9 @@
|
||||
// Local logging tag
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
bmeStatus_t bme_status;
|
||||
TaskHandle_t BmeTask;
|
||||
bmeStatus_t bme_status = {0};
|
||||
|
||||
Ticker bmecycler;
|
||||
|
||||
#define SEALEVELPRESSURE_HPA (1013.25)
|
||||
|
||||
@ -37,6 +38,8 @@ Adafruit_BME280 bme; // I2C
|
||||
|
||||
#endif
|
||||
|
||||
void bmecycle() { xTaskNotify(irqHandlerTask, BME_IRQ, eSetBits); }
|
||||
|
||||
// initialize BME680 sensor
|
||||
int bme_init(void) {
|
||||
|
||||
@ -106,6 +109,8 @@ int bme_init(void) {
|
||||
|
||||
finish:
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
if (rc)
|
||||
bmecycler.attach(BMECYCLE, bmecycle);
|
||||
return rc;
|
||||
|
||||
} // bme_init()
|
||||
@ -136,47 +141,37 @@ int checkIaqSensorStatus(void) {
|
||||
} // checkIaqSensorStatus()
|
||||
#endif
|
||||
|
||||
// loop function which reads and processes data based on sensor settings
|
||||
void bme_loop(void *pvParameters) {
|
||||
|
||||
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
||||
// store current BME sensor data in struct
|
||||
void bme_storedata(bmeStatus_t *bme_store) {
|
||||
if (I2C_MUTEX_LOCK()) { // block i2c bus access
|
||||
|
||||
#ifdef HAS_BME680
|
||||
while (1) {
|
||||
// block i2c bus access
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
if (iaqSensor.run()) { // If new data is available
|
||||
bme_status.raw_temperature =
|
||||
iaqSensor.rawTemperature; // Temperature in degree celsius
|
||||
bme_status.raw_humidity = iaqSensor.rawHumidity;
|
||||
bme_status.temperature = iaqSensor.temperature;
|
||||
bme_status.humidity =
|
||||
iaqSensor.humidity; // Humidity in % relative humidity x1000
|
||||
bme_status.pressure = // Pressure in Pascal
|
||||
(iaqSensor.pressure / 100.0); // conversion Pa -> hPa
|
||||
bme_status.iaq = iaqSensor.iaqEstimate;
|
||||
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
|
||||
bme_status.gas = iaqSensor.gasResistance; // Gas resistance in Ohms
|
||||
updateState();
|
||||
}
|
||||
I2C_MUTEX_UNLOCK();
|
||||
if (iaqSensor.run()) { // if new data is available
|
||||
bme_store->raw_temperature =
|
||||
iaqSensor.rawTemperature; // temperature in degree celsius
|
||||
bme_store->raw_humidity = iaqSensor.rawHumidity;
|
||||
bme_store->temperature = iaqSensor.temperature;
|
||||
bme_store->humidity =
|
||||
iaqSensor.humidity; // humidity in % relative humidity x1000
|
||||
bme_store->pressure = // pressure in Pascal
|
||||
(iaqSensor.pressure / 100.0); // conversion Pa -> hPa
|
||||
bme_store->iaq = iaqSensor.iaqEstimate;
|
||||
bme_store->iaq_accuracy = iaqSensor.iaqAccuracy;
|
||||
bme_store->gas = iaqSensor.gasResistance; // gas resistance in ohms
|
||||
updateState();
|
||||
}
|
||||
}
|
||||
#elif defined HAS_BME280
|
||||
while (1) {
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
bme_status.temperature = bme.readTemperature();
|
||||
bme_status.pressure =
|
||||
(bme.readPressure() / 100.0); // conversion Pa -> hPa
|
||||
// bme.readAltitude(SEALEVELPRESSURE_HPA);
|
||||
bme_status.humidity = bme.readHumidity();
|
||||
bme_status.iaq = 0; // IAQ feature not present with BME280
|
||||
I2C_MUTEX_UNLOCK();
|
||||
}
|
||||
}
|
||||
bme_store->temperature = bme.readTemperature();
|
||||
bme_store->pressure = (bme.readPressure() / 100.0); // conversion Pa -> hPa
|
||||
// bme.readAltitude(SEALEVELPRESSURE_HPA);
|
||||
bme_store->humidity = bme.readHumidity();
|
||||
bme_store->iaq = 0; // IAQ feature not present with BME280
|
||||
#endif
|
||||
|
||||
} // bme_loop()
|
||||
I2C_MUTEX_UNLOCK(); // release i2c bus access
|
||||
}
|
||||
|
||||
} // bme_storedata()
|
||||
|
||||
#ifdef HAS_BME680
|
||||
void loadState(void) {
|
||||
|
@ -23,25 +23,23 @@ void doHousekeeping() {
|
||||
if (cfg.runmode == 1)
|
||||
do_reset();
|
||||
|
||||
#ifdef HAS_SPI
|
||||
spi_housekeeping();
|
||||
#endif
|
||||
#if (HAS_LORA)
|
||||
lora_housekeeping();
|
||||
#endif
|
||||
|
||||
// task storage debugging //
|
||||
ESP_LOGD(TAG, "IRQhandler %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(irqHandlerTask),
|
||||
eTaskGetState(irqHandlerTask));
|
||||
#if (HAS_LORA)
|
||||
ESP_LOGD(TAG, "LMiCtask %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(lmicTask), eTaskGetState(lmicTask));
|
||||
#endif
|
||||
#if (HAS_GPS)
|
||||
ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask));
|
||||
#endif
|
||||
#if (HAS_BME)
|
||||
ESP_LOGD(TAG, "Bmeloop %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(BmeTask), eTaskGetState(BmeTask));
|
||||
#ifdef HAS_SPI
|
||||
ESP_LOGD(TAG, "spiloop %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(spiTask), eTaskGetState(spiTask));
|
||||
#endif
|
||||
|
||||
#if (defined HAS_DCF77 || defined HAS_IF482)
|
||||
ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d",
|
||||
uxTaskGetStackHighWaterMark(ClockTask), eTaskGetState(ClockTask));
|
||||
@ -59,16 +57,15 @@ void doHousekeeping() {
|
||||
ESP_LOGI(TAG, "Voltage: %dmV", batt_voltage);
|
||||
#endif
|
||||
|
||||
// display BME sensor data
|
||||
// display BME680/280 sensor data
|
||||
#if (HAS_BME)
|
||||
#ifdef HAS_BME680
|
||||
ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f | IAQacc: %d",
|
||||
bme_status.temperature, bme_status.iaq, bme_status.iaq_accuracy);
|
||||
#endif
|
||||
|
||||
// display BME280 sensor data
|
||||
#ifdef HAS_BME280
|
||||
#elif defined HAS_BME280
|
||||
ESP_LOGI(TAG, "BME280 Temp: %.2f°C | Humidity: %.2f | Pressure: %.0f",
|
||||
bme_status.temperature, bme_status.humidity, bme_status.pressure);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// check free heap memory
|
||||
|
@ -5,14 +5,19 @@
|
||||
// Local logging tag
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
// we use NMEA $GPZDA sentence field 1 for time synchronization
|
||||
// $GPZDA gives time for preceding pps pulse, but does not has a constant offset
|
||||
TinyGPSPlus gps;
|
||||
gpsStatus_t gps_status;
|
||||
TinyGPSCustom gpstime(gps, "GPZDA", 1); // field 1 = UTC time
|
||||
static const String ZDA_Request = "$EIGPQ,ZDA*39\r\n";
|
||||
|
||||
gpsStatus_t gps_status = {0};
|
||||
TaskHandle_t GpsTask;
|
||||
|
||||
#ifdef GPS_SERIAL
|
||||
HardwareSerial GPS_Serial(1); // use UART #1
|
||||
static uint16_t nmea_txDelay_ms =
|
||||
tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS;
|
||||
(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL) / portTICK_PERIOD_MS);
|
||||
#else
|
||||
static uint16_t nmea_txDelay_ms = 0;
|
||||
#endif
|
||||
@ -27,7 +32,7 @@ int gps_init(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined GPS_SERIAL
|
||||
#ifdef GPS_SERIAL
|
||||
GPS_Serial.begin(GPS_SERIAL);
|
||||
ESP_LOGI(TAG, "Using serial GPS");
|
||||
#elif defined GPS_I2C
|
||||
@ -55,11 +60,11 @@ int gps_config() {
|
||||
int rslt = 1; // success
|
||||
#if defined GPS_SERIAL
|
||||
|
||||
/* to come */
|
||||
/* insert user configuration here, if needed */
|
||||
|
||||
#elif defined GPS_I2C
|
||||
|
||||
/* to come */
|
||||
/* insert user configuration here, if needed */
|
||||
|
||||
#endif
|
||||
return rslt;
|
||||
@ -68,7 +73,7 @@ int gps_config() {
|
||||
// store current GPS location data in struct
|
||||
void gps_storelocation(gpsStatus_t *gps_store) {
|
||||
if (gps.location.isUpdated() && gps.location.isValid() &&
|
||||
(gps.time.age() < 1500)) {
|
||||
(gps.location.age() < 1500)) {
|
||||
gps_store->latitude = (int32_t)(gps.location.lat() * 1e6);
|
||||
gps_store->longitude = (int32_t)(gps.location.lng() * 1e6);
|
||||
gps_store->satellites = (uint8_t)gps.satellites.value();
|
||||
@ -77,40 +82,55 @@ void gps_storelocation(gpsStatus_t *gps_store) {
|
||||
}
|
||||
}
|
||||
|
||||
// store current GPS timedate in struct
|
||||
void IRAM_ATTR gps_storetime(gpsStatus_t *gps_store) {
|
||||
// function to fetch current time from struct; note: this is costly
|
||||
time_t fetch_gpsTime(uint16_t *msec) {
|
||||
|
||||
if (gps.time.isUpdated() && gps.date.isValid() && (gps.time.age() < 1000)) {
|
||||
time_t time_sec = 0;
|
||||
|
||||
// nmea telegram serial delay compensation; not sure if we need this?
|
||||
/*
|
||||
if (gps.time.age() > nmea_txDelay_ms)
|
||||
gps_store->timedate.Second = gps.time.second() + 1;
|
||||
else
|
||||
gps_store->timedate.Second = gps.time.second();
|
||||
*/
|
||||
// poll NMEA $GPZDA sentence
|
||||
#ifdef GPS_SERIAL
|
||||
GPS_Serial.print(ZDA_Request);
|
||||
// wait for gps NMEA answer
|
||||
vTaskDelay(tx_Ticks(NMEA_FRAME_SIZE, GPS_SERIAL));
|
||||
#elif defined GPS_I2C
|
||||
Wire.print(ZDA_Request);
|
||||
#endif
|
||||
|
||||
gps_store->timedate.Second = gps.time.second();
|
||||
gps_store->timedate.Minute = gps.time.minute();
|
||||
gps_store->timedate.Hour = gps.time.hour();
|
||||
gps_store->timedate.Day = gps.date.day();
|
||||
gps_store->timedate.Month = gps.date.month();
|
||||
gps_store->timedate.Year =
|
||||
// did we get a current time?
|
||||
if (gpstime.isUpdated() && gpstime.isValid()) {
|
||||
|
||||
tmElements_t tm;
|
||||
|
||||
String rawtime = gpstime.value();
|
||||
uint32_t time_bcd = rawtime.toFloat() * 100;
|
||||
uint32_t delay_ms =
|
||||
gpstime.age() + nmea_txDelay_ms + NMEA_COMPENSATION_FACTOR;
|
||||
uint8_t year =
|
||||
CalendarYrToTm(gps.date.year()); // year offset from 1970 in microTime.h
|
||||
|
||||
} else
|
||||
gps_store->timedate = {0};
|
||||
}
|
||||
ESP_LOGD(TAG, "time [bcd]: %u", time_bcd);
|
||||
|
||||
// function to fetch current time from struct; note: this is costly
|
||||
time_t fetch_gpsTime(gpsStatus_t value) {
|
||||
tm.Second = (time_bcd / 100) % 100; // second
|
||||
tm.Minute = (time_bcd / 10000) % 100; // minute
|
||||
tm.Hour = time_bcd / 1000000; // hour
|
||||
tm.Day = gps.date.day(); // day
|
||||
tm.Month = gps.date.month(); // month
|
||||
tm.Year = year; // year
|
||||
|
||||
time_t t = timeIsValid(makeTime(value.timedate));
|
||||
ESP_LOGD(TAG, "GPS time: %d", t);
|
||||
return t;
|
||||
// add protocol delay to time with millisecond precision
|
||||
time_sec = makeTime(tm) + delay_ms / 1000;
|
||||
*msec = (delay_ms % 1000) ? delay_ms % 1000 : 0;
|
||||
}
|
||||
|
||||
return timeIsValid(time_sec);
|
||||
|
||||
} // fetch_gpsTime()
|
||||
|
||||
time_t fetch_gpsTime(void) {
|
||||
uint16_t msec;
|
||||
return fetch_gpsTime(&msec);
|
||||
}
|
||||
|
||||
// GPS serial feed FreeRTos Task
|
||||
void gps_loop(void *pvParameters) {
|
||||
|
||||
@ -119,7 +139,7 @@ void gps_loop(void *pvParameters) {
|
||||
while (1) {
|
||||
|
||||
if (cfg.payloadmask && GPS_DATA) {
|
||||
#if defined GPS_SERIAL
|
||||
#ifdef GPS_SERIAL
|
||||
// feed GPS decoder with serial NMEA data from GPS device
|
||||
while (GPS_Serial.available()) {
|
||||
gps.encode(GPS_Serial.read());
|
||||
@ -134,7 +154,7 @@ void gps_loop(void *pvParameters) {
|
||||
} // if
|
||||
|
||||
// show NMEA data in verbose mode, useful for debugging GPS
|
||||
ESP_LOGV(TAG, "GPS NMEA data: passed %d / failed: %d / with fix: %d",
|
||||
ESP_LOGV(TAG, "GPS NMEA data: passed %u / failed: %u / with fix: %u",
|
||||
gps.passedChecksum(), gps.failedChecksum(),
|
||||
gps.sentencesWithFix());
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define CFG_sx1276_radio 1
|
||||
|
||||
#define HAS_LED (22) // Green LED on board
|
||||
#define HAS_RGB_LED (2) // WS2812B RGB LED on board
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_2) // WS2812B RGB LED on board
|
||||
#define HAS_BUTTON (0) // button "FLASH" on board
|
||||
#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
#define CFG_sx1272_radio 1
|
||||
#define HAS_LED NOT_A_PIN // FiPy has no on board LED, so we use RGB LED
|
||||
#define HAS_RGB_LED GPIO_NUM_0 // WS2812B RGB LED on GPIO0
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0
|
||||
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM
|
||||
|
||||
// Pins for LORA chip SPI interface, reset line and interrupt lines
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
#define HAS_LED (21) // on board LED
|
||||
#define HAS_BUTTON (39) // on board button
|
||||
#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0
|
||||
|
||||
// GPS settings
|
||||
#define HAS_GPS 1 // use on board GPS
|
||||
|
@ -17,7 +17,7 @@
|
||||
//#define DISPLAY_FLIP 1 // uncomment this for rotated display
|
||||
#define HAS_LED 22 // ESP32 GPIO12 (pin22) On Board LED
|
||||
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||
#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_13) // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
||||
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
#define HAS_LED NOT_A_PIN // Led os on same pin as Lora SS pin, to avoid problems, we don't use it
|
||||
#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||
// Anyway shield is on over the LoLin32 board, so we won't be able to see this LED
|
||||
#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_13) // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
||||
#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||
#define CFG_sx1272_radio 1
|
||||
#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED
|
||||
#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0 (P2)
|
||||
|
||||
// Note: Pins for LORA chip SPI interface come from board file pins_arduino.h
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
//#define SPI_CS GPIO_NUM_36
|
||||
|
||||
#define CFG_sx1276_radio 1
|
||||
//#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED
|
||||
#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0 (P2)
|
||||
#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED
|
||||
#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_0) // WS2812B RGB LED on GPIO0 (P2)
|
||||
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM
|
||||
|
||||
// Note: Pins for LORA chip SPI interface come from board file pins_arduino.h
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
#define HAS_LED 13 // ESP32 GPIO12 (pin22) On Board LED
|
||||
//#define LED_ACTIVE_LOW 1 // Onboard LED is active when pin is LOW
|
||||
//#define HAS_RGB_LED 13 // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
//#define HAS_RGB_LED SmartLed rgb_led(LED_WS2812, 1, GPIO_NUM_13) // ESP32 GPIO13 (pin13) On Board Shield WS2812B RGB LED
|
||||
//#define HAS_BUTTON 15 // ESP32 GPIO15 (pin15) Button is on the LoraNode32 shield
|
||||
//#define BUTTON_PULLUP 1 // Button need pullup instead of default pulldown
|
||||
|
||||
|
24
src/hal/tinypico.h
Normal file
24
src/hal/tinypico.h
Normal file
@ -0,0 +1,24 @@
|
||||
// clang-format off
|
||||
// upload_speed 921600
|
||||
// board esp32dev
|
||||
|
||||
|
||||
#ifndef _TINYPICO_H
|
||||
#define _TINYPICO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Hardware related definitions for crowdsupply tinypico board
|
||||
|
||||
#define HAS_LED NOT_A_PIN // Green LED on board
|
||||
#define HAS_RGB_LED Apa102 rgb_led(1, GPIO_NUM_12, GPIO_NUM_2) // APA102 RGB LED on board
|
||||
|
||||
//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
||||
#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
||||
#define BAT_VOLTAGE_DIVIDER 2.7625f // voltage divider 160k/442k on board
|
||||
#define BOARD_HAS_PSRAM // use extra 4MB external RAM
|
||||
#define LED_POWER_SW (13) // switches LED power
|
||||
#define LED_POWER_ON 0 // switch on transistor for LED power
|
||||
#define LED_POWER_OFF 1
|
||||
|
||||
#endif
|
46
src/hal/tinypicomatrix.h
Normal file
46
src/hal/tinypicomatrix.h
Normal file
@ -0,0 +1,46 @@
|
||||
// clang-format off
|
||||
// upload_speed 921600
|
||||
// board esp32dev
|
||||
|
||||
|
||||
#ifndef _TINYPICO_H
|
||||
#define _TINYPICO_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Hardware related definitions for crowdsupply tinypico board
|
||||
// for operating a 96x16 shift register LED matrix display
|
||||
|
||||
#define HAS_LED NOT_A_PIN // Green LED on board
|
||||
#define HAS_RGB_LED Apa102 rgb_led(1, GPIO_NUM_12, GPIO_NUM_2) // APA102 RGB LED on board
|
||||
|
||||
//#define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature
|
||||
#define BAT_MEASURE_ADC ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7
|
||||
#define BAT_VOLTAGE_DIVIDER 2.7625f // voltage divider 160k/442k on board
|
||||
#define BOARD_HAS_PSRAM // use extra 4MB external RAM
|
||||
#define LED_POWER_SW (13) // switches LED power
|
||||
#define LED_POWER_ON 0 // switch on transistor for LED power
|
||||
#define LED_POWER_OFF 1
|
||||
|
||||
// LED Matrix display settings
|
||||
#define HAS_MATRIX_DISPLAY 1 // Uncomment to enable LED matrix display output
|
||||
#define LED_MATRIX_WIDTH 64 // Width in pixels (LEDs) of your display
|
||||
#define LED_MATRIX_HEIGHT 16 // Height in pixels (LEDs ) of your display
|
||||
|
||||
// Explanation of pin signals see https://learn.adafruit.com/32x16-32x32-rgb-led-matrix/new-wiring
|
||||
#define MATRIX_DISPLAY_SCAN_US 500 // Matrix display scan rate in microseconds (1ms is about 'acceptable')
|
||||
#define LED_MATRIX_LATCHPIN 32 // LAT (or STB = Strobe)
|
||||
#define LED_MATRIX_CLOCKPIN 33 // CLK
|
||||
#define LED_MATRIX_EN_74138 21 // EN (or OE)
|
||||
#define LED_MATRIX_LA_74138 23 // LA (or A)
|
||||
#define LED_MATRIX_LB_74138 19 // LB (or B)
|
||||
#define LED_MATRIX_LC_74138 18 // LC (or C)
|
||||
#define LED_MATRIX_LD_74138 5 // LD (or D)
|
||||
#define LED_MATRIX_DATA_R1 22 // R1 (or R0)
|
||||
|
||||
// CLK: The clock signal moves the data bits from pin R1 ("red") in the shift registers
|
||||
// LAT: The latch signal enables LEDs according to the shift register's contents
|
||||
// Line Selects: LA, LB, LC, LD select which rows of the display are currently lit (0 .. 15)
|
||||
// OE: Output enable switches the LEDs on/off while transitioning from one row to the next
|
||||
|
||||
#endif
|
@ -45,10 +45,10 @@ void irqHandler(void *pvParameters) {
|
||||
refreshTheMatrixDisplay();
|
||||
#endif
|
||||
|
||||
// gps refresh buffer?
|
||||
#if (HAS_GPS)
|
||||
if (InterruptStatus & GPS_IRQ)
|
||||
gps_storelocation(&gps_status);
|
||||
// BME sensor data to be read?
|
||||
#if (HAS_BME)
|
||||
if (InterruptStatus & BME_IRQ)
|
||||
bme_storedata(&bme_status);
|
||||
#endif
|
||||
|
||||
// are cyclic tasks due?
|
||||
@ -59,9 +59,7 @@ void irqHandler(void *pvParameters) {
|
||||
// is time to be synced?
|
||||
if (InterruptStatus & TIMESYNC_IRQ) {
|
||||
now(); // ensure sysTime is recent
|
||||
time_t t = timeProvider();
|
||||
if (timeIsValid(t))
|
||||
setTime(t);
|
||||
calibrateTime();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -108,17 +106,6 @@ void IRAM_ATTR ButtonIRQ() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HAS_GPS)
|
||||
void IRAM_ATTR GpsIRQ() {
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
|
||||
xTaskNotifyFromISR(irqHandlerTask, GPS_IRQ, eSetBits,
|
||||
&xHigherPriorityTaskWoken);
|
||||
if (xHigherPriorityTaskWoken)
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
#endif
|
||||
|
||||
void mask_user_IRQ() { xTaskNotify(irqHandlerTask, MASK_IRQ, eSetBits); }
|
||||
|
||||
void unmask_user_IRQ() { xTaskNotify(irqHandlerTask, UNMASK_IRQ, eSetBits); }
|
@ -14,7 +14,7 @@ unsigned long LEDBlinkStarted = 0; // When (in millis() led blink started)
|
||||
#ifdef HAS_RGB_LED
|
||||
|
||||
// RGB Led instance
|
||||
SmartLed rgb_led(LED_WS2812, 1, HAS_RGB_LED);
|
||||
HAS_RGB_LED;
|
||||
|
||||
float rgb_CalcColor(float p, float q, float t) {
|
||||
if (t < 0.0f)
|
||||
|
@ -2,13 +2,16 @@
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#define NUMCHARS 5
|
||||
#define NUMROWS 16
|
||||
#define NUMCOLS 64
|
||||
#define MATRIX_DISPLAY_PAGES (2) // number of display pages
|
||||
#define LINE_DIAGRAM_DIVIDER (2) // scales pax numbers to led rows
|
||||
|
||||
// local Tag for logging
|
||||
static const char TAG[] = __FILE__;
|
||||
|
||||
uint8_t MatrixDisplayIsOn = 0;
|
||||
static const uint32_t DisplaySize = LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / 8;
|
||||
uint8_t MatrixDisplayIsOn = 0, displaybuf[DisplaySize] = {0};
|
||||
static unsigned long ulLastNumMacs = 0;
|
||||
static time_t ulLastTime = myTZ.toLocal(now());
|
||||
|
||||
@ -16,9 +19,6 @@ LEDMatrix matrix(LED_MATRIX_LA_74138, LED_MATRIX_LB_74138, LED_MATRIX_LC_74138,
|
||||
LED_MATRIX_LD_74138, LED_MATRIX_EN_74138, LED_MATRIX_DATA_R1,
|
||||
LED_MATRIX_LATCHPIN, LED_MATRIX_CLOCKPIN);
|
||||
|
||||
// Display Buffer 128 = 64 * 16 / 8
|
||||
uint8_t displaybuf[LED_MATRIX_WIDTH * LED_MATRIX_HEIGHT / NUMCHARS];
|
||||
|
||||
// --- SELECT YOUR FONT HERE ---
|
||||
const FONT_INFO *ActiveFontInfo = &digital7_18ptFontInfo;
|
||||
// const FONT_INFO *ActiveFontInfo = &arialNarrow_17ptFontInfo;
|
||||
@ -31,14 +31,21 @@ const FONT_CHAR_INFO *ActiveFontCharInfo = ActiveFontInfo->Descriptors;
|
||||
void init_matrix_display(bool reverse) {
|
||||
ESP_LOGI(TAG, "Initializing LED Matrix display");
|
||||
matrix.begin(displaybuf, LED_MATRIX_WIDTH, LED_MATRIX_HEIGHT);
|
||||
|
||||
if (MatrixDisplayIsOn)
|
||||
matrix.on();
|
||||
else
|
||||
matrix.off();
|
||||
|
||||
if (reverse)
|
||||
matrix.reverse();
|
||||
matrix.clear();
|
||||
DrawNumber(String("0"));
|
||||
matrix.drawPoint(0, NUMROWS - 1, 1);
|
||||
} // init_display
|
||||
|
||||
void refreshTheMatrixDisplay(bool nextPage) {
|
||||
static uint8_t DisplayPage = 0;
|
||||
static uint8_t DisplayPage = 0, col = 0, row = 0;
|
||||
uint8_t level;
|
||||
char buff[16];
|
||||
|
||||
// if Matrixdisplay is switched off we don't refresh it to relax cpu
|
||||
@ -48,25 +55,58 @@ void refreshTheMatrixDisplay(bool nextPage) {
|
||||
// set display on/off according to current device configuration
|
||||
if (MatrixDisplayIsOn != cfg.screenon) {
|
||||
MatrixDisplayIsOn = cfg.screenon;
|
||||
if (MatrixDisplayIsOn)
|
||||
matrix.on();
|
||||
else
|
||||
matrix.off();
|
||||
}
|
||||
|
||||
if (nextPage) {
|
||||
DisplayPage =
|
||||
(DisplayPage >= MATRIX_DISPLAY_PAGES - 1) ? 0 : (DisplayPage + 1);
|
||||
matrix.clear();
|
||||
col = 0;
|
||||
}
|
||||
|
||||
switch (DisplayPage % MATRIX_DISPLAY_PAGES) {
|
||||
|
||||
// page 0: pax
|
||||
// page 1: time
|
||||
// page 0: number of current pax OR footfall line diagram
|
||||
// page 1: time of day
|
||||
|
||||
case 0:
|
||||
|
||||
if (ulLastNumMacs != macs.size()) {
|
||||
ulLastNumMacs = macs.size();
|
||||
matrix.clear();
|
||||
DrawNumber(String(ulLastNumMacs));
|
||||
if (cfg.countermode == 1)
|
||||
|
||||
{ // cumulative counter mode -> display total number of pax
|
||||
if (ulLastNumMacs != macs.size()) {
|
||||
ulLastNumMacs = macs.size();
|
||||
matrix.clear();
|
||||
DrawNumber(String(ulLastNumMacs));
|
||||
}
|
||||
}
|
||||
|
||||
else { // cyclic counter mode -> plot a line diagram
|
||||
|
||||
if (ulLastNumMacs != macs.size()) {
|
||||
|
||||
// next count cycle?
|
||||
if (macs.size() == 0) {
|
||||
|
||||
// matrix full? then scroll left 1 dot, else increment column
|
||||
if (col < NUMCOLS - 1)
|
||||
col++;
|
||||
else
|
||||
ShiftLeft(displaybuf, DisplaySize);
|
||||
|
||||
} else
|
||||
matrix.drawPoint(col, row, 0); // clear current dot
|
||||
|
||||
// scale and set new dot
|
||||
ulLastNumMacs = macs.size();
|
||||
level = ulLastNumMacs / LINE_DIAGRAM_DIVIDER;
|
||||
row = level <= NUMROWS ? NUMROWS - 1 - level % NUMROWS : 0;
|
||||
matrix.drawPoint(col, row, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -164,4 +204,12 @@ uint8_t GetCharWidth(char cChar) {
|
||||
return CharDescriptor.width;
|
||||
}
|
||||
|
||||
void ShiftLeft(uint8_t *arr, uint32_t len) {
|
||||
uint32_t i;
|
||||
for (i = 0; i < len - 1; ++i) {
|
||||
arr[i] = (arr[i] << 1) | ((arr[i + 1] >> 31) & 1);
|
||||
}
|
||||
arr[len - 1] = arr[len - 1] << 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MATRIX_DISPLAY
|
@ -35,7 +35,7 @@
|
||||
// so consuming more power. You may sharpen (reduce) this value if you are
|
||||
// limited on battery.
|
||||
// ATTN: VALUES > 7 WILL CAUSE RECEPTION AND JOIN PROBLEMS WITH HIGH SF RATES
|
||||
#define CLOCK_ERROR_PROCENTAGE 5
|
||||
#define CLOCK_ERROR_PROCENTAGE 7
|
||||
|
||||
// Set this to 1 to enable some basic debug output (using printf) about
|
||||
// RF settings used during transmission and reception. Set to 2 to
|
||||
|
@ -20,6 +20,7 @@ static const char TAG[] = "lora";
|
||||
|
||||
osjob_t sendjob;
|
||||
QueueHandle_t LoraSendQueue;
|
||||
TaskHandle_t lmicTask = NULL;
|
||||
|
||||
class MyHalConfig_t : public Arduino_LMIC::HalConfiguration_t {
|
||||
|
||||
@ -423,28 +424,15 @@ esp_err_t lora_stack_init() {
|
||||
ESP_LOGI(TAG, "LORA send queue created, size %d Bytes",
|
||||
SEND_QUEUE_SIZE * sizeof(MessageBuffer_t));
|
||||
|
||||
// starting lorawan stack
|
||||
ESP_LOGI(TAG, "Starting LMIC...");
|
||||
|
||||
os_init(); // initialize lmic run-time environment on core 1
|
||||
LMIC_reset(); // initialize lmic MAC
|
||||
LMIC_setLinkCheckMode(0);
|
||||
// This tells LMIC to make the receive windows bigger, in case your clock is
|
||||
// faster or slower. This causes the transceiver to be earlier switched on,
|
||||
// so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE
|
||||
// in src/lmic_config.h if you are limited on battery.
|
||||
LMIC_setClockError(MAX_CLOCK_ERROR * CLOCK_ERROR_PROCENTAGE / 100);
|
||||
// Set the data rate to Spreading Factor 7. This is the fastest supported
|
||||
// rate for 125 kHz channels, and it minimizes air time and battery power.
|
||||
// Set the transmission power to 14 dBi (25 mW).
|
||||
LMIC_setDrTxpow(DR_SF7, 14);
|
||||
|
||||
#if defined(CFG_US915) || defined(CFG_au921)
|
||||
// in the US, with TTN, it saves join time if we start on subband 1
|
||||
// (channels 8-15). This will get overridden after the join by parameters
|
||||
// from the network. If working with other networks or in other regions,
|
||||
// this will need to be changed.
|
||||
LMIC_selectSubBand(1);
|
||||
#endif
|
||||
xTaskCreatePinnedToCore(lmictask, // task function
|
||||
"lmictask", // name of task
|
||||
4096, // stack size of task
|
||||
(void *)1, // parameter of the task
|
||||
2, // priority of the task
|
||||
&lmicTask, // task handle
|
||||
1); // CPU core
|
||||
|
||||
if (!LMIC_startJoining()) { // start joining
|
||||
ESP_LOGI(TAG, "Already joined");
|
||||
@ -476,11 +464,6 @@ void lora_enqueuedata(MessageBuffer_t *message, sendprio_t prio) {
|
||||
|
||||
void lora_queuereset(void) { xQueueReset(LoraSendQueue); }
|
||||
|
||||
void lora_housekeeping(void) {
|
||||
// ESP_LOGD(TAG, "loraloop %d bytes left",
|
||||
// uxTaskGetStackHighWaterMark(LoraTask));
|
||||
}
|
||||
|
||||
#if (TIME_SYNC_LORAWAN)
|
||||
void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||
int flagSuccess) {
|
||||
@ -507,15 +490,8 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||
return;
|
||||
}
|
||||
|
||||
// begin of time critical section
|
||||
|
||||
// lock I2C bus and application irq to ensure accurate timing
|
||||
// mask application irq to ensure accurate timing
|
||||
mask_user_IRQ();
|
||||
if (!I2C_MUTEX_LOCK()) {
|
||||
ESP_LOGW(TAG, "[%0.3f] Timesync handshake error: i2c bus locking failed",
|
||||
millis() / 1000.0);
|
||||
goto finish; // failure
|
||||
}
|
||||
|
||||
// Update userUTCTime, considering the difference between the GPS and UTC
|
||||
// time, and the leap seconds until year 2019
|
||||
@ -529,14 +505,44 @@ void IRAM_ATTR user_request_network_time_callback(void *pVoidUserUTCTime,
|
||||
time_t requestDelaySec = osticks2ms(ticksNow - ticksRequestSent) / 1000;
|
||||
|
||||
// Update system time with time read from the network
|
||||
setMyTime(*pUserUTCTime + requestDelaySec, 0);
|
||||
setMyTime(*pUserUTCTime + requestDelaySec, 0, _lora);
|
||||
|
||||
finish:
|
||||
// end of time critical section: release I2C bus and app irq
|
||||
I2C_MUTEX_UNLOCK();
|
||||
// end of time critical section: release app irq lock
|
||||
unmask_user_IRQ();
|
||||
|
||||
} // user_request_network_time_callback
|
||||
#endif // TIME_SYNC_LORAWAN
|
||||
|
||||
// LMIC lorawan stack task
|
||||
void lmictask(void *pvParameters) {
|
||||
configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check
|
||||
|
||||
os_init(); // initialize lmic run-time environment
|
||||
LMIC_reset(); // initialize lmic MAC
|
||||
LMIC_setLinkCheckMode(0);
|
||||
// This tells LMIC to make the receive windows bigger, in case your clock is
|
||||
// faster or slower. This causes the transceiver to be earlier switched on,
|
||||
// so consuming more power. You may sharpen (reduce) CLOCK_ERROR_PERCENTAGE
|
||||
// in src/lmic_config.h if you are limited on battery.
|
||||
LMIC_setClockError(MAX_CLOCK_ERROR * CLOCK_ERROR_PROCENTAGE / 100);
|
||||
// Set the data rate to Spreading Factor 7. This is the fastest supported
|
||||
// rate for 125 kHz channels, and it minimizes air time and battery power.
|
||||
// Set the transmission power to 14 dBi (25 mW).
|
||||
LMIC_setDrTxpow(DR_SF7, 14);
|
||||
|
||||
#if defined(CFG_US915) || defined(CFG_au921)
|
||||
// in the US, with TTN, it saves join time if we start on subband 1
|
||||
// (channels 8-15). This will get overridden after the join by parameters
|
||||
// from the network. If working with other networks or in other regions,
|
||||
// this will need to be changed.
|
||||
LMIC_selectSubBand(1);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
os_runloop_once(); // execute lmic scheduled jobs and events
|
||||
delay(2); // yield to CPU
|
||||
}
|
||||
} // lmictask
|
||||
|
||||
#endif // HAS_LORA
|
||||
|
62
src/main.cpp
62
src/main.cpp
@ -33,10 +33,10 @@ IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
||||
|
||||
clockloop 1 4 generates realtime telegrams for external clock
|
||||
timesync_req 1 3 processes realtime time sync requests
|
||||
irqhandler 1 2 display, timesync, gps, etc. triggered by timers
|
||||
gpsloop 1 2 reads data from GPS via serial or i2c
|
||||
bmeloop 1 2 reads data from BME sensor via i2c
|
||||
looptask 1 1 runs the LMIC LoRa stack (arduino loop)
|
||||
lmictask 1 2 MCCI LMiC LORAWAN stack
|
||||
irqhandler 1 1 display, timesync, gps, etc. triggered by timers
|
||||
gpsloop 1 1 reads data from GPS via serial or i2c
|
||||
looptask 1 1 arduino loop (unused)
|
||||
IDLE 1 0 ESP32 arduino scheduler -> runs wifi channel rotator
|
||||
|
||||
Low priority numbers denote low priority tasks.
|
||||
@ -48,7 +48,6 @@ So don't do it if you do not own a digital oscilloscope.
|
||||
-------------------------------------------------------------------------------
|
||||
0 displayIRQ -> display refresh -> 40ms (DISPLAYREFRESH_MS)
|
||||
1 ppsIRQ -> pps clock irq -> 1sec
|
||||
2 gpsIRQ -> gps store data -> 300ms
|
||||
3 MatrixDisplayIRQ -> matrix mux cycle -> 0,5ms (MATRIX_DISPLAY_SCAN_US)
|
||||
|
||||
|
||||
@ -58,13 +57,13 @@ So don't do it if you do not own a digital oscilloscope.
|
||||
fired by hardware
|
||||
DisplayIRQ -> esp32 timer 0 -> irqHandlerTask (Core 1)
|
||||
CLOCKIRQ -> esp32 timer 1 -> ClockTask (Core 1)
|
||||
GpsIRQ -> esp32 timer 2 -> irqHandlerTask (Core 1)
|
||||
ButtonIRQ -> external gpio -> irqHandlerTask (Core 1)
|
||||
|
||||
fired by software (Ticker.h)
|
||||
TIMESYNC_IRQ -> timeSync() -> irqHandlerTask (Core 1)
|
||||
CYLCIC_IRQ -> housekeeping() -> irqHandlerTask (Core 1)
|
||||
SENDCYCLE_IRQ -> sendcycle() -> irqHandlerTask (Core 1)
|
||||
BME_IRQ -> bmecycle() -> irqHandlerTask (Core 1)
|
||||
|
||||
|
||||
// External RTC timer (if present)
|
||||
@ -82,13 +81,11 @@ 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
|
||||
|
||||
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL,
|
||||
*gpsIRQ = NULL;
|
||||
hw_timer_t *ppsIRQ = NULL, *displayIRQ = NULL, *matrixDisplayIRQ = NULL;
|
||||
|
||||
TaskHandle_t irqHandlerTask = NULL, ClockTask = NULL;
|
||||
SemaphoreHandle_t I2Caccess;
|
||||
bool volatile TimePulseTick = false;
|
||||
time_t volatile gps_pps_time = 0;
|
||||
time_t userUTCTime = 0;
|
||||
timesource_t timeSource = _unsynced;
|
||||
|
||||
@ -198,17 +195,25 @@ void setup() {
|
||||
#if (HAS_LED != NOT_A_PIN)
|
||||
pinMode(HAS_LED, OUTPUT);
|
||||
strcat_P(features, " LED");
|
||||
|
||||
#ifdef LED_POWER_SW
|
||||
pinMode(LED_POWER_SW, OUTPUT);
|
||||
digitalWrite(LED_POWER_SW, LED_POWER_ON);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_TWO_LED
|
||||
pinMode(HAS_TWO_LED, OUTPUT);
|
||||
strcat_P(features, " LED1");
|
||||
#endif
|
||||
|
||||
// use LED for power display if we have additional RGB LED, else for status
|
||||
#ifdef HAS_RGB_LED
|
||||
switch_LED(LED_ON);
|
||||
strcat_P(features, " RGB");
|
||||
rgb_set_color(COLOR_PINK);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // HAS_LED
|
||||
|
||||
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
|
||||
// start led loop
|
||||
@ -272,7 +277,7 @@ void setup() {
|
||||
"gpsloop", // name of task
|
||||
2048, // stack size of task
|
||||
(void *)1, // parameter of the task
|
||||
2, // priority of the task
|
||||
1, // priority of the task
|
||||
&GpsTask, // task handle
|
||||
1); // CPU core
|
||||
}
|
||||
@ -372,16 +377,8 @@ void setup() {
|
||||
#elif defined HAS_BME280
|
||||
strcat_P(features, " BME280");
|
||||
#endif
|
||||
if (bme_init()) {
|
||||
if (bme_init())
|
||||
ESP_LOGI(TAG, "Starting BME sensor...");
|
||||
xTaskCreatePinnedToCore(bme_loop, // task function
|
||||
"bmeloop", // name of task
|
||||
2048, // stack size of task
|
||||
(void *)1, // parameter of the task
|
||||
2, // priority of the task
|
||||
&BmeTask, // task handle
|
||||
1); // CPU core
|
||||
}
|
||||
#endif
|
||||
|
||||
// starting timers and interrupts
|
||||
@ -419,14 +416,6 @@ void setup() {
|
||||
button_init(HAS_BUTTON);
|
||||
#endif // HAS_BUTTON
|
||||
|
||||
// gps buffer read interrupt
|
||||
#if (HAS_GPS)
|
||||
gpsIRQ = timerBegin(2, 80, true);
|
||||
timerAttachInterrupt(gpsIRQ, &GpsIRQ, true);
|
||||
timerAlarmWrite(gpsIRQ, 300 * 1000, true);
|
||||
timerAlarmEnable(gpsIRQ);
|
||||
#endif
|
||||
|
||||
// cyclic function interrupts
|
||||
sendcycler.attach(SENDCYCLE * 2, sendcycle);
|
||||
housekeeper.attach(HOMECYCLE, housekeeping);
|
||||
@ -438,9 +427,9 @@ void setup() {
|
||||
#warning you did not specify a time source, time will not be synched
|
||||
#endif
|
||||
|
||||
// initialize gps time
|
||||
// initialize gps time
|
||||
#if (HAS_GPS)
|
||||
gps_storetime(&gps_status);
|
||||
fetch_gpsTime();
|
||||
#endif
|
||||
|
||||
#if (defined HAS_IF482 || defined HAS_DCF77)
|
||||
@ -461,15 +450,8 @@ void setup() {
|
||||
// show compiled features
|
||||
ESP_LOGI(TAG, "Features:%s", features);
|
||||
|
||||
vTaskDelete(NULL);
|
||||
|
||||
} // setup()
|
||||
|
||||
void loop() {
|
||||
|
||||
while (1) {
|
||||
#if (HAS_LORA)
|
||||
os_runloop_once(); // execute lmic scheduled jobs and events
|
||||
#else
|
||||
delay(2); // yield to CPU
|
||||
#endif
|
||||
}
|
||||
}
|
||||
void loop() { vTaskDelete(NULL); }
|
||||
|
@ -48,7 +48,7 @@
|
||||
#define PAYLOAD_BUFFER_SIZE 51 // maximum size of payload block per transmit
|
||||
#define LORASFDEFAULT 9 // 7 ... 12 SF, according to LoRaWAN specs
|
||||
#define MAXLORARETRY 500 // maximum count of TX retries if LoRa busy
|
||||
#define SEND_QUEUE_SIZE 10 // maximum number of messages in payload send queue [1 = no queue]
|
||||
#define SEND_QUEUE_SIZE 10 // maximum number of messages in payload send queue [1 = no queue]
|
||||
|
||||
// Hardware settings
|
||||
#define RGBLUMINOSITY 30 // RGB LED luminosity [default = 30%]
|
||||
@ -58,6 +58,7 @@
|
||||
// Settings for BME680 environmental sensor
|
||||
#define BME_TEMP_OFFSET 5.0f // Offset sensor on chip temp <-> ambient temp [default = 5°C]
|
||||
#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // update every 360 minutes = 4 times a day
|
||||
#define BMECYCLE 1 // bme sensor read cycle in seconds [default = 1 secs]
|
||||
|
||||
// OTA settings
|
||||
#define USE_OTA 1 // set to 0 to disable OTA update
|
||||
|
@ -8,7 +8,7 @@ static const char TAG[] = __FILE__;
|
||||
// helper function
|
||||
void do_reset() {
|
||||
ESP_LOGI(TAG, "Remote command: restart device");
|
||||
#if(HAS_LORA)
|
||||
#if (HAS_LORA)
|
||||
LMIC_shutdown();
|
||||
#endif
|
||||
delay(3000);
|
||||
@ -132,7 +132,7 @@ void set_gps(uint8_t val[]) {
|
||||
}
|
||||
|
||||
void set_sensor(uint8_t val[]) {
|
||||
#if(HAS_SENSORS)
|
||||
#if (HAS_SENSORS)
|
||||
switch (val[0]) { // check if valid sensor number 1...4
|
||||
case 1:
|
||||
case 2:
|
||||
@ -170,7 +170,7 @@ void set_monitor(uint8_t val[]) {
|
||||
}
|
||||
|
||||
void set_lorasf(uint8_t val[]) {
|
||||
#if(HAS_LORA)
|
||||
#if (HAS_LORA)
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa SF to %d", val[0]);
|
||||
switch_lora(val[0], cfg.txpower);
|
||||
#else
|
||||
@ -179,7 +179,7 @@ void set_lorasf(uint8_t val[]) {
|
||||
}
|
||||
|
||||
void set_loraadr(uint8_t val[]) {
|
||||
#if(HAS_LORA)
|
||||
#if (HAS_LORA)
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa ADR mode to %s",
|
||||
val[0] ? "on" : "off");
|
||||
cfg.adrmode = val[0] ? 1 : 0;
|
||||
@ -222,7 +222,7 @@ void set_rgblum(uint8_t val[]) {
|
||||
};
|
||||
|
||||
void set_lorapower(uint8_t val[]) {
|
||||
#if(HAS_LORA)
|
||||
#if (HAS_LORA)
|
||||
ESP_LOGI(TAG, "Remote command: set LoRa TXPOWER to %d", val[0]);
|
||||
switch_lora(cfg.lorasf, val[0]);
|
||||
#else
|
||||
@ -252,7 +252,9 @@ void get_status(uint8_t val[]) {
|
||||
|
||||
void get_gps(uint8_t val[]) {
|
||||
ESP_LOGI(TAG, "Remote command: get gps status");
|
||||
#if(HAS_GPS)
|
||||
#if (HAS_GPS)
|
||||
gpsStatus_t gps_status;
|
||||
gps_storelocation(&gps_status);
|
||||
payload.reset();
|
||||
payload.addGPS(gps_status);
|
||||
SendPayload(GPSPORT, prio_high);
|
||||
|
@ -46,21 +46,20 @@ uint8_t rtc_init(void) {
|
||||
|
||||
} // rtc_init()
|
||||
|
||||
uint8_t set_rtctime(time_t t, mutexselect_t mutex) { // t is sec epoch time
|
||||
if (!mutex || I2C_MUTEX_LOCK()) {
|
||||
uint8_t set_rtctime(time_t t) { // t is sec epoch time
|
||||
if (I2C_MUTEX_LOCK()) {
|
||||
#ifdef RTC_INT // sync rtc 1Hz pulse on top of second
|
||||
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone); // off
|
||||
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeClock); // start
|
||||
#endif
|
||||
Rtc.SetDateTime(RtcDateTime(t - SECS_YR_2000)); // epoch -> sec2000
|
||||
if (mutex)
|
||||
I2C_MUTEX_UNLOCK();
|
||||
I2C_MUTEX_UNLOCK();
|
||||
ESP_LOGI(TAG, "RTC time synced");
|
||||
return 1; // success
|
||||
} else {
|
||||
ESP_LOGE(TAG, "RTC set time failure");
|
||||
return 0;
|
||||
} // failure
|
||||
return 0; // failure
|
||||
}
|
||||
} // set_rtctime()
|
||||
|
||||
time_t get_rtctime(void) {
|
||||
@ -71,8 +70,11 @@ time_t get_rtctime(void) {
|
||||
t = tt.Epoch32Time(); // sec2000 -> epoch
|
||||
}
|
||||
I2C_MUTEX_UNLOCK();
|
||||
return timeIsValid(t);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "RTC get time failure");
|
||||
return 0; // failure
|
||||
}
|
||||
return timeIsValid(t);
|
||||
} // get_rtctime()
|
||||
|
||||
float get_rtctemp(void) {
|
||||
|
@ -87,6 +87,8 @@ void sendCounter() {
|
||||
case GPS_DATA:
|
||||
// send GPS position only if we have a fix
|
||||
if (gps.location.isValid()) {
|
||||
gpsStatus_t gps_status;
|
||||
gps_storelocation(&gps_status);
|
||||
payload.reset();
|
||||
payload.addGPS(gps_status);
|
||||
SendPayload(GPSPORT, prio_high);
|
||||
|
@ -170,8 +170,4 @@ void spi_enqueuedata(MessageBuffer_t *message, sendprio_t prio) {
|
||||
|
||||
void spi_queuereset(void) { xQueueReset(SPISendQueue); }
|
||||
|
||||
void spi_housekeeping(void) {
|
||||
ESP_LOGD(TAG, "spiloop %d bytes left", uxTaskGetStackHighWaterMark(spiTask));
|
||||
}
|
||||
|
||||
#endif // HAS_SPI
|
@ -1,4 +1,5 @@
|
||||
#include "timekeeper.h"
|
||||
#include "paxcounter.conf"
|
||||
|
||||
#if !(HAS_LORA)
|
||||
#if (TIME_SYNC_LORASERVER)
|
||||
@ -22,31 +23,17 @@ Ticker timesyncer;
|
||||
|
||||
void timeSync() { xTaskNotify(irqHandlerTask, TIMESYNC_IRQ, eSetBits); }
|
||||
|
||||
time_t timeProvider(void) {
|
||||
void calibrateTime(void) {
|
||||
|
||||
time_t t = 0;
|
||||
uint16_t t_msec = 0;
|
||||
|
||||
#if (HAS_GPS)
|
||||
// fetch recent time from last NMEA record
|
||||
t = fetch_gpsTime(gps_status);
|
||||
t = fetch_gpsTime(&t_msec);
|
||||
if (t) {
|
||||
#ifdef HAS_RTC
|
||||
set_rtctime(t, do_mutex); // calibrate RTC
|
||||
#endif
|
||||
timeSource = _gps;
|
||||
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat
|
||||
ESP_LOGD(TAG, "GPS time = %d", t);
|
||||
return t;
|
||||
}
|
||||
#endif
|
||||
|
||||
// no time from GPS -> fallback to RTC time while trying lora sync
|
||||
#ifdef HAS_RTC
|
||||
t = get_rtctime();
|
||||
if (t) {
|
||||
timeSource = _rtc;
|
||||
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); // short retry
|
||||
ESP_LOGD(TAG, "RTC time = %d", t);
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -58,14 +45,68 @@ time_t timeProvider(void) {
|
||||
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
|
||||
#endif
|
||||
|
||||
if (!t) {
|
||||
timeSource = _unsynced;
|
||||
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync); // short retry
|
||||
// no time from GPS -> fallback to RTC time while trying lora sync
|
||||
#ifdef HAS_RTC
|
||||
t = get_rtctime();
|
||||
if (t) {
|
||||
timeSource = _rtc;
|
||||
goto finish;
|
||||
}
|
||||
#endif
|
||||
|
||||
return t;
|
||||
goto finish;
|
||||
|
||||
} // timeProvider()
|
||||
finish:
|
||||
|
||||
setMyTime((uint32_t)t, t_msec, timeSource); // set time
|
||||
|
||||
} // calibrateTime()
|
||||
|
||||
// adjust system time, calibrate RTC and RTC_INT pps
|
||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec,
|
||||
timesource_t mytimesource) {
|
||||
|
||||
// increment t_sec only if t_msec > 1000
|
||||
time_t time_to_set = (time_t)(t_sec + t_msec / 1000);
|
||||
|
||||
// do we have a valid time?
|
||||
if (timeIsValid(time_to_set)) {
|
||||
|
||||
// if we have msec fraction, then wait until top of second with
|
||||
// millisecond precision
|
||||
if (t_msec % 1000) {
|
||||
time_to_set++;
|
||||
vTaskDelay(pdMS_TO_TICKS(1000 - t_msec % 1000));
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "[%0.3f] UTC epoch time: %d.%03d sec", millis() / 1000.0,
|
||||
time_to_set, t_msec % 1000);
|
||||
|
||||
// if we have got an external timesource, set RTC time and shift RTC_INT pulse
|
||||
// to top of second
|
||||
#ifdef HAS_RTC
|
||||
if ((mytimesource == _gps) || (mytimesource == _lora))
|
||||
set_rtctime(time_to_set);
|
||||
#endif
|
||||
|
||||
// if we have a software pps timer, shift it to top of second
|
||||
#if (!defined GPS_INT && !defined RTC_INT)
|
||||
timerWrite(ppsIRQ, 0); // reset pps timer
|
||||
CLOCKIRQ(); // fire clock pps, this advances time 1 sec
|
||||
#endif
|
||||
|
||||
setTime(time_to_set); // set the time on top of second
|
||||
|
||||
timeSource = mytimesource; // set global variable
|
||||
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync);
|
||||
ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was set | source: %c",
|
||||
millis() / 1000.0, timeSetSymbols[timeSource]);
|
||||
} else {
|
||||
timesyncer.attach(TIME_SYNC_INTERVAL_RETRY * 60, timeSync);
|
||||
ESP_LOGI(TAG, "[%0.3f] Timesync failed, invalid time fetched | source: %c",
|
||||
millis() / 1000.0, timeSetSymbols[timeSource]);
|
||||
}
|
||||
}
|
||||
|
||||
// helper function to setup a pulse per second for time synchronisation
|
||||
uint8_t timepulse_init() {
|
||||
@ -131,11 +172,6 @@ void IRAM_ATTR CLOCKIRQ(void) {
|
||||
|
||||
SyncToPPS(); // advance systime, see microTime.h
|
||||
|
||||
// store recent gps time, and try to get gps time if time is not synced
|
||||
#if (HAS_GPS)
|
||||
gps_storetime(&gps_status);
|
||||
#endif
|
||||
|
||||
// advance wall clock, if we have
|
||||
#if (defined HAS_IF482 || defined HAS_DCF77)
|
||||
xTaskNotifyFromISR(ClockTask, uint32_t(now()), eSetBits,
|
||||
@ -209,11 +245,13 @@ void clock_init(void) {
|
||||
void clock_loop(void *taskparameter) { // ClockTask
|
||||
|
||||
// caveat: don't use now() in this task, it will cause a race condition
|
||||
// due to concurrent access to i2c bus for setting rtc!
|
||||
// due to concurrent access to i2c bus when reading/writing from/to rtc chip!
|
||||
|
||||
#define nextmin(t) (t + DCF77_FRAME_SIZE + 1) // next minute
|
||||
|
||||
#ifdef HAS_TWO_LED
|
||||
static bool led1_state = false;
|
||||
#endif
|
||||
uint32_t printtime;
|
||||
time_t t = *((time_t *)taskparameter), last_printtime = 0; // UTC time seconds
|
||||
|
||||
|
@ -128,13 +128,12 @@ void process_timesync_req(void *taskparameter) {
|
||||
// calculate fraction milliseconds
|
||||
time_to_set_fraction_msec = (uint16_t)(time_offset_ms.count() % 1000);
|
||||
|
||||
setMyTime(time_to_set, time_to_set_fraction_msec);
|
||||
setMyTime(time_to_set, time_to_set_fraction_msec, _lora);
|
||||
|
||||
finish:
|
||||
// end of time critical section: release app irq lock
|
||||
unmask_user_IRQ();
|
||||
|
||||
timeSyncPending = false;
|
||||
unmask_user_IRQ();
|
||||
|
||||
} // infinite while(1)
|
||||
}
|
||||
@ -208,43 +207,8 @@ int recv_timesync_ans(uint8_t seq_no, uint8_t buf[], uint8_t buf_len) {
|
||||
}
|
||||
}
|
||||
|
||||
// adjust system time, calibrate RTC and RTC_INT pps
|
||||
void IRAM_ATTR setMyTime(uint32_t t_sec, uint16_t t_msec) {
|
||||
|
||||
time_t time_to_set = (time_t)(t_sec + 1);
|
||||
|
||||
ESP_LOGD(TAG, "[%0.3f] Calculated UTC epoch time: %d.%03d sec",
|
||||
millis() / 1000.0, time_to_set, t_msec);
|
||||
|
||||
if (timeIsValid(time_to_set)) {
|
||||
|
||||
// wait until top of second with millisecond precision
|
||||
vTaskDelay(pdMS_TO_TICKS(1000 - t_msec));
|
||||
|
||||
// set RTC time and calibrate RTC_INT pulse on top of second
|
||||
#ifdef HAS_RTC
|
||||
set_rtctime(time_to_set, no_mutex);
|
||||
#endif
|
||||
|
||||
// sync pps timer to top of second
|
||||
#if (!defined GPS_INT && !defined RTC_INT)
|
||||
timerWrite(ppsIRQ, 0); // reset pps timer
|
||||
CLOCKIRQ(); // fire clock pps, this advances time 1 sec
|
||||
#endif
|
||||
|
||||
setTime(time_to_set); // set the time on top of second
|
||||
|
||||
timeSource = _lora;
|
||||
timesyncer.attach(TIME_SYNC_INTERVAL * 60, timeSync); // regular repeat
|
||||
ESP_LOGI(TAG, "[%0.3f] Timesync finished, time was adjusted",
|
||||
millis() / 1000.0);
|
||||
} else
|
||||
ESP_LOGW(TAG, "[%0.3f] Timesync failed, outdated time calculated",
|
||||
millis() / 1000.0);
|
||||
}
|
||||
|
||||
// create task for timeserver handshake processing, called from main.cpp
|
||||
void timesync_init() {
|
||||
// create task for timeserver handshake processing, called from main.cpp
|
||||
xTaskCreatePinnedToCore(process_timesync_req, // task function
|
||||
"timesync_req", // name of task
|
||||
2048, // stack size of task
|
||||
|
Loading…
Reference in New Issue
Block a user