CPU Load/% Busy

Place code snippets and demo code here
Post Reply
peridot
Posts: 46
Joined: Mon Mar 08, 2021 4:54 am
Has thanked: 7 times
Been thanked: 93 times

CPU Load/% Busy

Post by peridot »

Whilst trying to optimise some code I wanted to try and get a measure on how certain routines were tying up the cpu.
Basically I set up a tight loop containing a counter (Idle loop) then called a routine every second and calculated the amount of time the processor spent out of this loop executing program code and expressed it as %busy.

Here is the code, you first need to find the number of iterations the cpu makes when it is not executing any other user code including and setup code. An esp32 will do close to 15000 on a cpu with no other code. It is interesting to play with some code changes and set up (like removing WDT ) and seeing the effect on your programs load. Here are some results and the actual program is below.
{"wdir":360.00,"dir":360.00,"speed":7.30,"gust":11.50}
Raw:2456
Time:928
Idle:2456
Busy:83.04%

{"wdir":360.00,"dir":360.00,"speed":7.30,"gust":11.50}
Raw:4297
Time:1226
Idle:4297
Busy:70.32%

{"wdir":247.50,"dir":247.50,"speed":2.00,"gust":4.00}
Raw:3003
Time:926
Idle:3003
Busy:79.26%

www.pwsweather.com/pwsupdate/pwsupdate. ... lyrainin=0
Raw:1191
Time:841
Idle:1191
Busy:91.77%

Raw:2943
Time:903
Idle:2943
Busy:79.68%

Code: [Local Link Removed for Guests]

'CPU idle
lf=15000 'idle factor
p=millis
timer1 1000,idle

do
i=i+1
loop
end 

idle:
p=millis-p
wlog "Raw:";i
wlog "Time:";p
onerror skip
l=i
wlog "Idle:";l
l=100-((l/lf)*100)
wlog "Busy:";STR$(l, "%2.2f");"%"
wlog ""
skip:
i=0  'reset count
p=millis
return
I applied this to a program that was receiving some sensor data via UDP and performing other periodic processing.

Code: [Local Link Removed for Guests]

'  *******************************
  ' ***** udp-power Monitor *****
  ' *******************************
  '    Filename: udp-power_wps.bas
  '    Date: Dec 2019
  '    File Version:
  '     Written by: M.Ogden
  '    Function: udp-power Monitor 
  '   Device: ESP8266 with 4MB  
  '    Last Revision:
  '    Initial v0.6
  '
'reads data from UDP port
'processes data and prints json string on serial port
'monitors power sensor activity
'v0.8 update to Annex 1.41 , add WDT , add log.txt
  '  *******************************
ver$="v0.8"
 print "reset reason: ";
select case bas.ResetReason
  case 0: file.append "/log.txt", date$+" "+time$+"-"+"normal startup"+chr$(13)+chr$(10)
  case 1: file.append "/log.txt", date$+" "+time$+"-"+"hardware WDT"+chr$(13)+chr$(10)
  case 2: file.append "/log.txt", date$+" "+time$+"-"+"exception reset"+chr$(13)+chr$(10)
  case 3: file.append "/log.txt", date$+" "+time$+"-"+"software WDT"+chr$(13)+chr$(10)
  case 4: file.append "/log.txt", date$+" "+time$+"-"+"software restart"+chr$(13)+chr$(10)
  case 5: file.append "/log.txt", date$+" "+time$+"-"+"wake up from deep sleep"+chr$(13)+chr$(10)
  case 6: file.append "/log.txt", date$+" "+time$+"-"+"external reset"+chr$(13)+chr$(10)
end select

'apikey$="&apikey=98a035fb084987bc6e2a7ea8d4cc7948"
'emonapi$="192.168.0.9/input/post?node=emontx&fulljson="
'dweetapi$="dweet.io/dweet/for/3823grid?"
q$=chr$(34)
J$="&"
v$=""
ot$=""
oh$=""
ws$=""
wg$=""
wd$=""
pr$=""
ra$=""

'IO
D0=16:D1=5:D2=4:D3=0:D4=2:D5=14:D6=12:D7=13:D8=15:D9=3:D10=1
PIN.MODE d5, OUTPUT
PIN.MODE d6, OUTPUT
PIN.MODE d3, OUTPUT
PIN.MODE d2, OUTPUT
pin(d2)=1:pin(d6)=1:pin(d3)=1:pin(d5)=1
pause 2000
'serial.mode 115200
'Variables
ginpower=0
goutpower=0
nogridpower=0
upower=0
spower=0
flag=0
dim sa(6)
sdata=0
q$=chr$(34)

'*********************************************************************************
'CPU idle
lf=14480 'esp32 idle factor
p=millis

'initialise
'onudp goudp
TIMER1 30000, wps
timer0 1000,main
'timer0 1000,idle
udp.begin 5001
'DHT.SETUP d4 ,22
'option.WDT 5000 ' set the WDT at 5 second
'Idle loop
do
i=i+1
loop
end 


idle:
p=millis-p
wlog "Raw:";i
wlog "Time:";p
onerror skip
l=i
wlog "Idle:";l
l=100-((l/lf)*100)
wlog "Busy:";STR$(l, "%2.2f");"%"
wlog ""
skip:
i=0  'reset count
p=millis
return


'main loop processing
main:
'option.WDTreset
led1
'read udp
v$ = udp.read$
UDP.WRITE "192.168.0.9", 5001, "{Ramfree:"+ str$(ramfree)+"}"
'pause 100
if v$<>"" then
wlog v$
UDP.WRITE "192.168.0.9", 5001, "ESP-" + v$
'read value pairs
pw$= json$(v$,"count")
sw$= json$(v$,"solar")
getjson v$,ot$,"otemp"
getjson v$,oh$,"ohum"
getjson v$,ws$,"speed"
getjson v$,wg$,"gust"
getjson v$,wd$,"dir"
getjson v$,pr$,"pres"
getjson v$,ra$,"rain"

'wlog "temp is:"+ot$
'process json strings
if pw$ <> "not found" then
  upower=val(pw$)
  'print "Usage: "+pw$+" watts "
    gridpower
  led2
end if
if sw$ <> "not found" then
  spower=val(sw$)
  'print "Solar: "+sw$+" watts "
end if
v$=""
end if
gosub idle
return

'general routines
'check value for positive only value

'Heartbeat
T1:
'return

'pulse Led1
sub led1
pin(d5)=0
pause 200
pin(d5)=1
end sub

'pulse Led2
sub led2
pin(d6)=0
pause 200
pin(d6)=1
end sub


'pulse Led3
sub led3
pin(d2)=0
pause 200
pin(d2)=1
end sub

'pulse Led4
sub led4
pin(d3)=0
pause 200
pin(d3)=1
end sub

sub checkpos(v)
  if v<0 then v=0
end sub

'process the house usage and Solar generation
'to create grid in/out power values
sub gridpower
  nogridpower=upower
  upower=(upower*3600)/10
  'check solar contribution
  if nogridpower>0 then
    ginpower=upower
    goutpower=0
    upower=upower+spower  'add solar to grid power
    smooth upower
    
  else                    'solar is greater than grid input
   ' print "Calc Power.."
    'so apply just an average grid usage and the balance as grid out
    random=(RND(100))+350
    'wlog "Random:"; random
      smooth random
  upower=random
'wlog "smooth:";  upower
    ginpower=upower-spower
    checkpos ginpower
    goutpower=spower-upower
    checkpos goutpower
  end if
  'print "latest watts:";upower
  'print "latest Solar:";spower
  'print "to Grid:";goutpower
  'print "from Grid:";ginpower
  'get temperature
tw$="0"
  power$="{"+q$+"ptemp"+q$+":"+tw$+","+q$+"power"+q$+":"+str$(upower)+","+q$+"solar"+q$+":"+str$(spower)+","+q$+"gridout"+q$+":"+str$(goutpower)+","+q$+"gridin"+q$+":"+str$(ginpower)+"}"
  'dweet.io     power2$="power="+str$(upower)+"&solar="+str$(spower)+"&gridout="+str$(goutpower)+"&gridin="+str$(ginpower)
  UDP.WRITE "192.168.0.9", 5001, power$
  end sub
  
  sub smooth(sdata)
  'wlog "sdata:";sdata
  sa(6)=sdata
  for sc=0 to 5
  sa(sc)=sa(sc+1)
  next
  'wlog "smooth"
  for sc=0 to 5
 sdata=sdata+sa(sc)
  next
 sdata=sdata/6
 sdata=cint(sdata)
 'wlog sdata
  end sub
  

  
 wps:
   otf$=str$((val(ot$)*9/5+32)) 'temp in c to F
    dpf$ = str$(val(ot$) - ((100 - val(oh$))/5)) 'dew point in c
  dpf$=str$((val(dpf$)*9/5+32)) 'dew point convert to f
  wsm$=str$(val(ws$)/1.6)
  wgm$=str$(val(wg$)/1.6)
  pri$=str$(val(pr$)/33.864)
  rai$=str$(val(ra$)*0.03937)
  
  'now send YARRAGONAU via HTTP
  d$="20"+DATE$(2)
  d$=replace$(d$,"/","-")
  pws1$="dateutc="+d$+"%20"+time$+"&ID=YARRAGONAU&PASSWORD=rs419nd9&action=updateraw"
  pws2$=pws1$+"&tempf="+otf$+"&humidity="+oh$+"&dewptf="+dpf$
  pws2$=pws2$+"&windspeedmph="+wsm$+"&windgustmph="+wgm$+"&winddir="+wd$+"&baromin="+pri$
  pws2$=pws2$+"&dailyrainin="+rai$
  pws2$="www.pwsweather.com/pwsupdate/pwsupdate.php?"+pws2$
  wlog pws2$
     'WGETASYNC(pws2$, 80)
     pause 300
    return
  
 
  
  'gjson$ checks for w$ in a json string j$
  'replaces contents of r$ if found
  sub getjson(j$,r$,w$)
  local x$
  x$=json$(j$,w$)
  if x$ <> "not found" then
  r$=x$
  end if
  end sub
  
  
  
   answer_done:
'wlog WGETRESULT$
Return
  
 
Post Reply