Serial Input on an ESP32

Recurrent H/W and software problems
Basicfreak
Posts: 7
Joined: Tue Dec 14, 2021 8:49 am

Serial Input on an ESP32

Post by Basicfreak »

Hallo,
i have a problem with the serial input on an esp32. i send from an other prozessor data per serial port to the esp32. it works but only with the string funktion with the command SERIAL.INPUT$. The incomming Data are in String format. i had to receive many temperatures. Is there a way to receive many datas with the SERIAL.INPUT$ command and how can i separate the string into single variables to handle ?
User avatar
Electroguard
Posts: 277
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 55 times
Been thanked: 129 times

Re: Serial Input on an ESP32

Post by Electroguard »

Hi,

SERIAL.INPUT$ returns all the characters present in the input buffer of the serial port when ONSERIAL is triggered by an incoming RETURN character.
So if your sending device does not include the RETURN character after every temperature reading it sends, then the serial input buffer will receive multiple temperature readings without triggering ONSERIAL for each.
It will still need to be sent a RETURN character at some point, else the ONSERIAL will never be triggered to read any of the data sat in the input buffer.
And when the buffer is read, the contents will need to be parsed to separate out the individual temperature readings from the combined temp strings.

You haven't said what you are trying to achieve... but if you are wanting to avoid continuously responding too frequently to transmitted temperature readings you could use a timer to only periodically respond to incoming data - be aware that the example below is not complete or tested, it is merely a suggested strategy.

When the serial port is woken up the input buffer may have missed an earlier part of the incoming data, so discard the first ONSERIAl data, then keep the next full incoming ONSERIAL data, then turn ONSERIAL OFF again until the timer re-awakens it.

Code: [Local Link Removed for Guests]

TIMER1 Wakeup, 5 * 60 * 1000   '(every 5 minutes)
Wait

Wakeup:
ONSERIAL Discard     'discard the first partial buffer contents 
Return

Discard:
temp$=SERIAL.INPUT$    'read and discard first waking partial buffer contents
ONSERIAL GetTemp
temp$=""
return

GetTemp:
temp$=SERIAL.INPUT$    'read and keep the second complete buffer contents
ONSERIAL OFF                'turn serial off again
Return
cicciocb
Site Admin
Posts: 414
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 92 times
Been thanked: 297 times
Contact:

Re: Serial Input on an ESP32

Post by cicciocb »

[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Tue Dec 14, 2021 9:01 pm Hi,

SERIAL.INPUT$ returns all the characters present in the input buffer of the serial port when ONSERIAL is triggered by an incoming RETURN character.
So if your sending device does not include the RETURN character after every temperature reading it sends, then the serial input buffer will receive multiple temperature readings without triggering ONSERIAL for each.
It will still need to be sent a RETURN character at some point, else the ONSERIAL will never be triggered to read any of the data sat in the input buffer.
And when the buffer is read, the contents will need to be parsed to separate out the individual temperature readings from the combined temp strings.
Hi, Robin ( Electroguard ) what you report is not really exact as the ONSERIAL event is triggered as soon as the first character has been received and not when the RETURN character is received.
Probably the message is not received integrally because the ONSERIAL routine is called too early.
I suggest to put a little delay in the ONSERIAL triggered routine, for the time needed to acquire the complete message (generally few milliseconds)
User avatar
Electroguard
Posts: 277
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 55 times
Been thanked: 129 times

Re: Serial Input on an ESP32

Post by Electroguard »

The code must be terminated with ‘RETURN’
Ah, ok Francesco, so "terminated with RETURN" mentioned in OnSerial applies to the subroutine branch code, not the incoming serial data.
So Serial.Input$ works as a 'collection of chrs' rather than extracting complete terminated strings.
Which means there is no way for Serial.Input$ to actually parse out any terminated string(s), merely delaying Serial.Input$ as you suggested by a suitable guestimate to hopefully try to grab only one complete transmission.

But it might be possible to do both (either,or) if Serial.Input could have an optional 'delimiter' character capability similar to Word$ etc.
It could allow it to extract just complete terminated strings by returning only characters up to and including the optional delimiter, leaving any un-terminated characters still in the buffer.
Therefore repeated periodic use of Serial.Input$ (with the optional delimiter) could keep extracting any terminated strings as they become available.
And obviously Serial.Input$ could still function as before to return all buffer contents simply by not specifying an optional terminating delimiter chr.
cicciocb
Site Admin
Posts: 414
Joined: Mon Feb 03, 2020 1:15 pm
Location: Toulouse
Has thanked: 92 times
Been thanked: 297 times
Contact:

Re: Serial Input on an ESP32

Post by cicciocb »

[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Wed Dec 15, 2021 11:28 am Ah, ok Francesco, so "terminated with RETURN" mentioned in OnSerial applies to the subroutine branch code, not the incoming serial data.
So Serial.Input$ works as a 'collection of chrs' rather than extracting complete terminated strings.
Which means there is no way for Serial.Input$ to actually parse out any terminated string(s), merely delaying Serial.Input$ as you suggested by a suitable guestimate to hopefully try to grab only one complete transmission.

But it might be possible to do both (either,or) if Serial.Input could have an optional 'delimiter' character capability similar to Word$ etc.
It could allow it to extract just complete terminated strings by returning only characters up to and including the optional delimiter, leaving any un-terminated characters still in the buffer.
Therefore repeated periodic use of Serial.Input$ (with the optional delimiter) could keep extracting any terminated strings as they become available.
And obviously Serial.Input$ could still function as before to return all buffer contents simply by not specifying an optional terminating delimiter chr.
Yes, it could be possible to implement a kind of function like this but this will be a blocking function as the program will stop until the reception of the desired character (hence the timers / interrupts will stop to work).

The simplest solution is simply to implement this in the code simply reading char by char until the reception of the given char
User avatar
Electroguard
Posts: 277
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 55 times
Been thanked: 129 times

Re: Serial Input on an ESP32

Post by Electroguard »

Here is a possible strategy which might be used to extract out complete delimited strings from a collection of accumulating serial buffer characters.
Again, is not complete or tested, just a suggested direction...

After an OnSerial trigger, delay reading Serial.Input$ as CiccioCB suggested to allow enough time for several characters to be received.
Then add the delayed serial buffer contents to your own string, eg:
receivedData$ = receivedData$ + Serial.Input$

That will offer opportunity to parse out any complete terminated strings according to an appropriate delimiter
(from memory) Return = chr$(13), Linefeed = chr$(10), Space = chr$(32), etc

delimiter$ = chr$(13)
While Word.Count(receivedData$, delimiter$) > 0
data$ = Word$(receivedData$, 1, delimter$)
receivedData$ = Word.Delete$(receivedData$, 1, delimiter$)
Wend
Basicfreak
Posts: 7
Joined: Tue Dec 14, 2021 8:49 am

Re: Serial Input on an ESP32

Post by Basicfreak »

Hello,
i write this code:
''''''''''''''''''''''''''''''''''''''''''''''''''
' ANNEX WI-FI Basic
'Testprogramm für seriell Eingang
''''''''''''''''''''''''''''''''''''''''''''''''''
pause 2000
b = 0
a = 0
c = 0
d = 0

SERIAL.MODE 19200
light = 4 'Ausgang für Blitzlicht
pin(light) = 0 'Blitzlicht vom CAM Modul abschalten
onHtmlReload create_page 'Seite angeben für den 1. Start
'gosub create_page 'Seite darstellen
onserial daten_empfangen 'Sprungmarke für den seriellen Eingang

wait 'Warten auf Ereigniss


'*********************************************************************
create_page: 'hier wird die HTML Seite dargestellt

cls 'Seite löschen

'A$ = A$ + |<head><meta http-equiv=Refresh Content=20>| 'Seite wir alle 30 Sekunden aktualisiert
A$ = A$ + |<body><style>|
A$ = A$ + |body {background-color: blue}| 'Hintergrundfarbe Blau
A$ = A$ + |</style></body>|
html A$

html "<center>"
html "<h1> Status der Heizungsanlage</h1>"
html "<hr>"
html "<font size = 5 >"
html "<b>Aussen: "; a;" ° C <br>"
html "Warmwasser: "; b;" ° C"
html "<br>" + "<br>"
html "Pufferspeicher oben: "; c;" ° C"
html "<br>Pufferspeicher mitte: "; d;" ° C"

daten = 0

return
'************************************************************************

daten_empfangen:

daten = daten + 1

select case daten
case 1:
c$ = SERIAL.INPUT$
a = val(c$)

case 2:
c$ = SERIAL.INPUT$
b = val(c$)

case 3:
c$ = SERIAL.INPUT$
c = val(c$)

case 4:
c$ = SERIAL.INPUT$
d = val(c$)
end select

if daten = 4 then gosub create_page
if daten = 4 then daten = 0
return

This program works but very unstable. Somstimes it runs 2 Minutes, sometimes 30 Minutes but after that it stoppt and the only way to start it again is to turn off the power and restart the esp32.
Is there a problem in my code ?
The sending processor sends the data with 19200 baut and a waiting time 500 ms. As ich write it works but not good.
User avatar
Electroguard
Posts: 277
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 55 times
Been thanked: 129 times

Re: Serial Input on an ESP32

Post by Electroguard »

Hello, i write this code:
That doesn't give anyone else much to go on Basicfreak, so a quick explanation would have been helpful... particularly as it is dependent on unknown incoming serial data which we cannot know what is expected or how to replicate, and especially when the comments are not in forum english.


However, it looks like you need to periodically reset A$="" to prevent it continuously growing too big.
Basicfreak
Posts: 7
Joined: Tue Dec 14, 2021 8:49 am

Re: Serial Input on an ESP32

Post by Basicfreak »

Hello,
o.k. i see. I load up the program that is running on an Nano.
The Nano txt pin is direktly connectet with the esp 32 on pin GPIO3.

I hoop that this is more information you need.
You do not have the required permissions to view the files attached to this post.
User avatar
Electroguard
Posts: 277
Joined: Mon Feb 08, 2021 6:22 pm
Has thanked: 55 times
Been thanked: 129 times

Re: Serial Input on an ESP32

Post by Electroguard »

It looks like you are sending 4 different temperature values sequentially from the nano to the Annex32 device for it to display the different temperature readings in a web page - but you are re-writing the entire webpage after receiving each sequence of temperature readings, so a lot of html is being sent.

You don't need to keep clearing your webpage before displaying new data.
Use TEXTBOX$ to display the data rather than html

Better to write the webpage just once initially use textbox$'s for the 4 temperature readings and allow autorefresh to update their displayed values automatically using websockets without needing to keep sending html.

So at the top of the script you declare the variables which the textboxes will use, eg: a=0: b=0: c=0: d=0.

Create the web page, declaring CLS, Autorefresh, and your frills (but better to leave out frills until after everything works).
Initialise A$="" to blank before you start adding A$=A$+ more stuff else it will eventually overflow.
Html the 4 textboxes with the previously initialised temperature variables.


Whenever any of the 4 values change, autorefresh will update the textbox contents automatically using websockets.
Post Reply