* LED attached from pin 13 to ground * pushbutton attached to pin 2 from +5V * 10K resistor attached to pin 2 from ground * Note: on most Arduinos there is already an LED on the board attached to pin 13.
This is the circuit for it. In my case, the sewing machine would constitute the switch... I won't insert that picture here without a big warning sign because Andy (thanks Andy) showed me why I should not do it like this.
Naive use of "Button" example circuit substituting the sewing machine for the switch |
We opted to put the (probably ground-connected) machine on the safe side -- where the 'ground' connection of the Arduino is -- like this:
Circuit connecting the sewing machine as a switch to the Arduino |
When the lever is down/switch is open, the voltage on pin 2 is 5V. When the lever is up/switch is closed, the voltage on pin 2 goes down to 0V. The 'Ground' connection on the Arduino and the possibly ground-connected machine are connected, but between them and the 5V power source is a resistor, avoiding a short circuit.
The Arduino program to sense the machine speed from this is a very simple modification of the Button example. It doesn't use interrupts to know when the lever position has changed, it just runs in a loop. It uses a very simple heuristic to try and eliminate noise:We know that the minimum length between stitches is 75ms, so it's making the assumption that any two "needle ups" that were sensed less than 40 ms apart are noise, and ignores those.
/* State change frequency detection/sewing machine speed detection (modified from State change detection (edge detection) at http://arduino.cc/it/Tutorial/Button) Application: sewing machine, assuming that signal "off" means "needle (or thread takeup lever) is up" and "on" means "needle is down" including a simple noise elimination algorithm that assumes a stitch must at least be 40ms in length, or else, the variation is just noise. modified Jul 2012 by barbara */ // this constant won't change: const int leverPin = 2; //the pin that the machine lever switch is attached to const int ledPin = 13; // the pin that the LED is attached to const unsigned long minTimeBetweenStitchesMs = 40000; // minimum interval between stitches -- 40 ms // Variables that will change: unsigned long lastLeverUpTime; // last time the lever was up float stitchTime; // length of current stitch int leverState = 0; // current state of the lever int lastLeverState = 0; // previous state of the lever void setup() { // initialize the lever pin as a input: pinMode(leverPin, INPUT); // initialize the LED as an output: pinMode(ledPin, OUTPUT); // initialize serial communication: Serial.begin(9600); } void loop() { // read the input pin: leverState = digitalRead(leverPin); // compare the leverState to its previous state if (leverState != lastLeverState) { digitalWrite(ledPin, ! leverState); unsigned long changeTime = micros(); // if the state has changed, increment the counter if (leverState == LOW) { // if the current state is LOW then the lever went from high to low unsigned long diffTime = changeTime - lastLeverUpTime; if (diffTime > minTimeBetweenStitchesMs) { lastLeverUpTime = changeTime; stitchTime = diffTime/1000.0; Serial.print("stitchTime: "); Serial.print(stitchTime); Serial.print(" ms, stitch frequency: "); Serial.print(1000.0/stitchTime); Serial.print(" Hz, sewing speed: "); Serial.print(60.0*1000.0/stitchTime); Serial.println(" stitches per minute"); } } } // save the current state as the last state, //for next time through the loop lastLeverState = leverState; }
Here is some example output:
... as can be seen, the stitch length estimated by the program varies quite a bit -- actually, upon every other stitch -- whereas we know from a look to the oscilloscope that the stitches are quite uniform in length and frequency. This is probably due to the lever bouncing a few times on and off as it hits the PCB during each stitch. We will either have to improve the smoothing algorithm or the input signal.