Help re-starting my Loop

If you want to count 100 turns in each session of calls to runRotations why not make life simple

Start with countNum = 100; Every 204.8 pulses decrement countNum by 1 Stop when countNum reaches 0

I'm sorry but I am still unclear about where the problem lies

What about this

long oldPosition  = 0; // i dont know what this does
long newPosition  = 0; // i dont know what this does
byte countNum;

void loop() {
    byte btnState = digitalRead(buttonPin);
    if (btnState == LOW && turnsRunning == false) {
        digitalWrite(BUZZ,LOW);
        turnsRunning = true;
        countNum = 100;
            // initialize oldPosition to be the same as newPosition
        newPosition = myEnc.read();
        oldPosition = newPosition;
    }
    if (turnsRunning == true) {
        runRotations();
    }
}

void runRotations() {
    newPosition = myEnc.read(); // read  from enc library and establish it is a long number
    if (newPosition - oldPosition > 204) {
        countNum-- ;
        oldPosition = newPosition;
    }
    if (countNum == 0) {  // sets the relay to switch at countdown to zero

        digitalWrite(BUZZ,HIGH);
        lcd.clear();
        lcd.setCursor(8,1);
        lcd.print("DONE");
        turnsRunning = false; 
    }
 }

...R

jeffrey-davis: 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.

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.

OK. The problem then is your current code makes the assumption that when you turn the Arduino on, the encoder starts at position 0. If this is not the case, then your initial run of the code will also not work correctly.

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.

Look at Robin2's code for a solution for this, and the first-run problem.

Can you please break down the code you have written step by step for me so that i can understand better what is going on.

Thanks.

what does countnum-- do?

i looked up –

can somebody explain this to me;
Examples

x = 2;
y = ++x; // x now contains 3, y contains 3
y = x–; // x contains 2 again, y still contains 3
???

jeffrey-davis:
what does countnum-- do?

i looked up –

can somebody explain this to me;
Examples

x = 2;
y = ++x; // x now contains 3, y contains 3
y = x–; // x contains 2 again, y still contains 3
???

countnum is just a random variable name, and is being used as a counter. It is being used to count the number of times you have increased your value by 204. It starts at 100 and counts down to 0. Once it gets to 0, it gets reset to 100 in the main loop().

countnum–; is shorthand for
countnum = countnum - 1;

they mean exactly the same thing.

jeffrey-davis: Can you please break down the code you have written step by step for me so that i can understand better what is going on.

It will be easier to help if you ask specific questions such as you have done with countNum --

Also please note that the variable name is countNum and NOT countnum. I don't care, but the compiler will.

...R

ok, I feel like i am getting more and more lost in the code. I have fiddled with it and now have lots of different files and everything is all mixed up.

I understand that you guys have given me some good examples of code, but i get mixed up when i try to cut them into my code. I get lots of errors about things not being declared and what not. Like i said in the beginning, i am new to this, and if it was “Easy” to me, i would not be on this site. Sorry for the frustration. I would really like to LEARN what i am doing here.

If either of you guys feel like helping me piece the good examples you have provided, piece by piece, into my original and help me learn this and explain it for a moment i would appreciate it. As well as any learning pointers you can throw me along the way.

So here is where i am starting:

// 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);

int BUZZ = 6; // set pin 6 to Buzzer
int numberOfTurns = 100; // set the desired number of turns

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


void setup() {   // put your setup code here, to run once:

  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output
  digitalWrite (BUZZ, LOW); // set the buzzer pin as low

  Serial.begin(9600); // set baud rate

  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD

  lcd.begin(20, 4);  // set up the LCD's number of columns and rows:

  Serial.begin(9600);   // initialize the serial communications:

  lcd.setCursor(1, 0);   // set the position of the title text (1 colum 0 row)

  lcd.print("Coil Turns Counter");   // title text
  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");
}

void loop() {    // put your main code here, to run repeatedly:

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

  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 long 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

    lcd.setCursor(8, 2);   // set position of counting digits ( row 2, colum 8)

    lcd.print(numberOfTurns - x);   // printing the values as it counts down row 3, column 8

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

      digitalWrite(BUZZ, HIGH); // set buzzer pin high

      lcd.clear(); // clear the lcd and print done

      lcd.setCursor(8, 1); // set the curson position

      lcd.print("DONE"); // print "done" to lcd


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

I looked over your code and the problem lies in how you are counting your 100 turns and ill try to explain the problem.
As arduinodlb pointed out to reset your count this way you need to reset your encoder somehow or you need to add some math to your code.
When the arduino starts and your encoder starts it is at 0. Every rotation adds 1 rotation to the encoder so after 100 turns your x variable equals 100. Since that is what you are using for your count, the number will never be reset unless you reset your encoder back to 0.
In other words your x variable will always count the amount of rotations since the arduino has been turned on.
Since that is not a viable solution with your library you need to implement some math.
An easy way to do it is to set your numberOfTurns variable to (100 + timesSpun) every time the button is pressed. This would result in the following. At the start of the second run your x variable will be 100. numberOfTurns would equal 200. Your equation of, numberOfTurns - x wil give you 100 turns of the encoder left. Keep in mind you will run out of times you can do that without resetting the encoder or arduino.

Try the following code it is yours from post 8 i changed lines 54-56.

Hope This Helps

// 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;
    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
    numberOfTurns = 100 + x;
  }
  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);
  }
}

jeffrey-davis: ok, I feel like i am getting more and more lost in the code. I have fiddled with it and now have lots of different files and everything is all mixed up.

I understand that you guys have given me some good examples of code, but i get mixed up when i try to cut them into my code.

Have you tried the code I suggested in Reply #20? It should be complete (though untested) in itself with no need to "cut it into" any other code. I also tried to use code that deals with the problem in a simple and transparent fashion. And it has no need for zeroing the encoder position.

If you are trying to understand code (your own or anyone else's) it is a good idea to work through it line by line with a pencil and paper as though your own brain is the computer. Keep track of the value of all variables and follow through all the decisions tests.

...R

Ok, so the code in reply#20 i have put into a brand new file. I just transferred over my void setup information from the beginning of the original code i wrote.

The first error i got was that buttonPin was not declared (which was no big deal for me to handle). I made button pin #4 in the setup.

Now i am getting the error that “turnsRunning” is not declared in this scope. I am not sure how to declare this, or fix it, or whatever i need to do. What exactly is “turnsRunning”?

So when you are looking at some code, you write down every line and try to figure out what each line does? That seems like a good idea. I don’t think that i fully understand the cycle that the code runs in. The way that i picture it is that it runs down line by line in void loop until it hits an “if” statement that is true then it starts looping just in that defined “if” parameters until the end of time?

here is the code i have now:

  // put your setup code here, to run once:
  // 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);
int buttonPin = 4; // set pin 4 as button pin
int BUZZ = 6; // set pin 6 to Buzzer
int numberOfTurns = 100; // set the desired number of turns with a variable name numberOfTurns

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

void setup(){

  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output
  digitalWrite (BUZZ, LOW); // set the buzzer pin as low

  Serial.begin(9600); // set baud rate

  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD

  lcd.begin(20, 4);  // set up the LCD's number of columns and rows:

  Serial.begin(9600);   // initialize the serial communications:

  lcd.setCursor(1, 0);   // set the position of the title text (1 colum 0 row)

  lcd.print("Coil Turns Counter");   // title text
  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  = 0; // i dont know what this does
long newPosition  = 0; // i dont know what this does
byte countNum;

void loop() {
    byte btnState = digitalRead(buttonPin);
    if (btnState == LOW && turnsRunning == false) {
        digitalWrite(BUZZ,LOW);
        turnsRunning = true;
        countNum = 100;
            // initialize oldPosition to be the same as newPosition
        newPosition = myEnc.read();
        oldPosition = newPosition;
    }
    if (turnsRunning == true) {
        runRotations();
    }
}

void runRotations() {
    newPosition = myEnc.read(); // read  from enc library and establish it is a long number
    if (newPosition - oldPosition > 204) {
        countNum-- ;
        oldPosition = newPosition;
    }
    if (countNum == 0) {  // sets the relay to switch at countdown to zero

        digitalWrite(BUZZ,HIGH);
        lcd.clear();
        lcd.setCursor(8,1);
        lcd.print("DONE");
        turnsRunning = false; 
    }
 }

turnsRunning should be defined as boolean as it only has true or false values

put

boolean turnsRunning = false;

immediately after

int numberOfTurns = 100;

…R

Where do i need to put it? When i put it into void loop, it says in void turnsRunning that turnsRunning is not declared in this scope. If i put both lines you wrote into void setup it has the same error for void loop.

The line

int numberOfTurns = 100;

is already in YOUR code in Reply #29

I told you to put the new line after it.

...R

Robin2: the line

int numberOfTurns = 100;

is already in YOUR code in Reply #29

I told you to put the new line after it.

I know it is just text so i cant tell how you are writing it, but i always get an feeling of irritation when you reply to my questions. What is the point of being on here helping people if you are unhappy doing it?? People that act like this make it hard for others to ask questions for fear of that exact response.

If not then i am probably being soft. I will do as you asked and try it out. Thanks

I realize that i was probably being overly sensitive. :'(

you have been a lot of help, i am just not used to forums and trying to interpret what people type. I get to feeling like people on here are always getting impatient with teaching.

Any who... i figured it out. I just needed to add

myEnc.write(0)

to set everything back to zero!!!!!!!!!!! :grin:

// 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);

int reStart = 4; //set the restart button to pin 4

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

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

int buttonState = 0;     // variable for reading the pushbutton status

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


void setup() {   // put your setup code here, to run once:

  pinMode ( reStart, INPUT); // sets the restart button pin as input

  pinMode ( BUZZ, OUTPUT ); // set my Buzzer pin as output

  digitalWrite (BUZZ, LOW); // set the buzzer pin as low

  Serial.begin(9600); // set baud rate

  Serial.println("Coil Turn Counter"); // printing title in "serial print" not on LCD

  lcd.begin(20, 4);  // set up the LCD's number of columns and rows:

  Serial.begin(9600);   // initialize the serial communications:

  lcd.setCursor(1, 0);   // set the position of the title text (1 colum 0 row)

  lcd.print("Coil Turns Counter");   // title text
  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");
}

void loop() {    // put your main code here, to run repeatedly:

  buttonState = digitalRead(reStart); // variable for reading the state of button pin

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

  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 long 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

    lcd.setCursor(8, 2);   // set position of counting digits ( row 2, colum 8)

    lcd.print(numberOfTurns - x);   // printing the values as it counts down row 3, column 8

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

      digitalWrite(BUZZ, HIGH); // set buzzer pin high

      lcd.clear(); // clear the lcd and print done

      lcd.setCursor(8, 1); // set the curson position

      lcd.print("DONE"); // print "done" to lcd

    }
    if (buttonState == HIGH) {

      myEnc.write(0); // sets the encoder read value back to zero VERY IMPORTANT

      digitalWrite(BUZZ, LOW); // turn off buzzer

      lcd.clear(); // clears the lcd

      lcd.print("Number Of Turns Left"); //re prints the title line

      lcd.setCursor(8, 2);   // set position of counting digits ( row 2, colum 8)

      lcd.print(numberOfTurns - x);   // printing the values as it counts down row 3, column 8

    }
  }
}

jeffrey-davis: What is the point of being on here helping people if you are unhappy doing it?? People that act like this make it hard for others to ask questions for fear of that exact response.

I'm glad you now have a solution.

I am not unhappy providing advice. But I do think it is reasonable for the person seeking assistance to put in some effort to use that advice. And to say, clearly, when they do not understand the advice.

It is almost impossible to know the level of experience of the person asking the question. It would be very time consuming to write every reply as if the question was asked by someone who knows zero.

In your case I was surprised when you asked where to put the code when I had specifically said where to put it. And I assumed (perhaps wrongly) that you had made no attempt to find the existing line in your code.

...R

jeffrey-davis: So when you are looking at some code, you write down every line and try to figure out what each line does? That seems like a good idea.

Well, you read every single line of code and make sure you understand exactly what each line does.

I don't think that i fully understand the cycle that the code runs in. The way that i picture it is that it runs down line by line in void loop until it hits an "if" statement that is true then it starts looping just in that defined "if" parameters until the end of time?

No. Your understanding is incorrect.

It processes every line of code one after the other. There are two major exceptions to this in the Arduino (plus others, but they are advanced cases).

In perhaps over-simplified terms, the Arduino starts by calling setup(). It processes all the commands in setup, then calls loop(). It is loop() that is called continuously by the Arduino. So, the Arduino processes all lines until the end of the loop function, then calls loop() again automatically. "If" statements just determine whether particular lines are executed, or skipped, each time through the loop().

"While" statements can make certain lines repeat indefinitely, since that is what they may be telling the Arduino to do.

arduinodlb:
“If” statements just determine whether particular lines are executed, or skipped, each time through the loop().

“While” statements can make certain lines repeat indefinitely, since that is what they may be telling the Arduino to do.

So the whole code in loop is ran thru even while an “if” statement is true (besides the other “if” statements that are not true i mean)? So if i had the example:

void loop(){
dogs running;
if (cats meow){ Pigs Snorting}
}

if the cats started meowing, the dogs would continue running, and the only difference would be that the pigs are now snorting? Is there a way to only do something instead of the main loop when a certain parameter is met?

Also, in my code i now have the issue of my LCD printing “DONE” at the end repeatedly. Is there a way to make it print just once? I tried to use a delay to slow it down a bit but then the program did not recognize my button pushes until certain key moments.

Thanks,

Jeff Davis

jeffrey-davis: So the whole code in loop is ran thru even while an "if" statement is true (besides the other "if" statements that are not true i mean)?

yes

So if i had the example:

void loop(){ dogs running; if (cats meow){ Pigs Snorting} }

if the cats started meowing, the dogs would continue running, and the only difference would be that the pigs are now snorting?

yes

Is there a way to only do something instead of the main loop when a certain parameter is met?

Not really. The only thing you could do is a while loop, or equivalent, but that's generally not a good idea unless you understand what you are doing.

Also, in my code i now have the issue of my LCD printing "DONE" at the end repeatedly. Is there a way to make it print just once? I tried to use a delay to slow it down a bit but then the program did not recognize my button pushes until certain key moments.

Yes. Just have a global variable called boolean done = false;. Set it to true the first time through, and only print Done when it is false (just before setting it to true). This is when you use "if" statements.