Вывод на LCD текста и данных в одной строке

tran
Offline
Зарегистрирован: 20.10.2012

Добрый день! Возникла неприятная мелочь - в функции lcd.print() не получается объединить строковый и числовой типы, т.е. вот так не получается:

lcd.print("температура" +  h_temp);

Из-за этого приходится городить целую гору лишних вызовов этой функции и фунции, перемещающей курсор. Есть какой-нибудь выход?

msg31
Offline
Зарегистрирован: 01.12.2013

tran пишет:

Добрый день! Возникла неприятная мелочь - в функции lcd.print() не получается объединить строковый и числовой типы, т.е. вот так не получается:

lcd.print("температура" +  h_temp);

Из-за этого приходится городить целую гору лишних вызовов этой функции и фунции, перемещающей курсор. Есть какой-нибудь выход?

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

lcd.print.

 
tran
Offline
Зарегистрирован: 20.10.2012

эмм, всмысле данные и текст в одну строку запихать, а потом ее выводить на ЖКИ? Или как? Что-то не пойму что здесь делает spritf();

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013
 lcd.write(("Indoor Temp. = ")+(value));   // так получится только с двумя аргументами

Но лучше так:

  String message =  String("Indoor temp. = " + value + " C");  // любое количество аргументов
  lcd.print(message); 
  Serial.print(message);

 

 

msg31
Offline
Зарегистрирован: 01.12.2013

tran пишет:

эмм, всмысле данные и текст в одну строку запихать, а потом ее выводить на ЖКИ? Или как? Что-то не пойму что здесь делает spritf();

sprintf, это та же функция, что и printf, только результат выводит в строку.
Например.
 
char lcd_buffer[16]; // Массив для вывода
sprintf(lcd_buffer,"DSdebug=%u",ds1820_devices); //запись в буфер текста и значений
lcd.print(lcd_buffer); // Вывод
 
 
 
Piskunov
Offline
Зарегистрирован: 13.02.2014

Tomasina пишет:

  String message =  String("Indoor temp. = " + value + " C");  // любое количество аргументов
  // ...
  Serial.print(message);

А у меня так вообще не получается. Ошибки при компиляции...

Test_String_function.ino: In function 'void loop()':
Test_String_function:14: error: call of overloaded 'String(float)' is ambiguous
arduino\hardware\arduino\cores\arduino/WString.h:70: note: candidates are: String::String(long unsigned int, unsigned char)
arduino\hardware\arduino\cores\arduino/WString.h:69: note:                 String::String(long int, unsigned char)
arduino\hardware\arduino\cores\arduino/WString.h:68: note:                 String::String(unsigned int, unsigned char)

int a;
char b;
float c;
String output_string;
//
void setup(){
  Serial.begin(4800);
}
void loop(){
  a = 3;
  b = '-';
  c = 3,14;
  output_string = String (a + b + c);
  Serial.println(output_string);
  delay (1000);
}

 

com
Offline
Зарегистрирован: 06.09.2013

юзайте пример с sprintf который msg31 бросил,  там не так все сложно и намного больше возможностей чем с использованием String

Piskunov
Offline
Зарегистрирован: 13.02.2014

Всё равно ничего не выходит :-(

Ошибки.

Test_String_function.ino: In function 'void loop()':
Test_String_function:11: error: invalid conversion from 'int' to 'const char*'
Test_String_function:11: error: initializing argument 2 of 'int sprintf(char*, const char*, ...)'
 

int a = 3;
char b = '-';
float c = 3.14;
char output_string[16];
//
void setup(){
  Serial.begin(4800);
}
void loop(){
  sprintf(output_string, a, b, c);
  Serial.println(output_string);
  delay (1000);
}

 

com
Offline
Зарегистрирован: 06.09.2013

Piskunov пишет:

Всё равно ничего не выходит :-(

http://www.chitay.org/c/13/sprintf.htm и особенно http://www.chitay.org/c/13/printf.htm

Piskunov
Offline
Зарегистрирован: 13.02.2014

Супер! Теперь вышло.

 

DimaP.
Offline
Зарегистрирован: 21.04.2013

Piskunov пишет:

Супер! Теперь вышло.

 

Покажите пожалуйста, в каком виде все это получилось, чет читаю и ничего не пойму!!

msg31
Offline
Зарегистрирован: 01.12.2013

DimaP. пишет:

Piskunov пишет:

Супер! Теперь вышло.

 

Покажите пожалуйста, в каком виде все это получилось, чет читаю и ничего не пойму!!

Ты посмотри как функцию printf использовать. Просто погугли. Найдешь кучу примеров и ссылок на книжки всякие. Начни с азов "Hello World", это самое первое, что на Си изучают.

Piskunov
Offline
Зарегистрирован: 13.02.2014

DimaP. пишет:

Piskunov пишет:

Супер! Теперь вышло.

 

Покажите пожалуйста, в каком виде все это получилось, чет читаю и ничего не пойму!!

Вот мой тестовый вариант.

int a = 3;
char b = '-';
float c = 3.14;
char output_string[16];
//
void setup(){
  Serial.begin(4800);
}
void loop(){
  sprintf ( output_string, "%02i %2c %4.2f", a, b, c );
  // output_string - куда выводить, массив char
  // "%02i %2c %4.3f" формат вывода аргументов: 
  // %02(два поля - сначала нули)i(int)
  // %2(два поля)c(char)
  // %4(4 поля всего).2(после запятой)f(float)
  // про форматы - htp://www.chitay.org/c/13/printf.htm
  Serial.println(output_string);
  delay (1000);
}

 

pkv
Offline
Зарегистрирован: 20.08.2013

Воспользовался советом из данной темы, вот что получается:

char sdate[10];
char stime[8];

void loop()
{
    lcd.setCursor(0,0);
    lcd.print("Date: ");
    sprintf(sdate, "%04d.%02d.%02d", RTC.get(DS1307_YR,false), RTC.get(DS1307_MTH,false), RTC.get(DS1307_DATE,false));
    lcd.print(sdate);
    lcd.setCursor(0,1);
    lcd.print("Time: ");
    sprintf(stime, "%02d:%02d:%02d", RTC.get(DS1307_HR,false), RTC.get(DS1307_MIN,false), RTC.get(DS1307_SEC,false));
    lcd.print(stime);
  }

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

В то же время с таким кодом данные даты и времени обновляются из модуля часов реального времени:

void loop()
{
    lcd.setCursor(0,0);
    lcd.print("Date: ");
    lcd.print(RTC.get(DS1307_MTH,false));
    lcd.print(".");
    lcd.print(RTC.get(DS1307_DATE,false));
    lcd.setCursor(0,1);
    lcd.print("Time: ");
    lcd.print(RTC.get(DS1307_HR,true));
    lcd.print(":");
    lcd.print(RTC.get(DS1307_MIN,false));
    lcd.print(":");
    lcd.print(RTC.get(DS1307_SEC,false));  
  }

Из-за чего может быть проблема?

msg31
Offline
Зарегистрирован: 01.12.2013

pkv пишет:

Из-за чего может быть проблема?

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

char sdate[11];
02 char stime[9];

 

DimaP.
Offline
Зарегистрирован: 21.04.2013

Piskunov пишет:

DimaP. пишет:

Piskunov пишет:

Супер! Теперь вышло.

 

Покажите пожалуйста, в каком виде все это получилось, чет читаю и ничего не пойму!!

Вот мой тестовый вариант.



int a = 3;
char b = '-';
float c = 3.14;
char output_string[16];
//
void setup(){
  Serial.begin(4800);
}
void loop(){
  sprintf ( output_string, "%02i %2c %4.2f", a, b, c );
  // output_string - куда выводить, массив char
  // "%02i %2c %4.3f" формат вывода аргументов: 
  // %02(два поля - сначала нули)i(int)
  // %2(два поля)c(char)
  // %4(4 поля всего).2(после запятой)f(float)
  // про форматы - htp://www.chitay.org/c/13/printf.htm
  Serial.println(output_string);
  delay (1000);
}

 

Теперь все гораздо прозрачнее! Ну по крайней мере для меняя! Я не знал того что под каждый тип переменной надо в функции sprintf задавать так называемые "границы" Вообще крайне удобная вещь когда на LCD в строчке приходится выводить несколько переменных типа int+char/ А если переменная будет меньше размера поля, ну допустим 

%03i // 3 поля переменная типа int сначала нули

будет выведено число 

00X

 

com
Offline
Зарегистрирован: 06.09.2013

DimaP. пишет:

Теперь все гораздо прозрачнее! Ну по крайней мере для меняя! Я не знал того что под каждый тип переменной надо в функции sprintf задавать так называемые "границы"

не надо. это опционально

maksim
Offline
Зарегистрирован: 12.02.2012

pkv пишет:

Воспользовался советом из данной темы, вот что получается:

char sdate[10];
char stime[8];

void loop()
{
    lcd.setCursor(0,0);
    lcd.print("Date: ");
    sprintf(sdate, "%04d.%02d.%02d", RTC.get(DS1307_YR,false), RTC.get(DS1307_MTH,false), RTC.get(DS1307_DATE,false));
    lcd.print(sdate);
    lcd.setCursor(0,1);
    lcd.print("Time: ");
    sprintf(stime, "%02d:%02d:%02d", RTC.get(DS1307_HR,false), RTC.get(DS1307_MIN,false), RTC.get(DS1307_SEC,false));
    lcd.print(stime);
  }

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

В то же время с таким кодом данные даты и времени обновляются из модуля часов реального времени:

void loop()
{
    lcd.setCursor(0,0);
    lcd.print("Date: ");
    lcd.print(RTC.get(DS1307_MTH,false));
    lcd.print(".");
    lcd.print(RTC.get(DS1307_DATE,false));
    lcd.setCursor(0,1);
    lcd.print("Time: ");
    lcd.print(RTC.get(DS1307_HR,true));
    lcd.print(":");
    lcd.print(RTC.get(DS1307_MIN,false));
    lcd.print(":");
    lcd.print(RTC.get(DS1307_SEC,false));  
  }

Из-за чего может быть проблема?

char sdate[10];
char stime[8];

void loop()
{
    lcd.setCursor(0,0);
    lcd.print("Date: ");
    sprintf(sdate, "%04d.%02d.%02d", RTC.get(DS1307_YR,true), RTC.get(DS1307_MTH,false), RTC.get(DS1307_DATE,false));
    lcd.print(sdate);
    lcd.setCursor(0,1);
    lcd.print("Time: ");
    sprintf(stime, "%02d:%02d:%02d", RTC.get(DS1307_HR,false), RTC.get(DS1307_MIN,false), RTC.get(DS1307_SEC,false));
    lcd.print(stime);
}

 

pkv
Offline
Зарегистрирован: 20.08.2013

maksim пишет:

char sdate[10];
char stime[8];

void loop()
{
    lcd.setCursor(0,0);
    lcd.print("Date: ");
    sprintf(sdate, "%04d.%02d.%02d", RTC.get(DS1307_YR,true), RTC.get(DS1307_MTH,false), RTC.get(DS1307_DATE,false));
    lcd.print(sdate);
    lcd.setCursor(0,1);
    lcd.print("Time: ");
    sprintf(stime, "%02d:%02d:%02d", RTC.get(DS1307_HR,false), RTC.get(DS1307_MIN,false), RTC.get(DS1307_SEC,false));
    lcd.print(stime);
}

Максим, благодарю! Теперь работает, только почему Ваш код заработал, а мой нет я не понял.. разница ведь только в true/false в начале, но в чем разница между этими значениями нигде информации не нашел...

msg31
Offline
Зарегистрирован: 01.12.2013

Вижу, ты так и не увеличил размер массива. У тебя запихивается в массив sdate 10 символов, а надо еще место под завершающий символ с кодом 0. Также и в stime. Увеличь размер, а то запись пойдет неизвестно куда.

maksim
Offline
Зарегистрирован: 12.02.2012

Да кстати, не обратил внимание на эту красоту:

char sdate[11];
02 char stime[9];

Дело вам говорят, нужны еще по одному символу в массивах

char sdate[11];
char stime[9];

Иначе не равен час впишется этот ноль куда нибудь туда, куда не надо или наоборот затрется и будет вам экран показывать содержимое ОЗУ.

pkv
Offline
Зарегистрирован: 20.08.2013

msg31, maksim

да, да. Спасибо.

туда тоже добавил по дополнительному элементу. Пока вроде больше загвоздок не появилось.

 

PS: Пытаюсь сделать 4х канальный таймер для аквариума, а то китайские одноканальные периодически скидывают время и места много занимают...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Надо будет и себе попробовать

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Piskunov пишет:

DimaP. пишет:

Piskunov пишет:

Супер! Теперь вышло.

 

Покажите пожалуйста, в каком виде все это получилось, чет читаю и ничего не пойму!!

Вот мой тестовый вариант.

int a = 3;
char b = '-';
float c = 3.14;
char output_string[16];
//
void setup(){
  Serial.begin(4800);
}
void loop(){
  sprintf ( output_string, "%02i %2c %4.2f", a, b, c );
  // output_string - куда выводить, массив char
  // "%02i %2c %4.3f" формат вывода аргументов: 
  // %02(два поля - сначала нули)i(int)
  // %2(два поля)c(char)
  // %4(4 поля всего).2(после запятой)f(float)
  // про форматы - htp://www.chitay.org/c/13/printf.htm
  Serial.println(output_string);
  delay (1000);
}

 

У меня Ваш пример не выводит переменую типа float.

 

com
Offline
Зарегистрирован: 06.09.2013

и не выведет. %f в указателях формата работать не будет, особенности платформы. примите это как данность. если хочется вывести вещественное число, то выводите отдельно целую часть, затем запятую как символ, и затем дробную часть

Клапауций
Offline
Зарегистрирован: 10.02.2013

HWman пишет:

ап

я вообще не понял сути заморочек - делал бы так и не парился бы:

lcd.print("температура: "); lcd.print(h_temp);

 

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

Мне нужно засунуть в стринг число с точкой например 12.33 или 4.26.

Через %f это не получается.

 

com пишет:

и не выведет. %f в указателях формата работать не будет, особенности платформы. примите это как данность. если хочется вывести вещественное число, то выводите отдельно целую часть, затем запятую как символ, и затем дробную часть

хм...

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013
  Serial.begin(9600);
  char buf[10];
  char sbuf[50];
  float f = 10.25;
  int i = 256;
  char* s = "String";
  dtostrf(f,10,3,buf);
  sprintf_P(sbuf,PSTR("testing float %s and int %d plus %s"),buf,i,s);
  Serial.println(sbuf);

Я вижу доминацию гена лени над желанием и интелектом. За 15 минут решил ...

HWman
HWman аватар
Offline
Зарегистрирован: 26.02.2013

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

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

а в чем разница между sprintf_P и  sprintf?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Строка формата берётся из Флеша, а не из озу

leolem
Offline
Зарегистрирован: 22.06.2019
 
no matching function for call to 'LiquidCrystal_I2C::begin()'
Эта ошибка появляется появляется поятоянно. Подскажите что не правильно
 
 
 
 
kostyamat
Offline
Зарегистрирован: 16.11.2017

Пиши lcd.init();
Вместо lcd.begin();

А по поводу темы топика - я такие вещи вот так выводу

lcd.print(F("значение: ") + (String)intVal + " %");

leolem
Offline
Зарегистрирован: 22.06.2019
#include <LiquidCrystal_I2C.h> 
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);
byte smily[8] = {
  B00000,
  B00000,
  B01010,
  B00000,
  B00000,
  B10001,
  B01110,
};
void setup() 
{
  
}
 
void loop()
{
  lcd.init();   
  lcd.home();    
  lcd.backlight();
  lcd.createChar(0, smily); 
  lcd.write((byte)0);
}
Говорит ошибка, а бывает загружается но сам символ не выводит
 
kalapanga
Offline
Зарегистрирован: 23.10.2016

leolem пишет:

Говорит ошибка, а бывает загружается ...

Это уже чудеса какие-то. Кто говорит? Что за ошибка?

leolem пишет:

... но сам символ не выводит

А если перенести всё из loop в setup?

leolem
Offline
Зарегистрирован: 22.06.2019

leolem пишет:

#include <LiquidCrystal_I2C.h> 
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27,16,2);
byte smily[8] = {
  B00000,
  B00000,
  B01010,
  B00000,
  B00000,
  B10001,
  B01110,
};
void setup() 
{
  
}
 
void loop()
{
  lcd.init();   
  lcd.home();    
  lcd.backlight();
  lcd.createChar(0, smily); 
  lcd.write((byte)0);
}
загружается но сам символ не выводит
 

leolem
Offline
Зарегистрирован: 22.06.2019

неа смайла всё равно нет (я перенёс функции в setup)

b707
Offline
Зарегистрирован: 26.05.2017

а другие символы (стандартные) - выводит?

leolem
Offline
Зарегистрирован: 22.06.2019

yes

da

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

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

leolem
Offline
Зарегистрирован: 22.06.2019

пробовал неполучилось ( если что версия ардю 1.0.6)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ты б еще на 0.0.1b запустить пытался

leolem
Offline
Зарегистрирован: 22.06.2019

а чего не так?