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
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.
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 ?
#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);
}
}
}
}
}
#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);
}
}
}
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.
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.
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.
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.))
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.
I tried both methods both compile, serial monitor looks fine but the still don't do anything. Is it still in the program?
#include <Servo.h>
Servo m1;
const byte buttonPin = A2;
const int ledPin = 9;
int writeValues[5] = {1000, 1250,1500,1750,2000};
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 == LOW) {
// 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;
{
if (buttonState == LOW);
m1.writeMicroseconds(writeValues[5]);
}
}
#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);
}
// save the current state as the last state, for next time through the loop
lastButtonState = buttonState;
{
if (buttonState == HIGH);
byte index = buttonPushCounter % 5;
m1.writeMicroseconds(1000 + (index * 250));
}
}