PICAXE 08M Enthusiast Help please.

Hi guys.
Its been a while since i was here or dealt with picaxe's.
New project came up and im looking for some advise and help please.
I'll be working with PICAXE08M.
Basically, i'll have a relay that will be controlled by picaxe. It will have one input - a switch.
What i need is this, if the switch is turned ON then OFF and ON again within 1sec then PICAXE will close the relay ( or keep it closed ), then if the switch is turned OFF and ON once only the relay will open (or remain open if it was open).
I've been thinking for a few days about it now but cant come up with nothing worth mentioning.
I cant even figure out if its possible to get PICAXE to do the above task.
Sorry about the lack of CODE. Hope some one can point me in the right direction.
Thanks lads.
 

hippy

Ex-Staff (retired)
It should be possible though not sure my brain's up to a full solution. For turning on think of the condition which has to exist for the relay to be activated ...

1) Switch has to have gone from off to on twice, and
2) Switch has to have gone from on to off once, and
3) The time elapsed from first going on must be less than one second.

The (2) can be dropped as it's implicit in the first, you cannot turn on twice without the intervening off, so -

1) Switch has to have gone from off to on twice, and
2) The time elapsed from first going on must be less than one second.

Turning that about, exit 'something' when either a switch has gone off to on twice, or elapsed time equals one second, so a start is ...

Do : Loop Until switch = off
elapsedms = 0
switched = 0
Do
If switched from off to on Then switched = switched + 1
Pause 10
elapsed = elapsed + 10
Loop Until swiched = 2 Or elapsed = 1000
If switched = 2 Then close relay Else ...
 
It should be possible though not sure my brain's up to a full solution. For turning on think of the condition which has to exist for the relay to be activated ...

1) Switch has to have gone from off to on twice, and
2) Switch has to have gone from on to off once, and
3) The time elapsed from first going on must be less than one second.

The (2) can be dropped as it's implicit in the first, you cannot turn on twice without the intervening off, so -

1) Switch has to have gone from off to on twice, and
2) The time elapsed from first going on must be less than one second.

Turning that about, exit 'something' when either a switch has gone off to on twice, or elapsed time equals one second, so a start is ...

Do : Loop Until switch = off
elapsedms = 0
switched = 0
Do
If switched from off to on Then switched = switched + 1
Pause 10
elapsed = elapsed + 10
Loop Until swiched = 2 Or elapsed = 1000
If switched = 2 Then close relay Else ...
Thanks very much.
I'll give it a go, although its not 100% clear to me...
I'll get back to if i get stuck.
Just cant remember half the commands i worked with before.
 

1968neil

Senior Member
just a thought.....

it maybe an idea to count the presses of the switch and branch of to preset modes ie: 1 press = turn relay on, 2nd press = stay on, third press = go off etc.

ive knocked up a little bit of code to get you started, youll have to set the tasks to your own tastes. hope this helps

Regards
Neil
Code:
symbol relay = 2
symbol pbswitch = pin3     ' push button switch on pin3
symbol down = 0            ' define input state
symbol counter = b0

counter = 0                'set counter to 0 before starting


loop1:

if pbswitch = down then switchdown
branch counter, (Relayoff,Relayon, relaywait)
counter =0 
goto loop1

switchdown:
counter = counter +1
sdloop:
if pbswitch = down then sdloop
goto loop1

Relayoff:
low relay
goto loop1

RelayOn:
high relay
goto loop1

relaywait:
high relay
goto loop1
 
just a thought.....

it maybe an idea to count the presses of the switch and branch of to preset modes ie: 1 press = turn relay on, 2nd press = stay on, third press = go off etc.

ive knocked up a little bit of code to get you started, youll have to set the tasks to your own tastes. hope this helps

Regards
Neil
Code:
symbol relay = 2
symbol pbswitch = pin3     ' push button switch on pin3
symbol down = 0            ' define input state
symbol counter = b0

counter = 0                'set counter to 0 before starting


loop1:

if pbswitch = down then switchdown
branch counter, (Relayoff,Relayon, relaywait)
counter =0 
goto loop1

switchdown:
counter = counter +1
sdloop:
if pbswitch = down then sdloop
goto loop1

Relayoff:
low relay
goto loop1

RelayOn:
high relay
goto loop1

relaywait:
high relay
goto loop1
Thank you very much Neil.
I'll run the above and see if it suits but i really appreciate the ideas lads.
Thanks very much. Ye are very helpful.
 
just a thought.....

it maybe an idea to count the presses of the switch and branch of to preset modes ie: 1 press = turn relay on, 2nd press = stay on, third press = go off etc.

ive knocked up a little bit of code to get you started, youll have to set the tasks to your own tastes. hope this helps

Regards
Neil
Code:
symbol relay = 2
symbol pbswitch = pin3     ' push button switch on pin3
symbol down = 0            ' define input state
symbol counter = b0

counter = 0                'set counter to 0 before starting


loop1:

if pbswitch = down then switchdown
branch counter, (Relayoff,Relayon, relaywait)
counter =0 
goto loop1

switchdown:
counter = counter +1
sdloop:
if pbswitch = down then sdloop
goto loop1

Relayoff:
low relay
goto loop1

RelayOn:
high relay
goto loop1

relaywait:
high relay
goto loop1
Just tried your code, doesnt suit the needs.
Its basicaly becasue some times the Switch will do same sequence (i.e. ON, OFF and ON after same sequence, and some times after a Single OFF, ON sequence. ).
Its like if i press on a push button twice in 1sec relay will engage, if i do same again the relay will stay engaged but if i press once within 1sec then relay will disengage.
I know it sounds silly.
 
It should be possible though not sure my brain's up to a full solution. For turning on think of the condition which has to exist for the relay to be activated ...

1) Switch has to have gone from off to on twice, and
2) Switch has to have gone from on to off once, and
3) The time elapsed from first going on must be less than one second.

The (2) can be dropped as it's implicit in the first, you cannot turn on twice without the intervening off, so -

1) Switch has to have gone from off to on twice, and
2) The time elapsed from first going on must be less than one second.

Turning that about, exit 'something' when either a switch has gone off to on twice, or elapsed time equals one second, so a start is ...

Do : Loop Until switch = off
elapsedms = 0
switched = 0
Do
If switched from off to on Then switched = switched + 1
Pause 10
elapsed = elapsed + 10
Loop Until swiched = 2 Or elapsed = 1000
If switched = 2 Then close relay Else ...
Looks like you code is the one that will work for me hippy.
Would you mind giving me a few more tips.
I only built picaxe's to control relays on simple bases before and not very familiar with loops and such.
Sorry for asking too much.
Thank you.
 
Right, so im trying to work the following code (thatnks to hippy):

Code:
symbol elapsed = 0
symbol switched = 0

main:
do Loop Until switched = 0
If switched from off to on Then switched = switched + 1
Pause 10 
elapsed = elapsed + 10
Loop Until swiched = 2 Or elapsed = 1000
If switched = 2 Then high pin2
else goto main
Im not sure how to link SWITCHED to PIN1 would say.
It appears that switched is a variable but also has to be an input.
Am i missing something here?
 

hippy

Ex-Staff (retired)
The following code should do most of what you want and is based on my originally proposed code ...

Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3

Main:

  Do : Loop Until TOGGLE_SWITCH = 0
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    SerTxd( "Turn Relay On", CR, LF )
    Do : Loop Until TOGGLE_SWITCH = 0
    Do : Loop Until TOGGLE_SWITCH = 1
    SerTxd( "Turn Relay Off", CR, LF )
  End If

  Goto main

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = 1 Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
There is an issue though in re-reading your specification - "What i need is this, if the switch is turned ON then OFF and ON again within 1sec then PICAXE will close the relay ( or keep it closed ), then if the switch is turned OFF and ON once only the relay will open (or remain open if it was open)".

That "keep it closed" means that you cannot open the relay on the next off-on of the switch but need to check what happened in the last second to determine if it was another double off-on switches or a single off-on switching. That can be done but adds a one second delay to the off-on which opens the relay - that might be acceptable and what you want.

I can see what you want, and in my mind is like a vehicle ignition button; two presses turns it on / keeps it on, one press turns it off / keeps it off. To do that means a bit of rejigging, thinking in terms of a state machine ...

Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3
Symbol relayState      = b4

Pause 2000 ' Just to let the Terminal window open and be ready

Main:
  SerTxd( "Relay Off", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 1
  SerTxd( "Relay On", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 0
  Goto Main

CheckState:
  Do : Loop Until TOGGLE_SWITCH = 0
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    relayState = 1
  Else
    relayState = 0
  End If

  Return

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = 1 Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
 
The following code should do most of what you want and is based on my originally proposed code ...

Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3

Main:

  Do : Loop Until TOGGLE_SWITCH = 0
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    SerTxd( "Turn Relay On", CR, LF )
    Do : Loop Until TOGGLE_SWITCH = 0
    Do : Loop Until TOGGLE_SWITCH = 1
    SerTxd( "Turn Relay Off", CR, LF )
  End If

  Goto main

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = 1 Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
There is an issue though in re-reading your specification - "What i need is this, if the switch is turned ON then OFF and ON again within 1sec then PICAXE will close the relay ( or keep it closed ), then if the switch is turned OFF and ON once only the relay will open (or remain open if it was open)".

That "keep it closed" means that you cannot open the relay on the next off-on of the switch but need to check what happened in the last second to determine if it was another double off-on switches or a single off-on switching. That can be done but adds a one second delay to the off-on which opens the relay - that might be acceptable and what you want.

I can see what you want, and in my mind is like a vehicle ignition button; two presses turns it on / keeps it on, one press turns it off / keeps it off. To do that means a bit of rejigging, thinking in terms of a state machine ...

Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3
Symbol relayState      = b4

Pause 2000 ' Just to let the Terminal window open and be ready

Main:
  SerTxd( "Relay Off", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 1
  SerTxd( "Relay On", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 0
  Goto Main

CheckState:
  Do : Loop Until TOGGLE_SWITCH = 0
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    relayState = 1
  Else
    relayState = 0
  End If

  Return

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = 1 Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
Thank you hippy. This Code is represents more the i can understand at the moment.
I noticed that it does not specify which pin relay is connected to unless its there but i cant read it right.
And you are exactly spot on with the idea of my project.
 
UPDATE:
Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3
Symbol relayState      = b4

Pause 2000 ' Just to let the Terminal window open and be ready

Main:
  low 4 'i just added this line to turn output 4 OFF
  SerTxd( "Relay Off", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 1
  high 4 'i just added this line to turn output 4 ON
  SerTxd( "Relay On", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 0
  Goto Main

CheckState:
  Do : Loop Until TOGGLE_SWITCH = 0
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    relayState = 1
  Else
    relayState = 0
  End If

  Return

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = 1 Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
The second CODE is working almost 100% for my application.
One thing though.
I Have to use Toggle Switch and not push button, so if i go (from off) ON, OFF and then ON again with in 1sec it does not actiavate the relay unless i go to OFF withi same sequence although it i just go (from OFF) ON if reay was activated from prev sequence it does go OFF.
Would it be possible to activate the relay by going ON, OFF, ON with out having to go to OFF again on the toggle switch?
 
UPDATE:
Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3

Main:

  Do : Loop Until TOGGLE_SWITCH = 0
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then 
    SerTxd( "Turn Relay On", CR, LF )
    high 4
    Do : Loop Until TOGGLE_SWITCH = 0
    Do : Loop Until TOGGLE_SWITCH = 1
    SerTxd( "Turn Relay Off", CR, LF )
    low 4
  End If

  Goto main

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = 0 Then '[U][B]changed from 1 to 0[/B][/U]
      switchedCount = switchedCount + 1
    End If
  End If
  Return
Sorry for all the updates.
Went back to the first code you put up and changed lastSwitchState from 1 to 0 and now its working spot on for my project.
Thanks very much again hippy. you helped me tremendously the last time as well.
You are a real gent.
 

hippy

Ex-Staff (retired)
I think the issue is what logic level signal your switch provides when on. I assumed high for on, low for off - switch between +V and pin with pull-down to 0V - while you may have your switch wired the other way.

With the change made you're actually counting on to off transitions as I'd had it, but that cancels out, however the logic of the other parts of the code won't follow as they should.

You could turn the switch upside down and that will then work. If using a toggle switch and you've got no pull-ups you're inviting trouble so perhaps best to post a circuit of what you actually have.

Also note that that version of code does not implement the specification you asked for ! You need the state code for that.
 
Last edited:

hippy

Ex-Staff (retired)
Here's a version with a Symbol constant ( SWITCHED_ON ) which you can change to match what your switch puts out when on, 1 or 0 ...

Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol SWITCHED_ON     = [b]1[/b]

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3
Symbol relayState      = b4

Pause 2000 ' Just to let the Terminal window open and be ready

Main:
  SerTxd( "Relay Off", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 1
  SerTxd( "Relay On", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 0
  Goto Main

CheckState:
  Do : Loop Until TOGGLE_SWITCH <> SWITCHED_ON
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    relayState = 1
  Else
    relayState = 0
  End If

  Return

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = SWITCHED_ON Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
 
Here's a version with a Symbol constant ( SWITCHED_ON ) which you can change to match what your switch puts out when on, 1 or 0 ...

Code:
#Picaxe 08M
#Terminal 4800

Symbol TOGGLE_SWITCH   = pin1

Symbol SWITCHED_ON     = [b]1[/b]

Symbol elapsedTime     = w0 ' b1:b0
Symbol switchedCount   = b2
Symbol lastSwitchState = b3
Symbol relayState      = b4

Pause 2000 ' Just to let the Terminal window open and be ready

Main:
  SerTxd( "Relay Off", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 1
  SerTxd( "Relay On", CR, LF )
  Do
    Gosub CheckState
  Loop Until relayState = 0
  Goto Main

CheckState:
  Do : Loop Until TOGGLE_SWITCH <> SWITCHED_ON
  switchedCount = 0
  elapsedTime = 0

  Do
    Gosub CheckSwitchChanges
    Pause 10 
    elapsedTime = elapsedTime + 10
  Loop Until switchedCount = 2 Or elapsedTime = 1000

  If switchedCount = 2 Then
    relayState = 1
  Else
    relayState = 0
  End If

  Return

CheckSwitchChanges:
  If TOGGLE_SWITCH <> lastSwitchState Then
    lastSwitchState = lastSwitchState ^ 1
    If lastSwitchState = SWITCHED_ON Then
      switchedCount = switchedCount + 1
    End If
  End If
  Return
Thank you again, yep, its working with the toggle switch if 1 is changed to 0 in SWITCHED_ON line.
Thank you
Is there any good literature on PICAXE's out there that would help me in the future? Want to learn more.
 
Top