Помогите разобраться Вывод данных их СОМ порта на lcd 1602

avgustdon
Offline
Зарегистрирован: 28.02.2016

Добрый день!

Помогите разобраться, как вывести счет нажатий кнопки на дисплей. Скетч склеил из двух других скетчей. Часть отвечающия за работу кнопки и вывод счета на монитор СОМ порта работает замечательно. На дисплей, как не изгалялся, этот счет вывести не получается, хотя стандарное "Hello world!" без проблем работает. Буду рад любому совету, т.к. я совсем начинающий.

Вот то, что у меня получилось.

//счетчик импульсов
const int button = 7;     // вывод контроллера для кнопки
int count = 0;         // переменная для подсчета нажатий на кнопку
int button_old = 1;    // предыдущее значение входа для отлавливания момента нажатия
#include <LiquidCrystal.h> // Подключаем библиотеку работы с символьными дисплеями
LiquidCrystal lcd(13, 11, 5, 4, 3, 2); // (RS, E, D4, D5, D6, D7) подключаем выходы дисплея 
//согласно последовательности, R/W – GND, так как мы будем записывать данные в дисплей, а не считывать

void setup() {
{ //Здесь подключаем порт для работы с кнопкой:
    //Serial.begin(9600); //инициализация связи с монитором порта. 
  //конфигурация входа контроллера и подключение внутреннего подтягивающего резистора
  pinMode(button, INPUT_PULLUP);
}
{  //Здесь подключаем дисплей
  lcd.begin(16, 2); // Инициализируем LCD 1602
  Serial.begin(9600); // Запускаем последовательный порт
}}
void loop() {
{  //Здесь программа работы с кнопкой
  if ((digitalRead(button)==LOW)&&(button_old==1))
  { 
    count = count + 1;
    Serial.println(count);
  }
  button_old = digitalRead(button); 
  
  delay(100);

 //Здесь программа работы с дисплеем
  /* Устанавливаем курсор в 1 столбец 2й строки. Нумерация идёт с нуля,
  * первым аргументом идёт номер столбца.
  */
  {
  if(Serial.available()){
    lcd.setCursor(0, 1);
    lcd.print("                ");
    delay(100);
    lcd.setCursor(0, 1);
    while(Serial.available() > 0){
      lcd.write(Serial.read());
    }
  }
}}}

/* часть скетча отвечающая за кнопку работает безукоризненно. 
Часть отвечающая за работу с дисплеем кроме как заполнением экрана прямоугольниками 
никак себя не проявила. 
*/

 

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

void loop() {

if(digitalRead(button)==HIGH)

{

lcd.clear();

count++;

lcd.setCursor(0,1);

lcd.write(count);

}

}

То что прямоугольники, скорее всего подключили дисплей не верно.

avgustdon
Offline
Зарегистрирован: 28.02.2016

Спасибо за ответ.

Дисплей, думаю подключил верно, иначе не удалось бы изобразить "Hello world!"

Вставил вашу часть скетча вместо своей. Теперь в левом нижнем углу при нажатии кнопки сменяютя разные символы. 

На сколько я понял вы предложили считывать состояние кнопки и выводить счет на дисплей. Мне нужно выводить данные именно с СОМ порта. Кнопка применена потому, что она идет с удачным скетчем, выводящим данные нажатия кнопки на СОМ порт. В дальнейшем предполагаю адаптировать дисплей для вывода данных температуры и влажности. Тоже есть неплохой скетч выводящий данные на СОМ порт. 

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

Вероятно lcd может не нравится тип int, тогда можно попробовать тип char.

char count=0;

Немного не так, если быть "дословным", то ваш count будет увеличиваться на 1, при каждом нажатии на кнопку. Это то что я реализовал в это коде. Com порт в вашем случае будет лишним. И вместо lcd.setCursor(0,1); Поставьте (0,0); Полагаю вы понимаете что lcd.begin(16,2); указанный вами в сетапе означает что вы используете лсд дисплей с 16 символами на две строчки? Строки и столбцы в данном случае начинаются с нуля (0,0), будет означать левый верхний угол.

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015
 41     lcd.write(Serial.read());

заменить на 

41      lcd.print(Serial.read());

и учить из библеотеки Serial чем write отличается от print

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

А, точно.. :(

avgustdon
Offline
Зарегистрирован: 28.02.2016

Aleksey1317 пишет:

Вероятно lcd может не нравится тип int, тогда можно попробовать тип char.

char count=0;

Немного не так, если быть "дословным", то ваш count будет увеличиваться на 1, при каждом нажатии на кнопку. Это то что я реализовал в это коде. Com порт в вашем случае будет лишним. И вместо lcd.setCursor(0,1); Поставьте (0,0); Полагаю вы понимаете что lcd.begin(16,2); указанный вами в сетапе означает что вы используете лсд дисплей с 16 символами на две строчки? Строки и столбцы в данном случае начинаются с нуля (0,0), будет означать левый верхний угол.

Алексей, я попробовал внести предложенные вами изменения. Теперь символы также отображаются, но теперь в левом нижнем углу экрана.  Дисплей использую  с 16 символами в 2 строчки. Как я понимаю LCD 1602 именно поэтому так и называется. На всякий случай посчитал символы.)) Все совпадает. Насчет СОМ порта. Все-таки считаю, что он мне будет нужен, причину описывал выше. Мне кажется, проще считать данные из порта, чем стыковать дисплей с датчиками влажности и температуры. 

avgustdon
Offline
Зарегистрирован: 28.02.2016

Mr.Privet, я обязательно постараюсь разобраться чем write отличается от print, но ваша поправка не дала результата. На дисплее ничего не отображается. Я кстати, это уже пробовал до вашего предложения. Бессистемно, конечно, интуитивно, но в разных комбинациях. Не получилось, в общем. Но все равно спасибо за совет.

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

Попробуйте еще вместо вот этой строчки:  if ((digitalRead(button)==LOW)&&(button_old==1)) вставить вот эту:  if (digitalRead(button)==HIGH), по поводу переменной button old, она в себе не несет никакой значимости, это практически та же самая переменная, только в первый раз, в вашем условии у вас может будет равно 1, а вот все следующие уже нет, поэтому условие не будет работать. 

Aleksey1317
Offline
Зарегистрирован: 07.02.2015


попробуйте вставить вот это
//счетчик импульсов
const int button = 7;     // вывод контроллера для кнопки
int count = 0;         // переменная для подсчета нажатий на кнопку
#include <LiquidCrystal.h> // Подключаем библиотеку работы с символьными дисплеями
LiquidCrystal lcd(13, 11, 5, 4, 3, 2); // (RS, E, D4, D5, D6, D7) подключаем выходы дисплея 
//согласно последовательности, R/W – GND, так как мы будем записывать данные в дисплей, а не считывать
 
void setup() {
{ //Здесь подключаем порт для работы с кнопкой:
    //Serial.begin(9600); //инициализация связи с монитором порта. 
  //конфигурация входа контроллера и подключение внутреннего подтягивающего резистора
  pinMode(button, INPUT_PULLUP);
}
{  //Здесь подключаем дисплей
  lcd.begin(16, 2); // Инициализируем LCD 1602
  Serial.begin(9600); // Запускаем последовательный порт
lcd.setCursor(0,0);
}}
void loop() {
{  //Здесь программа работы с кнопкой
  if (digitalRead(button)==HIGH)
  { 
    count++;
    Serial.println(count);
  }
 
  
  delay(100);
 
 //Здесь программа работы с дисплеем
  /* Устанавливаем курсор в 1 столбец 2й строки. Нумерация идёт с нуля,
  * первым аргументом идёт номер столбца.
  */
  {
  if(Serial.available()){
   lcd.clear();
    lcd.setCursor(0, 0);
    while(Serial.available() > 0){
      lcd.write(Serial.read());
    }
  }
}}}
 
Aleksey1317
Offline
Зарегистрирован: 07.02.2015
А лучше вот это
const int button = 7;     // вывод контроллера для кнопки
int count = 0;         // переменная для подсчета нажатий на кнопку
#include <LiquidCrystal.h> // Подключаем библиотеку работы с символьными дисплеями
LiquidCrystal lcd(13, 11, 5, 4, 3, 2); // (RS, E, D4, D5, D6, D7) подключаем выходы дисплея 
//согласно последовательности, R/W – GND, так как мы будем записывать данные в дисплей, а не считывать
 
void setup() {
{ //Здесь подключаем порт для работы с кнопкой:
    //Serial.begin(9600); //инициализация связи с монитором порта. 
  //конфигурация входа контроллера и подключение внутреннего подтягивающего резистора
  pinMode(button, INPUT_PULLUP);
}
{  //Здесь подключаем дисплей
  lcd.begin(16, 2); // Инициализируем LCD 1602
  Serial.begin(9600); // Запускаем последовательный порт
}}
void loop() {
{  //Здесь программа работы с кнопкой
  if (digitalRead(button)==HIGH)
  { 
    count++;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(count);
 
   
  }
 
  
}
 
avgustdon
Offline
Зарегистрирован: 28.02.2016

Aleksey1317 пишет:

А лучше вот это
const int button = 7;     // вывод контроллера для кнопки
int count = 0;         // переменная для подсчета нажатий на кнопку
#include <LiquidCrystal.h> // Подключаем библиотеку работы с символьными дисплеями
LiquidCrystal lcd(13, 11, 5, 4, 3, 2); // (RS, E, D4, D5, D6, D7) подключаем выходы дисплея 
//согласно последовательности, R/W – GND, так как мы будем записывать данные в дисплей, а не считывать
 
void setup() {
{ //Здесь подключаем порт для работы с кнопкой:
    //Serial.begin(9600); //инициализация связи с монитором порта. 
  //конфигурация входа контроллера и подключение внутреннего подтягивающего резистора
  pinMode(button, INPUT_PULLUP);
}
{  //Здесь подключаем дисплей
  lcd.begin(16, 2); // Инициализируем LCD 1602
  Serial.begin(9600); // Запускаем последовательный порт
}}
void loop() {
{  //Здесь программа работы с кнопкой
  if (digitalRead(button)==HIGH)
  { 
    count++;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(count);
 
   
  }
 
  
}
 

Алексей, последний вариант вывел - таки на дисплей цифры, но за одно нажатие показания увеличиваются более чем на 1. Полагаю это дребезг контактов. Вариант, который пытаюсь применить я, полностью избавлен от этой проблемы. На мониторе СОМ порта  сейчас показаний нет. И как я понял вы опять берете данные считывая их непосредственно с кнопки. 

avgustdon
Offline
Зарегистрирован: 28.02.2016

Добавил в конце delay(500); Теперь значения на дисплее увеличиваются на количество нажатий кнопки. Уже за это спасибо огромное! Хорошо бы теперь победить считывание на дисплей с СОМ порта.)

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

А попробуйте так? 

void setup() {
{ //Здесь подключаем порт для работы с кнопкой:
    //Serial.begin(9600); //инициализация связи с монитором порта. 
  //конфигурация входа контроллера и подключение внутреннего подтягивающего резистора
  pinMode(button, INPUT_PULLUP);
}
{  //Здесь подключаем дисплей
  lcd.begin(16, 2); // Инициализируем LCD 1602
  Serial.begin(9600); // Запускаем последовательный порт
lcd.setCursor(0,0);
}}
void loop() {
 //Здесь программа работы с кнопкой
  if (digitalRead(button)==HIGH)
  { 
    count++;
    Serial.println(count);
  }
 
  
  delay(100);
 
 //Здесь программа работы с дисплеем
  /* Устанавливаем курсор в 1 столбец 2й строки. Нумерация идёт с нуля,
  * первым аргументом идёт номер столбца.
  */
  
   int serial_read=0;
   lcd.clear();
    lcd.setCursor(0, 0);
  serial_read=(Serial.read());
     lcd.print(serial_read);
    
  
}
avgustdon
Offline
Зарегистрирован: 28.02.2016

на мониторе увеличение показаний >1. на дисплее -1 и никуда не двигается.

avgustdon
Offline
Зарегистрирован: 28.02.2016

avgustdon пишет:

Добавил в конце delay(500); Теперь значения на дисплее увеличиваются на количество нажатий кнопки. Уже за это спасибо огромное! Хорошо бы теперь победить считывание на дисплей с СОМ порта.)

Забыл, еще count++; заменил на count+1; Без этого после первого нажатия устанавливался 0 и все.

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

А что монитор порта выводит? 

avgustdon
Offline
Зарегистрирован: 28.02.2016

увеличение показаний >1.

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

Попробуйте строку count++; заменить на count=count+1;

avgustdon
Offline
Зарегистрирован: 28.02.2016

то же самое

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Aleksey1317 пишет:

Попробуйте строку count++; заменить на count=count+1;

Попробуйте сложить 1 + 2, а потом 2 +1 - результат в том и другом случае будет одинаков. ++ - это оператор инкремента в С++, бывает постфиксный и префиксный. В приведённом куске тупо увеличивает на 1 значение переменной.

Ох уж это паскакалевское наследие :)

avgustdon
Offline
Зарегистрирован: 28.02.2016

DYIMan, похоже вы правы, это одно и то же. А можете по скетчу что-нибудь подсказать?

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

:D ну скорее шарповское)) Да, я понимаю что это одно и то же, но не понимаю почему Serialport не может выводить интовскую переменную..

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Вам надо счётчик нажатия кнопки на дисплей вывести? Самое тупое, в лоб:

lcd.print(String(count));

Или я не понял проблемы?

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Aleksey1317 пишет:

:D ну скорее шарповское)) Да, я понимаю что это одно и то же, но не понимаю почему Serialport не может выводить интовскую переменную..

Кто сказал что не может? Он её выводит, просто всё зависит от того, в каком виде он её выводит:

Serial.println(String(whatever_you_want));

Принудительно переведёт любую понятную классу String переменую в её строковое представление.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Aleksey1317 пишет:

:D ну скорее шарповское))

В C# тоже есть оператор ++ ;) https://msdn.microsoft.com/ru-ru/library/36x43w8w.aspx

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

То есть я правильно понимаю, что в serial port можно отправлять только строковые переменные? Просто дело в том, что даже сейчас у меня тот же код работает, за исключением lcd(у меня его попросту нет). Я никогда прежде не сталкивался с такой проблемой.

avgustdon
Offline
Зарегистрирован: 28.02.2016

DIYMan пишет:

Вам надо счётчик нажатия кнопки на дисплей вывести? Самое тупое, в лоб:

lcd.print(String(count));

Или я не понял проблемы?

Нужно на дисплей вывести данные СОМ порта. Полностью задачу и причину почему она именно так поставлена описал в своем втором посте.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

write - пишет байт как байт, что для LCD равнозначно команде "вывести символ с переданным кодом". Если вы хотите вывести число на lcd - его надо преобразовать в строковое представление. Согласитесь, что "123" и 123 - это не одно и то же, правда? Во втором случае, если скормить число 123 экрану - он попытается отобразить символ с кодом 123, в первом случае, когда передали строку  - коды каждого символа в строке уже соответствуют кодам символов в таблице дисплея.

Для понимания советую попробовать следующее:

Serial.println('1');
Serial.println(1);

 

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

Я понимаю:) Я всегда пользуюсь инкрементом такого вида, это удобно.

avgustdon
Offline
Зарегистрирован: 28.02.2016

Попробовать то я попробую, только вот в мои 53 года не все легко усваивается. Потому и попросил помощи у знающих людей. А вообще всегда  легче усваиваю на рабочих примерах. Но по любому спасибо. Буду пробовать.

Aleksey1317
Offline
Зарегистрирован: 07.02.2015

Все, понял вас, разобрался! Спасибо:)