And here's the code if anyone wants to pick through it.
/*
Title: Willy Winder v1.0
Author: William Begg
Website: www.willyguitars.com
Date: 01-20-2012
sketch for counting turns with optointerruptor for pickup
winder. Uses interrupt on pin 2 to increment counts and
displays pertinent information on a 20 x 4 LCD Display.
Thanks to the Arduino community for their help, and to Pete Mills at
petemills.blogspot.com for supplying some code I was able to use.
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
// Global Variables
volatile unsigned int M_SEC_0 = 0; // for rpm
volatile unsigned int M_SEC_1 = 0; // for rpm
volatile unsigned long CUR_WINDS = 0; // current count of winds
volatile unsigned int RPM_CNT = 0; // revolution increment for RPM calc
// pin map
const int tachPin = 0; // infrared tachometer input. Pin 2 for interrupt.
const int motorEng = 4; // pin for motor relay
const int pwmIn = A5; // Potentiometer pin to set motor speed pwm
const int pwmOut = 3; // PWM out for motor speed
const unsigned int A_SW = A0; // analog switch
void setup()
{
lcd.begin(20,4); // 20x4 HD44780 compatible LCD display (JHD204A)
pinMode(tachPin, INPUT); // input pin for calculating winds and rpm
pinMode(motorEng, OUTPUT); // connected to motor relay
pinMode(pwmIn, INPUT);
pinMode(pwmOut, OUTPUT);
digitalWrite(tachPin, HIGH);
digitalWrite(motorEng, HIGH);
// Attach the Interrupt
attachInterrupt(tachPin, tachometer, RISING); // interrupt for counting. Connected to optointerrupter on digital pin 2 (interrupt 0)
}
// Interrupt function
void tachometer()
{
CUR_WINDS++; // increment # of winds cnt
RPM_CNT++; // increment count for RPM calculation
}
// function set to read switches from resistor array to save analog inputs on arduino
int read_ana_switch()
{
/*
reads analog switch and returns integer val 1::n
This is done to save digital inputs. Here we can have numerous switches on
one analog pin.
switch int val
UP_SW 1
DN_SW 2
LT_SW 3 (not currently used)
RT_SW 4 (not currently used)
RED_SW 5
GRN_SW 6
*/
const int HYS = 4; // Hysteresis for selection +/- adc counts
const int UP_SW = 51; // adc counts for up switch
const int DN_SW = 61; // adc counts for down switch
const int LT_SW = 71; // adc counts for left switch
const int RT_SW = 84; // adc counts for right switch
const int RED_SW = 128; // adc counts for red arcade button
const int GRN_SW = 108; // adc counts for green arcade button
int adc = 0; // raw adc counts
int which_switch = 0; // which switch was pressed
adc = analogRead(A_SW); // dummy read for multiplex settling
delay(10);
adc = analogRead(A_SW);
if( ( adc >= UP_SW - HYS ) && ( adc <= UP_SW + HYS ) )
{
which_switch = 1;
}
else if( ( adc >= DN_SW - HYS ) && ( adc <= DN_SW + HYS ) )
{
which_switch = 2;
}
else if( ( adc >= LT_SW - HYS ) && ( adc <= LT_SW + HYS ) )
{
which_switch = 3;
}
else if( ( adc >= RT_SW - HYS ) && ( adc <= RT_SW + HYS ) )
{
which_switch = 4;
}
else if( ( adc >= RED_SW - HYS ) && ( adc <= RED_SW + HYS ) )
{
which_switch = 5;
}
else if( ( adc >= GRN_SW - HYS ) && ( adc <= GRN_SW + HYS ) )
{
which_switch = 6;
}
return which_switch;
}
void spinit()
{
/*
Turns motor and counts total turns and calculates RPM
*/
static unsigned int num_winds = 100; // default number of winds to perform
unsigned int wind_inc = 1; // increment num_winds by...
unsigned int ms_elapsed = 0; // number of milliseconds elapsed when counting to 1 second for rpm calc
unsigned int rpm = 0; // average speed of guitar pickup
int ana_sw = 0;
int prev_ana_sw = 0;
lcd.clear();
while( ana_sw != 5 )
{
if(num_winds >= (CUR_WINDS+1))
digitalWrite(motorEng, HIGH);
else digitalWrite(motorEng, LOW);
int sensorValue = analogRead(pwmIn); // read speed potentiometer
int outputValue = map(sensorValue, 0, 1023, 0, 255); // map the sensor value to a range from 0 - 255:
analogWrite(pwmOut, outputValue); // use that to control the transistor
long winds_rem = (num_winds - CUR_WINDS);
ana_sw = read_ana_switch(); // read the analog switch
if( ana_sw == 1 | ana_sw == 2 ) // inc/dec faster if sw is held down
{
if( ana_sw == prev_ana_sw )
{
wind_inc++;
}
else
{
wind_inc = 1;
}
}
if( ana_sw == 1 )
{
lcd.clear();
num_winds += wind_inc; // if the up switch is pressed, increment the number of winds to do
}
if( ana_sw == 2 )
{
lcd.clear();
num_winds -= wind_inc; // if the down switch is pressed, decrement the number of winds to do
}
prev_ana_sw = ana_sw;
// calculate RPM in 1hz intervals
M_SEC_1 = millis(); // get elapsed time
ms_elapsed = M_SEC_1 - M_SEC_0;
if( ms_elapsed >= 1000 )
{
rpm = ( ( 60000 / ms_elapsed ) * RPM_CNT ); // calculate rpm
M_SEC_0 = millis(); //reset counters
M_SEC_1 = M_SEC_0;
RPM_CNT = 0;
}
if (CUR_WINDS >= num_winds)
{
lcd.setCursor(0,3);
lcd.print("Winding is Complete!");
}
lcd.setCursor(0,0);
lcd.print("# Winds: ");
lcd.print(num_winds);
lcd.setCursor(0,1);
lcd.print("RPM: ");
lcd.print(rpm);
lcd.setCursor(0,2);
lcd.print("Total Winds: ");
lcd.print(CUR_WINDS);
lcd.setCursor(0,3);
}
lcd.clear();
digitalWrite(motorEng, LOW);
CUR_WINDS = 0;
delay(400);
}
void loop()
{
int start_sw = read_ana_switch();
lcd.setCursor(0,0);
lcd.print(" WILLY WINDER v1.0");
lcd.setCursor(0,1);
lcd.print(" Lower Motor Speed");
lcd.setCursor(0,2);
lcd.print(" And Press Enter");
lcd.setCursor(0,3);
lcd.print(" To Begin");
if (start_sw == 6 && (analogRead(pwmIn)) < 1) // enables motor only if speed is turned down at start.
spinit();
}