Smart picaxe outdoor light

hippy

Technical Support
Staff member
To me that does seem to be stretching the definition of "IoT" a bit :)

I recently acquired one of these minus the control panel which isn't much of a problem as it's simply 8 mains-switching relays with their coils wired to a 9-way D, I'm guessing the control panel is a 12V supply and a switch for each line -

https://prolight.co.uk/wp-content/uploads/2016/08/BOTE22_U01-1.jpg

I won't tell you much it cost; suffice to say another car boot sale bargain. One day I might "IoT" it or find a use for it.
 

AllyCat

Senior Member
Hi,

... do more homework on eeprom bytes ...variable ones b0-b27 is easiest and seem to get used up the fastest
Strictly it's Memory bytes, either EE... (Electrically Erasable..) or RA (Random Access) Memory. In most M2s, there is actually more than ten times more RAM than just the Variables b0 - b27 (it goes right up to 511) so you need to learn about PEEK/POKEs or the bptr (Byte Pointer). IMHO PEEK/POKE might be a little easier to understand, but @bptr is much more useful and powerful, so I'd recommend that.

However, before starting there, note that (in all M2s) there are the "System Word" variables that you can use just like any other Word variables. So for your "larger" numbers (>255), instead of using w0....w13 you can use S_W1 ... S_W6, which leaves bytes b0...b27 still available to use as you wish. Usually S_W0 is also available, and of course you can write "small" (byte) values into any of them if you wish.

There's lots that could be said about using those "Dimmable" mains LEDs (post #9), but let's take one thing at a time. ;)

Cheers, Alan.
 

newplumber

Senior Member
@Lbenson lol I said smartest...not the most expensivest! :) but always good for options and thanks

@allycat grabbing a hold of "bptr" is foggy for me although I am trying to understand
I understand peek and poke but where it (data) gets stored is still confusing
and its awesome from all the help you and all have tried to simplify it
I will continual practicing/reading and maybe it will clear up
I have to jet but when I get time this weekend I will post what i think i know
and questions of memory so I can be some what on the same page

You all have a great weekend
and thanks
your friend mark
 

hippy

Technical Support
Staff member
I understand peek and poke but where it (data) gets stored is still confusing
The best way to think of it is as 256 bytes of RAM, locations numbered 0 to 255.

Byte variable 'b0' shares RAM location 0, right up to 'b27' at location 27.

You can access all that RAM with "PEEK n, var" and "POKE n, var" where n can be a number or variable holding a number between 0 and 255.

You can access all that RAM with "var = @bPtr" (peek) and "@bPtr = var" (poke) where 'bPtr' holds a number between 0 and 255.

So all these will read RAM location 16 into 'b0' ...

b0 = b16

Peek 16, b0

b1 = 16
Peek b1, b0

bPtr = 16
b0 = @bPtr

And all these will write 'b0' to RAM location 16 ...

b16 = b0

Poke 16, b0

b1 = 16
Poke b1, b0

bPtr = 16
@bPtr = b0

Some PICAXE have larger RAM and more variables; adjust accordingly.
 

newplumber

Senior Member
@ hippy thanks and okay I think I am winning here
even tho I had to read it 6 times (lots of info)
so
So all these will read RAM location 16 into 'b0' ...
b0 = b16
lets say (in my training code)
Code:
symbol byte_16 =  b16
btye_16 = 16 
poke 16, b0
;now b0 is 16 ? then i can use?
poke 120, b0 
peek 120, b1 
; so now b1 = b0 and ram 120 is still 16?
now for the @bPtr stuff lol I think after i left school
they had to layoff 75% of the school tutors

@ Lbenson thanks I looked at that chart and .... and... its colorful
with straight lines and all but it does make sense for the B0 thru B27
but after that I see the line that says "rookies confusion starts here"
but for reals thanks to westaust55 that put all the detail in it someday I should understand clearly
btw I was having family time this weekend... went fishing for a record breaking time of 63 minutes
before i got delusional watching the bopper play dead.
 

hippy

Technical Support
Staff member
Code:
symbol byte_16 =  b16
btye_16 = 16 
poke 16, b0
;now b0 is 16 ? then i can use?
No ...

symbol byte_16 = b16
byte_16 = 16

You name 'b16' also as 'byte_16' and then set that to value 16. 'b16', 'byte_16' and RAM location 16 will all now hold the value 16.

poke 16, b0

That will put whatever value is in 'b0' into RAM location 16, 'b16' and 'byte_16'

You instead need to PEEK to read from RAM location 16 -

peek 16, b0

Then 'b0', RAM location 0, 'b16', 'byte_16', RAM location 16 will all hold the same value; 16.
 

newplumber

Senior Member
Okay so now I am spinning around
so
"poke 16, b0 " ...so the ram location of "poke 16" is the same or not the same location of variable B16?

@texas yes first time I made a typo :) joking

edit .. I am studying the memory map and under special function registers poke and peek to access sfr and ram
so maybe it would put the data in ram and in line 16 if used poke 16,bo ?
 
Last edited:

hippy

Technical Support
Staff member
Okay so now I am spinning around
so
"poke 16, b0 " ...so the ram location of "poke 16" is the same or not the same location of variable B16?
The "16" specifies RAM location 16 and that is also "b16".

But POKE writes a value into that RAM location. PEEK is what you need to read that RAM location.

Might be worth going back and re-reading post #45.
 

newplumber

Senior Member
thanks hippy as I did go back and you cleared up a lot for me
so now I know poke puts data into a ram address
peek reads the data from a ram address up to 255

Code:
; testing code
start:
DO
b0 = 10 
bPtr = 10 
@bptr = b0
b0 = b0 + 10
poke 20,b0
b0 = b0 + 10
write 30,b0 

read 30,b3
peek 20,b2 
bPtr = 10
b1 = @bptr

; b1 = 10
; b2 = 20 
; b3 = 30
debug 
pause 1000
LOOP
okay so I think I am grabbing something here
 
Last edited:

newplumber

Senior Member
thanks Lance so I can do ...
poke 511, b0
on my 20m2?

I am slowly making the smart light code work using
Marks codes ... of course its a big mess but in the early stages
 

newplumber

Senior Member
I must be making a mistake which probably don't understand @bptr
but shouldn't B1 in my code below be 1? it shows 2 in debug
using picaxe 20m2
Code:
b0 = 1 

start:
      bptr = 510
    @bptr = b0     ; 510 ram = 1
      b0 = b0 + 1 
    @bptrdec = b0  ; 509 ram = 2 
      b0 = b0 + 1 
    @bptrdec = b0  ; 508 ram = 3
      b0 = b0 + 1 
    @bptrdec = b0  ; 507 ram = 4
      b0 = b0 + 1 
    @bptrdec = b0  ; 506 ram = 5
     bptr = 510
     b1 = @bptr    ; 510 , b1 = 2
     b2 = @bptrdec ; 509 , b2 = 2
     b3 = @bptrdec ; 508 , b3 = 3
     b4 = @bptrdec ; 507 , b4 = 4
     b5 = @bptrdec ; 506 , b5 = 5       
   debug  
 end
maybe it needs to be coded differently
 

Buzby

Senior Member
@bptrdec decrements after the action.

Your code '@bptr = b0' puts b0 ( i.e 1 ) into RAM location 510.
Then you increment b0 to 2,
'@bptrdec = b0' then stores 2 in bptr, which is still 510, then it decrements bptr.

Follow it in the simulator.

( Change the first @bptr to @bptrdec to fix it. )

Cheers,

Buzby
 

newplumber

Senior Member
okay thanks Buzby
I didn't know that I will try it out
Change the first @bptr to @bptrdec to fix it.
yes true thats exactly what i did works like perfectly
another lesson gained
thanks
 

Buzby

Senior Member
Problems like this would be much easier for beginners to solve if the online reference ( http://www.picaxe.com/BASIC-Commands/A-Z/ ) included all the 'active variables' like @bptrinc.

'Time' is in there, but I can't see what difference between 'Time' and '@bptrinc' determines why one is included in the list, but the other isn't.
 

newplumber

Senior Member
Yes true ...I can't complain because the basic commands PDF helped me a ton
but more code examples would sure make it clearer and I know they can't jam everything in the manual
I do have to say I am very impressed with the PE6 simulator.
 

hippy

Technical Support
Staff member
Problems like this would be much easier for beginners to solve if the online reference ( http://www.picaxe.com/BASIC-Commands/A-Z/ ) included all the 'active variables' like @bptrinc.
The main thing is that '@bptr' variables and the like are not actually commands. Of course, 'time' isn't either but it does lend itself to being a single entry and is used often enough to justify its inclusion even though that is an anomaly.

That said; '@bptr' and other variables probably should be described in the on-line documentation and the best way to access that likely would be through the command list. We will look at seeing how we can add and incorporate that.

'Time' is in there, but I can't see what difference between 'Time' and '@bptrinc' determines why one is included in the list, but the other isn't.
The main difference is that students and others may well be using the 'time' variable, but they are less likely to be doing advanced things like accessing RAM buffers and using '@bptr' variables.
 

marks

Senior Member
Hi newplumber,
G there's been a fewposts since I last looked .when running out variables
i always seem to find a way of reusing them.but its always a good idea to explore suggestions.
I'm not quite sure how this willwork with actual hardware but seems to simulate ok.

I'll let you have a play one feature i like when you turn the light switch on and off
when it is still timing out from motion it will turn off canceling the remaing time.
SensorTime = 12 secs just change to whats required at the top at SYMBOLS.and added DST .
hopefully this be 1 step forward and you wont be posting too big of a bug report lol.
happy fishing.
Code:
#picaxe 20m2         'marks 
#terminal 19200      " 4800 for M4   19200 for M16
SETFREQ M16          "M4 OR M16 time increments at 1 second
dirsB = %11111001             
dirsC = %10111000
SYMBOL SensorTime = 12 ' seconds
SYMBOL LIGHTswitch  = pinB.2
SYMBOL MOTIONsensor = pinB.1
SYMBOL SSRpower     = outpinB.0
SYMBOL SSR       = b0     
 SYMBOL secs     = b1
 SYMBOL mins     = B2
 SYMBOL hours    = B3      
 SYMBOL date     = B4        : SYMBOL day  = B4  'day not used from RTC
 SYMBOL month    = B5   
 SYMBOL year     = B6 
 SYMBOL CommonYear  = b7     : SYMBOL Daylight = b7  : SYMBOL DL = b7
 SYMBOL D0          = b8  
 SYMBOL D1          = b9
 SYMBOL D2          = b10
 SYMBOL D3          = b11
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = w7
 SYMBOL DSTend      = w8     : SYMBOL DayS = w8  
 SYMBOL SunRise     = W9
 SYMBOL SunSet      = W10
 SYMBOL DayL        = w11
"SETFREQ M32 copy paste error      
	TABLE  0,(204,203,202,199,194,189,182,174,166,156)  '   Sunrise +240
	TABLE 10,(147,136,126,115,105, 94, 83, 73, 63, 54)  '   North Dakota
	TABLE 20,( 45, 37, 29, 23, 18, 14, 11, 10, 10, 11)  '  -7 StandardTime
	TABLE 30,( 13, 17, 21, 26, 32, 38, 44, 51, 58, 64)
	TABLE 40,( 71, 77, 84, 91, 97,104,111,118,125,133)  '  2018 (betweenleapyear) 
	TABLE 50,(140,148,156,163,171,178,185,191,196,200)
	TABLE 60,(202,204)
	TABLE 100,( 25, 30, 37, 44, 52, 60, 68, 76, 84, 92) '  Sunset +960 
	TABLE 110,(100,107,115,122,129,136,143,150,157,164)
	TABLE 120,(171,178,185,191,197,203,207,211,214,215)
	TABLE 130,(215,214,212,208,203,197,190,182,173,163)
	TABLE 140,(153,143,132,121,110, 99, 89, 78, 68, 58)
	TABLE 150,( 49, 41, 34, 27, 22, 18, 16, 15, 15, 17)
	TABLE 160,( 21, 25)
 InitialiseTime:
    HI2Csetup I2Cmaster, %11010000, I2Cslow_32, I2Cbyte  ' Set to 100kbps 
      HI2Cout $0 , ( $30, $16, $19, 0 , $07 , $09 , $17)  ' program with UTC/GMT -7 hours StandardTime	
 Main: 
   Switches:  IF MOTIONsensor = 1 THEN : TIME = 0 : ENDIF
              IF LIGHTswitch  = 1 THEN : TIME = SensorTime -1 : ENDIF 
              IF LIGHTswitch  = 0 THEN : SSR = 0 : ENDIF
	Conditionals: IF TIME  > SensorTime THEN : TIME = SensorTime : ENDIF	  
                    IF TIME  < SensorTime THEN : SSR = 1 : ENDIF
      HI2Cin  $0 , (secs,mins,hours,day,date,month,year) ' Read DS1307	or DS3231
        FOR bptr = 2 TO 6   
          @bptr = @bptr/$10*250+@bptr                    ' Convert BCD to Decimal  
        NEXT
  MountainDaylightTime:                     ' United States       
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238             ' First SunDay in November    
	 SunriseToSunset:
            Daylight = Daynumber /6 : READtable Daylight,D0 : INC Daylight :  READtable Daylight,D1
            DayLight = DayLight +99 : READtable Daylight,D2 : INC Daylight :  READtable Daylight,D3     
            DayLight = DayNumber //6 : IF D0 > D1 THEN : SWAP D0,D1 : DayLight = 6 -DayLight : ENDIF
             SunRise = D1 -D0 * Daylight /6 +D0 +240
            DayLight = DayNumber //6 : IF D2 > D3 THEN : SWAP D2,D3 : DayLight = 6 -DayLight : ENDIF
              SunSet = D3 -D2 * Daylight /6 +D2 +960   
	          DayL = hours *60 +mins : DL = 0
	       IF DayL > SunRise AND DayL < SunSet THEN  : DL =1 :  ENDIF       
     IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
     IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
     IF DayNumber = DSTend   AND hours >1 THEN Display   ' DST ends at 0200
	 IF hours =23 THEN : INC date  
	   IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	 ENDIF : hours =hours +1//24 : Sunrise =Sunrise +60 : Sunset =Sunset +60  
	  Sertxd ("MDT ") :  GOTO DateTime                 ' DST +1	  
  Display:Sertxd ("MST ")                                ' StandardTime  
   DateTime:  
   sertxd ("20",#year,"/",#month,"/",#date)              ' Date 20yy/mm/dd 
	d3=mins/10
	d2=mins//10
	d1=secs/$10
	d0=secs//$10
      sertxd ("  ",#hours,".",#d3,#d2,".",#d1,#d0)       ' 24hr time hh/mm/ss          
	   d2=sunrise/60
	   d1=sunrise//60 /10
	   d0=sunrise//60//10
	   Sertxd ("  Sunrise ",#d2,":",#d1,#d0)
	      d2=sunset/60
	      d1=sunset//60 /10
	      d0=sunset//60//10
	      Sertxd ("  Sunset ",#d2,":",#d1,#d0, cr,lf)
SSRcontrol:  IF SSR = 0 THEN : SSRpower = 0 : ENDIF
             IF SSR = 1 AND DL = 0 THEN : SSRpower = 1 : ENDIF	   
   goto main
 
Last edited:

newplumber

Senior Member
Hi Marks
first of all great thanks for making that code and all your other codes
lol
wont be posting too big of a bug report
in order for me to do that (bug report) ...is to take 20 years of picaxe coding classes
but I have a small start from people like you
later on I will use/study the code and feed back my mistakes (incase i screw up copy an paste)
btw this isn't 1 step forward more like 1 year forward
my test code was up to 220 lines and counting
but now you smashed it down to 99 in a smarter/professional way
but thank you again
my smart light just got smarter :)
 

AllyCat

Senior Member
Hi,

In #52, I believe you originally wrote the following, but it appears to have been "lost" in the edit:

does write and read in simple terms do the same but different locations of memory
so in example
poke 20, b0
write 20, b1
would this be two different locations of memory ?
Yes indeed, READ/WRITE and PEEK/POKE are very similar, but apply to different types of memory. Read/Write memory is EE (Electrically Erasable) or "non volatile", which means that it remains unchanged after cycling the power supply. This can be very useful, but EE memory has the disadvantage that it may eventually "wear out" if you make too many Writes (there is no limitation with Reading), so it should be used only for "suitable" purposes. The Program memory itself and also the "Table memory" in most PICAXEs are also EEPROM.

PEEK and POKE access the "RAM" (where the stored values cannot survive a power-down) and is normally set to zeros when the PICaxe starts up (it seems that all the "extended" RAM, above the normal registers b0 - b27, is also set to zero).

There is not normally much point in PEEK/POKEing the RAM which "overlays" the normal bytes and words, because a limitation with PEEK/POKE (and READ/WRITE) is that you can't write them directly into larger expressions. For example INC PEEK... and IF PEEK... etc. are not acceptable syntax, so I'm pleased to see that you're getting to grips with @bptr and even @bptrINC, which are quite "advanced" stuff. ;)

As you've asked for examples, here is a way that you might use POKE/PEEK (and/or WRITE/READ) to release some variables. In #61 above, some bytes are defined as secs, mins, hours, date, month and year. That's quite a lot of the available named variables if you're writing a complex program. So instead, you could write the SYMBOL commands as "pointers" into the extended area of RAM (or into EEPROM). In an even more advanced program you might use EEPROM (WRITE/READ) to avoid having to enter the date, month and year every time a program runs, but RAM (POKE/PEEK) for secs, mins and hours (which might "wear out" the EEPROM eventually). Here's part of the program above, potentially saving a few byte variables:

Code:
symbol SECS = 30      ; Pointer into RAM
symbol MINS = 31
symbol HOURS = 32
symbol DATE = 33
symbol MONTH = 34
symbol YEAR = 35
........
peek HOURS, w0
if w0 > 23 then
   poke HOURS,0
   peek DATE,w0
   inc w0
   poke DATE,w0
endif
.......
It's not quite as compact as using variables directly, but potentially releases 6 bytes of RAM. However, you'd probably want to use two "temporary" variables to handle those long conditional expressions.

Or it can be made more efficient by using @bptr, but the conditional expression really ought to be restructured to make it more readable (and perhaps to even work correctly):

Code:
bptr = HOURS
IF @bptr > 23 THEN
   @bptrINC = 0            ; Reset the HOURS then move bptr to DATE [U]afterwards[/U]
   @bptr = @bptr + 1     ; Increment the DATE
ENDIF
bptr = MONTH
IF @bptr = 4 OR @bptr = 6 OR @bptrtDEC= 9  AND @bptr = 31 OR @bptr = 32 THEN 
    @bptrINC = 1           ; Reset the DATE then move bptr to MONTH [U]afterwards[/U]
    INC @bptr                ; Increment the MONTH
ENDIF
Cheers, Alan.
 

newplumber

Senior Member
@ MARKS ... I ran your program and it is awesome now I get to see if it turns on my light (or led for now with a resistor)
one thing I had to change to see sertxd in the terminal window is the baud rate and it works at 38400 but moves very fast like
10 times a second and also I changed the setfreq to 4 so setfreq m4 but still trying the awesome code out

@allycat thanks, your information is priceless ... although I have to go thru line by line with your examples (could take up to china delivery times)
so to be on the same track ... the command "write" will save data after power is lost but is wearoutable ... so I have a question
If I use write to save data will the data be lost if there is no power to the picaxe for a specific time ..I.E. 10 minutes ...10 days ?
so I'm pleased to see that you're getting to grips with @bptr
I am actually seeing dim light in the tunnel (maybe another train) but I keep going back in forth
with the memory map and the code so I can maybe see/think of it visually

FWIW In killdeer ND where they let me live (for now) our time zone is Mountain standard time but
if you go WEST 60 miles and north 30 miles you will be in central time zone which is 1 hr ahead of us
I guess I'm just glad picaxe didn't mark out the time zones :)
 

AllyCat

Senior Member
Hi,

If I use write to save data will the data be lost if there is no power to the picaxe for a specific time ..I.E. 10 minutes ...10 days ?
According to the Microchip data sheet the typical expected time is 40 years, but it's probably more in practice. ;)

The Program memory can be re-written at least 10,000 times, which should allow you to fix a few bugs, even by trial and error. The EEPROM bytes can be written at least 100,000 times and perhaps 10 or 100 times that in normal operation. But if you used it for the "secs" counter in a continuously-running program, then that only represents just over one day minimum, or perhaps a few weeks in practice.

BTW, I've received three small packages from China in the last few days, each shipped within one day (nothing unusual there) and received in a week (yes, 7 days door to door) ! But another three still to arrive, which may push down the average. :rolleyes:

Cheers, Alan.
 

newplumber

Senior Member
thanks allycat
40 years... that's cool... now I know where to hide my bank password incase i stumble into some cash
"shipping 7 days china?" hmm thinking is London closer then USA from China? I'm still waiting on my cool battery chargers
I already have the batterys which i ordered 1.5 weeks after i ordered the chargers
 

newplumber

Senior Member
@ Marks okay I have your code working awesome now... I deleted the setfreq m32 right above the table charts
for some reason it didn't like it. Another thing is it works on baud rate of 4800 if I put
#terminal 9600 ... it shows some interesting scrabbled garbage
so to make clearer sense is
Code:
#picaxe 20m2         'marks 
#terminal 4800
SETFREQ M4          ' OR M4 time 1 second
dirsB = %11111001             
dirsC = %10111000
SYMBOL SensorTime = 12 ' seconds
SYMBOL LIGHTswitch  = pinb.2
SYMBOL MOTIONsensor = pinb.1
SYMBOL SSRpower     = outpinb.0
SYMBOL SSR       = b0     
 SYMBOL secs     = b1
 SYMBOL mins     = B2
 SYMBOL hours    = B3      
 SYMBOL date     = B4        : SYMBOL day  = B4  'day not used from RTC
 SYMBOL month    = B5   
 SYMBOL year     = B6 
 SYMBOL CommonYear  = b7     : SYMBOL Daylight = b7  : SYMBOL DL = b7
 SYMBOL D0          = b8  
 SYMBOL D1          = b9
 SYMBOL D2          = b10
 SYMBOL D3          = b11
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = w7
 SYMBOL DSTend      = w8     : SYMBOL DayS = w8  
 SYMBOL SunRise     = W9
 SYMBOL SunSet      = W10
 SYMBOL DayL        = w11
'SETFREQ M32   <-- had this ignored
I am using PE 6.0.9.2
 

marks

Senior Member
Hi newplumber,
sorry for the mistake i guess i should of tested on a real chip.
setfreq m32 was a copy paste error i missed
when using setfreq m4 you will need to use the terminal at 4800 time increments at 1 second
its best to use setfreq m16 use terminal 19200 also increments at 1 second
and at m32 seconds increment at half a second,sending all these sertxt may also affect the time accuracy
something you can check heres a slight edit to try.
Code:
#picaxe 20m2         'marks 
#terminal 38400
SETFREQ M32          ' time increments 0.5 seconds
dirsB = %11111001             
dirsC = %10111000
SYMBOL SensorTime = 12 ' so will be 6 seconds
SYMBOL LIGHTswitch  = pinB.2
SYMBOL MOTIONsensor = pinB.1
SYMBOL SSRpower     = outpinB.0
SYMBOL SSR       = b0     
 SYMBOL secs     = b1
 SYMBOL mins     = B2
 SYMBOL hours    = B3      
 SYMBOL date     = B4        : SYMBOL day  = B4  'day not used from RTC
 SYMBOL month    = B5   
 SYMBOL year     = B6 
 SYMBOL CommonYear  = b7     : SYMBOL Daylight = b7  : SYMBOL DL = b7
 SYMBOL D0          = b8  
 SYMBOL D1          = b9
 SYMBOL D2          = b10
 SYMBOL D3          = b11
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = w7
 SYMBOL DSTend      = w8     : SYMBOL DayS = w8  
 SYMBOL SunRise     = W9
 SYMBOL SunSet      = W10
 SYMBOL DayL        = w11
 SYMBOL CRC = b24 
	TABLE  0,(204,203,202,199,194,189,182,174,166,156)  '   Sunrise +240
	TABLE 10,(147,136,126,115,105, 94, 83, 73, 63, 54)  '   North Dakota
	TABLE 20,( 45, 37, 29, 23, 18, 14, 11, 10, 10, 11)  '  -7 StandardTime
	TABLE 30,( 13, 17, 21, 26, 32, 38, 44, 51, 58, 64)
	TABLE 40,( 71, 77, 84, 91, 97,104,111,118,125,133)  '  2018 (betweenleapyear) 
	TABLE 50,(140,148,156,163,171,178,185,191,196,200)
	TABLE 60,(202,204)
	TABLE 100,( 25, 30, 37, 44, 52, 60, 68, 76, 84, 92) '  Sunset +960 
	TABLE 110,(100,107,115,122,129,136,143,150,157,164)
	TABLE 120,(171,178,185,191,197,203,207,211,214,215)
	TABLE 130,(215,214,212,208,203,197,190,182,173,163)
	TABLE 140,(153,143,132,121,110, 99, 89, 78, 68, 58)
	TABLE 150,( 49, 41, 34, 27, 22, 18, 16, 15, 15, 17)
	TABLE 160,( 21, 25)
 InitialiseTime:
    HI2Csetup I2Cmaster, %11010000, I2Cslow_32, I2Cbyte  ' Set to 100kbps 
      HI2Cout $0 , ( $30, $16, $19, 0 , $07 , $09 , $17)  ' program with UTC/GMT -7 hours StandardTime	
 Main: 
   Switches:  IF MOTIONsensor = 1 THEN : TIME = 0 : ENDIF
              IF LIGHTswitch  = 1 THEN : TIME = SensorTime -1 : ENDIF 
              IF LIGHTswitch  = 0 THEN : SSR = 0 : ENDIF
	Conditionals: IF TIME  > SensorTime THEN : TIME = SensorTime : ENDIF	  
                    IF TIME  < SensorTime THEN : SSR = 1 : ENDIF
      HI2Cin  $0 , (secs,mins,hours,day,date,month,year) ' Read DS1307	or DS3231
        FOR bptr = 2 TO 6   
          @bptr = @bptr/$10*250+@bptr                    ' Convert BCD to Decimal  
        NEXT
  MountainDaylightTime:                     ' United States       
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238             ' First SunDay in November    
	 SunriseToSunset:
            Daylight = Daynumber /6 : READtable Daylight,D0 : INC Daylight :  READtable Daylight,D1
            DayLight = DayLight +99 : READtable Daylight,D2 : INC Daylight :  READtable Daylight,D3     
            DayLight = DayNumber //6 : IF D0 > D1 THEN : SWAP D0,D1 : DayLight = 6 -DayLight : ENDIF
             SunRise = D1 -D0 * Daylight /6 +D0 +240
            DayLight = DayNumber //6 : IF D2 > D3 THEN : SWAP D2,D3 : DayLight = 6 -DayLight : ENDIF
              SunSet = D3 -D2 * Daylight /6 +D2 +960   
	          DayL = hours *60 +mins : DL = 0
	       IF DayL > SunRise AND DayL < SunSet THEN  : DL =1 :  ENDIF       
     IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
     IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
     IF DayNumber = DSTend   AND hours >1 THEN Display   ' DST ends at 0200
	 IF hours =23 THEN : INC date  
	   IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	 ENDIF : hours =hours +1//24 : Sunrise =Sunrise +60 : Sunset =Sunset +60  
	   d0="D"   :  GOTO DateTime                       ' DST +1	  
  Display: d0= "S"                                       ' StandardTime  
   DateTime:
   IF secs <> CRC THEN                                   ' wait for change of secs
   Sertxd ("M",d0,"T ")
   sertxd ("20",#year,"/",#month,"/",#date)              ' Date 20yy/mm/dd 
	d3=mins/10
	d2=mins//10
	d1=secs/$10
	d0=secs//$10
      sertxd ("  ",#hours,".",#d3,#d2,".",#d1,#d0)       ' 24hr time hh/mm/ss          
	   d2=sunrise/60
	   d1=sunrise//60 /10
	   d0=sunrise//60//10
	   Sertxd ("  Sunrise ",#d2,":",#d1,#d0)
	      d2=sunset/60
	      d1=sunset//60 /10
	      d0=sunset//60//10
	      Sertxd ("  Sunset ",#d2,":",#d1,#d0, cr,lf)
	ENDIF : CRC = secs	
SSRcontrol:  IF SSR = 0 THEN : SSRpower = 0 : ENDIF
             IF SSR = 1 AND DL = 0 THEN : SSRpower = 1 : ENDIF	   
   goto main
 

newplumber

Senior Member
Hi Marks yes that last code works flawlessly
thanks
just so I understand this code right
at sunset time it will turn on ssr b.0 (the light) only when the motion sensor is activated
and not turn on when motion sensor is not activated...which is neat
thats what my test results are showing so far from last night
I am studing this code to make the light stay on from sunset to 24 hrs (or right at midnight)
then it would use the motion sensor to be on/activated or off/no activation till 1 hour before the sunrise time
when it hits 1 hour+/- before sunrise (I.E. sunrise = 6:13 light turns on at 5:13 or 5:10/5:20) it would stay on till it
passes the sunrise time. the lightswitch would do the same as your code does but only when time hours is 24+,1,2,3,4...to when ever 1 hr before sunrise
I am very impressed at your code which i hope for me it will make sense
but like always in order for me to make changes I first need to understand what the little picaxe is doing with the code
Atleast you sure gave me a year of information
thanks again

EDIT: okay this code rocks ...it is set that if lightswitch is ON = 1 then it will stay on with out
motion sensor activation ...I just hooked up my switch to pin b.2 wrong ( another brainless mistake)
I'll keep playing with the code ...seems like you made it exactly what i was hoping it could do
 
Last edited:

newplumber

Senior Member
@ Allycat I am studing your codes you put in post #63
where you put
"poke HOURS,0"
that is the same as
poke HOURS,B0 ?

so to calm my confusion if I was to code

"write hours,0"
this would not be the same as
write hours, b0
because of different memory maps ?
 

AllyCat

Senior Member
Hi,

"poke HOURS,0"
that is the same as
poke HOURS,B0 ?
No they're not the same, but it's more the "numbers" themselves than the memory type. In computing there are (at least) two different types of numbers called "variables" and "constants".

b0 is a "Variable"; consider it like an empty box in which you can put up to 255 "counters", be they coins, matches, marbles or sugar cubes*. So to remember today's date, you might put 10 cubes into a box marked "b0". Tomorrow, you'd add one cube (or "INCrement" the contents) so that you then know tomorrow's date is 11th. To help you remember what the contents of the box actually represent, you would probably write "DATE" on the outside of the box (consider that like the symbol command: SYMBOL DATE = b0).

To make a calendar, you might also mark a box b1 with the word MONTH and at the end of each month you would empty the DATE box (or strictly leave one cube in place) and add one cube to the MONTH box. In practice, the "rules" for the end of the month are quite complex ("Thirty days hath, September, April, June and November.....etc.") which is why there are some long conditional instructions in marks' program code.

A "constant" can be considered as being similar to our "Variable" boxes above, but the lid is glued in place so you cannot change the contents. Let's assume the box is transparent so you can still see the number of cubes inside. In a computing scenario, the box becomes "locked" when you write or download the program. In some computer languages there is a special character/symbol to identify a "constant", but in PICaxe basic, a number that does not have a "b" or "w" prefix may be considered as a "constant" number.

So back to the quoted example above: HOURS is a "constant" which was previously defined by the: SYMBOL HOURS = 32 and the "0" in POKE HOURS,0 is also a constant. So the command says: "store the value zero into the box (memory) numbered 32" (i.e. empty the HOURS box).

However, POKE HOURS, b0 says "read the (variable) number which is stored in b0 and save that same number in the box numbered 32" (i.e. copy the number stored in b0 into the RAM memory location 32).

You might be concerned that SYMBOL HOURS = might specify for example either "b0" or a "0", which could cause confusion. To overcome this, some people add a character to the variable or the constant name to indicate the "type", but personally I normally use CAPITALS to indicate CONSTANTS and (mainly) Lower Case names to indicate Variables.

* One could invent various scenarios as to why each "box" would be physically limited to exactly 255 "markers", and how the contents might be counted quickly (e.g. by counting the complete rows, columns and layers occupied by identical cubes). But you'd soon realise that exactly the same can be done with a pencil, some "Post It notes" and a few "rules" (e.g. you're not allowed to write a number > 255 onto any sheet), etc..

Cheers, Alan.
 
Last edited:

marks

Senior Member
Hi newplumber,
yes when ever you get a high from the motionsensor ,variable b0 will stay high for the time period
if you retrigger within that time 12(6seconds) the count starts again so will always stay high.
when the switch is on it will always remain high also.switch off cancels the count then goes low.
ssrcontrol works with flag DL=1 which meant daylight time between sunrise to sunset
this held the ssrpower output low during the day DL=0 meant zero daylight.
i was not too sure what you wanted but changed a few variable names to try and make things a little clearer.
I'm still blurry eyed from the weekend Our team the Eagles had another miracleous win its been non stop drinking since
code requires testing hopefully you'll do that...
Code:
#picaxe 20m2         'marks 
#terminal 38400
SETFREQ M32          ' time increments 0.5 seconds
dirsB = %11111001             
dirsC = %10111000
SYMBOL SensorTime = 12 ' so will be 6 seconds
SYMBOL LIGHTswitch  = pinB.2
SYMBOL MOTIONsensor = pinB.1
SYMBOL SSRpower     = outpinB.0
SYMBOL MSR       = b0     
 SYMBOL secs     = b1
 SYMBOL mins     = B2
 SYMBOL hours    = B3      
 SYMBOL date     = B4        : SYMBOL day  = B4  'day not used from RTC
 SYMBOL month    = B5   
 SYMBOL year     = B6 
 SYMBOL CommonYear  = b7     : SYMBOL Daylight = b7  : SYMBOL MFL = b7
 SYMBOL D0          = b8    
 SYMBOL D1          = b9
 SYMBOL D2          = b10
 SYMBOL D3          = b11
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = w7
 SYMBOL DSTend      = w8     : SYMBOL DayS = w8   : SYMBOL SunrisePlus10 = w8
 SYMBOL SunRiseTake60  = w9  : SYMBOL Sunrise = w9  
 SYMBOL SunSet      = W10
 SYMBOL DayTime     = w11
 SYMBOL CRC = b24 
 SYMBOL AON = b25
	TABLE  0,(204,203,202,199,194,189,182,174,166,156)  '   Sunrise +240 minutes
	TABLE 10,(147,136,126,115,105, 94, 83, 73, 63, 54)  '   North Dakota
	TABLE 20,( 45, 37, 29, 23, 18, 14, 11, 10, 10, 11)  '  -7 StandardTime
	TABLE 30,( 13, 17, 21, 26, 32, 38, 44, 51, 58, 64)
	TABLE 40,( 71, 77, 84, 91, 97,104,111,118,125,133)  '  2018 (betweenleapyear) 
	TABLE 50,(140,148,156,163,171,178,185,191,196,200)
	TABLE 60,(202,204)
	TABLE 100,( 25, 30, 37, 44, 52, 60, 68, 76, 84, 92) '  Sunset +960 minutes
	TABLE 110,(100,107,115,122,129,136,143,150,157,164)
	TABLE 120,(171,178,185,191,197,203,207,211,214,215)
	TABLE 130,(215,214,212,208,203,197,190,182,173,163)
	TABLE 140,(153,143,132,121,110, 99, 89, 78, 68, 58)
	TABLE 150,( 49, 41, 34, 27, 22, 18, 16, 15, 15, 17)
	TABLE 160,( 21, 25)
 InitialiseTime:
    HI2Csetup I2Cmaster, %11010000, I2Cslow_32, I2Cbyte  ' Set to 100kbps 
      HI2Cout $0 , ( $30, $22, $04, 0 , $07 , $09 , $17)  ' program with UTC/GMT -7 hours StandardTime	
 Main: 
   Switches:  IF MOTIONsensor = 1 THEN : TIME = 0 : ENDIF
              IF LIGHTswitch  = 1 THEN : TIME = SensorTime -1 : ENDIF 
              IF LIGHTswitch  = 0 THEN : MSR = 0 : ENDIF
   SSRconditionals1: IF TIME  > SensorTime THEN : TIME = SensorTime : ENDIF	  
                     IF TIME  < SensorTime THEN : MSR = 1 : ENDIF
      HI2Cin  $0 , (secs,mins,hours,day,date,month,year) ' Read DS1307	or DS3231
        FOR bptr = 2 TO 6   
          @bptr = @bptr/$10*250+@bptr                    ' Convert BCD to Decimal  
        NEXT
  MountainDaylightTime:                     ' United States       
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238             ' First SunDay in November    
	 SunriseToSunset:
            Daylight = Daynumber /6 : READtable Daylight,D0 : INC Daylight :  READtable Daylight,D1
            DayLight = DayLight +99 : READtable Daylight,D2 : INC Daylight :  READtable Daylight,D3     
            DayLight = DayNumber //6 : IF D0 > D1 THEN : SWAP D0,D1 : DayLight = 6 -DayLight : ENDIF
             SunRiseTake60 = D1 -D0 * Daylight /6 +D0 +180
            DayLight = DayNumber //6 : IF D2 > D3 THEN : SWAP D2,D3 : DayLight = 6 -DayLight : ENDIF
              SunSet = D3 -D2 * Daylight /6 +D2 +960   	           	              
     IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
     IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
     IF DayNumber = DSTend   AND hours >1 THEN Display   ' DST ends at 0200
	 IF hours =23 THEN : INC date  
	   IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	 ENDIF : hours =hours +1//24 : Sunrise =Sunrise +60 : Sunset =Sunset +60  
	   d0="D"   :  GOTO SSRconditionals2:              ' DST +1	  
  Display: d0= "S"                                       ' StandardTime  
   SSRconditionals2:DayTime = hours *60 +mins	         '' DayTime (total minutes of day)
MFL=0 :IF DayTime < SunriseTake60 THEN  : MFL =1 :  ENDIF
AON=0 :IF DayTime > Sunset THEN : AON =1 : ENDIF : SunRisePlus10 = SunriseTake60 +70
       IF DayTime > SunriseTake60 AND Daytime < SunRisePlus10 THEN : AON=1 : ENDIF
   IF secs <> CRC THEN                                   ' wait for change of secs
   Sertxd ("M",d0,"T ")
   sertxd ("20",#year,"/",#month,"/",#date)              ' Date 20yy/mm/dd 
	d3=mins/10
	d2=mins//10
	d1=secs/$10
	d0=secs//$10
      sertxd ("  ",#hours,".",#d3,#d2,".",#d1,#d0)       ' 24hr time hh/mm/ss
         sunrise = SunriseTake60 +60 
	   d2=sunrise/60
	   d1=sunrise//60 /10
	   d0=sunrise//60//10
	   Sertxd ("  Sunrise   ",#d2,":",#d1,#d0)
	      d2=sunset/60
	      d1=sunset//60 /10
	      d0=sunset//60//10
	      Sertxd ("  Sunset ",#d2,":",#d1,#d0, cr,lf)
	ENDIF : CRC = secs	
SSRcontrol:  IF MSR = 0 AND AON = 0 THEN : SSRpower = 0 : ENDIF    ' MotionSenseRelay    AlwaysON             
             IF MSR = 1 AND MFL = 1 OR AON = 1 THEN : SSRpower = 1 : ENDIF  'MidnighttoFirstLight	   
   goto main
 
Last edited:

newplumber

Senior Member
@allycat okay now it makes sense thanks for explaining ...just when I thought I might have a chance at being smart
my knowledge ladder collapses but I am learning one bit per hour at a time

@marks thanks I will test your code later on, its a good thing I never started drinking other wise I would still be celebrating my
vintage first led test (my blood has horrible alcoholism)
 

newplumber

Senior Member
@ Marks I have been testing your code but it seems not to make SSpower to zero "off" (its staying on forever)
after i reset the picaxe it stays off till sunset time then after sunset time = RTC time then SSpower =1 (which is correct) but after that it stays on even after sunrise till i reset it again.
I have been trying to determine why, of course it's probably something pretty simple but keeps jumping over my head
I will keep on studying it
 

marks

Senior Member
Hi newplumber,
I dont have an rtc or hardware available to me at this time '''
but you did give me a clue .
i did spot an error if switch was left on it would remain on or until sensor timed out just after sunrise.
how it's meant to work example

sensor or switch 0000 - 0527
always on 0528 - 0637 (if sunrise 0628 and sunset 1904)
off 0638 - 1903 (was unsure what time after sunrise so made it 10 mins after)
always on 1904 - 2359
i did spot an error if switch was left on it would remain on or until sensor timed out after sunrise.

3rd time lucky maybe lol - the lines i changed this time are marked '''
Code:
 #picaxe 20m2         'marks 
#terminal 38400
SETFREQ M32          ' time increments 0.5 seconds
dirsB = %11111001             
dirsC = %10111000
SYMBOL SensorTime = 12 ' so will be 6 seconds
SYMBOL LIGHTswitch  = pinB.2
SYMBOL MOTIONsensor = pinB.1
SYMBOL SSRpower     = outpinB.0
SYMBOL MSR       = b0     
 SYMBOL secs     = b1
 SYMBOL mins     = B2
 SYMBOL hours    = B3      
 SYMBOL date     = B4        : SYMBOL day  = B4  'day not used from RTC
 SYMBOL month    = B5   
 SYMBOL year     = B6 
 SYMBOL CommonYear  = b7     : SYMBOL Daylight = b7  : SYMBOL MFL = b7
 SYMBOL D0          = b8    
 SYMBOL D1          = b9
 SYMBOL D2          = b10
 SYMBOL D3          = b11
 SYMBOL DayNumber   = W6 
 SYMBOL DSTstart    = w7
 SYMBOL DSTend      = w8     : SYMBOL DayS = w8   : SYMBOL SunrisePlus10 = w8
 SYMBOL SunRiseTake60  = w9  : SYMBOL Sunrise = w9  
 SYMBOL SunSet      = W10
 SYMBOL DayTime     = w11
 SYMBOL CRC = b24 
 SYMBOL AON = b25
	TABLE  0,(204,203,202,199,194,189,182,174,166,156)  '   Sunrise +240 minutes
	TABLE 10,(147,136,126,115,105, 94, 83, 73, 63, 54)  '   North Dakota
	TABLE 20,( 45, 37, 29, 23, 18, 14, 11, 10, 10, 11)  '  -7 StandardTime
	TABLE 30,( 13, 17, 21, 26, 32, 38, 44, 51, 58, 64)
	TABLE 40,( 71, 77, 84, 91, 97,104,111,118,125,133)  '  2018 (betweenleapyear) 
	TABLE 50,(140,148,156,163,171,178,185,191,196,200)
	TABLE 60,(202,204)
	TABLE 100,( 25, 30, 37, 44, 52, 60, 68, 76, 84, 92) '  Sunset +960 minutes
	TABLE 110,(100,107,115,122,129,136,143,150,157,164)
	TABLE 120,(171,178,185,191,197,203,207,211,214,215)
	TABLE 130,(215,214,212,208,203,197,190,182,173,163)
	TABLE 140,(153,143,132,121,110, 99, 89, 78, 68, 58)
	TABLE 150,( 49, 41, 34, 27, 22, 18, 16, 15, 15, 17)
	TABLE 160,( 21, 25)
 InitialiseTime:
    HI2Csetup I2Cmaster, %11010000, I2Cslow_32, I2Cbyte  ' Set to 100kbps 
      HI2Cout $0 , ( $30, $20, $04, 0 , $13 , $09 , $17)  ' program with UTC/GMT -7 hours StandardTime
	TIME = SensorTime ''' remove sensortime out when first powering on during MFL
 Main: 
   Switches:  IF MOTIONsensor = 1 THEN : TIME = 0 : ENDIF
              IF LIGHTswitch  = 1 THEN : TIME = SensorTime -1 : ENDIF 
              IF LIGHTswitch  = 0 THEN : MSR = 0 : ENDIF
   SSRconditionals1: IF TIME  > SensorTime THEN : TIME = SensorTime : ENDIF	  
                     IF TIME  < SensorTime THEN : MSR = 1 : ENDIF
      HI2Cin  $0 , (secs,mins,hours,day,date,month,year) ' Read DS1307	or DS3231
        FOR bptr = 2 TO 6   
          @bptr = @bptr/$10*250+@bptr                    ' Convert BCD to Decimal  
        NEXT
  MountainDaylightTime:                     ' United States       
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber 
           DayS = year *512 **46752         ' year =1 to 99    
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238             ' First SunDay in November    
	 SunriseToSunset:
            Daylight = Daynumber /6 : READtable Daylight,D0 : INC Daylight :  READtable Daylight,D1
            DayLight = DayLight +99 : READtable Daylight,D2 : INC Daylight :  READtable Daylight,D3     
            DayLight = DayNumber //6 : IF D0 > D1 THEN : SWAP D0,D1 : DayLight = 6 -DayLight : ENDIF
             SunRiseTake60 = D1 -D0 * Daylight /6 +D0 +180
            DayLight = DayNumber //6 : IF D2 > D3 THEN : SWAP D2,D3 : DayLight = 6 -DayLight : ENDIF
              SunSet = D3 -D2 * Daylight /6 +D2 +960   	           	              
     IF DayNumber < DSTstart OR DayNumber > DSTend THEN Display
     IF DayNumber = DSTstart AND hours <2 THEN Display   ' DST starts at 0200 
     IF DayNumber = DSTend   AND hours >1 THEN Display   ' DST ends at 0200
	 IF hours =23 THEN : INC date  
	   IF month =4 or month =6 or month =9  and date =31 OR date=32 THEN : date =1 INC month: ENDIF
	 ENDIF : hours =hours +1//24 : Sunrise =Sunrise +60 : Sunset =Sunset +60  
	   d0="D"   :  GOTO SSRconditionals2:              ' DST +1	  
  Display: d0= "S"                                       ' StandardTime  
   SSRconditionals2:DayTime = hours *60 +mins	         '' (moved) DayTime  total minutes of day 
MFL=0 :IF DayTime < SunriseTake60 THEN  : MFL =1 :  ENDIF
AON=0 :IF DayTime => Sunset THEN : AON =1 : ENDIF : SunRisePlus10 = SunriseTake60 +70 ''' (=)
       IF DayTime >= SunriseTake60 AND Daytime < SunRisePlus10 THEN : AON=1 : ENDIF ''' (=)
   IF secs <> CRC THEN                                   ' wait for change of secs
   Sertxd ("M",d0,"T ")
   sertxd ("20",#year,"/",#month,"/",#date)              ' Date 20yy/mm/dd 
	d3=mins/10
	d2=mins//10
	d1=secs/$10
	d0=secs//$10
      sertxd ("  ",#hours,".",#d3,#d2,".",#d1,#d0)       ' 24hr time hh/mm/ss
         sunrise = SunriseTake60 +60 
	   d2=sunrise/60
	   d1=sunrise//60 /10
	   d0=sunrise//60//10
	   Sertxd ("  Sunrise   ",#d2,":",#d1,#d0)
	      d2=sunset/60
	      d1=sunset//60 /10
	      d0=sunset//60//10
	      Sertxd ("  Sunset ",#d2,":",#d1,#d0, cr,lf)
	ENDIF : CRC = secs	
SSRcontrol:  IF MSR = 0 or MFL = 0 AND AON = 0 THEN : SSRpower = 0 : ENDIF  ''' ( or MFL=0) MotionSenseRelay    AlwaysON             
             IF MSR = 1 AND MFL = 1 OR AON = 1 THEN : SSRpower = 1 : ENDIF  ' MidnighttoFirstLight	   
   goto main
 

hippy

Technical Support
Staff member
The code is becoming quite monolithic. It might be best to factor that out into individual routines which set or clear status bits or bytes. That way you can simplify control to something which may look like -

Code:
Do
  Gosub CheckPir
  Gosub CheckDaylightTimes
  If pirActivated = 1 And isDayTime = 0 Then
    Gosub LightOn
    Gosub StartTimeout
  End If
  If LightIsOn = 1 And timedOut = 1 Then
    Gosub LightOff
  End If 
Loop
That allows the routines to do what they need to without worrying about the rest, and the decision making can be done without worrying about how the data it uses is determined.

That will make things much easier to code, debug and alter to fit the specification.

For example, you can check the PIR is coming on and light timeout simply by including "isDayTime = 0 : Return" at the start of the 'CheckDaylightTimes:" routine.

You can also check the "CheckDaylightTimes;" routine without worrying about the PIR or lamp.
 

geezer88

Senior Member
I can guarantee that a year later, when you haven't messed with it for awhile, it will be much easier to pickup what's going on.

learned the hard way, tom
 

hippy

Technical Support
Staff member
learned the hard way, tom
I think we all did, and those who have not simply have that to come :)

There's nothing like a year-old bit of code which one looks at, can't understand, realise it's easier to rewrite from scratch than figure out, to make one realise there may be better ways to do things.

That's not criticism because we will all walk that path at some point; it's part of the learning experience. Things particularly to watch out for is what names of variables mean, will "MFL", "MSR" and "AON" be meaningful in a year ?

It is somewhat acceptable if a routine isn't explained or easily understood providing what it takes in and and what it gives out is well documented and it works.

When one comes back to code it's like others watching now who aren't familiar with it. The simpler it is made for them to follow now the easier it will be oneself in the future. One always starts with the outer big picture, the main loop; "On-Pause-Off-Pause", easy to understand even if one doesn't know what On, Off or Pause is or does, exactly how it's coded or works. You already know the program if not the detail.

The great advantage of modularisation and subroutines is that observers can look at what there is and say that looks right or wrong without considering the rest, can take it on trust that 'isDayTime' does what it's meant to, a different problem - and someone else's - if it does not.

If something is in a short loop and it's not working the problem is within that loop, or something is providing wrong data for the loop. Easier to track down and solve. If the code becomes monolithic an issue could lay anywhere, and it will be harder to know where and what the fix should be.
 

techElder

Well-known member
Tacking on to what Hippy and geezer88 have to say, it doesn't cost anything to make your variable names verbose. Verbose means highly descriptive in this case.

MSD would be MostSignificantDigit, or Psw might be PowerSwitch. Certainly you can overdo it and end up typing a lot, but that's nothing compared to having to rewrite parts of your code a month or two from now.
 

newplumber

Senior Member
@ okay Marks I have it on test again :)... 3rd times the charm for you ... 30th times the charm for me
but thanks again now I should be able to understand 2 percent of it.
How you keep this code all together in a tight form is beyond me

@hippy I think i understand what you said ..
like put chapters in it like a book
thats what i try to do with my code is subroutines
of course I'll need a few extra years to make it squeezeable like yours

@geezer88 lol I don't know about a year ... maybe 5
"learned the hardway"
I do that alot outside real world..
but for picaxe learning the hard way? ..I guess I don't know enough for a simpler way
I'm just happy when I click the "CHECK" button it says "compiled successfully"
memory used = 2047 out 2048 bytes :)
(joking but prolly use a few extra 100 bytes then needed)

@Texasclodhopper
Certainly you can overdo it and end up typing a lot
When I first started learning to code a picaxe I explained every line with 'and a note
Now after watching the pros code I understand how it can be totally over done with
lot more information then needed
but nothing helps me more then "_" key ... like I.E.
SYMBOL PAUSE_TIME = B1
instead of
SYMBOL PT = B1 ' pt = pause time
 
Top