Switching issues

Jack Burns

New 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
Thanks for the photo, it’s good to see your project advancing.
Would you be able to post the latest code, as I would be interested to see how much it has changed since the project started.


Well-known member
Starting point

#picaxe 08m2
setfreq m8   ' i set to 8mhz to see if it would help
    symbol green = 4   'pin c4
    symbol light = 400  'wait 400ms
    symbol btn = pinc.3   'pin c3
    if btn = 1 then
    high green   ' turn on green led
    pause light   ' wait 400ms
    low green     ' turn green led off after
goto main

After much help from several people

#picaxe 08m2
SetFreq M16

' Code snippets from Rampz, Goeytex & Jack Burns

#terminal 19200

'| Constants                  |
symbol BTN = PinC.3  '// Tilt Switch
symbol btn1 = PinC.1 ' memory recall button
symbol BTN2 = PinC.5 ' tilt switch reset switch, new xxxx
Symbol LED = C.4  ' mosfet output
Symbol LED2 = C.0 'changed back, battery volt read message gives a heartbeat effect once a second very useful
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
symbol C5counter = W11      ' counter to make C5 an input after 30 seconds

init: ' initialisation code
  for c5counter = 1 to 120
      pause 1000
      next c5counter

sertxd("coding by Rampz, Goeytex and Jack Burns V3:04/12/21",13,10) 'heading main users involved in code
read 0,WORD stallfaultcount ' To fill counter with previous faults after power fail
read 2,WORD LVDfaultcount ' To fill counter with previous faults after power fail

if btn1= released then 'added to check btn1 during main program, altered to high going low
    sertxd("Memory Recall, LVD then Battery Fail",13,10) 'added to display on terminal
    sertxd("   (stallfaultcount: ",#stallfaultcount,")",13,10) 'as above
    sertxd("   (LVDfaultcount: ",#LVDfaultcount,")",13,10) 'as above
    gosub memoryrecall 'added to send to memory recall if btn1 pressed
end if 'added as required

  IF BTN = Pressed then
      sertxd("Tilt switch operated",13,10)
        High LED
      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
        sertxd("Timed out",13,10)
      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)
            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       
                LowBattCount = 0 ' reset count if battery doesn't stay low for specified duration
            end if
    end if

    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)
        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 or btn2 pressed
    low LED2 '// Turn fault light off
        sertxd("Tilt switch has now reset",13,10)
        Counter = 0 ' Set to zero so that it falls through 400 ms delay after return to main code
        '// 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
        BinTOASCII Volts, b3,b2,b1 : IF  b3 = "0" THEN : b3 = " " : ENDIF' leading zero blanking
        Sertxd (b3,b2,".",b1," Volts")  ' 0.1 resolution XXXremove in normal operationXXX

for b22 = 1 to 10 'flash C0 10 times when LVD fault detected
    high led2
    PAUSE 200
    low led2
    PAUSE 500
next b22   

LVDfaultcount = LVDfaultcount + 1
write 2,WORD LVDfaultcount ' This stores the "LVDfaultcount" in EEPROM location 2
sertxd("LVDfaultcount: ",#LVDfaultcount,13,10)
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (") ' XXXremove in normal operationXXX
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 11.5V",13,10) ' XXXremove in normal operationXXX
            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)
        '// Now wait an hour while battery continues to charge
        '// Total charge time = Combination of ChargeReadInterval & ChargeReadCount
        Counter = ChargeReadCount
            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
read 0,WORD stallfaultcount
FlashCount = stallfaultcount     'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
pause 10000
read 2,WORD LVDfaultcount
flashcount =  LVDfaultcount  'Initialise loop counter to number of required flashes
Do Until FlashCount = 0
high 0
pause 5000
low 0
pause 5000
Dec FlashCount
stallfaultcount = 0 'clears counters in ram but not eeprom
write 0, stallfaultcount ' clear counter in eeprom
LVDfaultcount = 0 'clears counters in ram but not eeprom
write 2, LVDfaultcount ' clear counter in eeprom

'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
So pcb made and tested in the way it will be used, most timers are still as test times, i still need to looking to recovery rates of the battery i am using to determine how long to wait when when voltage reaches 11.5v that there is enough charge to allow the motors to start working again, i also need to monitor battery voltage and determine the voltage at which the above should start counting

You will see i added a correction for read battery voltage because the read voltage was 0.2v from what it should be while using the AXE091 development board, when i used my own pcb with LDO 5v regulator and 0.1% smd resistors, i found i didn't need any correction.

So still loads of work to get it to where i want it.