Smart picaxe outdoor light

newplumber

Senior Member
@ Marks your code is working perfect
on a real 20m2 chip...and I am slowly learning your code by wearing out the simulator with step by step
Its going to be one awesome light thanks to your code
This weekend I will try to put it all together when i get to my tig welder (to build the box)
I use a RTC like this
http://www.ebay.com/itm/2PCS-DS3231-AT24C32-IIC-RTC-Clock-Timer-Memory-Module-For-Arduino-Replace-DS1307-/131166685127?epid=1485562694&hash=item1e8a24c7c7:g:RpQAAOSwT2JZk6qo
and very impressed at the accuracy (have a clock display going for 2 years still on time to the second)
 

marks

Senior Member
Hi newplumber,
Thanks for letting me know, now i dont have too hook it to something ,test it or rewrite to make easy to read lol.
Altho I'd like to one day just see things work the way ,that was intended.
the next mod could be monitoring that rtc battery it flash twice at 2000 hrs for trouble
and 3 times for trouble with those solar rechargeable batteries lol.

those ds3231 modules do look good it would be interesting to know how long the batteries do last
and the holder makes it easy to change i would not of thought it was rechargable tho ,like it hints in the description
Ive had ones with those terrible yellow batteries that only last 3-5 years but there cheap to buy
once they die i remove and soldered leads and use them with a supercap and diode.

I did learn from this you just cant rely on similation to write code for someone
the variables sometimes do evolve into different meanings as you write thats normal
a lot of renaming and detail could have been added to make it easy for others(altho i understand it lol)
but because of the forums limits i had to start abreviating so i dont even look at changing this until its finished
quite often in the past ive deleted alot detail to make it fit.
and dont even try any more to upload in colour even the tiniest of examples dont fit.
 

newplumber

Senior Member
Hi Marks
Yes i don't know how long the batteries last either some claim 9 years
I am making this light even smarter since i have few LCDs laying around looking bored so I am adding one to the light
just so i can see the time...etc
I will gets pictures here when i get it working before jamming it to the box
One thing thats cool is all the "smart" will be hidden and look like a normal outside light
with a LCD on it ....but little will they(friends/not friends) know how smart this little box is ...well (cough) should be
Maybe later today I can get lcd to be my friend if not then monday (its working but "#date" etc needs broken down)
yes thats to bad of the forums limit but I understand internet space cost money

supercap? thats a good idea having good luck? heard they fall apart over the years too but
could be reading fake news
 
Last edited:

newplumber

Senior Member
Hi Marks or someone
Here is the front box I am putting together
now I need to make the main box
I added this code to your code for the LCD ...not even close to perfect but it works fine
Code:
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 
 poke 201,year
 poke 202,month
 poke 203,date      
   
If d0 = "D" then: d0 = "S" ' S ummer daylight time for short
elseif d0 = "S" then:d0= "W":endif ' W inter daylight time for short
poke 200,d0

      d3=mins/10
	d2=mins//10
	d1=secs/$10
	d0=secs//$10
      sertxd ("  ",#hours,".",#d3,#d2,".",#d1,#d0)       ' 24hr time hh/mm/ss
	poke 204,hours
	poke 205,d3
	poke 206,d2
         sunrise = SunriseTake60 +60 
	   d2=sunrise/60
	   d1=sunrise//60 /10
	   d0=sunrise//60//10
	   Sertxd ("  Sunrise   ",#d2,":",#d1,#d0)
	   poke 209,d2
	   poke 210,d1
	   poke 211,d0 
	      d2=sunset/60
	      d1=sunset//60 /10
	      d0=sunset//60//10
	      Sertxd ("  Sunset ",#d2,":",#d1,#d0, cr,lf)
		poke 212,d2
		poke 213,d1
		poke 214,d0
	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

	   'ADDED LCD CODE_____________vvvvvvvvvvvvvvv_________________________
peek 200,b2:peek 201,b3:peek 202,b4:peek 203,b5
peek 204,b6:peek 205,b7:peek 206,b8
BINTOASCII b3,b9,b9,b10  'year
BINTOASCII b4,b3,b3,b11  'month
BINTOASCII b5,b4,b4,b12  'date
BINTOASCII b6,b5,b5,b13  'hours
BINTOASCII b7,b6,b6,b6  'tens of minutes
BINTOASCII b8,b7,b7,b7  'unit of minutes
If b3 = "0" then: b3 = 32: endif

LOW RS ' commandmode
 senddata = 2 : GOSUB Send ' (128-147) __________Line 1 CursorPosition
 pause 2
 HIGH RS
FOR index = 0 to 15
 LOOKUP index, (b2,b3,b11,"/",b4,b12,"/",b9,b10,32,b5,b13,":",b6,b7,32),senddata :GOSUB Send
 NEXT index : PAUSE 2
 
 peek 209,b2:peek 210,b3:peek 211,b4:peek 212,b5
peek 213,b6:peek 214,b7
BINTOASCII b2,b8,b8,b8  'sunRISE time hours
BINTOASCII b3,b2,b2,b2  'sunRISE  tens of minutes
BINTOASCII b4,b3,b3,b3  'sunRISE  unites of minutes
BINTOASCII b5,b4,b4,b9  'sunSET time hours
BINTOASCII b6,b5,b5,b5  'sunSET tens of minutes
BINTOASCII b7,b6,b6,b6  'sunSET unit of minutes


LOW RS  'commandmode
 senddata = 192 : GOSUB Send ' ____________ Line 2 CursorPosition
 pause 2
 HIGH RS
FOR index = 0 to 15
 LOOKUP index, ("RIS",b8,":",b2,b3,32,"SET",b4,b9,":",b5,b6),senddata :GOSUB Send    
 NEXT index : PAUSE 2

peek 220,b27
If b27 = 75 then :high c.7:pause 20000
	elseif b27 = 0 then :low c.7:endif 
   goto main
SEND:
 DB7 = bit7
 DB6 = bit6
 DB5 = bit5
 DB4 = bit4
 PULSOUT E,1
 DB7 = bit3
 DB6 = bit2
 DB5 = bit1
 DB4 = bit0
 PULSOUT E,1
RETURN
lcd connections
DB7 = c.0
DB6 = c.1
DB5 = c.2
DB4 = c.3
E = c.4
RS = c.5
I didn't add the InitialiseLCD or other added parts
Maybe I will later but so far I am gaining alot
I also used more POKE n PEEK commands then I ever have but was the best way i could
use the code for the LCD and SERTXT
C.7 is the back light on the lcd so it can be off if motion not activated
BTW I was out of small pots so I used the most turnable one ...50 minutes later I have the contrast
for the LCD in view :)
 

Attachments

AllyCat

Senior Member
Hi,

i would not of thought it was rechargable tho ,like it hints in the description.
Some RTCs used to be shipped with rechargeable "coin" cells (LiR....) but it could be a disadvantage. The normal non-rechargeable coin cells (CR....) are 3 volts per cell, but I believe that the rechargeables are 3.6+ volts, probably over 4 volts when fully charged. That can be a problem because some clock chips use the battery as a reference voltage and "think" that the 5 volt supply is not high enough, so don't respond to the I2C commands.

But many of these RTC modules are now shipped without cells because of the (air) shipping restrictions on all Lithium cells (look at the photograph of the battery holder on the underside). One listing I saw claimed that the cell only costs $0.01 which seems rather optimistic, but you can probably buy several (non-rechargeables) on a card from a Dollar/Pound Store.

However, some of the "DS3231 for Pi" modules might come with a (soldered-in) cell, but I see that those from "Alice" (and many others) now do not include the battery. :( Ignore the photos and look all through the listing !

Cheers, Alan.
 
Last edited:

newplumber

Senior Member
Hi Marks ... I have been testing the awesome code but can you explain
this part of the code

Code:
   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 ''' (=)
the reason is because at 24 hrs or 0:00 ...the SSR is staying on when I am trying to make it shut off when motion sensor is not activated
because in this part of code
Code:
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
I must be missing something
This code I am testing is your original code post #75 with no changes from me
what I am thinking is DAYTIME = total numbers of minutes per day
from 00 to 1440 so maybe I can add another line
Code:
If daytime <= sunrisePlus10 and motionsensor = 0 then : MSR = 0 :endif
I will keep trying tho...thanks

@allycat all my RTCs come with out a battery so I always have to throw one in ...
I wouldn't have a clue if it charges it ...I highly doubt it tho
 

hippy

Technical Support
Staff member
Code:
   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 ''' (=)
I might be wrong but it looks to me that 'DayTime' is the number of minutes since the last midnight. So MFL=1 between midnight and an hour before sunrise, AON=1 between sunset and midnight, and also for an hour before sunrise until 10 minutes after -

Code:
      ____________                                  __
MFL _|            |________________________________|
    _              __________             _________
AON  |____________|          |___________|         |__
     :            :    :     :           :         :
     :          -1hr   :   +10m          :         :  
  midnight          sunrise           sunset    midnight
--------------------------------------------------------

Code:
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
Not so sure about that as I don't know what MSR is but mixed AND and OR operators in an IF statement are always advised against because they don't always do what might be intended.

Ignoring what MSR is I would guess it's enabling SSR power to be turned on during night and enabling it to be turned off during the day -

Code:
      ____________                                  __
MFL _|            |________________________________|
    _              __________             _________
AON  |____________|          |___________|         |__

SSRpower
on  *************************             ************
off                          *************

     :            :    :     :           :         :
     :          -1hr   :   +10m          :         :  
  midnight          sunrise           sunset    midnight
If someone can put brackets around the two conditionals so it is clear what the logical precedence should be it should then be possible to create code which matches that without mixing AND and OR.
 
Last edited:

marks

Senior Member
Hi ,
I just happened to have a look when I should be sleeping
as Hippy suggested I made a blunder there with the or and statements
you do always have to really check properly
this is the first time i pluggeg into some hardware and could see that things wernt working as expected
and slowly remembered how to use those statesments and check a few flags which wer working
and added so i could quickly view in the terminal a bit of cheating lol.briefly checked some times.
for some reason i had thought you could view the inputs and outputs while the chip is running but obviously not.

msr when the switch is on will always be 1

when the switch is off
msr will turn on when triggered if it retriggers within 6 seconds it will stay on
until it finaly timeout then turns off
if the switch is turned on then off before it has timed out it also jumps to the final count then switches off.
this only quick reply so havent had a chance to read everybit.
 
Last edited:

newplumber

Senior Member
@ hippy Thanks for the info... I do like the drawings always makes it clearer

@Marks well don't lose sleep over it I have all year to get this right ...
you already did a ton...plus i ran into bad luck ..no one around here stocks stainless steel so
I just went with 20 gauge steel for the box...then my tig welder pretended to work
so I had to mig weld it together (its more of a pain but doable) but now I have it (metal box) all complete
but since i will be back out of town ..I will have a week or two to perfect it (code) at my out of town picaxe station
enough blah blah about me but please don't loose sleep on this
I will keep testing the smart code
btw ROME wasn't built in 1/ONE/0001 day

EDIT: okay I have tested/retested your code from last post #88 and now
it works beautifully ...I will keep testing it and let you know if any thing gets weird
Thanks again ...I will post the awesome light when I have it all together
 
Last edited:

marks

Senior Member
Hi newplumber,
I rewrote the code hopefully it should make it easier for others to follow .
My head is still spinning trying to decide what to call different variables, headings,
and added some comments to also describe what its meant to be doing, that was so much harder
than copying a bit code just altering ,it should appear a little more modular just hope it was worth it!
i also changed the SSRpower=0 statements is -now doing what I intended
this is a bit different than usuall i would call it a latching state
you just have to make sure you cover all sequences otherwise it may not turn on or off when you want it too.
I did hook up to some hardware and the switches seem quite responsive which i like
when you look at the terminal while it running you can also see what the timed states ,switches,output is doing.
I had a win too wasn't expecting to make it fit here...
Code:
#picaxe 20m2         'marks 
#terminal 38400
SETFREQ M32          ' time increments 0.5 seconds
dirsB = %11111001             
dirsC = %10111000
SYMBOL DelayTime = 12 ' so will be 6 seconds
SYMBOL BYPASSswitch  = pinB.2
SYMBOL MOTIONtrigger = pinB.1
SYMBOL SSRpower      = outpinB.0
SYMBOL Motion_SENSE  = 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 DaySelect = b7  : SYMBOL Motion_ON = 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 Auto_ON     = b25
	TABLE  0,(204,203,202,199,194,189,182,174,166,156)  '   Sunrise = Data +240 minutes
	TABLE 10,(147,136,126,115,105, 94, 83, 73, 63, 54)  '   KillDear , 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) selected as a better fit as excell rounds up
	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 = Data +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, $59, $22, 0 , $19 , $09 , $17)  ' program with UTC/GMT -7 hours StandardTime
	TIME = DelayTime 
 Main: 
   MotionSwitches:  IF MOTIONtrigger = 1 THEN : TIME = 0 : ENDIF             'reset to begining of delaytime
                    IF BYPASSswitch  = 1 THEN : TIME = DelayTime -1 : ENDIF  'holds just before end of delaytime
                    IF BYPASSswitch  = 0 THEN : Motion_SENSE = 0 : ENDIF     'Motion_SENSE =0 (conditional will allow it on until delaytime reached)
      conditionals1: IF TIME  > DelayTime THEN : TIME = DelayTime : ENDIF    'halts when delaytime reached 
		         IF TIME  < DelayTime THEN : Motion_SENSE = 1 : ENDIF    'Motion_SENSE =1 until delaytime reached
		   
      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
  
     DayNumberOfYear:                         
     CommonYear = year //4 +3 /4            ' CommonYear =1              
      DayNumber = month +9 /12   
      DayNumber = CommonYear + DayNumber * DayNumber
      DayNumber = month *275 /9 +date -30 -DayNumber
	
	StartAndEndDaysForDST:                ' United States   
           DayS = year *512 **46752         ' days = year *365.25     
       DSTstart = Days +72//7                 
       DSTstart = 74 -CommonYear -DSTstart  ' Second SunDay in March                  
         DSTend = DSTstart +238             ' First SunDay in November
	   
	 SelectSunriseAndSunsetData:
            DaySelect = Daynumber /6 : READtable DaySelect,D0 : INC DaySelect :  READtable DaySelect,D1    'D0 , D1 holds DataMinutes for SunRise
            DaySelect = DaySelect +99 : READtable DaySelect,D2 : INC DaySelect :  READtable DaySelect,D3   'D2 , D3 holds DataMinutes for Sunset   
            DaySelect = DayNumber //6 : IF D0 > D1 THEN : SWAP D0,D1 :DaySelect = 6 -DaySelect : ENDIF 
        SunRiseTake60 = D1 -D0 * DaySelect /6 +D0 +180
	      DaySelect = DayNumber //6 : IF D2 > D3 THEN : SWAP D2,D3 : DaySelect = 6 -DaySelect : ENDIF    ' example if daynumber is 366 our tabledata for sunset is the last entry at 161
      SunSet = D3 -D2 * DaySelect /6 +D2 +960                                                              ' Sunset =25 + 960   (985minutes) /60 gives us our time 16:25
	                                                                                                     ' if our daynumber is between 360 and 366  table data 21 and 25 will be recalculated.
	StandardTime: d0 = "S"                                                 
     IF DayNumber < DSTstart OR DayNumber > DSTend THEN SelectOurDayTime_ONrequirement
     IF DayNumber = DSTstart AND hours <2 THEN SelectOurDayTime_ONrequirement  ' DST starts at 0200 
     IF DayNumber = DSTend   AND hours >1 THEN SelectOurDayTime_ONrequirement  ' DST ends at 0200
     
      AdjustForMountainDaylightTime:  d0 = "D"                                ' DST adjust +1
     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 	 
     
     SelectOurDayTime_ONrequirement:
     DayTime = hours *60 +mins	                     ' DayTime = minutes of day
                 conditionals:                                                                              ' example 19/09/2017  sunrise 06:35  sunset 18:53
          Motion_ON =0 :IF DayTime < SunriseTake60 THEN  : Motion_ON =1 :  ENDIF                            ' Motion_ON =1      0000 to 05:35
            Auto_ON =0 :IF DayTime => Sunset THEN : Auto_ON =1 : ENDIF : SunRisePlus10 = SunriseTake60 +70  '   Auto_ON =1                              18:53 to 23:59      
                 IF DayTime >= SunriseTake60 AND Daytime < SunRisePlus10 THEN : Auto_ON =1 : ENDIF          '   Auto_ON =1              05:35 to 06:44  
   Display:
   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,"  TIME  ",#TIME,"  ",#Auto_ON," ",#Motion_ON," ",#Motion_SENSE,"  ",#SSRpower, cr,lf)
	ENDIF : CRC = secs
	
SSRlatchcontrol: IF Auto_ON = 0 and Motion_ON = 0 THEN : SSRpower = 0 : ENDIF 
                 IF Auto_ON = 0 and Motion_ON = 1 and Motion_SENSE = 0 THEN : SSRpower = 0 : ENDIF
		     IF Auto_ON = 1 OR  Motion_ON = 1 and Motion_SENSE = 1 THEN : SSRpower = 1 : ENDIF 
   goto main
 

newplumber

Senior Member
Hi Marks
just hope it was worth it!
Definitely is worth it... thats awesome now your code just got better
Now I can understand way more clearer and thank you alot for doing that
Now back to the editor
 

newplumber

Senior Member
Hi
I have been testing the code with my schematic/drawing and it has been working sweet
Now all I have to do is put it all together when I get back home (in a week or less)
then hopefully it will be in finished projects with the final picture
thanks again to Marks and all of you ...
One thing I did add but not on the drawing is mosfet to pin B.0
in case I wanted to use a mech 5v-20amp relay with a diode
if my SSR doesn't stay smart
but over all it makes it so much fun to be winning (so far)
 

Attachments

newplumber

Senior Member
Allycat said:
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)
#63

Hi Allycat /all
I was doing some testing on EE memory using a 20m2 like I.E.
Code:
Start:
b2 = 111 :Write 100,b2 
b2 = 112 :Write 101,b2 
read 100,b2 
read 101,b3  
debug :end
after I programmed that code I programmed this code
Code:
Start:
read 100,b2 
read 101,b3 
debug :end
hoping b2/b3 would keep data the same but now I believe when PE5/6 programs a picaxe it clears all memory
so is it possible to program to a picaxe without clearing all memory or would I need to use a memory chip?
 

AllyCat

Senior Member
Hi,

You just need a #no_data at the top of the program. I nearly always use it anyway, because it speeds up programming by omitting the "second pass" of writing to the EEPROM. There's also the #no_table directive for X1s and X2s.

Cheers, Alan.
 

newplumber

Senior Member
Thanks Allycat I tested it out
using my both codes #93 then before i downloaded the
read 100,b2 I even cut the power to the chip for a while
and sure enough it saved it ...funny how two words and # can save the day
I'll have to try out the no_table when i hook up a 20X2
Thanks again
Now since the smart light code is working perfectly
and of course I have to add more so my next step is to
read how many times the motion sensor activates during midnight-sunrise hrs
I think I might try saving the activation data per year
some how to use write and in a word ... back to sharping my pen
If it goes over 65,536 I seriously have a problem with bats
 

lbenson

Senior Member
I think I might try saving the activation data per year
some how to use write and in a word ... back to sharping my pen
If it goes over 65,536 I seriously have a problem with bats
Note that if you run out of on-chip eeprom, the RTC you are using appears to be the kind which has 4K of eeprom onboard.
NP_RTC.jpg
For the RTC modules I have, the eeprom is usually addressed at address 7, not 0:
Code:
symbol cI2CeeprDeviceAdr=%10101110 ' AT24C32 on DS3231 module has high address bits

hi2csetup i2cmaster,cI2CeeprDeviceAdr, i2cfast, i2cword
 
Last edited:

newplumber

Senior Member
Hi lbenson
I think your right... and I will just use the RTC eeprom
except I will have to understand your code to access it
so I'm guessing ?

Code:
symbol cI2CeeprDeviceAdr=%10101110 ' AT24C32 on DS3231 module has high address bits

hi2csetup i2cmaster,cI2CeeprDeviceAdr, i2cfast, i2cword
HI2Cout $07, data
I'll try to find some examples
 

AllyCat

Senior Member
Hi,

some how to use write and in a word ... back to sharping my pen
If it goes over 65,536 I seriously have a problem with bats
You might also have a problem with "wearing out" the EEPROM memory location(s) ! And, your program should probably include something like counter = counter + 1 MAX 65535 (or a lower value) so that you know that a value of '1' really is '1' and not 65537 ;)

To avoid wearing out the EEPROM you would normally use RAM (variables) for any frequently-changing values. But various "tricks" are possible, for example spreading the count across a number of memory locations, or storing only the high byte of a counter word in EEPROM, or writing only when the power supply might be about to fail.

However, the simplest method is probably just to copy the (RAM) counter value to EEPROM once a day (e.g. at sunrise), not forgetting to Read the "non-volatile" value back into the RAM variable whenever power is re-applied.

Cheers, Alan.
 

newplumber

Senior Member
Hi Allycat
well first I have a problem how to write to the RTC eeprom
then I can wear it out :)
You mentioned many good points
the simplest method is probably just to copy the (RAM) counter value to EEPROM once a day (e.g. at sunrise), not forgetting to Read the "non-volatile" value back into the RAM variable whenever power is re-applied
I like the simplest method but....(thinking)....(rethinking my thinking)....how would I read the "non-volatile" value when say it lost power/power back on
or writing only when the power supply might be about to fail
that would be awesome ...like I.E.
(power company calls me and says a tree 1/2 mile from you is scheduled to break your power lines in about 10 minutes
so make sure your picaxe writes data to the RTC eeprom) :)
For reals I know it can be done (data to rtc eeprom once a day)
all i have to do is do separate tests (picaxe to rtc)which will break down more easily to understand
but thanks again
 

techElder

Well-known member
newplumber, one way to "forsee the future power loss" is to add a diode in your power supply line before a bunch of filter capacitance. Use an input to test the voltage on the anode end of the diode.

When the power goes off, this input will go towards zero (the diode will be reverse biased and isolate) while the filter capacitance will hold up the power supply voltage long enough to test the input and run a subroutine to save your data to EEPROM.
 

AllyCat

Senior Member
Hi,

..how would I read the "non-volatile" value when say it lost power/power back on
Re-loading the variable(s) when power is applied is easy enough - just put a routine at the start of the program to Read the EEPROM when the PICaxe boots up.

Writing the critical values to EEPROM when power fails is a little more tricky, but a PICaxe doesn't need much time or power to Write a few values, so the supply rail decoupling capacitance may hold sufficient energy. If lots of data needs to be saved then a "supercapacitor" or a small battery might be used.

Most M2s work down to below a 2 volts supply, so simply initiating the "backup" process when the supply falls to (say) 3 volts might be sufficient. However, if you don't want to include a permanently "polling" program to test the supply voltage, then an interrupt is needed:

All M2s have sufficient on-chip hardware (i.e. a Comparator, Fixed Voltage Reference and "DAC" resistive-divider chain) to generate an interrupt pulse when the supply rail falls. The problem is that M2s don't support any internal interrupts, so it's necessary to use a couple of pins to feed out the "pulse" and then input it as an "external" interrupt. But for a "minimum configuration" you might use a comparator output to drive the Serial (Programming) Input as a reset/interrupt.

Cheers, Alan.
 

newplumber

Senior Member
Okay I totally misunderstood "shortly before losing power"
which is okay for me ...sadly happens more then I admit (and I admit alot)

@texasclodhopper...makes perfect sense ...lol (after reading some other post you made about markers)
can you marker up some kind of schematic ? :)JK but for reals I was wondering if you had some
kind of simple schematic if not ...I suppose i can search the forum but thanks for setting me straight
totally forgot about the capacitors holding power but another tool in my box

@ Allycat yes okay make a "read data" routine before main routine
But for a "minimum configuration" you might use a comparator output to drive the Serial (Programming) Input as a reset/interrupt
I sure do not understand how a person can do that ...but thanks so much already Allycat
 

AllyCat

Senior Member
Hi,

for a "minimum configuration" you might use a comparator output to drive the Serial (Programming) Input ....
Perhaps I should have said "minimum hardware" because it won't be the simplest to program, nor easiest to understand. ;)

But basically, it just needs a wired connection from the comparator output (Leg5 on an 08M2) to the Programming Input (Leg 2). Not even any need for a resistor (because Leg2 is input only) but a diode or resistor might be used if Leg5 is required also for another function. However, it will need a larger supply decoupling capacitor, to hold up the supply voltage whilst the PICaxe restarts.

Normal PICaxe (M2) commands can set up the "FVR" as a 1 volt reference voltage, and the "DAC" as a voltage divider from the supply rail, to deliver 1 volt at a "low warning" supply level. Then it needs a few POKESFR commands to set up the comparator to compare the FVR with the DAC, and output a "High" level (to SerIn) if a "low supply" is detected. A "High" applied to the programming input resets the PICaxe, but that turns the Comparator Output (Leg5) back into an input, so the PICaxe doesn't find a program download and boots up as normal.

Early in the program initialisation, the PICaxe would measure the supply voltage (probably using CALIBADC10): If the supply voltage is "normal" then the program would Read the NV memory values into the appropriate RAM variables and run the main program; if the supply is "low" then it would assume the supply is failing and would copy the variables back into EEPROM. If the supply were detected as "very low" then it would not attempt to Write to the EEPROM, because the falling voltage might corrupt the memory data.

Of course with a battery supply, it would only be necessary to poll a CALIBADC10 occasionally and backup the variables if the voltage appears to be getting too low.

Cheers, Alan.
 

newplumber

Senior Member
Wow this is good stuff

@texasclodhopper thanks for the schematic ...i will give it a try

@Allycat Okay ...I ordered some super caps
http://www.ebay.com/itm/ELNA-LOT-OF-4-DH-5-5V-1F-Cap-Super-capacitor-RADIAL-For-battery-SNAP-IN/302029281623?ssPageName=STRK:MEBIDX:IT&_trksid=p2057872.m2749.l2649
..used a US supplier ...(I don't want to install the light in -20 F weather)
Ok so now I have a track to follow .... I like the your info and thanks but it always takes me (yes the confused one) a few times to read
I can make a test circuit just using a 4700uF cap for now with out RTC and a standard 1n4001 diode ..i think anyway

@lbenson
I do have eeprom on my RTC how did I find out? always the forums always
I tried hippys sweet code
Code:
Pause 2000
SerTxd( "Starting", CR, LF )
For b0 = $A0 To $AF Step 2
  HI2cSetup I2CMASTER, b0, I2CSLOW, I2CWORD
  HI2cOut 0, ($AA)
  Pause 20
  HI2cIn 0, (b1)
  If b1 = $AA Then
    HI2cOut 0, ($55)
    Pause 20
    HI2cIn 0, (b1)
    If b1 = $55 Then
      b1 = b0 /  16 + "0" : If b1 > "9" Then : b1 = b1 + 7 : End If
      b2 = b0 // 16 + "0" : If b2 > "9" Then : b2 = b2 + 7 : End If
      SerTxd( "Found at $", b1, b2, CR, LF )
    End If
  End If
Next
SerTxd( "Done", CR, LF )
then I tried your code with 20m2
Code:
#picaxe 20M2
hi2csetup i2cmaster,%10101110, i2cslow, i2cword
hi2cout 0, ("A","B","C","D","E","F","G","H","I","J","K","L"," M","N","O")
hi2cin 0, (b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14 ,b15)
sertxd (b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14 ,b15,cr,lf)
because I figured since "Found at $AE" which = %10101110
matched your "hi2csetup i2cmaster,%10101110..." and worked flawlessly
One question tho ...is that the full eeprom memory on the at24c32? b0-b15? I tried looking for a schematic on it ...OR i mean
I tried looking for a simple schematic for a plumber to understand ..i'll keep looking
 

newplumber

Senior Member
@texasclodhopper yes might be over kill but I always wanted to try super capacitors
so I figured why not try them out ... maybe if the power is off say for only short time it might not even notice

everytime I read into the ds3231
I discover more options ..its almost like a picaxe ....or not quite
but it is impressive
https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
 
Last edited:

newplumber

Senior Member
Texasclodhopper , I do see your point and I understand I go way over board on typing useless learning information here
but I am trying to have fun while learning , and I know I have to try harder to keep my posts to good use able points/questions.
 

hippy

Technical Support
Staff member
You could forego power fail detection by writing to EEPROM only when the count has increased by say 10. That way you will only be out by 10 every power fail which probably doesn't matter; can adjust until it doesn't really matter.

And you could even count restarts as likely power fails and adjust the count by how many of those there were. That would at least allow the likely range of counts to be determined.
 

newplumber

Senior Member
Thanks Hippy ...yes good point ... the motion activation data is not important..it would only be read for interest
what is important for me is the fact of learning how to save data before main power fails and you ,allycat,texas lots of others showed how
So I think for this project I will keep it simple and use your suggestion and save the low power warning for a different project
 

lbenson

Senior Member
... is that the full eeprom memory on the at24c32? b0-b15? ...
The at24c32 has 4K bytes of eeprom (that's the "32" (number of K bits) divided by 8 bits per byte). I used b0-b15 because that's the number of bytes in a "block" on this eeprom. If you try to write crossing a block boundry, you will overwrite to the beginning of the block. For instance, "HI2COUT 15, ("A","B") will write "A" to the 15th byte in the eeprom (starting from 0), and "B" into the first byte (eeprom address 0)--probably not what you intended.

So to fill all of the at24c32 eeprom with A-P you would do the following:
Code:
#picaxe 20M2
hi2csetup i2cmaster,%10101110, i2cslow, i2cword
w13 = 0
do ' through the last 16-byte block
  hi2cout w13, ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P")
  pause 20
  w13 = w13 + 16
  if w13 = 0 then exit ' upon wraparound--I think I got the terminating condition right--untested
loop
I'll second Tex's thanks for your enthusiastic and JK-y contribution to the forum. We geezers (speaking only for myself) love it when someone wants to know about the esoteric stuff we know.
 
Last edited:

newplumber

Senior Member
thanks alot Lance
now I think i understand (easy for everyone else)

so to have "B" saved correctly
"HI2COUT 15, ("A","B")
you need to use
Code:
HI2COUT 15, ("A")
HI2COUT 16, ("B")
EDIT: Okay I have ds3231/at24c32 eeprom mastered ..of course with all the help from you
my test code
Code:
#picaxe 20M2
#terminal 4800
hi2csetup i2cmaster,%10101110, i2cslow, i2cword 'address for the at24c32 memory 
  hi2cout 0,  ("block0_block0_00") :pause 2
  hi2cout 16, ("block1_block1_01") :pause 2' each block is 16 bytes 
  hi2cout 32, ("block2_block2_02") :pause 2

do 	
hi2cIN 0,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15)	' read block 0	
sertxd (" 0=  ",b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,CR,LF) 'terminal display
 pause 2000 
hi2cIN 16,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15)	' read block 16	
sertxd ("16=  ",b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,CR,LF) 'terminal display
 pause 2000 
hi2cIN 32,(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15)	'read block 32	
sertxd ("32=  ",b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,CR,LF) 'terminal display
 pause 2000 
loop
 
Last edited:

lbenson

Senior Member
You got it. As a special bonus, this works both in the PE6 simulator (with "Simulate 24LC512 EEPROM" selected under "Simulation Options") and on a real 08M2 with DS3231 module attached:
Code:
' 20at24c32 at24c32 tester
#picaxe 08M2 ' 20M2
#terminal 4800
pause 2000
sertxd("Beginning",cr,lf)
hi2csetup i2cmaster,%10101110, i2cslow, i2cword
w13 = 0
do ' through the last 16-byte block
  hi2cout w13, ("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P")
  sertxd("-") ' progress indicator
  w13 = w13 + 16
'  if w13 = 0 then exit ' upon wraparound--I think I got the terminating condition right--untested
  if w13 > 255 then exit ' upon wraparound--I think I got the terminating condition right--untested
loop
sertxd(cr,lf)
data 0, (6,14,14,3,9,14,1)
for b25 = 0 to 3
  read b25,b24
'  w13 = $fff0 + b24
  w13 = $00f0 + b24
  hi2cin w13,(b24)
  sertxd(b24)
next b25
sertxd(" ")
for b25 = 4 to 6
  read b25,b24
'  w13 = $fff0 + b24
  w13 = $00f0 + b24
  hi2cin w13,(b24)
  sertxd(b24)
next b25
sertxd("!",cr,lf)
(Only first 256 bytes are written.)

Your code also works in the simulator as well as on the chip.
 

newplumber

Senior Member
Thats cool Lance thanks ...i guess I only mastered sending/receiving bytes now
you showed some learning on how to use them.
So the eeprom memory on the at24c32 is 4k bytes
so it will have 249 blocks = 3984 bytes plus 16
this little ds3231 RTC has billions of uses
 

lbenson

Senior Member
4K may be 4,000 when you are talking dollars, but not when talking powers of 2 (which is generally what an eeprom storage amount will be--128 bytes, 256, 512, 4096, and 65536 (2^16) for an AT24C512). 2^12 is 4,096 and that's how many bytes you have with the AT24C32--256 16-byte blocks.

That particular indexing technique in the program I posted is not likely to be very useful--it was just a little bit of sport to illustrate that the data had been written as expected.
 

newplumber

Senior Member
Okay yes i should have known good reminder
That particular indexing technique in the program I posted is not likely to be very useful
Maybe true but it does open another way for messaging data
 
Top