|
Forum Index : Microcontroller and PC projects : Problem with ESP-01 ESP8266 & Nucleo-L432
| Author | Message | ||||
| lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3470 |
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 PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
| lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3470 |
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. PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10572 |
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 |
||||
| lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3470 |
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 KingdomPosts: 10572 |
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 |
||||
| lizby Guru Joined: 17/05/2016 Location: United StatesPosts: 3470 |
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] PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |