Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 15:45 12 Nov 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Problem with ESP-01 ESP8266 & Nucleo-L432

Author Message
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3470
Posted: 02:14am 17 Feb 2019
Copy link to clipboard 
Print this post

I had previously run the MM2+ESP-01 webserver posted by matherp here:
MM2: webserver with AT mode ESP8266

I'm trying to port it to the Nucleo-L432KC on a breadboard with a breakout board for the ESP-01. I can connect to wifi with the modified program, so there is successful communication with the ESP-01, but the program never gets back an ungarbled HTTP response.

I've connected RX on a CH340 USB/serial module to RX on the Nucleo board, and I can see that the HTTP response from the ESP-01 is perfectly OK, e.g.,
[code]
+IPD,0,359:GET /favicon.ico HTTP/1.1
Host: 192.168.1.210:1234
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.109 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://192.168.1.210:1234/
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
[/code]
This is an example of what the program prints:
[code]
nparams: 0: ||
Z!Q51± like Gecko) Chrome/72.0.3626.109 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
[/code]
(This is at 9600 baud. It was much more garbled at the baud rate where I started, 115200, though the connection to wifi worked at that baud rate.)

If I force the parsed input to be "INDEX", the web page is presented perfectly (at, on my system, http://192.168.1.210:1234/ in the chrome browser).

I don't have any sensors on the breadboard at present. My ESP-01 RX & TX connections to the nucleo board are to D1 USART1-TX and D0 USART1-RX, respectively.


What am I doing wrong?

(Code attached.)
2019-02-17_121201_ATWIFI-esp8266_L4x.zip Edited by lizby 2019-02-18
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3470
Posted: 04:58pm 17 Feb 2019
Copy link to clipboard 
Print this post

Essentially the same program works on the H7, mm.ver=5.05.03, except that there is a continual non-terminating error relating to the AT command "CIPSEND" (which I've ignored), and there is some chatter from the ESP-01 which I haven't yet been able to filter out (just starting to try).

There is also a terminating error with TEMPR START followed by TEMPR (but that may be the result of having no DS18B20 attached).

Other than that, the html page is rendered properly with the H7. This is with the ESP-01 set at 9600 baud. At other speeds (57600 & 115200) I haven't gotten reliable responses.


Edited by lizby 2019-02-19
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10572
Posted: 08:33am 18 Feb 2019
Copy link to clipboard 
Print this post

I'm trying to replicate but struggling with my ESP-01 which I updated to the latest release and am having a problem with CIPSEND which is only working once even using the original MM2 code.

On the H7 I can connect and I can receive the page request perfectly well at 115200 baud. Make sure you are using the very latest H7 firmware and most importantly check the power supply to the ESP. They are very hungry and very noisy. On my backpack I feed a 100uF capacitor in series with a 0.1uF cap through a 2R2 resistor to isolate the ESP.

On the L4 make sure of the power supply and then try removing all pause statements from the code. During pauses on the L4 the CPU clock is set down to 2MHz to save power and it may be possible that at this speed the CPU is too slow to buffer the incoming data. I'll try and check this later today and if necessary change the code to leave the CPU speed if a com port is active. The port itself works on a different clock so isn't impacted by CPU speed changes.

UPDATE

Please try this version on the L4, This doesn't slow the CPU during pause if one of the com ports is active. Works for me at 115200.

2019-02-18_202911_ArmmiteL4.zip

UPDATE UPDATE

For reasons I don't understand Chrome doesn't like port 1234. This code is tested on an L4 using above release and port 80 and works properly at 115200. Code includes lots of diagnostic prints

Option explicit
option default NONE
const MaxLen=4096
const max=20

' Global variables
const quote=chr$(34)
CONST SSID$=quote+"mySSID"+quote
CONST SSIDPassword$=quote+"myPASSWORD"+quote
'
const starttext$="HTTP"
const pnf$="<html><body>Page not Found</body></html>"
const title$="<html><head><title>Remote Thermostat</title></head><body>"
const ending$="</form></body></html>"
const form$="<form name='f1' method='get' action='D'>"
const h2$="<h2 align='left'>Remote Thermostat V3.0</h2>"
const code$="Update Code: <input type='text' name='S' size='6' value='000000'><br>"
const tstart$="<p><TABLE BORDER='1' CELLSPACING='0' CELLPADDING='5'>"
const heat$="<TR><TD>Heating</TD>"
const hon$="<TD BGCOLOR='#ff0000'> On</TD></TR>"
const hoff$="<TD BGCOLOR='#00ff00'>Off</TD></TR>"
const tend$="</TABLE></p>"
const h3$="<TR><TD></TD><TD>Temperature</TD></TR>"
const s1$="<TR><TD>Current</TD><TD>"
const s2$="<TR><TD>Max</TD><TD>"
const s3$="<TR><TD>Min</TD><TD>"
const check$="<input name='C' type='checkbox' value='R' onClick='this.form.submit()'> Reset Max/Min"
const s4$="<TR><TD>Thermostat</TD>"
const s5$="<TD><input name='R' type='radio' checked='checked' value='"
const s6$="<TD><input name='R' type='radio' value='"
const click$=" 'onClick='this.form.submit()'> "
const degree$="°C<br></TD>"
const offstr$="Off<br></TD>"
const onstr$="On<br></TD>"
const ON=1
const off=0
'
' Set up parameters
'
const starttemp=20 'set the lowest temperature on the thermostat select radio buttons
const hysteresis=2 ' 2 tenths of a degree either side of the setpoint
const waittime=1000 'wait time in readrequest before timeout
const password$="123456" 'password to access change mode


'
const dspin=28
const relaypin=26
'
Dim arg$(2,max) length 20
DIM integer inbuf(Maxlen\8) 'global input buffer
dim string CRLF=chr$(13)+chr$(10) length 2

dim integer IPDno 'global IPD numbers used to ensure transmit is on correct IPD
dim integer heater,currenttemp,maxtemp,mintemp,setpoint
dim integer nparams
dim mypage$ 'variables used by main loop only
DIM obuff$="" 'used to buffer writes to the internet to optimise speed
Init:
TEMPR start dspin,3 'measure temp to 0.0625 degree accuracy
mintemp=1000 'set to silly value to force reset if not saved
maxtemp=-1000
currenttemp=cint(TEMPR(dspin)*10)
TEMPR start dspin,3
var restore 'recover the setpoint and min and max temps if already saved
maxmin 'update the maximum and minimum and save them if changed
heater=off
pin(relaypin)=heater
setpin relaypin,dout
setpoint=asc("E")
pause 2000 'wait for ESP8266 to wake up afer power on
open "com1:115200,4096" as #1
close #1 'clear the buffer
open "com1:115200,4096" as #1
IF NOT Command("AT",500) THEN END
IF NOT Command("AT+RST",10000,"WIFI GOT IP") THEN 'reset and check for valid connection
PRINT "Set up WIFI on SSID: ",SSID$
IF NOT Command("AT+CWMODE_DEF=1",5000) THEN END 'set device mode (1=client, 2=AP, 3=both)
IF NOT Command("AT+CWLAP",30000) THEN END 'scan for WiFi hotspots
longstring print inbuf() 'output the list of valid networks
IF NOT Command("AT+CWJAP_DEF="+SSID$+","+SSIDPassword$,20000,"WIFI GOT IP") THEN END 'connect
IF NOT Command("AT+CIFSR",5000) THEN END 'check IP address
ENDIF

IF NOT Command("AT+CIPMUX=1",5000) THEN END
IF NOT Command("AT+CIPSERVER=1,80",5000) THEN END
Print "Connected"
IF NOT Command("AT+CIPSTATUS",30000) THEN END 'scan for WiFi hotspots
longstring print inbuf() 'output the list of valid networks

main:
DO
currenttemp=cint(TEMPR(dspin)*10)
updateheater
TEMPR start dspin,3
maxmin 'update the maximum and minimum and save them if changed
if ReadRequest(waittime) then 'process HTML request
mypage$=ucase$(parsehtmldata$(nparams)) 'parse the html request and get the page requested
if mypage$<>"" then 'real request so do something
if mypage$= "INDEX" then
drawpage
elseif mypage$="D" then
if nparams<>0 then 'we have parameters to process
if arg$(0,0)="S" and arg$(1,0) = password$ then
if arg$(0,1)="C" and arg$(1,1)="R" then 'reset the max min to current
maxtemp=currenttemp
mintemp=currenttemp
var save setpoint,maxtemp,mintemp
endif
if arg$(0,1)="R" then 'change the setpoint and update the heater if applicable
setpoint=asc(arg$(1,1))
var save setpoint,maxtemp,mintemp
updateheater
endif
endif
endif
drawpage
else
SendText pnf$+crlf+crlf'invalid page
endif
EndSend 'clear the write buffer and terminate the write
endif
endif
LOOP
end
'
Function parsehtmldata$(paramcount as integer) as string
local a$,b$
local integer buf(Maxlen\8)
local integer inpos,startparam,processargs
paramcount=0
inpos=lInstr(inbuf(),"GET /",1)
if inpos=0 then
parsehtmldata$=""
else
longstring RIGHT buf(),inbuf(),inpos+5
inpos=lInstr(buf(),starttext$,1)
If inpos>2 Then 'page request found
inpos=inpos-2
a$=lGetStr(buf(),1,inPos)
inpos=Instr(a$,"?")
If inpos<>0 Then 'parameters found
processargs=1
parsehtmldata$=Left$(a$,inpos-1)
a$=Mid$(a$,inpos+1)
Do
arg$(0,paramcount)=""
arg$(1,paramcount)=""
inpos=Instr(a$,"=")
startparam=1
arg$(0,paramcount)=Mid$(a$,startparam,inpos-startparam)
startparam=inpos+1
inpos=Instr(a$,"&")
If inpos<>0 Then
arg$(1,paramcount)=Mid$(a$,startparam,inpos-startparam)
a$=Mid$(a$,inpos+1)
paramcount=paramcount+1
Else
arg$(1,paramcount)=Mid$(a$,startparam)
paramcount=paramcount+1
processargs=0
EndIf
Loop while processargs
Else
parsehtmldata$=a$
EndIf
Else ' no page requested
parsehtmldata$="INDEX"
EndIf
endif
End Function

sub maxmin
local integer update=off
if currenttemp>maxtemp then
maxtemp=currenttemp
update=on
endif
if currenttemp<mintemp then
mintemp=currenttemp
update=on
endif
if update then var save setpoint,maxtemp,mintemp
end sub

sub updateheater
local integer hcalc
if setpoint=asc("L") then
pin(relaypin)=ON
heater=on
endif
if setpoint=asc("A") then
pin(relaypin)=OFF
heater=oFF
endif
if setpoint>=asc("B") and setpoint<=asc("K") then
hcalc=(setpoint-asc("B")+starttemp)*10 'setpoint temperature * 10
hcalc = hcalc + hysteresis
if currenttemp>=hcalc then 'turn heating off
pin(relaypin)=OFF
heater=oFF
endif
hcalc = hcalc - hysteresis - hysteresis
if currenttemp<=hcalc then 'turn heating on
pin(relaypin)=ON
heater=oN
endif
endif
end sub

sub drawpage
local integer loopcounter,tempconvert
local b$
sendText title$+form$+h2$+code$
sendText tstart$+heat$
if heater then
sendText hon$+tend$
else
sendText hoff$+tend$
endif
sendText tstart$
sendText h3$
b$=s1$+outtemp$(currenttemp)+degree$
b$=b$+s2$+outtemp$(maxtemp)+degree$
b$=b$+s3$+outtemp$(mintemp)+degree$
sendText b$
sendText tend$
sendText check$
sendText tstart$
sendText s4$
for loopcounter=asc("A") to asc("L")
if loopcounter=setpoint then
sendText s5$+chr$(loopcounter)
else
sendText s6$+chr$(loopcounter)
endif
sendText click$
tempconvert=loopcounter-asc("B")+starttemp
if loopcounter>asc("A") and loopcounter<asc("L") then sendText str$(tempconvert,2)+degree$
if loopcounter=asc("A") then sendText offstr$
if loopcounter=asc("L") then sendText onstr$
next loopcounter
sendText tend$
sendText ending$+crlf+crlf
end sub
'
function outtemp$(t as integer)
local integer tenths=t mod 10
local integer units= t\10
outtemp$=str$(units,3)+"."+chr$(tenths+48)
end function
'

sub EndSend
local b$
b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(len(obuff$)) 'send anything still in the buffer
IF NOT Command(b$,500,">") THEN
if lInstr(inbuf(),"link is not valid") then exit sub
endif
IF NOT Command(obuff$,500) THEN END
IF NOT Command("AT+CIPCLOSE="+CHR$(IPDno+48),500) THEN
if lInstr(inbuf(),"UNLINK") then
obuff$=""
exit sub
else
end
endif
endif
obuff$=""
end sub

sub SendText(a$)
local b$
if len(a$)+len(obuff$)< 240 then 'add the new string to the output buffer
obuff$=obuff$+a$
else 'too big to fit so send the current output buffer
b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(len(obuff$))
IF NOT Command(b$,1000,">") THEN
if LInstr(inbuf(),"link is not valid") then
print "link is not valid"
exit sub
endif
endif
print obuff$
IF NOT Command(obuff$,2000) THEN END
obuff$=a$
endif
end sub
'
FUNCTION ReadRequest(timeout%) as integer
ReadRequest=0
longstring Clear inbuf()
timer=0
do while TIMER<timeout% and LOC(#1)=0
loop
pause 50
if TIMER>=timeout% then exit function
do while loc(#1)<>0
longstring append inbuf(),input$(min(255,loc(#1)),#1)
loop
if (NOT lInstr(inbuf(),"favicon",0)) and (NOT lInstr(inbuf(),"CONNECT FAIL",1)) then ReadRequest=1 'junk the favicon requests and disconnects
IF lInstr(inbuf(),"IPD,0",1) then
IPDno=0
print "IPDno = ",IPDno
endif
IF lInstr(inbuf(),"IPD,1",1) then
IPDno=1
print "IPDno = ",IPDno
endif
end function
'

end sub
'
FUNCTION Command(AT$, timeout%, other$) as integer 'send a command and wait for the answer
local i%=0,j%,ex%=0
Local a$
Command=0
longstring Clear inbuf()
print #1,AT$+crlf;
TIMER=0
i%=0
do
if TIMER>timeout% then
ex%=0
EXIT DO
endif
j%=LOC(#1)
if j%>0 then
i%=i%+min(255,j%)
longstring append inbuf(),input$(min(255,j%),#1)
if llen(inbuf())>4 and other$="" then
if lInstr(inbuf(),"OK",1) then
ex%=1
exit DO
endif
endif
if llen(inbuf())>7 then
if lInstr(inbuf(),"ERROR",1) then
ex%=2
exit DO
endif
endif
if llen(inbuf())>len(other$)+2 then
if lInstr(inbuf(),other$,1) then
ex%=3
exit DO
endif
endif
endif
loop
select case ex%
case 0
Print "Timeout : "+AT$
case 1
Command=1
case 2
Print "ERROR : "+AT$
case 3
Command=1
end select
end function
Edited by matherp 2019-02-19
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3470
Posted: 03:26pm 18 Feb 2019
Copy link to clipboard 
Print this post

Thank you very much for this. I have a day trip planned for today, so probably won't get to it until this evening or tomorrow.

I also had upgraded the ESP-01 to the latest firmware.

PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10572
Posted: 06:39pm 18 Feb 2019
Copy link to clipboard 
Print this post

Here is an optimisation that uses "longstring print #n" to send the data after a CIPSEND. This allows us to use the maximum 2048 bytes allowed which reduces the number of sends.

Option explicit
option default NONE
const MaxLen=4096
const max=20

' Global variables
const quote=chr$(34)
CONST SSID$=quote+"TOASTY2"+quote
CONST SSIDPassword$=quote+"Testthewater01"+quote
'
const starttext$="HTTP"
const pnf$="<html><body>Page not Found</body></html>"
const title$="<html><head><title>Remote Thermostat</title></head><body>"
const ending$="</form></body></html>"
const form$="<form name='f1' method='get' action='D'>"
const h2$="<h2 align='left'>Remote Thermostat V3.0</h2>"
const code$="Update Code: <input type='text' name='S' size='6' value='000000'><br>"
const tstart$="<p><TABLE BORDER='1' CELLSPACING='0' CELLPADDING='5'>"
const heat$="<TR><TD>Heating</TD>"
const hon$="<TD BGCOLOR='#ff0000'> On</TD></TR>"
const hoff$="<TD BGCOLOR='#00ff00'>Off</TD></TR>"
const tend$="</TABLE></p>"
const h3$="<TR><TD></TD><TD>Temperature</TD></TR>"
const s1$="<TR><TD>Current</TD><TD>"
const s2$="<TR><TD>Max</TD><TD>"
const s3$="<TR><TD>Min</TD><TD>"
const check$="<input name='C' type='checkbox' value='R' onClick='this.form.submit()'> Reset Max/Min"
const s4$="<TR><TD>Thermostat</TD>"
const s5$="<TD><input name='R' type='radio' checked='checked' value='"
const s6$="<TD><input name='R' type='radio' value='"
const click$=" 'onClick='this.form.submit()'> "
const degree$="°C<br></TD>"
const offstr$="Off<br></TD>"
const onstr$="On<br></TD>"
const ON=1
const off=0
'
' Set up parameters
'
const starttemp=20 'set the lowest temperature on the thermostat select radio buttons
const hysteresis=2 ' 2 tenths of a degree either side of the setpoint
const waittime=1000 'wait time in readrequest before timeout
const password$="123456" 'password to access change mode


'
const dspin=25
const relaypin=26
'
Dim arg$(2,max) length 20
DIM integer inbuf(Maxlen\8), outbuf(2048/8-1) 'global input and output buffers
dim string CRLF=chr$(13)+chr$(10) length 2

dim integer IPDno 'global IPD numbers used to ensure transmit is on correct IPD
dim integer heater,currenttemp,maxtemp,mintemp,setpoint
dim integer nparams
dim mypage$ 'variables used by main loop only
DIM obuff$="" 'used to buffer writes to the internet to optimise speed
Init:
TEMPR start dspin,3 'measure temp to 0.0625 degree accuracy
mintemp=1000 'set to silly value to force reset if not saved
maxtemp=-1000
currenttemp=cint(TEMPR(dspin)*10)
TEMPR start dspin,3
var restore 'recover the setpoint and min and max temps if already saved
maxmin 'update the maximum and minimum and save them if changed
heater=off
pin(relaypin)=heater
setpin relaypin,dout
setpoint=asc("E")
pause 2000 'wait for ESP8266 to wake up after power on
open "com1:115200,4096" as #1
close #1 'clear the buffer
open "com1:115200,4096" as #1
IF NOT Command("AT",500) THEN END
IF NOT Command("AT+RST",10000,"WIFI GOT IP") THEN 'reset and check for valid connection
PRINT "Set up WIFI on SSID: ",SSID$
IF NOT Command("AT+CWMODE_DEF=1",5000) THEN END 'set device mode (1=client, 2=AP, 3=both)
IF NOT Command("AT+CWLAP",30000) THEN END 'scan for WiFi hotspots
longstring print inbuf() 'output the list of valid networks
IF NOT Command("AT+CWJAP_DEF="+SSID$+","+SSIDPassword$,20000,"WIFI GOT IP") THEN END 'connect
IF NOT Command("AT+CIFSR",5000) THEN END 'check IP address
ENDIF

IF NOT Command("AT+CIPMUX=1",5000) THEN END
IF NOT Command("AT+CIPSERVER=1,80",5000) THEN END
Print "Connected"
longstring clear outbuf()
main:
DO
currenttemp=cint(TEMPR(dspin)*10)
updateheater
TEMPR start dspin,3
maxmin 'update the maximum and minimum and save them if changed
if ReadRequest(waittime) then 'process HTML request
mypage$=ucase$(parsehtmldata$(nparams)) 'parse the html request and get the page requested
if mypage$<>"" then 'real request so do something
if mypage$= "INDEX" then
drawpage
elseif mypage$="D" then
if nparams<>0 then 'we have parameters to process
if arg$(0,0)="S" and arg$(1,0) = password$ then
if arg$(0,1)="C" and arg$(1,1)="R" then 'reset the max min to current
maxtemp=currenttemp
mintemp=currenttemp
var save setpoint,maxtemp,mintemp
endif
if arg$(0,1)="R" then 'change the setpoint and update the heater if applicable
setpoint=asc(arg$(1,1))
var save setpoint,maxtemp,mintemp
updateheater
endif
endif
endif
drawpage
else
SendText pnf$+crlf+crlf'invalid page
endif
EndSend 'clear the write buffer and terminate the write
endif
endif
LOOP
end
'
Function parsehtmldata$(paramcount as integer)
local a$,b$
local integer buf(Maxlen\4) ' long string
local integer inpos,startparam,processargs
paramcount=0
inpos=LInstr(inbuf(),"GET /",1)
parsehtmldata$="INDEX"
if inpos=0 then
parsehtmldata$=""
else
LONGSTRING MID buf(),inbuf(),inpos+5, llen(inbuf())-(inpos+5)
inpos=LInstr(buf(),starttext$,1)
If inpos>2 Then 'page request found
inpos=inpos-2
a$=LGetStr$(buf(),1,inPos)
inpos=Instr(a$,"?")
If inpos<>0 Then 'parameters found
processargs=1
parsehtmldata$=Left$(a$,inpos-1)
a$=Mid$(a$,inpos+1)
Do
arg$(0,paramcount)=""
arg$(1,paramcount)=""
inpos=Instr(a$,"=")
startparam=1
arg$(0,paramcount)=Mid$(a$,startparam,inpos-startparam)
startparam=inpos+1
inpos=Instr(a$,"&")
If inpos<>0 Then
arg$(1,paramcount)=Mid$(a$,startparam,inpos-startparam)
a$=Mid$(a$,inpos+1)
paramcount=paramcount+1
Else
arg$(1,paramcount)=Mid$(a$,startparam)
paramcount=paramcount+1
processargs=0
EndIf
Loop while processargs
Else
parsehtmldata$=a$
EndIf
Else ' no page requested
parsehtmldata$="INDEX"
EndIf
endif
End Function

sub maxmin
local integer update=off
if currenttemp>maxtemp then
maxtemp=currenttemp
update=on
endif
if currenttemp<mintemp then
mintemp=currenttemp
update=on
endif
if update then var save setpoint,maxtemp,mintemp
end sub

sub updateheater
local integer hcalc
if setpoint=asc("L") then
pin(relaypin)=ON
heater=on
endif
if setpoint=asc("A") then
pin(relaypin)=OFF
heater=oFF
endif
if setpoint>=asc("B") and setpoint<=asc("K") then
hcalc=(setpoint-asc("B")+starttemp)*10 'setpoint temperature * 10
hcalc = hcalc + hysteresis
if currenttemp>=hcalc then 'turn heating off
pin(relaypin)=OFF
heater=oFF
endif
hcalc = hcalc - hysteresis - hysteresis
if currenttemp<=hcalc then 'turn heating on
pin(relaypin)=ON
heater=oN
endif
endif
end sub

sub drawpage
local integer loopcounter,tempconvert
local b$
sendText title$+form$+h2$+code$
sendText tstart$+heat$
if heater then
sendText hon$+tend$
else
sendText hoff$+tend$
endif
sendText tstart$
sendText h3$
b$=s1$+outtemp$(currenttemp)+degree$
b$=b$+s2$+outtemp$(maxtemp)+degree$
b$=b$+s3$+outtemp$(mintemp)+degree$
sendText b$
sendText tend$
sendText check$
sendText tstart$
sendText s4$
for loopcounter=asc("A") to asc("L")
if loopcounter=setpoint then
sendText s5$+chr$(loopcounter)
else
sendText s6$+chr$(loopcounter)
endif
sendText click$
tempconvert=loopcounter-asc("B")+starttemp
if loopcounter>asc("A") and loopcounter<asc("L") then sendText str$(tempconvert,2)+degree$
if loopcounter=asc("A") then sendText offstr$
if loopcounter=asc("L") then sendText onstr$
next loopcounter
sendText tend$
sendText ending$+crlf+crlf
end sub
'
function outtemp$(t as integer)
local integer tenths=t mod 10
local integer units= t\10
outtemp$=str$(units,3)+"."+chr$(tenths+48)
end function
'

sub EndSend
local b$
b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(llen(outbuf()))
IF NOT Command(b$,1000,">") THEN
if LInstr(inbuf(),"link is not valid") then
print "link is not valid"
exit sub
endif
endif
IF NOT senddata(5000) THEN END
IF NOT Command("AT+CIPCLOSE="+CHR$(IPDno+48),500) THEN
if lInstr(inbuf(),"UNLINK") then
exit sub
else
end
endif
endif
longstring clear outbuf()
end sub

sub SendText(a$)
local b$
if len(a$)+llen(outbuf())< 2048 then 'add the new string to the output buffer
longstring append outbuf(),a$
else 'too big to fit so send the current output buffer
b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(llen(outbuf()))
IF NOT Command(b$,1000,">") THEN
if LInstr(inbuf(),"link is not valid") then
print "link is not valid"
exit sub
endif
endif
IF NOT senddata(5000) THEN END
longstring clear outbuf()
endif
end sub
'
FUNCTION ReadRequest(timeout%) as integer
ReadRequest=0
longstring Clear inbuf()
timer=0
do while TIMER<timeout% and LOC(#1)=0
loop
pause 50
if TIMER>=timeout% then exit function
do while loc(#1)<>0
longstring append inbuf(),input$(min(255,loc(#1)),#1)
loop
if (NOT lInstr(inbuf(),"favicon",0)) and (NOT lInstr(inbuf(),"CONNECT FAIL",1)) then ReadRequest=1 'junk the favicon requests and disconnects
IF lInstr(inbuf(),"IPD,0",1) then
IPDno=0
endif
IF lInstr(inbuf(),"IPD,1",1) then
IPDno=1
endif
end function
'

end sub
'
FUNCTION senddata(timeout%) as integer 'send a command and wait for the answer
local i%=0,j%,ex%=0
Local a$
senddata=0
longstring Clear inbuf()
longstring print #1,outbuf();
TIMER=0
i%=0
do
if TIMER>timeout% then
ex%=0
EXIT DO
endif
j%=LOC(#1)
if j%>0 then
i%=i%+min(255,j%)
longstring append inbuf(),input$(min(255,j%),#1)
if llen(inbuf())>4 then
if lInstr(inbuf(),"OK",1) then
ex%=1
exit DO
endif
endif
if llen(inbuf())>7 then
if lInstr(inbuf(),"ERROR",1) then
ex%=2
exit DO
endif
endif
endif
loop
select case ex%
case 0
Print "Timeout in CIPSEND data"
case 1
senddata=1
case 2
Print "ERROR in CIPSEND data"
end select
end function
'
FUNCTION Command(AT$, timeout%, other$) as integer 'send a command and wait for the answer
local i%=0,j%,ex%=0
Local a$
Command=0
longstring Clear inbuf()
print #1,AT$+crlf;
TIMER=0
i%=0
do
if TIMER>timeout% then
ex%=0
EXIT DO
endif
j%=LOC(#1)
if j%>0 then
i%=i%+min(255,j%)
longstring append inbuf(),input$(min(255,j%),#1)
if llen(inbuf())>4 and other$="" then
if lInstr(inbuf(),"OK",1) then
ex%=1
exit DO
endif
endif
if llen(inbuf())>7 then
if lInstr(inbuf(),"ERROR",1) then
ex%=2
exit DO
endif
endif
if llen(inbuf())>len(other$)+2 then
if lInstr(inbuf(),other$,1) then
ex%=3
exit DO
endif
endif
endif
loop
select case ex%
case 0
Print "Timeout : "+AT$
case 1
Command=1
case 2
Print "ERROR : "+AT$
case 3
Command=1
end select
end function
Edited by matherp 2019-02-20
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3470
Posted: 02:17am 19 Feb 2019
Copy link to clipboard 
Print this post

Thank you very much, Peter. It works for me.

I made a few modifications to print some stuff, including the IP address. I had to add back in the RESTART toggle (though perhaps I should try that again now that everything is working).

I am able to run it powered off of the 3.3V line on the Nucleo board. That might not work for all and might not work for me in other circumstances.

I'm downloading with XMODEM Transfer Send from TeraTerm. (When I tried pasting it in after AUTOSAVE, after some dozens of lines it started clipping off the first character, making, for instance, "UNCTION Command" not work.)

Here is what works for me with CHPD pulled high with 10K the only ESP-01 connections except for 3V3, 0V, RST, RX, & TX.
[code]
Option explicit
option default NONE
const MaxLen=4096
const max=20

' Global variables
const quote=chr$(34)
CONST SSID$=quote+"mySSID"+quote
CONST SSIDPassword$=quote+"myPassword"+quote
'
const starttext$="HTTP"
const pnf$="<html><body>Page not Found</body></html>"
const title$="<html><head><title>Remote Thermostat</title></head><body>"
const ending$="</form></body></html>"
const form$="<form name='f1' method='get' action='D'>"
const h2$="<h2 align='left'>Remote Thermostat V3.0</h2>"
const code$="Update Code: <input type='text' name='S' size='6' value='000000'><br>"
const tstart$="<p><TABLE BORDER='1' CELLSPACING='0' CELLPADDING='5'>"
const heat$="<TR><TD>Heating</TD>"
const hon$="<TD BGCOLOR='#ff0000'> On</TD></TR>"
const hoff$="<TD BGCOLOR='#00ff00'>Off</TD></TR>"
const tend$="</TABLE></p>"
const h3$="<TR><TD></TD><TD>Temperature</TD></TR>"
const s1$="<TR><TD>Current</TD><TD>"
const s2$="<TR><TD>Max</TD><TD>"
const s3$="<TR><TD>Min</TD><TD>"
const check$="<input name='C' type='checkbox' value='R' onClick='this.form.submit()'> Reset Max/Min"
const s4$="<TR><TD>Thermostat</TD>"
const s5$="<TD><input name='R' type='radio' checked='checked' value='"
const s6$="<TD><input name='R' type='radio' value='"
const click$=" 'onClick='this.form.submit()'> "
const degree$="°C<br></TD>"
const offstr$="Off<br></TD>"
const onstr$="On<br></TD>"
const ON=1
const off=0
'
' Set up parameters
'
const starttemp=20 'set the lowest temperature on the thermostat select radio buttons
const hysteresis=2 ' 2 tenths of a degree either side of the setpoint
const waittime=1000 'wait time in readrequest before timeout
const password$="123456" 'password to access change mode


'
const dspin=15 ' 25
const relaypin=14 ' 26
const resetpin=6 ' L4=6 ' a0 45
'
Dim arg$(2,max) length 20
DIM integer inbuf(Maxlen\8), outbuf(2048/8-1) 'global input and output buffers
dim string CRLF=chr$(13)+chr$(10) length 2

dim integer IPDno 'global IPD numbers used to ensure transmit is on correct IPD
dim integer heater,currenttemp,maxtemp,mintemp,setpoint
dim integer nparams, ipos, jpos
dim mypage$ 'variables used by main loop only
DIM obuff$="" 'used to buffer writes to the internet to optimise speed

Init:
print("Starting")
setpin resetpin,dout
pin(resetpin)=0 'put the ESP8266 into reset
TEMPR start dspin,3 'measure temp to 0.0625 degree accuracy
mintemp=1000 'set to silly value to force reset if not saved
maxtemp=-1000
currenttemp=cint(TEMPR(dspin)*10)
TEMPR start dspin,3
var restore 'recover the setpoint and min and max temps if already saved
maxmin 'update the maximum and minimum and save them if changed
heater=off
pin(relaypin)=heater
setpin relaypin,dout
setpoint=asc("E")
pause 2000 'wait for ESP8266 to wake up after power on
pin(resetpin)=1 'release the ESP8266 from reset
pause 500
open "com1:115200,4096" as #1
' open "com1:9600,4096" as #1
close #1 'clear the buffer
print "Opening COM1"
open "com1:115200,4096" as #1
' open "com1:9600,4096" as #1
IF NOT Command("AT",500) THEN END
IF NOT Command("AT+RST",10000,"WIFI GOT IP") THEN 'reset and check for valid connection
PRINT "Set up WIFI on SSID: ",SSID$
IF NOT Command("AT+CWMODE_DEF=1",5000) THEN END 'set device mode (1=client, 2=AP, 3=both)
IF NOT Command("AT+CWLAP",30000) THEN END 'scan for WiFi hotspots
longstring print inbuf() 'output the list of valid networks
IF NOT Command("AT+CWJAP_DEF="+SSID$+","+SSIDPassword$,30000,"WIFI GOT IP") THEN END 'connect
' IF NOT Command("AT+CWJAP_DEF="+SSID$+","+SSIDPassword$,20000,"WIFI CONNECTED") THEN END 'connect
IF NOT Command("AT+CIFSR",5000) THEN END 'check IP address
ENDIF

IF NOT Command("AT+CIPMUX=1",5000) THEN END
IF NOT Command("AT+CIPSERVER=1,80",5000) THEN END
print "Getting IP: ";
IF Command("AT+CIFSR",5000) THEN 'check IP address
iPos=LInstr(inbuf(),quote,1) ' opening quote
if iPos > 0 then
jPos=LInstr(inbuf(),quote,iPos+1) ' closing quote
if jPos > 0 then
print LGetStr$(inbuf(),iPos+1,jPos-iPos-1)
endif
endif
endif
Print "Connected"
longstring clear outbuf()
main:
DO
currenttemp=cint(TEMPR(dspin)*10)
updateheater
TEMPR start dspin,3
maxmin 'update the maximum and minimum and save them if changed
if ReadRequest(waittime) then 'process HTML request
mypage$=ucase$(parsehtmldata$(nparams)) 'parse the html request and get the page requested
if mypage$<>"" then 'real request so do something
if mypage$= "INDEX" then
drawpage
elseif mypage$="D" then
if nparams<>0 then 'we have parameters to process
if arg$(0,0)="S" and arg$(1,0) = password$ then
if arg$(0,1)="C" and arg$(1,1)="R" then 'reset the max min to current
maxtemp=currenttemp
mintemp=currenttemp
var save setpoint,maxtemp,mintemp
endif
if arg$(0,1)="R" then 'change the setpoint and update the heater if applicable
setpoint=asc(arg$(1,1))
var save setpoint,maxtemp,mintemp
updateheater
endif
endif
endif
drawpage
else
SendText pnf$+crlf+crlf'invalid page
endif
EndSend 'clear the write buffer and terminate the write
endif
endif
LOOP
end
'
Function parsehtmldata$(paramcount as integer)
local a$,b$
local integer buf(Maxlen\4) ' long string
local integer inpos,startparam,processargs
paramcount=0
inpos=LInstr(inbuf(),"GET /",1)
parsehtmldata$="INDEX"
if inpos=0 then
parsehtmldata$=""
else
LONGSTRING MID buf(),inbuf(),inpos+5, llen(inbuf())-(inpos+5)
inpos=LInstr(buf(),starttext$,1)
If inpos>2 Then 'page request found
inpos=inpos-2
a$=LGetStr$(buf(),1,inPos)
inpos=Instr(a$,"?")
If inpos<>0 Then 'parameters found
processargs=1
parsehtmldata$=Left$(a$,inpos-1)
a$=Mid$(a$,inpos+1)
Do
arg$(0,paramcount)=""
arg$(1,paramcount)=""
inpos=Instr(a$,"=")
startparam=1
arg$(0,paramcount)=Mid$(a$,startparam,inpos-startparam)
startparam=inpos+1
inpos=Instr(a$,"&")
If inpos<>0 Then
arg$(1,paramcount)=Mid$(a$,startparam,inpos-startparam)
a$=Mid$(a$,inpos+1)
paramcount=paramcount+1
Else
arg$(1,paramcount)=Mid$(a$,startparam)
paramcount=paramcount+1
processargs=0
EndIf
Loop while processargs
Else
parsehtmldata$=a$
EndIf
Else ' no page requested
parsehtmldata$="INDEX"
EndIf
endif
End Function

sub maxmin
local integer update=off
if currenttemp>maxtemp then
maxtemp=currenttemp
update=on
endif
if currenttemp<mintemp then
mintemp=currenttemp
update=on
endif
if update then var save setpoint,maxtemp,mintemp
end sub

sub updateheater
local integer hcalc
if setpoint=asc("L") then
pin(relaypin)=ON
heater=on
endif
if setpoint=asc("A") then
pin(relaypin)=OFF
heater=oFF
endif
if setpoint>=asc("B") and setpoint<=asc("K") then
hcalc=(setpoint-asc("B")+starttemp)*10 'setpoint temperature * 10
hcalc = hcalc + hysteresis
if currenttemp>=hcalc then 'turn heating off
pin(relaypin)=OFF
heater=oFF
endif
hcalc = hcalc - hysteresis - hysteresis
if currenttemp<=hcalc then 'turn heating on
pin(relaypin)=ON
heater=oN
endif
endif
end sub

sub drawpage
local integer loopcounter,tempconvert
local b$
sendText title$+form$+h2$+code$
sendText tstart$+heat$
if heater then
sendText hon$+tend$
else
sendText hoff$+tend$
endif
sendText tstart$
sendText h3$
b$=s1$+outtemp$(currenttemp)+degree$
b$=b$+s2$+outtemp$(maxtemp)+degree$
b$=b$+s3$+outtemp$(mintemp)+degree$
sendText b$
sendText tend$
sendText check$
sendText tstart$
sendText s4$
for loopcounter=asc("A") to asc("L")
if loopcounter=setpoint then
sendText s5$+chr$(loopcounter)
else
sendText s6$+chr$(loopcounter)
endif
sendText click$
tempconvert=loopcounter-asc("B")+starttemp
if loopcounter>asc("A") and loopcounter<asc("L") then sendText str$(tempconvert,2)+degree$
if loopcounter=asc("A") then sendText offstr$
if loopcounter=asc("L") then sendText onstr$
next loopcounter
sendText tend$
sendText ending$+crlf+crlf
end sub
'
function outtemp$(t as integer)
local integer tenths=t mod 10
local integer units= t\10
outtemp$=str$(units,3)+"."+chr$(tenths+48)
end function
'

sub EndSend
local b$
b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(llen(outbuf()))
IF NOT Command(b$,1000,">") THEN
if LInstr(inbuf(),"link is not valid") then
print "link is not valid"
exit sub
endif
endif
IF NOT senddata(5000) THEN END
IF NOT Command("AT+CIPCLOSE="+CHR$(IPDno+48),500) THEN
if lInstr(inbuf(),"UNLINK") then
exit sub
else
end
endif
endif
longstring clear outbuf()
end sub

sub SendText(a$)
local b$
if len(a$)+llen(outbuf())< 2048 then 'add the new string to the output buffer
longstring append outbuf(),a$
else 'too big to fit so send the current output buffer
b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(llen(outbuf()))
IF NOT Command(b$,1000,">") THEN
if LInstr(inbuf(),"link is not valid") then
print "link is not valid"
exit sub
endif
endif
IF NOT senddata(5000) THEN END
longstring clear outbuf()
endif
end sub
'
FUNCTION ReadRequest(timeout%) as integer
ReadRequest=0
longstring Clear inbuf()
timer=0
do while TIMER<timeout% and LOC(#1)=0
loop
pause 50
if TIMER>=timeout% then exit function
do while loc(#1)<>0
longstring append inbuf(),input$(min(255,loc(#1)),#1)
loop
if (NOT lInstr(inbuf(),"favicon",0)) and (NOT lInstr(inbuf(),"CONNECT FAIL",1)) then ReadRequest=1 'junk the favicon requests and disconnects
IF lInstr(inbuf(),"IPD,0",1) then
IPDno=0
endif
IF lInstr(inbuf(),"IPD,1",1) then
IPDno=1
endif
end function
'

end sub
'
FUNCTION senddata(timeout%) as integer 'send a command and wait for the answer
local i%=0,j%,ex%=0
Local a$
senddata=0
longstring Clear inbuf()
longstring print #1,outbuf();
TIMER=0
i%=0
do
if TIMER>timeout% then
ex%=0
EXIT DO
endif
j%=LOC(#1)
if j%>0 then
i%=i%+min(255,j%)
longstring append inbuf(),input$(min(255,j%),#1)
if llen(inbuf())>4 then
if lInstr(inbuf(),"OK",1) then
ex%=1
exit DO
endif
endif
if llen(inbuf())>7 then
if lInstr(inbuf(),"ERROR",1) then
ex%=2
exit DO
endif
endif
endif
loop
select case ex%
case 0
Print "Timeout in CIPSEND data"
case 1
senddata=1
case 2
Print "ERROR in CIPSEND data"
end select
end function
'
FUNCTION Command(AT$, timeout%, other$) as integer 'send a command and wait for the answer
local i%=0,j%,ex%=0
Local a$
Command=0
longstring Clear inbuf()
print #1,AT$+crlf;
TIMER=0
i%=0
do
if TIMER>timeout% then
ex%=0
EXIT DO
endif
j%=LOC(#1)
if j%>0 then
i%=i%+min(255,j%)
longstring append inbuf(),input$(min(255,j%),#1)
if llen(inbuf())>4 and other$="" then
if lInstr(inbuf(),"OK",1) then
ex%=1
exit DO
endif
endif
if llen(inbuf())>7 then
if lInstr(inbuf(),"ERROR",1) then
ex%=2
exit DO
endif
endif
if llen(inbuf())>len(other$)+2 then
if lInstr(inbuf(),other$,1) then
ex%=3
exit DO
endif
endif
endif
loop
select case ex%
case 0
Print "Timeout : "+AT$
case 1
Command=1
case 2
Print "ERROR : "+AT$
case 3
Command=1
end select
end function
[/code]
Edited by lizby 2019-02-20
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025