Help re-starting my Loop

Hello
I am very new at writing code of any kind and need some guidance if anybody can help. My cod is counting the number of rotations with an encoder for a geared setup i have. I have put a pre-set number of “turns” in the code that when reached there will be a signal sent to a relay that shuts the machine down.

My problem is that when i get to this point:

if (numberOfTurns - x <= 0)  // sets the relay to switch at countdown to zero
  {
    digitalWrite(BUZZ,HIGH);
    lcd.clear();
    lcd.setCursor(8,1);
    lcd.print("DONE");
  
    } else { digitalWrite (BUZZ,LOW);
  }
  }

I need to be able to push a button when i am ready to re start the process from the beginning, without going thru the initial “welcome” screen. and it seems to be stuck at this point.

Pleas be easy because most of this is like a foreign language.

Here is the whole sketch (i understand it is probably sloppy):

// include the library code:
#include <LiquidCrystal.h>
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capability
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
// turns counter encoder labeled myEnc
Encoder myEnc(2, 3);
// menu encoder labeled menu
Encoder menu(5, 6);
//   avoid using pins with LEDs attached

// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

int BUZZ = 6; // set pin 6 to Buzzer

const int menuButton = 4; // set pin 4 as menu button

const int reset = 0; // set pin 0 as reset button

int numberOfTurns = 100; // set the desired number of turns
void setup() {
  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output
  digitalWrite (BUZZ,LOW);
  pinMode (menuButton, INPUT); // set my menu button as input
  Serial.begin(9600); // set baud rate
    
  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 4);
  // initialize the serial communications:
  Serial.begin(9600);
  // set the position of the title text (1 colum 0 row)
  lcd.setCursor(1, 0);
  // title text
  lcd.print("Coil Turns Counter");
  delay(2400);
  lcd.clear();
   lcd.print("Number Of Turns Left");
}

long oldPosition  = -999; // i dont know what this does

void loop() {
  long newPosition = myEnc.read(); // read  from enc library and establish it is a long number
  long x = newPosition / 204.8; // set my 20 to 1 ratio for encoder has a new variable "x" math derived by the quadrature encoder i am using
  // "long" is just to describe that it can be a nong intiger?
  if (newPosition != oldPosition){ // this is to print it once and determine value
    oldPosition = newPosition;
    Serial.println(numberOfTurns - x); // prints x value to count down to "number of turns" is defined at start
    // set position of counting digits ( row 2, colum 8)
    lcd.setCursor(8, 2); // printing the values as it counts down row 3, column 8
    lcd.print(numberOfTurns - x); // some math
}
if (numberOfTurns - x <= 0)  // sets the relay to switch at countdown to zero
  {
    digitalWrite(BUZZ,HIGH);
    lcd.clear();
    lcd.setCursor(8,1);
    lcd.print("DONE");
  
    } else { digitalWrite (BUZZ,LOW);
  }
  }

Maybe something like this would work

// include the library code:
#include <LiquidCrystal.h>
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capability
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
// turns counter encoder labeled myEnc
Encoder myEnc(2, 3);
// menu encoder labeled menu
Encoder menu(5, 6);
//   avoid using pins with LEDs attached

// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

int BUZZ = 6; // set pin 6 to Buzzer

const int menuButton = 4; // set pin 4 as menu button

const int reset = 0; // set pin 0 as reset button

int numberOfTurns = 100; // set the desired number of turns

boolean turnsRunnig = false; // <<<<<<<<<<<<<<<<<<<< NEW

void setup() {
  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output
  digitalWrite (BUZZ,LOW);
  pinMode (menuButton, INPUT); // set my menu button as input
  Serial.begin(9600); // set baud rate
    
  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD
  // set up the LCD's number of columns and rows: 
  lcd.begin(20, 4);
  // initialize the serial communications:
  Serial.begin(9600);
  // set the position of the title text (1 colum 0 row)
  lcd.setCursor(1, 0);
  // title text
  lcd.print("Coil Turns Counter");
  delay(2400);
  lcd.clear();
   lcd.print("Number Of Turns Left");
}

long oldPosition  = -999; // i dont know what this does

void loop() {
	byte btnState = digitalRead(buttonPin);
	if (btnState == LOW && turnsRunning == false) {
		turnsRunning = true;
	}
	if (turnsRunning == true) {
		runRotations();
	}
}


void runRotations() {
  long newPosition = myEnc.read(); // read  from enc library and establish it is a long number
  long x = newPosition / 204.8; // set my 20 to 1 ratio for encoder has a new variable "x" math derived by the quadrature encoder i am using
  // "long" is just to describe that it can be a nong intiger?
  if (newPosition != oldPosition){ // this is to print it once and determine value
    oldPosition = newPosition;
    Serial.println(numberOfTurns - x); // prints x value to count down to "number of turns" is defined at start
    // set position of counting digits ( row 2, colum 8)
    lcd.setCursor(8, 2); // printing the values as it counts down row 3, column 8
    lcd.print(numberOfTurns - x); // some math
}
if (numberOfTurns - x <= 0)  // sets the relay to switch at countdown to zero
  {
    digitalWrite(BUZZ,HIGH);
    lcd.clear();
    lcd.setCursor(8,1);
    lcd.print("DONE");
    turnsRunning = false; //<<<<<<<<<<<<<<<<<
  
    } else { digitalWrite (BUZZ,LOW);
  }
  }

I have moved all the code you had in loop() into a function and I have added some code in loop() to read a button and start things going. I have marked a couple of new lines with // <<<<<<<<

…R

My cod is counting

I wasn't aware that fish could count.

I tried reading your code. I gave up. Use Tools + Auto Format to properly indent that mess. and post the corrected code.

PaulS:
I wasn’t aware that fish could count.

http://news.nationalgeographic.com/news/2009/03/090331-fish-count.html

I am currently trying to fiddle with what you gave me Robin2. Thanks for the help. I just had a thought,

can you do this?

void loop(){ myMainStartingJunk() if (button is high, then myMainStartingJunk())

and it restart itself?... If what i just tried to say makes sense in the slightest.

Here is the correctly formatted code.

// include the library code:
#include <LiquidCrystal.h>
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capability
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
// turns counter encoder labeled myEnc
Encoder myEnc(2, 3);
// menu encoder labeled menu
Encoder menu(5, 6);
//   avoid using pins with LEDs attached

// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

int BUZZ = 6; // set pin 6 to Buzzer

const int menuButton = 4; // set pin 4 as menu button

const int reset = 0; // set pin 0 as reset button

int numberOfTurns = 100; // set the desired number of turns
void setup() {
  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output
  digitalWrite (BUZZ, LOW);
  pinMode (menuButton, INPUT); // set my menu button as input
  Serial.begin(9600); // set baud rate

  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
  // initialize the serial communications:
  Serial.begin(9600);
  // set the position of the title text (1 colum 0 row)
  lcd.setCursor(1, 0);
  // title text
  lcd.print("Coil Turns Counter");
  delay(1200);
  lcd.setCursor(1, 1);
  lcd.print ("  Developed By: ");
  delay(1200);
  lcd.setCursor(1, 2);
  lcd.print ("    Jeff Davis     ");
  delay(2400);
  lcd.clear();
  lcd.print("Number Of Turns Left");
}

long oldPosition  = -999; // i dont know what this does

void loop() {
  long newPosition = myEnc.read(); // read  from enc library and establish it is a long number
  long x = newPosition / 204.8; // set my 20 to 1 ratio for encoder has a new variable "x" math derived by the quadrature encoder i am using
  // "long" is just to describe that it can be a nong intiger?
  if (newPosition != oldPosition) { // this is to print it once and determine value
    oldPosition = newPosition;
    Serial.println(numberOfTurns - x); // prints x value to count down to "number of turns" is defined at start
    // set position of counting digits ( row 2, colum 8)
    lcd.setCursor(8, 2); // printing the values as it counts down row 3, column 8
    lcd.print(numberOfTurns - x); // some math
  }
  if (numberOfTurns - x <= 0)  // sets the relay to switch at countdown to zero
  {
    digitalWrite(BUZZ, HIGH);
    lcd.clear();
    lcd.setCursor(8, 1);
    lcd.print("DONE");

  } else {
    digitalWrite (BUZZ, LOW);
  }
}

Robin2: I have added some code in loop() to read a button and start things going. ...R

Hello, I keep getting an error that says 'turnsrunning was not declared in this scope' right here.

void loop() { byte btnState = digitalRead(buttonPin); if (btnState == LOW && turnsRunning == false) { turnsRunning = true; } if (turnsRunning == true) { runRotations(); } }

How can i fix this?

never mind, i figured out why i got the error. There was a letter missing on accident.

ok,
So now that i have fiddled with the code for a while, i still cannot get it to restart at my “numberOfTurns” variable by pushing a button. After i get my reading of 0 and the buzzer goes on, it stays on. no matter what i do.

I need to be able to push a button after this happens, re-setting my count down to the “numberofturns” value, and being able to start from scratch to go again.

// include the library code:
#include <LiquidCrystal.h>
#include <Encoder.h>
// Change these two numbers to the pins connected to your encoder.
//   Best Performance: both pins have interrupt capability
//   Good Performance: only the first pin has interrupt capability
//   Low Performance:  neither pin has interrupt capability
// turns counter encoder labeled myEnc
Encoder myEnc(2, 3);
// menu encoder labeled menu
Encoder menu(5, 6);
//   avoid using pins with LEDs attached

// initialize the LCD library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);

int BUZZ = 6; // set pin 6 to Buzzer

const int buttonPin = 4; // set pin 4 as menu button

const int reset = 0; // set pin 0 as reset button

int numberOfTurns = 100; // set the desired number of turns

boolean turnsRunning = false; // <<<<<<<<<<<<<<<<<<<< NEW

void setup() {

  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output
  digitalWrite (BUZZ, LOW);
  pinMode (buttonPin, INPUT); // set my menu button as input
  Serial.begin(9600); // set baud rate

  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD
  // set up the LCD's number of columns and rows:
  lcd.begin(20, 4);
  // initialize the serial communications:
  Serial.begin(9600);
  // set the position of the title text (1 colum 0 row)
  lcd.setCursor(1, 0);
  // title text
  lcd.print("Coil Turns Counter");
  delay(2400);
  lcd.clear();
  lcd.print("Number Of Turns Left");
}

long oldPosition  = -999; // i dont know what this does

void loop() {
  byte btnState = digitalRead(buttonPin);
  if (btnState == LOW && turnsRunning == false) {
    turnsRunning = true;
  }
  if (turnsRunning == true) {
    runRotations();
  }
}


void runRotations() {
  long newPosition = myEnc.read(); // read  from enc library and establish it is a long number
  long x = newPosition / 204.8; // set my 20 to 1 ratio for encoder has a new variable "x" math derived by the quadrature encoder i am using
  // "long" is just to describe that it can be a nong intiger?
  if (newPosition != oldPosition) { // this is to print it once and determine value
    oldPosition = newPosition;
    Serial.println(numberOfTurns - x); // prints x value to count down to "number of turns" is defined at start
    // set position of counting digits ( row 2, colum 8)
    lcd.setCursor(8, 2); // printing the values as it counts down row 3, column 8
    lcd.print(numberOfTurns - x); // some math
  }
  if (numberOfTurns - x <= 0)  // sets the relay to switch at countdown to zero
  {
    digitalWrite(BUZZ, HIGH);
    lcd.clear();
    lcd.setCursor(8, 1);
    lcd.print("DONE");
    turnsRunning = false; //<<<<<<<<<<<<<<<<<

  } else {
    digitalWrite (BUZZ, LOW);
  }
}

i still cannot get it to restart at my "numberOfTurns" variable by pushing a button.

I have no idea what that means. Try again without using any pronouns.

What is "it" that can't restart? What does "restart at a variable" even mean?

I am trying to have a predefined number of rotations, and use an encoder to count that number down to zero. when that number reaches zero it turns on a relay and waits for me to push a button that resets the whole process back to square one from void loop on. (not the initial setup stuff though).

i can get everything to operate except the resetting part.

  if (numberOfTurns - x <= 0)  // sets the relay to switch at countdown to zero

x is a meaningless name. Perhaps if you used a name that meant something, you could figure out when to reset it.

How about this…

long newPosition = myEnc.read(); // read  from enc library and establish it is a long number
  long numberOfTurnsLeft = newPosition / 204.8; // set my 20 to 1 ratio for encoder has a new variable "x" math derived by the quadrature encoder i am using
  // "long" is just to describe that it can be a nong intiger?
  if (newPosition != oldPosition) { // this is to print it once and determine value
    oldPosition = newPosition;
    Serial.println(numberOfTurns - numberOfTurnsLeft); // prints x value to count down to "number of turns" is defined at start
    // set position of counting digits ( row 2, colum 8)
    lcd.setCursor(8, 2); // printing the values as it counts down row 3, column 8
    lcd.print(numberOfTurns - numberOfTurnsLeft); // some math
  }
  if (numberOfTurns - numberOfTurnsLeft <= 0)  // sets the relay to switch at countdown to zero
  {

Now can i somehow put numberOfTurnsLeft = my original value???
i am not sure how to reset it.

jeffrey-davis:
So now that i have fiddled with the code for a while, i still cannot get it to restart at my “numberOfTurns” variable by pushing a button. After i get my reading of 0 and the buzzer goes on, it stays on. no matter what i do.

I suspect you are not studying your code carefully. And in any case you have not listed all the things that constitute “no matter what I do”

My guess is that the problem is simply the lack of a line of code to turn the buzzer off.

What about this

void loop() {
  byte btnState = digitalRead(buttonPin);
  if (btnState == LOW && turnsRunning == false) {
    turnsRunning = true;
   digitalWrite (BUZZ, LOW);  // <<<<<<<<<<<<<<<<
  }
  if (turnsRunning == true) {
    runRotations();
  }
}

You must realize that the buzzer making noise does not necessarily mean that the rest of the program has stopped.

…R

Goldfish can count, but only if they don't have to remember how many they have counted for more than seven seconds.

yes, i realize that just because the BUZZER goes off it does not mean that the program has stopped. I can see the "numberOfTurns" variable on the LCD screen, and after the BUZZER goes, the number does not reset itself back to 100, even if i have unplugged the buzzer and forgotten about that aspect all together.

Can you create a loop function that is outside of the main "void loop" and then use some type of command to break that loop and continue on with the rest of the program? Would that work out better?

Like a hierarchy some what like this:

Setup(){} void mainFunctionLoop() {run the main function junk; while (BUZZ is high) {break the loop and run "secondaryFunction()"} }

void secondaryFunction() {old number of turns + 100; If (BUZZ = LOW) { mainFunctionLoop()}

void Loop(){}

jeffrey-davis:
yes, i realize that just because the BUZZER goes off it does not mean that the program has stopped. I can see the “numberOfTurns” variable on the LCD screen, and after the BUZZER goes, the number does not reset itself back to 100, even if i have unplugged the buzzer and forgotten about that aspect all together.

Do you have code to set the number back to 100?
You did not have code to turn the buzzer off?

Can you create a loop function that is outside of the main “void loop” and then use some type of command to break that loop and continue on with the rest of the program?

You could, but why would that help?
Don’t go looking for complex solutions to simple problems.

From my understanding of your need the code I suggested should be suitable (subject to minor additions such as resetting the counter value). If there is anything about my suggestion that you don’t understand please let me know.

If my suggestion is not suitable it is because I have not understood your requirement - so over to you to explain it for me.

…R

From my understanding of your need the code I suggested should be suitable (subject to minor additions such as resetting the counter value). If there is anything about my suggestion that you don’t understand please let me know.

[/quote]

I need the addition of resetting the counter value, as it is the whole premise of the project. It is not such a “simple” problem for me because i do not understand the programming very well.

My thought process is that wen i had reset the counter value the Buzzer would turn off because my “turnsLeft” variable would no longer be <= zero.

Is this a correct assumption?

The buzzer to me is not as important as resetting the counter value at this point in time.

OK.

You have a basic problem.

This is what your code is basically doing:

  long newPosition = myEnc.read();
  long x = newPosition / 204.8;   
  if (numberOfTurns - x <= 0)  {
    digitalWrite(BUZZ, HIGH);
  }

which is the same as:

  long newPosition = myEnc.read();
  long newPositionAdjusted = newPosition / 204.8;   
  if (newPositionAdjusted  >= 100)  {
    digitalWrite(BUZZ, HIGH);
  }

So, the “resetting” you are talking about, requires the myEnc.read() to be reset. I don’t know how your encoder works, but that is the thing you have to reset when the button is pushed, if you are going to leave your “if” check like this.

So, the loop should look like:

void loop() {
  byte btnState = digitalRead(buttonPin);
  if (btnState == LOW && turnsRunning == false) {
    turnsRunning = true;
    myEnc.reset();   // This is where the reset is done. You need to find out how to reset your encoder.
  }
  if (turnsRunning == true) {
    runRotations();
  }
}

ok, thank you. I am unsure if you are saying i need to reset the encoder in my code, or physically reset the encoder somehow. can you please clarify.

arduinodlb: OK. So, the "resetting" you are talking about, requires the myEnc.read() to be reset. I don't know how your encoder works, but that is the thing you have to reset when the button is pushed, if you are going to leave your "if" check like this.

I think that the encoder library that i have attached just is some code to read the pulses of the physical encoder. I am not sure that turning the encoder off then back on for example would do anything, but i will try it. What you are saying, is exactly what i want to do. I feel like i need to have some function that says "if button is pushed, add the original number of turns to the value that the variable is right now, and then have the code go back to the top and start fresh. This would make my if statement FALSE and everything would be back to square one. But i do not know how to achieve this.