Author Topic: "Distance Alert", looking for inspiration for project.  (Read 9220 times)

0 Members and 1 Guest are viewing this topic.

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #25 on: January 19, 2022, 04:48:14 pm »
I meanwhile bought two ESP32-C3 devkit boards. I've cobbled together a small sketch that sends out iBeacon advertisements and at the same time listens to iBeacon packets from other transmitters. The C3 devkit has a neopixel LED on it, I guess I should be able to make it so that the color changes with the distance between the two boards. That will allow me to explore how the solution will behave in real life settings.
Everybody likes gadgets. Until they try to make them.
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #26 on: January 20, 2022, 10:11:30 pm »
This is the current prototype sketch for the ESP32-C3-DevKitM-1, which is based on the ESP32-C3-MINI-1 module. I'm using the Arduino IDE, simply because it had the lowest entry hurdle. I usually use a baremetal SDK or toolchain and Eclipse as the IDE but the Arduino framework has something going for it, which is it allows to quickly code up simple stuff.

The functionality implemented is quite simple but I don't think I will need more.

The sketch initializes a beacon and starts advertising it and configures a passive scan.

In the main loop, it scans for two seconds (passive scan), then evaluates the scan results, then goes to sleep for one second to save battery.

If a beacon was received during the 2 seconds, it simply goes back to sleep.

If a beacon was not received for 8 seconds, it enters "ALARM" mode. This is when the buzzer on both devices would go off. For now only the RGB LED on the board turns from green to red.

Both devices stay in ALARM mode until they receive a beacon with sufficient signal strength (-60 dBm). That is roughly equivalent to being an arms length away. So the buzzer would keep sounding until I was near to my son again.

I made an experiment today with my little daughter, asked her to walk away from me with the "don't go too far away"-device until the light turned red and then come back. The range in free area is quite remarkable, maybe 50 meters or more. I expected it to be less, but I can still introduce an artificial RSSI limit.

I haven't yet checked power consumption or optimized anything. This evaluation will decide whether I'll just use an ESP32 module or go for a fully custom design.

Code: [Select]
/*
   Based on Neil Kolban example for IDF: [url]https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp[/url]
   Ported to Arduino ESP32 by pcbreflux
*/


#include "BLEDevice.h"
#include "BLEUtils.h"
#include "BLEScan.h"
#include "BLEAdvertisedDevice.h"
#include "BLEBeacon.h"
#include "Adafruit_NeoPixel.h"
#include "esp_sleep.h"

#define ENDIAN_CHANGE_U16(x) ((((x)&0xFF00) >> 8) + (((x)&0xFF) << 8))

static BLEAdvertising *pAdvertising;
static BLEScan *pBLEScan;

// See the following for generating UUIDs:
// [url]https://www.uuidgenerator.net/[/url]
#define BEACON_UUID           "94e82029-3762-45f2-befb-7fd39711751f" // UUID 1 128-Bit (may use linux tool uuidgen or random numbers via [url]https://www.uuidgenerator.net/[/url])
#define SERVICE_UUID          "c9a70b84-027e-4cf5-b8d5-708f1f9956a1"

// NeoPixel
#define NEO_PIN 8
#define NEO_NUM 1

Adafruit_NeoPixel pixel(NEO_NUM, NEO_PIN, NEO_GRB + NEO_KHZ800);

static void setScan()
{
  pBLEScan = BLEDevice::getScan(); //create new scan
}

static void setBeacon()
{
  BLEBeacon oBeacon = BLEBeacon();
  oBeacon.setManufacturerId(ENDIAN_CHANGE_U16(0xDEAF));
  oBeacon.setProximityUUID(BLEUUID(BEACON_UUID));
  oBeacon.setMajor(0);
  oBeacon.setMinor(0);
  oBeacon.setSignalPower(-50);
  BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
  BLEAdvertisementData oScanResponseData = BLEAdvertisementData();

  oAdvertisementData.setFlags(0x04); // BR_EDR_NOT_SUPPORTED 0x04

  std::string strServiceData = "";

  strServiceData += (char)26;     // Len
  strServiceData += (char)0xFF;   // Type
  strServiceData += oBeacon.getData();
  oAdvertisementData.addData(strServiceData);

  pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->setAdvertisementData(oAdvertisementData);
  pAdvertising->setScanResponseData(oScanResponseData);
  pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND);

  // set advertising intervals
  pAdvertising->setMinInterval(500);
  pAdvertising->setMaxInterval(1000);
  pAdvertising->setMinPreferred(500);
  pAdvertising->setMaxPreferred(800);

  // Start advertising
  pAdvertising->start();
}

void setup()
{
  Serial.begin(115200);

  // Create the BLE Device
  BLEDevice::init("ESP32 as iBeacon");
  // configure beacon and scan
  setBeacon();
  setScan();

  // clear the pixel for now
  pixel.begin();
  pixel.clear();
}

void loop()
{
  static int alarmState = -1;
  static int lastRssi = 0;
  static int lastSeen = 0;
  bool beaconFound = false;
   
  // start a 2 second passive scan
  BLEScanResults foundDevices = pBLEScan->start(2, false);

  // check what we found
  for (int i = 0; i < foundDevices.getCount(); ++i) {
    BLEAdvertisedDevice advertisedDevice = foundDevices.getDevice(i);
   
      if (advertisedDevice.haveManufacturerData() == true) {
        std::string strManufacturerData = advertisedDevice.getManufacturerData();

        uint8_t cManufacturerData[100];
        strManufacturerData.copy((char *)cManufacturerData, strManufacturerData.length(), 0);

        if (strManufacturerData.length() == 25 && cManufacturerData[0] == 0xAF && cManufacturerData[1] == 0xDE) {
          lastRssi = advertisedDevice.getRSSI();
          beaconFound = true;
        }
      }
  }

  pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory

  if (beaconFound) {
    lastSeen = 0;
    // call off alarm only when in near vicinity
    if ((alarmState < 0 || alarmState == 1) && lastRssi > -60) {
      pixel.setPixelColor(0, 0, 32, 0);
      pixel.show();
      alarmState = 0;
    }

  } else {
    ++lastSeen;
    if ((alarmState <= 0) && lastSeen > 3) {
      pixel.setPixelColor(0, 32, 0, 0);
      pixel.show();
      alarmState = 1;
    }
  }

  Serial.printf("Beacon last seen %i cycles ago with RSSI %i dBm, ALARM %s\n",
    lastSeen, lastRssi, alarmState == 1 ? "ON":"OFF");

  // flush serial before going to sleep
  Serial.flush();
  // enter light sleep for one seconds
  esp_sleep_enable_timer_wakeup(1000 * 1000);
  esp_light_sleep_start();
}


Everybody likes gadgets. Until they try to make them.
 

Offline A.Z.

  • Frequent Contributor
  • **
  • Posts: 879
  • Country: it
Re: "Distance Alert", looking for inspiration for project.
« Reply #27 on: January 21, 2022, 12:58:32 pm »
Nice ! I'd just change the timings and use prime numbers to have a bit better distribution; an alternate approach could be listening for beacons and using a timer so that if a beacon isn't received for a given time, the device will go into alert mode, such an approach would avoid the poll and turn the code into event driven mode
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #28 on: January 21, 2022, 01:23:14 pm »
Nice ! I'd just change the timings and use prime numbers to have a bit better distribution; an alternate approach could be listening for beacons and using a timer so that if a beacon isn't received for a given time, the device will go into alert mode, such an approach would avoid the poll and turn the code into event driven mode

Thanks for the response and suggestion. I don't understand what you mean with "prime numbers" for the timing, though.

I still have to explore the BLE API a bit more to understand what can be made asynchronous with callbacks, and whether it's truly async to the loop() function or must from from its context. The BLEScan API hints that a scan can be started without waiting for completion, but then I need to check what happens while the device is in sleep mode.

I can imagine, that if the BT module can be a wakeup source, I could have a mainloop that does nothing but sleep indefinitely and only wake up when a beacon is received. But then power consumption would depend on how crowded the environment is. Maybe the hardware can do filtering and only generate a wake-up events for certain packets received.

But I'm getting ahead of myself.
Everybody likes gadgets. Until they try to make them.
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #29 on: January 24, 2022, 09:33:33 am »
The system architecture is coming together. For the first functional prototype I will sandwich a second PCB under the DevKit board, which will have a PMIC, piezo driver and a LiPo battery.

I'm going to use the BQ25015 as PMIC, it integrates a LiPo charger and a buck converter that can output up to 300mA. That should be enough for the use case. The PMIC will be wired such that it gets its charge voltage from the DevKit when it's connected to USB.

The piezo driver is just a small mosfet that will be driven by a PWM pin from the DevKit. I'm connecting it directly to the battery to give it some more "Oomf".

The battery is going to be a 250mAh LiPo pouch cell, 503020 type.

The piezo buzzer will be resonating at around 1kHz, I'm going to use a passive type without integrated driver.

I will have to remove the onboard 3.3V LDO from the DevKit, though.

I'll post the schematic when it's ready.
Everybody likes gadgets. Until they try to make them.
 

Offline A.Z.

  • Frequent Contributor
  • **
  • Posts: 879
  • Country: it
Re: "Distance Alert", looking for inspiration for project.
« Reply #30 on: January 25, 2022, 07:53:02 am »
Thanks for the response and suggestion. I don't understand what you mean with "prime numbers" for the timing, though.

It's mostly an idiosyncrasy of mine ;D what I meant was changing the code somewhat like

Code: [Select]
  pAdvertising->setMinInterval(503);
  pAdvertising->setMaxInterval(1009);
  pAdvertising->setMinPreferred(503);
  pAdvertising->setMaxPreferred(809);

  ...
 
  esp_sleep_enable_timer_wakeup(1000003);

that is using prime numbers for the timings, that way you'll obtain a bit better distribution of polls/beacons, but again, it was just off the top of my head

Quote
I still have to explore the BLE API a bit more to understand what can be made asynchronous with callbacks, and whether it's truly async to the loop() function or must from from its context. The BLEScan API hints that a scan can be started without waiting for completion, but then I need to check what happens while the device is in sleep mode.

I can imagine, that if the BT module can be a wakeup source, I could have a mainloop that does nothing but sleep indefinitely and only wake up when a beacon is received. But then power consumption would depend on how crowded the environment is. Maybe the hardware can do filtering and only generate a wake-up events for certain packets received.

Yes, my line of thought was to check if the library/API allows to setup callbacks, in such a case your code may just setup a callback and a timer, if a callback due to a received beacon arrives before the timer ticks the timer is cancelled and restarted, if not the timer increases a counter and (which gets reset by beacon callback) when the counter reaches a given value (say 3 or whatever) the timer callback code sends an audio alert and restarts the timer w/o resetting the counter, this way the device will "beep" at intervals as long as it doesn't receive a new beacon; hope it's clear, this way your code won't need to "loop" but will just setup the callbacks (beacon and timer) and do nothing until one of the callbacks is received, this will lower the load on the CPU and allow the battery to last longer


 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #31 on: January 25, 2022, 08:37:22 am »
Okay, thanks a lot for the explanation. I'll take your suggestion into account. I believe, though, that the BLE stack will choose the beacon intervals by itself within the bounds set by the min and max values.

Regarding the API - it seems scanning can be done asynchronously to the main loop function, the handling is performed in a separate thread. I'm not sure if it will be of any advantage unless it helps letting the chip sleep more. The synchronous scan function just waits on a semaphore until the scan handler thread signals completion. If I can send the chip into light-sleep during the scan and still get proper results, that would certainly help, though.

Schematic of the companion board attached.
Everybody likes gadgets. Until they try to make them.
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #32 on: January 25, 2022, 05:51:04 pm »
PCB done.
Everybody likes gadgets. Until they try to make them.
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #33 on: January 27, 2022, 03:48:47 pm »
I've researched on the topic of BLE power-saving strategy and it seems to be possible to drop down the current consumption to less than 10mA when configuring the power management to go into light sleep automatically. But only if there is an external 32kHz crystal available for the SoC to use for timekeeping during sleep, as the main oscillator is switched off then.

This means I will definitely have to make my own PCB with either a module or bare ESP32 SoC as the DevKit does not have a 32kHz crystal that could be used, and also the Arduino library is not compiled with the correct options.

Everybody likes gadgets. Until they try to make them.
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #34 on: February 13, 2022, 09:22:35 am »
I managed to get the first prototype board made, the PCBs have arrived meanwhile. Not yet fired them up but I already found I had a wrong resistor placed in the feedback path for the BQ25015. Also, as it turns out there's an error in the reference design I copied the BQ25015 circuit from, which would violate some abs-max constraint for its enable pin, but that will not be a problem for the initial testing. As soon as I replace the wrong resistor I can fire the thing up and then do some field testing.

Meanwhile I completed the schematic and PCB for the "final" device. As soon as I've validated the prototype, I will have a couple of them manufactured and can go for optimizing the power consumption.

Everybody likes gadgets. Until they try to make them.
 

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #35 on: March 05, 2022, 04:40:20 pm »
Finally got around to replacing the wrong resistor and connected a battery and power supply to see if the DC/DC converter and the charge circuit work: both seem to be OK.

In other news, I gave in to a year-long craving and bought a 3D printer. Now dabbling in constructing a case for the thing so that it can be carried on a belt or something. FreeCAD is a whiny b*tch.
Everybody likes gadgets. Until they try to make them.
 
The following users thanked this post: MK14

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #36 on: March 05, 2022, 05:49:37 pm »
Here's the case.
Everybody likes gadgets. Until they try to make them.
 
The following users thanked this post: MK14

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #37 on: March 30, 2022, 08:30:19 pm »
Just a quick update on the progress: I've meanwhile tested all the functional units of the circuit, charger, DC/DC converter, piezo buzzer driver, went through at least 3 iterations of the enclosure design as I learned about sketches, constraints and parameters in FreeCAD.

Wasted a lot of PLA printing the parts, too (3D printers sure are fun!).

Next step: launch final PCBs and have as many components assembled by JLCPCB as are in stock. Unfortunately, the BQ25015 doesn't seem to be available at LCSC and so they will not be able to place that part. Unfortunate, but not a deal breaker.

I keep you posted.
Everybody likes gadgets. Until they try to make them.
 
The following users thanked this post: MK14

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #38 on: April 12, 2022, 04:21:45 pm »
So, yesterday something unexpected happened, and today something even less expected happened.

When JLCPCB finished the boards and DHL Express picked it up, they gave an expected delivery date some time next week. I wouldn't be at home then so i scheduled a delivery for the week after. Now, yesterday I checked on the delivery status (as you do), and the said the shipment was already in the local distribution center and would stay there until the scheduled delivery was up.

Naturally (as you do) I rescheduled the delivery for today and indeed a couple hours ago it showed up at my door.

So, I transplanted a BQ25015 from a spare out of the previous prototype run, connected a battery, hooked it up my laptop, fired up the Arduino IDE and lo and behold, was able to program the sketch and it worked right out of the box. Even the sketchy CP2102 I glued on last minute to make development and future firmware updates easier worked. No magic smoke, nothing.

I'm literally shaking of joy. Or, it's that third cup of coffee I had for lunch today.  :scared:
Everybody likes gadgets. Until they try to make them.
 
The following users thanked this post: cgroen, MK14, Bicurico

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
Re: "Distance Alert", looking for inspiration for project.
« Reply #39 on: April 13, 2022, 10:05:27 pm »
Alright, time for a quick update:

I switched from the Arduino IDE to Eclipse and the Espressif plugin for ESP32 and after a bit of tinkering I was able to put together a test program that uses power management, tickless idle and modem sleep while advertising a BLE beacon. It wasn't working initially, but I guessed that the 32khz crystal was probably off frequency, and indeed, after removing the two load capacitors, I can now receive the BLE beacons on my Android phone.

Next step will be to get the scanning going and then it will be time to optimize power consumption and write the actual software.
Everybody likes gadgets. Until they try to make them.
 
The following users thanked this post: MK14

Offline thinkfatTopic starter

  • Supporter
  • ****
  • Posts: 2150
  • Country: de
  • This is just a hobby I spend too much time on.
    • Matthias' Hackerstübchen
[DONE] "Distance Alert", looking for inspiration for project.
« Reply #40 on: July 10, 2022, 12:43:03 pm »
I feel I should give closure to this project. It is mostly complete, the hardware is done, the software is mostly functional for the intended purpose, the only thing left is fine tuning of parameters and trying to make it as convenient as possible.

I've attached some photos of the final hardware. The case is 3D printed out of blue PETG, I think it turned out well.

The PCB is 55mm by 36,6mm, the size is mainly dominated by the battery, which is a 40x30x4 mm LiPo pouch cell with 500mAh capacity. The PCB itself could by way smaller still. But I don't want to spend time on it, unless I decide to make more of them to sell: initial feedback from other parents of kids with the same genetic condition were positive.

I was able to characterize the power consumption and it mostly depends on how long the ESP32 can spend in "light sleep", and that in turn depends on the advertisement and scan intervals.

An interesting complication was, and still is, the 32kHz sleep clock. I can't seem to get it quite right. I computed the load capacitors to be around 15pF, based on the xtal datasheet, but when I place them, the oscillation becomes unstable. It's also a couple Hz off. I had best results with two 5.8pF capacitors, or none at all, but on one board the oscillator frequently wouldn't start at all of I don't place the caps. So, something's marginal here and that doesn't instill full confidence. Unfortunately, unlike for the STM32, there is no detailed design procedure for the oscillators and no part recommendations. The reference manual only states to choose the load capacitors to be compliant with the crystal datasheet. Well, that's what I did and it didn't work.

The first "field tests" were successful, though. Another topic I might pick up is writing an Android app so that one of the devices could be replaced by a smartphone.

Thanks to all who tagged along, cheerio for now.

Everybody likes gadgets. Until they try to make them.
 
The following users thanked this post: RoGeorge, MK14

Online RoGeorge

  • Super Contributor
  • ***
  • Posts: 6186
  • Country: ro
Re: "Distance Alert", looking for inspiration for project.
« Reply #41 on: July 10, 2022, 04:49:17 pm »
Congratz!  :-+
 
The following users thanked this post: MK14, thinkfat

Offline mag_therm

  • Frequent Contributor
  • **
  • Posts: 658
  • Country: us
Re: "Distance Alert", looking for inspiration for project.
« Reply #42 on: July 10, 2022, 06:58:45 pm »
Congratulations on the project.
My son with DS is now 18, and when younger, crowds alleyways museums  etc were a significant challenge.
I tried a commercial version of what you have built which also had a crude direction indicator,
but it was too troublesome ( not really fit for purpose )  and I only used it about 2 times.

Now he has a an ordinary cell device and uses sms  email , and the video phone.

When I looked a cell phone location apps a few years ago the main item was the costly subscription.
Not sure if same now.
 
The following users thanked this post: MK14, thinkfat


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf