using pullstime

Now that you have got the button press counting working does the program do what you want ?

I'm confused.

The % operator returns the remainder when one number is divided by another.

The reference says (my emphasis):

Syntax
remainder = dividend % divisor;
Parameters
remainder : variable. Allowed data types: int, float, double
dividend : variable or constant. Allowed data types: int
divisor : non zero variable or constant. Allowed data types: int

All OP's lines like this:

if (buttonPushCounter % 0 == 4)

.... are logically meaningless and mathematically inadmissible, since x%0 includes division by zero.

OP presumably has some successful results of the button pressing, and I find that in fact the result is always the dividend. In OP's case, that's the buttonPushCounter , which is probably what they want anyway.

Try this:

void setup()
{
  Serial.begin(9600);
  while (!Serial) {}

  int myVar1 = 11;
  int myVar2 = 0;
  int myResult1 = myVar1 % myVar2; //dividing by 0 here
  Serial.println(myVar1);
  Serial.println(myVar2);
  Serial.println(myResult1);       //returns myVar1

  myVar1 = 999;
  myResult1 = myVar1 % myVar2; //dividing by 0 here
  Serial.println(myVar1);
  Serial.println(myVar2);
  Serial.println(myResult1);       //returns myVar1

} //setup

void loop() {} //loop

I get this:

11
0
11
999
0
999

That's very odd, to me. I don't know what the C/C++ standard is supposed to do with division by 0, but it's allowing OP to get the result they expect, since I think they just want the number of button presses.

In that case:

if (buttonPushCounter % 0 == 4)

... which is meaningless but seems to provide the expected result, can just be replaced with:

if (buttonPushCounter == 4)

Can some C/C++ guru describe why x%0 returns x when division by zero is undefined? Is it by design?, or a bug in the compiler?

Can some C/C++ guru describe why x%0 returns x when division by zero is undefined? Is it by design?, or a bug in the compiler?

I am certainly not a guru, but it is the responsibility of the programmer to ensure that division by zero does not occur or if it does to ignore the result.

Lines like

if (buttonPushCounter % 0 == 1)

are just plain wrong, but the OP is just thrashing about as you can see throughout the thread. If he/she ever gets back here I am going to suggest a change that not only corrects the mistake but also considerably reduces the code

I await with bated breathe

UKHeliBob:
it is the responsibility of the programmer to ensure that division by zero does not occur or if it does to ignore the result.

Good point, C/C++ being a "trust the programmer" language.

One of the first, if not the actual first, programs I ever wrote was in Fortran in 1974, to solve a quadratic. There of course one needs to check it is quadratic (non-zero "a") else The Formula can't be used since "a" is in the denominator. So yeah we all learned to trap that by checking "a" and printing "not a quadratic" if it was zero. But if the code didn't include such a check, hours later when you eventually got your output in your pigeon hole, there would have been a run-time "division by real zero" error.

Yes I here, what's the change?

Matyk:
Yes I here, what's the change?

Before we start maing changes, do you understand why your current code does not work to produce the correct values to be writen to m1 based on the value of buttonPushCounter ?t

Have you tried printing the value that you are writing to m1 ?

I did not print but probably would nit have been much use anyway as the motors did not even budge

OK. Let's plunge on as you don't seem interested as to why it does not work

When you do

variableA = variableB % x

then variableA is assigned the remainder of variableB divided by the value of x

Change your code to add 2 extra print lines like this

      Serial.println(buttonPushCounter);
      Serial.print("buttonPushCounter % 5 = ");
      Serial.println(buttonPushCounter % 5);

Upload the code and press the button several times and post the output here

No, I am interested(this project has been going on for a long while)but it is just hard for me.

#include <Servo.h>
Servo m1;
const byte buttonPin = A2;
const int ledPin = 9;
const int mypulsebase =  (1000);
const int pulseIncrement = (250);
const int myPulsetime =  mypulsebase;


int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);

}

void loop() {
  buttonState = digitalRead(buttonPin);

   if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
     Serial.println(buttonPushCounter);
      Serial.print("buttonPushCounter % 5 = ");
      Serial.println(buttonPushCounter % 5);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;

 
  if (buttonPushCounter == 1) {
    m1.attach(9);
    m1.writeMicroseconds(myPulsetime + pulseIncrement);
    delay(1);
  } else {
    m1.writeMicroseconds(1000);
    delay(1);



    if (buttonPushCounter == 2) {
      m1.attach(9);
      m1.writeMicroseconds(myPulsetime + pulseIncrement + pulseIncrement);
      delay(1);
    } else {
      m1.writeMicroseconds(1000);
      delay(1);



      if (buttonPushCounter == 3) {
        m1.attach(9);
        m1.writeMicroseconds(myPulsetime + pulseIncrement + pulseIncrement + pulseIncrement);
        delay(1);
      } else {
        m1.writeMicroseconds(1000);
        delay(1);


        if (buttonPushCounter == 4) {
          m1.attach(9);
          m1.writeMicroseconds(myPulsetime + pulseIncrement + pulseIncrement + pulseIncrement + pulseIncrement);
          delay(1);
        } else {
          m1.writeMicroseconds(1000);
          delay(1);





        }
      }
    }
  }
}

post the output here

1
1
buttonPushCounter % 5 = 1
off
2
buttonPushCounter % 5 = 2
off
3
buttonPushCounter % 5 = 3
off
4
buttonPushCounter % 5 = 4
off
5
buttonPushCounter % 5 = 0
off
6
buttonPushCounter % 5 = 1
off
7
buttonPushCounter % 5 = 2
off
8
buttonPushCounter % 5 = 3
off
9
buttonPushCounter % 5 = 4
off
10
buttonPushCounter % 5 = 0

As you can see buttonPushCounter % 5 produces a number between 0 and 5

So you could use this value to set what you write to m1 like this

byte index = buttonPushCounter % 5;
if (index == 0)
  {
     m1.writeMicroseconds(something);
  }
else if (index == 1)
  {
     m1.writeMicroseconds(somethingElse);
  }
else if (index == 2)
  {
     m1.writeMicroseconds(anotherValue);
  }

Try that and get it working then I will suggest an even better way to do it

Compiles, no error

#include <Servo.h>
Servo m1;
const byte buttonPin = A2;
const int ledPin = 9;

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT_PULLUP);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);

}

void loop() {
  buttonState = digitalRead(buttonPin);

  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println(buttonPushCounter);
      Serial.print("buttonPushCounter % 5 = ");
      Serial.println(buttonPushCounter % 5);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }

  lastButtonState = buttonState;

  {
    byte index = buttonPushCounter % 5;
    if (index == 0)
    {
      m1.writeMicroseconds(1000);
    }
    else if (index == 1)
    {
      m1.writeMicroseconds(1250);
    }
    else if (index == 2)
    {
      m1.writeMicroseconds(1500);
    }
    else if (index == 3)
    {
      m1.writeMicroseconds(1750);
    }
      else if (index == 4)
      {
        m1.writeMicroseconds(2000);
      }
  }
}
pinMode(buttonPin, INPUT_PULLUP);
buttonState = digitalRead(buttonPin);
if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) { // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<

That code's actually counting releases. With pullups enabled, pressed is low, yet you're looking for a high after a change, which is a release not a press.

everything is working what now?

Well every press has a release, so if you count releases that's numerically the same as counting presses, but it's not strictly a buttonPushCounter, it's a buttonReleaseCounter.

This whole set of nested ifs:-

{
    byte index = buttonPushCounter % 5;
    if (index == 0)
    {
      m1.writeMicroseconds(1000);
    }
    else if (index == 1)
    {
      m1.writeMicroseconds(1250);
    }
    else if (index == 2)
    {
      m1.writeMicroseconds(1500);
    }
    else if (index == 3)
    {
      m1.writeMicroseconds(1750);
    }
      else if (index == 4)
      {
        m1.writeMicroseconds(2000);
      }
  }

Can be replaced with two lines of code:-

byte index = buttonPushCounter % 5;
m1.writeMicroseconds(1000 + (index * 250);

To explain it fully buttonPushCounter % 5 returns either 0, 1, 2, 3 or 4 to index therefore you have the following microsecond values written to m1:-

If index = 0, index * 250 is 0 so 1000 is written to m1.
If index = 1, index * 250 is 250 so 1250 is written to m1.
If index = 2, index * 250 is 500 so 1500 is written to m1.
If index = 3, index * 250 is 750 so 1750 is written to m1.
If index = 4, index * 250 is 100 so 2000 is written to m1.

Much simpler than a whole pile of nested ifs.

Ian

IanCrowe:
Much simpler than a whole pile of nested ifs.

Perhaps that's what this was going to be:

UKHeliBob:
Try that and get it working then I will suggest an even better way to do it

@IanCrowe, I think UKHeliBob has a plan here: he's walked this OP through a process for a couple of days now, and with all due respect to the OP, he (the OP) is struggling, and perhaps it would be better to leave UKHB to it....

(I've been here since #5, and just chipped in with parts where I saw errors, like the x%0 thing and the counting of releases not presses. Your suggestion is of course a very valid one, I just think it's best to let UKHB go with this... (imo, of course.))

Matyk:
everything is working what now?

Now we move on to reducing your code by using the number in the index variable to do some "magic"

As you have seen you can use it to calculate the value to write to m1 and that is one option that I had considered suggesting, and it works but the relationship between the number of button presses and the value written is fixed which may not always be what is wanted and it required the Arduino to do the caculation each time through loop()

I was going to suggest using an array of values to be written to m1 based on the value of index.

For the sake of Matyk, an array is a way of holding a list of several values of the same type and accessing the one you want using its place in the list. The index variable gives us a convenient way to access the required value.

So, how does it work ?
Declare a global array of ints like this

int writeValues[5] = {123, 234, 345, 456, 567};  //fill in the values that you really want

NOTE: This array has 5 spaces numbered 0 to 4 NOT 1 to 5

Then, once you have the value of index you can do
m1.writeMicroseconds(writeValues[index]);

This uses index to look up the value to write. Because you have control of the values in the array the value written for each button press is fully under your control and does not need to be linear.

Give both methods a try