How to exit or break from 'for loop' on Arduino C Program - for-loop

I'm not new to the programming world, but for last 2 weeks I'm working with Arduino C++. I have a strange problem. In general, I have a 7-segment display that will act as an up counter when the condition is 01, down counter when the condition is 10, 00 for reset to zero, and 11 for stop (pause in that number).
The problem is, when the up or down counter is still counting and I've change the state, the 7-segment is still counting! Besides that, I've printed the status of state when state is changed, but nothing happens. I think maybe there's mistakes in my code, I need some advice from you guys. Here is my code:
*FYI, I've try to use break, return, also call loop(), but nothing happens
*saklar1 = switch1
*saklar2 = switch2
#include <SevSeg.h>
SevSeg sevseg;
const int saklar1 = 2;
const int saklar2 = 3;
void setup() {
byte sevenSegments = 1;
byte commonPins[] = {};
byte sevenPins[] = {11, 10, 9, 8, 7, 6, 5, 4};
bool resistor = true;
sevseg.begin(COMMON_CATHODE, sevenSegments, commonPins, sevenPins, resistor);
sevseg.setBrightness(90);
pinMode(saklar1, INPUT);
pinMode(saklar2, INPUT);
Serial.begin(9600);
}
void loop() {
checking(digitalRead(saklar1), digitalRead(saklar2));
}
void checking(bool saklar1, bool saklar2){
if (saklar1 == LOW && saklar2 == LOW) {
setSevSeg(0);
} else if (saklar1 == LOW && saklar2 == HIGH) {
for (int i=0; i<=9; i++) {
setSevSeg(i);
if (saklar1 != LOW || saklar2 != HIGH) {
Serial.println("STATE CHANGED"); //THIS LINE IS NOT EXECUTED OR PRINTED
checking(digitalRead(saklar1), digitalRead(saklar2));
}
}
} else if (saklar1 == HIGH && saklar2 == LOW) {
for (int i=9; i>=0; i--) {
setSevSeg(i);
if (saklar1 != HIGH || saklar2 != LOW) {
checking(digitalRead(saklar1), digitalRead(saklar2));
}
}
} else if (saklar1 == HIGH && saklar2 == HIGH) {
delay(100); //Stop
}
}
void setSevSeg(int num) {
sevseg.setNumber(num);
sevseg.refreshDisplay();
delay(500); //1 detik
}

In the following code, the control exits the for loop when the sensor value exceeds the threshold.
Reference: [https://www.arduino.cc/reference/en/language/structure/control-structure/break]
int threshold = 40;
for (int x = 0; x < 255; x++) {
analogWrite(PWMpin, x);
sens = analogRead(sensorPin);
if (sens > threshold) { // bail out on sensor detect
x = 0;
break;
}
delay(50);
}

Related

Holding a push button for 3 second in a for loop

I have a button that basically has two functions. The aim is:
First push will blink a LED 15 times.
If someone holds the button longer than 3 seconds while the LED is blinking, it should stop and go back to the initial.
So I checked the Arduino's hold a button page and came up with this code. The problem is that I can not properly stop the blinking. The line Serial.println("DONE!!"); never works.
Where should I check if the button is held or not and should I use interrupt to end the for loop?
Here is my code:
int inPin = 2; // the pin number for input (for me a push button)
int ledPin = 9;
int current; // Current state of the button
// (LOW is pressed b/c I'm using the pullup resistors)
long millis_held; // How long the button was held (milliseconds)
long secs_held; // How long the button was held (seconds)
long prev_secs_held; // How long the button was held in the previous check
byte previous = LOW;
unsigned long firstTime; // how long since the button was first pressed
long millis_held2; // How long the button was held (milliseconds)
long secs_held2; // How long the button was held (seconds)
long prev_secs_held2; // How long the button was held in the previous check
byte previous2 = LOW;
unsigned long firstTime2; // how long since the button was first pressed
void setup() {
Serial.begin(9600); // Use serial for debugging
pinMode(ledPin, OUTPUT);
digitalWrite(inPin, INPUT); // Turn on 20k pullup resistors to simplify switch input
}
void loop() {
current = digitalRead(inPin);
// if the button state changes to pressed, remember the start time
if (current == HIGH && previous == LOW && (millis() - firstTime) > 200) {
firstTime = millis();
}
millis_held = (millis() - firstTime);
secs_held = millis_held / 1000;
// This if statement is a basic debouncing tool, the button must be pushed for at least
// 100 milliseconds in a row for it to be considered as a push.
if (millis_held > 50) {
// check if the button was released since we last checked
if (current == LOW && previous == HIGH) {
// HERE YOU WOULD ADD VARIOUS ACTIONS AND TIMES FOR YOUR OWN CODE
// ===============================================================================
//////////////////////////////////////////////////////// Button pressed Blink 15 times.
if (secs_held <= 0) {
for (int i = 0; i < 15; i++) {
ledblink(1, 750, ledPin);
current = digitalRead(inPin);
if (current == HIGH && previous == LOW && (millis() - firstTime2) > 200) {
firstTime2 = millis();
}
millis_held2 = (millis() - firstTime2);
secs_held2 = millis_held2 / 1000;
if (millis_held2 > 50) {
Serial.print("previousA ");
Serial.print(previous);
Serial.print(" currentA ");
Serial.println(current);
current = digitalRead(inPin);
if (current == HIGH && previous2 == HIGH) {
Serial.println("ALMOST! ");
Serial.println(secs_held2);
if (secs_held2 >= 2 && secs_held2 < 6) {
Serial.println("DONE!!");
}
}
}
previous2 = current;
prev_secs_held2 = secs_held2;
}
}
}
}
previous = current;
prev_secs_held = secs_held;
}
void ledblink(int times, int lengthms, int pinnum) {
for (int x = 0; x < times; x++) {
digitalWrite(pinnum, HIGH);
delay (lengthms);
digitalWrite(pinnum, LOW);
delay(lengthms);
}
}
This is how it would be done without using delay():
int inPin = 2;
int ledPin = 9;
long pressTimer;
long blinkTimer;
long blinkHalfDelay = 500; //milliseconds
int blinkCount = 0;
int blinkLimit = 15;
bool blinkFlag = false;
bool blinkLatch = true;
bool currentBtnState = false;
bool lastBtnState = false;
void setup() {
}
void loop() {
lastBtnState = currentBtnState;
currentBtnState = digitalRead(inPin);
//on rising edge, start timers
if(currentBtnState==true && lastBtnState==false)
{
pressTimer = millis();
}
//debounce activation
if(currentBtnState==true && !blinkFlag && millis()-pressTimer > 50)
{
blinkTimer = millis();
blinkCount = 0;
blinkLatch = true;
blinkFlag = true;
//functional execution would go here
}
if(currentBtnState = false || (millis()-pressTimer>3000 && currentBtnState == true))
{
blinkCount=blinkLimit;
blinkLatch = false;
}
if(blinkFlag == true)
{
if(millis()-blinkTimer > blinkHalfDelay)
{
blinkTimer = millis();
if(blinkLatch)
{
digitalWrite(pinnum, HIGH);
}
else
{
digitalWrite(pinnum, LOW);
blinkCount+=1;
}
}
if(blinkCount>blinkLimit)
{
blinkFlag = false;
digitalWrite(pinnum, LOW);
}
}
}
ps: sorry for not correcting your code directly, but it was kinda hard to read...

Arduino-uno project [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm currently working with an Raspberry Pi for a exercise.
I'm working with the following on the breadboard:
5 LED's
2 Switches
My following code is supposed to work as follows:
With the first button you can select the next LED and with the second button you can put the selected LED on/off. When you're at the last LED it gives a true or a false (on or off) with the following output:
Circuits
I don't see what's wrong with my code:
//const variables
const int leds[] = {3, 5, 6, 9, 11};
const int buttons[] = {12, 13};
//variables that will change
int buttonState[] = {false, false};
int lastButtonState[] = {false, false};
int values[] = {false, false, false, false};
void setup() {
//init LEDs
for(int i = 0; i < sizeof(leds); i++){
pinMode(leds[i], OUTPUT);
}
//init buttons
for(int i = 0; i < sizeof(buttons); i++){
pinMode(buttons[i], INPUT);
}
}
void loop() {
//fade when game starts
fade();
//start game
start();
//output of game
output();
}
void output(){
bool t1 = !values[0];
bool t2 = t1 && values[1];
bool t3 = values[2] || values[3];
bool Q = !(t2 || t3);
if(!Q){
digitalWrite(leds[4], true);
}else{
digitalWrite(leds[4], false);
}
}
void start(){
//total of leds
int j = 0;
//check if user is not at 5th led
while(j < 4){
//loop through buttons
for(int i = 0; i < 2; i++){
// Read button
buttonState[i] = digitalRead(buttons[i]);
// check button state
if (buttonState[i] != lastButtonState[i]) {
// if the state has changed
if (buttonState[i] == HIGH) {
//check if button 1
if(i == 0){
//select next LED
j++;
}
//else button 2
else{
// if the current state of the 2nd button is HIGH
while(i == 1){
//if current value of led is false, put it true
if(values[j] == false){
//put led on
digitalWrite(leds[j], true);
values[j] = true;
delay(50);
}else{
//put led off
digitalWrite(leds[j], false);
delay(50);
values[j] = false;
}
//go back to button 1?
i = 0;
}
}
//go back to button 1?
i = 0;
}
}
// save the current state as the last state,
// for next time through the loop
lastButtonState[i] = buttonState[i];
// wait a little
delay(50);
}
}
}
void fade(){
//put every led on half-on
for(int i = 0; i < sizeof(leds); i++){
analogWrite(leds[i], 100);
}
}
In C and C++, if you want to compare two values to check if they are equal, you have to use == (the comparison operator) instead of = (the assignment operator). You accidentily use the wrong operator here:
while(i = 1){
And here:
if(values[j] = false){
Change those to ==.

SG90 MIcro Servo Motor Push Button Arduino for Vending Machie Prototype

I have made my new code for my prototype again and my problems are:
When the arduino started running, the three SG90 Micro servo motors rotated 360 degrees at the same time and didn't stop. When I pushed the round push button it slowed the speed of rotation of the servo motor.
When I tried to simulate my program to 123d.circuits.io, it worked. I used the momentary push button since there is no round push button there.
What I wanted to achieve is that:
When push button A/B/C is pushed, the servo Motor A/B/C will rotate 360 deg to dispense an item for my vending machine prototype.
Here's my code. Hope you can help me.
#include <Servo.h>
const int pushButtonA = 2;
const int pushButtonB = 4;
const int pushButtonC = 7;
Servo myservoA;
Servo myservoB;
Servo myservoC;
int pos = 0;
int buttonStateA = 0;
int buttonStateB = 0;
int buttonStateC = 0;
void setup() {
Serial.begin(9600);
pinMode(pushButtonA, INPUT);
pinMode(pushButtonB, INPUT);
pinMode(pushButtonC, INPUT);
myservoA.attach(3);
myservoB.attach(5);
myservoC.attach(9);
}
void loop() {
buttonStateA = digitalRead (pushButtonA);
buttonStateB = digitalRead (pushButtonB);
buttonStateC = digitalRead (pushButtonC);
if((buttonStateA == LOW) && (buttonStateB == HIGH) && (buttonStateC == HIGH)){
digitalWrite(3, HIGH);
for(pos = 0; pos <=360; pos++);
myservoA.write(pos);
delay(15);
digitalWrite(3, HIGH);
}
if((buttonStateB == LOW) && (buttonStateA == HIGH) && (buttonStateC == HIGH)){
digitalWrite(5, HIGH);
for(pos = 0; pos <=360; pos++);
myservoB.write(pos);
delay(15);
digitalWrite(5, HIGH);
}
if((buttonStateC == LOW) && (buttonStateB == HIGH) && (buttonStateA == HIGH)){
digitalWrite(9, HIGH);
for(pos = 0; pos <=360; pos++);
myservoC.write(pos);
delay(15);
digitalWrite(9, HIGH);
};
}
There are two problems with your code.
As mentioned by #MikeCAT, the for loops in the code are empty because you added a semi-colon after them. See Effect of semicolon after 'for' loop for further clarification.
There is no need to perform digitalWrite in servo pins. For controlling them just use the method write from the Servo class.
Corrected code:
#include <Servo.h>
const int pushButtonA = 2;
const int pushButtonB = 4;
const int pushButtonC = 7;
Servo myservoA;
Servo myservoB;
Servo myservoC;
int pos = 0;
int buttonStateA = 0;
int buttonStateB = 0;
int buttonStateC = 0;
void setup() {
Serial.begin(9600);
pinMode(pushButtonA, INPUT);
pinMode(pushButtonB, INPUT);
pinMode(pushButtonC, INPUT);
myservoA.attach(3);
myservoB.attach(5);
myservoC.attach(9);
}
void loop() {
buttonStateA = digitalRead (pushButtonA);
buttonStateB = digitalRead (pushButtonB);
buttonStateC = digitalRead (pushButtonC);
if((buttonStateA == LOW) && (buttonStateB == HIGH) && (buttonStateC == HIGH)){
for(pos = 0; pos <=360; pos++) {
myservoA.write(pos);
delay(15);
}
}
if((buttonStateB == LOW) && (buttonStateA == HIGH) && (buttonStateC == HIGH)){
for(pos = 0; pos <=360; pos++) {
myservoB.write(pos);
delay(15);
}
}
if((buttonStateC == LOW) && (buttonStateB == HIGH) && (buttonStateA == HIGH)){
for(pos = 0; pos <=360; pos++) {
myservoC.write(pos);
delay(15);
}
}
}

MFRC 522 with ATmega8. Mifare Classic 1K won't authenticate

I have a problem with an ATmega8 and Mifare RC-522 based NFC/RFID controller.
I'm using this library and I've managed to read the UID of a card.
However, I'd like to also read and write other parts of the card but whenever I try to use the MFRC522_Auth function I don't get the idle interrupt which I should, instead it gives me LoAlertIrq saying that FIFObuffer is almost empty.
Here are the docs for the reader and the card, and below are relevant parts of my code.
main.c :
byte = mfrc522_request(PICC_REQALL,str);
if(byte == CARD_FOUND)
{
byte = mfrc522_get_card_serial(str);
if(byte == CARD_FOUND)
{
byte = mfrc522_auth(PICC_AUTHENT1A, 7, sectorKeyA, str);
if( (byte == CARD_FOUND) )
{
byte = MFRC522_Read1(4, str);
if(byte == CARD_FOUND)
{
//write content of that block
}
}
}
Relevant functions from the library :
void mfrc522_write(uint8_t reg, uint8_t data)
{
ENABLE_CHIP();
spi_transmit((reg<<1)&0x7E);
spi_transmit(data);
DISABLE_CHIP();
}
uint8_t mfrc522_read(uint8_t reg)
{
uint8_t data;
ENABLE_CHIP();
spi_transmit(((reg<<1)&0x7E)|0x80);
data = spi_transmit(0x00);
DISABLE_CHIP();
return data;
}
uint8_t mfrc522_to_card(uint8_t cmd, uint8_t *send_data, uint8_t send_data_len, uint8_t *back_data, uint32_t *back_data_len)
{
uint8_t status = 0;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint8_t tmp;
uint32_t i;
switch (cmd)
{
case MFAuthent_CMD: //Certification cards close
{
irqEn = 0x12;
waitIRq = 0x10;
break;
}
case Transceive_CMD: //Transmit FIFO data
{
irqEn = 0x77;
waitIRq = 0x30;
break;
}
default:
break;
}
mfrc522_write(ComIEnReg, irqEn|0x80); //Interrupt request
n=mfrc522_read(ComIrqReg);
mfrc522_write(ComIrqReg,n&(~0x80));//clear all interrupt bits
n=mfrc522_read(FIFOLevelReg);
mfrc522_write(FIFOLevelReg,n|0x80);//flush FIFO data
// mfrc522_write(CommandReg, Idle_CMD); //NO action; Cancel the current cmd???
n=mfrc522_read(CommandReg);
mfrc522_write(CommandReg,n|0x00);
//Writing data to the FIFO
for (i=0; i<send_data_len; i++)
{
mfrc522_write(FIFODataReg, send_data[i]);
}
//Execute the cmd
mfrc522_write(CommandReg, cmd);
if (cmd == Transceive_CMD)
{
n=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,n|0x80);
}
//Waiting to receive data to complete
i = 2000; //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
while (1) {
n = mfrc522_read(ComIrqReg); // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
if (n & waitIRq) { // One of the interrupts that signal success has been set.
break;
}
if (n & 0x01) { // Timer interrupt - nothing received in 25ms
// return 6; //debug purpose
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
if (--i == 0) { // The emergency break. If all other condions fail we will eventually terminate on this one after 35.7ms. Communication with the MFRC522 might be down.
if (cmd == MFAuthent_CMD) {
LCD_Clear();
LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
_delay_ms(2500);
}
break;
}
}
tmp=mfrc522_read(BitFramingReg);
mfrc522_write(BitFramingReg,tmp&(~0x80));
if (i != 0)
{
if(!(mfrc522_read(ErrorReg) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
{
status = CARD_FOUND;
if (n & irqEn & 0x01)
{
status = CARD_NOT_FOUND; //??
}
if (cmd == Transceive_CMD)
{
n = mfrc522_read(FIFOLevelReg);
lastBits = mfrc522_read(ControlReg) & 0x07;
if (lastBits)
{
*back_data_len = (n-1)*8 + lastBits;
}
else
{
*back_data_len = n*8;
}
if (n == 0)
{
n = 1;
}
if (n > MAX_LEN)
{
n = MAX_LEN;
}
//Reading the received data in FIFO
for (i=0; i<n; i++)
{
back_data[i] = mfrc522_read(FIFODataReg);
}
}
}
if (cmd == MFAuthent_CMD) {
LCD_WriteTextXY(1, 10, LCD_itoa16( mfrc522_read(Status2Reg) ) );
_delay_ms(2500);
}
} else status = 9;
return status;
}
uint8_t mfrc522_get_card_serial(uint8_t * serial_out)
{
uint8_t status;
uint8_t i;
uint8_t serNumCheck=0;
uint32_t unLen;
mfrc522_write(BitFramingReg, 0x00); //TxLastBists = BitFramingReg[2..0]
serial_out[0] = PICC_ANTICOLL;
serial_out[1] = 0x20;
status = mfrc522_to_card(Transceive_CMD, serial_out, 2, serial_out, &unLen);
if (status == CARD_FOUND)
{
//Check card serial number
for (i=0; i<4; i++)
{
serNumCheck ^= serial_out[i];
}
if (serNumCheck != serial_out[i])
{
status = ERROR;
}
}
return status;
}
uint8_t mfrc522_auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum)
{
uint8_t status;
uint32_t recvBits;
uint8_t i;
uint8_t buff[12];
// Validate instruction block address + sector + password + card serial number
buff[0] = authMode;
buff[1] = BlockAddr;
for (i=0; i<6; i++)
{
buff[i+2] = 0xFF /**(Sectorkey+i)*/;
}
for (i=0; i<4; i++)
{
buff[i+8] = *(serNum+i);
}
status = mfrc522_to_card(MFAuthent_CMD, buff, 12, buff, &recvBits);
return status;
}
uint8_t MFRC522_Read1(uint8_t blockAddr, uint8_t *recvData)
{
uint8_t status = 0;
uint8_t unLen, efa;
recvData[0] = PICC_READ;
recvData[1] = blockAddr;
CalculateCRC(recvData, 2, &recvData);
status = mfrc522_to_card(Transceive_CMD, recvData, 4, recvData, &unLen);
if ((status != CARD_FOUND)|| (unLen != 0x90))
{
status = ERROR;
}
return status;
}
uint8_t CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
uint8_t i, n;
uint8_t status = 0;
n = mfrc522_read(DivIrqReg);
mfrc522_write(DivIrqReg,n&(~0x04)); //CRCIrq = 0
n = mfrc522_read(FIFOLevelReg); //FIFO
mfrc522_write(FIFOLevelReg, n|0x80);
//Write_MFRC522(CommandReg, PCD_IDLE);
// Write data to the FIFO
for (i=0; i<len; i++)
{
mfrc522_write(FIFODataReg, *(pIndata+i));
}
mfrc522_write(CommandReg, CalcCRC_CMD);
// Read the CRC calculation result
i = 0xFF;
while(1){
n = mfrc522_read(DivIrqReg);
if (n & 0x04) {
break;
}
if (--i != 0) {
return 7;
}
}
// Read the CRC calculation result
pOutData[3] = mfrc522_read(CRCResultReg_2);
pOutData[4] = mfrc522_read(CRCResultReg_1);
return status = 0;
}

Read byte from Serial

I´ve made this program that reads info from serial and writes the value binary to 6 LEDs. I don´t feel that it´s the easiest or the fastest way though and that is what I´m really looking for. My code looks like this:
boolean enable = false;
void setup()
{
for (int i = 2; i < 8; i++)
{
pinMode(i, OUTPUT);
}
}
void loop()
{
if (Serial.available() > 0)
{
enable = true;
}
if (enable)
{
while (Serial.available() > 0)
{
byte b = Serial.parseInt();
b = constrain(b, 0, 63);
byte val = b;
for (int i = 7; i >= 2; i--)
{
if (pow(2, (i-2)) <= val)
{
digitalWrite(i, HIGH);
val -= pow(2, (i-2));
}
else
{
digitalWrite(i, LOW);
}
}
}
enable = false;
}
delay(100);
}
A valid code example would be nice. I´ve tried using PORTD but it does not work.
Use binary operations
for(int i = 0 ; i < 8 ; i++ ) {
val = ( b >> i ) & 0x1;
digitalWrite(i, val == 1 ? HIGH : LOW );
}
If you plan some serious serial communication have a look into library I created https://github.com/lukaszkujawa/arduino-serial-helper

Resources