I am kind of new to programming here and am working on creating a seven segment display speedometer with a reed switch. So far I have successfully connected the seven segment displays and run them.
I know the reed switch is registering the magnet since the led I attached to the other end lights up when i pass a magnet.
The problem is when I upload my code to the Arduino Mega it keeps freezing and wont return any values. Below is my code.
int i = 0;
int rps = 0;
void setup(){
pinMode(0, INPUT);
Serial.begin(9600);
}
void reed(){ //determines if magnet is passing by the reedswitch
if (analogRead(0) >= 400){ //value is 400 because LED
rps = rps + 1; //is drawing power
delay(50); //delay so the arduino doesnt double count
i + 1;
chk();
}
else {
rps = rps + 0; //tried to replicate above so time is the same
delay(50);
i + 1;
chk();
}
}
void chk(){ //determines if the wait for values is over
if (i < 500){
reed();
}
else{
Serial.println(i); //writes the rounds per 500 cycles
loop();
}
}
void loop(){
geschchk();
}
void geschchk(){ //resets values and starts reed program
i = 0;
rps = 0;
reed();
}
I tried using the millis(); function earlier, but my Arduino froze after printing 2 values.
unsigned long time;
int rps = 0;
void setup(){
pinMode(0, INPUT);
Serial.begin(9600);
}
void reed(){
if (analogRead(0) >= 400){ //determies if magnet is present
rps = rps + 1; //used 400 instesd of 1023 becuase of LED
delay(50); //prevents double counting
chk();
}
else{
chk();
}
}
void chk(){ //determies if time has passed
if (millis() < time + 500){
reed();
}
else loop();
}
void loop(){
Serial.println(rps); //prints rounds per half a second
geschchk();
}
void geschchk(){ //stores values
time = millis();
rps = 0;
reed();
}
I almost forgot, I also had another version which worked with the millis() function, but it always returned different values and was very laggy. here is a link to the code running : http://ubuntuone.com/p/DHr/
Thank you so much Marsheng, with the code you gave me, I was able to finish my speedometer, now I just have to implement the calculator to change the rounds per 500ms to km/hr, but that should be easy.
In case anyone is wondering, below is a link to my working code. FYI the 7 Segments I was using were common anode, so if you are using common cathode 7 segments, then you will have to change all the HIGH values to LOW and vice versa. Feel free to use my code even though it may not be the best.
The speedometer is not accurate when going slow ex. less than 1 round per half-second. if you wish, you could add a second magnet to your wheel if you are making this for a bike, or increase the wait time to one or two seconds, but then the refresh rate will be lower. If this is for a car, i think it is fine the way it is.
I will post an updated version of this code with a button to change from km/h to mph (pushbutton).
Thank you again for the suggestion on how to determine the speed, but I think I will just have the seven segments display the rps and drive at a constant speed of 45mph and then find the conversion factor.
Unfortunately, when I was driving today, the 7 segments were displaying random numbers ranging from 7 to 0 to 188. Later I disconnected the seven segment displays and just wrote the following code to test if the reedswitch was even registering.
This only returned random values around 463 whether or not the magnet was near the reedswitch (no resistor attached, so it should have been 1023). Even when I ran a wire directly from the 5v to analog in 0 pin, the values would not change, they just floated around 400 - 500. Meanwhile the serial monitor was still updating. Any ideas?
Afterward I re-uploaded the code and it worked, but when I installed the arduino in the car again, the same thing happened again with the random analogRead values. Sometimes it works, and sometimes it doesn't. Is something in my arduino broken?
I was driving and it registered a pass since it was displaying a one, but when I reset it, it wouldn't register anything. (sorry about the Blair Whitch project style filming, I had to shift). I believe I was using the statement while (analogRead(0) >= 900 ...... If I use 600 it might work now, but when I turn the arduino off and back on again, it might be hovering around 600 again and not work anymore.
to the setup and it sort of helped. The thing is that I believe the program is adding 1 to rps more than once per cycle, but I cant figure out why.
void reed(){
while (analogRead(0) >= 1000){} //Checked ob ein magnet orbei ist. determies if magnet is present
rps = rps + 1;
while(analogRead(0) < 1000){}
chk();
}
Doesnt the above code prevent it from double counting?
When I just drove it gave me ridiculous values of how many times the magnet passed in one second. It said it passed like 70 times when I was driving a mere 10 miles per hour. On top of that it sometimes seems to be working, but then randomly spikes to high numbers.
I tried recording the analogRead values with the analogReference(DEFAULT) and it was hovering around 900 and 1023.
Thank you again for helping out so much.
Below is a printout of the values it hovers at while driving.
I am pulling the input low when the switch is open without a resistor. But you may be right, the values could be so strange due to the noise. I do have the arduino under the driver side dash where all the electronics are. Maybe the electronics are interfering with the arduino or reed switch cable. When I last tested it without any problems, I had the arduino in the passenger glove compartment. Ill try relocating it and see what happens.
As for the engine noise, I have placed the reed switch on the rear right tire, so I dont believe that should pose any problems.
The reason why I am using analogRead instead of digitalRead is because I couldnt get the digitalRead to work correctly. Otherwise I would have used the pulseIn function which would have been so much easier. Theoretically do you think the pulseIn function could work even though the reed switch is changing from HIGH to LOW so fast?
I have no idea, that might be a possibility, but it was working before, so I dont think that is the case here. If I were to find out if that were the case, how would I go about doing that?
I just ran a jumper cable from the 5v to the analog input 0 and when I connect the two, it goes to 1023, but when I disconnect them, it slowly counts down until it reaches a smaller number. This is with a 50ms delay. Is this normal?
Correct me if I am wrong, but does the below code add one to rps once & only once, when analogRead is greater than 1000 and then wait till analogRead is less than 1000 to initiate chk();?
void reed(){
while (analogRead(0) >= 1000){} //Checked ob ein magnet orbei ist. determies if magnet is present
rps = rps + 1;
while(analogRead(0) < 1000){}
chk();
}
because it seems like it is adding 1 to rps multiple times and I have no idea why. If the code is not doing what I stated above, what would I have to do to get it to do that?
This is what you need to start with. The micro switch should switch to ground so if there is a problem with the wring, you dont blow the 5 volt supply.