2dom / PxMatrix

Adafruit GFX compatible graphics driver for LED matrix panels
BSD 3-Clause "New" or "Revised" License
851 stars 172 forks source link

Please help get rid of while #189

Closed TopoAS closed 4 years ago

TopoAS commented 4 years ago

I start working with PxMatrix on arduino mega and i made the following code::

#define PxMATRIX_COLOR_DEPTH 1
#define PxMATRIX_MAX_HEIGHT 32
#define PxMATRIX_MAX_WIDTH 64
#include <PxMatrix.h>
// Pins for LED MATRIX
#define P_A 2
[pixeltime_AVR.zip](https://github.com/2dom/PxMatrix/files/4535412/pixeltime_AVR.zip)

#define P_B 3
#define P_C 4
#define P_D 5
#define P_E 6
#define P_LAT 7
#define P_OE 8
PxMATRIX display(64, 32, P_LAT, P_OE, P_A, P_B, P_C);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

unsigned long start_time = 0;
int a = 0;

uint16_t myCOLORS[8] = {myRED, myGREEN, myBLUE, myWHITE, myYELLOW, myCYAN, myMAGENTA, myBLACK};
void textul() {
  display.clearDisplay();
  display.fillRect(0, 00, 21, 8, display.color565(255, 0, 0));
  display.fillRect(21, 00, 42, 8, display.color565(255, 255, 0));
  display.fillRect(42, 00, 64, 8, display.color565(0, 0, 255));

  display.setTextSize(2);
  display.setTextColor(myWHITE);
  display.setCursor(8, 9);
  display.print("FRAS");

  display.fillRect(0, 24, 21, 8, display.color565(255, 0, 0));
  display.fillRect(21, 24, 42, 8, display.color565(255, 255, 0));
  display.fillRect(42, 24, 64, 8, display.color565(0, 0, 255));
  start_time = millis();
  while ((millis() - start_time) < 5000) {
    display.display(30);
  }
}

void textul1() {
  display.clearDisplay();
  display.fillRect(0, 00, 21, 8, display.color565(255, 0, 0));
  display.fillRect(21, 00, 42, 8, display.color565(255, 255, 0));
  display.fillRect(42, 00, 64, 8, display.color565(0, 0, 255));

  display.setTextSize(2);
  display.setTextColor(myWHITE);
  display.setCursor(8, 9);
  display.print("2020");

  display.fillRect(0, 24, 21, 8, display.color565(255, 0, 0));
  display.fillRect(21, 24, 42, 8, display.color565(255, 255, 0));
  display.fillRect(42, 24, 64, 8, display.color565(0, 0, 255));
  start_time = millis();
  while ((millis() - start_time) < 5000) {
    display.display(30);
  }

}
void setup() {
  display.begin(8);
  display.setPanelsWidth(2);
  display.flushDisplay();
  display.setBrightness(255);
}
void scroll_text()
{
  display.setTextWrap(false);  // we don't wrap text so it scrolls nicely
  display.setTextSize(1);
  display.setRotation(0);
  for (int xpos = 64; xpos > -140; xpos--)
  {
    display.setTextColor(myWHITE);
    display.clearDisplay();
    display.setCursor(xpos, 12);
    display.println("Made by Andrei S.S. 2020");
    start_time = millis();
    while ((millis() - start_time) <10)
      display.display(5);
  }
}

void loop() {
  display.clearDisplay();
  scroll_text();
  textul();
  textul1();
}

i want to ask if i can display text without using while function like below:

 while ((millis() - start_time) < 2000) {
    display.display(30);
  }

instead just using something using something like display.display() . i intend using couple of buttons that will change what the display will show when i press different button, and i need that what is displayed to stay on screen until i press another button. Thank you.

sovcik commented 4 years ago

You need to change the approach and implement some "states".

  1. remove while from textul and textul functions
  2. move display.display() to loop()
int detectNewStatus(int oldStatus) {
    int s = oldStatus;
    if (button1Pressed()) s=1;
    if (button2Pressed()) s=2;
    if (button3Pressed()) s=3;
    return s;
}

int status=1;

void loop() {
  // check your buttons
  int s = detectNewStatus(status);

  // if changed, change display based on new status
  if (s != status) {
     switch (status) {
        case 1:
           textul();
           break;
        case 2:
           textul1();
           break;
      }
  }
  // make sure display will continue displaying :-)
  display.display(30);

}
TopoAS commented 4 years ago

Thank you. I will try tonight and came back with the results.

TopoAS commented 4 years ago

hello i adjusted a little bit your code, but now i am facing another problem after i restart the arduino when i press button 1 nothing happens when i press button 2 i get color green (what was supposed to appear when i pressed button 1), when i press button 3 i get the color from button 2 and so on. how to fix. Thank you very much for your help. and another problem who to make let`s say for example only green blink? (repeat for example case 2 until case changed) code i use:

int detectNewStatus(int oldStatus) {
  int s = oldStatus;
  if (digitalRead(pinA) == HIGH) s = 1;
  if (digitalRead(pinB) == HIGH) s = 2;
  if (digitalRead(pinC) == HIGH) s = 3;
  if (digitalRead(pinD) == HIGH) s = 4;
  return s;
}
int status=0 ;
void loop() {

  int s = detectNewStatus(status);

 Serial.println(s); // for debugging
  // if changed, change display based on new status
  if (s != status) {
    switch (status) {
      case 1:
        verdele();
        break;
      case 2:
        galbenul();
        break;
      case 3:
        galbenul();
        break;
      case 4:
        albastrul();
        break;
       default:
    break;
    }status=s;
  }
  // make sure display will continue displaying :-)
  display.display(30);
}
sovcik commented 4 years ago

Change line switch(status) to switch(s).

Blinking is basically switching between showing nothing (clear display) and showing something (e.g. verderle()). You have register phase: e.g. 0=not blinking, 1=blinking and periodically switch between those.

Something like

bool blink_phase=false;
bool phase_changed=false;
int blink_count=3;
unsigned int duration=500;
unsigned int timer=millis();

void blink(){
   if (blink_cound<=0) return;
   if (millis()-timer < 500) return;
   timer = millis();
   blink_phase=!blink_phase;
   phase_changed=true;
   if (blink_phase) blink_count--; 
}

void loop(){
   if (blink_count>0 && phase_changed){
      phase_changed = false;
      if (blink_phase) {
      // display something
      } else {
      // clear display
      }  
   }
}
TopoAS commented 4 years ago

thank you for the switch(s) i can`t figure out the blink command, maybe i am to tired this is what i tried:

bool blink_phase = false;
bool phase_changed = false;
int blink_count = 2;
unsigned int duration = 500;
unsigned int timer = millis();
void blink() {
  if (blink_count <= 0) return;
  if (millis() - timer < duration) return;
  timer = millis();
  blink_phase = !blink_phase;
  phase_changed = true;
  if (blink_phase) blink_count--;
}
int s = detectNewStatus(status);

  Serial.println(s);

  if (s != status) {
    switch (s) {
      case 1:
        verdele();
        break;
      case 2:
      //rose();
        blink();
        break;
      case 3:
        galbenul();
        break;
      case 4:
        albastrul();
        break;
      default:
        break;
    }  status = s;
  }
  display.display();
  if (blink_count > 0 && phase_changed) {
          phase_changed = false;
          if (blink_phase) {
           rose();
            display.display();
          } else {
            display.clearDisplay();
          }
        }

}
void rose() {
  display.clearDisplay();
  display.fillRect(0, 0, 64, 8, myRED);
  display.fillRect(0, 8, 8, 24, myRED);
  display.setTextSize(2);
  display.setTextColor(myWHITE);
  display.setCursor(8, 9);
  display.print("STOP");
  display.fillRect(54, 8, 64, 24, myRED);
  display.fillRect(0, 24, 64, 8, myRED);
}

Thank you!

sovcik commented 4 years ago

Well, this is not a good place for learning how to code... Maybe you should try forums like stackoverflow.com or similar. And exchanging pieces of code doesn't help either... Maybe you should have writter the whole use case..

sovcik commented 4 years ago

Look at implementation of beeping in this lib. You could do the same with display. https://github.com/sovcik/iot-minilib/blob/master/src/Beeper.cpp

TopoAS commented 4 years ago

Thank you for your instructions!