简体   繁体   中英

Arduino lcd fps strange behavior

I made a simple lcd display example from this guide . After it worked I'd like to play with it. I wrote a program to count fps of this screen. The big question is how slow is the Arduino.

Program code is here:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

int lastMillis = 0;
long fps = 0;

void setup() {
  lcd.begin(16, 2);

  lcd.print("seconds ");
  lcd.setCursor(0, 1);
  lcd.print("fps ");
}

void loop() {
  if ((millis() - lastMillis) > 1000) {
    lcd.setCursor(8, 0);
    lcd.print(millis()/1000);

    lcd.setCursor(4, 1);
    lcd.print(fps);
    fps = 0;
    lastMillis = millis();
  }
  fps = fps + 1;
}

And it worked. I was happy to know that Arduino can do more than 300,000 fps on a small 16x2 lcd display.

But after number of seconds goes beyond 32 second (magic number) fps freezes at value 124,185 and never changes after that.

If someone know why is that happen, please explain it. I don't have a clue why fps ( that's set to 0 every second ) could freeze, while seconds are keep changing.

I got a video that shows what happens. Video

Then, as ahaltindis suggested, I changed the code to this:

// include the library code:
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

int lastMillis = 0;
long fps = 0;

void setup() {
  lcd.begin(16, 2);
}

void loop() {
  if ((millis() - lastMillis) > 1000) {
    lcd.clear();

    lcd.setCursor(0, 0);
    lcd.print("seconds ");
    lcd.setCursor(0, 1);
    lcd.print("fps ");

    lcd.setCursor(8, 0);
    lcd.print(millis()/1000);

    lcd.setCursor(4, 1);
    lcd.print(fps);
    fps = 0;
    lastMillis = millis();
  }
  fps = fps + 1;
}

And it get worse: video

I tried your code with my arduino uno. But I used Serial.print instead of lcd.print . It acted with same way. When sec hits the 32, serial monitor goes crazy.

Then I found that you defined lastMillis as an integer. In arduino(atmega) integer keeps 16bit value and that means it can store values in range of -32,768 to 32,767. When millis function hits 32,767(32sec), arduino sets your lastMillis 's value as -32,768.

So your if block returns always true after 32 sec, because difference of millis() and lastMillis will always be greater than 1000. Thats why the only value you see is 1 and that is also why your lcd cannot respond well print requests after 32 sec.

The only change you should do is, change your lastMillis type as a long.

long lastMillis = 0;

Try changing

int lastMillis = 0;

To

unsigned int lastMillis = 0;

Let me know what happens If you use an unsigned int you will overflow back to one so that your original code will work

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM