Button Programming for Pickup Winder

Hello,

I am working on a project to turn a sewing machine into a guitar pickup winder. Basically, what I want is to have the Arduino switching a relay on and off according to two variables, the current number of turns and the total number of turns. I want to be able to press four different buttons to set the ones, tens, hundreds, and thousands columns of the total number of turns (WindTotal) and then have a button that starts the relay until the current number of winds (WindCurrent) equals the WindTotal set. I will monitor this with a reed switch/magnet combination attached to the sewing machine foot.

My problem is that I cannot seem to get the counter to go up. In fact, the button pressing seems to accomplish nothing at all! I'm sure that my approach is flawed, but I can't for the life of me figure out how. Is there a logical ordering I have out of whack? Or am I handling the reading of the buttons incorrectly?

I do not currently have a schematic, but can upload my crude drawings if that will help anyone.

My code is as follows:

#include <LiquidCrystalFast.h>

#define Relay 0

#define OnesButt A5
#define TensButt A4
#define HundButt A3
#define ThouButt A2

int onesval = 0;
int tensval = 0;
int hundval = 0;
int thouval = 0;

#define ClearButt A1

#define TurnSwitch 9
int currentval = 0;
int totalval = 0;
int TurnClear;

#define StartButt A0
int startval = 0;

#define HaltButt 13
int haltval = 0;

int WindCurrent = 0;     
int WindTotal = 0; 

LiquidCrystalFast lcd(8, 7, 6, 5, 4, 3, 2);    // LCD pins: RS  RW  EN  D4 D5 D6 D7

void setup() {
  // set up the LCD's number of rows and columns: 
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(TurnSwitch, INPUT);
  pinMode(OnesButt, INPUT);
  pinMode(TensButt, INPUT);
  pinMode(HundButt, INPUT);
  pinMode(ThouButt, INPUT);
  pinMode(ClearButt, INPUT);
  pinMode(StartButt, INPUT);
  pinMode(HaltButt, INPUT);
  pinMode(TurnSwitch, INPUT);  
}


void loop() {
  lcd.clear();
  startval = digitalRead(StartButt);
  TurnClear = digitalRead(ClearButt);
  onesval = digitalRead(OnesButt);
  tensval = digitalRead(TensButt);
  hundval = digitalRead(HundButt);
  thouval = digitalRead(ThouButt);

  if(WindTotal >> 9999){
    (WindTotal == 0);
    }
  
  if(startval == HIGH){
    wind();
    delay(100);
  }

  if(TurnClear == HIGH){
    (WindTotal == 0);
    delay(100); 
  }
  
  if(onesval == HIGH){
    WindTotal++;
    delay(100);
    }
  }
    
  if(tensval == HIGH){
    WindTotal+10;
    delay(100);
  }
  
  if(hundval == HIGH){
    WindTotal+100;
    delay(100);
  }
  
  if(thouval == HIGH){
    WindTotal+1000;
    delay(100);
  }
  
  Serial.println(WindTotal);
  lcd.setCursor(0, 0);
  lcd.print("Current = "); 
  lcd.print(WindCurrent);
  lcd.setCursor(0, 1);
  lcd.print("Total = "); 
  lcd.print(WindTotal);
  delay(50);
  
  
}

void wind() {
  lcd.clear();
  WindCurrent=0;
  while(WindCurrent < WindTotal){
    digitalWrite(Relay, HIGH);
    currentval = digitalRead(TurnSwitch);
 
    if (currentval == HIGH ){
     WindCurrent++;
     delay(30);
      }
      
    haltval = digitalRead(HaltButt);
    
    if (haltval == HIGH){
    digitalWrite(Relay, LOW);
      }
   
    lcd.setCursor(0, 0);
    lcd.print("Current = "); 
    lcd.print(WindCurrent);
    lcd.setCursor(0, 1);
    lcd.print("Total = "); 
    lcd.print(WindTotal);
    delay(20);
    }
    
    digitalWrite(Relay, LOW);
}

Thanks in advance for any tips, or if anyone can point me to a source for rewriting the trouble bits of code.

Lines like this

   (WindTotal == 0);

and this

    WindTotal+10;

are going to get you into trouble. Perhaps you intended this

    WindTotal = 0;

(unnecessary parentheses removed, and == changed to =)

and this

    WindTotal+=10;

(Actually changes WindTotal. The original did a calculation that was thrown away.)

Remember that one equal sign "=" stores a value, whereas two equal signs "==" are used for a comparison.

Learn to program in C, fix your code, and then come back here for more help. This project can get you into a lot of trouble; perhaps you should start with something simpler.

Thank you for your response vaj4088, I knew that it was something simple I was screwing up.

You mention this project getting me into trouble. What other problems can you forsee with the coding? Anything else glaringly wrong that I am doing, or any commands which could be simplified or refined?

If its on the engineering side of the project that your concerns lay, no worries about that. I already have the PCBs fabricated, the motor modified, proper gear ratios calculated for proper speeds, etc. I am an extreme novice when it comes to coding, but I have a good handle on the rest.

The major problems I can predict will come from the reed switch/turn counter and getting the counter to trigger once and only once for each revolution of the motor, but that will probably be a matter of tweaking the debounce delay and positioning/strength of the magnet in use.

Anyone else have any comments on the code and how to optimize this build? Or what trouble I may have to avoid? Here is the renewed code and a rough schematic:

#include <LiquidCrystalFast.h>

#define Relay 0

#define OnesButt A5
#define TensButt A4
#define HundButt A3
#define ThouButt A2

int onesval = 0;
int tensval = 0;
int hundval = 0;
int thouval = 0;

#define ClearButt A1

#define TurnSwitch 9
int currentval = 0;
int totalval = 0;
int TurnClear;

#define StartButt A0
int startval = 0;

#define HaltButt 13
int haltval = 0;

int WindCurrent = 0;     
int WindTotal = 0; 

LiquidCrystalFast lcd(8, 7, 6, 5, 4, 3, 2);   

void setup() { 
  Serial.begin(9600);
  lcd.begin(16, 2);
  pinMode(TurnSwitch, INPUT);
  pinMode(OnesButt, INPUT);
  pinMode(TensButt, INPUT);
  pinMode(HundButt, INPUT);
  pinMode(ThouButt, INPUT);
  pinMode(ClearButt, INPUT);
  pinMode(StartButt, INPUT);
  pinMode(HaltButt, INPUT);
  pinMode(TurnSwitch, INPUT);  
}


void loop() {
  lcd.clear();
  startval = digitalRead(StartButt);
  TurnClear = digitalRead(ClearButt);
  onesval = digitalRead(OnesButt);
  tensval = digitalRead(TensButt);
  hundval = digitalRead(HundButt);
  thouval = digitalRead(ThouButt);

  if(WindTotal >= 9999){
    WindTotal = 0;
    }
  
  if(startval == HIGH){
    wind();
    delay(100);
  }

  if(TurnClear == HIGH){
    WindTotal = 0;
    delay(100); 
  }
  
  if(onesval == HIGH){
    WindTotal+=1;
    delay(100);
    
  }
    
  if(tensval == HIGH){
    WindTotal+=10;
    delay(100);
  }
  
  if(hundval == HIGH){
    WindTotal+=100;
    delay(100);
  }
  
  if(thouval == HIGH){
    WindTotal+=1000;
    delay(100);
  }
  
  Serial.println(WindTotal);
  lcd.setCursor(0, 0);
  lcd.print("Current = "); 
  lcd.print(WindCurrent);
  lcd.setCursor(0, 1);
  lcd.print("Total = "); 
  lcd.print(WindTotal);
  delay(50);
  
  
}

void wind() {
  lcd.clear();
  WindCurrent=0;
  while(WindCurrent < WindTotal){
    digitalWrite(Relay, HIGH);
    currentval = digitalRead(TurnSwitch);
    if (currentval == HIGH ){
     WindCurrent++;
     delay(50);
      }
      
    haltval = digitalRead(HaltButt);
    
    if (haltval == HIGH){
    digitalWrite(Relay, LOW);
    loop();
      }
   
    lcd.setCursor(0, 0);
    lcd.print("Current = "); 
    lcd.print(WindCurrent);
    lcd.setCursor(0, 1);
    lcd.print("Total = "); 
    lcd.print(WindTotal);
    delay(20);
    }

    WindTotal=0;
    digitalWrite(Relay, LOW);
}

Reed switches were originally designed for use in reed relays. I still have some in the junk box. There is a coil of wire, a solenoid, wound on a form so the magnetic field from the coil flows completely through the steel leaves of the switch. There was never a bounce from these devices.

You will never get a reed switch bounce if you ensure the magnetic field from the magnet, from one pole to the other, flows though the entire switch.

Where designs encounter bounce is where only one pole of the magnet is used to trigger the reed switch. Remember the shape of the magnet field on a pole end is like a water fountain with a low magnetic field right over the end of the pole. This may actually close the reed switch twice as it passes.

Hope this helps.

Paul

As a matter of interest, how are the buttons wired ? Do you have pulldown resistors in place ?

@UKHeliBob - Oops, yes, I missed notating it in the schematic (or properly indicating switches for that matter) but I have 10k pulldown resistors to ground on each of the button pins. As of now, I have wires leading to a breadboard, but will eventually run a ribbon cable from main PCB to a separate button board affixed to the sewing machine chassis.

@Paul_KD7HB - I wasn't aware of the origins of reed switches, but now that you mention it, it makes perfect sense that they would be used as the basis for relays. It is good to know that bounce is not an issue, but the chance that the magnetic field will possibly trigger the reed twice per revolution seems like it will be a problem. Hopefully with careful positioning I can ensure that only the edge of the field passes over the switch, or perhaps I can just double the values of the windings in the code (though that will likely lead to headaches down the line.)

I was originally going to use a mechanical switch that would be pressed by the sewing machine foot on each revolution, but it seemed as if device failure would almost certainly happen much sooner than later with the force delivered. I have not run any real tests yet, but I have a feeling this will be the most fiddly part of the whole setup (besides getting the speed of the wheel to a point where it didn't destroy the fragile magnet wire).

Thank you for your responses.

@UKHeliBob - Double Ooops! I just realized that my schematic indicates the switches connect to Ground, but they do not. I'm not representing myself very well it seems.

Each digital button pin has a 10k pulldown to ground, and the NO momentary switches connect to the +V on the other side.

Last week I finished refurbishing a coil winding machine that used a stepper motor and was controlled by a PC using the parallel printer port. I built it perhaps 15 years ago for a customer requirement. The PC died and no newer one would work with the Basic program. It used a foot switch to control.

I added an Arduino nano and stepper motor controller board. There is a keypad to enter # turns. The foot switch tells the program to begin turning the spindle as soon as the switch is released. If the switch is pressed while the coil is turning. the stepper stops immediately and holds the spindle tightly to maintain tension on the wire. On release of the switch, the process continues.

When the turns match the requirement, the stepper stops and the controller put to sleep so the spindle is free to turn. When the operator is ready for the next coil, they press the foot switch to repeat the process.

A LCD shows the # turns required and the count of completed coils.

This is just another way of doing what you are doing.

Paul

I applaud the engineering work that you are doing. My concern is that novices often attempt and have difficulties with a complex program when they should start simple and grow from there.

vaj4088:
I applaud the engineering work that you are doing. My concern is that novices often attempt and have difficulties with a complex program when they should start simple and grow from there.

And starting simple and learning is what is so DIFFICULT to convince forum posters. Sometimes I wish there was a stick to beat them with!!!!

One reason to put logic in functions is to be able to toss out the entire function and start over because you have learned so much about what you are doing that you now realize it can't possibly work.

I guess making mistakes is not allowed in today's culture.

Paul

Well, starting simple and working up is what got me to this project. Rather than begin a riot regarding coding pedagogy, let me try to figure out where I went astray.

I worked through my blink and LED programs, I worked through my press-button-light-LED programs, I worked through my "Hello World" LCD programming, etc. I worked through basic serial communication stuff, calling other program functions within the loop() and testing two variables using while and if statements.This seems to be all that my program needs.

My program lets you set one integer, press a button to write the relay digitalpin HIGH, and then counts another integer incrementally up until it is greater than or equal to the first integer, at which point it writes the relay LOW.

What is so difficult about this program? I realize it is a large conglomeration of basic programs, but I pieced them all together one at a time, in logical order.

Are there any specific comments about my code and what I am doing wrong? I understand the Arduino community is very much dedicated to the "help people teach themselves" mentality, and I usually do learn better by trying and failing and trying again.

I was hoping for some concrete pointers to get me started on a better path.

Thank you all for your comments and suggestions.

djf26@buffalo.edu:
Well, starting simple and working up is what got me to this project. Rather than begin a riot regarding coding pedagogy, let me try to figure out where I went astray.

I worked through my blink and LED programs, I worked through my press-button-light-LED programs, I worked through my "Hello World" LCD programming, etc. I worked through basic serial communication stuff, calling other program functions within the loop() and testing two variables using while and if statements.This seems to be all that my program needs.

My program lets you set one integer, press a button to write the relay digitalpin HIGH, and then counts another integer incrementally up until it is greater than or equal to the first integer, at which point it writes the relay LOW.

What is so difficult about this program? I realize it is a large conglomeration of basic programs, but I pieced them all together one at a time, in logical order.

Are there any specific comments about my code and what I am doing wrong? I understand the Arduino community is very much dedicated to the "help people teach themselves" mentality, and I usually do learn better by trying and failing and trying again.

I was hoping for some concrete pointers to get me started on a better path.

Thank you all for your comments and suggestions.

Professional advice: Now that you are familiar with logic and with programming, and with what you want the program to do, start a new, fresh program from scratch and make it do what the current programming is doing, but in a more logical path.

I have had to start large commercial programs over from scratch after learning more about what the project was all about. I have also advised other programmers to do the same when they had cornered themselves. Much faster to start over than to fuss with a failed program.

Paul

Hi Paul,

Thank you for the advice. I certainly understand that in the throes of program writing, ideas pop in and out in an unruly fashion and it is worthwhile to revise after completion. My issue is that I would rewrite it basically the same, because in my mind, I am logically progressing through the goals I want to accomlplish.

That being said, I have done a bit of rewriting and rearranging, and I have streamlined the process a bit (I think!).

Can anyone see anything I am doing wrong, anything that I should do differently, anything that is working in the wrong way, and approaches I am taking that could be refined?

Any resources I can go to, or other programs to study and compare with?

#include <LiquidCrystalFast.h>

#define Relay 0

#define OnesButt A5
#define TensButt A4
#define HundButt A3
#define ThouButt A2

int onesval = 0;
int tensval = 0;
int hundval = 0;
int thouval = 0;

#define ClearButt A1

#define TurnSwitch 9
int currentval = 0;
int totalval = 0;
int TurnClear = 0;

#define StartButt A0
int startval = 0;

#define HaltButt 13
int haltval = 0;

int WindCurrent = 0;     
int WindTotal = 0; 

LiquidCrystalFast lcd(8, 7, 6, 5, 4, 3, 2);   

void setup() { 
  lcd.begin(16, 2);
  pinMode(Relay, OUTPUT);
  pinMode(TurnSwitch, INPUT);
  pinMode(OnesButt, INPUT);
  pinMode(TensButt, INPUT);
  pinMode(HundButt, INPUT);
  pinMode(ThouButt, INPUT);
  pinMode(ClearButt, INPUT);
  pinMode(StartButt, INPUT);
  pinMode(HaltButt, INPUT);
  pinMode(TurnSwitch, INPUT); 

  digitalWrite(Relay, LOW);
}


void loop() {
  lcd.clear();
  startval = digitalRead(StartButt);
  TurnClear = digitalRead(ClearButt);
  onesval = digitalRead(OnesButt);
  tensval = digitalRead(TensButt);
  hundval = digitalRead(HundButt);
  thouval = digitalRead(ThouButt);
  currentval = digitalRead(TurnSwitch);
  digitalWrite(Relay, LOW);
 
  if(TurnClear == HIGH){
    WindTotal = 0;
    WindCurrent = 0;
    delay(100); 
  }
  
  if(onesval == HIGH){
    WindTotal+=1;
    if(WindTotal >= 15000){
    WindTotal = 0;
    }
    delay(100);
  }
    
  if(tensval == HIGH){
    WindTotal+=10;
    if(WindTotal >= 15000){
    WindTotal = 0;
    }
    delay(100);
  }
  
  if(hundval == HIGH){
    WindTotal+=100;
    if(WindTotal >= 15000){
    WindTotal = 0;
    }
    delay(100);
  }
  
  if(thouval == HIGH){
    WindTotal+=1000;
    if(WindTotal >= 15000){
    WindTotal = 0;
    }
    delay(100);
  }

  if(startval == HIGH){
    digitalWrite(Relay, HIGH);
    while(WindCurrent < WindTotal){
      if (currentval == HIGH){
        WindCurrent++;
        delay(30);
         }
  
       haltval = digitalRead(HaltButt);
       if (haltval == HIGH){
         digitalWrite(Relay, LOW);
         WindCurrent=WindTotal;
           }
   
       lcd.setCursor(0, 0);
       lcd.print("Current = "); 
       lcd.print(WindCurrent);
       lcd.setCursor(0, 1);
       lcd.print("Total = "); 
       lcd.print(WindTotal);
      delay(20);
    }
  }

  
  lcd.setCursor(0, 0);
  lcd.print("Current = "); 
  lcd.print(WindCurrent);
  lcd.setCursor(0, 1);
  lcd.print("Total = "); 
  lcd.print(WindTotal);
  delay(60);

}

Best advice is to review "
Demonstration code for several things at the same time" in the project guidance section
and get rid of all the delay statements.

Paul

approaches I am taking that could be refined?

Use variable types appropriate to the maximum value that they are expected to hold. For instance you have

int onesval = 0;

but its largest value will be 9 so byte would do.

Whilst there is no problem using a mixture of #define and explicit declaration of variables there is no advantage in mixing the two approaches.

Hi,

Your power supply may need changing, you need at least 470uF for the cap on the input of the LM7805 reg as well as a 0.1uF cap from the reg input to gnd.
The 47uF on the reg output should be okay, but again 0.1uF cap from output to gnd, will help any stabilty problems that may occur.
What is your transformer rated at and when voltage do you measure at the input to the regulator?

Thanks.. Tom... :slight_smile:

turns switch not working

amarnathkeshari:
turns switch not working

How old is the thread you are posting to?

How do you know the switch is not working?

Paul