Help! Need 'reset'/'newgame' button in code which is always active

Hey guys and girls,

I'm pretty stuck...

For my skillset and knowledge this is the best i can do but can't figure out how to keep a reset button always 'hot' so whenever in the game i push it, the game will reset of restart.
Might be a simple one for you but i can't figure it out.

It's a kind of Beerpong...
LDR sensor to look for a ball in the cup (shadow from light when ball goes through cup).
And as you might notice some sweet RGB matrix animations together with neopixel strips.
It is single player but tend to make it multiplayer over Wire code, Wifi or Bluetooth after Christmas.
But for the school Christmas party i'd like to get it working.

This is what i got so far:

//RGBmatrix 
#include <avr/pgmspace.h>
#include <Adafruit_GFX.h> 
#include <RGBmatrixPanel.h>

#define CLK 8 
#define LAT A3
#define OE  9
#define A   A0
#define B   A1
#define C   A2

RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  32

#define F2(progmem_ptr) (const __FlashStringHelper *)progmem_ptr

//Neopixel
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define PIN            10
#define NUMPIXELS      1

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

//BITMAP characters
const unsigned char PROGMEM bitmap1[] =
{ 
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 
0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 
0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 
0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 
0x55, 0x55, 0x55, 0x55, 
};

const unsigned char PROGMEM bitmap2[] =
{ 
0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 
0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 
0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 
0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 
0xaa, 0xaa, 0xaa, 0xaa, 
};

//Miscellaneous
int resetPin = 11;

int var;

int varloop;

int clockVar;

int bierLvl;

int points = 0;

int sensorThreshold = 350;

int pointsThreshold = 3;

//////////////////////////////////////////////////////////////////////////////////////////// SETUP

void setup() {

Serial.begin(9600);

pinMode(11, INPUT_PULLUP);

matrix.begin();
matrix.setTextWrap(false); // Allow text to run off right edge
matrix.setTextSize(2);
pixels.begin();

fillGlass();

}


//////////////////////////////////////////////////////////////////////////////////////////// LOOP


void loop(){

if (digitalRead(resetPin) == HIGH)
{
  pushStart();
}

pixels.setPixelColor(0, pixels.Color(255,255,255));
pixels.show();
  
Serial.println(analogRead(5));

matrix.drawRect(0, 0, 32, 16, matrix.Color333(0, 0, 7));
matrix.setCursor(11,1);
matrix.setTextSize(2);
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.print(points);


if (analogRead(5) > sensorThreshold){ 
  score();
  points++;
  }

if (points == pointsThreshold){
winner();
}

}
 


//////////////////////////////////////////////////////////////////////////////////////////// VOIDS
//here where some voids but i exceeded the maximum characters for this forum..

As you might notice, i already tried to keep my void loop() as small as possible.

here the void loop() where i'd like to have some sort of code so that the restart button is always active

void loop(){

if (digitalRead(resetPin) == HIGH)
{
  pushStart();
}

pixels.setPixelColor(0, pixels.Color(255,255,255));
pixels.show();
  
Serial.println(analogRead(5));

matrix.drawRect(0, 0, 32, 16, matrix.Color333(0, 0, 7));
matrix.setCursor(11,1);
matrix.setTextSize(2);
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.print(points);


if (analogRead(5) > sensorThreshold){ 
  score();
  points++;
  }

if (points == pointsThreshold){
winner();
}

}

As this code is the 2.0 of the same game i had this problem before and a friend suggested this piece of code, but i don't get it. does this make any sense to you guys?

//boolean for 'push start' animation
bool checkPin(int pin, bool state, int duration){
  unsigned long end = millis() + duration;
  while(millis()<duration){
    if(digitalRead(pin)==state) return true;
  }
  return false;
}

Would be glad if you guys could help me out.
Cheers!
P.

You need to post your complete program. Add it as an attachment if it is too long.

By the way the correct name for them is "functions", not "voids". The word "void" tells the compiler that the function does not return a value.

...R

Sorry,

i've been educated poorly..

Here you go, the full code

BEERPONG_2_DRAFT_BLUE_animated_button_try_2.ino (7.16 KB)

As you can see there was no need to put it in an attachment. Here it is so others don't have to download it.

//RGBmatrix 
#include <avr/pgmspace.h>
#include <Adafruit_GFX.h> 
#include <RGBmatrixPanel.h>

#define CLK 8 
#define LAT A3
#define OE  9
#define A   A0
#define B   A1
#define C   A2

RGBmatrixPanel matrix(A, B, C, CLK, LAT, OE, false);

#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  32

#define F2(progmem_ptr) (const __FlashStringHelper *)progmem_ptr

//Neopixel
#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define PIN            10
#define NUMPIXELS      1

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

const unsigned char PROGMEM bitmap1[] =
{ 
0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 
0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 
0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 
0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 
0x55, 0x55, 0x55, 0x55, 
};

const unsigned char PROGMEM bitmap2[] =
{ 
0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 
0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 
0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 
0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, 0x55, 0x55, 0x55, 0x55, 
0xaa, 0xaa, 0xaa, 0xaa, 
};

//Miscellaneous
int resetPin = 11;

int var;

int varloop;

int clockVar;

int bierLvl;

int points = 0;

int sensorThreshold = 350;

int pointsThreshold = 3;

//////////////////////////////////////////////////////////////////////////////////////////// SETUP

void setup() {

Serial.begin(9600);

pinMode(11, INPUT_PULLUP);

matrix.begin();
matrix.setTextWrap(false); // Allow text to run off right edge
matrix.setTextSize(2);
pixels.begin();

fillGlass();

}


//////////////////////////////////////////////////////////////////////////////////////////// LOOP


void loop(){

if (digitalRead(resetPin) == HIGH)
{
  pushStart();
}

pixels.setPixelColor(0, pixels.Color(255,255,255));
pixels.show();
  
Serial.println(analogRead(5));

matrix.drawRect(0, 0, 32, 16, matrix.Color333(0, 0, 7));
matrix.setCursor(11,1);
matrix.setTextSize(2);
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.print(points);


if (analogRead(5) > sensorThreshold){ 
  score();
  points++;
  }

if (points == pointsThreshold){
winner();
}

}
 


//////////////////////////////////////////////////////////////////////////////////////////// VOIDS

void score(){
var = 0;
while (var <10){
  matrix.drawRect(0, 0, 32, 16, matrix.Color333(0, 0, 7));
  matrix.fillRect(1, 1, 30, 14, matrix.Color333(0,0,0));
  pixels.setPixelColor(0,pixels.Color(255,0,0));
  pixels.show();
  matrix.setTextSize(2);
  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.setCursor(2, 1);   
  matrix.print("H");
  matrix.setCursor(11, 1);   
  matrix.print("I");
  matrix.setCursor(20, 1);   
  matrix.print("T");
  delay(75);
  pixels.setPixelColor(0,pixels.Color(0,0,255));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(255,0,0));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(0,0,255));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(255,0,0));
  pixels.show();
  delay(75);
  matrix.drawRect(0, 0, 32, 16, matrix.Color333(7, 0, 0));
  matrix.fillRect(1, 1, 30, 14, matrix.Color333(0,0,0));
  matrix.setTextSize(1);
  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.setCursor(7, 0);   
  matrix.print("RED");
  matrix.setCursor(4, 9);   
  matrix.print("SHOT");
  pixels.setPixelColor(0,pixels.Color(0,0,255));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(255,0,0));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(0,0,255));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(255,0,0));
  pixels.show();
  delay(75);
  pixels.setPixelColor(0,pixels.Color(0,0,255));
  pixels.show();
  delay(75);
  var++;
}
matrix.fillScreen(0);

}
  

void pushStart(){                     //while loop statement verranderen met kijken naar button pin. alleen in eerste while loop button statement of in elke?
  
                                                                                                   //combineren met de pixel chase voor de strips.
matrix.setTextSize(1);
varloop = 0;
matrix.fillScreen(0);

  while(varloop<10){
    matrix.fillScreen(0);
    matrix.setTextColor(matrix.Color333(7,7,7));
    matrix.setCursor(4, 0);
    matrix.print("PUSH");
    delay(500);

    matrix.setTextColor(matrix.Color333(0,7,0));
    matrix.setCursor(2, 9);
    matrix.print("START");
    delay(500);
    matrix.setTextColor(matrix.Color333(0,0,0));
    matrix.setCursor(2, 9);
    matrix.print("START");
    matrix.setCursor(4, 0);
    matrix.print("PUSH");
    varloop++;
  }

fillGlass();

var++;
varloop = 0;
}




void winner(){
 var = 0;
while (var <30){
  matrix.drawRect(0, 0, 32, 16, matrix.Color333(0, 0, 0));
  matrix.drawRect(1, 1, 30, 14, matrix.Color333(7, 0, 0));
  pixels.setPixelColor(0,pixels.Color(255,0,0));
  pixels.show();
  matrix.setTextSize(2);
  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.setCursor(2, 1);   
  matrix.print("W");
  matrix.setCursor(11, 1);   
  matrix.print("I");
  matrix.setCursor(20, 1);   
  matrix.print("N");
  delay(100);
  matrix.drawRect(0, 0, 32, 16, matrix.Color333(0, 0, 7));
  matrix.drawRect(1, 1, 30, 14, matrix.Color333(0, 0, 0));
  matrix.fillRect(2, 2, 28, 12, matrix.Color333(0,0,0));
  
  pixels.setPixelColor(0,pixels.Color(0,0,255));
  pixels.show();
  delay(100);
  var++;
}
matrix.fillScreen(0);
points = 0;
pushStart();
  
}

void attractionMode() {
clockVar = 200;
while(clockVar > 10){
  matrix.drawBitmap(0, 0,  bitmap1, 32, 16, matrix.Color333(7,0,0));
  matrix.setCursor(1,1);
  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.setTextSize(1);
  matrix.print("BEER");
 
  delay(clockVar);
  matrix.drawBitmap(0, 0,  bitmap1, 32, 16, matrix.Color333(0,0,0));
  
  matrix.drawBitmap(0, 0,  bitmap2, 32, 16, matrix.Color333(0,0,7));
  matrix.setCursor(8,8);
  matrix.setTextColor(matrix.Color333(7,7,7));
  matrix.setTextSize(1);
  matrix.print("PONG");
  delay(clockVar);
  matrix.drawBitmap(0, 0,  bitmap2, 32, 16, matrix.Color333(0,0,0));
  clockVar = clockVar - 5;
}

matrix.drawBitmap(0, 0,  bitmap1, 32, 16, matrix.Color333(3,0,0));
matrix.drawBitmap(0, 0,  bitmap2, 32, 16, matrix.Color333(0,0,3));
matrix.setCursor(1,4);
matrix.setTextColor(matrix.Color333(7,7,7));
matrix.setTextSize(1);
matrix.print("2 . 0");
delay(4000);
matrix.fillScreen(0);
}


void fillGlass() {
matrix.fillScreen(0);
varloop = 0;
while (varloop < 5){
  matrix.drawLine(12, 3, 12, 12, matrix.Color333(7, 7, 7));
  matrix.drawLine(13, 13, 18, 13, matrix.Color333(7, 7, 7));
  matrix.drawLine(13, 14, 18, 14, matrix.Color333(7, 7, 7));
  matrix.drawLine(19, 3, 19, 12, matrix.Color333(7, 7, 7));
  matrix.drawLine(12, 3, 19, 3, matrix.Color333(7, 7, 7));
  matrix.drawCircle(20, 8, 3, matrix.Color333(7,7,7));
  matrix.fillRect(13, 4, 6, 8, matrix.Color333(0,0,0));

bierLvl = 9;
while (bierLvl >0){
  matrix.drawLine(13,bierLvl +3,18,bierLvl + 3, matrix.Color333(7,7,0));
  delay(200);
  bierLvl--;
  }
  varloop++;
}

matrix.fillScreen(0);

}

...R

As I suspected you are using the delay() function quite liberally. The Arduino can do nothing during a delay() so it cannot detect your button push.

Have a look at how millis() is used to manage timing without blocking in several things at a time

I have no idea what the calls to matrix.XXX do, or whether any or all of them takes an appreciable length of time. In some places you have a long series of such calls which may also make the program unresponsive. And they are inside a WHILE.

Maybe you can do one piece of the WHILE (change it to IF) in every iteration of loop(). Maybe it is possible to break a single iteration into a few parts.

...R

This is crude but effective… wire a switch to the board reset pin. SPST momentary to GND.

If the startup sequence is pretty enough, it'll look OK.

All other solutions should be explored of course for the situations where this hammer approach wouldn't be desirable.

But with the party coming up fast, you'd make time for other beauty enhancements or testing or…

I said crude, I say effective.

-- alto777

Hey Guys,

Sorry Robin, the extra text in the first message was too much and didn't try to post it as code. sorry for that.

For the long term i think that millis() will do the trick. have you got any idea what that extra piece of code does?
could i use that in setup() to refer to it in other lines of code?

//boolean for 'push start' animation
bool checkPin(int pin, bool state, int duration){
  unsigned long end = millis() + duration;
  while(millis()<duration){
    if(digitalRead(pin)==state) return true;
  }
  return false;
}

The calls for the matrix is pure animation and some sort of 'delay' is needed as it is the interface.

alto777, for this short term that isn't such a bad idea. thanks, didn't think of that.
after this friday i have plenty of time to dive deep into code heaven and recode the whole thing.
although i don't get millis() completely, it'll help already to get rid of some delay()'s

thanks for now, i'll get back to it when i have the time. (next week?)

Cheers.

Using millis() like this

unsigned long end = millis() + duration;
  while(millis()<duration){
    if(digitalRead(pin)==state) return true;
  }

will give problems when millis() rolls over. Always use subtraction as in my link.

The calls for the matrix is pure animation and some sort of 'delay' is needed as it is the interface.

The trick is to get the Arduino to use those intervals to check for a pushbutton and not leave it sitting on its hands.

...R