Самодельные шрифты для графических LCD дисплеев

fessefrem
Offline
Зарегистрирован: 08.04.2017

Друзья, написал шрифт, а он у меня в зеркальном виде на дисплее... Подскажите, что сделать, чтобы нормально выводить инфу на дисплей? Библиотеку поменять???

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А шрифт зеркально повернуть? Что-то с религией?

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

ЕвгенийП пишет:

А шрифт зеркально повернуть? Что-то с религией?

Ну вот я бы скорее добавил в библиотеку функцию зеркального вывода букв. Думаю, что это в разы проще (строчек 10 кода. вряд ли больше) - чем "обернуть" 100-200 символов, закодированных битовыми массивами...

arduinec
Offline
Зарегистрирован: 01.09.2015

Недавно на форуме кто-то обращался с вопросом: зеркально повернуть изображение на TFT-дисплее. Советов ему надавали, но похоже внести изменения в библиотеку у него не получилось.

Правильнее же один раз перекодировать шрифт, чем много раз редактировать разные библиотеки под него.

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

arduinec пишет:

Правильнее же один раз перекодировать шрифт, чем много раз редактировать разные библиотеки под него.

Правильнее - соглашусь... но другие пути могут быть проще и быстрее :)

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

. Думаю, что это в разы проще (строчек 10 кода. вряд ли больше) - чем "обернуть" 100-200 символов, закодированных битовыми массивами...

Да, ладно. Программка в те же 10 строчек первернёт хоть 200 симвлов, хоть 2000. Зато в ран-тайме никаких хатрат на это не будет. 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

ЕвгенийП пишет:

b707 пишет:

. Думаю, что это в разы проще (строчек 10 кода. вряд ли больше) - чем "обернуть" 100-200 символов, закодированных битовыми массивами...

Да, ладно. Программка в те же 10 строчек первернёт хоть 200 симвлов, хоть 2000. Зато в ран-тайме никаких хатрат на это не будет. 

да копеечные там затраты в рантайме...вот например менял библиотеку - шрифт под китайский дисплей - разницы в скорости вывода не заметил

		src_b = pgm_read_byte(&BasicFont[C-32][i]);
					b_out = (src_b & 0x01) << 1;
					b_tmp = (src_b & 0x02) << 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 4;
					b_out |= b_tmp;

 

Logik
Offline
Зарегистрирован: 05.08.2014

Нифига они не копеечные! Такой код затормозит вывод текста на экран в разы. А учитывая что скорость работы с экраном у ардуины и так не блеск то результат тоскливо медленый.  Но можна по хитрому сделать. Пишем вспомогательный скетч, который из зеркального фонта вытягивает байты, поворачивает их и выводит в сириал. При этом форматирует в вид, пригодный для записи в исходник, с запятыми между числами и переводами строки как нравится. Остается вывод скрипта из окна монитора скопипастить себе в исходник.

  А воще, знание-сила! Открываем даташит на свой экран и видим там чтото такое

 

 

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

Ворота
Ворота аватар
Offline
Зарегистрирован: 10.01.2016

Ну, ты садист, однако! "Всего подправить!" Ишь чего удумал! Нет шоб готовый код подправки дать! Щас ТС тебе всё объяснит!

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Logik, ну во первых я не претендую на истину в последней инстанции - описал то что я сам видел, во вторых мой кусок кода для oled 128x32 на ssd1306 и ваша фраза что будет тормозить и даташит ну вообще ни к месту.
И все зависит от алгоритма - я думаю можно написать чтоб в рантайме не тормозил

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

andycat пишет:
думаю можно написать чтоб в рантайме не тормозил
Ну, ведь так не бывает. Хоть на такт, а тормозить будет.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

И кстати да - вы прежде чем спорить - поняли что мой кусок кода с символом делает ? :)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Будет тормозить но на доли секунд

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Разбирать готовую конструкцию лень) завтра протестирую на голом МК разницу

Logik
Offline
Зарегистрирован: 05.08.2014

andycat пишет:
Logik, ну во первых я не претендую на истину в последней инстанции - описал то что я сам видел, во вторых мой кусок кода для oled 128x32 на ssd1306 и ваша фраза что будет тормозить и даташит ну вообще ни к месту.

Я оч. рад что у Вас "oled 128x32 на ssd1306", только в теме четко сказано "для графических LCD дисплеев" . Так что ни к месту какраз ваш oled. Хотя впрочем какая разница, если у ssd1306 есть Set COM Output Scan Direction (C0h/C8h) ;)

 

andycat пишет:
И все зависит от алгоритма - я думаю можно написать чтоб в рантайме не тормозил

Если быдумали - то понимали что чтение из PROGMEM - 3 такта плюс работа с указателем 5-7. А ваш перевертос в полсотни не факт что влезет. И таких действий на каждую выводимую букву прийдется от 5  и выше. Считайте сами, заодно узнаете во что обернется простенькое "<< 4". 

Кстати вспомнилось. Для масштабирования шрифта в 2 и 4 раза на том же ssd1306 чтоб не тормозило делел так

byte FontSize2Convert[16]={0,0x03,0x0c,0x0f,0x30,0x33,0x3c,0x3f,0xc0,0xc3,0xcc,0xcf,0xf0,0xf3,0xfc,0xff};
byte FontSize4Convert[4]={0,0x0f,0xf0,0xff};

......
    case FONT_SIZE_2:
        for (uint8_t i =0; i<5; addr++,i++ ) 
        {
            r=pgm_read_byte(addr);
.................
			 writeByte(FontSize2Convert[r&0x0f]);
......
case FONT_SIZE_3:
        for (uint8_t i =0; i<5; addr++,i++ ) 
        {
            r=pgm_read_byte(addr);
............
                    writeByte(FontSize4Convert[r&0x03]);

Таким путем можна и отзеркалить побыстрому. Можна, но не нужно, вышеизложеное эффективней полюбе.

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

Logik пишет:

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

не знаю, что в этом "хитрого" - собственно, ЕвгенийП сразу именно это и предлагал. Эта идея мне понятна  Но только лень писать отдельную программу :) (И непонятно, зачем это делать в виде скетча на ардуине - у нас же комп есть).

Что касается перекодировки "на лету" - в моем случае почти никаких накладных расходов не будет. В любой библиотеке работы с экраном всегда есть низкоуровневая функция вывода на экран отдельного символа, которая засвечивает отдельные пиксели в соответсвии с битами шрифтового массива. Функция обычно несложная, строк на 5-10 - и для зеркального вывода все что с ней нужно сделать - это поменять порядок выборки битов или байтов в матрице шрифта. Измененная функция в силу "зеркальности" будет иметь ровно столько же операторов и выполнятся строго за то же кол-во тактов, как оригинал.

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

Logik
Offline
Зарегистрирован: 05.08.2014

b707 пишет:

не знаю, что в этом "хитрого" - собственно, ..., зачем это делать в виде скетча на ардуине - у нас же комп есть).

В том и и хитрость что это можно сделать скетчем без дополнительных програмных сред,  к тому же только усложняющих задачу. Далеко не у всех MS VS под рукой. Я такое только на работе держу.

b707 пишет:

 

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

Дак битов или байтов? определетес таки. Для байтов все просто, а для битов - нет, для этого andycat и писал код.

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

Logik пишет:

Дак битов или байтов? определетес таки. Для байтов все просто, а для битов - нет, для этого andycat и писал код.

ну смотря в каком направлении зеркалить... Если придется обращать порядок битов в байте - да, не повезло.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Во вы флуда развели :) не спорьте - все зависит от задачи и реализации и кстати - при чем здесь progmem? Эта строчка останется в любом случае и в преобразовании шрифта не участвует

Logik
Offline
Зарегистрирован: 05.08.2014

b707 пишет:

Logik пишет:

Дак битов или байтов? определетес таки. Для байтов все просто, а для битов - нет, для этого andycat и писал код.

ну смотря в каком направлении зеркалить... Если придется обращать порядок битов в байте - да, не повезло.

Тоже не однозначно. По рисунку из #7 видно что направление перерисовки можна менять не только лево-право, но и вертикал-горизонталь. При владении аппаратной частю не повезти не может ;) У sd1306 аналогично, для  andycat замечу.

Logik
Offline
Зарегистрирован: 05.08.2014

andycat пишет:
Во вы флуда развели :) не спорьте - все зависит от задачи и реализации и кстати - при чем здесь progmem? Эта строчка останется в любом случае и в преобразовании шрифта не участвует

Где флуд? Здесь все по делу пока. progmem разумеется останется. Вы похоже слабо представляете как длительност выполнения тех или иных действий оценивается. Ну  да ладно, переходите к экспериментальной части. Скролинг текста например.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

итак выкладываю результаты тестирования, отдельно сообщение для Logik  - убрав лишнее чтение из progmem - я получил ускоренее не более 3 % - так что не надо тут высказывать что я представляю как работает и что не представляю :) - будьте практиком а не теоретиком.

забегая вперед пришел к выводу (вполне ожидаемому) что битовые операции МК очень мало влияют на общий результат, в моем конкретном случае самое большое время выполнения уходит на передачу информации на сам дисплей по IIC

далее тексты процедуры со временем выполнения, замерял просто секундомером, поэтому точность конечно +- секунда

сам тестовый скетч - вывод 100 символов в цикле по 10

#include <TinyOzOLED.h>

void setup () {
  OzOled.init();  //инициализация дисплей
  OzOled.setNormalDisplay();      //нормальный режим
  OzOled.setPageMode();           //адресация страничная
  OzOled.sendCommand(0xA1);       //выбор ориентации сверху - вниз
  OzOled.sendCommand(0xC8);       //слева - направо
}

void loop () {
  OzOled.clearDisplay();          //очистка дисплея
  for (byte i = 0; i < 10; ++i) {
    OzOled.printBigNumber("01234", 0, 0);
    OzOled.printBigNumber("56789", 0, 0);
  }
  OzOled.clearDisplay();          //очистка дисплея
  //OzOled.setPowerOff();
  delay(5000);
}

оригинальная процедура вывода из библиотеки TinyOzOLED - 14.81 секунда



void OzOLED::printBigNumber(const char *number, byte X, byte Y, byte numChar){
// big number pixels: 24 x 32

 // Y - page
	byte column = 0;
	byte count = 0;

	while(number[count] && count<numChar){
	
	
		setCursorXY(X, Y);
		
		for(byte i=0; i<96; i++) {
		
			// if character is not "0-9" or ':'
			if(number[count] < 46 || number[count] > 58)	
				sendData(0);
			else 				
				sendData(pgm_read_byte(&bigNumbers[number[count]-46][i]));
			
			
			if(column >= 23){
				column = 0;
				setCursorXY(X, ++Y);
			}
			else				
				column++;

		}
		
		count++;
		
		X = X + 3;
		Y = Y - 4;
		
	
	}

	
	
}

исправленная процедура для корректного вывода цифр - добавлен лишний цикл - время ожидаемо увеличилось в 2 раза = 27,85 секунд



void OzOLED::printBigNumber(const char *number, byte X, byte Y, byte numChar){
// big number pixels: 24 x 32
 // Y - page
	byte column = 0;
	byte count = 0;
	while(number[count] && count<numChar){
		setCursorXY(X, Y);
		// update for China OLED display 128*32
		byte src_b, b_out, b_tmp;
		for (byte i=0; i<4; ++i) {
			byte j;
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+j]); 
					b_out = (src_b & 0x01) << 1;
					b_tmp = (src_b & 0x02) << 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 4;
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+j]); 
					b_out = (src_b & 0x10) >> 3;
					b_tmp = (src_b & 0x20) >> 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80);
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
		}
		count++;
		X = X + 3;
		Y = Y - 8;
	}
}

убрал чтение лишнее из progmem, сделал через промежуочный буфер - время практически не поменялось = 27 секунд


void OzOLED::printBigNumber(const char *number, byte X, byte Y, byte numChar){
// big number pixels: 24 x 32
 // Y - page
	byte column = 0;
	byte count = 0;
	byte onech[96];
	while(number[count] && count<numChar){
		setCursorXY(X, Y);
		// update for China OLED display 128*32
		byte src_b, b_out, b_tmp;
		for (byte i=0; i<4; ++i) {
			byte j;
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+j]);
					onech[(i*24)+j] = src_b;
					b_out = (src_b & 0x01) << 1;
					b_tmp = (src_b & 0x02) << 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 4;
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					//src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+j]); 
					src_b = onech[(i*24)+j];
					b_out = (src_b & 0x10) >> 3;
					b_tmp = (src_b & 0x20) >> 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80);
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
		}
		count++;
		X = X + 3;
		Y = Y - 8;
	}
}

самое простое - зеркальное отображение символов по вертикальной оси - разницу во времени не заметил = 27 секунд


void OzOLED::printBigNumber(const char *number, byte X, byte Y, byte numChar){
// big number pixels: 24 x 32
 // Y - page
	byte column = 0;
	byte count = 0;
	byte onech[96];
	while(number[count] && count<numChar){
		setCursorXY(X, Y);
		// update for China OLED display 128*32
		byte src_b, b_out, b_tmp;
		for (byte i=0; i<4; ++i) {
			byte j;
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+(23-j)]);
					onech[(i*24)+j] = src_b;
					b_out = (src_b & 0x01) << 1;
					b_tmp = (src_b & 0x02) << 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 4;
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					//src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+j]); 
					src_b = onech[(i*24)+j];
					b_out = (src_b & 0x10) >> 3;
					b_tmp = (src_b & 0x20) >> 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80);
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
		}
		count++;
		X = X + 3;
		Y = Y - 8;
	}
}

зеркальное отображение по горизонтальной оси - добавлено немного кода - чуть медленнее стало = 27,22 секунд

void OzOLED::printBigNumber(const char *number, byte X, byte Y, byte numChar){
// big number pixels: 24 x 32
 // Y - page
	byte column = 0;
	byte count = 0;
	byte onech[96];
	while(number[count] && count<numChar){
		setCursorXY(X, Y);
		// update for China OLED display 128*32
		byte src_b, b_out, b_tmp;
		for (byte i=0; i<4; ++i) {
			byte j;
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					src_b = pgm_read_byte(&bigNumbers[number[count]-46][((3-i)*24)+j]);
					// bits 1 -> 8 and 8 -> 1 - H mirror
					b_out = (src_b & 0x01) << 7;
					b_tmp = (src_b & 0x02) << 5;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80) >> 7;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 5;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x20) >> 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x10) >> 1;
					b_out |= b_tmp;
					src_b = b_out;
					//--
					onech[(i*24)+j] = src_b;
					b_out = (src_b & 0x01) << 1;
					b_tmp = (src_b & 0x02) << 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 4;
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
			for (j=0; j<24; ++j) {
				if(number[count] < 46 || number[count] > 58)	
					sendData(0);
				else 	{			
					//src_b = pgm_read_byte(&bigNumbers[number[count]-46][(i*24)+j]); 
					src_b = onech[(i*24)+j];
					b_out = (src_b & 0x10) >> 3;
					b_tmp = (src_b & 0x20) >> 2;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80);
					b_out |= b_tmp;
					sendData(b_out);
				}
			}
			column = 0;
			setCursorXY(X, ++Y);
		}
		count++;
		X = X + 3;
		Y = Y - 8;
	}
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

И последнюю процедуру конечно можно сократить - так как там идет двойное преобразование битов - но на общем времени не сильно скажется

Logik
Offline
Зарегистрирован: 05.08.2014

27 секунд на вывод 1000 символов у Вас. Понятно что в такой тормозне нифига не заметно. Или Вы потролить решили? Так боян, уже мерялись, читайте - http://arduino.ru/forum/apparatnye-voprosy/medlennaya-rabota-liquidcrystali2c#comment-226474  (в #42 а то чет ссылка неотрабатывает) и какраз на sd1306)) И чистая практика ;) Измерено: 1000 символов  за 0,124 сек. При теоретическом пределе 0,075 сек на шине i2c 800КГц, тамже расписано почему столько. Правда размеры шрифта разные, у меня 6 байт на символ, у вас 96, в 16 раз больше. Ну значить и время гдето в 16 раз подростет получим 0.124*16= 2 сек или 1,2сек в идеале по ограничению шины. А никак не 27сек "на передачу информации на сам дисплей по IIC".

Научитесь работать с экраном быстро, в процессе и поймете что к чему, и что на что влияет. А без понимания Ваша практика - слепое тыканье в потемках с сплошными сюрпризами и разочерования.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Logik пишет:

27 секунд на вывод 1000 символов у Вас. Понятно что в такой тормозне нифига не заметно. Или Вы потролить решили? Так боян, уже мерялись, читайте - http://arduino.ru/forum/apparatnye-voprosy/medlennaya-rabota-liquidcrystali2c#comment-226474  (в #42 а то чет ссылка неотрабатывает) и какраз на sd1306)) И чистая практика ;) Измерено: 1000 символов  за 0,124 сек. При теоретическом пределе 0,075 сек на шине i2c 800КГц, тамже расписано почему столько. Правда размеры шрифта разные, у меня 6 байт на символ, у вас 96, в 16 раз больше. Ну значить и время гдето в 16 раз подростет получим 0.124*16= 2 сек или 1,2сек в идеале по ограничению шины. А никак не 27сек "на передачу информации на сам дисплей по IIC".

Научитесь работать с экраном быстро, в процессе и поймете что к чему, и что на что влияет. А без понимания Ваша практика - слепое тыканье в потемках с сплошными сюрпризами и разочерования.

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

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

и кстати :) -  1000 символов  за 0,124 сек.  - это на каком МК? т.е. вы опять не удосужившись уточнить на чем я практиковался - уже пытаетесь что то там подсчитать сравнить с моими результатами и выдать как истину - я же говорю - теоретик....

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

я кстати извиняюсь  - ошибочка вышла в тексте сообщения #21 - 10 циклов по 10 символов я тестировал = ~27 секунд = всего 100 символов

arduinec
Offline
Зарегистрирован: 01.09.2015

arduinec пишет:

Правильнее же один раз перекодировать шрифт, чем много раз редактировать разные библиотеки под него.

Пример скетча для преобразования кодов символов в визуальный формат и обратно (#27): http://arduino.ru/forum/programmirovanie/rusifikatsiya-biblioteki-adafru...

Logik
Offline
Зарегистрирован: 05.08.2014

andycat пишет:

 шрифт можно в рантайме переворачивать как угодно - что и продемонстрировал в практике.

пока на практике видно только криворутность и недалекость твою. И жажду срача тоже видно.

andycat пишет:

и кстати :) -  1000 символов  за 0,124 сек.  - это на каком МК?

Читайте тему по ссылке там кучу раз прописано 328-й 16МГц. И все ответы на отальные вопросы. Кстати там 3 чела получили скорости на порядок выше вашего при разных подходах к передаче данных. И очевидно что для хороших скоростей нужни хорошие подходы к коду. Переворот шрифта в реалтайме к ним явно не относится.

 

 

Logik
Offline
Зарегистрирован: 05.08.2014

andycat пишет:

я кстати извиняюсь  - ошибочка вышла в тексте сообщения #21 - 10 циклов по 10 символов я тестировал = ~27 секунд = всего 100 символов

Это воще писец. И хватает наглости с таким кодом вылазить и чето расказывать ))) Это 0,27сек на 1 символ. Т.е. при желании вывести часики то перерисовка секунд на них займет полсекунды. А мигание точек отгребет остальное процессорное время ))) Серезная заявка на самый кривой скетч.

Да. Вам переворот шрифта реалтайм точно неповредит ;)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Logik пишет:

пока на практике видно только криворутность и недалекость твою. И жажду срача тоже видно.

 

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

какой нахрен 328 на 16 мегагерц - я разве на нем пробовал? покажи хоть что нибудь что создал сам и проверил на реальном железе - какие то потуги и попытки показать что я обманываю народ.

на тебе практику:

а у тебя есть чем доказать обратное что переворот символа в рантайме не сильно затормаживает код?

нет - вот и заткни свой еб... и научись общаться корректно.

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

и на тебе еще реальность а не срач:

точные цифры затрат времени на переворот символа:

до переворота: 24861мс после 25734мс, разница 3.5%, можно еще уменьшить, но пусть это делает тот кому это надо.

скетч проверки:


void setup () {
  OzOled.init();  //инициализация дисплей
  OzOled.setNormalDisplay();      //нормальный режим
  OzOled.setPageMode();           //адресация страничная
  OzOled.sendCommand(0xA1);       //выбор ориентации сверху - вниз
  OzOled.sendCommand(0xC8);       //слева - направо
}

void loop () {
  OzOled.clearDisplay();          //очистка дисплея
  unsigned long showmillis = millis();
  for (byte i = 0; i < 10; ++i) {
    OzOled.printBigNumber("01234", 0, 0);
    OzOled.printBigNumber("56789", 0, 0);
  }
  showmillis = millis() - showmillis;
  OzOled.printBigNumber(".....", 0, 0);
  delay(1000);
  char str[6] = "";
  str[0] = (showmillis / 10000) + 0x30;
  str[1] = (showmillis % 10000) / 1000 + 0x30;
  str[2] = ((showmillis % 10000) % 1000) / 100 + 0x30;
  str[3] = (((showmillis % 10000) % 1000) % 100) / 10 + 0x30;
  str[4] = (((showmillis % 10000) % 1000) % 100) % 10 + 0x30;
  str[5] = 0;
  OzOled.printBigNumber(str, 0, 0);
  delay(10000);
}

 

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

andycat - а у вас какой МК? Вообще, если это что-то, кардинально отличное от атмеги328 - то это вы должны указывать контроллер, а не другие спрашивать у вас.

328-ая на форуме де-факто стандарт.

Ну и добавлю - 27 сек на 100 символов реально не быстро. Непонятно, на что вы вскинулись - Логик хоть и резковато, но высказал совершенно верную мысль - в вашем коде влияние зеркалирования на скорость незаметно, не потому что зеркалирование происходит быстро, а потому что все остальное тормозит. Медленный код вывода символа на экран маскирует остальные задержки, исследовать влияние зеркалирования в этом случае бессмысленно, ваши тесты ничего не показывают.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

b707 пишет:

andycat - а у вас какой МК? Вообще, если это что-то, кардинально отличное от атмеги328 - то это вы должны указывать контроллер, а не другие спрашивать у вас.

328-ая на форуме де-факто стандарт.

Ну и добавлю - 27 сек на 100 символов реально не быстро. Непонятно, на что вы вскинулись - Логик хоть и резковато, но высказал совершенно верную мысль - в вашем коде влияние зеркалирования на скорость незаметно, не потому что зеркалирование происходит быстро, а потому что все остальное тормозит. Медленный код вывода символа на экран маскирует остальные задержки, исследовать влияние зеркалирования в этом случае бессмысленно, ваши тесты ничего не показывают.

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

и как раз мои то тесты и показывают разницу, т.к. если я выведу на более мощном железе 100 символов - я просто не замечу эти микросекундные задержки например вот этих операций:

					// bits 1 -> 8 and 8 -> 1 - H mirror
					b_out = (src_b & 0x01) << 7;
					b_tmp = (src_b & 0x02) << 5;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80) >> 7;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 5;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x20) >> 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x10) >> 1;
					b_out |= b_tmp;
					src_b = b_out;
					//--

 

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

andycat пишет:

и на тебе еще реальность а не срач:

точные цифры затрат времени на переворот символа:

до переворота: 24861мс после 25734мс, разница 3.5%, можно еще уменьшить, но пусть это делает тот кому это надо.

Скажите, вы сами-то неужели не понимаете, что это провал? 9мс на переворот ОДНОГО символа?

Сравните с кодами Архата, Дракулы и Логика - у них вывод символа занимает ок 2мс, если добавить переворот 9мс - увеличение в ПЯТЬ раз...

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

b707 пишет:

andycat пишет:

и на тебе еще реальность а не срач:

точные цифры затрат времени на переворот символа:

до переворота: 24861мс после 25734мс, разница 3.5%, можно еще уменьшить, но пусть это делает тот кому это надо.

Скажите, вы сами-то неужели не понимаете, что это провал? 9мс на переворот ОДНОГО символа?

Сравните с кодами Архата, Дракулы и Логика - у них вывод символа занимает ок 2мс, если добавить переворот 9мс - увеличение в ПЯТЬ раз...

понимаю :) но у меня не стоит задача ускорить это, стояла задача показать в процентном отношении затраты - 3.5% это мало, и даже это можно уменьшить

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

andycat пишет:

понимаю :) но у меня не стоит задача ускорить это, стояла задача показать в процентном отношении затраты - 3.5% это мало, и даже это можно уменьшить

А по-моему не понимаете. Тут в первую очередь надо уменьшать 27 сек основного вывода на экран, а не 900мс зеркалирования. И когда основной вывод снизится до приемлимых величин - накладные расходы будут совсем не 3%

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

b707 пишет:

andycat пишет:

понимаю :) но у меня не стоит задача ускорить это, стояла задача показать в процентном отношении затраты - 3.5% это мало, и даже это можно уменьшить

А по-моему не понимаете. Тут в первую очередь надо уменьшать 27 сек основного вывода на экран, а не 900мс зеркалирования. И когда основной вывод снизится до приемлимых величин - накладные расходы будут совсем не 3%

отчего такое мнение? есть доказательства :) ?

если сообществу так любопытны точные цифры накладных расходов на другом МК - завтра сделаю - проверим теорию практикой.

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

andycat пишет:

отчего такое мнение? есть доказательства :) ?

если сообществу так любопытны точные цифры накладных расходов на другом МК - завтра сделаю - проверим теорию практикой.

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

А вот за сколько ваш код выведет 1000 символов на стандартной атмеге - и сравнить это с другими...

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

b707 пишет:

andycat пишет:

отчего такое мнение? есть доказательства :) ?

если сообществу так любопытны точные цифры накладных расходов на другом МК - завтра сделаю - проверим теорию практикой.

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

А вот за сколько ваш код выведет 1000 символов на стандартной атмеге - и сравнить это с другими...

естественно я собираюсь тестировать на стандартной UNO

и с какими другими вы собираетесь сравнивать? - сами же говорили что надо сравнивать переворот на стандартной меге

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

andycat пишет:

и с какими другими вы собираетесь сравнивать? - сами же говорили что надо сравнивать переворот на стандартной меге

я имел в виду сравнить с кодом других участников. Просто если ваш код и на 328-й будет на порядок-два медленнее разобранных по ссылке Логика кодов - то оценивать им влияение зеркалирования бессмысленно. Это как вычислять скорость пули, засекая время по будильнику.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

итак я все таки добил результат для UNO, желающие могут повторить :)

вывод 1000 символов на том же дисплее

12309 мс без переворота

12790 мс с переворотом

разница 3.9 % - как видите близко к 3.5 %  на Attiny85 1мгц - и кто тут не прав?

тестовый скетч:

#include <Wire.h>
#include <OzOLED.h>

void setup () {
  OzOled.init();  //инициализация дисплей
  OzOled.setNormalDisplay();      //нормальный режим
  OzOled.setPageMode();           //адресация страничная
  OzOled.sendCommand(0xA1);       //выбор ориентации сверху - вниз
  OzOled.sendCommand(0xC8);       //слева - направо
}

void loop () {
  OzOled.clearDisplay();          //очистка дисплея
  unsigned long showmillis = millis();
  for (byte i = 0; i < 100; ++i) {
    OzOled.printBigNumber("01234", 0, 0);
    OzOled.printBigNumber("56789", 0, 0);
  }
  showmillis = millis() - showmillis;
  OzOled.printBigNumber(".....", 0, 0);
  delay(1000);
  char str[6] = "";
  str[0] = (showmillis / 10000) + 0x30;
  str[1] = (showmillis % 10000) / 1000 + 0x30;
  str[2] = ((showmillis % 10000) % 1000) / 100 + 0x30;
  str[3] = (((showmillis % 10000) % 1000) % 100) / 10 + 0x30;
  str[4] = (((showmillis % 10000) % 1000) % 100) % 10 + 0x30;
  str[5] = 0;
  OzOled.printBigNumber(str, 0, 0);
  delay(10000);
}

измененные строки - переворота - аналогичные полностью:


void OzOLED::printBigNumber(const char *number, byte X, byte Y, byte numChar){
// big number pixels: 24 x 32
 // Y - page
	//byte column = 0;
	byte count = 0;
	while(number[count] && count<numChar){
		setCursorXY(X, Y);
		byte src_b, b_out, b_tmp;
		for (byte i=0; i<4; ++i) {
			byte j;
			for (j=0; j<24; ++j) {
				src_b = pgm_read_byte(&bigNumbers[number[count]-48][((3-i)*24)+j]);
					b_out = (src_b & 0x01) << 7;
					b_tmp = (src_b & 0x02) << 5;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x04) << 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x08) << 1;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x80) >> 7;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x40) >> 5;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x20) >> 3;
					b_out |= b_tmp;
					b_tmp = (src_b & 0x10) >> 1;
					b_out |= b_tmp;
				sendData(b_out);
			}
			setCursorXY(X, ++Y);
		}
		count++;
		X = X + 3;
		Y = Y - 4;
	}
}

 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

и я так думаю разница в данном случае больше из за того что саму функцию вывода выдывают в 10 раз больше - тоже + накладные расходы

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

@andycat, вот смотри, что до тебя пытаются донести про твои 3,5%. Давай просто разделим происходящее на две сущности: на вывод символов и их переворот, ок?

Так вот: если вывод символов - тормозной, то твои 3,5% как бы кажутся очень маленькой погрешностью. А теперь просто представь, что вывод символов работает в 10 раз быстрее, ок? Тогда ВНЕЗАПНО твоё зеркалирование становится бутылочным горлышком системы, не находишь?

Ты сравниваешь медленное с ооочень медленным, и делаешь неправильные выводы.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Эх....покажите мне хоть одну реальную систему и/или человека в которой мешает задержка 3.5% из 2мс отображения символа?

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

Не убедили, останемся при своём мнении.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Пойми, проценты - вещь ОТНОСИТЕЛЬНАЯ. Ты даже не пытался представить ситуацию, видимо. Давай ещё раз, на примерах:

1. Твой случай: 10 секунд отрисовка без переворота, 10,35 с - с переворотом, твои 3,5%, т.е. 0,35 с;

2. Случай с быстрой отрисовкой: 1 секунда отрисовка, 1,35 с - отрисовка с переворотом, уже 35% занимает твой переворот.

То, что ты, беря за основу МЕЕЕЕЕЕЕЕДЛЕННО работающую отрисовку, делаешь вывод, что твой МЕЕЕЕЕДЛЕННЫЙ код не вносит большого оверхеда - говорит ТОЛЬКО и ТОЛЬКО о текущей ситуации, делать далекоидущие выводы из твоего случая - ошибочно, что я и показал на конкретном примере. Твой код работает быстро только ОТНОСИТЕЛЬНО другого кода, который, в твоём случае - сам по себе небыстрый.

Чтобы это понять - просто сэмулируй более быструю отрисовку, закомментировав отсыл данных на экран, и увидишь, насколько печален подход с переворотом символов на лету на самом деле.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Прочитав про 35 % дальше даже не стал вчитываться)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

И да, я ситуацию даже представлять не хочу
Покажите реальный пример где 3.5 % мешают

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

andycat пишет:
Прочитав про 35 % дальше даже не стал вчитываться)

Ну конечно, это на тебя так похоже. Будешь спорить, что 1.35 на 35% больше, чем 1? Не тупи, смени поставщика наркоты, ты такую дичь гонишь, что тебя вразумлять, похоже, бесполезно: я уже третий, и, надеюсь, последний. Хер с ним, живи со своими тормозными лисапедами и дальше, раз не хочешь и не способен разобраться по сути.

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

А мой код на 35 %затормаживает?) сами то цифры посчитайте)

Logik
Offline
Зарегистрирован: 05.08.2014

DIYMan пишет:

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

 

И я к тому пришел! :) Пусть дальше процветает с выводом 4 букв в секунду ;)

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Logik пишет:

DIYMan пишет:

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

 

И я к тому пришел! :) Пусть дальше процветает с выводом 4 букв в секунду ;)

А где вы видите 4 символа в секунду? Последний пример как вы и просили на 328м 16мгц = 1000 символов за менее чем 13 секунд.....опять слова и ни капли фактов)