Help with 08M2

netpilot

New Member
Hi all.
I have a project which consists of 2 LEDs and a buzzer connected to pins 0, 1 & 2 on a prototype board.
1. I tested their operation with a simple programme which turned each device on and off in turn. No problems.
2. I am now trying to extend the programme to switch LED 1 on and off 4 times (on/off periods the same), then switch LED 2 on for a fixed period.
This loop should be repeated a number of times per minute.
3. The next stage is to introduce an error trap-if the push button connected to pin 3 is operated while LED 2 is off, the buzzer should go high and both LEDs should alternately flash quickly.
4. Finally, I would like to select the number of cycles per minute from another push button which will be connected to pin 4.
Unfortunately, I have run into a few problems due to my lack of programming know how.
Despite looking through Picaxe help files and trawling around this forum, I am at a loss to know how to progress.
I have attached the programme plus the error screen generated.
Any help/pointing in the right direction would be much appreciated.
Thanks.
 

Attachments

neiltechspec

Senior Member
You haven't defined the following symbols to variables -
cycles
blinks
gon
onoff

e.g.
symbol cycles = w5
symbol blinks = w6
symbol gon = w7
symbol onoff = w8

put these before you try & set values to them.

Neil.
 

BESQUEUT

Senior Member
Any help/pointing in the right direction would be much appreciated.
.
Here a version NOT TESTED but will compile :
Code:
[color=Navy]#PICAXE [/color][color=Black]08M2[/color]

[color=Green];stage 4
;do
;if pin 4 = 1 then
;pause 100
;do loop until pin 4 = 0
;mode = mode + 1
;if mode > 3 then 
;mode = 1
;endif
;select mode
;case 1: cycles per minute = 8 
;case 2: cycles per minute = 10
;case 3: cycles per minute = 12
;end select
;endif
;loop[/color]


[color=Blue]symbol [/color][color=Purple]cycles [/color][color=DarkCyan]= [/color][color=Purple]w5
 [/color][color=Blue]symbol [/color][color=Purple]blinks [/color][color=DarkCyan]= [/color][color=Purple]w6
 [/color][color=Blue]symbol [/color][color=Purple]gon [/color][color=DarkCyan]= [/color][color=Purple]w7
 [/color][color=Blue]symbol [/color][color=Purple]onoff [/color][color=DarkCyan]= [/color][color=Purple]w8[/color]


[color=Blue]symbol [/color][color=Purple]counter [/color][color=DarkCyan]= [/color][color=Purple]b1                 [/color][color=Green]; define the variable b1 as counter (count blinks)[/color]
[color=Blue]symbol [/color][color=Purple]counter2 [/color][color=DarkCyan]= [/color][color=Purple]b2                [/color][color=Green]; define the variable b2 as counter2 (count alarm on/offs)[/color]
[color=Blue]let [/color][color=Purple]cycles [/color][color=DarkCyan]= [/color][color=Navy]10                     [/color][color=Green]; red/green cycles per minute [/color]
[color=Blue]let [/color][color=Purple]blinks [/color][color=DarkCyan]= [/color][color=Navy]4                      [/color][color=Green]; red LED number on/off[/color]
[color=Blue]let [/color][color=Purple]gon [/color][color=DarkCyan]= [/color][color=Navy]1200                      [/color][color=Green]; green LED on time (ms)
'let onoff = (60/cycles-(gon/1000))/(2*blinks+2)*1000       ;red LED on/off duration
                                                      ;(60/10-1.2)/(2*4+2)*1000
                                                      ;4.8/10*1000 = 480 (ms)[/color]
[color=Blue]let [/color][color=Purple]onoff[/color][color=DarkCyan]=[/color][color=Navy]480[/color]
[color=Blue]symbol rLED [/color][color=DarkCyan]= [/color][color=Blue]C.0                   [/color][color=Green]; define pin 0 with the name rLED[/color]
[color=Blue]symbol gLED [/color][color=DarkCyan]= [/color][color=Blue]C.1                   [/color][color=Green]; define pin 1 with the name gLED[/color]
[color=Blue]symbol buzzer [/color][color=DarkCyan]= [/color][color=Blue]C.2                 [/color][color=Green]; define pin 2 with the name buzzer[/color]
[color=Blue]symbol sense [/color][color=DarkCyan]= [/color][color=Blue]C.3                  [/color][color=Green]; define pin 3 with the name sense[/color]
[color=Blue]symbol selector [/color][color=DarkCyan]= [/color][color=Blue]C.4               [/color][color=Green]; define pin 4 with the name selector[/color]

[color=Black]main:[/color][color=Blue]end

start1:
low C.0                             [/color][color=Green]; switch red LED off[/color]
[color=Blue]pause [/color][color=Navy]480                           [/color][color=Green]; pause onoff milliseconds (assumes 10 cycles per minute)[/color]
[color=Blue]for [/color][color=Purple]counter [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]4                [/color][color=Green]; for count = 1 to blinks           [/color]
[color=Blue]high C.0                            [/color][color=Green]; switch red LED on[/color]
[color=Blue]pause [/color][color=Navy]480                           [/color][color=Green]; pause onoff milliseconds[/color]
[color=Blue]low C.0                             [/color][color=Green]; switch red LED off[/color]
[color=Blue]pause [/color][color=Navy]480                           [/color][color=Green]; wait for onoff milliseconds[/color]
[color=Blue]next [/color][color=Purple]counter                        [/color][color=Green]; end of for...next loop[/color]
[color=Blue]high C.1                            [/color][color=Green]; switch green LED on[/color]
[color=Blue]pause [/color][color=Navy]1200                          [/color][color=Green]; wait for 1.2 seconds(gon)[/color]
[color=Blue]low C.1                             [/color][color=Green]; switch green LED off[/color]
[color=Blue]goto [/color][color=Black]main   [/color]
[color=Blue]goto [/color][color=Black]start1[/color]

[color=Blue]start2:
if [/color][color=Purple]pinC.0 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=DarkCyan]and [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then [/color][color=Black]alarm   [/color][color=Green]; jump to alarm if green LED is off and sense is on[/color]
[color=Blue]goto [/color][color=Black]start2

alarm:                              [/color][color=Green]; make a label called alarm ' useless comment ![/color]
[color=Blue]for [/color][color=Purple]counter2 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]2
      [/color][color=Blue]high C.2                            [/color][color=Green]; switch buzzer on
      [/color][color=Blue]high C.0                            [/color][color=Green]; switch red LED on
      [/color][color=Blue]pause [/color][color=Navy]150                           [/color][color=Green]; wait for 0.15 seconds
      [/color][color=Blue]low C.2                             [/color][color=Green]; switch buzzer off
      [/color][color=Blue]low C.0     [/color][color=Black]`                       [/color][color=Green]; switch red LED off
      [/color][color=Blue]pause [/color][color=Navy]150                           [/color][color=Green]; wait for 0.15 seconds
      [/color][color=Blue]high C.2                            [/color][color=Green]; switch buzzer on
      [/color][color=Blue]high C.1                            [/color][color=Green]; switch green LED on
      [/color][color=Blue]pause [/color][color=Navy]150                           [/color][color=Green]; wait for 0.15 seconds
      [/color][color=Blue]low C.2                             [/color][color=Green]; switch buzzer off
      [/color][color=Blue]low C.1                             [/color][color=Green]; switch green LED off
      [/color][color=Blue]pause [/color][color=Navy]150                           [/color][color=Green]; wait for 0.15 seconds
      [/color][color=Blue]next [/color][color=Purple]counter2[/color]
[color=Blue]goto [/color][color=Black]alarm[/color]
 

BESQUEUT

Senior Member
Same without useless comments :
Code:
[color=Navy]#PICAXE [/color][color=Black]08M2[/color]

[color=Green];stage 4
;do
;if pin 4 = 1 then
;pause 100
;do loop until pin 4 = 0
;mode = mode + 1
;if mode > 3 then 
;mode = 1
;endif
;select mode
;case 1: cycles per minute = 8 
;case 2: cycles per minute = 10
;case 3: cycles per minute = 12
;end select
;endif
;loop[/color]


[color=Blue]symbol [/color][color=Purple]cycles [/color][color=DarkCyan]= [/color][color=Purple]w5[/color]
[color=Blue]symbol [/color][color=Purple]blinks [/color][color=DarkCyan]= [/color][color=Purple]w6[/color]
[color=Blue]symbol [/color][color=Purple]gon [/color][color=DarkCyan]= [/color][color=Purple]w7[/color]
[color=Blue]symbol [/color][color=Purple]onoff [/color][color=DarkCyan]= [/color][color=Purple]w8[/color]


[color=Blue]symbol [/color][color=Purple]counter [/color][color=DarkCyan]= [/color][color=Purple]b1                 [/color][color=Green]; define the variable b1 as counter (count blinks)[/color]
[color=Blue]symbol [/color][color=Purple]counter2 [/color][color=DarkCyan]= [/color][color=Purple]b2                [/color][color=Green]; define the variable b2 as counter2 (count alarm on/offs)[/color]
[color=Blue]let [/color][color=Purple]cycles [/color][color=DarkCyan]= [/color][color=Navy]10                     [/color][color=Green]; red/green cycles per minute [/color]
[color=Blue]let [/color][color=Purple]blinks [/color][color=DarkCyan]= [/color][color=Navy]4                      [/color][color=Green]; red LED number on/off[/color]
[color=Blue]let [/color][color=Purple]gon [/color][color=DarkCyan]= [/color][color=Navy]1200                      [/color][color=Green]; green LED on time (ms)
'let onoff = (60/cycles-(gon/1000))/(2*blinks+2)*1000       ;red LED on/off duration
                                                      ;(60/10-1.2)/(2*4+2)*1000
                                                      ;4.8/10*1000 = 480 (ms)[/color]
[color=Blue]let [/color][color=Purple]onoff[/color][color=DarkCyan]=[/color][color=Navy]480[/color]
[color=Blue]symbol rLED [/color][color=DarkCyan]= [/color][color=Blue]C.0                   [/color][color=Green]; define pin 0 with the name rLED[/color]
[color=Blue]symbol gLED [/color][color=DarkCyan]= [/color][color=Blue]C.1                   [/color][color=Green]; define pin 1 with the name gLED[/color]
[color=Blue]symbol buzzer [/color][color=DarkCyan]= [/color][color=Blue]C.2                 [/color][color=Green]; define pin 2 with the name buzzer[/color]
[color=Blue]symbol sense [/color][color=DarkCyan]= [/color][color=Blue]C.3                  [/color][color=Green]; define pin 3 with the name sense[/color]
[color=Blue]symbol selector [/color][color=DarkCyan]= [/color][color=Blue]C.4               [/color][color=Green]; define pin 4 with the name selector[/color]

[color=Black]main:[/color][color=Blue]end

start1:
  low rLED
  pause [/color][color=Navy]480                         [/color][color=Green]; pause onoff milliseconds (assumes 10 cycles per minute)
  [/color][color=Blue]for [/color][color=Purple]counter [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]4              [/color][color=Green]; for count = 1 to blinks           
      [/color][color=Blue]high rLED
      pause [/color][color=Purple]onoff 
      [/color][color=Blue]low rLED
      pause [/color][color=Purple]onoff 
  [/color][color=Blue]next [/color][color=Purple]counter 
  [/color][color=Blue]high gLED
  pause [/color][color=Navy]1200 
  [/color][color=Blue]low gLED

goto [/color][color=Black]start1[/color]


[color=Blue]start2:
      if [/color][color=Purple]pinC.0 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=DarkCyan]and [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then [/color][color=Black]alarm   [/color][color=Green]; jump to alarm if green LED is off and sense is on[/color]
[color=Blue]goto [/color][color=Black]start2



alarm: 
   [/color][color=Blue]for [/color][color=Purple]counter2 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]2
      [/color][color=Blue]high buzzer
      high rLED
      pause [/color][color=Navy]150
      [/color][color=Blue]low buzzer
      low rLED
      pause [/color][color=Navy]150
      [/color][color=Blue]high buzzer
      high gLED
      pause [/color][color=Navy]150
      [/color][color=Blue]low buzzer
      low gLED
      pause [/color][color=Navy]150
   [/color][color=Blue]next [/color][color=Purple]counter2[/color]
[color=Blue]goto [/color][color=Black]alarm[/color]
ALSO : note that alarm is a never ending loop...
 

netpilot

New Member
Thanks for you advice BESQUEUT.
I have made a few tweaks and the code compiles ok, but when I run the simulator it stops at main:end (before the multi task threads run).
Is main:end in the right place?
Also, I had assumed that the thread numbering needed to start with 0.
Any further comments would be appreciated.
Thanks.
 

netpilot

New Member
Also, I need the alarm code to run only once (when the fault is detected), not infinitely.
I guess I need to goto start1 to continue where the alarm was triggered?
 

BESQUEUT

Senior Member
I have made a few tweaks and the code compiles ok, but when I run the simulator it stops at main:end (before the multi task threads run).
Picaxe Manual2, page 9: simtask directive
#simtask all/0/1/2/3 Programming Editor Only
The task to follow during simulation when using parallel multi-tasking M2 parts.
If no task is specified task 0 will be automatically traced.
Multiple tasks can also be traced at the same time by using ‘all’

Is main:end in the right place?
Also, I had assumed that the thread numbering needed to start with 0.
There is an implicit start0 at the start of any program, so in your case before :
let cycles = 10
You are right : the correct command to be used when multitasking is
suspend 0
, NOT END
The others tasks are infinites loops...
Also, I need the alarm code to run only once (when the fault is detected), not infinitely.
I guess I need to goto start1 to continue where the alarm was triggered?
So : replace
goto alarm
with
gosub /return

The GOTO command is always a source of problems...

Code:
[color=Navy]#PICAXE [/color][color=Black]08M2[/color]
[color=Navy]#simspeed 200
#simtask [/color][color=Blue]all[/color]

[color=Green];stage 4
;do
;if pin 4 = 1 then
;pause 100
;do loop until pin 4 = 0
;mode = mode + 1
;if mode > 3 then 
;mode = 1
;endif
;select mode
;case 1: cycles per minute = 8 
;case 2: cycles per minute = 10
;case 3: cycles per minute = 12
;end select
;endif
;loop[/color]

[color=Blue]start0:

symbol [/color][color=Purple]cycles [/color][color=DarkCyan]= [/color][color=Purple]w5[/color]
[color=Blue]symbol [/color][color=Purple]blinks [/color][color=DarkCyan]= [/color][color=Purple]w6[/color]
[color=Blue]symbol [/color][color=Purple]gon [/color][color=DarkCyan]= [/color][color=Purple]w7[/color]
[color=Blue]symbol [/color][color=Purple]onoff [/color][color=DarkCyan]= [/color][color=Purple]w8[/color]


[color=Blue]symbol [/color][color=Purple]counter [/color][color=DarkCyan]= [/color][color=Purple]b1                 [/color][color=Green]; define the variable b1 as counter (count blinks)[/color]
[color=Blue]symbol [/color][color=Purple]counter2 [/color][color=DarkCyan]= [/color][color=Purple]b2                [/color][color=Green]; define the variable b2 as counter2 (count alarm on/offs)[/color]

[color=Blue]let [/color][color=Purple]cycles [/color][color=DarkCyan]= [/color][color=Navy]10                     [/color][color=Green]; red/green cycles per minute [/color]
[color=Blue]let [/color][color=Purple]blinks [/color][color=DarkCyan]= [/color][color=Navy]4                      [/color][color=Green]; red LED number on/off[/color]
[color=Blue]let [/color][color=Purple]gon [/color][color=DarkCyan]= [/color][color=Navy]1200                      [/color][color=Green]; green LED on time (ms)
'let onoff = (60/cycles-(gon/1000))/(2*blinks+2)*1000       ;red LED on/off duration
                                                      ;(60/10-1.2)/(2*4+2)*1000
                                                      ;4.8/10*1000 = 480 (ms)[/color]
[color=Blue]let [/color][color=Purple]onoff[/color][color=DarkCyan]=[/color][color=Navy]480[/color]
[color=Blue]symbol rLED [/color][color=DarkCyan]= [/color][color=Blue]C.0                   [/color][color=Green]; define pin 0 with the name rLED[/color]
[color=Blue]symbol gLED [/color][color=DarkCyan]= [/color][color=Blue]C.1                   [/color][color=Green]; define pin 1 with the name gLED[/color]
[color=Blue]symbol buzzer [/color][color=DarkCyan]= [/color][color=Blue]C.2                 [/color][color=Green]; define pin 2 with the name buzzer[/color]
[color=Blue]symbol sense [/color][color=DarkCyan]= [/color][color=Blue]C.3                  [/color][color=Green]; define pin 3 with the name sense[/color]
[color=Blue]symbol selector [/color][color=DarkCyan]= [/color][color=Blue]C.4               [/color][color=Green]; define pin 4 with the name selector[/color]

[color=Black]main:[/color]
[color=Blue]suspend [/color][color=Navy]0[/color]


[color=Blue]start1:
do
  low rLED
  pause [/color][color=Navy]480                         [/color][color=Green]; pause onoff milliseconds (assumes 10 cycles per minute)
  [/color][color=Blue]for [/color][color=Purple]counter [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]4              [/color][color=Green]; for count = 1 to blinks           
      [/color][color=Blue]high rLED
      pause [/color][color=Purple]onoff 
      [/color][color=Blue]low rLED
      pause [/color][color=Purple]onoff 
  [/color][color=Blue]next [/color][color=Purple]counter 
  [/color][color=Blue]high gLED
  pause [/color][color=Navy]1200 
  [/color][color=Blue]low gLED
loop


start2:
do
      if [/color][color=Purple]pinC.0 [/color][color=DarkCyan]= [/color][color=Navy]0 [/color][color=DarkCyan]and [/color][color=Purple]pinC.1 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]then
            gosub [/color][color=Black]alarm                   [/color][color=Green]; jump to alarm if green LED is off and sense is on
      [/color][color=Blue]endif
loop[/color]



[color=Black]alarm: 
   [/color][color=Blue]for [/color][color=Purple]counter2 [/color][color=DarkCyan]= [/color][color=Navy]1 [/color][color=Blue]to [/color][color=Navy]2
      [/color][color=Blue]high buzzer
      high rLED
      pause [/color][color=Navy]150
      [/color][color=Blue]low buzzer
      low rLED
      pause [/color][color=Navy]150
      [/color][color=Blue]high buzzer
      high gLED
      pause [/color][color=Navy]150
      [/color][color=Blue]low buzzer
      low gLED
      pause [/color][color=Navy]150
   [/color][color=Blue]next [/color][color=Purple]counter2[/color]
[color=Blue]return[/color]
Note that all tasks will start at the same time.
Actually :
- first line from start0
- first line from start1
- first line from start2
- second line from start0
- second line from start1
- second line from start2
- third line from start0
- and so on

If you want do initialze some things before starting 1 and 2
you have to suspend them at the very beginning of start0, and resume them at the end of start0.
 
Last edited:

netpilot

New Member
Hi BESQUEUT,
Main code now runs OK.
Problem is with start2: - when the programme runs it always triggers alarm: even if the alarm condition is not present.
I have also corrected a typo in my code - it should read :
do
if pinC.3 = 1 and pinC.1 = 0 then
gosub alarm ; jump to alarm if sense is on and green LED is off
endif
loop
 

BESQUEUT

Senior Member
Problem is with start2: - when the programme runs it always triggers alarm: even if the alarm condition is not present.
I have also corrected a typo in my code - it should read :
do
if pinC.3 = 1 and pinC.1 = 0 then
gosub alarm ; jump to alarm if sense is on and green LED is off
endif
loop
Please re-read manual about special variables Pins and OutPins : that is NOT the same thing...
The AND operator is capricious... Try this :
Code:
if pinC.3 = 1  then
    if pinC.1 = 0 then
           gosub alarm ; jump to alarm if sense is on and green LED is off
    endif
endif
If that does not work, add debug :
Code:
if pinC.3 = 1  then
    if pinC.1 = 0 then
           sertxd ("C3=", #pinC.3, " C1=",#pinC.1,"  ")
           gosub alarm ; jump to alarm if sense is on and green LED is off
    endif
endif
 

netpilot

New Member
Thanks for your reply BESQUEUT,
I am a complete novice to programming/PicAxe and some of the finer points in the manuals have gone over my head.
I will try your suggestions later today.
In my code I tried to use an equation to determine the value of a variable.
Because the equation fails to give a result, I have resorted to calculating the values separately and using them-see below.
Again, am I missing something in the equation-I have checked the manual several times but I am unable to find an answer.

symbol cycles = w5
symbol blinks = w6
symbol gon = w7
symbol onoff = w8

symbol counter = b1 ; define the variable b1 as counter (count blinks)
symbol counter2 = b2 ; define the variable b2 as counter2 (count alarm on/offs)

let cycles = 10 ; red/green cycles per minute
let blinks = 4 ; red LED number on/off
let gon = 1200 ; green LED on time (ms)

' let onoff = (60/cycles-(gon/1000))/(2*blinks+2)*1000 ;red LED on/off duration << Ideal determination of onoff

let onoff = 480 << What I used

Any pointers to solutions and for future reference would be much appreciated.
 

netpilot

New Member
The alarm loop is also running every time (incorrectly).
If I comment out the alarm section, the main programme runs as I would expect it to.
 

BESQUEUT

Senior Member
Hi BESQUEUT,
both versions run in the simulator but both drop out with a 'stack underflow' error.
This is not my #7 code... (do...loop missing)
Please, publish you whole code (copy for forum...)

as there is nothing to stop program flow from start2:
the Picaxe continue with the alarm sub...

As it as never encoutered a GOSUB command
when it reach the RETURN command
it does not known where to go back
and so, make a "stack underflown" trying to read a RETURN address before start of stack...
 
Last edited:

netpilot

New Member
Sorry BESQUEUT, I used your code exactly from your last reply (without the do or loop lines).
When I added them back in, the programme ran perfectly.
The full working code is attached, as requested.
Thanks for your time and patience-it is very much appreciated.
 

Attachments

BESQUEUT

Senior Member
So the problem with the AND operator within an If THEN ELSE seems to be confirmed.
There is a thread for that, but I does not remember the exact title...
 

netpilot

New Member
Does anybody have any idea why my equation to evaluate onoff in post #10 does not work?
It appears to me that all variables have been correctly declared, and the number of close brackets matches the number of open brackets.
Any constructive criticism/suggestions for improving my programme would be appreciated.
I have pieced this together and made it work (with great help from forum users), but I'm sure it would not be considered elegant by a real programmer.
 

BESQUEUT

Senior Member
Does anybody have any idea why my equation to evaluate onoff in post #10 does not work?
)( does not exists in Picaxe math...
Expressions are evaluate strictly from left to right.
For example : PieM post #11
onoff = 60000 / cycles - gon /onoff
is evaluate like this :
onoff =(( 60000 / cycles) - gon) /onoff

With operators priority (* and / before + and -, etc...), this would be :
onoff = (60000 / cycles) - (gon /onoff)

that is not the same thing...

Also note that :
onoff = 2*blinks+2
onoff = 60000 / cycles - gon /onoff


is evaluate like this :

onoff = ((60000 / cycles) - gon) /((2*blinks)+2)


Also note that :
onoff = 2*blinks+2

is not the same thing as :
onoff = 2+2*blinks

Wich is evaluate as :
onoff = (2+2)*blinks
 
Last edited:

netpilot

New Member
Thanks again for the help regarding ( and ).
I assumed an equation was evaluated like in say Excel: first (), then * & /, then + & - etc.
Apologies PieM-I misunderstood that this is what you meant in post #11.
 

netpilot

New Member
Apologies PieM-I misunderstood that this is what you meant in post #11.
I assumed an equation was evaluated like in Excel: first (), then * & /, then + & - etc.
Thanks for your help.
 
Top