Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cyberman54/ESP32-Paxcounter
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.6.1
Choose a base ref
...
head repository: cyberman54/ESP32-Paxcounter
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Loading
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -169,7 +169,7 @@ jobs:
- os: windows-latest
path: ~\AppData\Local\pip\Cache
platformio-path: ~\AppData\Local\platformio\Cache
board: [ttgotdongles3.h, ttgotdongledisplays3.h]
board: [ttgotdongles3.h, ttgotdongledisplays3.h, heltecsticklitev3.h, ttgotsupremes3.h]
runs-on: ${{ matrix.os }}

steps:
1 change: 1 addition & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ on:
paths:
- 'mkdocs.yml'
- 'docs/**'
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ESP32-Paxcounter
![logo](docs/assets/paxcounter_logo_white.png)

**Wifi & Bluetooth driven, LoRaWAN enabled, battery powered mini Paxcounter built on cheap ESP32 LoRa IoT boards**
**Wifi & Bluetooth driven, LoRaWAN enabled, Paxcounter and multi-sensor appliance, built on cheap ESP32 LoRa IoT boards**

[Tutorial (in german language): heise.de](https://www.heise.de/select/make/2019/1/1551099236518668)

@@ -10,6 +10,8 @@

---

**Ready-to-go Hardware**: <a href="https://de.aliexpress.com/item/32915894264.html" target="_blank">LILYGO® Paxcounter LoRa</a>

**Documentation**: <a href="https://cyberman54.github.io/ESP32-Paxcounter" target="_blank">https://cyberman54.github.io/ESP32-Paxcounter</a>

**Source Code**: <a href="https://github.com/cyberman54/ESP32-Paxcounter" target="_blank">https://github.com/cyberman54/ESP32-Paxcounter</a>
@@ -28,7 +30,7 @@

# Use case

Paxcounter is an [ESP32](https://www.espressif.com/en/products/socs/esp32) MCU based device for metering passenger flows in realtime. It counts how many mobile devices are around. This gives an estimation how many people are around. Paxcounter detects Wifi and Bluetooth signals in the air, focusing on mobile devices by evaluating their MAC adresses.
Paxcounter is an [ESP32](https://www.espressif.com/en/products/socs/esp32) MCU based device for metering passenger flows and multi-sensor data in realtime. It counts how many mobile devices are around. This gives an estimation how many people are around. Paxcounter detects Wifi and Bluetooth signals in the air, focusing on mobile devices by evaluating their MAC adresses. In parallel, it reads and stores data from multiple connected environment sensors.

Intention of this project is to do this without intrusion in privacy: You don't need to track people owned devices, if you just want to count them. Therefore, Paxcounter does not persistenly store MAC adresses and does no kind of fingerprinting the scanned devices.

@@ -70,3 +72,4 @@ Thanks to
- [Stefan](https://github.com/nerdyscout) for paxcounter opensensebox integration
- [August Quint](https://github.com/AugustQu) for adding SD card data logger and SDS011 support
- [t-huyeng](https://github.com/t-huyeng) for adding a CI workflow and rework documentation
- [TD-er](https://github.com/TD-er) for bugfixings and T-Beam documentation
16 changes: 8 additions & 8 deletions docs/configuration/index.md
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ You can add up to 3 user defined sensors. Insert your sensor's payload scheme in

### Supported Peripherals

* Bosch BMP180 / BME280 / BME680
* Bosch BMP180 / BME280 / BMP280 / BMP680
* SDS011
* RTC DS3231
* generic serial NMEA GPS
@@ -18,15 +18,15 @@ See [`generic.h`](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/sha

=== "BME/ BMP Configuration"
```c linenums="37" title="shared/hal/generic.h"
--8<-- "shared/hal/generic.h:37:49"
--8<-- "shared/hal/generic.h:37:55"
```
=== "SDS011 Configuration"
```c linenums="51" title="shared/hal/generic.h"
--8<-- "shared/hal/generic.h:51:56"
--8<-- "shared/hal/generic.h:57:61"
```
=== "Custom Sensors Configuration"
```c linenums="57" title="shared/hal/generic.h"
--8<-- "shared/hal/generic.h:57:60"
--8<-- "shared/hal/generic.h:63:66"
```

=== "Complete `generic.h`"
@@ -52,7 +52,7 @@ Output of sensor and peripheral data is internally switched by a bitmask registe
\*) GPS data can also be combined with paxcounter payload on port 1, `#define GPSPORT 1` in paxcounter.conf to enable

```c linenums="102" title="shared/paxcounter_orig.conf"
--8<-- "shared/paxcounter_orig.conf:102:102"
--8<-- "shared/paxcounter_orig.conf:104:104"
```


@@ -74,13 +74,13 @@ Paxcounter supports a battery friendly power saving mode. In this mode the devic
Paxcounter can keep a time-of-day synced with external or on board time sources. Set `#define TIME_SYNC_INTERVAL` in `paxcounter.conf` to enable time sync.

```c linenums="88" title="shared/paxcounter_orig.conf"
--8<-- "shared/paxcounter_orig.conf:88:88"
--8<-- "shared/paxcounter_orig.conf:90:90"
```

Supported external time sources are GPS, LORAWAN network time and LORAWAN application timeserver time. Supported on board time sources are the RTC of ESP32 and a DS3231 RTC chip, both are kept sycned as fallback time sources. Time accuracy depends on board's time base which generates the pulse per second. Supported are GPS PPS, SQW output of RTC, and internal ESP32 hardware timer. Time base is selected by #defines in the board's hal file, see example in [`generic.h`](https://github.com/cyberman54/ESP32-Paxcounter/blob/master/shared/hal/generic.h).

```c linenums="87" title="shared/hal/generic.h"
--8<-- "shared/hal/generic.h:87:96"
--8<-- "shared/hal/generic.h:93:95"
```


@@ -101,7 +101,7 @@ Paxcounter can be used to sync a wall clock which has a DCF77 or IF482 time tele
This describes how to set up a mobile PaxCounter:<br> Follow all steps so far for preparing the device, selecting the packed payload format. In `paxcounter.conf` set `PAYLOAD_OPENSENSEBOX` to `1`.

```c linenums="60" title="shared/paxcounter_orig.conf"
--8<-- "shared/paxcounter_orig.conf:60:60"
--8<-- "shared/paxcounter_orig.conf:62:62"
```

Register a new sensebox on [https://opensensemap.org/](https://opensensemap.org). In the sensor configuration select "TheThingsNetwork" and set decoding profile to "LoRa serialization". Enter your TTN Application and Device ID. Setup decoding option using:
58 changes: 58 additions & 0 deletions docs/display-led.md
Original file line number Diff line number Diff line change
@@ -13,6 +13,64 @@ If you're using a device with OLED display, or if you add such one to the I2C bu

by pressing the button of the device.

# Notes on powering OLED display

**Different OLED display pinouts:**

The TTGO T-beam boards do have solder pads for a pinheader which seems to be just right for a commonly used OLED display like the SSD1306.

The most relevant pin pads are from left to right:

- GND
- 3V3
- GND
- 22 (SCL)
- 21 (SDA)
- 3.3V (label oddly differs from the other 3V3 labelled pin)

However there are 2 versions of the SSD1306 OLED display available:

- Most common available: GND/Vdd/SCL/SDA
- Hard to find: Vdd/GND/SCL/SDA

As can be seen, GND and Vdd are swapped and thus the most commonly available display version cannot be used without some tweaking.

In order to make the most commonly available version fit, you can strip of the plastics from the power pins and carefully bend both GND and Vdd pins in a Z-shape so they will fit in the adjacent pin hole.

![Display Image](img/SSD1306_OLED_t-beam.jpg)

This way the display is still positioned correctly to fit in the many available 3D printable enclosure designs out there.


**Hardware mod for power-on issues:**

Some boards like the TTGO T-beam v1.0 and newer do have a power management chip.

- T-Beam v1.0 and v1.1 use AXP192
- T-Beam v1.2 and T-Supreme use AXP2101

At least the ones using the AXP192 power management chip do have a annoying oversight in the board design.

When powering on the board, the AXP192 is set to output 1.8V to both pads in the aforementioned pin header labelled "3V3" and "3.3V".
If a display like the SSD1306 is soldered to use this as a power source, both I2C pins will be pulled down to about 1.8V + 0.3V = 2.1V by the protection diodes in the display controller.
This may be too low to work properly for all other I2C connected devices.

So the ESP32 may not be able to scan the I2C bus for any available I2C device and also not able to setup the AXP192 chip to output a higher voltage on the DCDC1 pin which powers the OLED display.

This catch-22 situation can be resolved by adding a simple diode from GPIO-0 to the "3.3V" pad. (the 'line' on the diode towards the "3.3V" pad)

![Display Image](img/SSD1306_t-beam_diode_mod.jpg)

In this test setup, a basic 1N4001 is used, which has a voltage drop of about 0.5V.
Another option is to use a germanium diode like the 1N4148, which does have a voltage drop of 0.3V.

GPIO-0 is pulled up to the 3V3 net of the ESP32. This is required for the ESP32 to boot the flashed sketch and not enter flash mode when powered on.

So as soon as the ESP32 is powered, the Vdd of the OLED display will be pulled up to 3.3V - 0.5V = 2.8V.
This is enough for the I2C pins of the display to not being pulled down and thus the ESP32 can communicate with the AXP192 power management chip.

N.B. Make sure the leads of the diode cannot short any of the other pins.

# LED blink pattern

**Mono color LED:**
12 changes: 6 additions & 6 deletions docs/hardware.md
Original file line number Diff line number Diff line change
@@ -4,9 +4,9 @@

*With LoRa radio data transfer*:

- **LilyGo: [Paxcounter-Board*](https://www.aliexpress.com/item/32915894264.html?spm=a2g0o.productlist.0.0.3d656325QrcfQc&algo_pvid=4a150199-63e7-4d21-bdb1-b48164537744&algo_exp_id=4a150199-63e7-4d21-bdb1-b48164537744-2&pdp_ext_f=%7B%22sku_id%22%3A%2212000023374441919%22%7D)**
- TTGO: T1*, T2*, T3*, T-Beam, T-Fox
- Heltec: LoRa-32 v1 and v2
- **LILYGO®: [Paxcounter LoRa V2.1*](https://de.aliexpress.com/item/32915894264.html)**
- TTGO: T1*, T2*, T3*, T-Beam (1.0/1.1/1.2), T-Fox, T-Supreme*, T-Display, T-Dongle
- Heltec: LoRa-32 v1/v2/v3, Stick Lite V3
- Pycom: LoPy, LoPy4, FiPy
- Radioshuttle.de: [ECO Power Board](https://www.radioshuttle.de/esp32-eco-power/esp32-eco-power-board/)
- WeMos: LoLin32 + [LoraNode32 shield](https://github.com/hallard/LoLin32-Lora),
@@ -16,7 +16,7 @@ LoLin32lite + [LoraNode32-Lite shield](https://github.com/hallard/LoLin32-Lite-L

*Without LoRa*:

- LilyGo: [T-Dongle S3*](https://github.com/Xinyuan-LilyGO/T-Dongle-S3)
- LILYGO®: [T-Dongle S3*](https://github.com/Xinyuan-LilyGO/T-Dongle-S3)
- 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)
@@ -35,9 +35,9 @@ Depending on board hardware following features are supported:
- [OLED Display](display-led.md) (shows detailed status)
- RGB LED (shows colorized status)
- Button (short press: flip display page / long press: send alarm message)
- Battery voltage monitoring (analog read / AXP192 / IP5306)
- Battery voltage monitoring (analog read / AXP192 / AXP202 / AXP2101 / IP5306)
- GPS (Generic serial NMEA, or Quectel L76 I2C)
- Environmental sensors (Bosch BMP180/BME280/BME680 I2C; SDS011 serial)
- Environmental sensors (Bosch BMP180/BME280/BME680/BMP280 I2C; SDS011 serial)
- Real Time Clock (Maxim DS3231 I2C)
- IF482 (serial) and DCF77 (gpio) time telegram generator
- Switch external power / battery
Binary file added docs/img/SSD1306_OLED_t-beam.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/SSD1306_t-beam_diode_mod.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/license-credits.md
Original file line number Diff line number Diff line change
@@ -33,3 +33,4 @@ Thanks to
- [Stefan](https://github.com/nerdyscout) for paxcounter opensensebox integration
- [August Quint](https://github.com/AugustQu) for adding SD card data logger and SDS011 support
- [t-huyeng](https://github.com/t-huyeng) for adding a CI workflow and rework documentation
- [TD-er](https://github.com/TD-er) for bugfixings and T-Beam documentation
2 changes: 1 addition & 1 deletion docs/payloadformat.md
Original file line number Diff line number Diff line change
@@ -5,7 +5,7 @@ You can select different payload formats in [`paxcounter.conf`](https://github.c

- ***Plain*** uses big endian format and generates json fields, e.g. useful for TTN console

- ***Packed*** uses little endian format and generates json fields
- ***Packed*** uses little endian format and generates json fields (exception: floats are big endian encoded)

- [***CayenneLPP***](https://developers.mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload) generates MyDevices Cayenne readable fields

2 changes: 1 addition & 1 deletion docs/remotecontrol.md
Original file line number Diff line number Diff line change
@@ -182,7 +182,7 @@ Send for example `83` `86` as Downlink on Port 2 to get battery status and time/

Device answers with it's current status on Port 4.

#### 0x85 get BME280 / BME680 sensor data
#### 0x85 get BME sensor data

Device answers with BME sensor data set on Port 7.

2 changes: 2 additions & 0 deletions include/bmesensor.h
Original file line number Diff line number Diff line change
@@ -16,6 +16,8 @@
#include <Adafruit_BME280.h>
#elif defined HAS_BMP180
#include <Adafruit_BMP085.h>
#elif defined HAS_BMP280
#include <Adafruit_BMP280.h>
#endif

extern Ticker bmecycler;
1 change: 0 additions & 1 deletion include/display.h
Original file line number Diff line number Diff line change
@@ -117,6 +117,5 @@ void dp_scrollVertical(uint8_t *buf, const uint16_t width,
int dp_drawPixel(uint8_t *buf, const uint16_t x, const uint16_t y,
const uint8_t dot);
void dp_plotCurve(uint16_t count, bool reset);
void dp_rescaleBuffer(uint8_t *buf, const int factor);

#endif
10 changes: 5 additions & 5 deletions include/globals.h
Original file line number Diff line number Diff line change
@@ -88,11 +88,11 @@ typedef struct {
} MessageBuffer_t;

typedef struct {
int32_t latitude;
int32_t longitude;
uint8_t satellites;
uint16_t hdop;
int16_t altitude;
int32_t latitude{};
int32_t longitude{};
uint8_t satellites{};
uint16_t hdop{};
int16_t altitude{};
} gpsStatus_t;

typedef struct {
3 changes: 2 additions & 1 deletion include/gpsread.h
Original file line number Diff line number Diff line change
@@ -11,12 +11,13 @@
#endif

extern TinyGPSPlus gps; // Make TinyGPS++ instance globally availabe
extern bool gps_location_isupdated; // Keep track of whether it was updated when showing on the display
extern TaskHandle_t GpsTask;

int gps_init(void);
int gps_config();
bool gps_hasfix();
void gps_storelocation(gpsStatus_t *gps_store);
bool gps_storelocation(gpsStatus_t *gps_store);
void gps_loop(void *pvParameters);
time_t get_gpstime(uint16_t *msec);

2 changes: 1 addition & 1 deletion include/i2c.h
Original file line number Diff line number Diff line change
@@ -18,7 +18,7 @@
#define SSD1306_SECONDARY_ADDRESS (0x3C)
#define BME_PRIMARY_ADDRESS (0x77)
#define BME_SECONDARY_ADDRESS (0x76)
#define AXP192_PRIMARY_ADDRESS (0x34)
#define PMU_PRIMARY_ADDRESS (0x34)
#define IP5306_PRIMARY_ADDRESS (0x75)
#define MCP_24AA02E64_PRIMARY_ADDRESS (0x50)
#define QUECTEL_GPS_PRIMARY_ADDRESS (0x10)
2 changes: 0 additions & 2 deletions include/led.h
Original file line number Diff line number Diff line change
@@ -2,9 +2,7 @@
#define _LED_H

#ifdef HAS_RGB_LED
#define FASTLED_INTERNAL
#include <FastLED.h>
#include "libpax_helpers.h"
#endif

#ifdef HAS_LORA
44 changes: 38 additions & 6 deletions include/power.h
Original file line number Diff line number Diff line change
@@ -43,6 +43,15 @@
#endif
#endif

#ifdef ADC_SW
#ifndef ADC_POWER_ON
#define ADC_POWER_ON 1
#endif
#ifndef ADC_POWER_OFF
#define ADC_POWER_OFF (!ADC_POWER_ON)
#endif
#endif

#ifdef BAT_MEASURE_ADC_UNIT // ADC2 wifi bug workaround
extern RTC_NOINIT_ATTR uint64_t RTC_reg_b;
#include "soc/sens_reg.h" // needed for adc pin reset
@@ -56,14 +65,37 @@ bool batt_sufficient(void);
extern int8_t batt_level;

#ifdef HAS_PMU
#include <XPowersLib.h>
extern XPowersPMU pmu;

#include "XPowersLib.h"
extern XPowersLibInterface *pmu;
#ifdef XPOWERS_CHIP_AXP192
extern XPowersAXP192 *axp192;
#elif defined XPOWERS_CHIP_AXP2101
extern XPowersAXP2101 *axp2101;
#endif

#ifndef PMU_SDA
#define PMU_SDA SDA
#endif

#ifndef PMU_SCL
#define PMU_SCL SCL
#endif

#ifndef PMU_WIRE
#define PMU_WIRE Wire
#else
#define WIRE1_PIN_DEFINED
#define SDA1 PMU_SDA
#define SCL1 PMU_SCL
#endif

enum pmu_power_t { pmu_power_on, pmu_power_off, pmu_power_sleep };
void IRAM_ATTR PMUIRQ();
void AXP192_powerevent_IRQ(void);
void AXP192_power(pmu_power_t powerlevel);
void AXP192_init(void);
void AXP192_showstatus(void);
void PMU_powerevent_IRQ(void);
void PMU_power(pmu_power_t powerlevel);
void PMU_init(void);
void PMU_showstatus(void);
#endif // HAS_PMU

#ifdef HAS_IP5306
Loading