Sunday, 15 July 2012

First Arduino Connection

What we did with an LED, we wanted to do with an Arduino next. I used an Arduino Mega and wrote a little program to sense and estimate the machine sewing speed, based upon using the machine as a switch. The program is based on the "Button" example that turns on an LED when a button is pressed. It specifies the set-up as follows:

* 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
The sewing machine just makes a simple switch with its upper thread lever and the newly inserted PCB, but putting it into the same circuit like a normal switch is dangerous, because it isn't just a switch... it is itself an electrical instrument connected to mains power and, when so, most likely to ground. In case something goes wrong, and the lever is up/switch is closed, we might have a direct connection from the power source on the Arduino to the ground, with no resistor in between... a recipe for trouble.
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  
  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:

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(" ms, stitch frequency:  ");
        Serial.print(" Hz, sewing speed: ");
        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.

1 comment:

  1. Great to see the Melbourne HackerSpace sewing machine getting an upgrade.

    Starting off with a directly connected switch is a good learning execise. In time, incorporating an opto-coupler or using a hall-effect switch will provide a greater level of electrical isolation and safety.