Ви не увійшли.
Всем привет. Возникла потребность измерять емкость элементов 18650.
Был куплен приборчик Liitokala Lii-500, но он слабоват. При установке сразу 4х элементов, ток заряда/разряда не превышает 500мА.
Для тех, кто не знает что это, небольшой гайд.
Прибор заряжает элемент, потом разряжает, измеряя при этом емкость на разряд, потом снова заряжает. На это все уходит часов 8-12, в зависимости от первоначального состояния элемента.
Захотелось ускорить этот процесс раза в два.
Купил
- четыре I2C 0,96" Oled дисплейчика
- модуль коммутатор I2C на TCA9548A для подключения 4х дисплеев с одним адресом к ардуинке
- ардуинку Pro Mini
- четыре модуля измерителя тока на ACS712
- четыре платки для павербанков (чтобы не изобретать алгоритм для зарядки/разрядки банок)
Теперь собственно проблема: как скоммутировать банку, чтобы не городить много элементов?
Можно взять допустим реле и решить проблему в лоб. Будет два положения - "заряд" или "разряд". Но я хочу третье положение "Стоп"
Для этого нужно два реле. Одно клацает на "заряд", другое на "разряд".
Тогда для четырех банок нужно 8 реле! Будет большая и шумная клацалка
Или использовать 8 мосфет ключей. Но тут проблема, они все коммутируют "минус". Плюс общий. Не пойму теперь как будет измеряться напряжение? Нужно ведь чтобы минус банки был все время соединет с ардуиной, иначе никакой analogRead() не измеряет напряжение на ней.
Короче башка уже устала, error...
Если что, вот схема подключения платы павербанка
и схема из даташита
Привет. Думаю плеер начнет играть как только напряжение на батарее станет таким, как нужно для его старта. И будет играть до тех пор пока напряжение не станет ниже этого значения. Какое номинальное значение напряжения для вашего mp3 плеера?
Если 5вольт, то лучше использовать что то типа такого:
Картинка не фонтан, но принцип понятен
У тачей обычно есть стандартная библиотека. Работает так: ловится прерывание по тачу. Если было нажатиие, то выдается координата нажатия. Что дальше делать с этой координатой - вам решать. Можно самому написать или использовать стандартные функции проверки - входит ли координата в зону реагирования. Не сушествует стандартных функций под вашу хотелку. Можно проверять как идет изменение координаты X и Y и от этого строить логику
Я как то заморочился подобной проблемой. Было около 50-ти строк по 20-24 символа в каждой
Решил проблему так. Первые 100 адресов EEPROM выделяю под хранение указателей, в которых храниться длина каждой строки.
В остальные записываю текст из массива посимвольно.
#include <EEPROM.h>
#define START_POINTER_ADDRESS 0 // Начальный адрес указателей, исправить при необходимости
#define START_STRING_ADDRESS 100 // Начальный адрес текста, исправить при необходимости
#define HOW_MANY_STRING_TO_SHOW 20 // Сколько строк показывать в Serial
int ptr_addr;
int strng_addr;
char* text_array [] = // Длина каждой строки не должна превышать 255 символов
{
"Текст кирилицей 0", //0
"Текст кирилицей 1", //1
"Текст кирилицей 2", //2
"Текст кирилицей 3", //3
"Текст кирилицей 4", //4
"Текст кирилицей 5", //5
"Текст кирилицей 6", //6
"Текст кирилицей 7", //7
"Текст кирилицей 8", //8
"Текст кирилицей 9", //9
"English Text 0", //10
"English Text 1", //11
"English Text 2", //12
"English Text 3", //13
"English Text 4", //14
"English Text 5", //15
"English Text 6", //16
"English Text 7", //17
"English Text 8", //18
"English Text 9", //19
};
void setup()
{
Serial.begin(9600);
while ( ! Serial )
{ // Ждать пока включится сериал, можно удалить
}
ptr_addr = START_POINTER_ADDRESS;
strng_addr = START_STRING_ADDRESS;
for (int n=ptr_addr; n<sizeof(text_array)/sizeof(text_array[0]); n++) // Выражение sizeof(text_array)/sizeof(text_array[0]
{ // определяет количество символов в строке массива строк
String text = text_array[n]; // Выдернуть из массива строк одну строчку
EEPROM.put(n, text.length()); // Записать в EEPROM по адресу n длину строки
for (int i = 0; i < text.length(); i++)
{
EEPROM.write(strng_addr + i, text[i]); // Записать строчку в EEPROM по одному символу, начиная с начального адреса
}
strng_addr += text.length()+1; // Увеличить начальный адрес на длину предыдущей строки +1
} // +1 нужен, чтобы не затереть последний символ предыдущей строки
strng_addr = START_STRING_ADDRESS;
Serial.println("poiter---length---Text message---"); // Вывод в сериал того, что получилось
for (int n=0; n<HOW_MANY_STRING_TO_SHOW; n++) // Перебрать указатели
{
Serial.print(n); // Вывод адрес указателя
Serial.print("\t");
Serial.print(strng_addr+EEPROM.read(n)); // Адрес начала строки = адрес старта + длина всех предыдущих строк
Serial.print("\t");
for (int i=0; i<EEPROM.read(n); i++) // Вывод символов (количество читается из ячейки n)
{
char text[1]; // Объявить массив char с одним символом
Serial.print(EEPROM.get(i+strng_addr,text)); // Вывести один символ
}
Serial.println("");
strng_addr += (1+EEPROM.read(n)); // Начало следующей строки = длина предыдущей строки +1
} // +1 по той же причине, что и выше
}
void loop()
{
}
Вот видос того, что получается
Вариант 2.
Для питания Arduino используйте отдельный блок питания или DC-DC преобразователь с гальванической развязкой, например вот такой B0505S-1W
http://www.kosmodrom.com.ua/pic/SIP4(stand).jpg
Отличная идея! Спасибо!
Боюсь вас огорчить, но по моему мнению за такое никто не заплатит.
Почему вы не хотите использовать WEB-интерфейс. Например ESP32 + WiFi.
Я разрабатываю не массовое устройство. Так что да, заплатят только те, кому это очень нужно. Я промониторил рынок, есть только два похожих прибора в ценовой категории до 250$. Мой девайс обойдется дешевле, при почти тех же возможностях.
Веб интерфейс мне не нужен, это настольный прибор. Допустим как осцилограф. Хотя наличие вебморды было бы интересным решением, но только в связке с соответтствующим ПО для смартфона и возможностью мониторинга удаленно, а не только в домашней сети. За такую опцию точно никто не заплатит))
Рассматриваю кстати использование вместо ESP32 вместо Arduino. Будет и быстрее и даже немного дешевле.
Попутно столкнулся с другими проблемами. Не все комплектующие работают так как задумывалось, приходится импровизировать на ходу. Корпусно-крепежные проблемы.
Не могу придумать как решить на первый взгляд простую проблему. Есть китайский измеритель тока, напряжения, мощности, вот такой.
Появилось желание добавить его в проект.
В готовом проекте показания напряжения были правильные, а вот показания тока были занижены раза в три. Я уж думал обижаться на китайцев и попутно начал искать другие подобные измерители, и обнаружил, что проходящий ток измеряется по минусовой шине. То есть плюс у них общий, и шунт стоит по минусу.
Если не использовать шину I2C, то показания тока будут правильные.
Теперь собственно вопрос: как подключить GND, SDA, SDL так, чтобы и шина работала и амперметр правильно мерял?
Забыл сказать. Плата не питается от USB, у нее отдельное питание. По USB только передается инфа в Serial. Так что, если даже компу сказать, чтобы он не отрубал питание с USB, не факт, что плата не зависнет.
И потом, расчитывая на все случаи жизни, лучше заранее предусмотреть защиту от такого поведения.
Есть еще одна проблема. Если плата подключена к компу по USB и комп выключить, то плата виснет. Помогает только передергивание кабеля. Не критично, но раздражает. Думаю как то сторожевого пса приделать, чтоб следил за Serial. Но пока не курил эту тему
Подскажу:
void bar(void) { // ... } void (*foo)[n](void) = {bar, ...}; for (int i = 0; i < n; i++) foo[i]();
Ваша конструкция не заработала, не знаю почему. Я не силен тонкостях программирования. Подсмотрел здесь
решение, не все понял, но результат устраивает. То, чего я добивался, получилось. Вот результат:
volatile boolean intFlag = false; // Флаг прерывания
int key = false; // Флаг нажатия кнопки
int newscreen = false; // Флаг нового экрана
pinMode(7, INPUT_PULLUP); // Кнопка на седьмой пин где будет ловиться прерывание №4
char *text1[]={ // Массив текстовых сообщений 1
"Сообщение 0:",
....
"Сообщение 9:",
};
void function_0 (void); // Объявление функций, сами функции расписаны в конце
....
void function_9 (void);
void (*a0)(void) = &function_0; // Создание указателей на адреса функций,
.... // которые получают данные с устройства
void (*a9)(void) = &function_9;
typedef void (* FuncPtr1) (); // Создание типа с названием FuncPtr1
// который представляет собой указатель на функцию
FuncPtr1 param1[10] = {a0, .... , a9}; // Складывание указателей в массив
// То же самое для второго экрана
char *text1[]={ // Массив текстовых сообщений 2
"Сообщение 10:",
....
"Сообщение 19:",
};
void function_10 (void); // Объявление функций, сами функции расписаны ниже
....
void function_19 (void);
void (*b0)(void) = &function_10; // Создание указателей на адреса функций
.... // которые получают данные с устройства
void (*b9)(void) = &function_19;
typedef void (* FuncPtr1) (); // Создание типа с названием FuncPtr2
// который представляет собой указатель на функцию
FuncPtr1 param2[10] = {b0, .... , b9}; // Складывание указателей в массив
void setup()
{
// Тут всякие нужные действия
}
void loop()
{
switch (intFlag) { // Обработчик нажатия кнопки
case true:
intFlag = false; // Сброс флага прерывания
key = !key; // Нажатие на кнопку зафиксировано
newscreen = !newscreen; // Новый экран - Да
LCD_Clear(0x0000); // Очистка всего экрана
break;
}
switch (key) { // Реакция на кнопку выбора экрана
case false: // Первый экран
switch (newscreen) { // Новый экран?
case false: // Да, новый екран
for (int i = 0; i < 10; i++){
Paint_DrawString_EN(x, y(i), text1[i], шрифт, фон, цвет); // Выводить текст 1 с просчетом координаты Y
switch (device_ready()) { // Подключено ли устройство:
case false: // Нет - ничего не выводить
break;
default: // Да - выводить данные 1
param1[i]();
}
}
newscreen = !newscreen; // Сбрасываем флаг "Новый экран"
break;
case true: // Экран уже был, выводить только данные
for (int i = 0; i < 10; i++){
switch (device_ready()) { // Подключено ли устройство:
case false: // Нет - затереть пробелами предыдущие значения
Paint_DrawString_EN(x, y(i), " ", шрифт, фон, цвет); // с просчетом координаты Y
break;
default: // Да - выводить данные 1
param1[i]();
}
}
break;
}
attachInterrupt(4, buttonTick, LOW); // Реакция на кнопку разрешена
break;
case true: // Второй экран
switch (newscreen) { // Новый экран?
case false: // Да, новый экран
for (int i = 0; i < 10; i++){
Paint_DrawString_EN(x, y(i), text2[i], шрифт, фон, цвет); // Выводить текст 2
(device_ready()) { // Подключено ли устройство:
case false: // Нет - ничего не выводить
break;
default: // Да - выводить данные 2
param2[i]();
}
}
newscreen = !newscreen; // Сбрасываем флаг "Новый экран"
break;
case true: // Экран уже был, выводить только данные
for (int i = 0; i < 10; i++){
switch (device_ready()) { // Подключено ли устройство:
case false: // Нет - затереть пробелами предыдущие значения
Paint_DrawString_EN(x, y(i), " ", шрифт, фон, цвет); // с просчетом координаты Y
break;
default: // Да - выводить данные 2
param2[i]();
}
}
break;
}
attachInterrupt(4, buttonTick, LOW); // Реакция на кнопку разрешена
break;
}
// Далее вывод в сериал
}
// Куча полезных функций
void function_0(){} // Функции объявленные в самом начале
....
void function_19(){}
void buttonTick() { // Хитрая реакция на прерывание, подсмотрел на одном форуме
detachInterrupt(digitalPinToInterrupt(7)); // Запрещаем прерывания по пину 7
intFlag = true; // Установка флага прерывания
}
Всем спасибо за идеи, конструктивная критика и новые идеи приветствуются
но надо задачу понимать.
Задача почти допилена, можно в принципе и так бросить, но я пока жду комплектуху из Китая, поэтому допиливаю по мере просветления мозгов.
По I2C подключен некий прибор, который может выдавать тучу параметров. Не хочу трепаться что именно, вдруг выгорит и стану миллионером
По SPI подключен IPS TFT дисплей 320х240.
Стандартная библиотека дисплея умеет выводить 'символы' по коду, "строку из букв", числа ну и рисовать всякие отрезки треугольники и прочие прямоугольники. Я пробовал другие библиотеки под чип ST7789, они не завелись. (почему то не работала треть экрана как я его не вращал, хотя в библиотеках была поддержка дисплея 320х240). Это сейчас не важно, использую, то, что работает.
Так вот. Заполнение 11 строк описательным текстом 16м шрифтом занимает 10 секунд, потом отображаются получаемые данные. Данные бывают либо текст, либо цифры. Это еще 2 секунды.
По нажатию кнопки дисплей стирается и отображаются еще 12 строк с тектом и параметрами.
Были некоторые трудности с приведением этого месива в красивый вид, чтобы не моргало лишний раз, об этом я писал в другом посте про оптимизацию вывода на дисплей. Сейчас все красиво и волшебно, но захотелось уплотнить код (сейчас используется 87% ROM и 55% RAM) так как в будущем хочу добавить пару хотелок, или не хочу. Пока не уверен.
После дисплея инфа выводится в сериал. (это я еще допиливаю, раскрашиваю в цвет и делаю таблицу).
Так вот, по поводу оптимизации. Хочу избавится от бесконечных if и goto. Не знаю почему, но опытных программеров они раздражают. Начал делать. И тут пришла идея вообще нафик все переделать. Чтобы было строка_описательного_текста_1 + данные_1, строка_описательного_текста_2 + данные_2 и так далее. Покурил указатели на функции, вроде бы то, что нужно. Ведь все уже набрано, осталось грубо говоря пронумеровать куски и выдавать их потом в любой последовательности.
Пока не могу вкурить как выдать на дисплей String
String formatted_date = "";
formatted_date += year;
formatted_date += "-";
formatted_date += month;
formatted_date += "-";
formatted_date += day;
Serial.println(formatted_date);
Вот так выдать в сериал можно, на дисплей нет
Kaka пише:Бред какой-то.
Согласен
Kaka предложил толковую идею, про которую я не знал, а вы могли бы предложить свою или воздержаться.
Покурил я printf - интересная вещица, ща сбацаю все хотелки
А я догадываюсь. Человек GUI валяет.
А учить мову не желает.
Правильно, ваяю GUI
Это мой первый проект и сразу такой масштабный. Второй месяц ковыряю, почти идеально уже, но нет предела совершенству
Желаю, поэтому и консультируюсь. В интернетах нарыл, что, то, что я хочу сделать называется указатель на функцию. Пересмотрел видосы и гайды, есть представление, но нет пока четкого понимания. Много сложной воды и мало примеров.
Однажды я услышал фразу: не нужно зубрить матчасть, нужно сразу брать и пробовать. На удачах и ошибках быстрее научишься.
За подсказку спасибо, примерно это я и имел ввиду.
Вообще логика такая:
Отображается один раз 11 строк текста и затем и соответственно 11 строк данных по циклу
Проверяется кнопка, если было нажатие, то следующие 12 строк текста один раз и 12 строк данных по циклу.
Ваш подход мне нравится, надо попробовать. А как будет правильнее, объявить все эти функции в setup() или можно в loop()?
Сейчас работает так.
Показывается текст один раз(который хочу переделать в текстовый функции 100....110)
Paint_DrawString_EN(2, 70, "Ток (мА):", &Font16, BLACK, WHITE);
Paint_DrawString_EN(2, 90, "Напряжение (мВ):", &Font16, BLACK, WHITE);
Потом идет отображение данных по циклу (хочу переделать в функции 200...210:
if (fetchWord(CURRENT) < 0) { // CURRENT
Paint_DrawString_EN(254, 70, "-", &Font16, BLACK, RED);
Paint_ClearWindows((265 + 11*digit_counter(abs (fetchWord(CURRENT)))), 70, 309, 87, BLACK);
Paint_DrawNum(265, 70, abs (fetchWord(CURRENT)), &Font16, BLACK, RED);
}
if (fetchWord(CURRENT) > 0) {
Paint_ClearWindows(254, 70, 265, 87, BLACK);
Paint_ClearWindows((265 + 11*digit_counter(fetchWord(CURRENT))), 70, 309, 87, BLACK);
Paint_DrawNum(265, 70, fetchWord(CURRENT) , &Font16, BLACK, GREEN);
}
if (fetchWord(CURRENT) == 0) {
Paint_ClearWindows(254, 70, 265, 87, BLACK);
Paint_ClearWindows((265 + 11*digit_counter(fetchWord(CURRENT))), 70, 309, 87, BLACK);
Paint_DrawString_EN(265, 70, "0", &Font16, BLACK, GREEN);
}
Paint_ClearWindows((265 + 11*digit_counter(fetchWord(VOLTAGE))), 90, 320, 107, BLACK); // VOLTAGE
Paint_DrawNum(265, 90, fetchWord(VOLTAGE), &Font16, BLACK, GREEN);
Возможно кто то решит, что здесь будет готовый код. Это не так. Я лишь хочу поделится своими находками в плане оптимизации вывода на не слишком шустрый дисплей.
Пример: вывод величины тока или напряжения на дисплей.
Есть несколько проблем:
1. величина может принимать отрицательные значения
2. количество знаков в значении может меняться как в большую так и в меньшую сторону. Из за чего отображаемое значение может быть некорректным
1я проблема решается использованием функции abs и рисованием или удалением в нужное время текстом знака минус"-".
2я проблема имеет несколько решений:
- перед каждым циклом отображения значения стирать строку пробелами. Не слишком изящное решение, так как дополнительный вывод пробелов отжирает оперативку на количество этих самых пробелов (не критично, если не часто и можно например выводить один пробел в цикле for), но работает медленно и видно как строка стирается и потом заполняется данными.
- перед каждым циклом отображения рисовать прямоугольник с цветом фона, работает более красиво, но все равно медленно, если нужно стереть много.
- самый удачный на мой взгляд вариант, это перед выводом на дисплей посчитать количество символов в значении и стирать любым из первых двух вариантов только лишние символы. Например величина тока была 1999 мА, а стала 888мА, то стереть нужно только место под четвертую цифру.
Нарыл 4 алгоритма как посчитать количество знаков числе. Как говорит автор - метод "сравнения" самый быстрый, а как по мне, так и самый простой для понимания, несмотря на длину кода.
Если у кого то есть еще варианты по оптимизации отображения, прошу поделится
Возможно нубский вопрос, но спрошу.
Есть ли возможность и будет ли работать следующая конструкция?
Функция100();
Функция101();
....
Функция110();
Функция200();
Функция201();
...
Функция210();
loop {
for(i = 0; i < 10; i++){
for(j = 0; j < 10; j++){
Функция(100+i)
Функция(200+j)
}
}
}
Функция с 100 по 110 выводит текст, а с 200 по 210 значение (или наоборот, пока не суть, главное понять возможно ли так)
Понимаю, что функция описана названием и просто так передать номер функции нельзя, но каким то другим способом можно, но как?
Реальное применение:
Допустим нужно вывести на дисплей несколько параметров:
"Напряжение" - текст
"Ток" - текст
"Мощность" - текст
"Что угодно еще" - текст
и затем
величина напряжения
величина тока
величина мощности
величина чего угодно
Текст выводится один раз, а величина потом может изменяться (но это уже другая тема, так что пока опустим).
Сейчас у меня есть готовая конструкция, которая выводит в такой последовательности, но дисплей долго заполняется сперва текстом потом данными, хочу сделать чтобы выводилось в другой последовательности:
"Напряжение" - текст, величина напряжения
"Ток" - текст, величина тока
"Мощность" - текст, величина мощности
"Что угодно еще" - текст, величина чего угодно
Появилась идея описать все функциями и вызывать их через for по номерам
Вот например на дисплее написано Waveshare
И вот их сайт https://www.waveshare.com/
Или нужно хотя бы представлять на каком чипе сделан дисплей, тогда можно поискать библиотеки под этот чип
А производитель кто? Обычно на сайте производителя есть все библиотеки
luminofor пише:... Всем сочувствующим спасибо
А про собаку? "The quick brown fox jumps over the lazy dog".
Нее.., этож у них ТАМ про собак, а у нас ТУТ про булки
ЕСС, товарищи, ЕСС!!!
Не скажу что все тупо просто, но есть не сложное решение!
Кодировкой по умолчанию, используемой компилятором Arduino IDE является UTF-8. А в ней килиллица кодируется двухбайтным числом. Поэтому-то при выводе строки на кириллице отображаются два символа и не те, что надо.
Есть костыль. Используем внешний редактор. Например Notepad++
В настройках IDE ставим галочку "Использовать внешний редактор"
Открываем скетч и в IDE и в Notepad++, в Notepad++ идем во вкладку "Кодировки"-"Кодировки"-"Windows-1251"
Пишем текст, который нужно вывести на дисплей кириллицей, сохраняем скетч, переходим в IDE, заливаем. Профит!
Кстати, в посте №2 я ошибся. Между последним читаемым символом "~" в стандартной таблице ASCII и первым символом "А" в кириллице (в кодировке Windows-1251) 66 символов. Поэтому в таблицу шрифта нужно добавить 66 пустых символов (допустим пробелов)
Кажись нарыл кое что полезное.
В файле GUI_Paint.h есть например строка
void Paint_DrawChar(UWORD Xstart, UWORD Ystart, const char Acsii_Char, sFONT* Font, UWORD Color_Background, UWORD Color_Foreground);
Это функция, выводящая отдельный символ из массива символов.
В ней указан тип константы char, которая может принимать значение от -127 до 127, то есть функция не может обратиться по адресу больше чем 127 (если от нуля считать)
Если я в этом файле меняю все типы константы на unsigned char (от 0 до 255) и потом во всех связанных с этим местах в файле GUI_Paint.cpp, то я могу по номеру символа в массиве вывести символ кириллицы.
Как бы УРА!
Но пока не совсем.
По одному символу выводить текст накладно, есть для этого другая функция Paint_DrawString_EN. Она должна выводить набор символов, используя Paint_DrawChar. Но она выводит не правильно. Вместь любых букв, я получаю "с" + пробел или "т" + пробел.
Пока не пойму где еще копнуть.
Но прогресс есть, это радует.
Примерно разобрался. Могу сделать любой латинский шрифт и вывести на дисплей. Нужно сгенерировать его программой, заменить код в библиотечном шрифте на сгенерированный, поправить в конце файла ширину и высоту в битах. Ну или создать с нуля файл со шрифтом и описать его в файле fonts.h
А вот с кириллицей проблема. Долго не мог понять почему. Дело в длине слова, описывающего массив с символами. Оно занимает 128 байт. (0-127)
Если я, в конце латинских букв присоединяю кириллицу, то вызывая например символ с номером 127, я получу букву "А". А если 128, то уже абракадабру.
То есть открывается два варианта.
1. Искать где в библиотеке можно расширить диапазон массива. Но тут есть пара проблем. Массив идет сплошной. А между последним символом таблицы ASCII и "А" на кириллице есть 40 других символов, которые тоже нужно забить в массив (хоть пустые), чтобы "А" попала на свое законное 160-е место и комп нормально все понимал при компиляции.
2. Просто тупо исправить латиницу на кирилицу, в тексте программы писать латиницей, а вывод будет кириллицей.
Есть еще один вариант, но для программеров - написать свою библиотеку вывода символов на дисплей
Всем привет! Заранее прошу прощения за возможно нубский и сто раз обмусоленный вопрос. Поиск по форуму ощутимых результатов не принес.
Есть дисплей. Если покопаться в его официальной библиотеке, то легко увидеть несколько файлов, содержащих шрифты. Содержимое, скажем латинской буквы "А" размером 16 пикселей выглядит так
// @1056 'A' (11 pixels wide)
0x00, 0x00, //
0x00, 0x00, //
0x3F, 0x00, // ######
0x0F, 0x00, // ####
0x09, 0x00, // # #
0x19, 0x80, // ## ##
0x19, 0x80, // ## ##
0x1F, 0x80, // ######
0x30, 0xC0, // ## ##
0x30, 0xC0, // ## ##
0x79, 0xE0, // #### ####
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
На просторах интернета нашлась программа The Dot Factory. В ней очень много настроек и она умеет из любого встроенного в винду шрифта сделать файл, похожий с оригинальным файлом со шрифтом от дисплея. Похожий, но видимо не совсем. При попытке добавить файл в проект, я получаю ошибку. Если просто тупо заменить в оригинальном файле латинскую букву "A" на "Ф", то можно добиться вывода именно "Ф".
// @4408 'Ф' (16 pixels wide)
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
0x07, 0xC0, // #####
0x01, 0x00, // #
0x0F, 0xE0, // #######
0x11, 0x10, // # # #
0x21, 0x08, // # # #
0x21, 0x08, // # # #
0x21, 0x08, // # # #
0x11, 0x10, // # # #
0x0F, 0xE0, // #######
0x01, 0x00, // #
0x07, 0xC0, // #####
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
0x00, 0x00, //
Но это как бы не правильно, долго и неудобно
Кто нибудь имеет опыт с решением такого вопроса?