Отображение информации на OLED 0.96''

Angie
Offline
Зарегистрирован: 17.05.2021

Доброго времени суток! Нужна консультация у знающих людей. Отец попросил сделать ему вольтметр в машину, который втыкается в прикурку. Решил сделать на Attiny85 + стандартный 0.96' OLED (128x64), управляемый по I2C. Вроде бы всё просто. Прошивка выглядит след. образом:

#include "ssd1306.h"

int u = 0; // переменная для числа пребразования 0-1023
float u_in = 0.0; // переменная для напряжения 0.0-5.0 

void setup() {
    pinMode(A3, INPUT);
    ssd1306_128x64_i2c_init();
    ssd1306_fillScreen(0x00);
    ssd1306_setFixedFont(comic_sans_font24x32_123);
}

void loop()
{
  u = analogRead(A3); // измерение 
  u_in = (u * 5.00) / 1023; // пересчет измерения в вольты. 
  ssd1306_printFixed(0, 0, u_in, STYLE_NORMAL);  //Вывод на дисплей
  delay(300);
}

При попытке скомпилировать программу, компилятор ругается, мол, не может преобразовать переменную u_in типа 'float' в переменную 'const char'. Сообщение ошибки следующее:

exit status 1
cannot convert 'float' to 'const char*' for argument '3' to 'uint8_t ssd1306_printFixed(uint8_t, uint8_t, const char*, EFontStyle)'
 
Если вместо переменной u_in запихать в функцию ssd1306_printFixed какое-либо число или слово, всё отображается на дисплее без проблем. 
Пробовал объявлять переменную u_in как 'char' вместо 'float', программа заливается в МК без проблем, но вместо измеренного напряжения u_in выводится искажённая информация вместо чего-то полезного. 
Быть может, кто-то сможет помочь в данном вопросе? Зараннее благодарен.
BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Так у тебя u и u_in разных типов, чего же ты хочешь? Сделай все переменные одного типа или явное приведение типа для u к float. Опять откуда то взято без головы?

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016
  u_in = (float)(u * 5.00) / 1023; // пересчет измерения в вольты. 

только видимо на коэффициент делителя надо еще умножить

Feofan
Offline
Зарегистрирован: 28.05.2017
Цитата:
cannot convert 'float' to 'const char*' for argument '3' to 'uint8_t ssd1306_printFixed(uint8_t, uint8_t, const char*, EFontStyle)'
BOOM, ua6em
Ругается-то на 17-ю строку, т.к. ssd1306_printFixed не интересует float 3-им параметром.
sadman41
Offline
Зарегистрирован: 19.10.2016
ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

А откуда библиотека?

ЗЫ если установлена через менеджер, то программа в 85 не влезет

Angie
Offline
Зарегистрирован: 17.05.2021

Ответ для BOOM
Нет, не "откуда то без головы". А из предыдущего своего проекта. Там я измерял выходную мощность ВЧ устройств в милливаттах, суть та же, только плюс еще несколько доп. математических операций, и информация выводилась на светодиодный индикатор на основе TM1637. Число с плавающей запятой прекрасно умножалось на целое число и проблем с этим не было. Я, конечно, когда вернусь с работы, проверю ваше предположение, но что-то мне подсказывает, что оно неверное.
И не нужно брызгать слюной, показывая своё превосходство в программировании над другими. Вы когда в банк звоните по какому-либо вопросу, вам тоже говорят "вы что там, совсем без головы?" Я вежливо попросил помощи. А вы совет даёте, словно деньги из своего кошелька дарите. С вас не убудет.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016
#include "ssd1306.h"

int u = 0; // переменная для числа пребразования 0-1023
float u_in = 0.0; // переменная для напряжения 0.0-5.0 
char voltages[5];

void setup() {
    pinMode(A3, INPUT);
    ssd1306_128x64_i2c_init();
    ssd1306_fillScreen(0x00);
    ssd1306_setFixedFont(comic_sans_font24x32_123);
}

void loop()
{
  u = analogRead(A3); // измерение 
  u_in = (u * 5.00) / 1023; // пересчет измерения в вольты. 
  dtostrf(u_in, 5, 2, voltages);
  ssd1306_printFixed(0, 0, voltages, STYLE_NORMAL);  //Вывод на дисплей
  delay(300);
}

Скетч использует 9638 байт памяти устройства.

 

PS я не настоящий сталевар ежели что )))

Angie
Offline
Зарегистрирован: 17.05.2021

Да, верно, он там был, только я его убрал из кода, ибо к сути дела это не относится :)

Angie
Offline
Зарегистрирован: 17.05.2021

ua6em пишет:

#include "ssd1306.h"

int u = 0; // переменная для числа пребразования 0-1023
float u_in = 0.0; // переменная для напряжения 0.0-5.0 
char voltages[5];

void setup() {
    pinMode(A3, INPUT);
    ssd1306_128x64_i2c_init();
    ssd1306_fillScreen(0x00);
    ssd1306_setFixedFont(comic_sans_font24x32_123);
}

void loop()
{
  u = analogRead(A3); // измерение 
  u_in = (u * 5.00) / 1023; // пересчет измерения в вольты. 
  dtostrf(u_in, 5, 2, voltages);
  ssd1306_printFixed(0, 0, voltages, STYLE_NORMAL);  //Вывод на дисплей
  delay(300);
}

Скетч использует 9638 байт (29%) памяти устройства.

 

PS я не настоящий сталевар ежели что )))

Спасибо большое, вы как про эту функцию написали, я начал её гуглить, и примерно так себе код и представил. После работы обязательно попробую, и отпишусь, получилось, или нет :)

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

Angie пишет:

 Спасибо большое, вы как про эту функцию написали, я начал её гуглить, и примерно так себе код и представил. После работы обязательно попробую, и отпишусь, получилось, или нет :)

Это не я, это Sadman41 подсказал, компилировал под nano так как аддона на 85 нет

Angie
Offline
Зарегистрирован: 17.05.2021

ua6em пишет:

А откуда библиотека?

ЗЫ если установлена через менеджер, то программа в 85 не влезет


Библиотека с Гитхаба, прочитал про неё в какой-то статье, сейчас и не вспомню, ибо на работе. Ставил вручную, не через менеджер, так что всё влазит в 85 тиньку.
Смотрел примеры использования этой библиотеки, там был скетч "часы", но там часы и минуты изначально обрабатываются как массив. Пробовал последовать их примеру, не вышло :(

sadman41
Offline
Зарегистрирован: 19.10.2016

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

Angie
Offline
Зарегистрирован: 17.05.2021

sadman41 пишет:

dtostrf()


Спасибо за подсказку :)

Angie
Offline
Зарегистрирован: 17.05.2021

sadman41 пишет:

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


Это для меня уже эльфийский пошёл :)
Пока остановлюсь на попытке использовать приведенную вами функцию.

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

строку 5 длину массива увеличьте до 7 (с запасом) )))

sadman41
Offline
Зарегистрирован: 19.10.2016

Это не эльфийский. Объявлен буфер в 5 байт. dtostrf() все 5 байт заполнит цифрами/пробелами/минусами, как ему задано в аргументе. В 6-й запишет '\0'. Только этот 6-й байт уже принадлежит какой-то другой переменной.

В лучшем случае, конечно, ничего не произойдет.

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

только думаю тип float и функция dtostrf() - абсолютно излишни для этого этого кода на тиньке. Куда проще было бы умножить формулу на 100 и считать в целых, а при выводе на экран просто нарисовать запятую перед последними двумя цифрами

Angie
Offline
Зарегистрирован: 17.05.2021

ua6em пишет:

строку 5 длину массива увеличьте до 7 (с запасом) )))


Я попробую и так и так :)

Angie
Offline
Зарегистрирован: 17.05.2021

sadman41 пишет:

Это не эльфийский. Объявлен буфер в 5 байт. dtostrf() все 5 байт заполнит цифрами/пробелами/минусами, как ему задано в аргументе. В 6-й запишет '\0'. Только этот 6-й байт уже принадлежит какой-то другой переменной.

В лучшем случае, конечно, ничего не произойдет.


Благодарю за разъяснение :)

Angie
Offline
Зарегистрирован: 17.05.2021

b707 пишет:

только думаю тип float и функция dtostrf() - абсолютно излишни для этого этого кода на тиньке. Куда проще было бы умножить формулу на 100 и считать в целых, а при выводе на экран просто нарисовать запятую перед последними двумя цифрами


Вчера, в аккурат после того, как я создал эту тему, мне пришла в голову именно эта идея, однако в этом автомобильное вольтметре для меня главное функционал и простота кода, а не занимаемся им память ) А мысль была расчитать напряжение, умножить на 100, разложить получившееся значение на разряды, записать их в массив с точкой, а потом вывести на экран. Но это получится много строк :)

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

Angie пишет:
ua6em пишет:

строку 5 длину массива увеличьте до 7 (с запасом) )))

Я попробую и так и так :)

 

диалог в гаражах:

Гуру: - только не забудь АКБ подключить, когда заводить будешь!

Чайник: - спасибо, я попробую и так и так...

Angie
Offline
Зарегистрирован: 17.05.2021

b707 пишет:

Angie пишет:
ua6em пишет:

строку 5 длину массива увеличьте до 7 (с запасом) )))

Я попробую и так и так :)

 

диалог в гаражах:

Гуру: - только не забудь АКБ подключить, когда заводить будешь!

Чайник: - спасибо, я попробую и так и так...

Каждый силён в определенных областях. Только кто-то останавливается на достигнутом, а кто-то старается расширять свои способности. Чем я, собственно, и занимаюсь, изучая микроконтроллеры и прочее :)

Angie
Offline
Зарегистрирован: 17.05.2021

sadman41 пишет:

dtostrf()

Благодарю от всей души, всё заработало :) Плюсик вам в карму!

Angie
Offline
Зарегистрирован: 17.05.2021

ua6em пишет:

строку 5 длину массива увеличьте до 7 (с запасом) )))

 

Большое спасибо, вставил строку из вашего скетча, и всё завертелось :) Плюсик в карму вам! Приятно, когда люди действительно хотят помочь, а ни брызгать слюной )