Вывод вводимой строки на экран 1602 I2C

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

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

#include <StaticThreadController.h>
#include <Thread.h>
#include <ThreadController.h>
#include <LiquidCrystal_I2C.h>
#include <iarduino_RTC.h>//Часы, DS1302
#include <Wire.h>

iarduino_RTC watch(RTC_DS1302,10,13,12);
LiquidCrystal_I2C screen(0x3F,16,2);

Thread watchThread = Thread();
Thread textThread = Thread();

void setup() {
  watch.begin();
  screen.init();
  screen.backlight();

  watchThread.onRun(startWatch);
  watchThread.setInterval(1000);

  textThread.onRun(startText);
  textThread.setInterval(10);
  
  Serial.begin(9600);
}

void loop() {
  if(watchThread.shouldRun()) 
    watchThread.run();
  if(Serial.available() > 0)
    textThread.run();

}

void startWatch() {
  screen.setCursor(0,0);
  screen.print(watch.gettime("H:i d-m-y"));
}

void startText() {
  char cin; 
  char cout[16]; 
  cin = Serial.read();
  screen.setCursor(0,1);
  sprintf(cout,"%c",cin);
  String str(cout);
  screen.print(str);
  Serial.print(str);
}

 

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Извиняюсь, проблема оказалась в другом: char разбивает слова. С р разобрался, мой косяк сборки. Как выводить слова целиком на экран?

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

#include <LiquidCrystal.h>

LiquidCrystal screen(2,3,4,5,6,7);

void setup() {
  Serial.begin(9600);
  screen.begin(16,2);
}
void loop() 
{
  if(Serial.available() > 0)
  {
    delay(100);
    char cout[]="                ";
    for (int i=0;Serial.available();i++)
    cout[i] = Serial.read();
    screen.setCursor(0,1);
    print_char_array(cout);
    Serial.write(cout);
    Serial.println("");
  }
}
void print_char_array(char *char_array)
{
  byte i=0;
  while(char_array[i]!='\0')screen.write(char_array[i++]);
}

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Вашем скетче переменная cin была типа char, ее значение вы брали из порта, то есть только один символ. а нужно весь буфер запилить. печатать можно и через String но ведь это зло...

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Mr.Privet пишет:

 печатать можно и через String но ведь это зло...

Зло, но печатаю жеж и экран не блымает, а то некоторым не нравится, когда блымает

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

if(Serial.available() > 0)
  {
    delay(100);

 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

ua6em пишет:

Зло, но печатаю жеж и экран не блымает, а то некоторым не нравится, когда блымает

Ну я тоже сторонник того что ресурсы нужно использовать полностью, но когда Стринг уже не влазиет можно же и посимвольно блымать. а чтобы блымать быстро подключайте без i2c, на прямую

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а всё жеж, насчёт задержки... а IIC это святое )))
 и второе, я задолбался с версиями IDE, под 1.6.12 ваш код не компилируется, не нравится ему функция print_char_array!
Сволочь, кричит, что не объявлена )))

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Ну да, забыл совсем выше ее нужно ставить. Видимо circuis еще не обновили калькулятор. Кстати на счет circuis там сейчас кучу латчиков добавили, тебе и дальномер и газ. Нравится мне этот проект. Да и единственный для меня способ с работы сидеть там...

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Пробовал String, она выводит коды букв из таблицы ASCI. До ардуины только добрался, сейчас попробую местные варианты

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

да работает:

//вывод символов на дисплей//
    String str001 = String(chas);
    String str002 = String(min);
    String str003 = String(sek);
     utftDisplay.setFont(SevenSegmentFull);
     utftDisplay.setColor(0, 255, 173);
   // utftDisplay.print(str001 + ":" + str002 + ":" + str003, 5,  7);
   if (chas>=0 && chas<10 && min>=0 && min<10) {
       utftDisplay.print("0"+str001 + ":" + "0"+str002, 5,  7);}
     if (chas>=0 && chas<10 && min>=10) {
       utftDisplay.print("0"+str001 + ":" + str002, 5,  7);}
       if (chas>=10 && min>=0 && min<10) {
       utftDisplay.print(str001 + ":" + "0"+str002, 5,  7);}
         if (chas>=10 && min>=10) {
         utftDisplay.print(str001 + ":" + str002, 5,  7);}
         
         // секунды выводим други шрифтом
         utftDisplay.setFont(BigFont);
         
         if (sek>=0 && sek<10) {
         utftDisplay.print(":0" + str003, 167, 7);}
          if (sek>=10) {
         utftDisplay.print(":" + str003, 167, 7);}
         
  }

 

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Попробовал ваш метод... код:

#include <StaticThreadController.h>
#include <Thread.h>
#include <ThreadController.h>
#include <LiquidCrystal_I2C.h>
#include <iarduino_RTC.h>
#include <Wire.h>

iarduino_RTC watch(RTC_DS1302,10,13,12);
LiquidCrystal_I2C screen(0x3F,16,2);

Thread watchThread = Thread();
Thread textThread = Thread();

void setup() {
  watch.begin();
  //watch.settime(15,27,21,16,11,16,3);
  screen.init();
  screen.backlight();

  watchThread.onRun(startWatch);
  watchThread.setInterval(1000);

  textThread.onRun(startText);
  textThread.setInterval(10);
  
  Serial.begin(9600);
}

void loop() {
  if(watchThread.shouldRun()) 
    watchThread.run();
  if(Serial.available() > 0)
    textThread.run();

}

void startWatch() {
  screen.setCursor(0,0);
  screen.print(watch.gettime("H:i d-m-y"));
}

void startText() {
  char cout[16] = "                "; 
  for(int i=0;Serial.available();i++) {
    cout[i]=Serial.read();
  }
  screen.setCursor(0,1);
  print_char_array(cout);
  Serial.write(cout);
}

void print_char_array(char *charArray) {
  byte i = 0;
  while(charArray[i] != '\0')
    screen.write(charArray[i++]);
}
Скрин консоли:
 
Кстати, стринг он тоже на отдельные части разбивал
Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Сейчас собаку вышулю и разберемся, пока про не закидали какашками

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

ua6em пишет:

А вот позвольте полюбопытствовать, зачем задержка в 100 миллисекунд?

(есть предположение, что я на косяк нарывался именно из-за этого)

if(Serial.available() > 0)
  {
    delay(100);

тут такое дело, данные у нас с сириал не мгновенно попадают в ардуину, а передаются какое то время если не ставить задержку то при попадании первого байта у нас available уже становится больше нуля, программа лезит в иф, но там только 1 байт, она его как положено печатает, а во втором цыкле уже печатает все остальные так как они успевают добежать пока мы все там выводим на экран. так что когда aveilable я решил подождать остальные байты, чтобы они точно пришли. Может есть способ сделать по другому, я сделал так, и все работает.

Lone Simba пишет:

Попробовал ваш метод... 

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

 if (chas>=0 && chas<10 && min>=0 && min<10) {
       utftDisplay.print("0"+str001 + ":" + "0"+str002, 5,  7);}
     if (chas>=0 && chas<10 && min>=10) {
       utftDisplay.print("0"+str001 + ":" + str002, 5,  7);}
       if (chas>=10 && min>=0 && min<10) {
       utftDisplay.print(str001 + ":" + "0"+str002, 5,  7);}
         if (chas>=10 && min>=10) {
         utftDisplay.print(str001 + ":" + str002, 5,  7);}

с моими глазами происходит то же что и на моей аватарке. Хотя в принципе работает да и ладно, но мы же развиваемся, поэтому пишем 

char out[5];
sprintf(out,"%02i:%02i",chas,min);
utftDisplay.print(String(out);

В принципе должно печатать тоже самое.

Если уж так нравится String то давайте сделаем так:

#include <LiquidCrystal.h>

LiquidCrystal screen(2,3,4,5,6,7);
String cout;
void setup() {
  Serial.begin(115200);
  screen.begin(16,2);
}
void loop() 
{
  if(Serial.available())
  {
    delay(2);
    while(Serial.available())cout+=(char)(Serial.read());
  }
  if(cout!=""){
    screen.setCursor(0,1);
    screen.print("                ");// типа очистки
    screen.setCursor(0,1);
    screen.print(cout);
    Serial.println(cout);
    cout="";
  }
}

Ну и в качестве задания для Вас объединить 2 скеча

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Учитель, можно ДЗ завтра сделать, а то меня уже мутит от C++ 

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Lone Simba пишет:

Учитель, можно ДЗ завтра сделать, а то меня уже мутит от C++ 


Да я такой же ученик, только на год старше))))

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

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

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Урааа, вы были правы, все заработало. Вот только эти квадраты в конце вывода консоли меня напрягают. PS - это из-за указания размера массива cout. убрал цифры(как в вашем скетче) и все чистенко.

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Кстати, вот у меня вопрос... я, понимаете-ли, немного дуб в плюсах, и не могу понять, почему print остаток места в массива забивает своими кракозябрами, а write нет

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Вот здесь мне трудно подсказать так как я сам не до конца догнал. print печатает символы, а write бинарный код. И печатает он то что есть в массиве, если он печатает крыказябы значит они есть в массиве. Обычно это свидетельствует о выходе за пределы массива. Попробуйте мой скетч со String, новичку он должен быть более понятнн. Вообще String для новичков и создан, просто не далек тот день когда Ваш проект упрется String'ом в ограничение памяти и тогда нужно будет изобретать безстринговые конструкции как в моем первом примере...

Lone Simba
Lone Simba аватар
Offline
Зарегистрирован: 14.11.2016

Собственно из-за памяти я String и не стал использовать в скетчах. На ПеКе то памяти 15 товарных составов, а тут пол-вагонетки