Honda Twins banner

1 - 11 of 11 Posts

·
Registered
Joined
·
161 Posts
Discussion Starter #1
So, I have a broken CB450 k0 speedometer/tach gauge. The speedometer works fine, however the tachometer malfunctioned while in use and was destroyed. The only remaining usable part is the bar magnet (in a metal drum) attached to the tachometer gear box frame that the tachometer cable connects too. The entire gear box can be easily replaced, however finding a functioning one for a reasonable price isn’t as easy.

What I figured I would try to do is build an electric tachometers that still looks stock. I would achieve this by using a small stepper motor (really small) to drive the tachometer needle. The stepper motor will be attached to a small Arduino microprocessor, and the microprocessor will be reading the rpm by using a Hall effect sensor to record the number of turned per minute of the bar magnet (or RPM).

If you do not know what a Hall effect sensor is, it’s a small semiconductor device that acts like a switch. However, this switch is only activated when a magnet is placed in front of it. Since old vintage speedometers/tachometers work by spinning a magnet really fast the Hall effect sensor can trigger its internal “switch” every time the magnet passes it. Since a bar magnet has two ends, Then the end of the speedometer/tachometer bar magnet will pass the Hall effect sensor twice per revolution (once when the front side passes and once when the back side passes). A small Arduino computer can record the number of times the “switch” is triggered per minute, divide that by 2, and rotate an attached stepper motor to the correct angle on the gauge.

To test if this would work I bought a pack of 5 cheap A3144 Hall effect sensors from eBay for around a buck. Once I received them I connected the circuit and attached a small LED that lights up every time the “switch” in the Hall effect sensor is triggered. I wasn’t sure if the magnet in the CB450 K0 tachometer would be strong enough to trigger the sensor. But, to my surprise this seems to work and be possible.

Here’s a video of my test set up. Sorry for the scotch tape all over the gear box. The bar magnet spindle broke loose when the tachometer was destroyed. I taped it Back in place to allow for easier testing.


Please let me know what you think!

-Isais
 

·
Registered
Joined
·
125 Posts
Cool! I was actually thinking of something like this myself for my 450 nighthawk since my tach is acting weird. My idea was to use a hall effect sensor and arduino like yours, but instead of a stepper motor to turn the needle I was thinking of using something like an analog voltage needle being driven by PWM from the arduino.
 

·
Registered
Joined
·
161 Posts
Discussion Starter #3
Cool! I was actually thinking of something like this myself for my 450 nighthawk since my tach is acting weird. My idea was to use a hall effect sensor and arduino like yours, but instead of a stepper motor to turn the needle I was thinking of using something like an analog voltage needle being driven by PWM from the arduino.
I like your idea. Here’s a video I found on YouTube with someone using your method. Looks interesting.

Would you have to replace the entire tachometer or would you take the tachometer apart and migrate the parts over?

I already ordered the parts for the stepper motor method so I’ll give that a try first. Im going to be using this automotive stepper motor.
https://www.adafruit.com/product/2424
You can find it on eBay for $2 (free shipping). It’s the same one that GMC uses on their trucks.
 

·
Registered
Joined
·
315 Posts
Interesting concept. Where would you put the arduino--will it fit inside the tach housing? Have you considered using a VSS sensor instead of a hall-effect? In any case, keep up the experimenting--it looks promising.
 

·
Registered
Joined
·
125 Posts
Would you have to replace the entire tachometer or would you take the tachometer apart and migrate the parts over?.
Take it apart and shove the electronics inside. I like the stock look.

Interesting concept. Where would you put the arduino--will it fit inside the tach housing? Have you considered using a VSS sensor instead of a hall-effect? In any case, keep up the experimenting--it looks promising.
They make tiny arduinos that would fit pretty easily. I think a hall effect sensor works best in this case since the stock tach already has a rotating magnet assembly inside it.
 

·
Registered
Joined
·
161 Posts
Discussion Starter #6 (Edited)
So, here’s an update on this project.

The parts have all came in.

1 arduino tiny
1 a3144 Hall effect sensor
1 10k resistor
1 x27.168 “stepper” motor

I spent the last 2 days working on this. About 16 hours total.

Day 1 was dedicated to figuring out how to connect the parts together without releasing the magic smoke. I’ve accidentally let the magic smoke out before, and once the smoke has left it’s hard to get it back inside. I found an arduino sketch for counting RPMs from a Hall effect sensor that worked out pretty well. The sketch had problems where after a certain amount of data gathering it spits out bad calculations and then correct itself for a brief period of time. This was ok for now. I can always delve deeper into the code later to see where the errors where happening. I then found several arduino sketches for controlling stepper motors using the arduino directly with no additional components. The sketch somewhat worked. The rpms where counted and sent to the motor. And the motor moved. However, I had no actual control of the motor movement. This was a good start, but I had much much more reading to do before continuing forward.

Day 2. I discovered Guy Carpenters arduino library for the X25 motor (the x27’s sister motor). I decided to give that a shot using the example sketch Guy provided for basic motion. This worked Great! Now I had very accurate control of the motor in this very basic example. Now to implement it into the bigger picture. After several hours of testing I was still getting nowhere in the big picture plan. I discovered I was having problems with controlling the motor when the arduino code containing While() loops in the main loop program. In the end this turned out to be a very easy fix, but I wasn’t going to figure that out till the following day. For now I had a sketch that successfully captured the rpm of a spinning magnet, then delivered that information to a “stepper” motor, and a motor that turned to a desired value. However, the motor turned extremely slow. It was pretty much an unusable tachometer at this point. I figured that maybe the latency was due to the code being too demanding. So I spent the rest of the day making cuts and edits where I could. Fixing the accuracy issues with the rpm calculations. And in the end there was SOME improvement, but I still had an unusable tachometer on my hands. I went to bed at this point thinking about how the motor.update function works and how it needs to be implemented. Guy has a small note about it at the top of his example sketch and I couldn’t get what he said out of my mind. “Call motor.update as much as possible.”

Day 3. I woke up with the answer!! I don’t know how it came to me, but in my half asleep morning daze the entire function of the tachometer code seemed clear to me. The motor.update() code was running in the main loop. However, when the program went into the While() loop it ignored the main loop code till it was done. With the way I wrote my code I noticed the sketch is spending more time inside the While() loop (where I DO NOT call motor.update) than in the main loop (where I DO call the motor.update). The answer was simple! Add motor.update inside the While() loop.... and ta-da! IT’S ALIVE.

I still have some more programming too do. Ad a go-to-zero-marker when no rpms are received. Adjust the movement to accurately read on a CB450K0 tachometer scale (right now I have it maxing out at 180 degrees since the k0 tach only travels about 180 degrees).

One piece of information that I do need to look up to finish this project is, what is the gearing ratio for the CB450k0 tachometer? In other words, how many spins of the tachometer cable is equal to 1000rpm. I need this ratio to give an accurate reading on the dial. I’m sure it’s in the shop manual somewhere.

Well, thanks for reading and following along
-Isaias


 

·
Registered
Joined
·
161 Posts
Discussion Starter #7 (Edited)
I received a request on YouTube to share my code. I figured this would eventually happen as when I was looking for functioning code myself I kept finding videos of people who succeeded, but didn't share how they did it. My video above is pretty much the equivalent of those videos. Success, but no information as too how. I was hoping to have this completed and the code posted here before the first request came. But I'll post what I have so far to assist anyone that finds themselves needing the information.

While I'm at it, I'll post an update as too where I'm at with this project.

This project is more for fun, and too see if I can actually accomplish this. I've seen people use these gauges to build functioning instrument panels for vintage museum aircrafts, video game driving/flying simulators, RC aircraft's to display RPM, Velocity, and pitch. In each of those cases the gauge is installed in a panel that is not subject to vibrations. In my case the gauge will be stressed by the vibrations of an Old vintage motorcycle. If I'm successful with this gauge rebuild I do plan to run it on the motorcycle out of curiosity. I don't plan on it lasting very long but I will be pleasantly surprised if it does.

Here are some pictures of where I'm currently at..

soldering the wires to the motor
IMG_3639.jpg

running the wires through the 3d printed mounts
IMG_3640.jpg

The Hall effect holder, with internal channel for wire routing
IMG_3641.jpg

test fitting the pieces outside the tach frame
IMG_3645.jpg

The tachometer frame with the bar magnet shield in place.
IMG_3648.jpg

Cutting off the shield to allow room for the 3d printed parts
IMG_3649.jpg

All the parts mounted together
IMG_3653.jpg IMG_3652.jpg

Test fitting in the speedometer housing
IMG_3650.jpg IMG_3651.jpg

Materials you will need:

1 - Arduino
1 - X25 or X27 stepper motor
1 - 10k resistor (to be placed on arduino between pin-2 and vin to keep pin from bouncing)
1 - A1344 hall effect sensor
various lengths of wires and a method to mount the devices for your application.
(NOTE: WHEN USING GUY CARPENTERS LIBRARY NO H-BRIDGE DRIVER IS NEEDED. THE MOTOR IS DRIVEN DIRECTLY
FROM THE ARDUINO)

I will also be adding a L805CV voltage regulator to protect the board from electrical power spikes created by the motorcycle.
(The CB450 runs on 12V of power, and the arduino has been approved for 12V applications. However, I worry that the small
voltage regulator on the arduino board will not be strong enough to withstand a voltage spike from a motorcycle. The L805CV
can withstand a voltage spike of 35Volts and 2Amps and if much more likely to survive such a scenario while at the same time
lowering the voltage to 5Volts)

As for the Code:

The wiring for the X25.168 or X27.168 stepper motor
Switec pinout.jpg

Guy Carpenters X25/X27 motor library that needs to be loaded onto your Arduino IDU to control the motor
View attachment SwitecX25-master.zip

A link explaining how to load a .zip library to your Arduino IDU
https://www.arduino.cc/en/guide/libraries
"https://www.arduino.cc/en/guide/libraries"

The CODE, with TONES of notes to help anyone that finds this useful. Please note that I am currently still working on the final pieces of the code to give the correct angle for each reading of RPM's. A final simple piece. But since this code was requested I'm sharing it here in it currently unfinished, but functioning, form.

************************************************************************************
*************COPY EVERYTHING BETWEEN THE ASTERISK'S INTO YOUR ARDUINO IDU*************
************************************************************************************

//----------------------------------------------------------------------
// https://github.com/clearwater/SwitecX25
//
// This is an example of using the SwitchX25 library.
//
// This code has been rewriten from Guy Carpenters X25 example to
// function as a Tachometer for a CB450 K0 Motorcycle (Tach
// gearing ratio of 1:7)
//
// Note that the maximum speed of the motor will be determined
// by how frequently you call update(). If you put a big slow
// serial.println() call in the loop below, the motor will move
// very slowly!
//----------------------------------------------------------------------

// Guy Carpenters X25 library
#include <SwitecX25.h>

// standard X25.168 & X27.168 range 315 degrees at 1/3 degree steps
#define STEPS (315*3) //totaling 945 steps to complete 315 degrees of rotation

// For motors connected to digital pins 4,5,6,7 (on X25 & X27 pin 1-> pin4, pin 2-> pin5, pin3 -> pin6, pin4 -> pin7)
SwitecX25 motor1(STEPS,4,5,6,7);

// digital pin 2 is the hall effect sensor input pin (AT ARDUINO, ADD A 10K RESISTOR BETWEEN PIN 2 AND VIN TO KEEP PIN FROM 'BOUNCING'!!!!)
int hall_pin = 2;

// pick number of rotations to analyze to determin rpm (higher improves accuracy)
float rotations = 1.0;

// Time program has spent in "While" loop per half rotation of tach cable
float WhileTime2;

// each rotation trips hall effect 2 times due to each half of bar magnet triping hall effect sensor once
// correct number of trips per rotation.
float hall_thresh = (rotations*2);

// tach cables rpm result
float rpm_val;

// to mark the first turn of tach cable. due to no previous recording for position of magnet.
int first_run;

// used to record previous state of hall effect sensor
int previous_hall_pin_state;



void setup(void)
{
// run the motor against the stops at start up
motor1.zero();
// start moving towards the 0 value (for my wiring and tach gauge 0 value is at positon 945)
// changing the wiring may change the 0 position to postion 0. If wiring is changed code will need to be updated.
motor1.setPosition(944);

// Mark that first turn of tach cable has NOT happened yet
first_run = 0;

// make the hall pin an input:
pinMode(hall_pin, INPUT);

// initialize serial communication at 9600 bits per second:
// Serial.begin(9600);
}


void loop(void)
{

// nextPos will be the value where the needle will be moved too
// setting nextPos to 0 at begining of loop does not move the motor, it only clears the value to
// prepare it for its new value
static int nextPos = 0;
// the motor only moves when you call update. It will pull the value from the last motor1.setPosition()
// value in your code
motor1.update();

// preallocate values for tach (clear values at begining of new loop for new data and calculations)

// rotations equal 0
float hall_count = 0.0;
// start timer
float start = micros();
// while loop timer
WhileTime2 = 0;
// Marks current status of hall effect sensor (0=ON, 1=OFF)
// NOTE: THIS WAS USED ON THE EARLY DESIGN OF THE CODE. THE CODE HAS CHANGED SINCE THEN, AND
// I AM UNSURE IF THIS MARKER IS STILL NEEDED. WILL LOOK INTO LATER
int on_state = 0;

// counting number of times the hall sensor is tripped
// While code is in "While loop" code in main loop is paused. be sure to include "motorl.update()"
// In "While" loop to keep motor running smoothly

// run "While" loop as long as number of sample rotaions entered in "roataions" above have not been meet
while(hall_count < hall_thresh){ //remember hall_count = 2*rotations

// continue to update motor position even when code is stuck in while loop
motor1.update();

// The amount of time needed for 100rpm reading (used to send needle to 0rpm when readings under 100rpm are received
// or no data is received and time threshold for 100rpm has been exceded for Honda CB450)
// Value is in Micro-Seconds
float hund_rpm_time = ((30000000/10)*hall_thresh);

// The amount of time program has spent in "While" loop for each loop in the "While" loop
WhileTime2 = micros()-start;

// If time in 1 pass through a "While" loop exceeds time for 100rpm minimum
// then begin to send needle to 0rpm position
// NOTE: INCREASE THE "14" FOR FASTER NEEDLE RESPONSE. I'LL LOOK INTO THIS PART OF THE CODE FURTHER IN THE
// FUTURE TO SEE IF THIS EFFECTS ACCURACY
if (WhileTime2 > (hund_rpm_time/14)){
//Sends motor to position 944 (0 rpms for this code)
motor1.setPosition(944);
}

// if magnet is triggering hall effect sensor then...
if (digitalRead(hall_pin)==0){ // hall effect Sending signal (hall_pin = 0)

// if first_run = 0 then the Tach cable has not turned yet. Thus, during previous drive Tach magnet came to rest next
// to hall effect sensor once engine was turned off. reading is false.
if (first_run = 0){
// mark hall effect sensor as previously on (previous_hall_pin_state = 0)
previous_hall_pin_state = 0;
// mark first_run = 1 so this section of code only runs at the very first turn of tach cable only
first_run = 1;

// incriment tach cable rotation value by 1/2 (remember that 2 counts are equal to 1 rotation of the cable)
// TECHNICALLY THE CABLE HAS NOT TURNED AT ALL. INCIMENTING MAY NOT BE NEEDED HERE. HOWEVER, IF INCIMENTING
// HERE IS PRODUCING A FALSE VALUE IT IS ONLY FOR THE 1ST VALUE AND THEN IGNORED. ARITHMETIC ERROR IS UN-NOTICABLE
hall_count+=1.0;
}

/// if hall effect sensor is on now and was previoulsy off then...
if (digitalRead(hall_pin)==0 && previous_hall_pin_state==1){

/// if on_state is equal to 0 (ON) then set on_state equal to 1 (OFF) to prepare for next pass,
// increase hall_count, change previous_hall_pin_state=0 (ON)
if (on_state==0){
on_state = 1;
hall_count+=1.0;
previous_hall_pin_state = 0;
}
}

// if hall_pin = 1, magnet is NOT triggering hall effect sensor then...
} else{

// if you reach this point in code and still first_run = 0
// then Tach cable has not turned yet. And you know that the end of the Tach bar magnet
// did NOT come to rest next to hall effect sensor when engine was last turned off
// mark hall effect sensor as previously off (previous_hall_pin_state = 1)
if (first_run = 0){
previous_hall_pin_state = 1;
// mark first_run = 1 so this section of code only runs at the very first turn of tach cable only
first_run = 1;
}

// if hall effect sensor is off now and was previoulsy on then...
if (digitalRead(hall_pin)==1 && previous_hall_pin_state==0){

//set on_state = 0 (set marker to ON) to prepare for next time hall_pin=0 (ON)
on_state = 0;
// change previous_hall_pin_state=1 (OFF)
previous_hall_pin_state = 1;
}
}

// if number of data gathering cable rotations have been met then exit "while" loop
// and begin doing RPM calculations
if (hall_count>hall_thresh){
break;
}

//continue to update motor position even when code is stuck in while loop
motor1.update();
}

// record current time to compare to start time
float end_time = micros();

// calculate how much time has passed in seconds (dividing microseconds by 1 million gives you seconds)
float time_passed = ((end_time-start)/1000000.0);

// calculate rpm value (hall sensor is tripped twice per rotation, so divide hall_count in half to get
// number of rotations. then divide by the amount of time that passed to get rotations per second.
// multiply by 60 to get rotations per minute
rpm_val = ((hall_count/2)/time_passed)*60.0;

// send value to motor to rotate needle.
// NOTE: CB450 TACH GEARING IS 1:7. SO RPM'S WILL BE (1/7)OF THE MOTORS ACTUAL RPM's

// (for values greater than 1571) situation where tachometer has reached its max amount (Motorcycle about to EXPLODE!)
if(rpm_val > 1571){ //CB450 K0 tach max at 11000rpm (tach ratio of 1:7. 11000/7=1571)
nextPos = 472; // turn gage about 180 deg (X27 turns 945 steps. 945/2=472). (ACTUAL ANGLE FOR CB450 IS SLIGHLTY LESS. WILL WORK OUT LATER)
motor1.setPosition(nextPos); // call needle to rotate to given potition
nextPos = 0; // clear nextPos value to zero for next calculation

//send value to motor to rotate needle (for values between 0 and 1571, between 0 and 11000 rpm)
}else if(rpm_val >= 0 && rpm_val <= 1571){

// nextPos represents "motor potition" or steps. Since 944 is our zero we will work backwards by subtracting he the steps from our zero mark (944).
// first we need to covert our RPM's to steps. Since we are only using 180 degrees of the motor for the CB450 K0 Tach our max steps is 472 (half of 945).
// these 180 degrees will represent a max of 11000 rpms. Since our gearing ratio is 1/7th of the motor that is a max of 11000/7= 1571 rpms of the cable in these 180 degrees.
// so our conversion factor is (472/1571). we multiply our RPM's (rpm_val) by (472/1571) to get the number of steps to subtract from our zero point.
// ..................its not as confusing as I'm explaining. I'm just doing a horrible job.
nextPos = 944-((rpm_val*472)/1571);
motor1.setPosition(nextPos); // call needle to rotate to given potition
nextPos = 0; // clear nextPos value to zero for next calculation

}

}

************************************************************************************
************************************************************************************

-Isaias
 

Attachments

·
Administrator
Joined
·
13,086 Posts
I admire anyone with the time and patience to learn and work with code... a few years back, while I was still busy with computer work on a daily basis, I was almost fascinated enough to try learning a bit about it, but I'm beyond that point now. Nice job, and I hope you can find a way to ensure its reliability - very slick application of modern tech to make part of our vintage stuff functional again. Very cool.
 

·
Registered
Joined
·
161 Posts
Discussion Starter #9
I admire anyone with the time and patience to learn and work with code... a few years back, while I was still busy with computer work on a daily basis, I was almost fascinated enough to try learning a bit about it, but I'm beyond that point now. Nice job, and I hope you can find a way to ensure its reliability - very slick application of modern tech to make part of our vintage stuff functional again. Very cool.
Thanks Tom. Funny thing is I accidentally learned the basics of C language computer code while in college. I was looking for a class that would result in a "easy A" so I could focus my time on classes related to my major. A friend of mine pointed out the "Introduction to Computer Programming" course. He said the first 2 months of the course are spent explaining what a mouse and a keyboard are, LOL!! And I said, that's the course for me. I expected the course to be useless and only function as a method to maintain my GPA, however, I ended up getting much more out of it than I expected. To be honest with you, I enjoyed the course so much that If I had discovered it early on in my College years I may have just changed my major.

All the computer languages have very similar formats. Close enough, that after learning just one semester of beginning C programming I've been able to adapt what I learned to modify and write programs in C++, raspian (raspberry-pi language), groovy (Smart home devices), HTML (webpages), Visual Basic (excel), LISP (AutoCAD), JSON (servers). Nothing of a professional quality, but enough to create something for my work and home use. Even though, I still consider myself to be a complete novice at computer programming. If it wasn't for Google I would have just walked away from it after completing that 1 semester.

-Isaias
 

·
Registered
Joined
·
81 Posts
I'll tell you what Isaias - you are an inspiration. I hope you have kids to pass this onto man. We need more fathers like you bro - seriously. Teach boys how to be men and solve problems!
 

·
Registered
Joined
·
161 Posts
Discussion Starter #11
I'll tell you what Isaias - you are an inspiration. I hope you have kids to pass this onto man. We need more fathers like you bro - seriously. Teach boys how to be men and solve problems!
Thanks for the kinds words Amir. I don't have any kids myself, but I try passing as much as I can onto my nephews. However, their mom's and dad's usually aren't very happy about it because I try to get them on the power tools as early as possible. lol

-Isaias
 
1 - 11 of 11 Posts
Top