My first PICaxe attempt was a success!

Chris Kelly

Well-known member
Hi guys

Just managed to get a program working on a 20M2 PICaxe! I know it sounds strange but I was amazed that it worked :D

It was a simple program to help with a couple of functions on my project, but it was good to actually see the process in full, from code to breadboard.

Code:
#picaxe 20M2

symbol inputs = b0         ' 8 bits of inputs
symbol lastInputs = b1         ' previous inputs, port B
dirsc = $00000000         ' all 8 inputs, set as needed

symbol BDmute = bit16
symbol SDmute = bit17
symbol HHmute = bit18
symbol CBmute = bit19

b2 = %11111111              ' these bits will change to
                      ' zeroes when the
                        ' corresponding drum is muted
symbol BDsolo = bit24
symbol SDsolo = bit25
symbol HHsolo = bit26
symbol CBsolo = bit27
b3 = 0                ' bits 24, 25, 26, 27 will change to
                    ' 1 if a drum sound is put into SOLO mode

high B.0                ' All drums start off as unmuted
high B.1
high B.2
high B.3

main:
  do
    inputs = pinsc
    
'//// Start to monitor MUTE inputs for momentary button presses

    if inputs <> lastInputs then
      if bit0 <> bit8 then     ' BD Mute button has been pressed
        if bit0 = 1 then
          
          if BDMute = 1 then    ' toggle BD mute
            BDMute = 0
                else if   BDMute = 0 then
            BDMute = 1
        endif       
        endif
      endif
      
    if bit1 <> bit9 then     ' SD Mute button has been pressed
        if bit1 = 1 then
          
        if SDmute = 1 then    ' toggle SD mute
            SDmute = 0
            else if   SDmute = 0 then
            SDmute = 1
        endif       
        endif
      endif
      
    if bit2 <> bit10 then     ' HH Mute button has been pressed
        if bit2 = 1 then
          
        if HHmute = 1 then    ' toggle HH mute
            HHmute = 0
            else if   HHmute = 0 then
            HHmute = 1
        endif       
        endif
    endif
    
    if bit3 <> bit11 then     ' CB Mute button has been pressed
        if bit3 = 1 then
          
        if CBMute = 1 then    ' toggle CB mute
            CBMute = 0
            else if   CBMute = 0 then
            CBMute = 1
        endif
      endif
    endif
    
' //// Start to monitor SOLO inputs for momentary button presses
    
    if bit4 <> bit12 then     ' BD Solo button has been pressed
        if bit4 = 1 then
                
        if BDSolo = 0 and b3 = 0 then ' Check to make sure no other drum is already in SOLO mode
            BDSolo = 1
            SDMute = 0
            HHMute = 0
            CBMute = 0
            
        else if BDSolo = 1 then
            BDSolo = 0
            SDMute = 1
            HHMute = 1
            CBMute = 1
        end if
       end if
       endif
      
    if bit5 <> bit13 then     ' SD Solo button has been pressed
        if bit5 = 1 then
          if SDSolo = 0 and b3 = 0 then ' Check to make sure no other drum is already in SOLO mode
            SDSolo = 1
            BDMute = 0
            HHMute = 0
            CBMute = 0
            
        else if SDSolo = 1 then               
            SDSolo = 0
            BDMute = 1
            HHMute = 1
            CBMute = 1
        end if
        endif
      endif
      
    if bit6 <> bit14 then     ' HH Solo button has been pressed
        if bit6 = 1 then
          if HHSolo = 0 and b3 = 0 then ' Check to make sure no other drum is already in SOLO mode
            HHSolo = 1
            BDMute = 0
            SDMute = 0
            CBMute = 0
            
        else if HHSolo = 1 then
            HHSolo = 0
            BDMute = 1
            SDMute = 1
            CBMute = 1
        end if
        endif
    endif
    
    if bit7 <> bit15 then     ' CB Solo button has been pressed
        if bit7 = 1 then
          if CBSolo = 0 and b3 = 0 then ' Check to make sure no other drum is already in SOLO mode
            CBSolo = 1
            BDMute = 0
            SDMute = 0
            HHMute = 0
            
        else if CBSolo = 1 then
            CBSolo = 0
            BDMute = 1
            SDMute = 1
            HHMute = 1
        end if
        endif
    endif
    
      lastInputs = inputs
      pause 40
    endif

' /// Set outputs based the on mute status for each pin
    
       if BDMute = 1 then
                high B.0
            low B.4
        else if   BDMute = 0 then
            low B.0
            high B.4
    endif
    if SDmute = 1 then
                high B.1
            low B.5
        else if   SDmute = 0 then
            low B.1
            high B.5
        endif   
    if HHmute = 1 then
                high B.2
            low B.6
        else if   HHmute = 0 then
            low B.2
            high B.6
    endif
        if CBMute = 1 then
                high B.3
            low B.7
        else if   CBMute = 0 then
            low B.3
            high B.7
    endif
      
  loop
I'm, pretty hyped up now! Just wanted to say thanks for all the help so far.

Cheers

Chris
 

hippy

Technical Support
Staff member
Just managed to get a program working on a 20M2 PICaxe! I know it sounds strange but I was amazed that it worked
It is all quite magical and amazing isn't it, and indeed quite satisfying, even exhilarating. Glad to hear the PICAXE helped you out.
 

Buzby

Senior Member
Great stuff !.

Glad to see you're on the way to being a PICAXE fan.

I've not gone through your code fully yet, but it does look like you've got the right mindset for a programmer !.

Just one thing I spotted is that you don't need 'else if' when the 'if' only has two options, yes or no. The 'else if' still works, but is just not needed.

For example ...
Code:
     if BDMute = 1 then
            high B.0
            low B.4
     else if   BDMute = 0 then
            low B.0
            high B.4
    endif

only needs to be ...

   if BDMute = 1 then
            high B.0
            low B.4
   else 
            low B.0
            high B.4
   endif
Cheers,

Buzby
 

hippy

Technical Support
Staff member
There's a trick one can use to quickly determine which buttons have been pushed ...
Code:
#Picaxe 20M2

Symbol pushedButtons   = b0
Symbol BDMute          = bit0
Symbol SDMute          = bit1
Symbol HHMute          = bit2
Symbol CBMute          = bit3
Symbol BDSolo          = bit4
Symbol SDSolo          = bit5
Symbol HHSolo          = bit6
Symbol CBSolo          = bit7

Symbol currentInputs   = b4
Symbol lastInputs      = b5
Symbol changedInputs   = b6

Do
  currentInputs = pinsC
  changedInputs = currentInputs ^ lastInputs
  pushedButtons = changedInputs & currentInputs
  lastInputs    = currentInputs

Loop
After that you don't need to compare bit values, you can just use something like this to be activated whenever BDMute is pushed ...
Code:
  If BDMute = 1 Then ; BD Mute button was pushed
    ...
  End If
I have only skimmed over your code so I'm not entirely sure what functionality it has in full, but it seems it might even be possible to determine your output pin states directly from the raw inputs, which might allow your code to become just a few lines of code, no IF commands needed at all.

Not that there's anything wrong with large monolithic programs when they work, and there's nothing wrong with not knowing all the clever tricks there may be from the start.

And in particular don't get disheartened that those of us who have been doing it for years may have "something better". Getting code to work, a project running and doing what it's meant to, is the primary goal and there is success in that. Everything else is just being flashy with it :)
 

Chris Kelly

Well-known member
And in particular don't get disheartened that those of us who have been doing it for years may have "something better". Getting code to work, a project running and doing what it's meant to, is the primary goal and there is success in that. Everything else is just being flashy with it :)
I'm always appreciative of "something better" since that means a more efficient / elegant solution! Thanks for the alternative code - I'll run it through PE6 to try and understand it fully
 

hippy

Technical Support
Staff member
This may help to explain the boolean logic.

Starting from having button 0 and 1 held (last), we then press button 7 and release button 1 while still keeping 0 pressed (current). The ^ is an a Exclusive Or which identifies which bits have changed between current and last. The & is an And which allows us to identify which have just been pushed, changed=1 and current=1.
Code:
           7   6   5   4   3   2   1   0
         .---.---.---.---.---.---.---.---.
Last     | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
         |---|---|---|---|---|---|---|---|
Current  | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
         `---'---^---^---^---^---^---^---'
         .---.---.---.---.---.---.---.---.
Changed  | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | Current ^ Last
         |---|---|---|---|---|---|---|---|
Pushed   | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | changed & Current
         `---'---^---^---^---^---^---^---'
So button 7 is the only one which was just pushed, which is correct.

One can also determine which ones have been released though not necessarily required here -
Code:
         .---.---.---.---.---.---.---.---.
         | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | Not current
         |---|---|---|---|---|---|---|---|   
Released | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | Changed &/ Current
         `---'---^---^---^---^---^---^---'
So button 1 is the only one which was just released, which is also correct.
 

The bear

Senior Member
Congratulations Chris,
Is there any chance of changing the description from "It was a simple program to help with a couple of functions on my project." To: It was a very very complex program to help with a couple of functions on my project.
Depressed bear..
 

Chris Kelly

Well-known member
Thanks Bear!
I think a more apt title would be "Here is a simple program taken mainly from other people's code snippets" :ROFLMAO:
 
Top