Switching issues

Rampz

Well-known member
Add some new code for the voltage measurements into your "Volttoolow:" routine (makin
So if I readadc10 a second time, make the adjustments as I already have, then compare to my existing SYMBOL settings, then and "IF" to compare leading to "low led"? Kind of arrangement within the "Volttoolow:" routine?
Simon
 

Jack Burns

New Member
Rampz, I have had a go at restructuring your code and implenting some of the features you require, so hopefully this will help you make further progress. However, do bear in mind that it's just something for you to experiment with and should NOT be seen as a final solution. As I said before, structured programming isn't my strong point. See the comments section at the top of the code to see what has been implemented.

Please note:
The formatting is far from ideal as there is a mixture of upper and lowercase code (Yours, Geoytex & mine), also the indentation changed when it was posted to the Forum (this may be down to different contributors having different tab/space settings in Program Editor).
However, this gives you something to play around with and hopefully improve upon as you learn more.

I have added lots of sertxd commands so that I could see what was happening on the Terminal screen, however sertxd uses C.0, so this can conflict with any output command on that pin (e.g. high C.0 , low C.0). Also setting a high or low on C.0 can cause sertxd data to become corrupt if not used carefully (as I found out!).

I have changed LED2 to C.1 for posting, however the code will work with if set back to C.0 (just make sure you don't use C.0 for driving a motor).

Good luck with your project.

Code:
#picaxe 08m2
SetFreq M16

' Code snippets from Rampz, Goeytex & Jack Burns

'.----------------------------.
#REM

REQUIREMENTS
============
1.     If the button is pressed for say 20ms then I want the output to
        stay on for 400ms.
        (DONE)

2.    If the button is pressed and held on, then I want the output to
        stay on till button released plus 400ms.
        (DONE)

3a.    If the output is switched on continuously for more than say 
        30 seconds,    then treat it as a stalled motor, so stop the output
        to protect the motor until the microswitch resets and re-triggers.
        (DONE)

3b.    Also flash C0 a couple of times and write 1 to memory for
        later recall.
    (NOT IMPLEMENTED)
        
4a    Disable C4 if voltage is seen to be below 10.4v for a set time
        of (say) 10secs to protect motor and battery.
        (DONE)
                
5.  When voltage returns to a higher level say 11.5v wait 1 hour
        for battery to charge enough to power the motor again.
        (DONE)

6.  Each time C4 is disabled due to low voltage write 1 to memory
        for later recall.
        (NOT IMPLEMENTED)
        
#ENDREM


#no_data
#terminal 19200

'.----------------------------.
'| Constants                  |
''----------------------------'
Symbol BTN = PinC.3  '// Switch
Symbol LED = C.4
Symbol LED2 = C.1 ' Originally used C.0 but changed to C.1 as SERTXD messages are now used
Symbol Pressed = 1
Symbol LowBattLevel = 104 ' Low voltage threshold x 10 (104 = 10.4v)
Symbol AvgCount = 10 ' Number of ADC readings to be averaged when calculating battery voltage
Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
Symbol MinRunTime = 501 '// 501 = 400 ms approx.  Adjust this value to change delay time after button released
Symbol LowBattDuration = 10
Symbol ChargeReadInterval = 4000 ' 4000 = 1 sec @ 16Mhz Take a reading every second
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600
Symbol ChargeReadCount = 20 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)

'.----------------------------.
'| Variables Used             |
''----------------------------'
SYMBOL ReserveB1 = b1 ' Used in "MeasureBatteryVoltage" routine
SYMBOL ReserveB2 = b2 ' Used in "MeasureBatteryVoltage" routine
SYMBOL ReserveB3 = b3 ' Used in "MeasureBatteryVoltage" routine
Symbol Counter = W2 ' Used in several places
SYMBOL ADCvalue = W3 ' Used in "MeasureBatteryVoltage" routine
SYMBOL ADCavg = W4 ' Used in "MeasureBatteryVoltage" routine
SYMBOL Volts = W5 ' Used in several places
Symbol VmonCount = W6 ' Used in battery monitoring loop
Symbol LowBattCount = W7 ' Used for testing batt low for 10 seconds


MAIN:
  IF BTN = Pressed then
        High LED
      StartCounter:
      Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
        '// If here then switch released
      '//  Time Out after 400 ms (however, no delay if motor was previously stalled)
      '// If another Press detected then reset timer
      Do While Counter > 1    
          Counter = Counter - 1
          If BTN = Pressed then 'start over
            Goto StartCounter
          END IF
      Loop
      LOW LED
  END IF      
    ' Now measure battery voltage approx once a second
    inc VmonCount
    if VmonCount>1000 then ' 1000 = approx 1 sec.  Measure battery voltage approx once a second
            VmonCount = 0
            gosub MeasureBatteryVoltage
            sertxd("Main Loop - Battery level: ")
            gosub ShowVoltage
            sertxd("   (LowBattCount: ",#LowBattCount,")",cr,lf)
            if Volts <= LowBattLevel then ' Set at 10.4 Volts in "Constants" section
                inc LowBattCount
                if LowBattCount > LowBattDuration then ' approx 10 seconds
                        gosub LowBatteryVoltage
                end if        
            else
                LowBattCount = 0 ' reset count if battery doesn't stay low for specified duration
            end if
    end if
GOTO MAIN:

MotorStalled:
    sertxd("Motor Stalled",13,10)
        low LED '// Turn motor drive off
    high LED2 '// Turn fault light on
        do : loop while BTN = pressed '// Wait for switch to be released
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Microswitch has now reset",cr,lf)
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
     
MeasureBatteryVoltage:
        '// Measure average voltage over 10 readings.
        ADCavg = 0 'Initialise to 0
        for b1 = 1 to AvgCount
            ReadADC10 C.2,ADCvalue
        ADCavg = ADCavg + ADCvalue
        next b1
        ADCavg = ADCavg / AvgCount
        ' Convert ADC Value to Voltage
        Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
        Volts = Volts *16      ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
        Volts = Volts /100 ' Reduce to 3 digits
        '// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
        return
    
    ShowVoltage:
        BinTOASCII Volts, b3,b2,b1 : IF  b3 = "0" THEN : b3 = " " : ENDIF' leading zero blanking 
        Sertxd (b3,b2,".",b1," Volts")  ' 0.1 resolution
        return

LowBatteryVoltage:
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (")
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 11.5V",cr,lf)
            pause 4000 ' wait 1 second between readings
        loop until Volts >= 115 ' 11.5 Volts
        '// Battery voltage has now reached upper level
        sertxd("Battery has reached ")
        gosub ShowVoltage
        sertxd(" - Now charging for 1 hour",cr,lf)
        '// Now wait an hour while battery continues to charge
        '// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
        Counter = ChargeReadCount
        do
            gosub MeasureBatteryVoltage
            sertxd("Battery level: ")
            gosub ShowVoltage
            sertxd(" - Charge time remaing: ",#Counter," Seconds",cr,lf)
            pause ChargeReadInterval ' Time between voltage readings while charging
            dec Counter
        loop while Counter > 0
        LowBattCount = 0 ' Reset time count for low battery voltage
        return
 

Jack Burns

New Member
I forgot to say that for test purposes the motor stall time (MaxRunTime) has been reduced to 6 seconds and the charge time (MaxReadCount) has also been reduced from 1 hour to 20 seconds. MaxReadCount now seems a strange name, but it is the number of voltage measurements taken while the battery charges.
Code:
Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
Code:
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600
Symbol ChargeReadCount = 20 ' Normally 3600 readings while battery charges
 

Rampz

Well-known member
Rampz, I have had a go at restructuring your code and implenting some of the features you require, so hopefully this will help you make further progress. However, do bear in mind that it's just something for you to experiment with and should NOT be seen as a final solution. As I said before, structured programming isn't my strong point. See the comments section at the top of the code to see what has been implemented.
Thank you Jack Burns its is a huge help such great work, its been and still is a massive learning curve, like i say i am a slow learner, i need to see it, understand it fully, then work out why it can't be anything else, then i can get my head around it a bit.

Like indents, i could see it but only by using it and Goeytex comments do i now understand it better

I have been playing with Sertxd and bintoascii from that learning about CR or 13 (carrier return) and LF or 10 (line Feed) following on how i can't then use b1, b2 or b3 or w0 and w1 because of it.

Regards C0 i was aware not to connect a motor to it as an example or it would just drive when sending data or using sertxd etc, it was flickering madly anyway with data to the terminal and coming on when needed which i guess would interfere with data transfer?

I hope eventually to be able to use C1 with a puch button for memory read back of faults and C0 for the led to show them

I do manage to try things and get a lot less "syntax errors" and when i do i can start to sort the problem.

I did notice at higher clock speeds i need to set the terminal to 19200 for 16mhz and could see that i can include that at the top of the program.

Just so much to learn to do basic things, i have several books with projects and a great forum with a huge range of experts willing to help out or advise, thank you everyone

Time to keep learning, test and move forward with my project

Rampz
 

Jack Burns

New Member
Regards C0 i was aware not to connect a motor to it as an example or it would just drive when sending data or using sertxd etc, it was flickering madly anyway with data to the terminal and coming on when needed which i guess would interfere with data transfer?
Most of the flashing you are seeing on C.0 is due to the data transfer taking place while the battery voltage is monitored within the main loop. The BTN is monitored between these readings, so it doesn’t cause a problem if the LED comes on due to it being pressed.

The only time I had data corruption (which puzzled me for a while) was when I had a “low LED” command before a sertxd message. Then it occurred to me that the serial terminal was interpreting the signal as data.

Changing the order to that shown below fixed the problem.

Code:
MotorStalled:
   sertxd("Motor Stalled",13,10)
   low LED '// Turn motor drive off
 

Rampz

Well-known member
Code:
MeasureBatteryVoltage:
        '// Measure average voltage over 10 readings.
        ADCavg = 0 'Initialise to 0
        for b1 = 1 to AvgCount
            ReadADC10 C.2,ADCvalue
        ADCavg = ADCavg + ADCvalue
        next b1
        ADCavg = ADCavg / AvgCount
        ' Convert ADC Value to Voltage
        Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
      volts = volts *65    ' correction needed to make 102  (mine)
      volts = volts /64    ' read 104                       (mine)
      volts = volts - 1    ' slight adjustment to increase accuracy of read out (mine)
        Volts = Volts *16      ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
        Volts = Volts /100 ' Reduce to 3 digits
        '// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
I have managed to add some maths to get which i struggled with to get the terminal displayed voltage to match my power supply display which matches my Fluke 87 max so i am happy with that, maybe not much accuracy but displays the same.

Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)
        low LED '// Turn motor drive off
      
      
      
    high LED2 '// Turn fault light on
        do : loop while BTN = pressed '// Wait for switch to be released
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Tilt switch has now reset",13,10) 'was cr,lf
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
The gap above i tried putting "counter = counter + 1" i named my "symbol stalledfaultcount = W8"

Question is do i do my counting from the above position in Motorstalled: section or do i GOSUB to a new area then RETURN

Question can i use the "low LED" above as an action to control a counter?

I tried with SEXTD command to try and see my counter but couldn't work it out, is there a simple way to see the contents of W8?

Its all really confusing, if i knew what i was doing i bet the questions would seem stupid or maybe i am over thinking everything?
 

lbenson

Senior Member
I tried with SEXTD command to try and see my counter but couldn't work it out, is there a simple way to see the contents of W8?
SERTXD(#w8,cr,lf)

or better: SERTXD(#stalledfaultcount ,cr,lf)

"#" before a variable or symbol will display the value in human readable form. You might also want to add text to show what you're displaying: SERTXD(" stalled fault count: ",#stalledfaultcount ,cr,lf)
 

Jack Burns

New Member
Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)
        low LED '// Turn motor drive off
      
      
      
    high LED2 '// Turn fault light on
        do : loop while BTN = pressed '// Wait for switch to be released
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Tilt switch has now reset",13,10) 'was cr,lf
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return

The gap above i tried putting "counter = counter + 1" i named my "symbol stalledfaultcount = W8"

Assuming your just trying to keep a total of the number of times the motor has stalled, then all you need is:
Code:
stalledfaultcount = stalledfaultcount + 1
or you could use:
Code:
inc stalledfaultcount
and you dont need "counter = counter + 1".


The reason your having problems seeing the contents of W8 using SERTXD is because your using C.0 for SERTXD as well as driving the LED, so data is probably being corrupted. If you move the gap so it's before the "low LED" command, then it should work okay. If this causes you a problem and you would rather keep the gap where it is, then you could try adding a short pause (pause 10 for example) immediately after the "low LED" to see if that helps.

Then do what lbenson said:
SERTXD(#stalledfaultcount ,cr,lf)
You can add your new code in one of the gaps mentioned above, however if you plan on adding lots of code then using a gosub should help to keep the code more readable.

If you can accurately measure the value of your 2 resistors (R1 22K)(R2 10K) with your meter, and also the 5v rail at the PICAXE, then we could possibly simplify the extra calibration steps that you put in the MeasureBatteryVoltage routine.
 

Rampz

Well-known member
Thank you Ibenson and Jack Burns this part makes much more sense now and works, i will measure the 2 resistors and the supply rail it would be good to find a way to make the maths easyier it was a struggle and will be each time i build this, resistors being different etc

Now with the program i found it easy to kind of work out where to count "stalls" but with battery low i can't see any trigger or "low LED" that i can use to advance the counter for "LVDfaultcount" its on W9

Below is code as it stands at the moment

Code:
#picaxe 08m2
SetFreq M16

' Code snippets from Rampz, Goeytex & Jack Burns

'.----------------------------.
#REM

REQUIREMENTS
============
1.     If the button is pressed for say 20ms then I want the output to
        stay on for 400ms.
        (DONE)

2.    If the button is pressed and held on, then I want the output to
        stay on till button released plus 400ms.
        (DONE)

3a.    If the output is switched on continuously for more than say
        30 seconds,    then treat it as a stalled motor, so stop the output
        to protect the motor until the microswitch resets and re-triggers.
        (DONE)

3b.    Also flash C0 a couple of times and write 1 to memory for
        later recall.
    (NOT IMPLEMENTED)
       
4a    Disable C4 if voltage is seen to be below 10.4v for a set time
        of (say) 10secs to protect motor and battery.
        (DONE)
               
5.  When voltage returns to a higher level say 11.5v wait 1 hour
        for battery to charge enough to power the motor again.
        (DONE)

6.  Each time C4 is disabled due to low voltage write 1 to memory
        for later recall.
        (NOT IMPLEMENTED)
       
#ENDREM


#no_data
#terminal 19200

'.----------------------------.
'| Constants                  |
''----------------------------'
symbol BTN = PinC.3  '// Tilt Switch
Symbol LED = C.4  ' mosfet output
Symbol LED2 = C.1 ' Originally used C.0 but changed to C.1 as SERTXD messages are now used
symbol released = 0 'added
Symbol Pressed = 1
Symbol LowBattLevel = 104 ' Low voltage threshold x 10 (104 = 10.4v)
Symbol AvgCount = 10 ' Number of ADC readings to be averaged when calculating battery voltage
Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
Symbol MinRunTime = 501 '// 501 = 400 ms approx.  Adjust this value to change delay time after button released
Symbol LowBattDuration = 10 'set at 10 seconds
Symbol ChargeReadInterval = 4000 ' 4000 = 1 sec @ 16Mhz Take a reading every second
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600
Symbol ChargeReadCount = 20 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 115 'battery on again voltage 115 = 11.5v

'.----------------------------.
'| Variables Used             |
''----------------------------'
symbol ReserveB1 = b1 ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB2 = b2 ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB3 = b3 ' Used in "MeasureBatteryVoltage" routine
symbol Counter = W2 ' Used in several places
symbol ADCvalue = W3 ' Used in "MeasureBatteryVoltage" routine
symbol ADCavg = W4 ' Used in "MeasureBatteryVoltage" routine
symbol Volts = W5 ' Used in several places
symbol VmonCount = W6 ' Used in battery monitoring loop
symbol LowBattCount = W7 ' Used for testing batt low for 10 seconds
symbol stallfaultcount = W8 ' counter for how many times stalled
symbol LVDfaultcount = W9 ' counter for how many times low voltage disconnect happened

sertxd("coding by Rampz, Goeytex and Jack Burns",13,10)

MAIN:
  IF BTN = Pressed then
        High LED
      StartCounter:
      Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
        '// If here then switch released
      '//  Time Out after 400 ms (however, no delay if motor was previously stalled)
      '// If another Press detected then reset timer
      Do While Counter > 1   
          Counter = Counter - 1
          If BTN = Pressed then 'start over
            Goto StartCounter
          END IF
      Loop
      LOW LED
  END IF     
    ' Now measure battery voltage approx once a second
    inc VmonCount
    if VmonCount>1000 then ' 1000 = approx 1 sec.  Measure battery voltage approx once a second
            VmonCount = 0
            gosub MeasureBatteryVoltage
            sertxd("Main Loop - Battery level: ")
            gosub ShowVoltage
            sertxd("   (LowBattCount: ",#LowBattCount,")",13,10) 'was cf,lf
            if Volts <= LowBattLevel then ' Set at 10.4 Volts in "Constants" section
                inc LowBattCount
                if LowBattCount > LowBattDuration then ' approx 10 seconds
                        gosub LowBatteryVoltage
                end if       
            else
                LowBattCount = 0 ' reset count if battery doesn't stay low for specified duration
            end if
    end if
GOTO MAIN:

MotorStalled:
    sertxd("Motor Stalled",13,10)
    stallfaultcount = stallfaultcount + 1 ' added
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
        low LED '// Turn motor drive off 
    high LED2 '// Turn fault light on
        do : loop while BTN = pressed '// Wait for switch to be released
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Microswitch has now reset",13,10) 'was cr,lf
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
    
MeasureBatteryVoltage:
        '// Measure average voltage over 10 readings.
        ADCavg = 0 'Initialise to 0
        for b1 = 1 to AvgCount 'adjust above for readings to average
            ReadADC10 C.2,ADCvalue
        ADCavg = ADCavg + ADCvalue
        next b1
        ADCavg = ADCavg / AvgCount
        ' Convert ADC Value to Voltage
        Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
      volts = volts *65    ' correction needed to make 102
      volts = volts /64    ' read 104
        Volts = Volts *16      ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
        Volts = Volts /100 ' Reduce to 3 digits
        '// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
        return
   
    ShowVoltage:
        BinTOASCII Volts, b3,b2,b1 : IF  b3 = "0" THEN : b3 = " " : ENDIF' leading zero blanking
        Sertxd (b3,b2,".",b1," Volts")  ' 0.1 resolution
        return

LowBatteryVoltage:
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (")
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 11.5V",13,10) 'was cf,ld
            pause 4000 ' wait 1 second between readings
        loop until Volts >= highbattvolt 'see symbols above was (115)
        '// Battery voltage has now reached upper level
        sertxd("Battery has reached 11.5v ")
        gosub ShowVoltage
        sertxd(" - Now charging for 1 hour",13,10) 'was cr.lf
        '// Now wait an hour while battery continues to charge
        '// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
        Counter = ChargeReadCount
        do
            gosub MeasureBatteryVoltage
            sertxd("Battery level: ")
            gosub ShowVoltage
            sertxd(" - Charge time remaing: ",#Counter," Seconds",13,10) 'was cr,lf
            pause ChargeReadInterval ' Time between voltage readings while charging
            dec Counter
        loop while Counter > 0
        LowBattCount = 0 ' Reset time count for low battery voltage
        return
     

     
'info
     
'Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
     
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600 (currently 20 seconds)
'Symbol ChargeReadCount = 20 ' Normally 3600 readings while battery charges
At the moment i had left "LED2 on C4"
 

Rampz

Well-known member
Next fun i thought to try and flash C0 the amount of times that "stallfaultcount" total in W8

I found some simple code that flashed a led 15 times as below

Code:
main:
      if pin3=1 then
      gosub Blink5
      end if
    
goto main

Blink5:
for b3 =1 to 15 step 1
      high 4
      pause 150
      low 4
      pause 150
next b3
return
i modified it, and added the few lines below to above all my existing code, that seemed fine

Code:
if btn1= pressed then
gosub memoryrecall
end if
I modified the second half to C0 and to use W8, hoping it would flash the amount of times stored in W8, it seems to flash at the right speed but never never stops till i send the program again from laptop, stallfaultcount = W8, W8 increments ok in the terminal as i stall the system

Code:
Memoryrecall:
for stallfaultcount =1 to stallfaultcount step 1
high 0
pause 5000
low 0
pause 5000
next stallfaultcount
return
I think i have the issue at

Code:
for stallfaultcount =1 to stallfaultcount step 1
The original code i copied seemed to simulate ok when flashing a set number etc
 

Jack Burns

New Member
Now with the program i found it easy to kind of work out where to count "stalls" but with battery low i can't see any trigger or "low LED" that i can use to advance the counter for "LVDfaultcount" its on W9

Just advance LVDfaultcount at the beginning of the “LowBatteryVoltage” subroutine as this subroutine is only called once whenever the battery discharges to the specified minimum level (LowBattLevel).

Code:
LowBatteryVoltage:

LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
sertxd(“LVDfaultcount: “,#LVDfaultcount,13,10) ‘ <<< Add this line


        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (")
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 11.5V",13,10) 'was cf,ld
            pause 4000 ' wait 1 second between readings
        loop until Volts >= highbattvolt 'see symbols above was (115)
        '// Battery voltage has now reached upper level
        sertxd("Battery has reached 11.5v ")
        gosub ShowVoltage
        sertxd(" - Now charging for 1 hour",13,10) 'was cr.lf
        '// Now wait an hour while battery continues to charge
        '// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
        Counter = ChargeReadCount
        do
            gosub MeasureBatteryVoltage
            sertxd("Battery level: ")
            gosub ShowVoltage
            sertxd(" - Charge time remaing: ",#Counter," Seconds",13,10) 'was cr,lf
            pause ChargeReadInterval ' Time between voltage readings while charging
            dec Counter
        loop while Counter > 0
        LowBattCount = 0 ' Reset time count for low battery voltage
        return
 

Jack Burns

New Member
I modified the second half to C0 and to use W8, hoping it would flash the amount of times stored in W8, it seems to flash at the right speed but never never stops till i send the program again from laptop

There is a problem in the following line as you can’t use stallfaultcount in both places:
Code:
for stallfaultcount =1 to stallfaultcount step 1
The name after the “for” needs to be different as it clashes with the name between “to” and “step”. Also you don’t need to include “step 1” as a for/next loop will always count up in units of 1. Just use step if you need bigger increments.

To fix the code try something like this:
Code:
for W9 = 1 to stallfaultcount
I used W9 as an example, but you may need to change that to a variable of your choice.
 

Rampz

Well-known member
Code:
Memoryrecall:
for W9 =1 to stallfaultcount
high 0
pause 5000
low 0
pause 5000
next W9
pause 10000
for W11 =1 to LVDfaultcount
high 0
pause 5000
low 0
pause 5000
next W11
stallfaultcount = 0
LVDfaultcount = 0
return
Ok i have managed with much help to get both counters to count faults correctly, that works ok in the terminal.

Read back when BTN 1 is pressed kind of works as long as the number in the counter is greater than 1, if i have 4 of each fault it reads back correctly, but if i have zero faults i get 1 for each, i tried setting the counters to zero before they started, that didn't work as expected, i guess because that part works anyway.

I just tried

Code:
for W9 =1 to stallfaultcount
to
Code:
for W9 =0 to stallfaultcount
It altered things slightly in as i get 1 flash for each as before but if i have given a fault count on stallfaultcount i then get 2 flashes for that and one for the other, making it worse, previously no errors gave 1 flash for each and if i gave an error to stallcountfault then i got still 1 flash for each, so the change seems to have added an extra flash, really strange

Just tring to get when no errors in the counter that they playback is no flashes

I added a couple of line at the end of this routine to clear both counters back to zero, thats seems to work fine which is great.

Between us all i'm getting there

The last issue will be to write both error counts to eeprom to store them through complete power failure, i guess at each counter i need to add a line to write to memory and for recall i need to read from memory in each case, well thats my logic
 

inglewoodpete

Senior Member
The 'For' will always execute at least once.

If you want to want to avoid entering a loop when a value is zero, try something like like this:
Code:
b12 = 0     'Initialise loop counter
Do Until b12 = 0
   High B.0
   Pause 100
   Low B.0
   Pause 100
   Dec b12
Loop
 

Jack Burns

New Member
Based on inglewoodpete's code, the following should work for you:
Code:
symbol FlashCount = w10 ' Put this line at start of main code.  Change w10 if you're using a different variable

FlashCount = stallfaultcount     'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
   High B.0
   Pause 100
   Low B.0
   Pause 100
   Dec FlashCount
Loop
Edit: Forgot to say you can use the same variable "FlashCount" in both of your loops (stallfaultcount & LVDfaultcount).
 

Rampz

Well-known member
Edit: Forgot to say you can use the same variable "FlashCount" in both of your loops (stallfaultcount & LVDfaultcount).
Thank you Jack Burns yep i tried your edit and the general set up and ammeded code for both counters and yes awesome it works

How do i go about saving the counter increments following faults to eeprom rather than just local, then playing back from eeprom followed by deleting eeprom memory?

Edit:

Busy reading the picaxe manuals, i see i need "READ" and "WRITE" with "EEPROM" used for writing during download from what i can make out, can i just re-label my current word locations with prefix WRITE or do i need to select new locations? I understood that existing locations can be local stored or could eeprom stored, meaning both share the same locations? my first counter uses word location W8 made up of b16, b17

Adding the last line in the code below and the second line down in bottom code, it kind of works, counter increments in terminal ok, remove power and reconnect, read back flashes the correct amount, eeprom doesn't seem to reset at all, but local ram does and increments correctly on terminal, do i need to clear local ram and eeprom? after a new download it clears the eeprom but on memory recall i am back to a single flash when there are no faults, really strange, partly working

Just downloaded twice and after that the eeprom still holds the previous count although both counters on the terminal are incrementing correctly

Earlier when a download did manage to clear the eeprom and i then tried the memory recal knowing both counters were at zero, i got a strange array of flashes that could only be stopped by downloading again



Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)

    stallfaultcount = stallfaultcount + 1 ' added
    write 16, word w8

Code:
Memoryrecall:
read 16,word w8
FlashCount = stallfaultcount     'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
pause 10000
[\code]

Edit 2

Further playing and removed #nodata and it clears eeprom on download, so thats a bit better, just can't seem to clear eeprom memory after finishing the recall routine

Offending code

Code:
Memoryrecall:
read 16,word w8 ' added for eprom storage
FlashCount = stallfaultcount     'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
pause 10000
read 20,word w10 ' added for eeprom storage
flashcount =  LVDfaultcount
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
stallfaultcount = 0 'clears counters in ram but not eeprom
LVDfaultcount = 0 'clears counters in ram but not eeprom
return
Ok having ammended the last few lines to "write" 0 to 2 locations it appears to work correctly

Code:
stallfaultcount = 0 'clears counters in ram but not eeprom
 write 16, 0
LVDfaultcount = 0 'clears counters in ram but not eeprom
 write 20, 0
return
 
Last edited:

Rampz

Well-known member
If you can accurately measure the value of your 2 resistors (R1 22K)(R2 10K) with your meter, and also the 5v rail at the PICAXE, then we could possibly simplify the extra calibration steps that you put in the MeasureBatteryVoltage routine.
R1 actual value is 10.00k
R2 actual value is 21.99K

i did go and select resistors as close as possible to required, it would be great to be able to enter resistor values and Vdd and have a routine that ammends the displayed voltage, i guess its just ratios, but just where to begin, what i have works but needs altering every time and is fairly close

Supply voltage going to 08m2 is 5.064v
 

Jack Burns

New Member
Busy reading the picaxe manuals, i see i need "READ" and "WRITE" with "EEPROM" used for writing during download from what i can make out, can i just re-label my current word locations with prefix WRITE or do i need to select new locations? I understood that existing locations can be local stored or could eeprom stored, meaning both share the same locations? my first counter uses word location W8 made up of b16, b17, i have tried playing with this and don't get past syntax errors
The EEPROM command is only used during code downloads, it is a method of pre-loading data into non-volatile memory (EEPROM). You would then use some code to retrieve that data. As an example a light chaser could be built using a light pattern stored in EEPROM.

For your project you need to use the "WRITE" and "READ" commands. In addition you also need to use the "WORD" keyword because you will be storing word variables (W0, W1, W2 etc).

I assume you want to store the variables "stallfaultcount" & "LVDfaultcount", so I suggest you do the storage immediately after the variable has incremented. Looking at old snippets of code (shown below), I have made some suggested changes (further down).

Existing code snippets:
Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)
    stallfaultcount = stallfaultcount + 1 ' added
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
Code:
LowBatteryVoltage:
LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
sertxd(“LVDfaultcount: “,#LVDfaultcount,13,10) ‘ <<< Add this line

Proposed changes:
Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)
    stallfaultcount = stallfaultcount + 1 ' added
    write 0,WORD stallfaultcount ' <<<<<<<<<<<<<<< This stores the "stallfaultcount" in EEPROM location 0
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
Code:
LowBatteryVoltage:
LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
write 2,WORD LVDfaultcount ' <<<<<<<<<<<<<<< This stores the "LVDfaultcount" in EEPROM location 2
sertxd(“LVDfaultcount: “,#LVDfaultcount,13,10) ‘ <<< Add this line

Then to read the values back, just use
Code:
read 0,WORD stallfaultcount
read 2,WORD LVDfaultcount
However, it might be better to use different variable names just to prove the data really has been stored.

In addition, it might be an idea to place the same lines (not changing variable names) before the label "MAIN:" as this would recall the current fault counts during power-up, otherwise switching the PICAXE power off during code testing would result in "stallfaultcount" & "LVDfaultcount" initialising back to 0, which would then get written back to the EEPROM (if the values incremented) thus causing the original counts to be lost.

It might be an idea to post your complete code before asking further questions.
 

Rampz

Well-known member
It might be an idea to post your complete code before asking further questions.

Code as it currently stands, one way or another completly works, maybe needs tidying around the voltage offset area, and a general tidy.
I just tried making a few faults on each counter then powered down for 5 mins, powered back up waited few second and did Recall and led flashed as it should and reset just fine, its great to have been able to sort out a section of code to suit a requirment by myself, hopefully the first of many, so as not to clogg the forum up.

Code:
#picaxe 08m2
SetFreq M16

' Code snippets from Rampz, Goeytex & Jack Burns

'.----------------------------.
#REM

REQUIREMENTS
============
1.     If the button is pressed for say 20ms then I want the output to
        stay on for 400ms.
        (DONE)

2.    If the button is pressed and held on, then I want the output to
        stay on till button released plus 400ms.
        (DONE)

3a.    If the output is switched on continuously for more than say
        30 seconds,    then treat it as a stalled motor, so stop the output
        to protect the motor until the microswitch resets and re-triggers.
        (DONE)

3b.    Also flash C0 a couple of times and write 1 to memory for
        later recall.
    (NOT IMPLEMENTED)
       
4a    Disable C4 if voltage is seen to be below 10.4v for a set time
        of (say) 10secs to protect motor and battery.
        (DONE)
               
5.  When voltage returns to a higher level say 11.5v wait 1 hour
        for battery to charge enough to power the motor again.
        (DONE)

6.  Each time C4 is disabled due to low voltage write 1 to memory
        for later recall.
        (NOT IMPLEMENTED)
       
#ENDREM


'#no_data
#terminal 19200

'.----------------------------.
'| Constants                  |
''----------------------------'
symbol BTN = PinC.3  '// Tilt Switch
symbol btn1 = PinC.1 ' memory recall button
Symbol LED = C.4  ' mosfet output
Symbol LED2 = C.0 ' Originally used C.0 but changed to C.1 as SERTXD messages are now used
symbol released = 0 'added
Symbol Pressed = 1
Symbol LowBattLevel = 104 ' Low voltage threshold x 10 (104 = 10.4v)
Symbol AvgCount = 10 ' Number of ADC readings to be averaged when calculating battery voltage
Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
Symbol MinRunTime = 501 '// 501 = 400 ms approx.  Adjust this value to change delay time after button released
Symbol LowBattDuration = 10 'set at 10 seconds
Symbol ChargeReadInterval = 4000 ' 4000 = 1 sec @ 16Mhz Take a reading every second
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600
Symbol ChargeReadCount = 20 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 115 'battery on again voltage 115 = 11.5v

'.----------------------------.
'| Variables Used             |
''----------------------------'
symbol ReserveB1 = b1       ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB2 = b2       ' Used in "MeasureBatteryVoltage" routine
symbol ReserveB3 = b3       ' Used in "MeasureBatteryVoltage" routine
symbol Counter = W2         ' Used in several places
symbol ADCvalue = W3        ' Used in "MeasureBatteryVoltage" routine
symbol ADCavg = W4          ' Used in "MeasureBatteryVoltage" routine
symbol Volts = W5           ' Used in several places
symbol VmonCount = W6       ' Used in battery monitoring loop
symbol LowBattCount = W7    ' Used for testing batt low for 10 seconds
symbol stallfaultcount = W8 ' counter for how many times stalled
symbol FlashCount = W9      ' Put this line at start of main code.
symbol LVDfaultcount = W10  ' counter for how many times low voltage disconnect happened


sertxd("coding by Rampz, Goeytex and Jack Burns",13,10)



MAIN:
if btn1= pressed then 'new mine
gosub memoryrecall 'new mine
end if 'new mine

  IF BTN = Pressed then
        High LED
      StartCounter:
      Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
        '// If here then switch released
      '//  Time Out after 400 ms (however, no delay if motor was previously stalled)
      '// If another Press detected then reset timer
      Do While Counter > 1   
          Counter = Counter - 1
          If BTN = Pressed then 'start over
            Goto StartCounter
          END IF
      Loop
      LOW LED
      END IF     
    ' Now measure battery voltage approx once a second
    inc VmonCount
    if VmonCount>1000 then ' 1000 = approx 1 sec.  Measure battery voltage approx once a second
            VmonCount = 0
            gosub MeasureBatteryVoltage
            sertxd("Main Loop - Battery level: ")
            gosub ShowVoltage
            sertxd("   (LowBattCount: ",#LowBattCount,")",13,10) 'was cf,lf
            if Volts <= LowBattLevel then ' Set at 10.4 Volts in "Constants" section
                inc LowBattCount
                if LowBattCount > LowBattDuration then ' approx 10 seconds
                        gosub LowBatteryVoltage
                end if       
            else
                LowBattCount = 0 ' reset count if battery doesn't stay low for specified duration
            end if
    end if
GOTO MAIN:

MotorStalled:
    sertxd("Motor Stalled",13,10)
  
    stallfaultcount = stallfaultcount + 1 ' added
    write 16, word w8
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
        low LED '// Turn motor drive off 
    high LED2 '// Turn fault light on
        do : loop while BTN = pressed '// Wait for switch to be released
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Microswitch has now reset",13,10) 'was cr,lf
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
    
MeasureBatteryVoltage:
        '// Measure average voltage over 10 readings.
        ADCavg = 0 'Initialise to 0
        for b1 = 1 to AvgCount 'adjust above for readings to average
            ReadADC10 C.2,ADCvalue
        ADCavg = ADCavg + ADCvalue
        next b1
        ADCavg = ADCavg / AvgCount
        ' Convert ADC Value to Voltage
        Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
      volts = volts *65    ' correction needed to make 102
      volts = volts /64    ' read 104
        Volts = Volts *16      ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
        Volts = Volts /100 ' Reduce to 3 digits
        '// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
        return
   
    ShowVoltage:
        BinTOASCII Volts, b3,b2,b1 : IF  b3 = "0" THEN : b3 = " " : ENDIF' leading zero blanking
        Sertxd (b3,b2,".",b1," Volts")  ' 0.1 resolution
        return

LowBatteryVoltage:

LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
write 20,word w10
sertxd("LVDfaultcount: ",#LVDfaultcount,13,10) ‘ <<< Add this line
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (")
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 11.5V",13,10) 'was cf,ld
            pause 4000 ' wait 1 second between readings
        loop until Volts >= highbattvolt 'see symbols above was (115)
        '// Battery voltage has now reached upper level
        sertxd("Battery has reached 11.5v ")
        gosub ShowVoltage
        sertxd(" - Now charging for 1 hour",13,10) 'was cr.lf
        '// Now wait an hour while battery continues to charge
        '// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
        Counter = ChargeReadCount
        do
            gosub MeasureBatteryVoltage
            sertxd("Battery level: ")
            gosub ShowVoltage
            sertxd(" - Charge time remaing: ",#Counter," Seconds",13,10) 'was cr,lf
            pause ChargeReadInterval ' Time between voltage readings while charging
            dec Counter
        loop while Counter > 0
        LowBattCount = 0 ' Reset time count for low battery voltage
        return
     
Memoryrecall:
read 16,word w8 ' added for eprom storage
FlashCount = stallfaultcount     'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
pause 10000
read 20,word w10 ' added for eeprom storage
flashcount =  LVDfaultcount
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
loop
stallfaultcount = 0 'clears counters in ram but not eeprom
write 16, 0
LVDfaultcount = 0 'clears counters in ram but not eeprom
write 20, 0
return

     
'info
     
'Symbol MaxRunTime = 6 ' Time in seconds. (Set low for testing, 30 required)
     
'// TEMPORARILY SET ChargeReadCount TO 20 WHILE BENCH TESTING (This will make testing quicker).
'// ChargeReadCount NEEDS TO BE 3600 (currently 20 seconds)
'Symbol ChargeReadCount = 20 ' Normally 3600 readings while battery charges
 
Last edited:

Rampz

Well-known member
In addition, it might be an idea to place the same lines (not changing variable names) before the label "MAIN:" as this would recall the current fault counts during power-up, otherwise switching the PICAXE power off during code testing would result in "stallfaultcount" & "LVDfaultcount" initialising back to 0, which would then get written back to the EEPROM (if the values incremented) thus causing the original counts to be lost.
I will look into this I hadn't tried this scenario, Thank you Jack Burns
 

Jack Burns

New Member
I just tried making a few faults on each counter then powered down for 5 mins, powered back up waited few second and did Recall and led flashed as it should and reset just fine, its great to have been able to sort out a section of code to suit a requirment by myself
Well done with getting your code to work.


Further playing and removed #nodata and it clears eeprom on download, so thats a bit better, just can't seem to clear eeprom memory after finishing the recall routine
It may be beneficial to keep "#no_data" in place as downloads will be faster and you will be able to test new code without losing the counts already stored in EEPROM.

If you change this:
Code:
stallfaultcount = 0 'clears counters in ram but not eeprom
write 16, 0
LVDfaultcount = 0 'clears counters in ram but not eeprom
write 20, 0
to this:
Code:
stallfaultcount = 0 'clears counter in ram
write 16, stallfaultcount ' clear counter in eeprom
LVDfaultcount = 0 'clears counter in ram
write 20, LVDfaultcount ' clear counter in eeprom
then the stored counts in EEPROM will be set back to 0.

Out of interest, is there a particular reason why you chose addresses 16 & 20 in the EEPROM for storing your data?
 

Jack Burns

New Member
Looking at your code, it would be easier to follow if you used "stallfaultcount" in place of w8, and "LVDfaultcount" in place of w10, as I found it necessary to scroll up and down the code several times to check what w8 and w10 represented.

By changing these:
Code:
    stallfaultcount = stallfaultcount + 1 ' added
    write 16, word w8
Code:
LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
write 20,word w10

to this makes it obvious what is being stored:
Code:
    stallfaultcount = stallfaultcount + 1 ' added
    write 16, word stallfaultcount
Code:
LVDfaultcount = LVDfaultcount + 1 ‘ <<< Add this line
write 20,word LVDfaultcount
 

Rampz

Well-known member
Out of interest, is there a particular reason why you chose addresses 16 & 20 in the EEPROM for storing your data?
Since i was going trial and error i came to the conclusion that RAM and EEPROM shared the same memory numbers so where stallfaultcount is using Word 8 i used the numbers from its bytes b16 or b17

Only after viewing what you have done i have changed then to in this example 0 seems i was wrong as it turned out, like i say trial and error Lol

I have implemented all your changes so at least its more readable and prevents too much scrolling

I put the below before Main as you said so after power up the values would be put into the counters so additional counts would increment correctly following on from a previous count, i have tested and that works, otherwise it would have become a bug i would have noticed later on
Code:
read 0,WORD stallfaultcount
read 2,WORD LVDfaultcount
Thank you again to Jack Burns and everyone else that has commented on my project it has been quite a journey for me
 

Rampz

Well-known member
If you can accurately measure the value of your 2 resistors (R1 22K)(R2 10K) with your meter, and also the 5v rail at the PICAXE, then we could possibly simplify the extra calibration steps that you put in the MeasureBatteryVoltage routine.
Project is basically complete but have been thinking regards calibration of the voltage measurement, i would think if i can input R1 resistance in ohms as a number and do the same for R2 and the voltage to the 08m2 in Mv i should be able to write something wher i can enter these values and have the maths make the voltage read correctly, just can't get my head around any of it.
To be fair it does work currently but will need re-caculating each time i build the circuit

Battery measuring section

Code:
MeasureBatteryVoltage:
        '// Measure average voltage over 10 readings.
        ADCavg = 0 'Initialise to 0
        for b1 = 1 to AvgCount 'adjust above for readings to average
            ReadADC10 C.2,ADCvalue
        ADCavg = ADCavg + ADCvalue
        next b1
        ADCavg = ADCavg / AvgCount
        ' Convert ADC Value to Voltage
        Volts = ADCavg **64064 ' Convert 1023 to 1000 steps (**64064) for 5.00v reference
      volts = volts *65    ' correction needed to make 102
      volts = volts /64    ' read 104
        Volts = Volts *16      ' Multiply by Vin (Fullscale 16v)(R1 22K)(R2 10K)
        Volts = Volts /100 ' Reduce to 3 digits
        '// Volts here will be 10 times actual voltage, eg 104 = 10.4v , 115 = 11.5v
        return
 

lbenson

Senior Member
How many times do you anticipate writing to eeprom? If several times a day for years, no problem, but you can wear it out if you get stuck in a loop writing to it, say, every few seconds.

If it's guaranteed for around 100,000 writes, then if you wrote to the same location once a minute you might start getting erroneous read-backs after 8 months or so.

It may well not be a problem in your circumstances, but if you can conceive of a way it could happen, you might do well to assure that you don't write to the eeprom more than once every 10 minutes.
 

Rampz

Well-known member
How many times do you anticipate writing to eeprom? If several times a day for years, no problem, but you can wear it out if you get stuck in a loop writing to it, say, every few seconds.
Hello Ibenson

I had read about the limit, in my project it should only write to EEPROM when there is a stall situation which when the time is suitable adjusted may only happen a few times a year, the other situation that write to EEPROM is when there is a battery fail, which could happen when there is a mains power fail lasting longer than a week so this could be a few times a year.

I guess the other times that the EEPROM will be written to is after complete power fail eg when battery voltage during mains fail gets down to around 3v, battery being used is a 12v SLA 10ah so should last very well, so few times a year at worst, and after the recall button is pressed during a routine service of the system, the counters are cleared and 0 will be written to EEPROM

So all in all i guess the EEPROM will be written to 30-40 times a year at most

Rampz
 

Rampz

Well-known member
Hello again

Through testing the program in the real world i have come against a problem, firstly i need an extra input so want to try and use C.5, i can see i need to use the "reconnect" and "disconnect" commands, so my thought was to put this before MAIN in my program, as follows to allow me a window of 30 seconds following power up to do a download if required

Code:
symbol C5counter = W11      ' counter to make C5 an input after 30 seconds

reconnect
for c5counter = 1 to 120
    pause 2000
    next c5counter
disconnect
Is the best way to make a window of time during which i can use C.5 as a download pin after which i can use it as a input? Being written before MAIN at the start of my code it will get run only after a cycle of supply, and not get run loads of time during the main program

While the counter is running will i be able to do the download, i thought if i used a solid pause or time i might not be able to do a download?
 
Last edited:

oracacle

Senior Member
Its simpler than that, attach to your download lead, leave you circuit unpowered, hit download and then power it on.
Normally referred to here as a reset download.
 

Rampz

Well-known member
Its simpler than that, attach to your download lead, leave you circuit unpowered, hit download and then power it on.
Normally referred to here as a reset download.
Oracacle Yes i did read you can do a hard reset like that, in my situation of how the programming will be used it will prove difficult to make that happen, will what i proposed work do you think? I need to make it fool proof so to speak, if i have a download window following power up it would be easier.
 

oracacle

Senior Member
Providing it is the first thing to be executed yes, But you only need to the reconnect after a disconnect.
 

Rampz

Well-known member
Providing it is the first thing to be executed yes, But you only need to the reconnect after a disconnect.
My thinking is that I will be in a disconnect position after my code runs, will a cycle of power reset it?
 

oracacle

Senior Member
Yes.
The other way would be to make some sort of routine that is called with a specific input from the user.
There is an actual reset command that could be used to "soft reset" the programme. It should be the same as power cycling the controller, but again you would ahve to find a way of calling this command from a user input.
Your code from post 68 will work fine providing yuou can call it as a subroutine and start to programme in the designated period of time.
 

Rampz

Well-known member
Your code from post 68 will work fine providing yuou can call it as a subroutine and start to programme in the designated period of time.
Ok i hoped i could just put it before the "Main" code started such that it would do it right at the start after power up

I suppose the other route would be to put code in the "Motorstalled" gosub, that when i am in the motor stalled position it set C5 to disconnect to allow the input to be used to reset the counter below and when we get to the "Return" position to reconnect C5, then i can download at anytime apart from during motor stall, but need to work that bit out?

Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)
  
    stallfaultcount = stallfaultcount + 1 ' added
   write 0,WORD stallfaultcount ' <<<<<<<<<<<<<<< This stores the "stallfaultcount" in EEPROM location 0
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
        low LED '// Turn motor drive off 
    high LED2 '// Turn fault light on
        do : loop while BTN = pressed '// Wait for switch to be released
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Tilt switch has now reset",13,10) 'was cr,lf
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
 

oracacle

Senior Member
Ok i hoped i could just put it before the "Main" code started such that it would do it right at the start after power up
You can, like i said in post 71,
as a note just because you execute you main looping code in you "main" programme title, you can have thing before that, they dont even have to have a tittle to execute. However it good practice to to do so

Code:
init:
  'do you initialisation code here
  for c5counter = 1 to 120
      pause 2000
      next c5counter
  disconnect

main:
  'do you main code here

goto main
Hopefully that is a little clearer, I am often not good at explaining myself very well.
 

Rampz

Well-known member
Code:
MotorStalled:
    sertxd("Motor Stalled",13,10)
   
    stallfaultcount = stallfaultcount + 1 ' added
   write 0,WORD stallfaultcount ' <<<<<<<<<<<<<<< This stores the "stallfaultcount" in EEPROM location 0
    SERTXD("motor stalled count = ",#stallfaultcount ,cr,lf) 'added
        low LED '// Turn motor drive off 
    high LED2 '// Turn fault light on
    
     
        
    do : loop while BTN = pressed and btn2 = released '// Wait for switch to be released, btn2 = released resets motorstalled condition
      
    '// If here then switch has been released
    low LED2 '// Turn fault light off
        sertxd("Tilt switch has now reset",13,10) 'was cr,lf
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
    return
I just added in the line, do : loop while BTN = pressed
and added, and btn2 = released

And the "Motorstalled" condition is reset and it gives me a route to reset the stalled condition perfectly.

I thought i would say what i had done, since normally nothing works when i have tried something, it seems i am often over thinking the solution
 

Rampz

Well-known member
At the moment I am waiting for my PCB to be produced hopefully should get it in next few days, I have very little space the PCB is from memory about 16mm x 35mm which has forced me to go mainly surface mount which I could have done without.
For the voltage divider I have gone for 0.1% smd resistors 1/8 watt so hopefully not much correction needed along with a low drop out precision 5v regulator.
 

Rampz

Well-known member
Here is the prototype motor control picaxe PCB mounted on the motor connections PCB, next to the box is the previous 555 timer board, there are 10x smd resistors on the back of the picaxe board, don't enjoy soldering them.
On testing with the precision regulator I found I had to remove my 0.2v correction maths from the code and it just worked perfectly as Jack Burns wrote it.
The 2 smd switches on is the reset when recovering the motor from a stall and the other is the memory recall button and its associated led.

There are some mistakes, the capacitor on the picaxe board isn't in the best of places will sort when I order some more boards

Quick run down of the box,
Bottom left blue connector is tilt switch connections
Top left is 12v motor connections
3 pole connector is 12v power
Big switch at top of PCB allows the motor to run in either direction along with big led bottom right is blue in one direction and red in other direction.
Microswitch is a limit switch there is a plastic pole this is pushed through the box top to bottom and holds the microswitch in, if the motor drives too far this gets pulled out because it has a cord attached to it.

Hopefully you all understand what I've said.

Thank you again for everybodies support and code work as I worked though the ptoject
 

Attachments

Top