Вопрос вывода символов на дисплей. Знатоки, подскажите !
- Войдите на сайт для отправки комментариев
Дисплей двухстрочный подключаю через I2C
Имею код (представлен ниже) просто беру инфу с сенсора и отображаю на дисплей.
если значения с сенсора двух значное, то выглядит это примерно так:
СО 41
СН4 16
если трех значное то единицы уползают вправо примерно так:
СО 418
СН4 16
а нужно мне сделать чтобы было так:
СО 418
СН4 16
а именно единицы должны стоять в одном столбце и если появляются сотни то они ставятся в столбец слева а не двигают единицы направо.
Знатоки, подскажите кто знает как это сделать?
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2);
#define sens A0
#define sensmq A1
void setup() {
Serial.begin(9600);
lcd.init();
lcd.init();
lcd.backlight();
pinMode(sens, INPUT);
pinMode(sensmq, INPUT);
}
void loop() {
int data = analogRead(sens);
int data1 = analogRead(sensmq);
Serial.print("CO ");
Serial.print(data);
lcd.setCursor(0,0);
lcd.print(F("CO "));
lcd.setCursor(4,0);
lcd.print(data);
Serial.print(" CH4 ");
Serial.println(data1);
lcd.setCursor(0,1);
lcd.print(F("CH4 "));
lcd.setCursor(4,1);
lcd.print(data1);
delay(1000);
}
http://arduino.ru/forum/programmirovanie/problema-s-vyvodom-znacheniya-p...
http://arduino.ru/forum/programmirovanie/problema-s-vyvodom-znacheniya-p...
Если надо попроще, в две строки, то можно вот так:
Запустите, посмотрите. szBuffer будет всегда содержать число n шириной в 4 символа, прижатое вправо. Это же то, что Вам нужно?
Если хотите слева дозаполнить незначащими нулями, просто вместо "%4d" напишите "%04d"
честно сказать я не понял как это должно работать
решил вопрос одной строчкой
я просто переношу курсор в другой столбей если он ставится трехзначным
lcd.setCursor(data < 100 ? 4 : 3, 0);
Ваш вариант возможно более универсален
Буду благодарен за разяснения по пердложенному код,
а именно первые две строчки ? что там за магия такая?
что куда возвращаем?
где посмотреть что значат эти операторы?
что значит
szBuffer[5];?
int
n = 432;?
Строка №1 - не берите в голову, она не относится к примеру. Она нужна для того, чтобы строку 8 можно было записать кратко, как она записана, а не в три оператора ( Serial.print("==="); Serial.print(szBuffer); Serial.println("===\n"); )
Строки 2-4 - не берите в голову, они стандартные - всегда такие.
Строка 5 - заводим буфер размером в 5 символов
Строка 6 - заводим целую переменную n и что-нибудь ей присваиваем
Строка 7 - преобразем n в символьный вид, при этом требуем, чтобы она занимала 4 символа и сели надо, дополнялась слева пробелами
Строка 8 - печатаем для проверки
Так как Вы сделали - хорошо при условии, что
1) там всегда три или четыре, и никогда не может быть, например, два
2) если сначала было 4-значное число, а потом стало 3-значное, Вы сместите курсор, но не сотрёте уже ненужную крайнюю левую цифру и она так там и останется.
у меня бывают и двух значные
Пробелы после СО стирают старые значения количество пробелов перекрывает область в котором выводятся значения
после чего я пишу на них новые
lcd.print("CO ");
lcd.setCursor(data < 100 ? 6 : 5, 0);
lcd.print(data);
Ну, вот я и говорю, что Вам проще сформировать печатаемую строку целиком одним вызовом sprintf а потом одним махом всё и вывести и не париться.
Вы не знаете что такое sprintf и как записывать формат строки? Так в сети полно примеров. Поищите по названию функции.
А то Вот Вы проверяеете на <100. А если она >999 - так может быть? если может, то у Вас опять проблема.
Согласен, пойду дальше учится)
Строка №1 - не берите в голову, она не относится к примеру. Она нужна для того, чтобы строку 8 можно было записать кратко, как она записана, а не в три оператора ( Serial.print("==="); Serial.print(szBuffer); Serial.println("===\n"); )
В данном случае я предпочитаю использовать макросы типа:
Это получается мы создаем функцию sp3, вызываем ее и даем ей значения?
Ну, если только для печати, то разницы-то никакой абсолютно, используйте на здоровье. Разница проявляется, если это надо использовать с разными переменными типа Stream (несколько сериалов, софтверный сериал и т.п.) - моё определение работает на всё сразу, а макросы надо писать отдельно для каждой потоковой переменной.
Только, надеюсь, Вы не так "в лоб" пишете, а то так, как у Вас написано могут возникнуть проблемы, например, if (a>b) sp3("a=", a, "\n"); сработает неадекватно.
Это получается мы создаем функцию sp3, вызываем ее и даем ей значения?
Мы не создаём функцию. При компиляции макрос sp3 просто заменяется на 3 отдельных Serial.print, и поэтому в приведённом примере с if нужно использовать фигурные скобки:
if (a>b) { sp3("a= ", a, " >b"); }
поэтому в приведённом примере с if нужно использовать фигурные скобки:
if (a>b) { sp3("a= ", a, " >b"); }
Да, лучше уж сразу в #define определить это блоком, обычно пишут
Приличный компилятор никаких глупых проверок не вставит, зато то, что это единое целое, поймёт.
первые две строчки ? что там за магия такая?
Кстати, вся магия подробно разбирается вот здесь.
Почему если переменная n - int все работает а если float то вот так?
мне просто очень нужно дробное выражение с 3 знаками после запятой
=== 0===
В 13 строке напишите
Только, сейчас мне не на чем проверить, написал по памяти. Если лажанулся, посмотрите сами, пожалуйста форматы функции printf
Но так "по памяти" то, что я написал должно означать, что будет число ширной пять символов с двумя знаками после точки (т.е. XX.YY - где XX - целая часть, а YY - дробная). Если для целой части надо 3 знака, а не 2, то укажите 6 после %
Да, кстати, если надо, чтобы по-прежнему было прижато вправо, а не влево, то перед шириной поля поставьте 0 (т.е. не "%5.2f", а "%05.2f".