Go Down

Topic: Reset Button Counter (Read 82 times) previous topic - next topic

warcowan

Hi. I'm helping a friend with a simple project. We have 3 PTH Neopixels hooked up to an arduino. We have a button connected between Pin6 and Ground. The button is there to act as a selector switch and switch the color of the Neopixels.

By default, the pixels are lit up and colored white, press the button again and they change to green, press the button again and they change to red. The problem we are having is after they change to red we would like the counter to reset and start over at white again. I used some code to reset the counter to zero but it does not seem to be working.

Can someone help me figure out how to reset the counter to zero so the sequence can start again. Thanks in advance.


Code: [Select]
#include <Adafruit_NeoPixel.h>

#define PIXEL_PIN  4 // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT  3 // Define number of pixels used

#define BUTTON_PIN  6  // Define selector switch which changes the color of the nexpixels. Button makes a connection between pin6 and ground

int counter = 0; // Set a counter variable and initialize it at 0

// Declare our NeoPixel strip object:
Adafruit_NeoPixel pixels(PIXEL_COUNT, PIXEL_PIN, NEO_RGB + NEO_KHZ800);
// Argument 1 = Number of pixels in NeoPixel strip
// Argument 2 = Arduino pin number (most are valid)
// Argument 3 = Pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)



void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pixels.begin(); // Initialize NeoPixel object (REQUIRED)
  pixels.setBrightness(200); // Set BRIGHTNESS values can range from 0 to 255
 
}


// loop() function -- runs repeatedly as long as board is on ---------------

void loop(){

  int buttonState;
  buttonState = digitalRead(BUTTON_PIN);
  if (buttonState == LOW) // change the color of the pixels
  {
  counter++; // when button is pressed increment counter by 1
  delay(1500); // delay for switch debounce
  }
  if (counter == 0)  // Code for first/default color in this case it's white
  {
  pixels.setPixelColor(0, 255, 255, 255); // set first pixel to white
  pixels.setPixelColor(1, 255, 255, 255); // set second pixel to white
  pixels.setPixelColor(2, 255, 255, 255); // set third pixel to white
  pixels.show(); // "push" the color data to all the pixels
  }
  else if (counter == 1) // Code for second color in this case it's green
  {
  pixels.setPixelColor(0, 0, 255, 0); // set first pixel to green
  pixels.setPixelColor(1, 0, 255, 0); // set second pixel to green
  pixels.setPixelColor(2, 0, 255, 0); // set third pixel to green
  pixels.show(); // "push" the color data to all the pixels
  }
  else if (counter == 2) // Code for third color in this case it's red
  {
  pixels.setPixelColor(0, 255, 0, 0); // set first pixel to red
  pixels.setPixelColor(1, 255, 0, 0); // set second pixel to red
  pixels.setPixelColor(2, 255, 0, 0); // set third pixel to red
  pixels.show(); // "push" the color data to the pixels
   
  if (counter => 3)
{
  (counter == 0);
}
  }
}

TimMJN

Use the modulo operator for this:

counter = (counter+1) %3

cattledog

#2
May 24, 2020, 12:45 am Last Edit: May 24, 2020, 01:17 am by cattledog
Good job posting with code tags on your first posting.

Not so good job posting code which does not compile and not posting an error message.

Code: [Select]
sketch_may23c:61:16: error: expected primary-expression before '>' token

   if (counter => 3)

                ^


You have a syntax error. The expression should be
Code: [Select]
if (counter >= 3)

If you fix that, you will run into a logical error you have in your code. The test for counter >=3 is nested within the conditional test for counter==2 and will never be true.

You should make the test for >= 3  a separate conditional and you will need another button press to get to three which will take you back to zero.

I think if you use @timMJN's suggestion to place counter = (counter+1) %3 in the counter == 2 conditional block, you will only be there very briefly and may not even see the red.

EDIT: If the suggestion was to replace the counter++ with counter = (counter+1) %3  in the button reading block, and eliminate the test for counter==3 that would be fine.




warcowan

Good job posting with code tags on your first posting.

Not so good job posting code which does not compile and not posting an error message.

Code: [Select]
sketch_may23c:61:16: error: expected primary-expression before '>' token

   if (counter => 3)

                ^



OOPPS. Sorry about that. I copied from an old version of the code. I ran into the same compilation error myself and fixed it in later versions

You have a syntax error. The expression should be
Code: [Select]
if (counter >= 3)

If you fix that, you will run into a logical error you have in your code. The test for counter >=3 is nested within the conditional test for counter==2 and will never be true.

You should make the test for >= 3  a separate conditional and you will need another button press to get to three which will take you back to zero.

I think if you use @timMJN's suggestion to place counter = (counter+1) %3 in the counter == 2 conditional block, you will only be there very briefly and may not even see the red.

EDIT: If the suggestion was to replace the counter++ with counter = (counter+1) %3  in the button reading block, and eliminate the test for counter==3 that would be fine.


Of course now I see how obvious my mistake was. I fixed it using a slightly different solution.


Code: [Select]
void loop(){

  int buttonState;
  buttonState = digitalRead(BUTTON_PIN);
  if (buttonState == LOW) // change the color of the pixels
  {
  counter++; // when button is pressed increment counter by 1
  delay(1500); // delay for switch debounce
  }
  if (counter == 0)  // Code for first/default color in this case it's white
  {
  pixels.setPixelColor(0, 255, 255, 255); // set first pixel to white
  pixels.setPixelColor(1, 255, 255, 255); // set second pixel to white
  pixels.setPixelColor(2, 255, 255, 255); // set third pixel to white
  pixels.show(); // "push" the color data to all the pixels
  }
  else if (counter == 1) // Code for second color in this case it's green
  {
  pixels.setPixelColor(0, 0, 255, 0); // set first pixel to green
  pixels.setPixelColor(1, 0, 255, 0); // set second pixel to green
  pixels.setPixelColor(2, 0, 255, 0); // set third pixel to green
  pixels.show(); // "push" the color data to all the pixels
  }
  else if (counter == 2) // Code for third color in this case it's red
  {
  pixels.setPixelColor(0, 255, 0, 0); // set first pixel to red
  pixels.setPixelColor(1, 255, 0, 0); // set second pixel to red
  pixels.setPixelColor(2, 255, 0, 0); // set third pixel to red
  pixels.show(); // "push" the color data to the pixels
  }
  else {
  counter = 0;
  }
 }

cattledog

#4
May 24, 2020, 04:19 am Last Edit: May 24, 2020, 04:22 am by cattledog
Quote
I fixed it using a slightly different solution.
Code: [Select]
else {
  counter = 0;
  }


Good choice. You posting demonstrates promise as a programmer.

If you want to move further along, see if you can get rid of the delay() for switch debounce in your button code. delay() is a blocking function, and the processor can not do other tasks while it is running. Learning to write non blocking code to keep the processor free for other tasks is a skill which will carry you a long way.

Code: [Select]
if (buttonState == LOW) // change the color of the pixels
  {
  counter++; // when button is pressed increment counter by 1
  delay(1500); // delay for switch debounce
  }


Look at the 02 Digital ide examples for debounce and state change detection.

Also there are good tutorials at
Using millis() for timing
https://forum.arduino.cc/index.php?topic=503368.0

and
Demonstration Code for several things at the same time
https://forum.arduino.cc/index.php?topic=223286.0


TimMJN

EDIT: If the suggestion was to replace the counter++ with counter = (counter+1) %3  in the button reading block, and eliminate the test for counter==3 that would be fine.
Yes it was, I'm sorry for being unclear, I just checked very briefly

Go Up