Moving code from a 08m2 to a 20X2

Rampz

Well-known member
I expected there would be issues, reading through the manuals i can't yet see what they are, I have "TIME = 0" on the 08m2 that is fine but not liked when i do a check having changed the editor to 20X2, i bet there will be many more issues as i resolve each one, is there a guide somewhere to help the transition etc?

So it seems TIME is a m2 only command

The code i want to move over

Code:
#picaxe 08m2
SetFreq M16


' Code snippets from Rampz, Goeytex & Jack Burns

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




#no_data
#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 ' Originally used C.0 but changed to C.1 as SERTXD messages are now used
symbol released = 0
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 ' Normally 3600 readings while battery charges, 1800 30 mins
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 140 '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
  disconnect

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

MAIN:
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 = Released then
      sertxd("Tilt switch operated",13,10)
        High LED
      StartCounter:
      Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Released 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 = Released then 'start over
            Goto StartCounter
          END IF
    Loop
        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       
            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 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 = Released 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
    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 XXXremove in normal operationXXX
        return

LowBatteryVoltage:
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)
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (") ' XXXremove in normal operationXXX
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 14V",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 14v ")
        gosub ShowVoltage
        sertxd(" - Now charging for 30 mins",13,10)
        '// 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 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
loop
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
loop
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
return
#picaxe 08m2
SetFreq M16

i know the 08m2 needs changing to 20X2

I see the 20X2 runs at 64mhz so i guess i need to delete "SetFreq M16" and i assume it will throw all my time settings based on M16 also?
 
Last edited:

inglewoodpete

Senior Member
The 20X2 is a more sophisticated chip and has a superior implementation of the background timer. Of course, that makes its configuration a little more complicated!

Due to the X2's configurable timer and background serial data reception, I tend to use them (inconjunction with interrupts) for nearly all of my PICAXE projects.

Initially, you may not want to implement interrupts. The X2's timer can be configured without interrupts if required.

If using interrupts, you can base your code on the following snips. I have added a spreadsheet to assist with calculating SetTimer values (remove the .pdf extension from the file name before opening in Excel).
Rich (BB code):
'Variables
Symbol bEighthSecs   = b38    'w19  1/8 Seconds (125mS Tick)
Symbol bSeconds      = b39    'w19  Whole seconds
'Constants
Symbol False         = 0
Symbol True          = 1
'Interrupt masks
Symbol mskSerialOnly = %00100000
Symbol flgSerialOnly = %00100000
Symbol mskTmrAndSer  = %10100000
Symbol flgTmrAndSer  = %10100000
Symbol mskBGTimer    = %10000000 'For the background timer (only) interrupt
Symbol flgBGTimer    = %10000000 'For the background timer (only) interrupt
'Timer constants
Symbol tmrIntOn1stTick = 65535   'Interrupt to be caused by roll over on first major tick
Symbol t250mS_64     = 3036      'SetTimer value for 1/4 second ticks
Symbol t125mS_64     = 34286     'SetTimer value for 1/8 second ticks
Symbol t125mS_32     = 49911     'SetTimer value for 1/8 second ticks @ 32MHz
Rich (BB code):
'Background timer initialisation: perform once at startup, before main loop
      'Start the background timer (runs continuously), uses interrupts
      Timer = tmrIntOn1stTick    'Defines number of primary periods before an interrupt
      SetTimer t125mS_32         'Configure timer preload. Expires after 1/8 second @ 32 MHz
      '                           SetTimer command specifies smallest increment for used in code
      Flags = 0                  'Reset all flags
      'bSoundPtr = eNoSound      'Uses PWM and timer to control short beeps etc
      'bPWMPeriod = 0
      'SetIntFlags Or flgTmrAndSer, mskTmrAndSer 'Set timer 0 or hSerial to interrupt
      SetIntFlags flgBGTimer, mskBGTimer 'Set timer 0 to interrupt
Rich (BB code):
'
' ************************************************************
'  Interrupt handler
' ************************************************************
'  
Interrupt:If TOFlag = True then                       'All timer ticks
            Timer = tmrIntOn1stTick                   'Then reset the timer
            TOFlag = False                            'Reset (clear) the flag first
            Inc bEighthSecs
            If bEighthSecs > 7 Then                   'Every whole second
               Inc bSeconds
               bEighthSecs = 0                        'Reset
            End If
            '
            '(Insert any timer expiry related code here)
            '
          EndIf    'Timer has ticked
          SetIntFlags flgBGTimer, mskBGTimer   'Set timer 0 to interrupt
          Return
 

Attachments

Rampz

Well-known member
Due to the X2's configurable timer and background serial data reception, I tend to use them (inconjunction with interrupts) for nearly all of my PICAXE projects.
Thank you Inglewoodpete, can you see anything else in the code i posted that will cause an issue changing to X2 picaxe?

Most of the code was created with the help of forum members and although works nicely on the 08m2 i can see the X2 is a different beast

I can see the advantage of making use of background process like Interrupts, hserin and hserout, but not sure how i'm going to optimise the code to best effect, i will read through what you say and have a look
 

inglewoodpete

Senior Member
I tried a syntax check with your code (after changing the #picaxe directive to 20X2) and the only syntax errors were the three lines referring to "Time".

I have to admit that I haven't been following the saga of your project, so don't know much about its intricacies. The only things that I can see that might affect the programme are the Pauses (and any timeout periods, if you have them). The 20X2's defaut speed is 8MHz, as opposed to the 08M2's 4MHz. This could affect pauses if you run the chip at a different speed. You have configured your 08M2 to run at 4 times its native speed (SetFreq = M16). The pauses should be equivalent if you run the 20X2 at 32Mhz.

If there are any time-critical pieces of code, you may need to adjust them during testing. While the two chips are largely code-comparible, they use different silicon (PIC12F vs PIC18F) so the 20X2 may be a little more efficient but this could be offset with the larger program 'tokens' that the 20X2 uses.
 

hippy

Technical Support
Staff member
The time issue should be fairly easy to resolve. How it currently is -
Code:
      StartCounter:
      Time = 0
      Do : Loop while BTN = Released and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
With the MaxRunTime being 30 seconds, one can use a counter to count 30 seconds or, better still, 30,000 milliseconds -
Code:
      StartCounter:
      counter = 0
      Do
         Pause 10
         counter = counter + 10
      Loop while BTN = Released and counter < 30000
      if counter >= 30000 then gosub MotorStalled
You can keep 'MaxRunTime' in that code, just need to make it milliseconds based rather than seconds based -
Code:
Symbol MaxRunTime = 6 * 1000 ; 30 seconds (30,000ms) - 6 seconds (6,000 ms) while debugging
I would recommend running the 20X2 at its default speed, no SETFREQ, until you have it working, then add the SETFREQ and adjust the PAUSE times as appropriate.
 

Rampz

Well-known member
StartCounter:
Time = 0
Do : Loop while BTN = Released and Time < MaxRunTime
if Time >= MaxRunTime then gosub MotorStalled
I am a little confused, there is a line missing from above, it should be:
Code:
Startcounter = 0
Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Released and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
the counter = MinRunTime ' approx 400 ms

So your alteration although it gets past syntax check,

The idea was that any amount of quick presses less than 400ms allowed the output to stay on and when the button was finally released then 400ms was added to the time, so last activation + 400ms, but if the button was held down for longer than 6 seconds (during testing) then it would go to motorstalled

Seems when the button is pressed the ouput stay on for several mins

Not sure whats going wrong i did try putting the missing line back in but it didn't help any
 

Rampz

Well-known member
This was the original code requirements, i didn't include it since i was over the 10,000 maximum for a post

Code:
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
        6 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 light C0 and write 1 to memory for
        later recall.
        (DONE)
       
4a     Disable C4 if voltage is seen to be below 10.4v for a set time
        of (say) 10secs to protect motor and battery. C0 is flashed 15 times
        (DONE)
               
4b.    When voltage returns to a higher level say 11.5v wait 1 hour
        for battery to charge enough to power the motor again.
        (DONE)

4c.    Each time C4 is disabled due to low voltage write 1 to memory
        for later recall,Flash C0 10 times
        (DONE)
     
5.     At power up a 30 second window is allowed during which programming can take place
      after which programming is dis allowed and C5 becomes a means to reset the
      "Motorstalled" condition only during a stall condition
       (DONE)
      
6.     A button on C1 allows memory recall first of stalls then after a delay low
      voltage disconnects, then resets the counters, counters are stored in EEPROM
      and written back to RAM at any power up
       (DONE)
       
#ENDREM
 

Rampz

Well-known member
This is below the most up to date 08m2 code that works, the code posted at the start had been inverted and not tested, so i think its best to go back to the previous working code

Code:
#picaxe 08m2
SetFreq M16


' Code snippets from Rampz, Goeytex & Jack Burns




#no_data
#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 ' 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 = 30 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 140 '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
  disconnect

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

    sertxd("   (stallfaultcount: ",#stallfaultcount,")",13,10) 'added to display fault counter at power up
    sertxd("   (LVDfaultcount: ",#LVDfaultcount,")",13,10) 'added to display fault counter at power up

MAIN:
if btn1= pressed 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
      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
        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        
            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 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
    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 remove
      volts = volts /64    ' read 104 remove
        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 XXXremove in normal operationXXX
        return

LowBatteryVoltage:
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) 
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (") ' XXXremove in normal operationXXX
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 14.0V",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 14.0v ") 
        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
        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 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
loop
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
loop
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
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
 

Rampz

Well-known member
Additional info from the top of the code that wouldn't fit in the 10,000 limit

Code:
'.----------------------------.
#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 light C0 and write 1 to memory for
        later recall.
        (DONE)
        
4a     Disable C4 if voltage is seen to be below 10.4v for a set time
        of (say) 10secs to protect motor and battery. C0 is flashed 15 times
        (DONE)
                
4b.    When voltage returns to a higher level say 11.5v wait 1 hour
        for battery to charge enough to power the motor again.
        (DONE)

4c.    Each time C4 is disabled due to low voltage write 1 to memory
        for later recall,Flash C0 10 times
        (DONE)
      
5.     At power up a 30 second window is allowed during which programming can take place
      after which programming is dis allowed and C5 becomes a means to reset the
      "Motorstalled" condition only during a stall condition
       (DONE)
       
6.     A button on C1 allows memory recall first of stalls then after a delay low 
      voltage disconnects, then resets the counters, counters are stored in EEPROM
      and written back to RAM at any power up
       (DONE)
        
#ENDREM
Sorry for the confusion, the above works fine on the 08m2 and i have 2x AXE091 set up with 08m2 in one and the 20X2 in the other
 

hippy

Technical Support
Staff member
Code:
StartCounter: 
Time = 0 
     Do : Loop while BTN = Released and Time < MaxRunTime 
     if Time >= MaxRunTime then gosub MotorStalled
I am a little confused, there is a line missing from above, it should be:
Code:
Startcounter = 0
Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Released and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
the counter = MinRunTime ' approx 400 ms
Sorry about that. The 'counter' isn't used in that code's loop and test so I reused 'counter' for the timer fix, moving the ''Counter = MinRunTime" to after that fix, but then forgot to include that in my copy and paste. The full version of the replacement code should have been -
Code:
      StartCounter:
      counter = 0
      Do
         Pause 10
         counter = counter + 10
      Loop while BTN = Released and counter < 30000
      if counter >= 30000 then gosub MotorStalled
      Counter = MinRunTime ' approx 400 ms
 

Jack Burns

New Member
Rampz,
The idea was that any amount of quick presses less than 400ms allowed the output to stay on and when the button was finally released then 400ms was added to the time, so last activation + 400ms, but if the button was held down for longer than 6 seconds (during testing) then it would go to motorstalled

Seems when the button is pressed the ouput stay on for several mins

Not sure whats going wrong i did try putting the missing line back in but it didn't help any

The problem seems to be a conflict in the Counter variable as you're running 2 timers, one for the 400mS pulse extension and the other for the timeout if the motor stalls.

Changing this
Code:
Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled

to the following seems to work on a 08M2 and passes syntax check for a 20X2.
Code:
            '// START OF NEW CODE
            RunTime = 0
            Counter = MinRunTime ' approx 400 ms
            Do
                pause 20 ' 5 mS @ 16MHz
                RunTime = RunTime + 5
            Loop while BTN = Pressed and RunTime < MaxRunTime ' NOTE: Value of MaxRunTime now in ms, so 6000 for testing
            if RunTime >= MaxRunTime then gosub MotorStalled
            '// END OF NEW CODE
NOTE:
The value of MaxRunTime was changed in the Constants section, as this now works in milliseconds.
Code:
Symbol MaxRunTime = 6000 ' Time in mS. (Set low for testing, 30000 required)
and a new variable was also defined.
Code:
symbol RunTime = W12        ' Used to replace TIME variable so code will work on a X2

I will post the complete code in the following post.
 

Jack Burns

New Member
REQUIREMENTS section removed from beginning of code due to 10,000 character limit.
Code:
#picaxe 08m2
SetFreq M16


' Code snippets from Rampz, Goeytex & Jack Burns




#no_data
#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 ' 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 MaxRunTime = 6000 ' Time in mS. (Set low for testing, 30000 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 = 30 ' 3600 ' Normally 3600 readings while battery charges
'// 3600 Readings at 1 sec = 1 hour (Combination of ChargeReadInterval & ChargeReadCount)
symbol highbattvolt = 140 '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
symbol RunTime = W12        ' Used to replace TIME variable so code will work on a X2
 
init: ' initialisation code
  
  for c5counter = 1 to 120
      pause 1000
      next c5counter
  disconnect

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

    sertxd("   (stallfaultcount: ",#stallfaultcount,")",13,10) 'added to display fault counter at power up
    sertxd("   (LVDfaultcount: ",#LVDfaultcount,")",13,10) 'added to display fault counter at power up

MAIN:
if btn1= pressed 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
      StartCounter:
      
            
            
            
            #REM
            Time = 0
      Counter = MinRunTime ' approx 400 ms
      Do : Loop while BTN = Pressed and Time < MaxRunTime
      if Time >= MaxRunTime then gosub MotorStalled
            #ENDREM
            
            '// START OF NEW CODE
            RunTime = 0
            Counter = MinRunTime ' approx 400 ms
            Do
                pause 20 ' 5 mS @ 16MHz
                RunTime = RunTime + 5
            Loop while BTN = Pressed and RunTime < MaxRunTime ' NOTE: Value of MaxRunTime now in milliseconds, so 6000 for testing
      if RunTime >= MaxRunTime then gosub MotorStalled
            '// END OF NEW CODE
            
            
            
            
            
            
            
      '// 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
        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        
            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 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
    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 remove
      volts = volts /64    ' read 104 remove
        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 XXXremove in normal operationXXX
        return

LowBatteryVoltage:
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) 
        do
            gosub MeasureBatteryVoltage
            sertxd("Low Battery (") ' XXXremove in normal operationXXX
            gosub ShowVoltage
            sertxd(") - Waiting for Voltage to reach 14.0V",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 14.0v ") 
        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
        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 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
loop
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
loop
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
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
 

hippy

Technical Support
Staff member
The problem seems to be a conflict in the Counter variable as you're running 2 timers, one for the 400mS pulse extension and the other for the timeout if the motor stalls.
I don't think there is because the counter can be used multiple times providing it is set as appropriate before each part of the code. In the original code the counter was being set before the timing, is not used within that so can be moved after it. That also allows it to be re-used before it is set, as in my fix for time.

One of the problems with the original is that it's not clear what the code is doing. "BTN" suggests a button, is described as that but also described as a microswitch and tilt switch, which appears to be low when activated. Counter is a timer rather than a counter.

I am not entirely sure what the original code is meant to achieve but, if it's meant to trigger something for 400ms when the tilt switch is activated, issue a stall warning if tilt hasn't gone high after 30 seconds, I am not convinced it does that. I would probably have done it like this ...
Code:
Symbol TILT_SWITCH     = pinC.3  ; Tilt switch
Symbol TILT_ACTIVE_LED =         ; Tilt switch active LED
Symbol ACTIVE          = 0       ; Tilt switch is active low
Symbol MIN_RUN_TIME_MS = 400     ; 400 ms
Symbol STALLED_TIME_MS = 30000   ; 30000ms = 30 seconds 

Symbol runTimeMs       = w12 

If TILT_SWITCH is ACTIVE Then
  SerTxd("Tilt switch operated", CR, LF)
  High TILT_ACTIVE_LED
  runTimeMs = 0
  Do
    Do
      Pause 10
      runTimeMs = runTimeMs + 10
    Loop While runTimeMs < MIN_RUN_TIME_MS
  Loop While TILT_SWITCH is ACTIVE and runTimeMs < STALLED_TIME_MS
  If runTimeMs >= STALLED_TIME_MS Then
    SerTxd("Motor has stalled", CR, LF)
    Gosub MotorHasStalled
  Else
    SerTxd("Tilt switch now inactive", CR, LF)
    Low TILT_ACTIVE_LED
  End If
I wasn't entirely sure what is meant to happen after that, when the motor has stalled or it hasn't.

It's not clear "if Time >= MaxRunTime then gosub MotorStalled" is meant to be a single line IF or part of an IF-ENDIF block - which it seems to be, what the logic is for proceeding after a stall. If the motor has been stopped it doesn't seem to me that TILT would ever go inactive.

The best way forward would be for Rampz to rewrite the requirements so it's clearer what each part refers to, which button or tilt switch, and, rather than "light C0", explicitly name what "C0" means; "light error led" or whatever it is.

Then adjust the variable names and symbols used in the code to better reflect what they are used for, what is connect to a pin. With things named as BTN, BTN1, BTN2, LED and LED2 it's not clear what they actually are, which makes it difficult to verify code is doing what the specification asks for.
 

hippy

Technical Support
Staff member
pause 20 ' 5 mS @ 16MHz
Not on a 20X2. Pause times are as stated at a PICAXE's default operating speed; PAUSE 10 is a 10ms pause on an 08M2 at default 4MHz, is also a 10ms pause on a 20X2 at default 8MHz.

This is why I recommend using default speed during development and using the actual values wanted.

A more sophisticated approach can be to determine what pause times should be based on what has been selected -
Code:
#Ifdef _08M2
  SetFreq M16
  Symbol  PAUSE_MULTIPLIER = 4   ; 16MHz = 4 x 4MHz default
  Symbol  LED              = C.2 ; Bottom right
#endif

#Ifdef _20X2
  SetFreq M16
  Symbol  PAUSE_MULTIPLIER = 2   ; 16MHz = 2 x 8MHz default
  Symbol  LED              = B.7 ; Bottom right
#endif

Symbol FIVE_SECONDS = 5000 * PAUSE_MULTIPLIER ; 5s = 5000ms

Do
  Toggle LED
  Pause  FIVE_SECONDS
Loop
Because PE6 tries to simulate PAUSE in real time you can see the LED being on then off for five seconds when simulated, whether using 08M2 or 20X2.

The main point is to make the main code the same no matter what it is running on, no matter its speed. No 'magic numbers' where a literal 20 may mean 20, 10 or 5. When another chip is added, it means only the SYMBOL definitions, need to change. Get those right and the code should run and run the same on any PICAXE chip at any speed.
 

Rampz

Well-known member
I am not entirely sure what the original code is meant to achieve but
Hippy the original code I posted was amended for a tilt switch / btn being on going off as a result of testing on the tilt switch test rig, I felt it best to re-post the code as originally was working with a 08m2 and then later when working I can look at inverting the way it works.

The code evolved and like you say I need to update it so its more clear
Rampz
 

Rampz

Well-known member
#Ifdef _08M2 SetFreq M16 Symbol PAUSE_MULTIPLIER = 4 ; 16MHz = 4 x 4MHz default Symbol LED = C.2 ; Bottom right #endif #Ifdef _20X2 SetFreq M16 Symbol PAUSE_MULTIPLIER = 2 ; 16MHz = 2 x 8MHz default Symbol LED = B.7 ; Bottom right #endif Symbol FIVE_SECONDS = 5000 * PAUSE_MULTIPLIER ; 5s = 5000ms Do Toggle LED Pause FIVE_SECONDS Loop
Hippy thats a lovely solution, just not sure how to implement it in my code, i understand that directives used now, just not sure how to relate it to each use of time etc in the code.

When i was using the 08M2 C5 being the serial out pin also had a led attached that worked great as a kind of heartbeat, by controlling what messages were sent to the editor i could have it flash whenever voltage data was being sent - which ofcourse it was what lit the led, so now i want to get the C5 pin on the 20X2 to also flash only when its measuring voltage above 10.4 the cut off voltage, as a heartbeat led, doesn't want to flash when either stalled or in low voltage cutoff, doesn't seem to flash in stalled since program has stopped anyway waiting for motor to unstall, does still flash in low voltage unfortunately.

At the show voltage area i added to "high led2" for a "pause 50" "low led2"

Edit

Sorted the heartbeat led to flash while measuring voltage normally by adding a gosub "heartbeatled" and putting that in the code where its normally measuring voltage
 
Last edited:

hippy

Technical Support
Staff member
Hippy thats a lovely solution, just not sure how to implement it in my code, i understand that directives used now, just not sure how to relate it to each use of time etc in the code.
The best way is to "start again". Put the code you have to one side, rewrite the code from the ground up using the improved code, any new program flow.

That's not as bad as it seems as much of the 'new' will actually be pulled from the 'old'. Add a bit at a time, test the code, add some more, repeat.
 

papaof2

Senior Member
From many years as a programmer (PICAXE to PC to multi-user Unix machines), I agree with Hippy - starting "fresh" is sometimes the best way to incorporate changes. Save your current code, notes and references in a folder named "Version1" and put the new code, notes and references in a folder named "Version2" so you have the original if you wish to go back to it. It wasn't unusual for me to have "Version1" through"VersionXX" during extended development processes - and do put good comments in your code, including where you found ideas or solutions ;-)
 

hippy

Technical Support
Staff member
Programming is often no different to any other project where one would build a prototype and hack it about to determine the final version. The only difference is the final prototype is the final version, doesn't have to be 'cast in bronze' or whatever.

There's nothing wrong with adding to code, hacking it about, but as that gets harder to do - takes longer to figure out how to add something, without breaking something else, as what one now wants doesn't fit with how things are, the direction it evolved in - that's often the time to 'knock it off the pottery wheel' and start again.

It can feel like "that was a waste of time", "starting again will take forever", but that's rarely the case. You don't have to relearn the things which have already been learned, which is what takes most of the time.

I tend to judge how good code is on how aesthetically pleasing it is. When I think "that's a nice looking piece of code" I'm on the right track. If it's not then it's usually time to rethink what one has.
 

inglewoodpete

Senior Member
One method of program development is to keep the main loop as small as possible and use it to reference "functional blocks" to perform tasks, in the PICAXE environment, implemented in subroutines and macros.

As the project evolves, including migrating to a different microcontroller chip, some of these functional blocks can be reused, modified, replaced or discarded.

As @papaof2 suggests, create an archive copy of each working step of your project. That way, if you make a hash of your latest "improvement", you have a good operational copy to fall back to. Some of my projects have dozens of archived versions. PICAXE projects usually consist of just one code file, so upping the version is often as simple as doing a "Save As...".
 

Attachments

hippy

Technical Support
Staff member
One method of program development is to keep the main loop as small as possible and use it to reference "functional blocks" to perform tasks, in the PICAXE environment, implemented in subroutines and macros.
That is definitely something I favour, unless it is trivial and easy to follow example code to illustrate something or other.

Even for a simple light a LED when a button is pushed I would probably have code like the following -
Code:
Do
  If PUSH_BUTTON is PUSHED Then
    Gosub TurnOnTheLed
  Else
    Gosub TurnOffTheLed
  End If
Loop
It doesn't matter if the two LED routines are just HIGH and LOW commands then RETURN, the point is to make it clear as to what the program is doing without any knowledge of how things are actually done in the routines which do what's wanted.

That makes it much easier for others to understand the essence of the code, even if they don't understand the deeper parts of it - Anyone could probably figure out what that code does even if they have never used a PICAXE, aren't familiar with PICAXE Basic, even if they don't have any aptitude for coding..

And it also applies to the author of the code when they return to it some time after being away from it. There is always a temptation to minimise what we type, use cryptic names, but most explicit is usually best, though there are some unavoidable limits on just how long names can be.

It also means that whatever is done in those routines the main loop will always be the same, be just as good no matter how things are done.

It also means that whatever pin PUSH_BUTTON is on, whether it is active high or low, it doesn't matter, same too for the LED. Those can be set by SYMBOL statements and the code will still work as it did with those changed if the hardware ever does.

And the other big advantage is you can use that code, add two dummy LED routines which do nothing, and be able to simulate the code to prove it goes where it is meant to without needing the LED control itself. That's a fundamental principle of 'top-down coding', where 'what it does' is implemented and tested before worrying about how each part will have to do its thing.
 
Top