Input Hall Effect, Output to Servo

Hey guys, this is my first practical project using arduino or any microcontroller for that matter. My area of expertise is not programming or electrical, so this is very difficult for me.

So i have an old speedometer that used to run a mechanical drive unit. My motorcycle does not have this provision, therefore it has to be converted to electric drive. My plan is to use a hall effect sensor on the brake rotor to sense wheel speed and with simple dimensional analysis convert that to vehicle speed and send that to the servo driving the speedo needle.

I have found the rpm tutorial on the arduino website to be very helpful in configuring the setup to read frequency on the hall sensor. I was able to run the serial monitor on a bench test and read rpm and frequency in Hz. My problem is then using a linear function to convert to speed and output to the servo.

With the way i have it setup in the photo, rotating the wheel does nothing to the servo. The servo just sits at ~0 degrees and pushes against its own gears... In addition, the wheel speed does not change its behavior at all.

Im sure my problem is in the code; im a total beginner with all programming languages.

Please help. I would like to have a functional speedometer. Thanks!

 #include <Servo.h> 

Servo myservo;

// read RPM then output value to servo to display speed on a gauge face
 int half_revolutions = 0;
 int rpm = 0;
 int speed = 0;
 int needleangle = 5;
 unsigned long lastmillis = 0;
 
 void setup(){
 myservo.attach(9);
 Serial.begin(9600); 
 attachInterrupt(0, rpm_fan, FALLING);
 }
 
 void loop(){
 if (millis() - lastmillis == 200){ //Uptade every one second, this will be equal to reading frecuency (Hz).
 detachInterrupt(0);//Disable interrupt when calculating
 rpm = half_revolutions * 60; // Convert frequency to RPM, note: this works for one interruption per full rotation. For two interrups per full rotation use half_revolutions * 30.
 speed = rpm*.068423;  // Convert wheel rotations to theoretical vehicle speed
 needleangle = speed*1.55; // Convert speed to gauge needle angle
 myservo.write(needleangle); // Write value to servo
 Serial.print("RPM =\t"); //print the word "RPM" and tab.
 Serial.print(rpm); // print the rpm value.
 Serial.print("\t Speed =\t"); // print the word "Speed"
 Serial.print(speed); // print speed.
 Serial.print("\t Hz=\t"); //print the word "Hz".
 Serial.println(half_revolutions); //print revolutions per second or Hz. And print new line or enter.
 half_revolutions = 0; // Restart the RPM counter
 lastmillis = millis(); // Uptade lasmillis
 attachInterrupt(0, rpm_fan, FALLING); //enable interrupt
  }
 }
 // this code will be executed every time the interrupt 0 (pin2) gets low.
 void rpm_fan(){
  half_revolutions++;
 }

rpm_1working.ino (1.47 KB)

If you ever miss the millisecond where the elapsed time is 200 you won't trigger again for over a month. You should change "== 200" to ">= 200". You should also change the comment that says that 200 mS is one second.

Ok great. I made the changes. Thank you for the tips John.

Is there any way using an interrupt can interfere with the way the servo should function?

In the past i tried this project using an adafruit gps, but i could never get it to work as something would cause interference with the function of the servo causing it to respond very erratically. Im worried that the issue might persist here with this setup.

It looks like your code is broadly correct.

Don't detach interrupts - that is not necessary for doing calculations.

And add the word volatile here

volatile int half_revolutions = 0;

I'm not sure this will work

needleangle = speed*1.55;

because needleangle is an integer.

Try needleangle * 3 / 2 or needleangle * 30 / 19

But be careful that needleangle * 3 (and especially * 30) will fit in an int. Perhaps use an unsigned long.

What happens if you simply make needleangle = 90; immediately before servo.write()

...R

...R

Hey Robin, thanks for the corrections. I tried needleangle = 90; and it writes to 90 degrees just fine. Then i tried simply saying needleangle = 1 + speed*3/2 and now the servo is not trying to commit suicide. The needleangle function past 0 rpm is not yet verified.

I was finally able to take the laptop out to the garage and check hall input to verify function was similar to the bench tests i conducted using the magnet mounted to a drill. Unfortunately no. Serial monitor show 0 rpm and frequency across the board, im assuming my hall sensor's minimum frequency is greater than how fast i can turn the front wheel by hand; about 60 rpm. Im not quite sure how to test this. I cant hold my laptop while i ride down the street... :frowning: Its too bad there isnt an integrated datalogger on the uno.

Additionally i checked the output of the hall sensor using a multimeter. With the 5v supply voltage to the hall sensor, i yield .35 volts and when triggered it falls to around .05 volts. Under these conditions, FALLING is the correct trigger mode for the interrupt?

Ah. Your hall effect is not working quite the way you should have it.

I suspect your hall effect device is quite a good expensive hall effect sensor which can accurately detect the strength of a magnetic field, whereas what would be more useful would be a hall effect switch like this one.

Whilst it has to be very precisely located, so that it does trigger (you have a 1 to 3 mm tolerance for location) it either does 0 or 5V.

I completely agree with you that a switch would have probably been much easier to setup. On the other hand the aging roads of california provide some pretty rough conditions sometimes. I need something to be very secure and reliable considering the amount of vibrations this mounting location will experience.

I will look up the specifications of my sensor to determine what the correct output looks like.

If you stick with your sensor you could amplify it. You will then have to check it provides the correct output.

I built a similar system for a model boat tacho using picaxe.

There may be an idea in it for you.

Alas you can't see the pictures of your sensor board without having an account.

O joy. I just confirmed my hall effect sensor is dead. Now the magnetic field produces absolutely no change in voltage. Time to return it.

Well, i will return when i have a working sensor. Thanks for all the help guys, im really feeling like my code is damn near working.

O joy. I just confirmed my hall effect sensor is dead. Now the magnetic field produces absolutely no change in voltage. Time to return it.

What type is your hall sensor? It may need a pull-up resistor to produce a proper signal.

roachdogg28:
I tried

needleangle = 90;

and it writes to 90 degrees just fine. Then i tried simply saying

needleangle = 1 + speed*3/2

and now the servo is not trying to commit suicide.

That proves very neatly that the problem lies with the value calculated for needleangle.

Though I see from subsequent posts that you may have other problems - which may or may not be to blame for needleangle being incorrect.

It would be wise to add a couple of lines to set min and max values for needleangle that are within the range of servo movement you want.

...R

PS - sorry the layout of this post is crap but I'm leaving it as an example for a complaint I want to make in the Website section of the Forum.

Sorry about that......here are a couple of images.

Note that I now use the Allegro A1120 hall effect.

Bluejets, am I right in thinking that your hall effect is a hall effect switch rather than sensor?

ChilliTronix:
Bluejets, am I right in thinking that your hall effect is a hall effect switch rather than sensor?

The tacho has gone through a couple of changes since the original.

When I started, the only hall effect I could get was the UGN3503 which is a sensor, not a switch. To overcome this I connected it using an LM311 comparator. This then fed the LM2917 frequency to voltage converter which originally drove a series of LEDs in a circular pattern around the tacho readout.

Picaxe then came along and i was looking for an alternative, more realistic unit.

Rather than change everything, I decided to retain the above and use the 0-5V and drive a servo which has a gear driven output to give me 270 degree needle travel.

Nowadays I tend to stick with the allegro 1120 which is a switch.

A schematic of the sensor drive may be useful to the OP.

I'll see what I can find but unfortunately we had a massive flood here 2 years ago (biggest in recorded history) and all my records on file went with the dirty water.

Wonders will never cease.
I managed to find a write-up I did of the final arrangement.

Bear in mind the system was originally driving a row of LEDs and then converted to picaxe micro.

It is more than likely the whole process can be done with just the picaxe and different programming.

Might give the OP some ideas though.

Doc contains 2 programs. The first was the final version to run the tacho.

The second was used to calibrate the servo travel to the signal. Long time ago, forgot what I did actually.

Miniature Tacho.doc (52.5 KB)

The important bit for the OP is the amplifier for the Hall effect sensor. I could not see that on a quick scan.