Confusing increment behaviour - c

int i = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
if(i == 1){
Serial.print(i);
}
i++;
}
This is intended to only print the value of i once. Why does it keep printing 1 forever?
This code works properly only writing i once:
int i = 1;
void setup() {
Serial.begin(9600);
}
void loop() {
if(i == 1){
Serial.print(i);
}
i = 2;
}

Assuming loop() is called in a loop:
i will overflow in the first example.
In the second example it is fixed to the value of 2 after the first iteration.

You may also want to add some delay because sometimes you can miss the first Serial.println();.
Something like that:
int i = 1;
void setup() {
Serial.begin(9600);
delay(1000); //wait for one second
}
Hope it helps!

If you want your first example to work longer. Change "int" to "long".
int can only store 2 bytes. -32,768 to 32,767. You will reach this number really fast.
long can store 4 bytes. -2,147,483,648 to 2,147,483,647. This will take a whiiiile.

Related

Arduino: detecting buttons pressed inside a while loop

I have been trying to write a code to basically add points to a score whenever I pressed a button while a certain amount of time is running down. The problem I am finding is that it doesn't detect when the button is pressed while the time is decreasing, in fact it can only detect when the time starts to decrease and then it doesn't matter at which state the button is it will continue to add to the score. Anyway here is the main code:
void loop() {
buttonState01 = digitalRead(button01);
buttonState02 = digitalRead(button02);
buttonState03 = digitalRead(button03);
if (buttonState01){
time = 3000;
while(time > 0){
if (buttonState02){
score += 10;
Serial.println(score);
}
time--;
Serial.println(time);
}
}
}
And here is the full code if needed:
int button01 = 4;
int button02 = 3;
int button03 = 2;
int buttonState01 = 0;
int buttonState02 = 0;
int buttonState03 = 0;
float time;
int score;
void setup() {
score = 0;
time = 0;
pinMode(button01, INPUT);
pinMode(button02, INPUT);
pinMode(button03, INPUT);
Serial.begin(9600);
}
void loop() {
buttonState01 = digitalRead(button01);
buttonState02 = digitalRead(button02);
buttonState03 = digitalRead(button03);
if (buttonState01){
time = 3000;
while(time > 0){
if (buttonState02){
Serial.println("Points");
}
time--;
Serial.println(time);
}
}
}
You should read the status of a button inside the while loop. Like this:
while(time > 0)
{
buttonState02 = digitalRead(button02);
if (buttonState02){
Serial.println("Points");
}
time--;
Serial.println(time);
}
And in your code, there is no logic to add points to the score.
A hardware interrupt would do exactly what you need.
Attach an interrupt routine to the pin your button is linked to, and get it to set the 'score' variable. Make sure you introduce some sort of timeout to avoid button-bounce (I.e. set LastTimeIncremented when you increase the score, and only increment score if LastTimeIncremented is more than 1 second ago)
This way the score will always be set regardless of what else the program may be doing.
Information on this can be found in the Arduino https://www.arduino.cc/en/Reference/attachInterrupt
The example on that page would do exactly what you want, just replace 'blink' with 'incrementScore' and you're pretty much done
const byte ledPin = 13;
const byte interruptPin = 2;
int score = 0;
int increment = 1;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), incScore, RISING);
}
void loop() {
digitalWrite(ledPin, state);
}
void incScore() {
score = score+increment;
// add anti-bounce functionality here
}

Arduino creating delay function

I am trying to make my own delay function. Briefly mydelay function is calling toggled function every secs seconds. The code is not well written, i know (this is the first version). But i am just trying to get it work properly. Then i will refactor it. But i have some unexpected bugs. First time the loop in x function is working properly. It is printing "I am in while" for 1 second and then it prints "Im ending mydelay" which is the behaviour i want. But after finishing the loop in x. The second time when it loops. It enters the mydelay function (that is ok). But then it is not printing "I am in while" at all. It just prints "Im ending mydelay" which is not good.
Here is the code:
#include <Arduino.h>
int led = 7;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop() {
x();
Serial.println("Im ending main loop");
}
void x() {
for (int i = 0; i <= 10; i++) {
mydelay(led, 0, 1);
mydelay(led, 1, 1);
}
}
void mydelay(int pin, int hol, int secs) {
int starttime = millis();
while ((millis() - starttime) <= (secs * 1000)) Serial.println("I am in while");
toggled(pin, hol);
Serial.println("Im ending mydelay");
}
void toggled(int pin, int hol) {
digitalWrite(led, hol);
}
Change int starttime = millis(); to unsigned long starttime = millis();. This might be the problem because if you are using an int, your program will go crazy after 32 seconds. That is a problem because an int can only hold a number going from -32,768 to 32,767 .
Also, you might as well try this:
while ((millis() - starttime) <= (secs * 1000))
{
Serial.println("I am in while");
}
maybe you can try to reset the millis using something like this, I don't have an arduino so it's not tested but hopefully it can help.
extern volatile unsigned long timer0_millis;
unsigned long reset = 0;
#include <Arduino.h>
int led = 7;
void setup() {
Serial.begin(9600);
pinMode(led, OUTPUT);
}
void loop(){
x();
Serial.println("Im ending main loop");
setMillis(reset);
}
void setMillis(unsigned long new_millis){
uint8_t oldSREG = SREG;
cli();
timer0_millis = new_millis;
SREG = oldSREG;
}
void x() {
for (int i = 0; i <= 10; i++) {
mydelay(led, 0, 1);
mydelay(led, 1, 1);
}
}
void mydelay(int pin, int hol, int secs) {
int starttime = millis();
while ((millis() - starttime) <= (secs * 1000)) Serial.println("I am in while");
toggled(pin, hol);
Serial.println("Im ending mydelay");
}
void toggled(int pin, int hol) {
digitalWrite(led, hol);
}

Arduino millis not work

I have written a huge program for Arduino.
I have tested each function individually, and all go fine except the function where I need millis().
Now carry the code block that I encounter any difficulties.
the variable T contains the number in seconds for this is multiplied by 1000
void onResistance(){
Input = sensors.getTempC(tempSensor);
sensors.requestTemperatures(); // prime the pump for the next one - but don't wait
digitalWrite(RelayPin, HIGH);
//more code
Input = sensors.getTempC(tempSensor);
sensors.requestTemperatures(); // prime the pump for the next one - but don't wait
if(Input<Setpoint){ onResistance(); }
else{ digitalWrite(RelayPin, LOW); istru++; return ; }
return ;
}
void statTemp(){
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > ttemp){
previousMillis = currentMillis;
Input = sensors.getTempC(tempSensor);
sensors.requestTemperatures();
lcd.setCursor(0,1);
lcd.print(F("T. Att.:"));
lcd.print(Input);
lcd.write(1);
lcd.print(F("C"));
if (Input<Setpoint) {
digitalWrite(RelayPin, HIGH);
statTemp();
} else if(Input>Setpoint || Input == Setpoint) {
digitalWrite(RelayPin, LOW);
statTemp(); }
} else if(currentMillis - previousMillis < ttemp) { playShortBeep(); istru++; return; }
return ;
}
void startFan(){
Input = sensors.getTempC(tempSensor);
sensors.requestTemperatures(); // prime the pump for the next one - but don't wait
digitalWrite(FAN_PIN, HIGH);
//more code
Input = sensors.getTempC(tempSensor);
sensors.requestTemperatures(); // prime the pump for the next one - but don't wait
if(Input>Tm){ startFan(); }
else{ digitalWrite(FAN_PIN, LOW); istru++; return ; }
return ;
}
void controll(){
if(!start)
return ;
if(start){
if(istru==0){
onResistance();
}
if(istru==1){
ttemp = (T * 1000) + millis() ;
statTemp();
}
if(istru==2){
startFan();
}
if(istru==3){
start =false;
opState = OFF;
playShortBeep();
playShortBeep();
playShortBeep();
istru=0;
}
}
delay(100);
return ;
}
I need for the time T the function statTemp remains running conducting checks if written in it.
sorry for my bad english
So you want to stay in the function statTemp() until time T has passed?
Then something like this might work
void statTemp(){
unsigned long currentMillis;
unsigned long enteringMillis = millis();
while (((currentMillis = millis()) -enteringMillis) < T)
{
if(currentMillis - previousMillis > ttemp){
etc etc etc....
}
return ;
}
Notice the MIGHT. I don't know if millis is updated at every timer interrupt or just in the loop function; in the latter case, you will be stuck forever in the function.
Consequently i suggest you not to do this, but think at another approach: an FSM which handles the function to be executed. It's a cleaner way to proceed and less error-prone.
Bye
EDIT:
Here is a complete working example. In this example, the function myfunc is executed for 10 seconds; during this time the board performs some actions (in this example serial output). When 10 seconds pass, the program goes on, thus repeating the loop function.
unsigned long previousTime;
void myfunc();
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("I'm in the loop function");
myfunc();
}
void myfunc()
{
unsigned long currentTime;
unsigned long enteringTime = millis();
while(((currentTime = millis()) - enteringTime) < 10000)
{
if(currentTime - previousTime > 1000)
{
previousTime = currentTime;
Serial.println("I'm in the custom function");
}
}
}
HOWEVER my suggestion is still the same: instead of blocking the execution inside of a function, use a finite state machine; it's much more flexible and easier to understand, implement and edit.

Arduino integer array returns value of 3 for index 0 always

I wrote this sketch to send codes to a speakjet sound processor. It will store any number of three digit integers from 128 to 254. I type them into the serial monitor and hit enter after each one. it is stored in an array, and after 900 is entered, the values stored in the array are sent to the speakjet and also read back to the serial monitor. The issue I'm having is that the array will return a value of three for index 0 every time. I have no clue as to why this is.
Here is the code.
int in=0;
int code;
int phrase[] {};
int x=0;
String stack="";
void setup() {
Serial.begin(9600);
Serial1.begin(9600);
Serial.println("Ready");
}
void loop() {
while (Serial.available()>0) {
int inbyte = Serial.read();
if (in<=2);
{
stack += (char)inbyte;
in++;
//Serial.println(stack);
//Serial.println(in);
}
if (in==3) {
if (stack == "900") {
for(int i=0;i<x;i++) {
Serial1.write(phrase[i]);
Serial.println(i);
Serial.println(phrase[i]);
Serial.println();
}
stack="";
x = 0;
in = 0;
Serial.println("Ready");
} else {
phrase[x]=0;
int code = stack.toInt();
if (code < 128) {
code = 253;
}
phrase[x]=code;
Serial.println(x);
Serial.println(phrase[x]);
x++;
in=0;
Serial.write(code);
Serial.println();
stack = "";
}
}
}
}
Thanks for any advice, or help with this matter.
Brewer.
well, first of all, I noticed while reformatting your code you've got a typo here:
if (in<=2); // <-- if the condition is true, it does nothing
{
// this block of code always gets executed
stack += (char)inbyte;
in++;
}
Then I find it really surprising that you can store anything at all in your array:
int phrase[] {};
as it is allocated no memory to store something.
I guess those two errors alone can explain a few undefined behaviors for your program. Given those basic things are totally wrong, I did not analyze the validity of your algorithm itself, because it's being late, and I'm about to go to sleep ;-)

Arduino won't read the buttons

This program is intended to count the number of button1 presses and then break out of the loop with the button2 press. The button2 is like an enter key.
If I run what is inside the do while statement by itself without the do while it will count up each button push. I used this to verify that I have constructed my circuit correctly. but for some unknown reason if I put the same code into a do while or just a while then it does not read the pins. It will loop inside the do while but never exit to that done statement at the end. If I start the arduino as I press down either of the two buttons then it will register that a button is being pressed, but as soon as I let go then it will do nothing again. Please tell me what I am doing wrong.
My code
int ledpin = 11;
int button1pin = 7;
int button2pin = 2;
int button1counter = 0;
int button1state = 0;
int lastButton1state = 0;
int button2state = 0;
int lastButton2state = 0;
int button2counter = 0;
void setup() {
// initialize the digital pin as an output.
pinMode(button1pin, INPUT);
pinMode(button2pin, INPUT);
Serial.begin(9600);
}
void loop() {
button1state = digitalRead(button1pin);
button2state = digitalRead(button2pin);
do {
if (button1state != lastButton1state) {
if (button1state == HIGH) {
button1counter++;
Serial.print("number of button 1 pushes: ");
Serial.println(button1counter);
}
lastButton1state = button1state;
}
} while(button2state == LOW);
Serial.println("done");
}
Thanks I changed it and of course your right. However, I can't quite understand why your right. Let me comment the code with my understanding and please correct me if I'm wrong.
void setup() {
pinMode(button1pin, INPUT);//tells comp to make button 1 input
pinMode(button2pin, INPUT);//tells comp to make button 2 input
Serial.begin(9600);
}
void loop() {
button1state = digitalRead(button1pin);//tells comp to begin reading pin? but for how long?
button2state = digitalRead(button2pin);
do {
You read your button state outside of your while loop, so your button1state and button2state are never updated, that is why you enter in an infinite loop just do that little change:
void loop() {
do {
button1state = digitalRead(button1pin);
button2state = digitalRead(button2pin);
if (button1state != lastButton1state) {
if (button1state == HIGH) {
button1counter++;
Serial.print("number of button 1 pushes: ");
Serial.println(button1counter);
}
lastButton1state = button1state;
}
} while(button2state == LOW);
Serial.println("done");
}

Resources