Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:24 21 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 : Simple Variation of Lew247's weather station for MMBasic for Windows

Author Message
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3481
Posted: 02:13pm 17 Jul 2022
Copy link to clipboard 
Print this post

From the work of Lew247, matherp, and others.



In the lower right, outside and inside temperatures are hard coded, since no pins for connecting DS18B20s with MMBasic for Windows. At one time I had a web page set up on another device which had those readings, and another version of this program (F4, I think) got them--but I've lost track of that, so in this example they're unchanging awaiting revision (though I could just plug in the openweathermap.org temperature for "outside").

The code (MYID$ and APIKEY$ values need to be replaced for your locale)
mode 1 ' mode 1 600x480; 2 320x240
dim string cpu="W" ' windows
Dim integer lblue=RGB(172,209,255),grey=RGB(192,192,192),i,j,k,l,m,n
Dim integer EspFlag=1,iconFlag=1,firstPassFlag=1,txtFont=1,ESPOKFlag%
Dim integer ls%(1000),nNames=10,degrees, x_endpoint, y_endpoint
Dim integer outsideTemp=-2, insideTemp=21, OldOutsideTemp, OldInsideTemp
'Dim cx% = 225, cy% = 100, wid% = 50
Dim cx% = MM.HRes*.75-5, cy% = (MM.VRes-40)/2+22, wid% = MM.HRes/6
Dim ang! = 0.087266463, rad90! = 1.570796327  x'90 degrees in radians
Dim string a$,b$,c$,d$,e$,http$,minute$,second$,item$,weathGet$,qt=chr$(34),Values(10) length 20
Dim string names$(10) length 15
names(0)="description":names(1)="temp":names(2)="pressure":names(3)="humidity"
names(4)="speed":names(5)="deg":names(6)="gust":names(7)="country":names(8)="name"
names(9)="icon"
Dim string labels$(10) length 25
labels$(0)="Sky": labels$(1)="Temperature": labels$(2)="Atmospheric Pressure"
labels$(3)="Humidity": labels$(4)="Wind Speed": labels$(5)="From the"
labels$(6)="Gusting to": labels$(7)="City": labels$(8)=","
Dim string points$(16) length 3  =("N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","","")
points(15)="NNW": points(16)="N"
Dim string iconCodes$="01d02d03d04d09d10d11d13d50d"
Dim integer pInTemp=1,iFailedCnt,iEspStage,wOrgFailedFlag=1

Dim MYID$="YOUR_ID" ' Liverpool, Nova Scotia
Dim APIKEY$="YOUR_KEY"
Dim report$="weather", URL$="api.openweathermap.org"
http$= "GET /data/2.5/"+report$+"?id="+MYID$+"&APPID="+APIKEY$
http$=http$+" HTTP/1.0"+Chr$(13)+Chr$(10)+Chr$(13)+Chr$(10)

If iconFlag Then: geticons: EndIf

If MM.HRes=320 Then: txtFont=7: EndIf
Box 0,0,MM.HRes,40,,RGB(white),grey
Box 0,40,MM.HRes/2,MM.VRes-40,2,RGB(white),lblue
Box MM.HRes/2+1,40,MM.HRes/2,MM.VRes-40,2,RGB(white),lblue
Text MM.HRes/2,5,"Weather: Milton, Nova Scotia",C,1,,RGB(white),grey
Text MM.HRes/2,20,Date$+" "+Time$,C,1,,RGB(white),grey
compass_rose cx%,cy%,wid%
getWeather
writeScreen
a$=Mid$(Time$,4,2) ' get minutes
i=Val(a$) MOD 15
If i < 5 Then: firstPassFlag=0: EndIf ' GET won't violate 10 minute rule

Do
 a$=Mid$(Time$,7,2) ' get second
 If second$<>a$ Then
   Text MM.HRes/2,20,Date$+" "+Time$,C,1,,RGB(white),grey
   second$=a$
   a$=Mid$(Time$,4,2) ' get minute
   If minute$<>a$ Then
     minute$=a$
     If wOrgFailedFlag OR minute="00" OR minute="15" OR minute="30" OR minute="45" Then ' get weather
       If firstPassFlag Then
         firstPassFlag=0 ' don't violate "no more than once every 10 minutes" rule
       Else
         getWeather
         writeScreen
       EndIf
     EndIf
   EndIf
 EndIf
 if CPU<>"W" then: i=TEMPR(pInTemp): If i<>1000 Then: insideTemp=i: EndIf: Endif
 If oldInsideTemp<>insideTemp Then
   oldInsideTemp=insideTemp
   Text MM.HRes/2+13,MM.VRes*.80,"INSIDE",,txtFont,,RGB(black),lblue
   Text MM.HRes/2+10,MM.VRes*.85,Str$(insideTemp)+"C",,5,,RGB(gray),lblue
   logTmp
 EndIf
 If oldOutsideTemp<>outsideTemp Then
   oldOutsideTemp=outsideTemp
   Text MM.HRes-65,MM.VRes*.80,"OUTSIDE",,txtFont,,RGB(black),lblue
   Text MM.HRes-70,MM.VRes*.85,Str$(outsideTemp),,5,,RGB(gray),lblue
 EndIf
Loop

Sub writeScreen
 x=10:y=45
 For i=0 To 6
   If i=2 Then
     Text x,y,labels$(i)+": ",,txtFont,,RGB(black),lblue:y=y+15
     Text x,y,"  "+Values$(i),,txtFont,,RGB(black),lblue:y=y+15
   Else
     if Values$(i)<>"" then
       Text x,y,labels$(i)+": "+Values$(i),,txtFont,,RGB(black),lblue):y=y+15
     endif
   EndIf
 Next i
 Circle cx%,cy%,wid%-6,,,lblue,lblue
 Circle cx%,cy%,wid%/8,,,RGB(red),RGB(red) ' center
 n=((630-degrees) MOD 360) ' opposite of direction of wind
''  Text x,225,"Wind to "+Str$(n),,txtFont,,RGB(black),lblue
 n=((degrees+180) MOD 360) ' opposite of direction of wind
 For i=-3 To 3 ' lines offset from center (cx%) to make arrow
   x_endpoint=(cx%)+(Cos(n/5*ang!)*(wid%-8)) ' ang! = 0.087266463 (5 degrees)
   y_endpoint=(cy%)-(Sin(n/5*ang!)*(wid%-8))
   Line (cx%+i),(cy%+i),x_endpoint,y_endpoint,,RGB(RED)
   Line (cx%-i),(cy%-i),x_endpoint,y_endpoint,,RGB(RED)
'  Line (cx%+i),(cy%+i),(cx%)+(Cos(n*ang!)*(wid%-8)),(cy%)-(Sin(n*ang!)*(wid%-8)),,RGB(RED)
 Next i
'  text x,200,"Condition: ",,txtFont,,rgb(black),lblue
''do until inkey$<>"": loop
 Text x,200,"Condition:  "+Values(9),,txtFont,,RGB(black),lblue
 iconFlag=0
 if Values$(9)<>"" then
   For i=0 To 8 ' check icon availability
     a$=Mid$(iconCodes$,i*3+1,3)
'      print a$+"="+Values(9)+"? ";
     If a$=Values$(9) Then: iconFlag=i+1: Exit For : EndIf
   Next i
 endif
 If iconFlag Then
   Blit write iconFlag,MM.HRes/4,180,50,50
 Else
   Text x+10,212,Values$(0),,txtFont,,RGB(black),lblue
 EndIf
End Sub

Sub compass_rose cx%,cy%,wid%
Local a%
Text cx%-6,cy%-wid%-16),"N",L,1,,RGB(1,1,1),lblue
Text cx%-6,cy%+wid%+5,"S",L,1,,RGB(1,1,1),lblue
Text cx%+wid%+5,cy%-11,"E",L,1,,RGB(1,1,1),lblue
Text cx%-(wid%)-10,cy%-11,"W",L,1,,RGB(1,1,1),lblue
If a%<>a% Then
Text 10,10,"NE",L,7,,RGB(1,1,1),RGB(134,174,230)
Image rotate 6,4,30,30,cx%+(wid%-16)*Cos(.785),cy%-(wid%-16)*Cos(.785),45,1
Text 10,10,"SE",L,7,,RGB(1,1,1),RGB(134,174,230)
Image rotate 6,4,30,30,cx%+(wid%-16)*Cos(.785),cy%+(wid%-16)*Cos(.785),135,1
Text 10,10,"SW",L,7,,RGB(1,1,1),RGB(134,174,230)
Image rotate 6,4,30,30,cx%-(wid%-16)*Cos(.785),cy%+(wid%-16)*Cos(.785),225,1
Text 10,10,"NW",L,7,,RGB(1,1,1),RGB(134,174,230)
Image rotate 6,4,29,29,cx%-(wid%-16)*Cos(.785),cy%-(wid%-16)*Cos(.785),315,1
Text 10,10,"  ",L,7,,RGB(134,174,230),RGB(134,174,230) ' clear text
' tick marks, every 5 degrees (360/5 = 72)
EndIf
For a% = 0 To 71 ' note: for angles, East is zero
 Line (cx%)+(Cos(a%*ang!)*(wid%-4)),(cy%)-(Sin(a%*ang!)*(wid%-4)),(cx%)+(Cos(a%*ang!)*(wid%+1)),(cy%)-(Sin(a%*ang!)*(wid%+1)),,RGB(WHITE)
Next
' COMPASS perimiter
Circle cx%,cy%,wid%
Circle cx%,cy%,wid%-4
Circle cx%,cy%,wid%/8,,,RGB(red),RGB(red) ' center
End Sub

Sub getWeather
   LongString clear ls%()
   weathGet$="wget -q -O- "+qt$+"api.openweathermap.org/data/2.5/weather?id="+MYID$+"&appid="+APIKEY$+qt
'' debugging    text 0,420,weathGet$ ''' print weathGet$
'' debugging    text 0,435,""
'' debugging    pause 2000 '''
   system weathGet$,ls%()
'' debugging    a$=lgetstr$(ls%(),1,250)
'' debugging    text 0,435,a$ '''

 For n=0 To nNames-1
   item$=names$(n)
   if CPU="W" then
'names(0)="description":names(1)="temp":names(2)="pressure":names(3)="humidity"
'names(4)="speed":names(5)="deg":names(6)="gust":names(7)="country":names(8)="name":names(9)="icon"
     if n=0 then
       Values$(n)=json$(ls%(),"weather[0]."+item$)
     elseif n=>0 and n<=3 then
       Values$(n)=json$(ls%(),"main."+item$)
     elseif n=>4 and n<=6 then
       Values$(n)=json$(ls%(),"wind."+item$)
     elseif n=7 then
       Values$(n)=json$(ls%(),"sys."+item$)
     else
       Values$(n)=json$(ls%(),item$)
     endif
   else
     Values$(n)=pseudo_json$(ls%(),item$)
   endif
'    Print item$,Values$(n)
   If item$="temp" Then: Values$(n)=Str$(Val(Values$(n))-273.15,0,1)+"C": EndIf
   If item$="deg" Then
     degrees=Val(Values$(n))
'      i=(degrees+11.25)/22.5
     i=((450-degrees+11.25) MOD 360)/22.5
     Values$(n)=points$(i)
'      print item$,degrees,i,Values$(n)
   EndIf
   If item$="humidity" Then: Values$(n)=Values$(n)+"%": EndIf
   If item$="speed" Then: Values$(n)=Values$(n)+"kph": EndIf
   If item$="pressure" Then: Values$(n)=Values$(n)+" millibars": EndIf
   If item$="gust" and Values$(n)<>"" Then: Values$(n)=Values$(n)+"kph": EndIf
'    text 0,460+(n*mm.fontheight),item$+": "+Values$(n) '' debugging
'' debugging    pause 500
 Next n
End Sub

Sub geticons
Local integer i,j,k,x,y
if CPU<>"W" then
 Load image "icons.bmp"
else
 Load BMP "icons.bmp"
endif
'for i=1 to 9: on error skip: blit close i: next i
k=1:x=0
For i=1 To 3
 y=0
 For j=1 To 3
   Blit read k,x,y,50,50: y=y+50:k=k+1
 Next j
 x=x+50: y=0
Next i
End Sub

Sub logTmp
 On error skip 4
 Open "wtemp.log" For append As #3
 a$=Mid$(Date$,9,2)+Mid$(Date$,4,2)+Mid$(Date$,1,2)+Mid$(Time$,1,2)+Mid$(Time$,4,2)+Mid$(Time$,7,2)
 Print #3,"T "+Str$(insideTemp)+" "+Str$(outsideTemp)+" ~ "+a$
 Close #3
 i=0 ' null
End Sub

Some detritus remains in the code from other versions using ESP-01. This data from weathermap.org doesn't return the weather icon code, so the icon is not displayed (icon bmp attached).

icons.zip
PicoMite, Armmite F4, SensorKits, MMBasic Hardware, Games, etc. on fruitoftheshed
 
lizby
Guru

Joined: 17/05/2016
Location: United States
Posts: 3481
Posted: 03:10pm 17 Jul 2022
Copy link to clipboard 
Print this post

Hmmm, somehow an extra character got in the code when I copied it. the "x" before the single quote in line 9 needs to be removed.

Also, I noticed that the program was taking 40% to 50% of the CPU time. I put a PAUSE 950 just before LOOP in the main do loop, and that knocked it down below 10%. No point in spinning wheels while idling.

openweathermap.org has a restriction of no more than one call every 10 minutes, so I only update every 15 minutes, but the time updates every second. If you only wanted the time to show minutes, you could put in PAUSE 59950.
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