Hi,
I have an Arduino Uno with a LCD connected by I2C. I realized when I am writing messages to it it does not show the correct time, it's ~50% off. I tried to print the millis() only, which is off by the same amount.
I found an old thread where it was caused by the delayMicroseconds() in the LiquidCrystal.cpp, so I tried those fixes, aswell as commenting out the LCD-update code, which no difference (I sent the millis() over the serial this time).
Does anyone know what could be causing the timer to be slow on this Arduino?
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include "CustomChars.h"
#define TX_BAUD 2400
#define PACKET_SIZE 3
#define DELAY 50
#define RX_PIN 2
#define TX_PIN 3
#define LCD_UPDATE 490
// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);
SoftwareSerial telemetry(RX_PIN,TX_PIN);
byte packet[PACKET_SIZE];
byte voltage[2];
unsigned long lastUpdate = 0;
unsigned long receivedPackets = 0;
unsigned long lastPacks = 0;
int packetsPerSecond = 0;
void setup() {
Serial.begin(115200);
telemetry.begin(TX_BAUD);
lcd.begin();
lcd.createChar(0,antenna);
lcd.createChar(1,oneBar);
lcd.createChar(2,twoBars);
lcd.createChar(3,threeBars);
lcd.createChar(4,fourBars);
lcd.createChar(5,fiveBars);
lcd.createChar(6,noBars);
lcd.backlight();
lcd.clear();
lcd.home();
lcd.print("Naze32 Telemetry");
delay(1000);
lcd.clear();
}
void loop() {
while(telemetry.available() > 0){
addByte(telemetry.read());
if (testChecksum(packet, PACKET_SIZE)){
voltage[0] = packet[0];
voltage[1] = packet[1];
receivedPackets++;
}
}
if (millis() - lastUpdate > LCD_UPDATE){
updatePacketsPerSecond();
lastUpdate = millis();
lcd_WriteVoltage();
lcd_WriteTime();
//lcd_WriteMillis();
lcd_WriteConnectionStatus();
lcd_WriteConnected();
}
}
void addByte(byte b){
for (byte i = 0; i < PACKET_SIZE-1; i++){
packet[i] = packet[i+1];
}
packet[PACKET_SIZE-1] = b;
}
bool testChecksum(byte* packet, byte packetSize){
byte crc = CRC8(packet, PACKET_SIZE-1);
return (packet[PACKET_SIZE-1] == crc);
}
byte CRC8(const byte *data, byte len){
byte crc = 0x00;
while (len--) {
byte extract = *data++;
for (byte tempI = 8; tempI; tempI--) {
byte sum = (crc ^ extract) & 0x01;
crc >>= 1;
if (sum) {
crc ^= 0x8C;
}
extract >>= 1;
}
}
return crc;
}
void updatePacketsPerSecond(){
packetsPerSecond = 1000*(receivedPackets - lastPacks)/(millis()-lastUpdate);
lastPacks = receivedPackets;
}
void lcd_WriteVoltage(){
char string[8];
sprintf(string,"%02u.%uV",voltage[0],voltage[1]);
for (byte i = 0; i < 8; i++){
if (string[i] == 'V'){
for (byte b = i+1; b < 8; b++){
string[b] = ' ';
}
break;
}
}
lcd.setCursor(0,0);
lcd.print(string);
}
void lcd_WriteConnectionStatus(){
lcd.setCursor(0,1);
char string[6];
sprintf(string,"%03ipps",packetsPerSecond);
lcd.print(string);
}
void lcd_WriteTime(){
char time[8];
getTime(time);
lcd.setCursor(9,0);
lcd.print(time);
}
void getTime(char *time){
unsigned long t = millis()/1000;
byte h = t/3600;
byte m = (t-h*3600)/60;
byte s = t-60*(60*h+m);
sprintf(time,"%u:%02u:%02u",h,m,s);
}
void lcd_WriteConnected(){
if (isConnected()){
lcd.setCursor(7,1);
lcd.write(0);
if (packetsPerSecond > 99)
lcd.write(5);
else if (packetsPerSecond > 89)
lcd.write(4);
else if (packetsPerSecond > 69)
lcd.write(3);
else if (packetsPerSecond > 49)
lcd.write(2);
else
lcd.write(1);
}
else {
lcd.setCursor(7,1);
lcd.write(0);
lcd.write(6);
}
}
bool isConnected(){
return packetsPerSecond > 30;
}
void lcd_WriteMillis(){
lcd.setCursor(0,0);
lcd.print(millis() / 1000);
}