Button question

Hi All,
My first post! I've been playing with Arduinos for a while now and feel okay doing basic stuff. I'm scratching my head a bit on this one though and I am hoping someone can assist please?

I am using a sketch posted on this forum - MAX7219 Message Selector - #14 by StriderTR but I want the display to be blank to start with and then play the first message once when the button is pressed. Once that message has played, then clear the display and wait for the button to be pressed again to display the next message and so on...

I thought I could call a function to run the display animation called dismess() but I seem to have fallen at the first hurdle getting that to work!

Thanks in advance!

// Program to demonstrate the MD_Parola library
// button select canned messages
// MD_MAX72XX library can be found at https://github.com/MajicDesigns/MD_MAX72XX
// by groundFungus AKA c. goulding

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

const byte  buttonPin = 2;    // the pin that the pushbutton is attached to

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// individual messages in strings
const char msg_1[] = "1111";
const char msg_2[] = "2222";
const char msg_3[] = "3333";
const char msg_4[] = "4444";
const char msg_5[] = "5555";
const char msg_6[] = "6666";

// an array of pointers to the strings
char *messages[] = {msg_1, msg_2, msg_3, msg_4, msg_5, msg_6};
byte messageNum = sizeof(messages) / sizeof(messages[0]);

int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup(void)
{
   Serial.begin(115200);
   Serial.println("\nParola pick a message program\n");
   P.begin();
   pinMode(buttonPin, INPUT_PULLUP);
}

void loop()
{

while(digitalRead(buttonPin)==HIGH) 
{
; // wait for the button to be pressed 

dismess() //call dismess() function
}

void dismess() {
     if (P.displayAnimate())  // time to show next frame?
   {
      P.displayText(messages[buttonPushCounter], PA_CENTER, 30, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
   }
   checkButton();
}

void checkButton()
{


   static unsigned long timer = 0;
   unsigned long interval = 50;
   if (millis() - timer >= interval)
   {
      timer = millis();
      buttonState = digitalRead(buttonPin);
      // compare the buttonState to its previous state
      if (buttonState != lastButtonState)
      {
         if (buttonState == LOW)
         {
            // if the current state is LOW then the button
            // went from off to on:
            buttonPushCounter++;  // add one to counter
            // if counter over number of messages, reset the counter to message 0
            if (buttonPushCounter >= messageNum)
            {
               buttonPushCounter = 0;
            }
            //Serial.println(buttonPushCounter);
         }
      }
      lastButtonState = buttonState;
   }
}
}

Then put the code for that at the end of the setup function.

It seems I didn't word that well - Currently, the code starts running the first message as soon as it is powered up. I want it to wait until the button is pressed...

It seems you didn't understand what I said.

Then put the look for the button press inside the setup function. Only end the setup function once the button is pressed.
You might want to use a 'while' structure here.

1 Like

Learn about button bounce, maybe write your own software debounce, it used to be a forum rite of passage away from beginner programmer.

2 Likes

your code seems overly complicated

const byte ButtonPin = A1;
byte butState;

void
loop (void)
{
    byte but = digitalRead (ButtonPin);
    if (butState != but)  { // state change
        butState = but;
        delay (20);         // debounce

        if (LOW == but)     // pressed
            Serial.println ("button pressed");
    }
}

void
setup (void)
{
    Serial.begin (9600);

    pinMode (ButtonPin, INPUT_PULLUP);
    butState = digitalRead (ButtonPin);
}
2 Likes

@leebert Your code has several structural errors, so it doesn't compile.

1 Like

@leebert See if this code meets your needs and adapt it to your project.

Simulated at:
"Rolling.ino - Wokwi ESP32, STM32, Arduino Simulator

// Program to demonstrate the MD_Parola library
// button select canned messages
// MD_MAX72XX library can be found at https://github.com/MajicDesigns/MD_MAX72XX
// by groundFungus AKA c. goulding

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

const byte  buttonPin = 2;    // the pin that the pushbutton is attached to

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4

#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// individual messages in strings
const char msg_1[] = "1111";
const char msg_2[] = "2222";
const char msg_3[] = "3333";
const char msg_4[] = "4444";
const char msg_5[] = "5555";
const char msg_6[] = "6666";

// an array of pointers to the strings
char *messages[] = {msg_1, msg_2, msg_3, msg_4, msg_5, msg_6};
byte messageNum = sizeof(messages) / sizeof(messages[0]);

int counter = 0;   // counter for the number of button presses
//-------------------------------------------------------------------
void setup(void)
{
  Serial.begin(115200);
  Serial.println("\nParola pick a message program\n");
  P.begin();
  pinMode(buttonPin, INPUT_PULLUP);
}
//-------------------------------------------------------------------
void loop()
{
  while (digitalRead(buttonPin) == LOW) {
    if (digitalRead(buttonPin) == HIGH)
    {
      for (counter = 0; counter < 4096; counter++)
      {
        if (P.displayAnimate())  // time to show next frame?
        {
          P.displayText(messages[counter], PA_CENTER, 30, 0, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
        }
      }
       P.begin();
    }
  }
}

1 Like

Why a while loop inside of loop()?
Why does counter goes to from 0 to 4095 but the messages array only has 6 members?
Why do you call P.begin() in the loop() function?

1 Like

Thank you! I found another example on the same site and have created this from it which almost works the way I want it to. Just a bit more thought required...

Try the following sketch which has been tested in UNO.

// Including the required Arduino libraries
#include <MD_Parola.h>   //deals with methods for display animation, scrolling etc.
#include <MD_MAX72xx.h>  //deals with registers -- the hardware
#include <SPI.h>

const byte buttonPin = 2;
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define MAX_DEVICES 4
#define CS_PIN 10

// Create a new instance of the MD_Parola class with hardware SPI connection
MD_Parola myDisplay = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

/*const char msg_1[] = "1111";
  const char msg_2[] = "2222";
  const char msg_3[] = "3333";
  const char msg_4[] = "4444";
  const char msg_5[] = "5555";
  const char msg_6[] = "6666";*/

char *myArray[] =
{
  "1111",
  "2222",
  "3333",
  "4444",
  "5555",
  "6666"
};

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);

  myDisplay.begin();
  myDisplay.setIntensity(0);
  myDisplay.setTextAlignment(PA_CENTER);
  myDisplay.displayClear();
  delay(2000);
}

void loop()
{
  for (int i = 0; i < 6; i++)
  {
    myDisplay.displayClear();   //clear the display
    while (digitalRead(buttonPin) != LOW)
    {
      ;    //wait until Button is pressed
    }
    myDisplay.print(myArray[i]);    //show message for 1-sec
    delay(1000);
  }
}
1 Like

Please take a look at the below sketch,

#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>

// Define the number of devices we have in the chain and the hardware interface
// NOTE: These pin numbers will probably not work with your hardware and may
// need to be adapted
#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW
#define MAX_DEVICES 4 // Define the number of displays connected
#define CLK_PIN    13 // CLK or SCK
#define DATA_PIN   11 // DATA or MOSI
#define CS_PIN     10 // CS or SS

#define buttonPin  2        // the pin that the pushbutton is attached to
#define debouncePeroid 10

// Hardware SPI connection
MD_Parola P = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary output pins
// MD_Parola P = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// individual messages in strings
const char msg_1[] = "1111";
const char msg_2[] = "2222";
const char msg_3[] = "3333";
const char msg_4[] = "4444";
const char msg_5[] = "5555";
const char msg_6[] = "6666";

// an array of pointers to the strings
char *messages[] = {msg_1, msg_2, msg_3, msg_4, msg_5, msg_6};
uint8_t numberOfMessages = sizeof(messages) / sizeof(messages[0]);

uint8_t msgIndex;
bool enable;

void setup(void) {
  Serial.begin(115200);
  pinMode(buttonPin, INPUT_PULLUP);

  P.begin();
  enable = false;
  msgIndex = numberOfMessages - 1;
}

void loop(void) {
  if (enable & P.displayAnimate()) {
    P.displayText(messages[msgIndex], PA_CENTER, 40, 10, PA_SCROLL_LEFT, PA_SCROLL_LEFT);
    enable = false;
  } else if (isPressed()) {
    enable = true;
    msgIndex = (msgIndex + 1) % numberOfMessages;
  }
}

bool isPressed() {
  static bool state = HIGH;
  static bool input = HIGH;
  static unsigned long startTime;

  bool prevInput = input;
  input = digitalRead(buttonPin);

  if (input != prevInput) {
    startTime = millis();
  }

  if (input != state) {
    if (millis() - startTime >= debouncePeroid) {
      state = input;
      return state == LOW;  // When pressed, state = LOW, if pinmode = INPUT_PULLUP, and state = HIGH, if pinmode = INPUT.
    }
  }
  return LOW;
}
1 Like

Thanks for all your kind help. I've sorted it out with your help and I have some interesting sketch examples that show different ways of doing things.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.