Disability Aid

Desert Dan

New Member
I have been asked by a disabled children’s learning centre to build an aid to do the following:-

A momentary switch is pressed then a linked LED lights and stays on. Then a second momentary switch is pressed, the first LED goes out and a second linked LED lights.
Then finally a third momentary switch is pressed, that LED goes out and another linked LED lights.
Having the same momentary switch always lighting the same LED but no two LEDS being on at the same time.
By linked I mean the same momentary switch always lights the same LED.
Seems basic but that’s what they require. If three switches can’t be accommodated then two would do.

I have limited Picaxe programming experience with 08M2+ chips. Any help with writing a program for this chip would be appreciated.
 

matchbox

Senior Member
You would have to use the serin and serout programming pins to accomplish this with a 08M2. Because you will have 3 inputs and 3 outputs.
It may be less trouble to use a 14M2.
 

Desert Dan

New Member
You would have to use the serin and serout programming pins to accomplish this with a 08M2. Because you will have 3 inputs and 3 outputs.
It may be less trouble to use a 14M2.
Hi, I only have a programming board for the 8 pin chip. What’s involved with using those pins?
 

premelec

Senior Member
Note that you can use a READADC pin and resistors to get three or even more inputs on a single pin...
 

matchbox

Senior Member
Premelec has a good idea with that. It isn't as bad as it sounds Dan.

While to use the programming pins.......
To use C.0 serout pin. It is just a matter of connecting the center pin of a two position switch to the 08M2 pin C.0 . And then connect one of the other switch pins to the serout programming plug and the other to the LED (or output device). This way you can have the switch in one direction for programming and the other direction to drive your LED.

When it come to the 08M2 serin pin C.5. It is simple enough too. But it will require you to enter a Disconnect command. This will prevent the 08m2 from scanning the serial input for new program downloads periodically, when you don't want this to happen.
I'll refer you to Picaxe manual 1 - page 46. It also gives a diagram.
 

Desert Dan

New Member
Premelec has a good idea with that. It isn't as bad as it sounds Dan.

While to use the programming pins.......
To use C.0 serout pin. It is just a matter of connecting the center pin of a two position switch to the 08M2 pin C.0 . And then connect one of the other switch pins to the serout programming plug and the other to the LED (or output device). This way you can have the switch in one direction for programming and the other direction to drive your LED.

When it come to the 08M2 serin pin C.5. It is simple enough too. But it will require you to enter a Disconnect command. This will prevent the 08m2 from scanning the serial input for new program downloads periodically, when you don't want this to happen.
I'll refer you to Picaxe manual 1 - page 46. It also gives a diagram.
Hi matchbox, that all sound good. If it’s not asking to much could you write the programming for me.
Dan
 

matchbox

Senior Member
Just a quick go at it. The first is what you asked. The second is the idea that Premelec gave. It will require a little more setup.

The divider image is just an example. You will have to calculate the resistor values based on your voltage supply. And you will only need 3 resistors in this case.

Code:
;****************************************************************

; Using 3 switch input pins

       #picaxe 08m2
        pause 500
        Disconnect

        symbol LED_1 = c.2
        symbol LED_2 = c.1
        symbol LED_3 = c.0
        symbol push_switch_1 = pinc.3
        symbol push_switch_2 = pinc.4
        symbol push_switch_3 = pinc.5
  

start:

do
    if push_switch_1 = 1 then
        high LED_1
        low LED_2
        low LED_3
    
    elseif push_switch_2 = 1 then
        high LED_2
        low LED_1
        low LED_3
    
    elseif push_switch_3 = 1 then
        high LED_3
        low LED_2
        low LED_1
    
    end if   
loop

;**************************************************************



  ;Using three switches that selects between 3 different ADC voltage levels
  ;It will require you to make up a multi-stage "voltage divider network"
  ;Then using the DEBUG command to set the ADC values

 
    #picaxe 08m2

     
      symbol LED_1 = c.0
      symbol LED_2 = c.1
      symbol LED_3 = c.2
      symbol volt_divider = b0
   

Start:

do
       readadc c.4, volt_divider
    
    
    ;voltage divider range falls between 0 and 85
    if volt_divider <= 85 then
       high LED_1
       low LED_2
       low LED_3
    endif

    ;voltage divider range falls between 86 and 169
    if volt_divider > 85 and b0 < 170 then
       high LED_2
       low LED_1
       low LED_3
    endif

    ;voltage divider range falls between 171 and 254
    if volt_divider >= 170 and b0 < 255 then
       high LED_3
       low LED_2
       low LED_1
    endif
  
loop
 

Attachments

Last edited:

Desert Dan

New Member
Hi Matchbox, Appreciate you writing the code so quick. I will give each program a try.
Would you be able to draw the voltage divider network circuit for me.
Cheers Dan
 

steliosm

Senior Member
Hello Dan. What is this device going to be used for? Based on the type of output I would presume it will be a communications device.
 

AllyCat

Senior Member
Hi,
A momentary switch is pressed then a linked LED lights and stays on. Then a second momentary switch is pressed, the first LED goes out and a second linked LED lights.
Then finally a third momentary switch is pressed, that LED goes out and another linked LED lights.
.
Sorry to be pedantic, but what (if anything) is required to happen if (for example) the second button is pressed first, or two buttons are pressed at the same time, etc.? As a "learning aid" I would expect the program/device to "ignore" any incorrect sequence? Note that the program in #8 will simply leave illuminated whichever was the last button/LED to be pressed, regardless of the sequence. Also, how is the device to be returned to the OFF state (i.e. no LEDs illuminated); A separate power switch?

Ultimately, I would probably use the Analogue (resistor mixing) input method on a single pin.... But an advantage of the "three pin" input method is that it's easy to test in the Simulator, which IMHO is the best place to begin. Note that on real hardware, it will be necessary to use a DISCONNECT command to prevent the button on c.5 resetting the PICaxe, which is a complication that would be best avoided by a novice.

Try loading the program in #8 into the Program Editor and run the Simulator. You can "press" pins c3 - c.5 with the mouse to simulate pressing the buttons, but note that you must press each pin/button a second time to release it (i.e. to simulate a momentary type of switch).

Cheers, Alan.
 

hippy

Technical Support
Staff member
f it’s not asking to much could you write the programming for me.
Dan
My approach to programming is to write each step of the program out as a sequence of commands prefaced with a GOSUB. So what you seem to want is -
Code:
Do
  Gosub TurnLed1Off
  Gosub TurnLed2Off
  Gosub TurnLed3Off
  Gosub WaitForButton1Pushed
  Gosub TurnLed1On
  Gosub WaitForButton2Pushed
  Gosub TurnLed1Off
  Gosub TurnLed2On
  Gosub WaitForButton3Pushed
  Gosub TurnLed2Off
  Gosub TurnLed3On
Loop
Then all you need to do is write routines to fulfil all those GOSUB calls -

TurnLed1On and TurnLed1Off
TurnLed2On and TurnLed2Off
TurnLed3On and TurnLed3Off
WaitForButton1Pushed
WaitForButton2Pushed
WaitForButton3Pushed

Those routines may be ridiculously simply, for example -
Code:
TurnLed1On:
  High C.0
  Return
But that approach has the advantage of making the program easier to understand and somewhat self documenting. Anyone picking up the program code can probably figure out its intent and how it works without even knowing what it was supposed to do.

It also makes it easier to write the code as, once the main intent is written down, the only thing left is to fill in the gaps, which are in themselves fairly simple. It will often be copy, paste and edit.

The downside is the code may not be as compact as it could be. But "meh"; it works, it's readable, it's understandable, doesn't use much memory, leaves plenty available, and isn't really any slower.

It's also easier to modify if one did want to move to different hardware or to put the three buttons on an ADC input. One only has to change the 'waiting for button push' code; everything else can stay how it is.

Assuming the same hardware as matchbox suggested. My version would be -
Code:
#Picaxe 08M2

Symbol LED1    = C.2
Symbol LED2    = C.1
Symbol LED3    = C.0

Symbol BUTTON1 = pinC.2
Symbol BUTTON2 = pinC.4
Symbol BUTTON3 = pinC.5

Symbol PUSHED  = 1 ; Active high buttons

Disconnect ; Because we are using C.5 as an input
Do
  Gosub TurnLed1Off
  Gosub TurnLed2Off
  Gosub TurnLed3Off
  Gosub WaitForButton1Pushed
  Gosub TurnLed1On
  Gosub WaitForButton2Pushed
  Gosub TurnLed1Off
  Gosub TurnLed2On
  Gosub WaitForButton3Pushed
  Gosub TurnLed2Off
  Gosub TurnLed3On
Loop

TurnLed1On:
  High LED1
  Return

TurnLed1Off:
  Low LED1
  Return

TurnLed2On:
  High LED2
  Return

TurnLed2Off:
  Low LED2
  Return

TurnLed3On:
  High LED3
  Return

TurnLed3Off:
  Low LED3
  Return

WaitForButton1Pushed:
  Do : Loop Until BUTTON1 Is PUSHED
  Return

WaitForButton2Pushed:
  Do : Loop Until BUTTON2 Is PUSHED
  Return

WaitForButton3Pushed:
  Do : Loop Until BUTTON3 Is PUSHED
  Return
That "IS" may not be immediately obvious. It has been there "since forever" as an equivalent to an "=" (equals). It doesn't often get used, but is quite handy for button level detection such as this as it makes things easier to read and understand.
 

hippy

Technical Support
Staff member
Here's the other way I would do it. Technically a little more advanced but just as simple. One can replace #DEFINE with #MACRO if more than one line of code needs to be used to achieve a particular intent -
Code:
#Picaxe 08M2

Symbol LED1    = C.2
Symbol LED2    = C.1
Symbol LED3    = C.0

Symbol BUTTON1 = pinC.2
Symbol BUTTON2 = pinC.4
Symbol BUTTON3 = pinC.5

Symbol PUSHED  = 1 ; Active high buttons

#Define TurnLed1On           High LED1
#Define TurnLed1Off          Low  LED1
#Define TurnLed2On           High LED2
#Define TurnLed2Off          Low  LED2
#Define TurnLed3On           High LED3
#Define TurnLed3Off          Low  LED3
#Define WaitForButton1Pushed Do : Loop Until BUTTON1 Is PUSHED
#DEfine WaitForButton2Pushed Do : Loop Until BUTTON2 Is PUSHED
#Define WaitForButton3Pushed Do : Loop Until BUTTON3 Is PUSHED

Disconnect
Do
  TurnLed1Off
  TurnLed2Off
  TurnLed3Off
  WaitForButton1Pushed
  TurnLed1On
  WaitForButton2Pushed
  TurnLed1Off
  TurnLed2On
  WaitForButton3Pushed
  TurnLed2Off
  TurnLed3On
Loop
 

AllyCat

Senior Member
Hi,
Code:
Do   ....
  TurnLed3_off
    ......  { main button functionality }
  TurnLed3_On
Loop
Note that (as written) LED3 will blink only very briefly (imperceptibly?). Hence, my question at the end of para 1 in #12. ;) Easily fixed of course, once the required functionality is defined.

Cheers, Alan.
 

Desert Dan

New Member
Hello Dan. What is this device going to be used for? Based on the type of output I would presume it will be a communications device.
it’s to be used partly for memory retention. Each of the illuminated momentary push buttons is numbered and the teacher pushes each one in a number pattern. The young person is then asked to repeat the number pattern. Pressing two buttons together should not light either and reset is just power off.
 

Desert Dan

New Member
Here's the other way I would do it. Technically a little more advanced but just as simple. One can replace #DEFINE with #MACRO if more than one line of code needs to be used to achieve a particular intent -
Code:
#Picaxe 08M2

Symbol LED1    = C.2
Symbol LED2    = C.1
Symbol LED3    = C.0

Symbol BUTTON1 = pinC.2
Symbol BUTTON2 = pinC.4
Symbol BUTTON3 = pinC.5

Symbol PUSHED  = 1 ; Active high buttons

#Define TurnLed1On           High LED1
#Define TurnLed1Off          Low  LED1
#Define TurnLed2On           High LED2
#Define TurnLed2Off          Low  LED2
#Define TurnLed3On           High LED3
#Define TurnLed3Off          Low  LED3
#Define WaitForButton1Pushed Do : Loop Until BUTTON1 Is PUSHED
#DEfine WaitForButton2Pushed Do : Loop Until BUTTON2 Is PUSHED
#Define WaitForButton3Pushed Do : Loop Until BUTTON3 Is PUSHED

Disconnect
Do
  TurnLed1Off
  TurnLed2Off
  TurnLed3Off
  WaitForButton1Pushed
  TurnLed1On
  WaitForButton2Pushed
  TurnLed1Off
  TurnLed2On
  WaitForButton3Pushed
  TurnLed2Off
  TurnLed3On
Loop
Thanks very much Hippy.
 

AllyCat

Senior Member
Hi,

Ah, so basically a much simplified version of Simon.

Sorry to be pedantic again, but what happens if the wrong button is pressed? Does the sequence Reset, or does nothing happen so that the "student" can use a "trial and error" approach? Is there any "reward" for completing the sequnce? A sequence of flashing lights, or even a tune, is quite possible with a PICaxe. ;)

Is the button sequence to be permanently coded into the program? A "learning" mode (for the teacher to use) to change the sequence and/or the number of button-presses in the sequence would be more flexible, but obviously more complex to code.

Cheers, Alan.
 

Desert Dan

New Member
Hi Ally Cat,
Interesting additions you suggested. They could be incorporated in the MK11 version. Only needs the chip swapping over I guess. The flashing reward at the end is good, I will suggest it. But i’ll get the simpler version going first. Have copied the three programs into three different chips. Will mock up the hardware prototype board and try them out.

Cheers Dan
 

Desert Dan

New Member
Just a quick go at it. The first is what you asked. The second is the idea that Premelec gave. It will require a little more setup.

The divider image is just an example. You will have to calculate the resistor values based on your voltage supply. And you will only need 3 resistors in this case.

Code:
;****************************************************************

; Using 3 switch input pins

       #picaxe 08m2
        pause 500
        Disconnect

        symbol LED_1 = c.2
        symbol LED_2 = c.1
        symbol LED_3 = c.0
        symbol push_switch_1 = pinc.3
        symbol push_switch_2 = pinc.4
        symbol push_switch_3 = pinc.5
 

start:

do
    if push_switch_1 = 1 then
        high LED_1
        low LED_2
        low LED_3
   
    elseif push_switch_2 = 1 then
        high LED_2
        low LED_1
        low LED_3
   
    elseif push_switch_3 = 1 then
        high LED_3
        low LED_2
        low LED_1
   
    end if  
loop

;**************************************************************



  ;Using three switches that selects between 3 different ADC voltage levels
  ;It will require you to make up a multi-stage "voltage divider network"
  ;Then using the DEBUG command to set the ADC values


    #picaxe 08m2

    
      symbol LED_1 = c.0
      symbol LED_2 = c.1
      symbol LED_3 = c.2
      symbol volt_divider = b0
  

Start:

do
       readadc c.4, volt_divider
   
   
    ;voltage divider range falls between 0 and 85
    if volt_divider <= 85 then
       high LED_1
       low LED_2
       low LED_3
    endif

    ;voltage divider range falls between 86 and 169
    if volt_divider > 85 and b0 < 170 then
       high LED_2
       low LED_1
       low LED_3
    endif

    ;voltage divider range falls between 171 and 254
    if volt_divider >= 170 and b0 < 255 then
       high LED_3
       low LED_2
       low LED_1
    endif
 
loop
Hi Matchbox,

I have tried the first version of your code. Switches 1 & 2 activate LED’s 1 & 2 correctly. I connected switch 3 to pin 5 and supply and a 10k resistor to ground. I presume it should light the LED on output 0 but it doesn’t, it just flashes the LED on output 2. Your help would be appreciated.

Dan
 

AllyCat

Senior Member
Hi,

Did you include the DISCONNECT command as shown by Matchbox (and hippy)? As I wrote in #12:
Note that on real hardware, it will be necessary to use a DISCONNECT command to prevent the button on c.5 resetting the PICaxe, which is a complication that would be best avoided by a novice.
The reason I "dislike" the Disconnect command (unless absolutely essential) is that it requires the "Hard Reset" procedure to reprogram the PICaxe. This is inconvenient, and novices can find it difficult to apply. So :

To avoid the Disconnect, I would drive two LEDs fromone pin, by using HIGH c.2 (for LED1), LOW c.2 (for LED2) and INPUT c.2 (both OFF). Each LED is connected to either the Supply or Earth rail as appropriate (via a resistor of course).

Only needs the chip swapping over I guess.
Do you mean a larger PICaxe, because, by using tricks like the above and/or Analogue switch detection, it could still all be done with an 08M2 (including sound output) !?

Cheers, Alan.
 

hippy

Technical Support
Staff member
it’s to be used partly for memory retention. Each of the illuminated momentary push buttons is numbered and the teacher pushes each one in a number pattern. The young person is then asked to repeat the number pattern.
That is rather more complicated than a fixed sequence program. You would need to determine which of the buttons are pressed in turn, remember those, then match what the child is pressing with what the stored sequence is.

It is possible, but would take more than a couple of minutes to do.
 

RNovember

Well-known member
Hello, I think this code would allow for the teacher to enter any combination for the test.
Code:
Disconnect
Do
    goto GETSEQ
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    goto TEST
Loop

GETSEQ:
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    goto GETFIRST
    goto GETSECOND
    goto GETTHIRD

    pause 1      ;time to see the last LED glowing

    return

GETFIRST:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        write 0, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed2On
        write 0, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed3On
        write 0, 3
    else
        goto GETFIRST
    endif
     
    return

GETSECOND:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 1, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 1, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 1, 3
    else
        goto GETSECOND
    endif
     
    return

GETTHIRD:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 2, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 2, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 2, 3
    else
        goto GETTHIRD
    endif
     
    return

TEST:
    read 0, b0
    read 1, b1
    read 2, b2

    if b0 Is 1 then
        First
        TurnLed1On
    elseif b0 Is 2 then
        Second
        TurnLed2On
    elseif b0 is 3 then
        Third
        TurnLed3On
    endif

    if b1 Is 1 then
        First
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
    elseif b1 Is 2 then
        Second
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
    elseif b1 is 3 then
        Third
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
    endif
     
    if b2 Is 1 then
        First
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
    elseif b2 Is 2 then
        Second
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
    elseif b2 is 3 then
        Third
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
    endif
 
    return
I haven't had time to test this myself, but it looks to me like it should work.
 
Last edited:

hippy

Technical Support
Staff member
Hello, I think this code would allow for the teacher to enter any combination for the test
Yes; something like that should work. Your code could be optimised and shortened by having a "GetSomeButton" and a "SaveThatButton" routine with some incrementing index of where to write the data to, which would also allow it to be extended to more that three button pushes.

The 'can they follow that?' is then a matter of going through that recorded sequence to see if the button pushed does or doesn't match that step.

The main thing though is having a full specification of the project. Whether it's a fixed three sequence task or should handle more than that, and how one terminates the variable length sequence if it does - 'no button pushed within five seconds of the last' or similar.

Plus exactly what to do when the student gets the sequence wrong or completes it. And how to get it into programming the next sequence, forced once the student has got it right, or, whether it may be desirable to allow the student to keep repeating the sequence until it is then put into a reprogamming mode.

It is best to get that full specification, iron out any ambiguity and any unanswered questions before moving to implementation. There's nothing worse than having to rip something up and start again because it has gone in a direction which isn't suitable for what is actually needed, and can equally be wasted effort to have code handle all possible things which it may never actually be required to do.

On the other hand it can be good to have something which 'handles anything and everything' which can then be moulded to what's actually needed for a particular implementation. In the absence of a specification it's acceptable to code it for personal preferences and tweak it later which can allow code to be produced before the specification is finalised.
 

Aries

New Member
Hello, I think this code would allow for the teacher to enter any combination for the test.
Code:
Disconnect
Do
    goto GETSEQ
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    goto TEST
Loop

GETSEQ:
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    goto GETFIRST
    goto GETSECOND
    goto GETTHIRD

    pause 1      ;time to see the last LED glowing

    return
If you use GOTO in the loop and elsewhere, you cannot use RETURN in the routine "gone-to", because RETURN only works with GOSUB (or CALL). You will get some very strange behaviour (in the simulator I would expect a stack overflow or similar). Replace the GOTOs with GOSUBs and it should be all right.
 

RNovember

Well-known member
What the code is supposed to do is first allow the teacher to enter a sequence of buttons, in any order, even pushing one button more than once, and it will save it in memory. This is the GETSEQ part of the code.

In the GETSEQ part, it has subroutines that get each digit. They each loop continuously until one input goes high. it then saves which button was pushed in a memory location. After three buttons are pushed, it goes into test mode.

This mode reads the combination out of memory, and depending on what it is, waits for each digit to be pressed. Once they have all been pressed correctly, the code continues on to GETSEQ again.

I have some ideas for a better version that will provide better feedback about if everything was entered correctly, and have gosubs, not gotos.
 

RNovember

Well-known member
Here it is. This one gets the teachers sequence and then gets the students sequence. it then checks them to see if they are the same. if they are, it flashes all the LEDs, and gets another sequence from the teacher. if they are not the same, then it turns them all on and off once and then gets the students sequence again.

At least that is what it should do, I haven't tested this one either.

Code:
#Picaxe 08M2

Symbol LED1    = C.2
Symbol LED2    = C.1
Symbol LED3    = C.0

Symbol BUTTON1 = pinC.3
Symbol BUTTON2 = pinC.4
Symbol BUTTON3 = pinC.5

Symbol PUSHED  = 1 ; Active high buttons

#Define TurnLed1On           High LED1
#Define TurnLed1Off          Low  LED1
#Define TurnLed2On           High LED2
#Define TurnLed2Off          Low  LED2
#Define TurnLed3On           High LED3
#Define TurnLed3Off          Low  LED3
#Define First             Do : Loop Until BUTTON1 Is PUSHED
#DEfine Second              Do : Loop Until BUTTON2 Is PUSHED
#Define Third             Do : Loop Until BUTTON3 Is PUSHED


Disconnect
Do
    gosub GETSEQ1
    gosub GETSEQ2
    gosub CHECK
Loop

GETSEQ1:
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    gosub GETFIRST
    gosub GETSECOND
    gosub GETTHIRD

    pause 1      ;time to see the last LED glowing
    return

GETFIRST:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        write 0, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed2On
        write 0, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed3On
        write 0, 3
    else
        goto GETFIRST
    endif
    
    return

GETSECOND:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 1, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 1, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 1, 3
    else
        goto GETSECOND
    endif
    
    return

GETTHIRD:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 2, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 2, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 2, 3
    else
        goto GETTHIRD
    endif
    
    return
    
    
GETSEQ2:
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    gosub GET1
    gosub GET2
    gosub GET3

    pause 1      ;time to see the last LED glowing
    return

GET1:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        write 3, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed2On
        write 3, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed3On
        write 3, 3
    else
        goto GET1
    endif
    
    return

GET2:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 4, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 4, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 4, 3
    else
        goto GET2
    endif
    
    return

GET3:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 5, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 5, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 5, 3
    else
        goto GET3
    endif
    
    gosub CHECK
    return
    
    
CHECK:
    read 0, b0
    read 1, b1
    read 2, b2
    
    read 3, b3
    read 4, b4
    read 5, b5
    
    if b0 = b3 and b1 = b4 and b2 = b5 then
      for b6 = 0 to 5
            TurnLed1On
          TurnLed2On
          TurnLed3On
        pause 500
        TurnLed1Off
        TurnLed2Off
        TurnLed3Off
        pause 500
      next b6
    else
        TurnLed1On
      TurnLed2On
      TurnLed3On
      pause 1000
      TurnLed1Off
      TurnLed2Off
      TurnLed3Off
      
      gosub GETSEQ2
    endif
    return
 
Last edited:

hippy

Technical Support
Staff member
My take on it, but only playing one game, no reprogramming after victory, have to restart the simulation ...
Code:
#Picaxe 08M2

Symbol LED1       = C.2
Symbol LED2       = C.1
Symbol LED3       = C.0

Symbol BUTTON1    = pinC.3
Symbol BUTTON2    = pinC.4
Symbol BUTTON3    = pinC.5

Symbol PUSHED     = 1  ; Active high buttons

Symbol timeout    = w1 ; b3:b2
Symbol putIndex   = b4
Symbol getIndex   = b5
Symbol buttonPush = b6
Symbol wanted     = b7

Symbol BUFFER     = 10 ; b10 upewards

Symbol NONE       = 0  ; No button pushed

Disconnect ; Because we are using C.5 as an input

ProgramMode:
  Gosub TurnAllLedsOff
  putIndex = BUFFER
  Do
    Do
      Gosub WaitForNoButtonsPushed
      Gosub WaitForButtonPushOrTimeout
      If buttonPush <> NONE Then
        Gosub StorePush
        Gosub IndicatePushed
      End If
    Loop Until putIndex = 100 Or buttonPush = NONE
  Loop While putIndex  = BUFFER

PlayBackMode:
  Gosub TurnAllLedsOff
  getIndex = BUFFER
  Do
    Gosub GetWanted
    Gosub waitForNoButtonsPushed
    Gosub WaitForButtonPush
    Gosub CheckMatch
    If buttonPush = NONE Then
      getIndex = BUFFER
    End If
    Gosub IndicatePushed    
  Loop Until getIndex = putIndex

Victory:
  Pause 1000
  Gosub TurnAllLedsOff
  Do
    Gosub turnLed1On  
    Gosub turnLed1Off  
    Gosub turnLed2On  
    Gosub turnLed2Off  
    Gosub turnLed3On  
    Gosub turnLed3Off  
    Gosub turnLed2On  
    Gosub turnLed2Off  
  Loop

TurnLed1On:
  High LED1
  Return

TurnLed1Off:
  Low LED1
  Return

TurnLed2On:
  High LED2
  Return

TurnLed2Off:
  Low LED2
  Return

TurnLed3On:
  High LED3
  Return

TurnLed3Off:
  Low LED3
  Return

TurnAllLedsOff:
  Gosub TurnLed1Off
  Gosub TurnLed2Off
  Gosub TurnLed3Off
  Return

IndicatePushed:
  Select Case buttonPush
    Case 1
      Gosub TurnLed1On
      Gosub TurnLed2Off
      Gosub TurnLed3Off
    Case 2
      Gosub TurnLed1Off
      Gosub TurnLed2On
      Gosub TurnLed3Off
    Case 3
      Gosub TurnLed1Off
      Gosub TurnLed2Off
      Gosub TurnLed3On
    Else
      Gosub TurnAllLedsOff
  End Select
  Return

WaitForNoButtonsPushed:
  Do : Loop While BUTTON1 Is PUSHED _
               Or BUTTON2 Is PUSHED _
               Or BUTTON3 Is PUSHED
  Return

WaitForButtonPushOrTimeout:
  buttonPush = NONE
  timeout = 0
  Do
    If BUTTON1 Is PUSHED Then : buttonPush = 1 : End If
    If BUTTON2 Is PUSHED Then : buttonPush = 2 : End If
    If BUTTON3 Is PUSHED Then : buttonPush = 3 : End If
    Pause 100 
    timeout = timeout + 100  
  Loop Until buttonPush <> NONE Or timeout >= 2000
  Return

WaitForButtonPush:
  Do
    Gosub WaitForButtonPushOrTimeout
  Loop While buttonPush = NONE
  Return

StorePush:
  Poke putIndex, buttonPush
  putIndex = PutIndex + 1
  Return

GetWanted:
  Peek getIndex, wanted
  getIndex = getIndex + 1
  Return

CheckMatch:
  If buttonPush <> wanted Then
    buttonPush = NONE
  End If
  Return
 

Desert Dan

New Member
Hello, I think this code would allow for the teacher to enter any combination for the test.
Code:
Disconnect
Do
    goto GETSEQ
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    goto TEST
Loop

GETSEQ:
    TurnLed1Off
    TurnLed2Off
    TurnLed3Off
    goto GETFIRST
    goto GETSECOND
    goto GETTHIRD

    pause 1      ;time to see the last LED glowing

    return

GETFIRST:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        write 0, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed2On
        write 0, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed3On
        write 0, 3
    else
        goto GETFIRST
    endif
    
    return

GETSECOND:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 1, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 1, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 1, 3
    else
        goto GETSECOND
    endif
    
    return

GETTHIRD:
    if BUTTON1 Is PUSHED then
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
        write 2, 1
    elseif BUTTON2 Is PUSHED then
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
        write 2, 2
    elseif BUTTON3 Is PUSHED then
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
        write 2, 3
    else
        goto GETTHIRD
    endif
    
    return

TEST:
    read 0, b0
    read 1, b1
    read 2, b2

    if b0 Is 1 then
        First
        TurnLed1On
    elseif b0 Is 2 then
        Second
        TurnLed2On
    elseif b0 is 3 then
        Third
        TurnLed3On
    endif

    if b1 Is 1 then
        First
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
    elseif b1 Is 2 then
        Second
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
    elseif b1 is 3 then
        Third
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
    endif
    
    if b2 Is 1 then
        First
        TurnLed1On
        TurnLed2Off
        TurnLed3Off
    elseif b2 Is 2 then
        Second
        TurnLed1Off
        TurnLed2On
        TurnLed3Off
    elseif b2 is 3 then
        Third
        TurnLed1Off
        TurnLed2Off
        TurnLed3On
    endifdebug

    return
I haven't had time to test this myself, but it looks to me like it should work.
Hi Rn,
I appreciate your writing the code but in simulation it comes up with errors. I’m not knowledgeable enough to debug it.
Could have another look please, cheers Dan
 

Desert Dan

New Member
Hi,

Did you include the DISCONNECT command as shown by Matchbox (and hippy)? As I wrote in #12:

The reason I "dislike" the Disconnect command (unless absolutely essential) is that it requires the "Hard Reset" procedure to reprogram the PICaxe. This is inconvenient, and novices can find it difficult to apply. So :

To avoid the Disconnect, I would drive two LEDs fromone pin, by using HIGH c.2 (for LED1), LOW c.2 (for LED2) and INPUT c.2 (both OFF). Each LED is connected to either the Supply or Earth rail as appropriate (via a resistor of course).


Do you mean a larger PICaxe, because, by using tricks like the above and/or Analogue switch detection, it could still all be done with an 08M2 (including sound output) !?

Cheers, Alan.
Still using the 08M2 PICaxe, cheers Dan
 

Desert Dan

New Member
Hi,

Did you include the DISCONNECT command as shown by Matchbox (and hippy)? As I wrote in #12:

The reason I "dislike" the Disconnect command (unless absolutely essential) is that it requires the "Hard Reset" procedure to reprogram the PICaxe. This is inconvenient, and novices can find it difficult to apply. So :

To avoid the Disconnect, I would drive two LEDs fromone pin, by using HIGH c.2 (for LED1), LOW c.2 (for LED2) and INPUT c.2 (both OFF). Each LED is connected to either the Supply or Earth rail as appropriate (via a resistor of course).


Do you mean a larger PICaxe, because, by using tricks like the above and/or Analogue switch detection, it could still all be done with an 08M2 (including sound output) !?

Cheers, Alan.
You mean the Word Disconnect after “pause 500”, yes I did include it. I copy and paste the programmes in.

Cheers Dan
 

AllyCat

Senior Member
Hi,

[#24] .... The main thing though is having a full specification of the project. Whether it's a fixed three sequence task or should handle more than that [eventually], and how one terminates the variable length sequence if it does -......

Plus exactly what to do when the student gets the sequence wrong or completes it. And how to get it into programming the next sequence, forced once the student has got it right, or, whether it may be desirable to allow the student to keep repeating the sequence until it is, then put into a reprogramming mode.

It is best to get that full specification, iron out any ambiguity and any unanswered questions before moving to implementation. There's nothing worse than having to rip something up and start again because it has gone in a direction which isn't suitable for what is actually needed, . ......
+1. There really isn't any point in debugging program code which might not even have been intended to do what is required.

And as @hippy (and others) often suggests: Start with a simple (and modular) program first (so that it is easy to debug) and then expand it as required, later on. For example, include simple subroutines such as::
Code:
Success:
     sertxd("cr,lf,"* WELL DONE ! *"
return
Fail:
     sertxd("cr,lf,"Sorry, Try again")
return
and then you can expand those with all the "Bells and Whistles" (perhaps literally) later on.

Cheers, Alan.
 

hippy

Technical Support
Staff member
I appreciate your writing the code but in simulation it comes up with errors. I’m not knowledgeable enough to debug it.
Could have another look please, cheers Dan
I suspect, if you tried to simulated the code exactly as was quoted, the issue is that it doesn't include any PICAXE, button or LED definitions. It is going to produce some kind of 'don't know what that is' error as soon as a syntax check or simulation is attempted.

It always helps to say what any error messages are as they are often a good indicator as to what may be wrong. Otherwise one simply has to guess and crystal balls aren't always as shiny as they could be.

I think you also need to make a decision; do you want to develop the code yourself, would like help in how to do that, or would you prefer a solution just handed to you ?

There is nothing wrong with wanting either and, of course, desiring a solution handed to you doesn't preclude you from also wanting to learn to program with PICAXE.

If it's merely a project idea you would like to solve to help others; nothing wrong with that and there will be help given as it seems a worthy cause. If you would like to learn to do it yourself, there will be help with that too. You can have both, whatever suits you best.
 

Desert Dan

New Member
Hi Guys,

I agree with no bells and whistles at this stage, so i’ll go through again what the centre wants as a memory aid for the children.

Using the O8M+ PICAXE chip.

Number 1 momentary push button switch is pressed and the corresponding LED illuminates and stays on ( the LED inside the PB switch).

Number 2 momentary switch is pressed and it’s LED illuminates and stays on BUT number 1 LED extinguishes.

Now number 3 momentary switch is pressed and it’s LED illuminates and stays BUT number 2 LED now extinguishes.

Now only number 3 LED is lit and stays on and that’s it. Only 1 LED can be on at any time.

Any combination of button pushing will produce the same on off LED conditions.

Power off to reset, simple.

It seems to me as a novice that the tricky bit is having three inputs and three outputs on the O8M, it’s only meant to have two inputs and three outputs. So there is the super challenge to make it work but as simple and reliable as possible. The more advanced stuff can come later.

Cheers Desert Dan
 

AllyCat

Senior Member
Hi,

That still doesn't define what is required to happen if (for example) the student is supposed to press button #2 but actually presses #1 (or #3, etc.). Ignore or Reset, or.....?

It seems to me as a novice that the tricky bit is having three inputs and three outputs on the O8M, it’s only meant to have two inputs and three outputs.
IMHO that really isn't a problem. It's easy to put two LEDs (with opposite polarities) on one pin so three (or even 4) need only two pins. Then three (or more) switches can be easily detected on a single (ADC) input pin by using mixing resistors (or by a "strobe" multiplex technique), so neither the Programming Input nor Output pins need to be used for this application.

Cheers, Alan.
 

hippy

Technical Support
Staff member
I agree with no bells and whistles at this stage, so i’ll go through again what the centre wants as a memory aid for the children.
That's still not a complete specification though. As it reads; any sequence of all three button pushes without repeating a button push would reach the end of the task.

There's no indication of programming the sequence, or how one distinguishes between programming and the student following the memorised pattern. And, as AllyCat mentions, there's no indication of what should happen when the student gets a button push wrong ( simply ignore that, or force a restart from step one, something else ), and what happens when the sequences is completed ?

It seems to me as a novice that the tricky bit is having three inputs and three outputs on the O8M, it’s only meant to have two inputs and three outputs. So there is the super challenge to make it work but as simple and reliable as possible.
That's not a problem. The 08M2 has three inputs when C.5 is used, and it can be so long as a DISCONNECT command is also used.

Using C.5 as a button input means one usually needs a power-cycle Hard Reset to download a new program, and not press the button attached to C.5 while downloading, but isn't really problematic as such.
 

RNovember

Well-known member
Hi Rn,
I appreciate your writing the code but in simulation it comes up with errors. I’m not knowledgeable enough to debug it.
Could have another look please, cheers Dan
This code has lots of problems, I realize because I just got around to simulating it. In the second one, I fixed all of them (I think). It works in the simulation.
 

Desert Dan

New Member
Hi Guys,

I agree with no bells and whistles at this stage, so i’ll go through again what the centre wants as a memory aid for the children.

Using the O8M+ PICAXE chip.

Number 1 momentary push button switch is pressed and the corresponding LED illuminates and stays on ( the LED inside the PB switch).

Number 2 momentary switch is pressed and it’s LED illuminates and stays on BUT number 1 LED extinguishes.

Now number 3 momentary switch is pressed and it’s LED illuminates and stays BUT number 2 LED now extinguishes.

Now only number 3 LED is lit and stays on and that’s it. Only 1 LED can be on at any time.

Any combination of button pushing will produce the same on off LED conditions.

Power off to reset, simple.

It seems to me as a novice that the tricky bit is having three inputs and three outputs on the O8M, it’s only meant to have two inputs and three outputs. So there is the super challenge to make it work but as simple and reliable as possible. The more advanced stuff can come later.

Cheers Desert Dan
I doesn’t matter if the wrong button is pushed the same corresponding single LED lights. The teacher notes that the student didn’t copy the number pattern that she did, E.G. the teacher pressses the numbered 1,2,3 buttons in the following order. 3,1,2,3,1, 3 then the student is asked to repeat that order. The student pushes 3,1,2,1,3 the individual LED’s light one by one but the sequence is not the same. The teacher then says whatever is appropriate for the task at hand.

Dan
 

Desert Dan

New Member
I suspect, if you tried to simulated the code exactly as was quoted, the issue is that it doesn't include any PICAXE, button or LED definitions. It is going to produce some kind of 'don't know what that is' error as soon as a syntax check or simulation is attempted.

It always helps to say what any error messages are as they are often a good indicator as to what may be wrong. Otherwise one simply has to guess and crystal balls aren't always as shiny as they could be.

I think you also need to make a decision; do you want to develop the code yourself, would like help in how to do that, or would you prefer a solution just handed to you ?

There is nothing wrong with wanting either and, of course, desiring a solution handed to you doesn't preclude you from also wanting to learn to program with PICAXE.

If it's merely a project idea you would like to solve to help others; nothing wrong with that and there will be help given as it seems a worthy cause. If you would like to learn to do it yourself, there will be help with that too. You can have both, whatever suits you best.
Hi Hippy and others,

I have been asked to make the hardware to to hold the illuminated push buttons etc. 1 am 72 and to learn the code to write the program at my age is daunting. So it would be appreciated if you or the guys could write a working version as per my previous reply as to how it is to be used. If the simulator shows an error I will post that error.

Cheers Dan
 
Top