How to display two individual scrolling messages on 8x32 MAX7219 ? [CLOSED post #23]

Hi! Another topic about MAX7219 matrix panel.
The sketch is "MD_MAX72xx_Message_Serial" from the MD_MAX72xx library, here is also a simulation using Wokwi, in the circuit I added a push button. By default, scrolling message no. 1 is displayed, and I want scrolling message no. 2 to be displayed when I press the button. Basically, when I press the button, the message changes.
I thought that in order to display message no. 2, I can modify the readSerial() function like this:
void readSerial(void)

{
  newMessage[BUF_SIZE] = (" Message 2!     ");
  newMessageAvailable = true;

}

This function appears only twice in the program, once when it is written, and the second time when it is called by the user, but it contains a variable that looks important.
There are two messages to display:

uint8_t curMessage[BUF_SIZE] = { "Message 1!     " };
uint8_t newMessage[BUF_SIZE];

"currMessage" is default and is displayed at startup. "newMessage" is the new message taken from Serial Monitor and is entered by the user.
"newMessage" modifies inside the "readSerial()" function.
I thought that this function only has the role of retrieving the new message to be displayed. There is also this variable "newMessageAvailable = true;" which is set when the condition in the if statement is met, and it is the only one which appears elsewhere in the program.
As the second message will be by default, it will not change, I thought of rewriting the "readSerial" function as above, and when I press the button, the function will be called. But nothing is displayed.
What else should I include in the readSerial() function? I think the problem is here. I just think that it is an easier option by which I can insert a second message in the program. I just tried to simplify the function, basically the message is a prescribed one, it is no longer taken from the Serial Monitor.

Complete program:

// Use the MD_MAX72XX library to scroll text on the display
//
// Demonstrates the use of the callback function to control what
// is scrolled on the display text.
//
// User can enter text on the serial monitor and this will display as a
// scrolling message on the display.
// Speed for the display is controlled by a pot on SPEED_IN analog in.
#include <MD_MAX72xx.h>
#include <SPI.h>

#define IMMEDIATE_NEW   0     // if 1 will immediately display a new message
#define USE_POT_CONTROL 1
#define PRINT_CALLBACK  0

#define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }

// 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 CLK_PIN   13  // or SCK
#define DATA_PIN  11  // or MOSI
#define CS_PIN    10  // or SS

// SPI hardware interface
MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// Arbitrary pins
//MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);

// Scrolling parameters
#if USE_POT_CONTROL
#define SPEED_IN  A5
#else
#define SCROLL_DELAY  75  // in milliseconds
#endif // USE_POT_CONTROL

#define CHAR_SPACING  1 // pixels between characters

// Global message buffers shared by Serial and Scrolling functions
#define BUF_SIZE  75
uint8_t curMessage[BUF_SIZE] = { "Message 1!     " };
uint8_t newMessage[BUF_SIZE];
bool newMessageAvailable = false;

uint16_t  scrollDelay;  // in milliseconds

const int buttonPin = 5; // push button is connected to D5
int toggleState = 1;
int lastButtonState = 1;
long unsigned int lastPress;
int debounceTime = 20;
unsigned long previousMillis = 0;

/*void readSerial(void)
{
  static uint8_t  putIndex = 0;

  while (Serial.available())
  {
    newMessage[putIndex] = (char)Serial.read();
    if ((newMessage[putIndex] == '\n') || (putIndex >= BUF_SIZE - 3)) // end of message character or full buffer
    {
      // put in a message separator and end the string
      newMessage[putIndex++] = ' ';
      newMessage[putIndex] = '\0';
      // restart the index for next filling spree and flag we have a message waiting
      putIndex = 0;
      newMessageAvailable = true;
    }
    else if (newMessage[putIndex] != '\r')
      // Just save the next char in next location
      putIndex++;
  }
}*/

void readSerial(void)
{
  newMessage[BUF_SIZE] = (" Message 2!     ");
  newMessageAvailable = true;

}

void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col)
// Callback function for data that is being scrolled off the display
{
#if PRINT_CALLBACK
  Serial.print("\n cb ");
  Serial.print(dev);
  Serial.print(' ');
  Serial.print(t);
  Serial.print(' ');
  Serial.println(col);
#endif
}

uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
// Callback function for data that is required for scrolling into the display
{
  static uint8_t* p = curMessage;
  static enum { NEW_MESSAGE, LOAD_CHAR, SHOW_CHAR, BETWEEN_CHAR } state = LOAD_CHAR;
  static uint8_t  curLen, showLen;
  static uint8_t  cBuf[15];
  uint8_t colData = 0;    // blank column is the default

#if IMMEDIATE_NEW
  if (newMessageAvailable)  // there is a new message waiting
  {
    state = NEW_MESSAGE;
    mx.clear(); // clear the display
  }
#endif

  // finite state machine to control what we do on the callback
  switch (state)
  {
    case NEW_MESSAGE:   // Load the new message
      memcpy(curMessage, newMessage, BUF_SIZE);	// copy it in
      newMessageAvailable = false;    // used it!
      p = curMessage;
      state = LOAD_CHAR;
      break;

    case LOAD_CHAR: // Load the next character from the font table
      showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
      curLen = 0;
      state = SHOW_CHAR;

      // if we reached end of message, opportunity to load the next
      if (*p == '\0')
      {
        p = curMessage;     // reset the pointer to start of message
#if !IMMEDIATE_NEW
        if (newMessageAvailable)  // there is a new message waiting
        {
          state = NEW_MESSAGE;    // we will load it here
          break;
        }
#endif
      }
    // !! deliberately fall through to next state to start displaying

    case SHOW_CHAR: // display the next part of the character
      colData = cBuf[curLen++];
      if (curLen == showLen)
      {
        showLen = CHAR_SPACING;
        curLen = 0;
        state = BETWEEN_CHAR;
      }
      break;

    case BETWEEN_CHAR: // display inter-character spacing (blank columns)
      colData = 0;
      curLen++;
      if (curLen == showLen)
        state = LOAD_CHAR;
      break;

    default:
      state = LOAD_CHAR;
  }

  return (colData);
}

void scrollText(void)
{
  static uint32_t	prevTime = 0;

  // Is it time to scroll the text?
  if (millis() - prevTime >= scrollDelay)
  {
    mx.transform(MD_MAX72XX::TSL);  // scroll along - the callback will load all the data
    prevTime = millis();      // starting point for next time
  }
}

uint16_t getScrollDelay(void)
{
#if USE_POT_CONTROL
  uint16_t  t;

  t = analogRead(SPEED_IN);
  t = map(t, 0, 1023, 25, 250);

  return (t);
#else
  return (SCROLL_DELAY);
#endif
}

void setup()
{
  pinMode(buttonPin, INPUT); // push button as input

  mx.begin();
  mx.setShiftDataInCallback(scrollDataSource);
  mx.setShiftDataOutCallback(scrollDataSink);

#if USE_POT_CONTROL
  pinMode(SPEED_IN, INPUT);
#else
  scrollDelay = SCROLL_DELAY;
#endif

  newMessage[0] = '\0';

  Serial.begin(57600);
  Serial.print("\n[MD_MAX72XX Message Display]\nType a message for the scrolling display\nEnd message line with a newline");
}

void loop()
{
  //scrollDelay = getScrollDelay();
  //readSerial();
  //scrollText();

  int buttonState = digitalRead(buttonPin);   //read the state of buttonPin and store it as buttonState (0 or 1)
  unsigned long buttonMillis = millis();

  if ((buttonMillis - lastPress) > debounceTime)  //if the time between the last buttonChange is greater than the debounceTime
  {
    lastPress = buttonMillis;   //update lastPress
    if (buttonState == 0 && lastButtonState == 1)   //if button is pressed and was released last change
    {
      toggleState = ! toggleState;                //toggle the state
      lastButtonState = 0;    //record the lastButtonState
    }

    if (buttonState == 1 && lastButtonState == 0)   //if button is not pressed, and was pressed last change
    {
      lastButtonState = 1;    //record the lastButtonState
    }
  }
  // if the button is pressed
  if (toggleState == 0)
  {
    scrollDelay = getScrollDelay();
    readSerial();
    scrollText();
    Serial.println("read");
  }
  // is hte button was not pressed
  if (toggleState == 1)
  {
    scrollDelay = getScrollDelay();
    scrollText();
    Serial.println("scroll");
  }


} // loop

Did you try your simulation?

  • Something IS displayed - one in the Serial Monitor another on the Matrix
  • You configured the button as "pressed" at the beginning of the sketch
  • You enable a potentiometer, but have no potentiometer

I can see you began with the original simulation that has serial input to change the message. I think you lost control of your code. Try from the beginning again. Add a pushbutton and show that you can control it in the Serial monitor. Then add a second message and control the messages with the pushbutton.

The best debugging method was to put a Serial.print() in certain places, to see where the program is.
Before the first push of the button, "Message 1" is displayed. At the first press of the button, "Message 2" should be displayed, maybe sometimes some kind of something appears, but it is certain that the desired message is not displayed in any form.
As for the button, it seems to do its job, I have used this method before, even if it is robust. At the first press of the button, and if I call the readSerial() function as before, the message inserted in the Serial Monitor is displayed (there would also be a problem that if I press the button once more, "Message 1" is no longer displayed :sweat::sweat_smile:). So, the lack of that potentiometer doesn't bother me, nor does the simulator take that into account.
I will look more carefully at the program you suggested, maybe I understand something better, although I didn't want to approach two paths.

Well, it sounds like everything is good and I am only giving bad information. So I will stop.

I didn't consider things that way, I don't know how you came to this opinion.
I know I'm not very good at this.
So you say that the button is a bit confusing. I consider "int lastButtonState = 1;" as High state, or not pressed.
Maybe I'll have a better idea, I will test again in the circuit, in general a simulator doesn't reflect reality very well.

void readSerial(void)
{
  newMessage[BUF_SIZE] = (" Message 2!     ");
  newMessageAvailable = true;

}

The method of copying the message into newMessage is wrong. newMessage[BUF_SIZE] is a single element of the newMessage array, and in this case is actually one byte past the end of that array. It does not help that newMessage is declared as a uint8_t array, usually a char array is used for text.
It would also be better to have the function only return the new message once, otherwise every time you call readSerial() it will indicate that a new message has been received. Not a problem with your particular code, but could be in other situations.

void readSerial(void)
{
  static bool firstCall = true;
  if (firstCall) {
    firstCall = false;
    strlcpy((char*)newMessage, " Message 2!     ", sizeof(newMessage));
    newMessageAvailable = true;
  }
}

Your code will have problems with actually receiving a message over Serial. You only call readSerial() when the button is pressed, so any serial data received that is over 63 characters long will cause a buffer overflow and be lost, in which case the terminating newline character will never be seen. The readSerial() function also has a serious flaw, the value of putIndex is never check to see if it points to a location past the end of the newMessage array.

@cristian10001

Wihout having defined very precisely what your code shall do any advice is just guessing
And will cause a lot of asking back questions for these details.

You should describe your wanted functionality very precise.

I will give an example of how precise ist must be

On power-up of the microcontroller the display shall show the message that is
58 characters long

//                    10                 20                  30                 40                  50
//123456789012345678901234567890123456789012345678901234567890
  "Hello I am the first display-message I great you what shall I show next?"

this message shall scroll over the display until I press the button

When the button is pressed the message shall change to the second message
65 characters long

//                    10                 20                  30                 40                  50                  60
//1234567890123456789012345678901234567890123456789012345678901234567890
  "My new message is to to anounce that dinner starts at 18 o clock in the evening"

Whenever I send a message over the serial interface the message shall be received automatically and kept in the background until I press the button

So confirm or modify this description until it fits 100% to what you want to have.

best regards Stefan

It is an example sketch taken from the MD_MAX72xx library.
It seems to work with your version, at least on the simulator. In the circuit it seems that I still have things to solve.
But as xfpd says above, I have a problem with the push button, and the rest of the program, because it seems that at this moment the program only displays a message (I tested in the circuit). At startup, the current message is displayed by default ("Message 1!"), but when a message is taken from the Serial Monitor, or I insert a message using your method, the previous message, the one by default from currMessage is no longer displayed . So the program only displays a message.
Thanks for your time.

You are mostly right, when I power up the circuit, the first message must be displayed, then when I press the button, the second message must be displayed, so by pressing the button it switches between the two messages. The messages are predefined in the program, none will be changed. Regarding the sketch above, I now realized that in fact only one message is displayed, either the one by default, or the one taken through the serial from Serial Monitor, which definitively replaces any previous message.
So I think I have to "reconfigure the route". :sweat:

Now I am confused.
Will your final code:

  • receive a message over serial interface?
    or
  • have two textes hard coded in the source-code and these two textes stay always the same?

To begin with, I am looking to use two messages, always the same, either one or the other will be displayed, but I also intend to use two PIR sensors to trigger the display (something like pass in and pass out), maybe I will open another post when I move forward with this idea. The first step, display two messages, the second step, insert the PIR sensors.

After seeing some videos on the internet, it seems that in the sketch presented above a bluetooth module can also be used, so through an application on the phone I can send the message I want to display to the board. Quite interesting.

You should post a road-map what you plan to do all in all.
It is annoying that you add more and more details.
Then you can choose an order what to do first, second, third etc.

Depending on how much you want to do in the end it might be nescessary to choose a different microcontroller

You are collecting more and more ideas but you did not show a new code-version
that shows one part of the functionality.
nor did you ask any specific questions about any detail of the code.

So what do you want to do as the next thing?

Yes, you're right, I didn't start this post right, I explained it to you above, I approached the main topic wrongly.
I don't really have time to work on this, more on the weekend, but I managed to gather some more information and put them in a program that displays a text scroll and if I press a push button, another scroll text will be displayed. Wokwi simulation: https://wokwi.com/projects/376046306998807553
Next, I will look to replace the push button with PIR sensors to create that pass-in and pass-out mode. Imagine that it is something like "Welcome!" when you enter somewhere (pass-in) and "Goodbye!" when you leave (pass-out).

You seem to prefer writing a lot of words instead of getting straight forward to the point.
You haven't answered the questions I posted.
Well it is your choice.
If you like to take more time to finish your project you can do so.

Your link does not work. No idea how you managed it to make it not work

I think I said how I want to build this project. I don't know why you can't access the hyperlink, but it can be copied to the tab.
I have added something besides the program that displays the two messages and the push button to change them.

#include <MD_Parola.h>     // include MajicDesigns Parola library
#include <MD_MAX72xx.h>    // include MajicDesigns MAX72xx LED matrix library
#include <SPI.h>           // include Arduino SPI library

#define HARDWARE_TYPE MD_MAX72XX::PAROLA_HW   // this line defines our dot matrix hardware type (FC-16)
#define MAX_DEVICES 4                       // define number of total cascaded modules

#define CS_PIN    10   // define CS (Chip Select) pin

MD_Parola display = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);

#define POTPIN   A5   // define speed control potentiometer output pin connection

uint8_t scrollSpeed = 150;    // set initial scroll speed, can be a value between 10 (max) and 150 (min)
textEffect_t scrollEffect  = PA_SCROLL_LEFT;  // scroll direction, right-to-left direction
textPosition_t scrollAlign = PA_LEFT;         // scroll align
uint16_t scrollPause = 2000;                  // scroll pause in milliseconds

char mesg[100];
uint8_t love[] = { 7, 14, 31, 63, 126, 63, 31, 14 };
uint8_t emot[] = { 7, 28, 34, 69, 81, 69, 34, 28 };
int matrix = 0;

const int buttonPin = 5;
int toggleState = 1;
int lastButtonState = 1;
long unsigned int lastPress;
int debounceTime = 20;
unsigned long previousMillis = 0;

// setup function
void setup(void)
{
  pinMode(buttonPin, INPUT);

  // initialize the dot matrix display
  display.begin();
  // set the intensity (brightness) of the display (choose a number between 0 and 15)
  display.setIntensity(5);
  // clear the whole display
  display.displayClear();

  display.addChar('$', love);
  display.addChar('~', emot);

  // print text on the display
  //display.displayText(mesg, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
}

// main loop function
void loop(void)
{
  uint16_t an = analogRead(POTPIN);    // read analog data from potentiometer output

  int16_t speed = map(an, 0, 1023, 150, 10);  // map previous value between 150 & 10 (min & max speed)

  if ( speed != display.getSpeed() )   // check if speed changed
    display.setSpeed(speed);           // set new scrolling speed

  int buttonState = digitalRead(buttonPin);   //read the state of buttonPin and store it as buttonState (0 or 1)

  unsigned long buttonMillis = millis();

  if ((buttonMillis - lastPress) > debounceTime)  //if the time between the last buttonChange is greater than the debounceTime
  {
    lastPress = buttonMillis;   //update lastPress
    if (buttonState == 0 && lastButtonState == 1)   //if button is pressed and was released last change
    {
      toggleState = ! toggleState;                //toggle the state
      lastButtonState = 0;    //record the lastButtonState
    }

    if (buttonState == 1 && lastButtonState == 0)   //if button is not pressed, and was pressed last change
    {
      lastButtonState = 1;    //record the lastButtonState
    }
  }

  if (toggleState == 0)
  {
    if (display.displayAnimate()) {    // animate the display
      display.displayText("Display message 2!", scrollAlign, scrollSpeed, 0, scrollEffect, scrollEffect); // display continuously, without any interrupt
      display.displayReset();          // reset the current animation
    }
  }

  if (toggleState == 1)
  {
    if (display.displayAnimate()) {    // animate the display
      display.displayText("Display message 1!", scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
      display.displayReset();          // reset the current animation
    }
  }

} // end of code.

I added two PIR sensors. The thing was how to use these two sensors (the idea is to use distance sensors), how to position them. I am trying the option by which I will position these two sensors approximately 20cm apart from each other, the same orientation. In the program, I thought to check which sensor detects the first movement. "Coming in!" it means sensor 1 detects the first movement, then I check if the second sensor also detects the movement "Coming out!" it works the other way around.
I tested in the circuit (the simulator doesn't really help in this case, ignore the push button in the circuit), at the "Coming in!" phase. pass in front of the two sensors and scroll text is displayed once, so this part of the program is executed quite okay, but the phase "Coming out!" it does not run as well, out of 10 times only once or twice the text "Coming out!" is displayed, in the other cases either "Coming in!" is displayed. or nothing is displayed.
The program is robust, repetitive, but it is what it is.
I have time to work on the weekend.

You have hidden your wokwi-simulation behind a link that looks like a link that leads to a description of the PIR-sensors that you use in your real project.

Your WOKWI-simulation does not show any text on the matrix display
nor
does it print to the serial monitor.

I will wait without answering until you have added serial printing to your code which will make visible which part of your code is executed.

This all is voluntary. If some other users want to guide: feel free to do it.
To me personal it depends on the pre-condition of adding serial printing to the code

best regards Stefan

#include <MD_Parola.h>     // include MajicDesigns Parola library
#include <MD_MAX72xx.h>    // include MajicDesigns MAX72xx LED matrix library
#include <SPI.h>           // include Arduino SPI library

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW   // this line defines our dot matrix hardware type (FC-16)
#define MAX_DEVICES 4                       // define number of total cascaded modules

#define CS_PIN    10   // define CS (Chip Select) pin

MD_Parola display = MD_Parola(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
// attach the potentiometer
#define POTPIN   A5   // define speed control potentiometer output pin connection
// attach PIR sensors
#define PIR_SENSOR_1 3
#define PIR_SENSOR_2 2

uint8_t scrollSpeed = 150;    // set initial scroll speed, can be a value between 10 (max) and 150 (min)
textEffect_t scrollEffect  = PA_SCROLL_LEFT;  // scroll direction, right-to-left direction
textPosition_t scrollAlign = PA_LEFT;         // scroll align
uint16_t scrollPause = 2000;                  // scroll pause in milliseconds

// display messages
char message_1 [100] = {"Coming in!"};
char message_2 [100] = {"Coming out!"};

// Initialize variables to track PIR sensor readings
int pirSensor1Reading = 0;
int pirSensor2Reading = 0;

// No motion is detected at first, State are LOW
int pirSensor1State = LOW;
int pirSensor2State = LOW;

// Just joggling variables
int toggle_1 = 1;
int toggle_2 = 2;

// Initialize variables to keep track of the time
unsigned long previousMillis_1 = 0;
unsigned long currentMillis_1 = 0;
unsigned long previousMillis_2 = 0;
unsigned long currentMillis_2 = 0;

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

  // Set PIR sensor pins as input
  pinMode(PIR_SENSOR_1, INPUT);
  pinMode(PIR_SENSOR_2, INPUT);

  // initialize the dot matrix display
  display.begin();
  // set the intensity (brightness) of the display (choose a number between 0 and 15)
  display.setIntensity(5);
  // clear the whole display
  display.displayClear();

  // print text on the display
  //display.displayText(message, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
}

// main loop function
void loop(void)
{
  uint16_t an = analogRead(POTPIN);    // read analog data from potentiometer output

  int16_t speed = map(an, 0, 1023, 150, 10);  // map previous value between 150 & 10 (min & max speed)

  if ( speed != display.getSpeed() )   // check if speed changed
    display.setSpeed(speed);           // set new scrolling speed

  // Read PIR sensor 1
  pirSensor1Reading = digitalRead(PIR_SENSOR_1);

  // if PIR sensor 1 detects movement first
  if (pirSensor1Reading == HIGH && pirSensor1State == LOW) {
    Serial.println("PIR 1 detected movement first!");

    // then also read PIR sensor 2
    pirSensor2Reading = digitalRead(PIR_SENSOR_2);

    // if PIR sensor 2 also detects movement, but after PIR sensor 1
    if (pirSensor2Reading == HIGH && pirSensor2State == LOW) {

      Serial.println("PIR 2 detected movement second!");
      toggle_1 = ! toggle_1;
      pirSensor2State = HIGH;
      previousMillis_1 = millis();
    }
    if (pirSensor2Reading == LOW && pirSensor2State == HIGH)
    {
      pirSensor2State = LOW;
    }
  }
  if (pirSensor1Reading == LOW && pirSensor1State == HIGH)
  {
    pirSensor1State = LOW;
  }
  if (toggle_1 == 0)
  {
    Serial.println("Coming in!");
    currentMillis_1 = millis();
    if (currentMillis_1 - previousMillis_1 <= 10000)
    {
      Serial.println("Coming in!");
      if (display.displayAnimate()) {    // animate the display
        display.displayText(message_1, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
        display.displayReset();          // reset the current animation
      }
    }
    if (currentMillis_1 - previousMillis_1 > 10000)
    {
      Serial.println("Nothing coming in!");
      display.displayClear();
      toggle_1 = 1;
      pirSensor1Reading = LOW;
      pirSensor2Reading = LOW;
    }
  }
  // *******************************************************************************************************************************************
  // Read PIR sensor 2
  pirSensor2Reading = digitalRead(PIR_SENSOR_2);

  // if PIR sensor 2 detects movement first
  if (pirSensor2Reading == HIGH && pirSensor2State == LOW) {
    Serial.println("PIR 2 detected movement first!");

    // then also read PIR sensor 1
    pirSensor1Reading = digitalRead(PIR_SENSOR_1);

    // if PIR sensor 1 also detects movement, but after PIR sensor 2
    if (pirSensor1Reading == HIGH && pirSensor1State == LOW) {

      Serial.println("PIR 1 detected movement second!");
      toggle_2 = ! toggle_2;
      pirSensor1State = HIGH;
      previousMillis_2 = millis();
    }
    if (pirSensor1Reading == LOW && pirSensor1State == HIGH)
    {
      pirSensor1State = LOW;
    }
  }
  if (pirSensor2Reading == LOW && pirSensor2State == HIGH)
  {
    pirSensor2State = LOW;
  }
  if (toggle_2 == 0)
  {
    Serial.println("Coming out!");
    currentMillis_2 = millis();
    if (currentMillis_2 - previousMillis_2 <= 10000)
    {
      Serial.println("Coming out!");
      if (display.displayAnimate()) {    // animate the display
        display.displayText(message_2, scrollAlign, scrollSpeed, scrollPause, scrollEffect, scrollEffect);
        display.displayReset();          // reset the current animation
      }

    }
    if (currentMillis_2 - previousMillis_2 > 10000)
    {
      Serial.println("Nothing coming out!");
      display.displayClear();
      toggle_2 = 1;
      pirSensor1Reading = LOW;
      pirSensor2Reading = LOW;
    }
  }

} // end of code.

I kept making changes to the program, what I put above had some gaps (I got a little confused too).

This is the most advanced version of the program (simulation in wokwi, it doesn't help much because I can't simulate the detection of the sensors in a row, only individually; ignore the button). For debugging, I have no better method than placing some serial prints here and there. What I could see, as I wrote in the program, if sensor 1 detects the first movement (the confirmation message also appears on the serial monitor) and then sensor 2 detects movement (the confirmation message appears), the scroll text "Coming in! " on matrix panel. The reverse is also valid, with sensor 2 first and then sensor 1, and "Coming out!" is displayed.
Obviously, as I said in the previous reply, there are times when it doesn't work well. I don't know for sure if it is from the PIR sensors or from the program, but it also happens that when they detect movement nothing is displayed, or the displayed text does not start from the beginning (that is, the text appears where it left off), or the text displayed is the opposite of what it should be, here I think there is a problem with the positioning of the sensors and the sensitivity, maybe the sensors get confused between them. I will try to put the sensors in small cardboard boxes, because the distance between them will be small, ~20cm, so that they do not intersect, I narrow the detection field. I was saying that I want to put them in the same orientation, and basically the detection will be done from left to right, and vice versa, with the rule of the first sensor that detects movement. I don't really have a better option.
As for the program, the way I handled the use of the two sensors is about the best that occurred to me, that is to check which sensor detects the first movement. How bad do you think it is? Maybe I can't take it to a very high level, but maybe you have ideas for some improvements.

You should structure your information into multiple paragraphs
your is one big loong paragraph

It could be structured like this:

This is the most advanced version of the program (simulation in wokwi,

it doesn't help much because I can't simulate the detection of the sensors in a row, only individually; ignore the button).

For debugging, I have no better method than placing some serial prints here and there.

What I could see, as I wrote in the program, if sensor 1 detects the first movement (the confirmation message also appears on the serial monitor)
and then sensor 2 detects movement (the confirmation message appears),
the scroll text "Coming in! " on matrix panel.

The reverse is also valid, with sensor 2 first and then sensor 1, and "Coming out!" is displayed.

Obviously, as I said in the previous reply, there are times when it doesn't work well.
I don't know for sure if it is from the PIR sensors or from the program.

It also happens that when they detect movement nothing is displayed, or the displayed text does not start from the beginning (that is, the text appears where it left off),
or
the text displayed is the opposite of what it should be.

If I test with my real sensors
Here I think there is a problem with the positioning of the sensors and the sensitivity, maybe the sensors get confused between them.

I will try to put the sensors in small cardboard boxes, because the distance between them will be small, ~20cm, so that they do not intersect, I narrow the detection field.

I was saying that I want to put them in the same orientation, and basically the detection will be done from left to right, and vice versa, with the rule of the first sensor that detects movement. I don't really have a better option.

As for the program, the way I handled the use of the two sensors is about the best that occurred to me, that is to check which sensor detects the first movement.

What do you think about my approach? If you have ideas for improvements please make suggestions.

1 Like