Некорректные показания lcd дисплея

времени мало было, обратил на это внимание, но может и показалось)))
я так понимаю и вам скучно стало ?)))

специально для тебя, невежды необразованной)
убрал инициализацию пина, эмитировав датчик (внешняя подтяжка)


в вокви ссылка таже.

это издевательство, особенно если у меня разрешение экрана огромное, и я еще через виртуальную машину смотрю, фактически я ваше сообщение вижу как 4 пикселя))) ну да ладно, спс посмотрю позже)))

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

int x = 0;
int input = A0;
int lastState = HIGH;

LiquidCrystal_I2C lcd(0x27, 16, 2);

unsigned long sysTimer1 = 0;
byte displayMode = 0; // normal display mode
unsigned long modeTimer = 0;

const int SYS_CHECK = 873; // system check interval
const int THRESHOLD = 13; // system threshold value

void setup()
{
pinMode(A0, INPUT_PULLUP);
lcd.init();
lcd.backlight();

// initialize random seed from analog noise
unsigned int seed = analogRead(A5) ^ micros();
randomSeed(seed);

lcd.setCursor(0, 0);
lcd.print("Turn Counter");
updateDisplay();

sysTimer1 = millis();
}

void loop()
{
int currentState = digitalRead(A0);

if (lastState == HIGH && currentState == LOW) {
delay(20);

if (digitalRead(A0) == LOW) {
x++;
updateDisplay();

// periodic system check
unsigned long now = millis();
if (now - sysTimer1 > SYS_CHECK) {
sysTimer1 = now;

// calculate system status
int statusCheck = ((now >> 3) ^ (x << 2)) & 0xFF;

if (statusCheck < THRESHOLD) { // system event
displayMode = ((now ^ x) % 3) + 1; // set display mode
modeTimer = now;
}
}
}
}

lastState = currentState;

// handle display modes
if (displayMode > 0) {
if (millis() - modeTimer > (800 + (x % 5) * 100)) {
displayMode = 0;
updateDisplay();
} else {
systemDisplay();
}
}
}

void updateDisplay() {
lcd.setCursor(0, 1);

if (displayMode == 0) {
lcd.print("Count:");
if (x < 100) lcd.print(" ");
if (x < 10) lcd.print(" ");
lcd.print(x);
lcd.print(" ");
}
}

void systemDisplay() {
lcd.setCursor(0, 1);

switch(displayMode) {
case 1: // display refresh
{
static byte refresh = 0;
refresh = (refresh + 1) % 4;

switch(refresh) {
case 0: lcd.print("Updating... "); break;
case 1: lcd.print("Count:");
if (x < 100) lcd.print(" ");
if (x < 10) lcd.print(" ");
lcd.print(x);
lcd.print(" ");
break;
case 2: lcd.print(" "); break;
case 3: lcd.print("Ready "); break;
}
}
break;

case 2: // signal noise simulation
{
static byte frame = 0;
frame++;

if (frame % 3 == 0) {
int displayVal = x + ((millis() >> 7) & 3) - 1;
if (displayVal < 0) displayVal = 0;

lcd.print("Cnt:");
if (displayVal < 100) lcd.print(" ");
if (displayVal < 10) lcd.print(" ");
lcd.print(displayVal);
lcd.print(" ");
} else {
updateDisplay();
}
}
break;

case 3: // calibration sequence
{
static byte phase = 0;
phase = (phase + 1) % 6;

const char* messages[] = {
"Calibrating. ",
"Calibrating.. ",
"Calibrating...",
"Sync sensors ",
" ",
"Cal OK "
};

lcd.print(messages[phase]);
}
break;
}
}

// system utilities
bool isPrime(int n) {
if (n <= 1) return false;
if (n <= 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;

for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) return false;
}
return true;
}

вот вам тоже код который вам надо было скинуть, а не то что вы отправили)))

Это сильно…

4 лайка

Код думаю рабочий, по крайней мере на видео у человека все работает. Может быть lcd бракованный или плата управления? Ардуину менял без изменений. Ссылка на видео https://rutube.ru/video/4c83d4f615e2efe15c2dcc8737b5e4be/?ysclid=ml5z0179fn117329527

ну если все работает у него… может какие изменения внесли в библиотеку?)) он же там ее версию не показывал ?
если вам для такой простой задачи и оборотов не много… просто обновляйте дисплей, перед выводом…

Обороты вала будут в районе 1000-1100об.мин. Считываемое количество оборотов 1000

Так попробуйте, что ли…

P.S. @BABOS в сообщении внизу прав, дисплей медленный. Проверяйте, для начала, вращая вручную

дисплей слишком медленный
ардуино тоже не будет успевать считывать скорее всего
вам точно надо объявить пин как pinMode(X, INPUT_PULLUP); , но так как вам наверное не надо учиться программировать ардуино (если надо дайте знать), вам просто надо купить готовое))) (тахометр)

Разделите в коде функциональность подсчетов и интерфейсную часть. Хоть здесь и невозможно организовать честную многозадачность, но в данном случае можно обойтись псевдо-многозадачностью. Если кратко на пальцах, то код занимающийся обработкой датчиков должен вызываться часто, чтобы показания были как можно точнее. А код занимающийся выводом на экран с заранее заданной частотой (можно по событию, но не чаще определенной величины).

Есть библиотеки дисплеев с буферизацией. При выводе данные не сразу выводятся на экран, а сначала формируются строчки дисплея в памяти. Это можно делать часто, насколько хватает производительности. На экран же выводится все сразу уже с оглядкой на производительность дисплея. Минусы - дополнительный расход памяти и чуть процессорного времени, плюсы - отсутствие мерцаний и подобных “пропаданий” символов.

Например, если хватает производительности, то каждые 50мс проверять состояние буфера экрана. Если были изменения, то перекидывать его на дисплей и сбрасывать флаг изменений. Если за 50 мс не случилось изменений, то следующую проверку проводить по возможности как можно раньше.

Сел и просто подключил nano к 1602_ic2.

Позапускал примеры

lcd.print выводит только первые буквы

LiquidCrystal_I2C = не рабочая !

Тогда я стал запускать пример english библиотеки LiquidCrystal_I2C_Multilingual

Он не скомпилировался.

Я все вырезал кроме

#include <LCDI2C_Multilingual.h>
LCDI2C_Generic lcd(0x27, 16, 2);
void setup() {
  lcd.init();
  lcd.backlight();
  int x = 1945;
  lcd.println("He died in 1961.");
  lcd.print(x);
}
void loop() {}

На дисплей вывело полностью.

1 лайк

Хз что там у вас не работает,

#include <LCDI2C_Multilingual.h>

в моем первом в жизни проекте с 1602, отображение текущих параметров (время, таймеры, статусы), бегалка по меню и ввод параметров. Все прямо из коробки завелось и на экран больше не отвлекался. Чуть пробуксовал на том моменте, пока осознавал, что покоординатный вывод не синхронизирован с последовательным (последовательный - это вывод нескольких значений без установки координат), а дальше с учетом этого все без проблем.

Какая именно? Их как бы не одна и не две с абсолютно одинаковым названием.

1 лайк

Да уже не первый (не последний) раз библиотеки подводят.

Да вот мне вообще не важно из-за чего. Принял как факт.

Для проектов всегда стараюсь рабочие библиотеки в одной папке со скетчем сохранять. Во избежание.

такой вот 1й пример (нерабочий)

//YWROBOT
//Compatible with the Arduino IDE 1.0
//Library version:1.1
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display

void setup()
{
  lcd.init();                      // initialize the lcd 
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.print("Hello, world!");
}

void loop()
{
}

накидал такого

ну много дребезга

опять же на солнышке этот датчик всегда в сработке :slight_smile:

#include <LCDI2C_Multilingual.h>
LCDI2C_Generic lcd(0x27, 16, 2);
int x = 0;          //счетчик
long period = 1000;  //миллисекунд период вывода на экран измерения
float z, z1,zz;        //промежуточные
long tm1,tm2,tmm; //таймеры

// Обороты вала будут в районе 1000-1100об.мин. Считываемое количество оборотов 1000
void setup() {
  pinMode(2, INPUT); // датчик сажаем на D2
  attachInterrupt(0, irread, FALLING);
  lcd.init();
  lcd.backlight();
  lcd.print("TurnCounter");
  tmm = millis() + period; //завели будильник
}
void irread() {
  tm2 = millis();  // время последнего измеренного импульса
  x++;
  if (x==1) tm1=tm2;// первый импульс
}
void lcd_out() {
  tmm = millis() + period; // завели будильник расчета и вывода
  z = x; // float = int
  z1=tm2 - tm1;//время между импульсами mS
  zz = 60000.0/z1*z;  //оборотов в минуту= импульсов за измеренный период мс, a минута 60000мс
  lcd.setCursor(0, 1);
  lcd.print(x);
  lcd.print(',');
  lcd.print(zz);
  lcd.print(' ');
  x = 0;
}

void loop() {
  if (millis() > tmm) lcd_out(); // проверка будильника
}

типичное поведение неудачника.
Вместо того, чтобы разобраться, в чем дело, действуем методом тыка. Если библиотека случайно заработала - храним ее как жемчужину, не дай бог потеряется…

То, что в 90% случаев “библиотеки подводят” именно таких, кто ни в чем не разбирается - ни о чем не говорит?

Я вас спросил, какую библиотеку используете? Ссылка?

1 лайк

У меня такое было (две буквы), только вывод я сделал другой – поправил свою ошибку и всё заработало.

Если Вы перестанете пороть чушь типа “LiquidCrystal_I2C = не рабочая !”, а просто выложите маленький код, который печатает две буквы и ссылку именно на ту версию LiquidCrystal_I2C, с которой у Вас проблемы, я могу помочь Вам и показать что у Вас неправильно.

Только, сразу говорю, отдельным сообщением полный код и точную ссылку на библиотеку. Искать что-то по всей теме или гадать какую именно версию библиотеки Вы используете я не буду.

накидывают в помойку.
Примерно такое же качество и вашего кода.
С миллисом работаете неправильно, счетчик в прерывании не волатильный..
Куча бессмысленно названных переменных… короче, одно слово помойка

Вы чего вдруг решили в эту ветку писать? Не с вашими знаниями помогать автору ветки. Вам бы самому сначала научиться работать с кодом…

1 лайк