The code I am writing has been designed to record the time it takes between a reed switch being turned on, and the next occurrence of the switch being turned on.
During this time, other things are happening.
Generally speaking the switch will turn on and off in a very short space of time, however, I discovered that the Arduino will cycle a few times in the HIGH switch state (anything from 2 - 5 times) which causes a degree of inaccuracy.
void loop() {
reedSwitchState1 = digitalRead(reedSwitch1);
if (reedSwitchState1 == HIGH) {
elapsedtime=((millis()-prevtime));
Serial.println(elapsedtime);
prevtime = millis();
//Wait for the switch to turn off
int i = 1;
while (reedSwitchState1 == HIGH) {
reedSwitchState1 = digitalRead(reedSwitch1);
}
}
//Check other switch states and do stuff...
While this code works, the problem I face is that if the reed switch stays on HIGH or spends a large amount of time on HIGH, other functionality will not work efficiently.
Now the purpose of the switch is to measure the rotation time of a wheel. If the rotation is very slow, the reed switch will be on for a longer period of time and this is where I see an issue.
One solution was to use a beam rather than a reed switch as it would have a lot less "play" and I would likely not have to code in the while loop...
Any suggestions?
It's more reliable if you detect changes in the reed switch state, rather than just monitoring when it goes high or low. Something like this:
- Store the old state of the reed switch in a variable.
- Test the state and compare the current state with the old state.
- If the old state is low, and the new state is high, do whatever you need to do etc. Otherwise do nothing.
- Upate the old state variable and go back to the start of the loop.
Here is a site that has an explanation and code example for what GypsumFantastic is talking about. Tutorial_ButtonStateChange
The code I am writing has been designed to record the time it takes between a reed switch turning on and the next occurrence of the switch turning on.
In addition to this, there are other tasks that are being tested via some push button / potentiometer events.
Generally speaking the switch will turn on and off in a short space of time, however, I have included a while loop to cater for the mechanical delay when switching between the on and off state.
Here's the code:
void loop() {
reedSwitchState1 = digitalRead(reedSwitch1);
if (reedSwitchState1 == HIGH) {
elapsedtime=((millis()-prevtime));
Serial.println(elapsedtime);
prevtime = millis();
//Wait for the switch to turn off
while (reedSwitchState1 == HIGH) {
reedSwitchState1 = digitalRead(reedSwitch1);
}
}
//Do other stuff...
Now this code works, however, if the switch stays on HIGH for a longer period of time, other tasks will be missed...
Essentially I am attaching a magnet and the switch onto anything that can turn or move (up and down) the idea being to time the revolution or movement. If the movement is very slow, this is where that while loop will cause issues since the reed switch will stay on for a longer time period.
So my question:
- Should I consider using a different type of switch?
- Can I improve the code?
Many thanks!
I don't know what you posted in the other post, but this post leads me to believe you are using TOO strong of a magnet. In other words, the magnetic field of the magnet is covering a great area and this is being reflected in the reed switch closure.
Paul
The title here (reed switch 'noise') suggests that this is a debounce problem, which hasn't been addressed in the other answers. Any mechanical switch can/will go through several transitions each time it is switched (i.e. it will 'bounce'), and if the code monitoring it is fast enough, it will record several on/off events when in fact there is only one.
The best way of dealing with debounce is to use interrupts and time the delay between them, but the code for that is beyond a quick answer here because it depends on whatever else the program is doing.
chateaux:
2. Can I improve the code?
Yes definitely.
You don't need the while loop to detect a rising edge. Just sample the state of the switch each time you enter the main loop and compare the present state to the previous state.
For example
currentReedState = digitalRead(reedswitch1);
if ( (currentReedState == HIGH) && (previousReedState == LOW) ) {DoRisingEdgeCode();}
previousReedState = currentReedState;
You can software debounce the digitalRead() results before you do the above comparison if you wish.