-
There is enough space, however, all the signal processing is done by the SI4732 chip so the audio output goes straight to an amplifier. The ESP32 controls the SI4732 via I2C and does not get access to the audio output so sadly without a hardware mod, you cannot do things like Morse decoding which would be neat.
-
The firmware referenced above should work on the PineTime, however, I have not tried it. There are some pin out differences which you can find listed by @atc1441 here https://github.com/atc1441/ATCwatch/blob/master/ATCwatch/pinout.h. These can easily be dealt with by editing the Espruino device driver modules. There are quite a few different versions of the P8 with different accelerometers which can again be dealt with in Espruino code.
There are I think some posts from @fanoush on this topic (or comments on his Github repository).
-
Yes, some of those options might help, however, the code below proved the simplest most reliable driver.
function createEncoder(pinA,pinB){ pinMode(pinA,"input_pullup"); pinMode(pinB,"input_pullup"); var a0=pinA.read(), c0=pinB.read(), incr0 =0, second=false; var OBJ = {}; function handler () { var a = pinA.read(); var b = pinB.read(); if (a != a0) { // A changed a0 = a; if (b != c0) { c0 = b; var incr = (a == b)?-1:1; if (incr!=incr0 || !second) OBJ.emit("change",incr); incr0=incr; second = !second; } } } setWatch(handler,pinA,{repeat:true,edge:"both"}); return OBJ; }
-
These all-band (FM,LW,MW,SW with SSB) radios (see picture below) are available on AliExpress and Ebay. They consist of an SI4732-A10 chip which provides the radio functions driven via I2C by an ESP32 WROOM module which implements the display interface. This is an ILI9341 (with XPT2046 touch ) 320x240 pixel display.
There is an extensive well documented Arduino library for the SI4732 and a sketch which implements the firmware running on the pictured radio. The firmware can easily be updated from Arduino via the USB-C port at the rear of the radio. However, the combined library and sketch is over 10,000 lines of C++ which makes it cumbersome to change so I had a go at an Espruino version. So far I have implemented the FM only radio shown in the video:
There were a few technical challenges in getting this to work. Firstly, the display and touch controller share the SPI bus and while the screen SPI runs at 20MHz, touch only works with SPI at around 2MHz so you have to re setup SPI each time there is a touch interrupt. This generates a new SPI reference which needs to be passed back to the
lcd_spi_unbuf
driver. I implemented a simple additional function in this driver to pass back the SPI reference.
@Gordon have you met this issue before with the ILI9431 and XPT2046? - it's a very common display.Secondly, the rotary controller does two increments every click which is not ideal and the module in the Espruino library seems to generate a lot of spurious increments. I implemented a new driver based on an elegant idea outlined here.
Lastly, the rotary controller knob press switch is connected to D33 which cannot be used in
setWatch
in the current ESP32 Espruino. Indeed it did not work as a digital input at all so I implemented a simple polled routine which usedanalogRead
to detect the press event.I plan to extend the implementation with LW, MW and SW with SSB - the current Espruino S/W and Firmware can be found here.
-
The “p undefined” means that there is no graphics instance. Boot creates a dummy one which is overridden when you load “main”. As @fanoush mentioned if the lcd driver is not in the firmware then that would explain the error.
-
-
The driver is a mixture of
lcd_spi_unbuf
andlcd_spilcd
. You can send a minimum of 4 pixels to the screen which is why you need a buffer although there may be the possibility of reading pixels directly from the screen framebuffer. Using 32MHz SPI, I think the absolute maximum for writing 454 x 454 8 bit pixels would be 50ms, so 75 ms is not bad. The driver code needs cleaned up w.r.t comments/generality etc but you can see it here. -
There is now a port of Espruino to this NRF52840 watch which has a 454x454 AMOLED display. The watch can be operated in an always on mode in which the display takes approx 4ma with about 20% of pixels lit and 50-60% of full brightness. The G5 has a 290maH battery.
The current screen driver stores 4-bits per pixel (103Kbyte framebuffer) and takes around 75ms to do a full screen update with the screen set to 8 bits per pixel. The pictures below do not do justice to the display which is very sharp and bright.
It is necessary to open the watch to flash Espruino via SWD pins. Fortunately, it is not too difficult to open as the back is held on by four screws - however it is also glued and needs to be heat softened.
The G5 port is a team effort involving @fanoush and @yngv126399 with credit to atc1441 for discovering the watch and critical information like the location of the SWD pins.
-
-
-
Thanks Gordon, I will see what happens if I use that instead of disconnecting and reconnecting.
@Numerist Better to wait to see how this works out as it would make the operation much more lightweight.
-
-
That's really neat. I tried it on my Bangle and also an emulated Bangle (ROCK). On the Bangle, ROOT is the centre of the network while the ROCK has two centres Hidden Root and Timers - a much larger network since everything is written in Espruino. BTW - what network display code are you using? - the animation and layout is very impressive.
-
@Gordon Yes, I have the function implemented in my Bangle firmware, however, getting time does work if it is not defined. It is a bit frustrating as actually its not dealing with >1 central device, as you are connecting back to to the iPhone you are already connected to for ANCS. If you could get the address of the iPhone you are connected to then something like
getGattforCentralServer
would let you get the time without disconnecting and reconnecting. -
Actually, I have a bit of code that sets the Bangle time using the iPhone Time service. However, I did it as a quick hack from the original ANCS app and it is a bit clumsy as you must first be paired with the iPhone and the routine then disconnects and reconnects so that it can create the needed GATT service. The code is here if you would like to try it.
@Gordon - There must be an easier way of creating the GATT service since all the information must already be held internally? I am sure I am missing something obvious! -
-
-
-
It looks like they are both using the original threshold of 14 which is why the simulation with 17 is very different. @halemmerich I would be really interested in seeing these with the DCFilter - b77 has a strong positive bias. Happy to run the test harness if you can provide the files or you run it yourself using my version of the harness from here.
-
I have forked a copy of the test harness repository and added my copy of
stepcount.c
with the DCfilter. You can find the repository here. -
Thanks, here are the results for those files. First the current algorithm with threshold 17:
X_STEPS = 6, RAW_THRESHOLD = 17 File, Expected, Simulated, Diff, %, (Original) mrploppy_train1.csv, 0, 20, 20, 0.00 %, (61) mrploppy_train2.csv, 0, 6, 6, 0.00 %, (96) mrploppy_walk600.csv, 600, 577, -23, 96.17 %, (577) mrploppy_walk500.csv, 500, 575, 75, 115.00 %, (541)
and next the algorithm with the DCFilter and threshold 15:
NSAMPLE = 12 X_STEPS = 6, RAW_THRESHOLD = 15 File, Expected, Simulated, Diff, %, (Original) mrploppy_train1.csv, 0, 29, 29, 0.00 %, (61) mrploppy_train2.csv, 0, 0, 0, 0.00 %, (96) mrploppy_walk600.csv, 600, 590, -10, 98.33 %, (577) mrploppy_walk500.csv, 500, 563, 63, 112.60 %, (541)
It's marginal but in my view, the DCFilter helps here.
-
At threshold 14, the results are still pretty good:
NSAMPLE = 12 X_STEPS = 6, RAW_THRESHOLD = 14 File, Expected, Simulated, Diff, %, (Original) HughB-walk-6605.csv, 6605, 6135, -470, 92.88 %, (3223) HughB-walk-2350.csv, 2350, 2188, -162, 93.11 %, (1042) HughB-walk-a3070-b3046.csv, 3070, 2913, -157, 94.89 %, (1909) HughB-walk-a10021-b10248.csv, 10021, 10220, 199, 101.99 %, (12222) HughB-drive-36min-0.csv, 0, 53, 53, 0.00 %, (1199) HughB-drive-29min-0.csv, 0, 60, 60, 0.00 %, (1153) HughB-drive-a3-b136.csv, 3, 75, 72, 2500.00 %, (535) HughB-work-66.csv, 66, 81, 15, 122.73 %, (980) HughB-work-66.csv, 66, 81, 15, 122.73 %, (980) HughB-mixed-390.csv, 390, 465, 75, 119.23 %, (1871) HughB-general-a260-b573.csv, 260, 444, 184, 170.77 %, (3854) HughB-housework-a958-b2658.csv, 958, 2078, 1120, 216.91 %, (5762) MrPloppy-stationary-0.csv, 0, 0, 0, 0.00 %, (1) TOTAL DIFFERENCE 1709
10 still solves Mr Ploppy but I think it's too sensitive.
NSAMPLE = 12 X_STEPS = 6, RAW_THRESHOLD = 10 File, Expected, Simulated, Diff, %, (Original) HughB-walk-6605.csv, 6605, 6548, -57, 99.14 %, (3223) HughB-walk-2350.csv, 2350, 2268, -82, 96.51 %, (1042) HughB-walk-a3070-b3046.csv, 3070, 3082, 12, 100.39 %, (1909) HughB-walk-a10021-b10248.csv, 10021, 11388, 1367, 113.64 %, (12222) HughB-drive-36min-0.csv, 0, 120, 120, 0.00 %, (1199) HughB-drive-29min-0.csv, 0, 164, 164, 0.00 %, (1153) HughB-drive-a3-b136.csv, 3, 195, 192, 6500.00 %, (535) HughB-work-66.csv, 66, 154, 88, 233.33 %, (980) HughB-work-66.csv, 66, 154, 88, 233.33 %, (980) HughB-mixed-390.csv, 390, 663, 273, 170.00 %, (1871) HughB-general-a260-b573.csv, 260, 790, 530, 303.85 %, (3854) HughB-housework-a958-b2658.csv, 958, 3601, 2643, 375.89 %, (5762) MrPloppy-stationary-0.csv, 0, 0, 0, 0.00 %, (1) TOTAL DIFFERENCE 4092
With NSAMPLE=6 you lose too much low frequency I think and step counting suffers:
NSAMPLE = 6 X_STEPS = 6, RAW_THRESHOLD = 15 File, Expected, Simulated, Diff, %, (Original) HughB-walk-6605.csv, 6605, 5977, -628, 90.49 %, (3223) HughB-walk-2350.csv, 2350, 2091, -259, 88.98 %, (1042) HughB-walk-a3070-b3046.csv, 3070, 2775, -295, 90.39 %, (1909) HughB-walk-a10021-b10248.csv, 10021, 9506, -515, 94.86 %, (12222) HughB-drive-36min-0.csv, 0, 12, 12, 0.00 %, (1199) HughB-drive-29min-0.csv, 0, 53, 53, 0.00 %, (1153) HughB-drive-a3-b136.csv, 3, 26, 23, 866.67 %, (535) HughB-work-66.csv, 66, 54, -12, 81.82 %, (980) HughB-work-66.csv, 66, 54, -12, 81.82 %, (980) HughB-mixed-390.csv, 390, 356, -34, 91.28 %, (1871) HughB-general-a260-b573.csv, 260, 339, 79, 130.38 %, (3854) HughB-housework-a958-b2658.csv, 958, 1476, 518, 154.07 %, (5762) MrPloppy-stationary-0.csv, 0, 0, 0, 0.00 %, (1) TOTAL DIFFERENCE 1171
So 15 with NSAMPLE=12 worked best, however, I agree more data would be desirable.
-
I had a go with using a DC filter to remove the bias and here are the results. First. here is the simulated performance of the current Pedometer with
RAW_THRESHOLD = 17
:X_STEPS = 6, RAW_THRESHOLD = 17 File, Expected, Simulated, Diff, %, (Original) HughB-walk-6605.csv, 6605, 6215, -390, 94.10 %, (3223) HughB-walk-2350.csv, 2350, 2204, -146, 93.79 %, (1042) HughB-walk-a3070-b3046.csv, 3070, 2936, -134, 95.64 %, (1909) HughB-walk-a10021-b10248.csv, 10021, 9107, -914, 90.88 %, (12222) HughB-drive-36min-0.csv, 0, 52, 52, 0.00 %, (1199) HughB-drive-29min-0.csv, 0, 109, 109, 0.00 %, (1153) HughB-drive-a3-b136.csv, 3, 82, 79, 2733.33 %, (535) HughB-work-66.csv, 66, 68, 2, 103.03 %, (980) HughB-work-66.csv, 66, 68, 2, 103.03 %, (980) HughB-mixed-390.csv, 390, 408, 18, 104.62 %, (1871) HughB-general-a260-b573.csv, 260, 361, 101, 138.85 %, (3854) HughB-housework-a958-b2658.csv, 958, 1728, 770, 180.38 %, (5762) MrPloppy-stationary-0.csv, 0, 0, 0, 0.00 %, (1) TOTAL DIFFERENCE 1508
Now here are the results with using a DC Filter and reducing the threshold to 15:
NSAMPLE = 12 X_STEPS = 6, RAW_THRESHOLD = 15 File, Expected, Simulated, Diff, %, (Original) HughB-walk-6605.csv, 6605, 6054, -551, 91.66 %, (3223) HughB-walk-2350.csv, 2350, 2164, -186, 92.09 %, (1042) HughB-walk-a3070-b3046.csv, 3070, 2858, -212, 93.09 %, (1909) HughB-walk-a10021-b10248.csv, 10021, 9903, -118, 98.82 %, (12222) HughB-drive-36min-0.csv, 0, 45, 45, 0.00 %, (1199) HughB-drive-29min-0.csv, 0, 58, 58, 0.00 %, (1153) HughB-drive-a3-b136.csv, 3, 67, 64, 2233.33 %, (535) HughB-work-66.csv, 66, 65, -1, 98.48 %, (980) HughB-work-66.csv, 66, 65, -1, 98.48 %, (980) HughB-mixed-390.csv, 390, 407, 17, 104.36 %, (1871) HughB-general-a260-b573.csv, 260, 400, 140, 153.85 %, (3854) HughB-housework-a958-b2658.csv, 958, 1825, 867, 190.50 %, (5762) MrPloppy-stationary-0.csv, 0, 0, 0, 0.00 %, (1) TOTAL DIFFERENCE 1399
NSAMPLE is a parameter of the filter:
//Exponential Moving Average DC removal filter alpha = 1/NSAMPLE int DCFilter_sample_avg_total = 8192*NSAMPLE; int DCFilter(int sample) { DCFilter_sample_avg_total += (sample - DCFilter_sample_avg_total/NSAMPLE); return sample - DCFilter_sample_avg_total/NSAMPLE; }
@HughB It appears that the accuracy gets worse on your shorter walks and better on your longer walk with this approach.
The main advantage is that it deals with the Mr Ploppy problem even if you set the threshold as low as 10.
That looks interesting - did you develop an Espruino driver for the E-paper screen?