Serial Input on an ESP32
-
- Posts: 7
- Joined: Tue Dec 14, 2021 8:49 am
Serial Input on an ESP32
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 ?
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 ?
- Electroguard
- Posts: 852
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 273 times
- Been thanked: 321 times
Re: Serial Input on an ESP32
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.
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: 1979
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 425 times
- Been thanked: 1320 times
- Contact:
Re: Serial Input on an ESP32
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.[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.
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)
- Electroguard
- Posts: 852
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 273 times
- Been thanked: 321 times
Re: Serial Input on an ESP32
Ah, ok Francesco, so "terminated with RETURN" mentioned in OnSerial applies to the subroutine branch code, not the incoming serial data.The code must be terminated with ‘RETURN’
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: 1979
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 425 times
- Been thanked: 1320 times
- Contact:
Re: Serial Input on an ESP32
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).[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.
The simplest solution is simply to implement this in the code simply reading char by char until the reception of the given char
- Electroguard
- Posts: 852
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 273 times
- Been thanked: 321 times
Re: Serial Input on an ESP32
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
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
-
- Posts: 7
- Joined: Tue Dec 14, 2021 8:49 am
Re: Serial Input on an ESP32
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.
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.
- Electroguard
- Posts: 852
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 273 times
- Been thanked: 321 times
Re: Serial Input on an ESP32
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.Hello, i write this code:
However, it looks like you need to periodically reset A$="" to prevent it continuously growing too big.
-
- Posts: 7
- Joined: Tue Dec 14, 2021 8:49 am
Re: Serial Input on an ESP32
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.
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.
- Electroguard
- Posts: 852
- Joined: Mon Feb 08, 2021 6:22 pm
- Has thanked: 273 times
- Been thanked: 321 times
Re: Serial Input on an ESP32
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.
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.