Using hall effect sensor with 6 channel maestro

Good evening

Equipment:
Pololu 6 channel maestro Assembled
SpringRC SM-S4303R Continuous Rotation Servo
44E 938 hall effect switch
6v battery
Magnet

I have hall effect sensor hooked up to maestro 5v out reg hole and ground and signal hooked up to maestro ground and signal rail (0 pins). I have servo connected to maestro (1 pins).

What I am looking to do is connect a magnet to servo rotating a disk with the hall effect sensor above. I would like the program to begin with servo off then rotate it by my set number of time using the sensor. For example if I put 20 in, the program will turn the servo making the magnet pass the sensor 20 times. when it reaches 20 I would like the servo to rotate the other way counting down to 0 and stopping.

If the magnet is away from the sensor it reads 1023 and sometimes 1021 but when the magnet passes the sensor it reads 1 and sometime 2. I have been trying to write scripts but with no joy. can someone please give me a hand?

Hello.

I think it is possible to accomplish this with your setup. Could you post a script you have tried? It would probably be a good place to start, and I can try to help you troubleshoot from there.

-Brandon

Good afternoon BrandonM
Thanks in advance for your help.

Servo in position 0
Hall effect sensor in position 1

Below is that I need the servo to do

begin
5600 0 servo
500 delay
put 20 on stack and every time hall sensor passes the magnet it minus 1 until 0 is reached
6000 0 servo stop servo
500 delay
6600 0 servo reverse servo
500 delay
adds 1 every time the hall sensor passes the magnet and stops servo when 20 is reached
6000 0 servo
500 delay
repeat

I managed to get the code to count down when the hall sensor sees the magnet and when it doesn’t but don’t know how to tell it to wait until hall sensor actually passes the magnet to count minus 1 or plus 1 to the stack.

10
begin
dup
while
1 get_position
512 less_than
dup
drop
if
1 plus
else
1 minus
endif
repeat

Really hope you can help. if I can clarify any part of that I will be happy to.
Thanks
Orionm45

The counter you made will increment for every cycle of the script, increasing when the sensor reads low and decreasing when the sensor reads high. You should have a counter that only changes when the sensor detects something. You might have to add a delay after incrementing the counter so that it does not count a single revolution more than one time. Your counter might look something like this:

0
begin

  1 get_position
  512 less_than if

    1 plus

    dup
    20 equals if

      negate
    
    endif

    250 delay #This delay should stop it from counting more than once per revolution

  endif

repeat

Please note that this counter will start at zero and count up to 20, then flip to -20 and increase back to zero. You can use a method like this to command the servo to move one direction when the counter is greater than zero, flip directions when the counter is less than zero, and stop when the counter is equal to zero. Also, you might want to adjust the delay time at the end of this counter to fit your application, depending on the speed of your servo.

I added in some servo commands to the script below as an example. You might have to adjust this code a bit to get it to react exactly how you want, but this should be a good start:

0
begin

  dup
  0 equals if

    6000 0 servo

  else
    dup 
    0 less_than if

      8000 0 servo

    endif

    dup
    0 greater_than if

      4000 0 servo

    endif
  endif

  1 get_position
  512 less_than if

    1 plus

    dup
    20 equals if

      negate
    
      6000 0 servo
      500 delay
    endif

    250 delay #This delay should stop it from counting more than once per revolution

  endif

repeat

The way this code is now, the servo should stay stationary (the counter will be at 0) until the sensor detects something for the first time. You might try adding in some initial criteria to start moving the servo, and you might need to adjust the delays.

If you continue to have trouble, let me know and I will see what I can do.

-Brandon

Thanks again Brandon

Your code go me thinking and this is what I came up with>

2 # No of times the magnet passes the sensor until servo changes direction
begin
dup
while
6300 0 servo # Servo speed
1 get_position # Get position of hall effect sensor
521 less_than
800 delay
if
1 minus # If magnet passes take one away
400 delay
else
endif
600 delay # Delay so only one readings is taken at one time
repeat

drop
2 # No of times the magnet passes the sensor until servo stops
dup
begin
while
5600 0 servo
1 get_position
521 less_than
600 delay
if
1 minus
800 delay
dup
else
dup
endif
repeat
255 delay
6000 0 servo
drop

It starts by turning the servo and keeps checking the sensor. when the magnet passes it takes one away from the number i set at the top and when it reaches 0 it reverses the servo. It puts a number I decide at the top and keeps checking the sensor taking away one each time then stops the servo when 0 is reached.

I would like to know when the servo stalls. can I add a code to stop the servo if the sensor reading does not change for a number of seconds?

Im slowly getting used to making code

Thanks for your help on this

Orionm45

The get_ms command puts a number on the stack that corresponds to the Maestro’s millisecond timer. You could use this to check how long it has been since the sensor has detected something. You should be able to call get_ms when the sensor detects something and then compare the current timer value to that by subtracting them. As an example, I added code to the your script that demonstrates one way that you could do this. Please note that this example script compares the difference of the timer values to 5000, which corresponds to 5 seconds:

get_ms #Adds the start time to the stack
2  # No of times the magnet passes the sensor until servo stops

begin
      dup
      while

        swap  #This sequence calculates the time since the last detection 
        dup  #by subtracting the last detection time from the current time
        get_ms 
        swap 
        minus

        5000 greater_than  #This stops the servo if it has been longer than 5 seconds since the last detection

        if
            6000 0 servo
        else
            6300 0 servo
        endif
        
        swap
        1 get_position 
        521 less_than
        800 delay

        if
            1 minus

            swap  #This sequence will update the timer when a detection occurs
            drop
            get_ms
            swap

            400 delay
        else
        endif
        
        600 delay

    repeat

drop

2 # No of times the magnet passes the sensor until servo stops
dup

begin
    while

        swap  #This sequence calculates the time since the last detection 
        dup  #by subtracting the last detection time from the current time
        get_ms 
        swap 
        minus

        5000 greater_than  #This stops the servo if it has been longer than 5 seconds since the last detection

        if
            6000 0 servo
        else
            5600 0 servo
        endif
    
        swap
        1 get_position
        521 less_than
        600 delay

        if
            1 minus

            swap  # This sequence will update the timer when a detection occurs
            drop
            get_ms
            swap

            800 delay
        else
        endif
   
        dup 
    repeat

255 delay
6000 0 servo
drop
drop

-Brandon

Thanks you so much Brandon. After I run the script and stalled the servo it stopped which is precisely what I needed unfortunate the servo starts again after a few sec. Is there any way to tell it when the servo has stalled and stopped to remain stopped?

After looking at the script again, I noticed that the servo starting again is caused by the Maestro’s millisecond timer rolling over and cycling back to within 5000ms of the value stored when there was a detection. The timer ranges from -32768 to 32767, so it should take a little over a minute to roll over.

There are multiple ways that you could make the servo stop without restarting. I am not sure what your application is, but if you want the servo to stop indefinitely when there has not been a detection, the easiest way would be to add a “quit” command after your command to stop the servo. This will cause the script to stop running, and when you want to restart it, you will need to reset it through the Maestro Control Center or by cycling the power to the Maestro if you are not using the USB interface.

Alternatively, you might try entering a separate loop after you stop the servo and waiting for some input before starting the servo again.

Another solution might be to update the last detection time with get_ms - 10000 when the servo stops. This would prevent an overflow from happening by changing the last detection time, making it lag behind the current time.

-Brandon