Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 01:28 06 Dec 2022 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 : CMM2: V5.07.00b11: json support with full ESP-01 example code

     Page 1 of 3    
Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 6619
Posted: 03:10pm 30 Jan 2021
Copy link to clipboard 
Print this post

V5.07.00b11 now available for download

http://geoffg.net/Downloads/Maximite/CMM2_Beta.zip

I've added a new edit font OPTION EDIT FONT VERY LARGE for use with high resolution modes and changed the horrible font 3 to a different one that is the same size

This release also supports a json parsing function.

  Quote  JSON$(array%(),string$) Returns a string representing a specific item out of the JSON input stored in the longstring array%()

e.g.
JSON$(a%(), "name")
JSON$(a%(), "coord.lat")
JSON$(a%(), "weather[0].description")
JSON$(a%(),"list[4].weather[0].description

Examples taken from api.openweathermap.org



Attached is some code that uses the openweathermap.org api which is called using an ESP-01 with the default "AT" firmware. You need to substitute your own wifi login details and your own openweathermap api username and key in lines 3, 4, and 14 to get it to work. This is code I previously published to work on the Micromite eXtreme  that works without a single change on the CMM2 - Isn't compatibility wonderful




You can see from the local report why I have so much time for coding  


option explicit
option default none
Dim MYID$="myID"
Dim APIKEY$="myKEY"
Dim report$="weather"
dim b$= "GET /data/2.5/"+report$+"?id="+MYID$+"&APPID="+APIKEY$
Dim m%(8000)
b$=b$+" HTTP/1.0"+Chr$(13)+Chr$(10)+Chr$(13)+Chr$(10)

open "com2:115200,8192" as #1
LongString clear m%()
print #1,"AT+CWMODE_CUR=1"+chr$(13)+chr$(10);
if NOT OKwait(4000) then errorexit("AT+CWMODE_CUR=1")
print #1,"AT+CWJAP_CUR="+chr$(34)+"mySSID"+chr$(34)+","+chr$(34)+"myPASSWORD"+chr$(34)+chr$(13)+chr$(10);
if NOT OKwait(10000) then errorexit("AT+CWJAP_CUR=")
print #1,"AT+CIPSTART="+chr$(34)+"TCP"+chr$(34)+","+chr$(34)+"api.openweathermap.org"+chr$(34)+",80"+chr$(13)+chr$(10);
if NOT OKwait(10000) then errorexit("AT+CIPSTART=")
print #1,"AT+CIPMODE=1"+chr$(13)+chr$(10);
if NOT OKwait(4000) then errorexit("AT+CIPMODE=1")
print #1,"AT+CIPSEND"+chr$(13)+chr$(10);
if NOT OKwait(4000) then errorexit("AT+CIPSEND")
print #1,b$;
getinput(10000)
Print "Weather for "+json$(m%(),"name")
Print "Temperature is ",val(json$(m%(),"main.temp"))-273
Print "Pressure is ",json$(m%(),"main.pressure")
Print json$(m%(),"weather[0].description")
print #1,"+++";
pause 1000
print #1,"AT+CIPMODE=0"+chr$(13)+chr$(10);
if NOT OKwait(4000) then errorexit("AT+CIPMODE=0")
print #1,"AT+CIPCLOSE"+chr$(13)+chr$(10);
if NOT OKwait(4000) then errorexit("AT+CIPCLOSE")
end

function OKwait(timeout as integer) as integer
OKwait=1
timer=0
do
loop until input$(1,1)="O" or timer>=timeout
do
loop until input$(1,1)="K" or timer>=timeout
if timer>=timeout then OKwait=0
end function

sub errorexit(calling as string)
print "AT call timeout from - ",calling
print #1,"AT+CIPCLOSE"+chr$(13)+chr$(10)
end
end sub

sub getinput(waitpause as integer)
local a$
local j%,i%=-1
timer=0
do
a$=input$(1,1)
If a$<>"" Then
LongString append m%(),a$
' print a$;
if a$="{" then
if i%=-1 then
i%=1
else
i%=i%+1
endif
endif
if a$="}" then i%=i%-1
endif
loop while timer<=waitpause and i%<>0
LongString trim m%(),LInStr(m%(),"{")-1
print ""
end sub

Edited 2021-01-31 01:30 by matherp
 
chris
Regular Member

Joined: 24/08/2020
Location: United Kingdom
Posts: 54
Posted: 05:00pm 30 Jan 2021
Copy link to clipboard 
Print this post

Sounds great.

How is it possible for the regular CMM2 to access Wifi/Internet?

Is there a guide somewhere, or does it require the special 'deluxe' model?
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 6619
Posted: 05:11pm 30 Jan 2021
Copy link to clipboard 
Print this post

This is for running on a regular CMM2 - just connect a standard ESP-01 to com port 2 and power it from 3.3V/GND (make sure the CH-PD pin is also pulled high) and you have network access



Edited 2021-01-31 03:39 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 2830
Posted: 05:35pm 30 Jan 2021
Copy link to clipboard 
Print this post

  matherp said  This is for running on a regular CMM2 - just connect a standard ESP-01 to com port 2 and power it from 3.3V/GND (make sure the CH-PD pin is also pulled high) and you have network access


@matherp

Didn't you say we shouldn't drive an ESP-01 from the CMM2's power rails a couple of months back because it can draw too much current under some loads?

Tom
CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 6619
Posted: 05:40pm 30 Jan 2021
Copy link to clipboard 
Print this post

Seems to test OK but put a 2.2R resistor in the 3.3V line and a 100uF cap across the ESP-01 if any problems



Edited 2021-01-31 03:43 by matherp
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 2830
Posted: 05:46pm 30 Jan 2021
Copy link to clipboard 
Print this post

Did you really mean a 2.2 ohm resistor ... do they come that small, other than 0 ohm SMDs ?

Tom
CMM2 Welcome Tape, Creaky old text adventures
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 6619
Posted: 05:51pm 30 Jan 2021
Copy link to clipboard 
Print this post

Yes 2R2 as used already on the CMM2 in the power supply to the SDcard. Together with the cap just slows the spikes slightly



Edited 2021-01-31 03:54 by matherp
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1607
Posted: 07:54pm 30 Jan 2021
Copy link to clipboard 
Print this post

Thank you Peter for all your help
 
jirsoft

Guru

Joined: 18/09/2020
Location: Czech Republic
Posts: 526
Posted: 08:03pm 30 Jan 2021
Copy link to clipboard 
Print this post

This is simply perfect!
What kind of JSON parser are you using? For this kind of devices is maybe JSMN one of the best... (I saw in the your other thread, that JSON parser is memory hungry, this one isn't and is also fast)
Jiri
Napoleon Commander and SimplEd  for CMM2 (GitHub),  CMM2.fun
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 2830
Posted: 08:14pm 30 Jan 2021
Copy link to clipboard 
Print this post

  matherp said  Yes 2R2 as used already on the CMM2 in the power supply to the SDcard. Together with the cap just slows the spikes slightly.


Thanks Peter, I've learnt (and ordered) something new. I think providing photographic evidence that such resistors exist was overkill though

Tom
CMM2 Welcome Tape, Creaky old text adventures
 
Rado
Regular Member

Joined: 27/11/2020
Location: Croatia
Posts: 59
Posted: 08:28pm 30 Jan 2021
Copy link to clipboard 
Print this post

Wow. This opens up CMM2 to the whole new world of real-life data exchange. We just need something to pack data back to JSON and we can communicate with anything (excluding Death Star v1.0)
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5005
Posted: 08:30pm 30 Jan 2021
Copy link to clipboard 
Print this post

I used the 5V supply with a 3.3V regulator for my ESP interface.
I also used com1 so that all the pins are together on the expansion port.



Thank you for json, I wasn't looking forward to doing that in Basic.

Jim
VK7JH
MMedit   MMBasic Help
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 2367
Posted: 10:32pm 30 Jan 2021
Copy link to clipboard 
Print this post

Jim--what high-current 3V3 TO-92 regulator did you use?
PicoMite on fruitoftheshed
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5005
Posted: 11:08pm 30 Jan 2021
Copy link to clipboard 
Print this post

  lizby said  Jim--what high-current 3V3 TO-92 regulator did you use?


MCP1700
VK7JH
MMedit   MMBasic Help
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 2367
Posted: 11:15pm 30 Jan 2021
Copy link to clipboard 
Print this post

Ok, I've got some of those--in Box #10, my notes say, if I can find that.

I like your arrangement.
PicoMite on fruitoftheshed
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5005
Posted: 01:29am 31 Jan 2021
Copy link to clipboard 
Print this post

Now I have to work out how to get SSL working.
There aren't many websites that don't use https now.

As far as I can see, the necessary functions are in the older firmware that fits the 1MB modules.
The later firmware has HTTP functions that would make things simpler but I think you need at least 2MB of flash to run it.

Jim
VK7JH
MMedit   MMBasic Help
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 2830
Posted: 01:40pm 31 Jan 2021
Copy link to clipboard 
Print this post

Thanks for providing a morning's amusement Peter.

I found I had to replace:
dim b$= "GET /data/2.5/"+report$+"?id="+MYID$+"&APPID="+APIKEY$


with:
dim b$= "GET /data/2.5/"+report$+"?q="+MYID$+"&APPID="+APIKEY$


Otherwise it complained that "manchester,uk" was not a valid city, which I thought was rather opinionated for a computer

I've also found my ESP-01 module to not be terribly stable, sometimes it works, but othertimes it only flashes its LED on initial power-up and then will refuse to flash it further or make a connection. It will then stubbornly refuse for a while whilst I faff with the cables and switch things on and off a couple of times, or attach it to an external power supply and then it will decide it will work again after all even when connected back to the CMM2 3.3V power rail ??? Maybe that resistor and capacitor will help when the former arrives. TBH I'm not convinced that the 3.3V rail is always supplying 3.3V ... sometimes I'm measuring as low as 2.8V - though I must acknowledge there may be a certain amount of incompetence involved.

Anyway, if we get many more upgrades then I think I'm going to need a bigger breadboard:



Best wishes,

Tom
CMM2 Welcome Tape, Creaky old text adventures
 
RetroJoe

Senior Member

Joined: 06/08/2020
Location: Canada
Posts: 289
Posted: 02:36pm 31 Jan 2021
Copy link to clipboard 
Print this post

At this rate, we're going to need a Maximite Expansion Interface...
Enjoy Every Sandwich / Joe P.
 
Nimue

Guru

Joined: 06/08/2020
Location: United Kingdom
Posts: 314
Posted: 02:43pm 31 Jan 2021
Copy link to clipboard 
Print this post

  RetroJoe said  At this rate, we're going to need a Maximite Expansion Interface...


I remember networking ZX Spectrums the the interface 1 (https://en.wikipedia.org/wiki/ZX_Interface_1 back when I was a wee girl (~15yo)

Nim
Entropy is not what it used to be
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 6619
Posted: 03:51pm 31 Jan 2021
Copy link to clipboard 
Print this post

Here is a simple webserver using the ESP-01 in tcp server mode. Just substitute the login for your network in lines 8 and 9





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

' Global variables
const quote=chr$(34)
CONST SSID$=quote+"mySSID"+quote
CONST SSIDPassword$=quote+"myPASSWORD"+quote
'
const crlf$=chr$(13)+chr$(10)
const header$="<!DOCTYPE html>"
const starttext$="HTTP"
const pnf$="<html><body>Page not Found</body></html>"
const title$="<html><meta charset="+quote+"UTF-8"+quote+"><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=42
const relaypin=5
'
Dim arg$(2,max) length 20
DIM integer inbuf(Maxlen\8) 'global input buffer

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 integer obuff(2048\8) '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 "com2:115200,4096" as #1
 close #1 'clear the buffer
 open "com2:115200,4096" as #1
 IF NOT Command(0, "AT",obuff(), 500) THEN END
 IF NOT Command(0, "AT+RST",obuff(), 10000,"WIFI GOT IP") THEN 'reset and check for valid connection
   PRINT "Set up WIFI on SSID: ",SSID$
   IF NOT Command(0, "AT+CWMODE_DEF=1",obuff(), 5000) THEN END 'set device mode (1=client, 2=AP, 3=both)
   IF NOT Command(0, "AT+CWLAP",obuff(), 30000) THEN END 'scan for WiFi hotspots
   longstring print inbuf() 'output the list of valid networks
   IF NOT Command(0, "AT+CWJAP_DEF="+SSID$+","+SSIDPassword$,obuff(), 20000,"WIFI GOT IP") THEN END 'connect
   IF NOT Command(0, "AT+CIFSR",obuff(), 5000) THEN END 'check IP address
 ENDIF

 IF NOT Command(0, "AT+CIPMUX=1",obuff(), 5000) THEN END
 IF NOT Command(0, "AT+CIPSERVER=1,80",obuff(), 5000) THEN END
 Print "Connected"

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\8)
 local integer inpos,startparam,processargs
 paramcount=0
 inpos=lInstr(inbuf(),"GET /",1)
 if inpos=0 then
   parsehtmldata$=""
 else
   longstring mid buf(),inbuf(),inpos+5,1000
   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 header$
 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$
 pause 25
 b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(llen(obuff())) 'send anything still in the buffer
 IF NOT Command(0,b$,obuff(), 500,">") THEN
   if lInstr(inbuf(),"link is not valid") then exit sub
 endif
 IF NOT Command(1, b$, obuff(),500) THEN END
 pause 25
 IF NOT Command(0, "AT+CIPCLOSE="+CHR$(IPDno+48),obuff(), 500) THEN
   if lInstr(inbuf(),"UNLINK") then
     longstring clear obuff()
     exit sub
   else
     end
   endif
 endif
 longstring clear obuff()
end sub

sub SendText(a$)
 local b$
 if len(a$)+llen(obuff())< 2048 then 'add the new string to the output buffer
   longstring append obuff(),a$
 else 'too big to fit so send the current output buffer
  pause 25
  b$="AT+CIPSEND="+CHR$(IPDno+48)+","+STR$(llen(obuff()))
   IF NOT Command(0,b$,obuff(),1000,">") THEN
     if lInstr(inbuf(),"link is not valid") then exit sub
   endif
   IF NOT Command(1, b$, obuff(),1000) THEN END
   longstring clear obuff()
longstring append 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
 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
 IF lInstr(inbuf(),"IPD,1",1) then IPDno=1
end function
'

end sub
'
FUNCTION Command(mode, AT$, outdata%(), 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()
 if mode=0 then
   print #1,AT$+crlf$;
 else
   longstring print #1,obuff();
 endif
 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
 
     Page 1 of 3    
Print this page
© JAQ Software 2022