Pages: [1]   Go Down
Author Topic: Reed Switch Frequency  (Read 223 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am developing a tachometer with a reed switch for a bicycle roller using an UNO. If I ride 30 MPH on my bike, the roller will spin at ~50 Hz. Right now I am counting the number of revolutions and printing that number using println(). I ran some tests and the output did not seem to keep up with the speed of the roller. Doing some basic testing, I determined how long it took me to reach 1000 counts going 15MPH and 30 MPH, both were equal in time suggesting that the counter was not picking up each revolution. Is this a hardware or a software issue?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12428
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please post your code (between apropiate tage # button) and we can check if it is a software problem.

If not SWP it is a HWP.

Doing reliable RPM measurements often require an interrupt based approach.

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int LED = 13;     //pin for the LED
int SWITCH[] = {7,8,9};   //input for REED SWITCH
int pinset = 0;
int count[] = {0,0,0};
int val[] = {0,0,0};
int ckstatus[] = {0,0,0}; //The status of the previous iteration of each channel
int check = 0;
int dread = 0;


void setup() {
  pinMode(LED, OUTPUT);   //tell arduino LED is an output
  for (pinset=0; pinset < 8; pinset++){
  pinMode(SWITCH[pinset], INPUT);
  }
  Serial.begin(9600);
 
}

void loop(){
  if (digitalRead(3)==HIGH){
    count[0]=0;
    count[1]=0;
    count[2]=0;
  }
  for (dread=0;dread<3;dread++){
  val[dread]=digitalRead(SWITCH[dread]);
  }  //read input value and store it
  //check whether input is HIGH (switch closed)
 
  // if the switch was closed last time, then dont count it. if it was open, then count it
  for (check=0;check<3;check++){
    if (val[check]==HIGH) {
      if (ckstatus[check]==0){
      count[check]++;
      ckstatus[check]=1;
    }
      //digitalWrite(LED, HIGH);   //turn LED on
    } else{
      ckstatus[check]=0;
      //digitalWrite(LED, LOW);
          }
  }
 

  Serial.println(count[2]);
  delay(1);
}
Logged

Copenhagen, Denmark
Offline Offline
Edison Member
*
Karma: 25
Posts: 1133
Have you testrun your INO file today?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You have 3 switch inputs and you only print the count of one of them - what is the reasoning behind that? Are the 3 reeds measuring independently or the same axel just offset or ...?

What does the digitalRead(3) hook up to?

How is each reed connected. You do not do any software debounce, so presumably you have som in your input circuit. Send a diagram (handdrawn and mobilphone captured ok, but a proper schematic f.ex. Fritzing would be better)
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24317
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd used a Hall-effect instead of a reed.
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I simplified the project when I noticed the timing issue. In its final form, I will have 8 reed switches counting the revolutions of 8 different user rollers. I started out with three reed switches to test the idea, which is why you see the array of three switches.
digitalread(3) is a reset button. for now i am using another reed switch to reset the counter.
  


* Uno-reed-1.JPG (112.99 KB, 827x702 - viewed 14 times.)
Logged

NSW Australia
Offline Offline
Edison Member
*
Karma: 33
Posts: 2307
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I usually counsel against using interrupts unless you need to respond to something fast, and revolutions of a bicycle wheel is anything but fast in computer terms.

The problem here though is that you have a loop with two delays in it.

Code:
  Serial.println(count[2]);
  delay(1);

You cannot put delays in counting code because you are not counting while you perform the delay.  Either you decide to count for a certain period and then (stop counting while you) display the result, or you will need to use interrupts - for both counting the events and determining the counting "window", which gets much more complex.

With reed switches, you will need to consider debouncing in order to actually do the counting - of course, the present limitation has restricted you from seeing such errors.
Logged

Saskatchewan, Canada
Offline Offline
Edison Member
*
Karma: 32
Posts: 1174
Coding Geezer
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Not sure what you mean by a "roller", but if you want to measure speed of the bike, I would first suggest hall-effect sensors.

Second, I would forget the frequency and the idea of counting pulses.

Assume you have a wheel that has a diameter of 24 inches, including the tire. Every revolution of the wheel will mean that the bike travelled about 75 inches. If you count the spokes on one side of your wheel, you can get accurate spacing of multiple magnets attached to spokes that are an evenly divisible number of spoke apart. For example, if you have 40 spokes, you could easily space magnets at 5 or , 8, 10 spoke distances, giving you 8, 5, or 4 pulses per revolution, respectively. Then you only need one sensor, and instead of counting pulses, you count the time between pulses. From that, you can calculate the speed of the rim of the wheel every time a pulse arrives, and from that, you calculate the speed in MPH, KmH, or Furlongs per Fortnight. If you only resume looking for another pulse after say, 10ms, you do not even need to debounce (assuming you stick with reed switches).
Logged

Helsingborg, Sweden
Offline Offline
Sr. Member
****
Karma: 23
Posts: 498
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I suppose you are building some Bike-roller competition or similar. Nice idea.
For the sensors i would go for all sensors or optical for reasons stated by others before me (frequency and debouncing).

Here is some code to count on 8 channels simultaneously. It uses my state machine libraryfound here:
http://playground.arduino.cc/Code/SMlib

Please observe that all code you add to this MUST be non-blocking.

Code:
#include <SM.h>

SM Counter8(Reset, Count);

int OngoingCount[8];
int SignalState[8];
int FinishedCount[8];
const int FirstChannel = 2;
const int Period = 1000;

void setup(){}//setup()

void loop(){
  EXEC(Counter8);
}//loop()

State Reset(){
  for(int i = 0; i<8; i++){//all channels
    FinishedCount[i] = OngoingCount[i];//save all channels
    OngoingCount[i] = 0;//reset all channels
  }//for(i)
}//Reset()

State Count(){
  for(int i = 0; i<8; i++){//all channels
    SignalState[i] = (SignalState[i]<<1)|digitalRead(FirstChannel + i)&3;//detect raising edge on channel i
    if(SignalState[i] == 1) OngoingCount[i]++;//edge detected, increase channel counter
  }//for(i)
  if(Counter8.Timeout(Period)) Counter8.Set(Reset, Count);
}//Count()
Logged

Pages: [1]   Go Up
Jump to: