-
-
-
-
I see the value of firing on press when there is no other option and I understand also the issue of double press because of timing and queuing of the events. For that reason - and especially on app / context switch - repeat has to be disabled and the new context (app) has to arm the button again the way the app expects.
-
I'm not so sure if that is the only (or good) way to give the impression to be (more) responsive.
Why? If something 'goes off' on the press event, you cannot 'go back'. To still support long presses requires two different contexts and the awareness of them - action starts either on press or on release. To be aware of which context is active requires a visual cue.
My solution to give feedback - visual cue - to the user that the press has happen / is noticed - and I think it is all about that - can be conveyed differently, for example with a quick change / flash of a half circle or oval next to button.
The case of press event starts something is still a valid case, thinking about the cursor keys on a key board or the special character - character w/ diacritics - in pop-up. The response to such a press would be passing callback that is then called over and over on a configurable interval until release. Double press in rapid fashion is could be integrated as well in the event.
In the beginning when I had to use a single button interface vs a two - left and right - button interface, it created some relearning pain, but the value of dealing with just a track pad - position irrelevant - made up for a lot of it.
When building the UI - https://www.espruino.com/ui - visuals at https://forum.espruino.com/conversations/292990/ - I had to handle the touch this way... on touch a visual cue is give to the user about it: an element fence or border shows as a white rectangle, which goes away on un-touch (for speed sake redrawn in same place in background color... all on a 'big', 262K color serially connected - thus slow - display. On other occasions I was trying to save and restore, but that took ages, see https://forum.espruino.com/comments/11906513/. With Bangle2's limited color depth and speed, it should not be that a big issue to save the few pixels around the button and flip the around and then restore, or some other kind 'flash', noticeable by the user.
This kind of a visual cue could be a 'OS' level integrated option. It would also have to handle app-redraws of the area, so than on release the correct display is restored in this area.
Side note: touch screen vs. (single) button is not that much difference: touch is just setting the focus before treating the touch (or release), and w/ button, the select happens in a different way. Without touch there are two modes: navigation and (data) entry/edit mode. In navigation mode, a short press unselects current element and selects next element, a longer press switches into the entry and would also be either directly the return to navigation mode or to a (popup-) menu, that even allows a cancel / restore (and other - app - options). A single button UI needs absolute consistency in behavior for a 'happy' - not confused and giving up - user.
-
...oops... sorry @Coder2012 to have mysellf repeated.... figured by digging in the past...
-
The STM32 option from Waveshare mentions Nucleo STM32F103RB (https://www.waveshare.com/wiki/RGB-Matrix-P3-64x64#Working_with_STM32) is the 'same' chip as is on the Espruino Original board.... The software is a different story, though.
To drive the panel decently, it needs a dedicated controller to meet the timing requirements for a flicker free operation. The software has to pull all registers to use optimally the hardware and not the sosftware. Reading https://thepihut.com/products/interstate-75 tells me that there is not much juice left on a STM32F103RB - not from point of memory and cycles - to run and application on a source based interpreter (even though thins have sped up incredibly since Espruino's birth in the form of and on the Original board).
BUT: you could find a way to combine any Espruino with an STM32F103RB Nucleo board and run some smart and fast buffer transfer-sw on both boards. In the Espruino you use the Graphics object to build the Graphics.... after all - w/ a 24bit color depth - it is 64x64x3 = 12288 < 13kBytes Espruino graphics buffer that has to be transferred in the background from Espruino to the Controller where it is then displayed.
Conceptually you can compare it with what is described in Large Display: x by y w/ 24 bpp Graphics buffer visualized with neopixel string in zig-zag layout. I used Espruino (-Wifi) to for the application and the Graphics buffer, and a neopixel string as a combined controller and display. All was inspired by Retro Horse Derby Game Board with Neopixels showing Reaction Game Status.
The advantage of using neopixel is that there is no constant scanning required: each 8x8x8 color dot has its own memory and led driver. On the other hand, updating a 64x64 matrix with neopixels takes it's time since it is serial and can only be 800Kbps, which yields a max 8 fps (frames per second) using constant transfer. Going parallel allows higher frame rates.
You find more 'display stories' of mine in the forum to inspire you... such as Driving LED matrix with shift registers such as 74HC595, or ShiftOut question for Hannio flipDot Display or Retro Bubble Displays driven with 74HC595... it is all about the same...
For fast manipulation / transfer within graphics buffer I esperimented with embeded C functions. Efficiently moving things around in zig-zag Graphics buffer visualized w/ 24/32 bpp displays / neopixel strings. This technique can be used for a fast transfer from Graphics application board to Display controller board....
How snappy graphics could be depends all on the color depth and resolution.
-
-
-
Sorry for the confusion... updated the original post and repeat it here again for who ever will come across same need...
Getting cutting edge build: Go to the Espruino Download page,
Find a Binary
section,select the board
, and pick theCutting Edge build
link - at the bottom of the build(/release) list.Btw, list of ALL cutting edge Espruino builds is at espruino.com/binaries/travis/master/
-
The cutting edge build
espruino_2v19.123_wifi.bin
from https://www.espruino.com/binaries/travis/master/espruino_2v19.123_wifi.bin does it [EDITED: BUT WATCH: this is fluid... go to the Espruino Download page,Find a Binary
section,select the board
, and pick theCutting Edge build
link - at the bottom of the build(/release) list].> ____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |____|___| _|_| |___|_|_|_|___| |_| espruino.com 2v19.123 (c) 2023 G.Williams > 88.02419090270 wifi connecting... 00.74121856689 wifi connected >
...and it will be in 2v20 when that is released.
-
used the binary approach and figured that 2.15, 2.17, 2.18 work. So I doubted my earlier confirmation that 2v19 failed. But: it kept failing... So now back to 2v18... (and some chat w/ @Gordon).
I noticed that connection could be made within the range of 8..12 seconds, but failing was always within 10..11 seconds:
2v19 (c) 2021 G.Williams > 42.02763271331 wifi connecting... 52.05555248260 wifi connect error No 'ready' after AT+RST >
2v19 (c) 2021 G.Williams > 69.02761077880 wifi connecting... 79.05558586120 wifi connect error No 'ready' after AT+RST >
> ____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |____|___| _|_| |___|_|_|_|___| |_| espruino.com 2v18 (c) 2021 G.Williams > 00.02708053588 wifi connecting... 08.74545001983 wifi connected >
2v18 (c) 2021 G.Williams > 15.02713966369 wifi connecting... 23.73204612731 wifi connected >
2v18 (c) 2021 G.Williams > 17.02713966369 wifi connecting... 29.74073886871 wifi connected >
Disconnecting from power and reconnecting power, Espruino-Wifi, upload-run test code usually made it 12 seconds... but also got 8 seconds versions...
-
dug up my Espruino-Wifi... 2v01... a while updated it to 2v19 and and checked ESP8266 firmware:
var t = ` Ai-Thinker Technology Co.,Ltd. ready AT+GMR AT version:0.40.0.0(Aug 8 2015 14:45:58) SDK version:1.3.0 Ai-Thinker Technology Co.,Ltd. Build:1.3.0.2 Sep 11 2015 11:48:04 OK `;
Using just the Wifi connection part from your code w/ time added in loggin :
// EspruinoWifiCheck.js // 2024-01-08_ao // after update to 2v19 from 2v00, w/ ESP8266 v4.0 const WIFI_NAME = "<REDACTED>"; const WIFI_OPTIONS = { password : "<REDACTED>" }; const wifi = require("Wifi"); const t = (n) => { var t = getTime(); t=""+t; return t.substr(t.indexOf(".")-(n||2)); }; var wc = "wifi connect"; const connect = () => { console.log(t(),wc+"ing..."); wifi.connect(WIFI_NAME, WIFI_OPTIONS, (err) => { if (err) { console.log(t(),wc+" error", err); return; } console.log(t(),wc+"ed"); wc = "wifi re-connect"; }); }; const onInit = () => { wifi.on('disconnected', connect); connect(); }; setTimeout(onInit,999);
And to my dismay, I get nothing different than:
> ____ _ | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |____|___| _|_| |___|_|_|_|___| |_| espruino.com 2v19 (c) 2021 G.Williams > 83.02755451202 wifi connecting... 93.05551528930 wifi connect error No 'ready' after AT+RST >
You obvious dug further... My Wifi had still this Retro Horse Derby Game Board with Neopixels showing Reaction Game Status code on it, which was not (yet) using Wifi (the intent was to store game results via Wifi in some (google) doc / db in the cloud), but I know Wifi at worked before (obviously like your's too...).
I'll restore older Espruino version and try again...
-
I'm surprised that you do low-level communication to the ESP-##/ EX8266 module sitting on the Espruino-Wifi... Your code reminds me of using Pico with an ESP-01. As far as I recall, this is all hidden behind Espruino-Wifi firmware... No need to deal w/ GPIO pins and the like.
Take a look at this conversation EspruinoWiFi module builtin? and, for example, at this code example: EspruinoWiFi module builtin? - where Espruino-Wifi connects to the local Wifi and exposes a WebServer / interactive WebPage to control the train; and here is another example... not showing me in the best light, but it shows how to connect Espruino-Wifi and check the ip address your access point w/ DHCP give the connection Espruino/Wifi - getIP() returns undefined but callback receives null,ip.
Updating the onboard ESP-## is though a different story... but there is documentation about it... https://www.espruino.com/WiFi
(@Gordon, ooops, read
The Espruino WiFi board is now discontinued. We will be releasing a new WiFi + Bluetooth board in 2022
... I guess COVID-19 and related supply chain challenges ask for a special interpretation of the number 2022... :\ ) -
does your system already see STM32... before you initiate the connect? From what I understand, it should not already connect on the (operating) system level. When you connect, the browser should initiate and setup the connection using the serial device. 'Driver not found' tells me that the operating system has already communicated with Pico and tries now to find the driver for this device... I'd try to disconnect in the system setup and then try to connect in the Espruino IDE.
That you could update the firmware tells me, that you can connect when your system is in the right setup in regard w/ the USB-Serial... because: when you put Pico into flash mode, your system could not / did not connect or lost connection, but connected successfully when the flasher in the IDE initiated connection... and there it could obviously connect.
But take my thoughts with a rock of salt... I'm working in the Apple OS X context...
-
tried both... using 330 for baud rate failed no matter what - w/ and w/o E.setClock(). But the combination of lowering the clock rate of the UART using
E.setClock({M:8, N:336, P:4, Q:7, PCLK1:2, PCLK2:8});
and316bps
did the job (onSerial1/USART1
).What properties and values do I have to use in
E.setClock(...)
for usingSerial2/USART2
? -
thanks for taking the time to read and respond... I'll give it a shot, last but not least because I'm not successful yet with 'playing back' the received data, which means that either Espruino is not producing the right bit stream or the modulation/demodulation in the original case added something that was compensated in the device's receiving software.
Questions - answered them myself by reading the API doc... haha...:
- Is the
E.setClock(...)
also good for Serial2/USART2? - switched over to Serial2 from Serial1 - What is the impact of changing this for any other serial communication?
Btw, I noticed that the protocol is two (2) stop bits... (explaining the 'gap' of one bit between the bytes received).
I noticed that I never shared the code that does super-soft software serial in JS... Espruino JavaScript is so fast and efficient, that it can handle the 316 baud rate...
Main line is:
- have a single object for control and data to minimize scope for / optimize var look up (rather than have individual globals or a bunch of locals w/ multiple parameters passings - does it matter? @Gordon can debunk by thoughts...)
- setup to wait for first start bit in
wSB()
, start flank - sample start bit
sSB()
'half a bit later' (or a tad shorter - 1.47 instead of 1.57 ms... to not be/start late for sure... also trying to compensate not only for the setup of setWatch() but also for the setup of setInterval()... have though no clue if it and what value makes sense... I'm just thinking) - keep sampling remaining bits - mainly data bits - in
sDB()
in intervals of 'a bit later' until including all bits of a byte are done: data, parity and stop bits. Also handle / check parity and keep only 'good' bytes. Key concept used is the bit weight.w
that controls everything... (state of 'state machine'). - start over with waiting and sampling until done - stop stopRecSOD() is invoked from console (when device's transmit LED stops flickering), which sets a flag to not watch for stop bits anymore and clear eventual watch, but let eventual sampling finish.
- do hex dump for validation of bytes receive after waiting at least for a byte
Here the code (a bit formatted for legibility...):
// SWSerialInEspruinoJS.js // 20231228ao // var u; // = undefined constant var lon = true; // false; // true; // logging is on function log() { if (lon) { console.log.apply(console,arguments); } } // wire connections (in code use ums view names) // ums=pico view | ums view || ums pico var SOD=A3 // I | SOD O || serial out on USART2/1 SERIAL2/1 RX (A3/B7) I , SID=A2 // O | SID I || serial in on USART2/1 SERIAL2/1 TX (A2/B6) O ; function setPinModes() { // ums - pico view pinMode(SID,"output"); pinMode(SOD,"input"); } function hex(v) { return ((v>15) ? hex(v>>4) : "")+"0123456789ABCDEF".charAt(v&15); } // hex... function hep(v,ds) { // hex, digits (w/ blank padding up to ds) return (" "+hex(v)).substr(-ds); } function lep(v,ds) { // hex, digits (w/ 0 padded up to ds) return ("00000000"+hex(v)).substr(-ds); } var sod = { l: 2056 // length of d , d: [] // bytes as u8int array , f: 0 // fill level of d , wId: u // stop bit watch id , iId: u // data / parity / stop bit interval id , byt: 0 // byte , w: 0 // bit weight , pC: 0 // parity calculated , pR: 0 // parity received , pEC: 0 // parity error count , fEC: 0 // framing error count , r: 0 // running (status) }; sod.d = new Uint8Array(sod.l); function startRecSOD() { // uses: // wSB(): Watch SOD Start Bit // sSB(): Sample SOD Start Bit // sDB(): Sample SOD Data Bit and others too, incl parity handling // sPB(); Sample SOD Parity Bit - part of sDB() - no need, included in sDB // sTB(); Sample SOD sTop Bit - part of sDB() - no need, included in sDB if (sod.d.length !== sod.l) sod.d=new Uint8Array(sod.l); sod.f=0; sod.pEC=0; sod.fEC=0; sod.r=1; wSB(sod); // 314,157 ms full bit time / half bit time } function stopRecSOD(sAddr) { sod.r=0; if (sod.wId) sod.wId=clearWatch(sod.wId); setTimeout(function(){ // console.log(new Uint8Array(sod.buffer,0,_.f)); console.log("...stopRecSOD."); var arr=[], prtd=0, cols=16, addr = sAddr || 0; console.log( lep(addr,4) + "..." + lep(addr+sod.f - 1 - 1,4) + " + " + lep(sod.d[sod.f - 1],2) + " check byte: " + sod.f + " bytes ok, " + sod.pEC + " parity errs, " + sod.fEC + " framing errs" ); while (prtd<sod.f-1) { arr=[]; cols=16; arr.push(lep(addr,4)); arr.push(":"); while (--cols>=0 && prtd<sod.f-1) { arr.push(lep(sod.d[prtd++],2)); addr++; } console.log(arr.join(" ")); } },11*3.14); } function wSB(_) { _.byt=0; _.w=1; _.pC=1; if (_.r) { _.wId=setWatch(()=>setTimeout(sSB,1.47,_) ,SOD,{repeat:0,edge:"falling"}); } } function sSB(_) { _.iId=(!digitalRead(SOD)) ? setInterval(sDB,3.14,_) : wSB(_); } function sDB(_) { var b=digitalRead(SOD); if (_.w<256) { if (b) { _.byt+=_.w; _.pC^=b; } _.w=_.w<<1; } else { _.w=_.w<<1; if (_.w>512) { clearInterval(_.iId); if (b) { if (_.pC===_.pR) _.d[_.f++]=_.byt; else _.pEC++; } else { _.fEC++; } wSB(_); } else { _.pR=b; } } } function onInit() { setPinModes(); startRecSOD(); } setTimeout(onInit,999); // dev only; remove before upload for save()
Here the console output:
var t=` | __|___ ___ ___ _ _|_|___ ___ | __|_ -| . | _| | | | | . | |____|___| _|_| |___|_|_|_|___| |_| espruino.com 2v19 (c) 2021 G.Williams > startRecSOD... >stopRecSOD(0x800); =undefined ...stopRecSOD. 0800...080E + FC check byte: 16 bytes ok, 0 parity errs, 0 framing errs 0800 : 00 01 02 04 08 10 20 40 80 FF 0F F0 00 55 AA > `;
The code borrowed ideas from the device's implementation of reading serial input. Something next in line to simulate input for.
'Formatted' code looks a bit bloated... here the origin:
function wSB(_) { _.byt=0; _.w=1; _.pC=1; if (_.r) _.wId=setWatch(()=>setTimeout(sSB,1.47,_) ,SOD,{repeat:0,edge:"falling"}); } function sSB(_) { _.iId=(!digitalRead(SOD))?setInterval(sDB,3.14,_):wSB(_); } function sDB(_) { var b=digitalRead(SOD); if (_.w<256) { if (b) { _.byt+=_.w; _.pC^=b; } _.w=_.w<<1; } else { _.w=_.w<<1; if (_.w>512) { clearInterval(_.iId); if (b) { if (_.pC===_.pR) _.d[_.f++]=_.byt; else _.pEC++; } else { _.fEC++; } wSB(_); } else _.pR=b; } }
Now working on reading the data back: sending the data back to device as received before and stored in a 'file'. Even Espruino Software Serial is not producing a serial data stream accepted by the device. Playing w/ the 330 baud rate and E.setClock(...) gives me some hope until I will take out the 'big guns', like DSO... (My pride to be frugal in material but wasteful in thinking and time gets in my way for moving speedy... but it is somewhat the goal: understanding what's going on and where 'it' leaves the 'happy path'... (I'm part of the 'it'... haha...)...)
...so much for (late) Happy New Espruino Year 2024
- Is the
-
Using software serial moved me ahead a bit and may even be the solution...
Minimal change of the routine I had for hardware serial:
function receiveSOD() { var errs = true , serial = Serial1 ; serial = new Serial(); serial.setup(316, {rx:SOD, tx:SID, parity:"o", errors:errs }); serial.on('data', function (data) { print(data); }); if (errs) { serial.on('parity', ()=>console.log('P')); serial.on('framing', ()=>console.log('F')); } }
Console output for 0x0E byte sequence of:
Byte# 0x## 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E
Value 0x##: 00 01 02 04 08 10 20 40 80 FF 00 0F F0 55 AA
VALUE dec.: 0 1 2 4 8 16 32 64 128 255 0 15 240 85 170
var t=` > @ ÿ ð U ª ü > `;
With
ü
as being the CRC / checksum.Creating a version that prints the data in decimal to show non-printable
characters - changingprint(data);
toprint(data.charCodeAt(0));
-
shows the expected (values in) console:var t=` > 0 1 2 4 8 16 32 64 128 255 0 15 240 85 170 252 > `;
But as @Gordon pointed out in USART / UART / Serial Port for software serial, there is not much processing cycles left for other things while communication is going on, such as my attempt to print the received data in hex using my generic approach, which also can handle reception of more than one byte at a time. Here the changes and the versatile (hex) output creation (complete, runnable code to load):
// wire connections (in code use ums view names) // ums=pico view | ums view || ums pico var SOD=B7 // I | SOD O || serial output on USART1 SERIAL1 RX (B7) I , SID=B6 // O | SID I || serial input on USART1 SERIAL1 TX (B6) O ; function setPinModes() { // ums - pico view pinMode(SID,"output"); pinMode(SOD,"input"); } function hex(v) { return ((v>15) ? hex(v>>4) : "")+"0123456789ABCDEF".charAt(v&15); } // hex... function hep(v,ds) { // hex, digits (w/ blank padding up to ds) return (" "+hex(v)).substr(-ds); } function lep(v,ds) { // hex, digits (w/ 0 padded up to ds) return ("00000000"+hex(v)).substr(-ds); } function receiveSOD() { var errs = true , serial = Serial1 , opt ; serial = new Serial(); serial.setup(316, {rx:SOD, tx:SID, parity:"o", errors:errs }); opt = // 0 // 0 or any: just print as received (as initialy) // 1 // most unasumptional, flexibel hex output // 2 // assuming 1 byte at a time reception hex output 3 // assuming 1 byte at a time charCode (dec) output ; serial.on('data' , (opt==1) ? (function(data){ for (i=0; i++; i<data.length) print(lep(data.charCodeAt(i),2)); } ) : (opt==2) ? (function(data){ print(lep(data.charCodeAt(0),2)); } ) : (opt==3) ? (function(data){ print(data.charCodeAt(0)); } ) : (function(data){ print(data); }) ); if (errs) { serial.on('parity', ()=>console.log('P')); serial.on('framing', ()=>console.log('F')); } } function onInit() { setPinModes(); receiveSOD(); } setTimeout(onInit,999); // dev only; remove before upload for save()
With output option 1, the console output was absent... (a simpler implementation for 2-digit hex output may have worked, but was not done and tried).
For that reason, I built a buffering into/around the code with a routine for visualization of the buffer... shown in a next post, including the Espruino js Bitbanging solution (not using any appliances (except the timer/interrupts... as is used by setWatch, setTimeout, setInterval for that purpose).
-
@ser156811
Regarding hooking up scope: mentioned only the device. But hooking it to Espruino Pico USART1 and transmitting something with 300 (or 316) bauds would also provide new information, mostly so if it will go down that low...
@Gordon mostlikely can answer that right away and would also know how accurate timing is across the bandwidth. I know that at very high frequencies differences between bit times are very course grain (see Espruino controlling LC resonance experiment in HAM Radio class, in particular, post #4).
-
@ser156811
First, thank you for reading thru and sharing your thoughts.
Regarding speed, I had a similar thought: can Espruino Pico - the serial appliance of the STM32F401CDU6 - go so low down to 300 bps, but did not think about the divider issue... I should though have taken that though serious, since I know how USARTs (chips of same age) have to be configured...
I also had the thought of using Espruino firmware's software serial... but it may have the very same issue. After all, it uses the same basic hardware: some timer(s), relaying on the same counters...
There are server options for a next step before more serious actions have to be considered:
- Change Serial1 to a software
new Serial()
... very easy to do - The device has also an output only serial routine using similar bitbanging hardware and software, but with configurable baud rate, and it usually ran on 1200bps and can go up to 400bps. Disadvantages are: has no parity, no CRC (checksum), and disabling for full control of the device: it has output ONLY. The input is only for checking DTR.
- Making changes to the firmware of the device, posing several sub-options. The devices hardware is though too weak for a reasonable implementation of a configurable, bidirectional serial communication to implement serial with XON/XOFF flow control. Basically: there is no independent time or interrupt control used (and implemented in the devices monitor).
Hooking on a scope is an option... which I did 40+ years ago when validating the devices capabilities and putting it to service. Time fluctuations according to Espruino Poco's measurments are at it's most extreme in the range of 0.003152 thru 0.003157 (time of 1 bit), which is less than 0.2%. With that, I can comfortably exclude accuracy issues, but for sure not speed range ones.
New results will be available soon.
- Change Serial1 to a software
-
To cut to the chase:
Question: What do I do wrong that Espruino Pico's
Serial1.setup(300, {rx:B7, tx:B6, parity:"o"});
gets nothing for me but framing and parity errors?
To be more helpful, first some TL;DR:
I'd like to reuse - and showcase the device - but being it in the context and connectivity of more recent peripherals.
For exploration and possibly future interfacing, I picked Espruino Pico, because I have access to the device's TTL signal levels before it's fed into RS-232 drivers that do the typical -12V/+12V business or into FSK (Frequncy Shift Keying) communication over regular copper phone lines as of that time for remote operation. Commisurate with the means at that time is the speed: about 300 baud or 300 bps (bits per second) - Baud from French Baudot 5-bit code, invented 150+ years ago for telegraphy...
Espruino and Pico are a good match, for easy coding and quick to apply, and has TTL / 5V signal compatibility. Espruino software supports Serial communication with configuration option for number of data, parity and stop bits.
Unfortunately, for yet unknown reason, the code below
Serial1.setup(300, {rx:B7, tx:B6, parity:"o", errors:true}); Serial1.on('data', function (data) { print(data); }); if (errs) { Serial1.on('parity', ()=>console.log('P')); Serial1.on('framing', ()=>console.log('F')); }
prints nothing but
F
s for framing andP
s for parity errors for a block of0x20
0xAA
and another block of0x20
0x55
. Looking a the signal timings, it shows that a bit is around0.003148
seconds, yielding a rate of 318 bps. 18 is about a 6% error, over the 10-1/2 sampling times this makes worst case 63% 'off-beat'. Center sampling can at best handle a 40%..45% off-beat situation, so no surprise it failed... But I'm in for a greater surprise: even with setup adjusted to 318 bps, the result is equally depressing:PF
.Since the 40+ year old device is so slow, I just used Pico and a few lines of code to find the timings including baud rate AND visualization of the signal shape... The code looks like this:
var baudFindWId = null // baud find watch ID , ths, lst // this and last bit's Espruino getTime() , SOD = B7 // USART1 B7 rx - watching device's Serial Out Data ; function findBaud() { unfindBaud(); pinMode(SOD,"input"); lst = getTime(); baudFindWId = setWatch( function(s) { console.log( ( (s.state) ? "|_" // low signal for... : "_|" ) // high signal for... , (ths=getTime())-lst // ...t sec(s) before switching to high, rsp low ); lst=ths; }, SOD, {repeat:true, edge:"both", bounce:10} ); log("made SOD watched"); } function unfindBaud() { if (baudFindWId) { baudFindWId = clearWatch(baudFindWId); log("made baud unfound"); } else { log("baud is (already) unfound"); } }
The device was setup to transmit this sequence of 0x20 0x##s bytes (ignore
var t=...
js, it overcome render challenges of fixed font text blocks in forum... how to <pre> w/ line # but w/o coloring?):var t=` Byte# 0x##: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 .. 1f Value 0x##: 00 01 02 04 08 10 20 40 80 00 00 00 FF FF 0F F0 00 .. 00 CRC 0x##: FC ;`
The generated out put in console looks like this:
var t=` _| 9.82303428649 // <--- A) idle, since setup / before tx and |_ 0.02833652496 before start of 1st byte 0x00 _| 0.00949668884 // <--- B) before start of 2nd byte 0x01 |_ 0.00314712524 _| 0.00315475463 |_ 0.02518844604 _| 0.00633430480 // <--- C) before start of 3rd byte 0x20 |_ 0.00630855560 _| 0.00314426422 |_ 0.02202987670 _| 0.00633335113 // <--- D) before start of 4th byte 0x40 |_ 0.00944900512 _| 0.00314807891 |_ 0.01888561248 _| 0.00635814666 // <--- E) before start of 5th byte 0x80 |_ 0.01259136199 _| 0.00315093994 |_ 0.01572895050 _| 0.00633239746 // <--- F) before start of 6th byte 0x10 .... .... _| 0.00948810577 |_ 0.02837276458 // <--- G) unknown idle time after transmission `;
Since in above 'graph' the signal level line show NOT to time, I manually extended them according the times measured. I commented start bit, data bits 0 thru 7, odd parity bit, stop bit and the idle or byte separation 'bit'. With the extension, the signal lines make it very obvious what is going on:
var t=` Signal Level TTL Low 0 |Signal Level TTL High 1 || Bit type or value (start, value, stop, idle/'space'(:)) || | Bit # 0 (LSB) thru 7 (MSB) || | | Byte# - last is CRC - and Byte value 0x## || | | | seconds of equal signal level || | | | | (n) number of average || | | | | | time units of one bit VV V V V V V | : _| : | start #00 | 0 0 | 0 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 |_ 0 7 00 0.02833652496 (9) | odd | stop _| : 0.00949668884 (3) |_ start #01 0.00314712524 (1) _| 1 0 0.00315475463 (1) | 0 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 01 |_ odd 0.02518844604 (8) | stop _| : 0.00633430480 (2) | start #02 |_ 0 0 0.00630855560 (2) _| 1 1 0.00314426422 (1) | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 02 |_ odd 0.02202987670 (7) | stop _| : 0.00633335113 (2) | start #03 | 0 0 |_ 0 1 0.00944900512 (3) _| 1 2 0.00314807891 (1) | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 04 |_ odd 0.01888561248 (6) | stop _| : 0.00635814666 (2) ..... ..... ..... |_ 0.02839469909 (9) [#1D](https://forum.espruino.com/search/?q=%231D) _| 0.00951004028 (3) |_ 0.02837276458 (9) [#1E](https://forum.espruino.com/search/?q=%231E) _| 0.00948810577 (3) |_ 0.02837276458 (9) [#1F](https://forum.espruino.com/search/?q=%231F) | odd | stop _| : 0.01068019866 (3+...) - prep CRC | start CRC | 0 0 |_ 0 1 0.00946521759 (3) | 1 2 | 1 3 | 1 4 | 1 5 | 1 6 | 1 7 FC | odd | stop | : | : `;
End of
TL;DR
and back to the question:What is wrong with my setup of
Serial1
?Bitbanging shows that the device produces what it states... with the minor adjustment of the baud rate (which btw does not really matter, since the partner device is of the same make in hard and software (but I consider changing the device's code to be as close as possible to the 300 - or configurable - bps... after all, it does bit banging too, but no unpredictability by garbage collect or interrupts...). Bitbanging will also get me reading the device, but 40+ and the 32 Bit ST ... what ever should have outgrown that need... after all.
The device in today's money is about $1120... $290 then... Espruino Pico today cost about $25. Considering these numbers just from a point of money, would it be fair to conclude: You get what you pay for ? - The answer to that is an easy: no.
What do I do wrong in my Serial1 setup and use?
A Very Merry Christmas and Happy New Year to you, Gordon! - A well deserved break.