SENSING MOVEMENT FROM ROTATION

Im tryin find a sketch that can determine if a machine is moving or not. Seems quite simple but to me Im having problems with debouncing and reseting counters etc. Im new to this stuff.

I have a shaft rotation speed of up to 500rpm and have a reed (prox) switch (NOpen) + UNO. [+new wifi sheild +cosm]

I would would like to write a variable to 1 = moving or 0 = not moving, from criterion like rpm < 10 = not moving etc

So when using a cosm feed I can check the history of when the machine was working or no.

Ive tried using rpm counters but they seem to have bounce probs and also seem to not register the zero rotation to the wifi feeds Ive set up to cosm.

Can anyone help me with this sketch please.

Can anyone help me with this sketch please.

No, because we haven't seen it. Don't forget to use the code tags (# button in the editor) when posting it.

Ok the first sketch Ive trialed

volatile byte rpmcount;
 
 unsigned int rpm;
 
 unsigned long timeold;
 
 void setup()
 {
   Serial.begin(9600);
   attachInterrupt(0, rpm_fun, RISING);
 
   rpmcount = 0;
   rpm = 0;
   timeold = 0;
 }
 
 void loop()
 {
   if (rpmcount >= 20) { 
     //Update RPM every 20 counts, increase this for better RPM resolution,
     //decrease for faster update
     rpm = 30*1000/(millis() - timeold)*rpmcount;
     timeold = millis();
     rpmcount = 0;
     Serial.println(rpm,DEC);
   }
 }
 
 void rpm_fun()
 {
   rpmcount++;
   //Each rotation, this interrupt function is run twice
 }

This doesnt seem to give the correct rpm, (Im using 1 magnet) and not sure why the function rpm_fun() runs twice (giving 30,000)

When inserting this in "wifi sheild code" for posting to cosm it doesnt output zero rpm when wheel is not spinning. Somehow I think the 10sec wifi output only refers to the last known rpm reading.

Anyway the second sketch I trialled here,

// this constant won't change:
const int  buttonPin = 2;    // the pin that the pushbutton is attached to
//const int ledPin = 13;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button


// the following variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long lastEvent = 0;  // the last time the output pin was toggled
long interval = 10;    // the debounce time; increase if the output flickers


void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  //pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}

void loop() 
{
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

// compare the buttonState to its previous state
 if (buttonState != lastButtonState)
 {
 // if the state has changed, increment the counter
 if (buttonState == HIGH && (millis() - lastEvent > interval) ) // <-- Ignore this press if it is too close to the last one
 {
 lastEvent = millis(); // <-- record when the last good event occurred

        buttonPushCounter++;
        
        Serial.println(buttonPushCounter);
 }    
  
 }
  // save the current state as the last state, 
  //for next time through the loop
  lastButtonState = buttonState;

}

This is really good for "smoothing out" debouncing problems with the "interval" feature, but Id really like to use it to turn the count (buttonPushCounter) into an rpm reading or a rev count per hr to dsitingusih when the shaft is rotating. ie after 1 hr(some defined time period) output the count of revs. I could later define motion/movement by a threshold of more than a certain number or revs per hr (min) etc.

Hope that makes sense

Cheers

This doesnt seem to give the correct rpm

What do you get then? Why do you know the values are not correct?

Have you checked the signal from your reed switch with a scope? It probably has two rising edges per round.

Pylon thaks for the response.

Ive just been moving the magnet close to the reed swith by hand and taking it away at a timed interval ie to close the switch 1 every second should give 60rpm (i have a stopwatch only). The actual readings are higher and closer to 400 rpm. So im confused a bit.

Maybe you can explain how I might be getting "2 rising edges per round"? I would have thought the 2nd rise would be the start of the 2nd rev? so that means 1 rise per rev right?

So thinking more... Id actully like to be able to use the second sketch (without interrupts) but convert the out to rpm. ie Currently it outputs "buttonPushCounter" but Id like to somehow convert this to an rpm output. Im a begginer here so sorry if that seems simple. Im a bit consued with best place to do this conversion in the if statements.

I favour this tecchnique (not using interupts) as it gives me better intefacing/updating with the wifi timing (10sec update) upload to cosm and a correct rpm count when motion has stopped ie it still outputs the currect/last rpm reading even when zero. ( the 1st sketch does not do this, it uses the last rpm reading, not the current if zero)

Hope that mekes sense

Reed switches are mechanical switches operated by a moving magnet. Depending on the physical construction of the moving magnet and the reed's position they tend to bounce like a manual switch. If you know the RPM range your setup can be in you can measure the time between two edges and ignore all edges too close to the former one.

Ok are you saying its the bouncing that is repsonsible for the 2 rising events per cylce? (meaning I need to use 30,000ms and not 60,000ms in formulae)

Maybe you can show me a sketch that does what you say? ie. that ignores the noise and measures time between start and finish edges of 1 rev cycle?

My other hope/idea to detect shaft motion is to find a sketch that asigns output 100 to moving and 0 to stopped (for cosm feed), with a threadhold variable (time interval ~ 2sec per edge separation) to detect for motion.

Im sure someone will find this an easy task, Im just not much of a programmer yet. Cheers in advance

Ok are you saying its the bouncing that is repsonsible for the 2 rising events per cylce?

No, if my assumptions are correct, you're not getting exactly 2 rising events per cycle but sometimes 2, sometimes 3, sometimes only 1. Depending on you mechanical installation you may have two impulses because the magnetic field is hitting the sensor with two maximas. In any of these cases you should be able to filter the double edges out by comparing the times when they occur. What is your expected speed of the motor? 400rpm to 500rpm?

SENSING MOVEMENT FROM ROTATION

Put an accelerometer on that and it will sense rotational speed.

Pylon thanks for the explanation, didnt come across that anywhere else. Makes good sense.

I may be to find some code that just tries to determine the time period between any rising edges and use abuot 2-5sec of no detection to mean the machine is stationary.

dhenry
Prob with an acceleromter is it needs wires attached to the shaft, unless you mean to use it in some otherway?