Wifi/BLE Paxcounter Project with ESP32 boards

(Verkehrsrot) #121

You can configure payload send cycle in paxcounter.conf and change it during runtime by remote command to the device.

(michellamie) #122

Thanks for the answer. I found it on GitHub. I also found Wi-Fi scanning is using channel hopping. Very nice and can’t wait to get started :slight_smile:

As soon it works I will make some comparison’s with some of our own scanners.

P.s. what is the setup downstream. Do you gather the data and process it in a certain way?

(michellamie) #123

A nice read: https://documentation.meraki.com/MR/Monitoring_and_Reporting/Location_Analytics

On privacy they mention hashing, salting and truncating. Did you consider truncating as well?

Beside the above I see you included a vendor list, that is a nice addition. Did you also consider a opt-out possibility? Would it be possible to have that on the devices (over the air updates) or should it be something that will be applied downstream?

P.s. I’m not a expert on security, but will the MAC address have the same outcome if it will be scanned again (other time/day) and can you see it as a recurring device?

(Verkehrsrot) #124

MACs are truncated in code, only 50% is used for hashing.
Reoccuring MACs are not identified, because salt changes after each send payload loop (timespan configurable, default 240secs).
Vendor OUI list is currently hardcoded on the device.

(michellamie) #125

Clear, with the opt-out vendors are providing a way to people that they can be ignored in the scans. For example if people live above a shop and a Wi-Fi scanner is placed for a period of time you might get a good idea of who is at home at a certain time. Therefore might be interesting to see if a sort of “ignore” list can be maintained on the device beside the vendor OUI list.
Or do you consider salting as the solution for that situation?

(Verkehrsrot) #126

Salting prevents that MACs residing on site are identified. The price for this is that they are always counted. You could suppress this by footprinting or blacklisting devices, but i think this would be more intrusion in privacy than simply count them.


hi charles
what data type did you use for the counters?
digital output is only 1 byte. did you “abuse” a two byte type? e.g. temp or press?

could you please publish the mydata part?
thanks :slight_smile:


TTGO LoRa32 V2.1

(Verkehrsrot) #129

Looks like old software version.
Actual version shows LoRa SF and free memory on Display :slight_smile:


nice to see that they took a license on your hard work :wink:

(Verkehrsrot) #131

Meanwhile they contacted me and suggested a deal, still waiting for details. A version with case is also announced.

(Verkehrsrot) #132

Paxcouter v1.3.41 released

This version was successful tested in 14 days continous operation without any device resets on Heltec, TTGOv2 and Pycom Lopy. So it should run stable.

There are several major improvments since v1.3.0:

Non- functional:

  • Display refresh is now interrupt driven and centralized in code (solves race condition problem that somtimes caused garbage on display)
  • Wifi channel rotator is now interrupt driven, this avoids the previously blocking task
  • A simple continous running state machine in main loop avoids previously used delays
  • Bluetooth scanning is now build on native ESP32 functions, avoiding previously used arduino BLE library with (too) big footprint
  • LoRaWAN payload send loop is now decoupled from Wifi scan loop, giving a more precise timing for payload send trigger
  • Improved LED blinking, for digital as well as for RGB LED (thanks to @Charles)
  • low memory threshold implemented which prevents the device to reset while running in a memory leakage


  • actual LoRa SF-rate is now shown on display
  • free memory is shown on display


(Verkehrsrot) #133

“We have already modified our V2.0. Do you have any suggestions? DIO1 and DIO2 have been connected to GPIO32, GPIO33.”

(michellamie) #137

I have received the Heltec WIFI Lora 32 board. I did follow the GitHub instructions, but I’m stuck. Can someone give me some pointers?

I downloaded Atom and Platform IO IDE. I also installed the Espressif 32 Platform in Platform IO.
I downloaded and installed CP210x USB to UART Bridge VCP Drivers

Downloaded the GitHub zip and checked paxcounter.conf but looks ok default.

I created a new loraconf.h file and updated the 3 values with the key from the TTN and pasted the msb format

  • Device EUI
  • Application EUI
  • App Key

When I press the PlatformIO Build button I get some errors (see below).

You can toggle the Git tab with Ctrl+Shift+9
3.3 s
platformio run
src\main.cpp:127:12: error: 'RST' was not declared in this scope
.rst = RST,
src\main.cpp:128:13: error: 'DIO0' was not declared in this scope
.dio = {DIO0, DIO1, DIO2}

src\main.cpp:128:19: error: 'DIO1' was not declared in this scope
.dio = {DIO0, DIO1, DIO2}
src\main.cpp:128:25: error: 'DIO2' was not declared in this scope
.dio = {DIO0, DIO1, DIO2}
src\main.cpp: In function 'void sniffer_loop(void*)':
src\main.cpp:233:34: error: 'WIFI_CHANNEL_MAX' was not declared in this scope
channel = (channel % WIFI_CHANNEL_MAX) + 1;
src\main.cpp: In function 'void led_loop()':
src\main.cpp:443:32: error: 'HAS_LED' was not declared in this scope
digitalWrite(HAS_LED, HIGH);
src\main.cpp:450:32: error: 'HAS_LED' was not declared in this scope
digitalWrite(HAS_LED, LOW);
src\main.cpp: In function 'void setup()':
src\main.cpp:504:13: error: 'HAS_LED' was not declared in this scope
src\main.cpp: In function 'void loop()':
src\main.cpp:631:45: error: 'MEM_LOW' was not declared in this scope
if (esp_get_minimum_free_heap_size() <= MEM_LOW) {
*** [.pioenvs\heltec_wifi_lora_32\src\configmanager.cpp.o] Error 1
*** [.pioenvs\heltec_wifi_lora_32\src\main.cpp.o] Error 1
*** [.pioenvs\heltec_wifi_lora_32\src\macsniff.cpp.o] Error 1
 [ERROR] Took 2.67 seconds
Severity 	Provider 	Description	Line

(Verkehrsrot) #138

Looks like a corrupt paxcounter.conf file. Did you make any edits in it?
Please post your paxcounter.conf and platformio.ini here for further check.

(michellamie) #139

Based on your comments I found that the platformio.ini file was incorrect. I followed the steps again, used VSCode and PlatformIO now and compilation and upload to device worked without a issue. Also the scanning and refresh works! Except for the upload to The Things Network, maybe there is no gateway found. I don’t own one yet, on the map I see 2 gateways in Alphen aan den Rijn (medium city). How can I check if there is a gateway which I can use?

Or is the edit in the loraconf.h alone insufficient?

Google Photos

And a short video: https://photos.app.goo.gl/5SHYRQRjUyVAoW722

(Verkehrsrot) #140

Based on your comments I found that the platformio.ini file was incorrect.

Did you find an error in the platformio.ini in the repository, or was ist an erraneous edit?

How can I check if there is a gateway which I can use?

If the OTAA join does not go through, you are probably too far away or in a non covered area like inside building, etc. Try to test it outside on a high point with clear line of sight in direction of the gateway. If it still does not join, try to get closer to a gateway, e.g. go on a nice weather bike trip to Alphen :slight_smile: If it then still does not join, you either have wrong keys in your localconf.h, or gateway is offline or your board / antenna is not working properly.

Or is the edit in the loraconf.h alone insufficient?

You need three keys: DEVEUI, APPEUI, APPKEY.

The DEVEUI key is displayed on the paxcounter display during startup. Take a foto with your smartphone, look at it and write it down. Or open serial terminal in platformio, the DEVEUI is printed to the console during device startup.

To get APPEUI and APPKEY from TTN follow the steps below. Copy/paste the keys from TTN in your local file loraconf.h, as explained in loraconf.sample.h.

  1. Create TTN account
  2. Go to console - applications menu.
  3. Add application -> after this step you get the APPEUI. Copy/paste it to loraconf.h
  4. Register device -> enter the DEVEUI shown on paxcounter display during startup
  5. Press Register -> after this step you get the APPKEY. Copy/paste it to loraconf.h

With all keys entered in loraconf.h, build & upload code with platformio.

(Verkehrsrot) #141

TTNmapper shows 3 gateways in Alphen.
2 are single channel gateways, probably not suitable for OTAA join.
The 3rd one has very limited coverage:

Use the TTNmapper heatmap to check the coverage in or near your area, and go a red colored zone for testing. Zoom into the map until you see colored dots, not boxes, for fine tuning.


I had some difficulty in getting Paxcounter to join LoRaWAN. Turned out that I had provided DEVEUI and APPEUI in LSB instead of MSB format.

In loraconf.sample.h it is mentioned for APPEUI that it uses MSB format, but this is not mentioned for DEVEUI and because DEVEUI comes first I didn’t actually notice the MSB remark for APPEUI below it.

LSB format is what LMIC-Arduino normally uses for DEVEUI and APPEUI, so I just copy/pasted all three identifiers/keys from some of my other code. This did overwrite the MSB remark for APPEUI, not only with my DEVEUI and APPEUI keys in LSB format but also with comments that DEVEUI and APPEUI must be in LSB format (which is correct for LMIC-Arduino). I wasn’t directly aware of the cause of the issue because at first look everything appeared to be correct.

Suggestions for loraconf.sample.h:

  • Add a remark for DEVEUI that it uses MSB.
  • Clearly mention at the top that Paxcounter deviates from LMIC-Arduino in that it uses MSB instead of LSB format for DEVEUI and APPEUI.
    This makes it more clear but also prevents that inline comments about MSB get overwritten when copy/pasting the keys (in LSB format) from other code.

(Verkehrsrot) #143

i changed this in loraconf.sample.h