Can't get code to recognize switch closure in motor gear train.

tracecom

Senior Member
I am building a project that involves controlling a small DC gear motor with an SIRC remote via a 14M2 and an H-bridge. For the most part, I can get the code to do what I want, but I have one problem that I have not been able to solve.
There is a set of dry contacts in the motor gear train that close once for a second or so during each revolution of the final gear in train. I want to use that closure to establish a "home" position for the motor, that is, I want to be able to press a button on the remote which will cause the motor to start and run until the dry contacts close. I have one side of the contacts connected to +5V, and the other side connected to pinC.0 on the 14M2. I have a 4.7k pulldown resistor on pinC.0 as well as a .1uF bypass cap to ground.
In operation, I have confirmed that pinC.0 is being pulled high once during each revolution of the final gear. However, debug shows that bit0 is not being set high. Thus, when I push the correct button on the remote, the motor turns endlessly until I disconnect power. I have stripped the code of all (or most) functions that do not pertain to this issue. It is reproduced below; please point out what I have done wrong. I have never been a good programmer and have been away from PICAXE basic for a couple of years. Thanks.

Code:
'Experiment: Controlling 12VDC Motor with SIRC
'20 Aug 2019
'Schematic: PA-14M2 12V Motor Controller for PCB.dch
'Code: PA-14M2 SIRC go home test.bas
'Objective: Use a SIRC remote to cause a DC motor to return to a "home" position
'based on the closure of a set of switch contacts in the gear train of the motor.
'The switch contacts close briefly during each revolution of the final output gear.

#picaxe 14M2 'Identify the PICAXE being used as an 14M2.
#no_data 'Prevent data from being downloaded to PICAXE.
setfreq m4

main:
debug
b4 = 0 'Clear contents of byte register b4.
bit0 = 0 'Clear contents of bit register bit0.
irin B.5, b4 'Read SIRC from pinC.3 and store in b4.

if b4 = 5 and bit0 = 0 then 'Check to see that correct SIRC code has been received
    gosub clockwise 'and that the motor is not in "home" position (i.e., bit0 is low.)
endif
goto main

'Subroutine
clockwise:
low B.2 'Apply ground to one side of DC motor.
high C.2 'Apply +V to other side of DC motor.
if pinC.0 = 1 then 'Check pinC.0 to see if motor gear train switch is closed.
    bit0 = 1 'If switch is closed, set bit0 high to indicate motor is in "home" position.
endif
return
goto main
 

hippy

Technical Support
Staff member
Two problems I can foresee -

1) that you don't actually stop the motor when pinC.0 is high, in your clockwise routine or elsewhere. That may just be a result of editing the code down.

2) More importantly ; when you set 'bit0=1' to indicate pinC.1 is high, as soon as you return, go round the main loop, there's a 'bit0=0' which will come quite quickly and may be hiding it ever being seen as a 1 in the DEBUG.

I would try something like this -
Code:
Do
  low  B.2
  high C.2
  Do : Loop While pinC.0 = 1
  Do : Loop While pinC.0 = 0
  Low B.2                                     ; ?
  Low C.2                                     ; ?
  Pause 10000
Loop
Every 10 seconds that should rotate the wheels one revolution. I'm guessing the Low B.2, Low C.2 will stop the motor. If not change that to whatever does.

The two DO-LOOP commands firstly allow the motor to move past home position, where it probably ends up when stopped. The second allows it to continue until the home position is encountered again.
 

tracecom

Senior Member
Two problems I can foresee -

1) that you don't actually stop the motor when pinC.0 is high, in your clockwise routine or elsewhere. That may just be a result of editing the code down.

2) More importantly ; when you set 'bit0=1' to indicate pinC.1 is high, as soon as you return, go round the main loop, there's a 'bit0=0' which will come quite quickly and may be hiding it ever being seen as a 1 in the DEBUG.

I would try something like this -
Code:
Do
  low  B.2
  high C.2
  Do : Loop While pinC.0 = 1
  Do : Loop While pinC.0 = 0
  Low B.2                                     ; ?
  Low C.2                                     ; ?
  Pause 10000
Loop
Every 10 seconds that should rotate the wheels one revolution. I'm guessing the Low B.2, Low C.2 will stop the motor. If not change that to whatever does.

The two DO-LOOP commands firstly allow the motor to move past home position, where it probably ends up when stopped. The second allows it to continue until the home position is encountered again.
I copy/pasted your Do Loop into the clockwise subroutine (replacing everything that was there. It worked as you said it would. Making both B.2 and C.2 low allows the motor to coast to a stop, so I changed them both to be high, which brakes the motor (a function of the H-bridge chip I am using.) That also worked. Thanks.

Now, I am going to study Do Loops to try to better understand your code. In addition, I want to find a way to make the motor go home and stop (rather than repeating every 10 seconds. Thanks for the help.
 

hippy

Technical Support
Staff member
You can use the main part of the loop as a go to home position subroutine, then just call that when you trigger it. For example, this should move one revolution per IR key press it receives -
Code:
Do
  IrIn B.5, b4
  Gosub ForwardOneRevolution
Loop

ForwardOneRevolution:
  Low  B.2
  High C.2
  Do : Loop While pinC.0 = 1
  Do : Loop While pinC.0 = 0
  High B.2
  Return
C.2 is already high when we come to stop the motor so no need to set it high again.
 

tracecom

Senior Member
You can use the main part of the loop as a go to home position subroutine, then just call that when you trigger it. For example, this should move one revolution per IR key press it receives -
Code:
Do
  IrIn B.5, b4
  Gosub ForwardOneRevolution
Loop

ForwardOneRevolution:
  Low  B.2
  High C.2
  Do : Loop While pinC.0 = 1
  Do : Loop While pinC.0 = 0
  High B.2
  Return
C.2 is already high when we come to stop the motor so no need to set it high again.
Thanks again. I think I am on track now.
 
Top