Кириллица на дисплее или что я делаю не так?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Кириллица на дисплее или что я делаю не так?

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

http://lesson.iarduino.ru/page/urok-8-russkiy-yazyk-na-oled-displee-128x64/

http://arduino-project.net/russkie-ukrainskie-shrifty-oled-i2c/

предлагают использовать ее следующим образом.
Допустим, все библиотеки, шрифты и т.п. скачаны и установлены, переходим к программированию.
Скажем, нужно вывести на экран фразу "Моя Arduino сгорела.". Оказывается, что просто так это сделать нельзя. Следует:
- установить русский фонт,
- вывести "Моя " с нужного места экрана,
- теперь переключить фонт на английский,
- посчитать, сколько символов занимает первая надпись,
- вывести строку с учетом указанного смещения,
- вывести строку "Arduino ",
- снова переключить фонт - обратно на русский,
- снова посчитать смещение,
- вывести "сгорела."

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

То есть это должно выглядеть примерно так:
 

  myOLED.setFont(RusFont);
  myOLED.print("Vjz ", 0, 3); // Выводим надпись "Моя "
  myOLED.setFont(LatFont);
  myOLED.print("Arduino ", 4, 3); // Выводим надпись "Arduino "
  myOLED.setFont(RusFont);
  myOLED.print("cujhtkf/", 12, 3); // Выводим надпись "сгорела."

Я лично делаю так:
 

        LD.printString6("0123456789!\"#$%&'()*+", 0, 0, 21);
        LD.printString6(",-./:;<=>?@[\\]^_`{|}~", 0, 1, 21);
        LD.printString6("ABCDEFGHIJKLMNOPQRSTU", 0, 2, 21);
        LD.printString6("VWXYZabcdefghijklmnop",0, 3, 21);
        LD.printString6("qrstuvwxyzАБВГДЕЁЖЗИЙ", 0, 4, 21);
        LD.printString6("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ", 0, 5, 21);
        LD.printString6("Яабвгдеёжзийклмнопрст", 0, 6, 21);
        LD.printString6("уфхцчшщъыьэюяЇїЎў§°±µ", 0, 7, 21);

и получаю на экране:

При этом моя IDE, как и положено, работает в utf-8.

Что я делаю неправильно?

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

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Ну, библиотекой это пока называть рано. Это - пока мои первые попытки что-то написать для arduino.

Удалить, конечно, можно.

Только ведь я снова смогу это написать - вот проблема!

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

Придётся тебя ликвидировать. Человечество важнее.
А по делу - мне строки LD.printString6 незнакомы, это что-то новое, и что значат три цифры в конце?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

"6" в конце названия функции означает фонт шириной 6 пикселей.

Послежние 3 цифры - наследие библиотеки by Oscar Liang (OzOLED), которая послужила одним из прототипов: первые два числа означают координаты символа на экране, а последняя - количество выводимых символов.

В общем, все это нуждается в упорядочивании, чем я постепенно и занимаюсь.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Так как никакой конструктивной критики моей идеи по использованию кириллицы в Ардуино не последовало (за исключением предложения убицца ап стену), выкладываю предварительный вариант библиотеки.

Библиотека разрабатывалась, исходя из минимизации занимаемого ею места как в постоянной, так и в оперативной памяти.

Библиотека работает с кодировкой utf-8, которая принята в IDE Arduino.

Библиотека позволяет отображать все символы ASCII кроме управляющих, все символы русского алфавита, включая Ёё, некоторые символы кириллицы украинского и беларусского алфавита [ЃѓЄєІіЇїЎўҐґ], и четыре прочих символа, которые мне понравились [§°±µ].

Никакие другие символы библиотека отображать не может. Зато при попытке отображения произвольной последовательности utf-8 символов последствия могут быть непредсказуемы.

Библиотека позволяет отображать символы двух размеров 6х8 и 12х16 пикселей, но в целях экономии большой фонт получается путем "растягивания" малого, а потому довольно угловат.

Для меня пока непонятен принци переключения между фонтами. Я вижу здесь 2 варианта:

    LD.setFont(Font_12x16);
    LD.printString("10");
    LD.setFont(Font_6x8);
    LD.printString("3");
    LD.setFont(Font_12x16);
    LD.printString(" = 1000");

и

    LD.printStringBig("10");
    LD.printStringSmall("3");
    LD.printStringBig(" = 1000");

Хотелось бы услышать мнение, какой вариант удобнее.

Библиотека проверялась исключительно с 0.96" OLED дисплеем SSD1306 128x64, может ли она работать с чем-либо другим, не знаю.

Работа над библиотекой пока не закончена, поэтому просьба не распространять эту библиотеку.

Пример работы (файл Test_ASOLED_1.ino):

#include <Wire.h>

#include "ASOLED.h"

#include "mice.c"

int State = 0;
long NewTime, OldTime;

void setup()
{
  OldTime = millis();
  LD.init();  //initialze OLED display
  LD.clearDisplay(); 
}


void loop()
{
  int n0 = 123;
  int n1 = -321;
  float d0 = 456.789;
  float d1 = -0.00789;
  NewTime = millis();
  if ((NewTime - OldTime) > 5000)
  {
    OldTime = NewTime;
    State = ++State % 5;
    LD.clearDisplay();
  }
  switch (State)
  {
    case 0:
        LD.printString6("0123456789!\"#$%&'()*+", 0, 0);
        LD.printString6(",-./:;<=>?@[\\]^_`{|}~", 0, 1);
        LD.printString6("ABCDEFGHIJKLMNOPQRSTU", 0, 2);
        LD.printString6("VWXYZabcdefghijklmnop",0, 3);
        LD.printString6("qrstuvwxyzАБВГДЕЁЖЗИЙ", 0, 4);
        LD.printString6("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ", 0, 5);
        LD.printString6("Яабвгдеёжзийклмнопрст", 0, 6);
        LD.printString6("уфхцчшщъыьэюяЇїЎў§°±µ", 0, 7);
        break;
    case 1:
        LD.printString12("012345%&'+", 0, 0);
        LD.printString12("ABCDEFGHIJ", 0, 2);
        LD.printString12("vwxyzАБВЕЁ", 0, 4);
        LD.printString12("юяЇїЎў§°±µ", 0, 6);
        break;
    case 2:
        for (int i = 0; i < 128; i++){
          int j = (int)(sin(i*0.09 + 0.2)*35) + 45;
          LD.VertBar(i, j, 0, 90);
        }
        break;
    case 3:
        LD.printNumber((long)n0, 0, 0);  // 123
        LD.printNumber((long)n1, 0, 2); // -321
        LD.printNumber(d0, 6, 60, 2);     // 456.789
        LD.printNumber(-d0, 6, 48, 0);   // -456.789
        LD.printNumber(d1, 8, 0, 6);     // 0.00789
        LD.printNumber((long)10, 28, 4);        // 10
        LD.printString6("3"); //, 0, 4);  // ^3
        LD.printString12("="); //, 0, 4); // =
        LD.printNumber((long)1000); //, 0, 4);  // 1000
        break;
    case 4 :
        LD.drawBitmap(mice, 0, 0, 128, 8);
        break;
  }
}

Заголовочный файл библиотеки (ASOLED.h):

/*
  ASOLED.h - 0.96' I2C 128x64 OLED Driver Library
  ver. 0.1a

  2015 Copyright (c) Sergey Andrianov

  Please, do not distribute this library. 
  It is not ready yet. Work is not complete. 
  It is a preliminary variant exceptionally for testing.
*/

#ifndef ASOLED_data_H
#define ASOLED_data_H

#include <Arduino.h>

#define ASOLED_Max_X				128	//128 Pixels
#define ASOLED_Max_Y				64	//64  Pixels

#define OLED_ADDRESS				0x3C // 0x78
#define I2C_400KHZ					1	// 0 to use default 100Khz, 1 for 400Khz

#define Font_6x8            1
#define Font_12x16          2


class ASOLED {

public:
  void init();
  void setSize(const char font);
//	void printString(const char *String, byte X=255, byte Y=255, byte numChar=255);
	void printString6(const char *String, byte X=255, byte Y=255);
  void printString12(const char *String, byte X=255, byte Y=255);  // font 12x16

	byte printNumber(long n, byte X=255, byte Y=255);
	byte printNumber(float float_num, byte prec=6, byte Y=255, byte numChar=255);
	void drawBitmap(const byte *bitmaparray, byte X, byte Y, byte width, byte height); // X - in 1 pixel, Y - in 8 pixels

	void VertBar(int Num, int Val, int MinVal, int MaxVal);

	void clearDisplay();
	
	void setNormalDisplay();
	void setInverseDisplay();
	void setBrightness(byte Brightness);

private:
  void sendCommand(byte command);
  void sendData(byte Data);

  void printChar(char c);
  void setCursorXY(byte Column, byte Row); // X * 1 pixels, Y * 8 pixels
  void setPowerOff();
  void setPowerOn();
  void setPageMode();
  void setHorizontalMode();

  byte addressingMode;

  char CurrFont; // font size
  char NumberString[16]; // 4 print numbers
  byte LenString = 0;   // current length of NumberString
  byte CurrX = 0;   // current position
  byte CurrY = 0;
};

extern ASOLED LD;  // ASOLED object 

#endif

Код библиотеки (ASOLED.cpp):

#include "ASOLED.h"
#include <Wire.h>
#include <avr/pgmspace.h>

#include "a_Small_Rus.c"

// registers
#define ASA_OLED_COMMAND_MODE        0x80
#define ASA_OLED_DATA_MODE        0x40

//==========================================================

unsigned char ASA_utf8_preliminary_byte = 0;

unsigned char RecodeUTF_ASA(unsigned char c)
{
	switch (c)
	{
	case (unsigned char)0xD0:
		ASA_utf8_preliminary_byte = c; // wait second byte
		return 255;
	case (unsigned char)0xD1:
		ASA_utf8_preliminary_byte = c; // wait second byte
		return 255;
  case (unsigned char)0xD2:
    ASA_utf8_preliminary_byte = c; // wait second byte
    return 255;
  case (unsigned char)0xC2:
    ASA_utf8_preliminary_byte = c; // wait second byte
    return 255;
	default:
		if(ASA_utf8_preliminary_byte == 0) // first half of ASCII table or nonsupported symbol
		{
			if((c >= ' ') && (c <= '~')) {
				return c;
			}else{
				return '*';
			}
		}
		else if(ASA_utf8_preliminary_byte == 0xD0) //
		{
			ASA_utf8_preliminary_byte = 0;
			if((c >= 144) && (c <= 191))	{
				return c - 17;
			} else if (c == 129) { // РЃ
				return 191;
      } else if (c == 131) { // Рѓ
        return 193;
      } else if (c == 132) { // Р„
        return 195;
      } else if (c == 134) { // Р†
        return 197;
      } else if (c == 135) { // Р‡
        return 199;
      } else if (c == 142) { // РЋ
        return 201;
			} else {
				return '*';
			}
		}
		else if(ASA_utf8_preliminary_byte == 0xD1) //
		{
			ASA_utf8_preliminary_byte = 0;
			if((c >= 128) && (c <= 143)){
				return c + 47;
			} else if (c == 145) { // С‘
				return 192;
      } else if (c == 147) { // С“
        return 194;
      } else if (c == 148) { // С”
        return 196;
      } else if (c == 150) { // С–
        return 198;
      } else if (c == 151) { // С—
        return 200;
      } else if (c == 158) { // Сћ
        return 202;
			} else {
				return '*';
			}
		}
    else if(ASA_utf8_preliminary_byte == 0xD2) //
    {
      ASA_utf8_preliminary_byte = 0;
      if (c == 144) { // Тђ
        return 203;
      } else if (c == 145) { // Т‘
        return 204;
      } else {
        return '*';
      }
    }
    else if(ASA_utf8_preliminary_byte == 0xC2) //
    {
      ASA_utf8_preliminary_byte = 0;
      if (c == 167) { // В§
        return 205;
      } else if (c == 176) { // В°
        return 206;
      } else if (c == 177) { // В±
        return 207;
      } else if (c == 181) { // Вµ
        return 208;
      } else {
        return '*';
      }
    }
		else {
			return '*';
		}
	}
}

// ====================== LOW LEVEL =========================

void ASOLED::sendCommand(byte command){
	Wire.beginTransmission(OLED_ADDRESS); // begin transmitting
	Wire.write(ASA_OLED_COMMAND_MODE);//data mode
	Wire.write(command);
	Wire.endTransmission();    // stop transmitting
}

void ASOLED::sendData(byte data){
	Wire.beginTransmission(OLED_ADDRESS); // begin transmitting
	Wire.write(ASA_OLED_DATA_MODE);//data mode
	Wire.write(data);
	Wire.endTransmission();    // stop transmitting
}

void ASOLED::printChar(char C){ // write to temp string for numbers
  NumberString[LenString++] = C;
  NumberString[LenString] = 0;
}

void ASOLED::printString6(const char *String, byte X, byte Y){
 	setCursorXY(X, Y);
	while(*String){
		unsigned char c = RecodeUTF_ASA(*String++);
		if (c != 255) {                   //			printChar6(c);
      sendData(0);
      for(byte i=0; i<5; i++)
        sendData(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4]));
      CurrX += 6;
		}
	}
}

unsigned int EnlardeByte2Word(char b)
{
	unsigned int d = 0;
	for (byte i = 0; i < 8; i++)
	{
		unsigned int e = (((unsigned int)b) & (1 << i)) << i;
		d = d | e | (e << 1);
	}
	return d;
}

void ASOLED::printString12(const char *String, byte X, byte Y){
  setCursorXY(X, Y);
  const char *String0 = String;
  unsigned int m = 0;
  byte tmpX = CurrX;
  while(*String){                               // print upper half of the string
    unsigned char c = RecodeUTF_ASA(*String++);
    if (c != 255)
    {
      if(tmpX < (ASOLED_Max_X - 2)) {
        sendData(0);
        sendData(0);
        tmpX += 2;
      }
      for(byte i=0; i<5; i++) {
        if(tmpX < (ASOLED_Max_X - 2)) {
          m = EnlardeByte2Word(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4]));
          sendData(lowByte(m));
          sendData(lowByte(m));
          tmpX += 2;
        }
      }
    } 
  }
  setCursorXY(CurrX, CurrY+1);
  while(*String0){                               // print lower half of the string
    unsigned char c = RecodeUTF_ASA(*String0++);
    if (c != 255)
    {
      if(CurrX < (ASOLED_Max_X - 2)) {
        sendData(0);
        sendData(0);
        CurrX += 2;
      }
      for(byte i=0; i<5; i++) {
        if(CurrX < (ASOLED_Max_X - 2)) {
          m = EnlardeByte2Word(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4]));
          sendData(highByte(m));
          sendData(highByte(m));
          CurrX += 2;
        }
      }
    } 
  }
  setCursorXY(CurrX, CurrY-1);
}

byte ASOLED::printNumber(long long_num, byte X, byte Y){
  LenString = 0;
	setCursorXY(X, Y);
	byte char_buffer[10] = "";
	byte i = 0;
	byte f = 0; // number of characters
	if (long_num < 0) {
		f++;
		printChar('-');
		long_num = -long_num;
	} 
	else if (long_num == 0) {
		f++;
		printChar('0');
    printString12(&NumberString[0]); //, X, Y);
		return f;
	} 
	while (long_num > 0) {
		char_buffer[i++] = long_num % 10;
		long_num /= 10;
	}
	f += i;
	for(; i > 0; i--) 
		printChar('0'+ char_buffer[i - 1]);
  printString12(&NumberString[0]); //, X, Y);
	return f;
}

byte ASOLED::printNumber(float float_num, byte prec, byte X, byte Y){
  LenString = 0;
	setCursorXY(X, Y);
// prec - 6 maximum
	byte num_int = 0;
	byte num_frac = 0;
	byte num_extra = 0;
	long d = float_num; // get the integer part
	float f = float_num - d; // get the fractional part
	if (d == 0 && f < 0.0){
		printChar('-');
		num_extra++;
		printChar('0');
		num_extra++;
		f *= -1;
    printString12(&NumberString[0]); //, CurrX, CurrY);
    LenString = 0;
	}
	else if (d < 0 && f < 0.0){
		num_int = printNumber(d); //, CurrX, CurrY); // count how many digits in integer part
    LenString = 0;
		f *= -1;
	}
	else{
		num_int = printNumber(d); //, CurrX, CurrY); // count how many digits in integer part
    LenString = 0;
	}
	// only when fractional part > 0, we show decimal point
	if (f > 0.0){
		printChar('.');
		num_extra++;
    printString12(&NumberString[0]); //, X, Y);
    LenString = 0;
		if (num_int + prec > 8) 
			prec = 8 - num_int;
    for (byte j=0; j<prec; j++){
      f *= 10.0;
      byte dd = f;
      printChar('0' + dd);
      f -= dd;
    }
    printString12(&NumberString[0]); //, X, Y);
    num_frac = prec;
	}
	return num_int + num_frac + num_extra;
}

void ASOLED::drawBitmap(const byte *bitmaparray, byte X, byte Y, byte width, byte height){
// max width = 128
// max height = 8
  for (int j = 0; j <  height; j++) {
    setCursorXY(X, Y + lowByte(j));
    for (byte i = 0; i < width; i++)    
      sendData(pgm_read_byte(&bitmaparray[i + 4 + j*width]));
  }
}

void ASOLED::VertBar(int Num, int Val, int MinVal, int MaxVal)
{
	if (Val < MinVal) Val = MinVal;            // consider that Val already scaled
	if (Val > MaxVal) Val = MaxVal;
	Val -= MinVal;
    for (int i = 0; i < 8; i++)              // go from high levels to low ones
	{
		setCursorXY(Num, i);
    int b;                                   // will calc this value for each columns (bars)
		int UpB = (MaxVal - MinVal)*(8-i)/8;
    if (Val <= UpB)                          // top boundary
		{
			int DownB = (MaxVal - MinVal)*(7-i)/8;
      if (Val >= DownB)                      // bottom boundary
      {                                      // Val are in this interval
				int j = (Val - DownB)*8/(UpB - DownB);
				int k = 0xFF00;
				b = (k >> j) & 0xFF;
			}
			else
			{
				b = 0;
			}
		}
		else
		{
			b = 0xFF;
		}
		sendData(b);
	}
  setCursorXY(0, 0);
}

// =================== High Level ===========================

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// commands
#define ASA_OLED_CMD_DISPLAY_OFF      0xAE
#define ASA_OLED_CMD_DISPLAY_ON     0xAF
#define ASA_OLED_CMD_NORMAL_DISPLAY   0xA6
#define ASA_OLED_CMD_INVERSE_DISPLAY    0xA7
#define ASA_OLED_CMD_SET_BRIGHTNESS   0x81

#define ASA_OLED_RIGHT_SCROLL       0x26
#define ASA_OLED_LEFT_SCROLL        0x27
#define ASA_OLED_SET_VERTICAL_SCROLL_AREA 0xA3
#define ASA_OLED_VERTICAL_RIGHT_SCROLL  0x29
#define ASA_OLED_VERTICAL_LEFT_SCROLL   0x2A
#define ASA_OLED_CMD_ACTIVATE_SCROLL    0x2F
#define ASA_OLED_CMD_DEACTIVATE_SCROLL  0x2E

#define HORIZONTAL_ADDRESSING 0x00
#define PAGE_ADDRESSING     0x02

#define Scroll_Left       0x00
#define Scroll_Right      0x01
#define Scroll_Up       0x02
#define Scroll_Down       0x03

#define Scroll_2Frames      0x07
#define Scroll_3Frames      0x04
#define Scroll_4Frames      0x05
#define Scroll_5Frames      0x00
#define Scroll_25Frames     0x06
#define Scroll_64Frames     0x01
#define Scroll_128Frames    0x02
#define Scroll_256Frames    0x03

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SSD1306 Commandset
// ------------------
// Fundamental Commands
#define ASA_DISPLAY_ALL_ON_RESUME	    	0xA4
// Addressing Setting Commands
#define ASA_MEMORY_ADDR_MODE	    		0x20
// Hardware Configuration Commands
#define ASA_SET_START_LINE    			0x40
#define ASA_SET_SEGMENT_REMAP	    		0xA0
#define ASA_SET_MULTIPLEX_RATIO		    	0xA8
#define ASA_COM_SCAN_DIR_DEC			0xC8
#define ASA_SET_DISPLAY_OFFSET    			0xD3
#define ASA_SET_COM_PINS	    			0xDA
#define ASA_CHARGE_PUMP   			0x8D
// Timing & Driving Scheme Setting Commands
#define ASA_SET_DISPLAY_CLOCK_DIV_RATIO		0xD5
#define ASA_SET_PRECHARGE_PERIOD		0xD9
#define ASA_SET_VCOM_DESELECT		    	0xDB

void ASOLED::init(){
	Wire.begin();
	// upgrade to 400KHz! (only use when your other i2c device support this speed)
	if (I2C_400KHZ){
		// save I2C bitrate (default 100Khz)
		byte twbrbackup = TWBR;
		TWBR = 12; 
	}
	
	setPageMode();	// default addressing mode
	clearDisplay();
	setCursorXY(0,0);
	
// Additional command
	LD.setPowerOff();
	LD.sendCommand(ASA_SET_DISPLAY_CLOCK_DIV_RATIO);
	LD.sendCommand(0x80);
	LD.sendCommand(ASA_SET_MULTIPLEX_RATIO);
	LD.sendCommand(0x3F);
	LD.sendCommand(ASA_SET_DISPLAY_OFFSET);
	LD.sendCommand(0x0);
	LD.sendCommand(ASA_SET_START_LINE | 0x0);
	LD.sendCommand(ASA_CHARGE_PUMP);
		LD.sendCommand(0x14);
	LD.sendCommand(ASA_MEMORY_ADDR_MODE);
	LD.sendCommand(0x00);
	LD.sendCommand(ASA_SET_SEGMENT_REMAP | 0x1);
	LD.sendCommand(ASA_COM_SCAN_DIR_DEC);
	LD.sendCommand(ASA_SET_COM_PINS);
	LD.sendCommand(0x12);
	LD.setBrightness(0xCF);
	LD.sendCommand(ASA_SET_PRECHARGE_PERIOD);
		LD.sendCommand(0xF1);
	LD.sendCommand(ASA_SET_VCOM_DESELECT);
	LD.sendCommand(0x40);
	LD.sendCommand(ASA_DISPLAY_ALL_ON_RESUME);
	LD.setNormalDisplay();
	LD.setPowerOn();
}

void ASOLED::setCursorXY(byte X, byte Y){
// Y - 1 unit = 1 page (8 pixel rows)
// X - 1 unit = 1 pixel columns
  if (X < 128)
    if ((X != CurrX) || (Y != CurrY)){
      sendCommand(0x00 + (X & 0x0F)); 		//set column lower address
      sendCommand(0x10 + ((X>>4)&0x0F)); 	//set column higher address
      sendCommand(0xB0 + Y); 					//set page address
      CurrX = X;
      CurrY = Y;
    }
}

void ASOLED::setSize(const char font)
{
  CurrFont = font;
}

void ASOLED::clearDisplay()	{
	for(byte page=0; page<8; page++) {	
		setCursorXY(0, page);     
		for(byte column=0; column<128; column++)  //clear all columns
			sendData(0);    
	}
	setCursorXY(0,0);
}


void ASOLED::setInverseDisplay(){
	sendCommand(ASA_OLED_CMD_INVERSE_DISPLAY);
}

void ASOLED::setNormalDisplay(){
	sendCommand(ASA_OLED_CMD_NORMAL_DISPLAY);
}

void ASOLED::setPowerOff(){
	sendCommand(ASA_OLED_CMD_DISPLAY_OFF);
}

void ASOLED::setPowerOn(){
	sendCommand(ASA_OLED_CMD_DISPLAY_ON);
}

void ASOLED::setBrightness(byte Brightness){
	sendCommand(ASA_OLED_CMD_SET_BRIGHTNESS);
	sendCommand(Brightness);
}

void ASOLED::setPageMode(){
	addressingMode = PAGE_ADDRESSING;
	sendCommand(0x20); 				//set addressing mode
	sendCommand(PAGE_ADDRESSING); 	//set page addressing mode
}

void ASOLED::setHorizontalMode(){
	addressingMode = HORIZONTAL_ADDRESSING;
	sendCommand(0x20); 				//set addressing mode
	sendCommand(HORIZONTAL_ADDRESSING); 	//set page addressing mode
}

ASOLED LD;  // Preinstantiate Objects


Шрифт (a_Small_Rus.c):

#if defined(__AVR__)
  #include <avr/pgmspace.h>
  #define fontdatatype const uint8_t
#elif defined(__PIC32MX__)
  #define PROGMEM
  #define fontdatatype const unsigned char
#elif defined(__arm__)
  #define PROGMEM
  #define fontdatatype const unsigned char
#endif

// New font 177 symbols 5x8 = 885+4 bytes

fontdatatype SmallFont[] PROGMEM =
{
0x05, 0x08, 0x20, 0xb1,
0x00, 0x00, 0x00, 0x00, 0x00,   // sp
0x00, 0x00, 0x2f, 0x00, 0x00,   // !
0x00, 0x07, 0x00, 0x07, 0x00,   // "
0x14, 0x7f, 0x14, 0x7f, 0x14,   // #
0x24, 0x2a, 0x7f, 0x2a, 0x12,   // $
0x23, 0x13, 0x08, 0x64, 0x62,   // %
0x36, 0x49, 0x55, 0x22, 0x50,   // &
0x00, 0x05, 0x03, 0x00, 0x00,   // '
0x00, 0x1c, 0x22, 0x41, 0x00,   // (
0x00, 0x41, 0x22, 0x1c, 0x00,   // )
0x14, 0x08, 0x3E, 0x08, 0x14,   // *
0x08, 0x08, 0x3E, 0x08, 0x08,   // +
0x00, 0x00, 0xA0, 0x60, 0x00,   // ,
0x08, 0x08, 0x08, 0x08, 0x08,   // -
0x00, 0x60, 0x60, 0x00, 0x00,   // .
0x20, 0x10, 0x08, 0x04, 0x02,   // /

0x3E, 0x51, 0x49, 0x45, 0x3E,   // 0
0x00, 0x42, 0x7F, 0x40, 0x00,   // 1
0x42, 0x61, 0x51, 0x49, 0x46,   // 2
0x21, 0x41, 0x45, 0x4B, 0x31,   // 3
0x18, 0x14, 0x12, 0x7F, 0x10,   // 4
0x27, 0x45, 0x45, 0x45, 0x39,   // 5
0x3C, 0x4A, 0x49, 0x49, 0x30,   // 6
0x01, 0x71, 0x09, 0x05, 0x03,   // 7
0x36, 0x49, 0x49, 0x49, 0x36,   // 8
0x06, 0x49, 0x49, 0x29, 0x1E,   // 9
0x00, 0x36, 0x36, 0x00, 0x00,   // :
0x00, 0x56, 0x36, 0x00, 0x00,   // ;
0x08, 0x14, 0x22, 0x41, 0x00,   // <
0x14, 0x14, 0x14, 0x14, 0x14,   // =
0x00, 0x41, 0x22, 0x14, 0x08,   // >
0x02, 0x01, 0x51, 0x09, 0x06,   // ?

0x32, 0x49, 0x59, 0x51, 0x3E,   // @
0x7C, 0x12, 0x11, 0x12, 0x7C,   // A
0x7F, 0x49, 0x49, 0x49, 0x36,   // B
0x3E, 0x41, 0x41, 0x41, 0x22,   // C
0x7F, 0x41, 0x41, 0x22, 0x1C,   // D
0x7F, 0x49, 0x49, 0x49, 0x41,   // E
0x7F, 0x09, 0x09, 0x09, 0x01,   // F
0x3E, 0x41, 0x49, 0x49, 0x7A,   // G
0x7F, 0x08, 0x08, 0x08, 0x7F,   // H
0x00, 0x41, 0x7F, 0x41, 0x00,   // I
0x20, 0x40, 0x41, 0x3F, 0x01,   // J
0x7F, 0x08, 0x14, 0x22, 0x41,   // K
0x7F, 0x40, 0x40, 0x40, 0x40,   // L
0x7F, 0x02, 0x0C, 0x02, 0x7F,   // M
0x7F, 0x04, 0x08, 0x10, 0x7F,   // N
0x3E, 0x41, 0x41, 0x41, 0x3E,   // O

0x7F, 0x09, 0x09, 0x09, 0x06,   // P
0x3E, 0x41, 0x51, 0x21, 0x5E,   // Q
0x7F, 0x09, 0x19, 0x29, 0x46,   // R
0x46, 0x49, 0x49, 0x49, 0x31,   // S
0x01, 0x01, 0x7F, 0x01, 0x01,   // T
0x3F, 0x40, 0x40, 0x40, 0x3F,   // U
0x1F, 0x20, 0x40, 0x20, 0x1F,   // V
0x3F, 0x40, 0x38, 0x40, 0x3F,   // W
0x63, 0x14, 0x08, 0x14, 0x63,   // X
0x07, 0x08, 0x70, 0x08, 0x07,   // Y
0x61, 0x51, 0x49, 0x45, 0x43,   // Z
0x00, 0x7F, 0x41, 0x41, 0x00,   // [
0x01, 0x06, 0x08, 0x30, 0x40,   // Backslash
0x00, 0x41, 0x41, 0x7F, 0x00,   // ]
0x04, 0x02, 0x01, 0x02, 0x04,   // ^
0x40, 0x40, 0x40, 0x40, 0x40,   // _

0x00, 0x03, 0x05, 0x00, 0x00,   // `
0x20, 0x54, 0x54, 0x54, 0x78,   // a
0x7F, 0x48, 0x44, 0x44, 0x38,   // b
0x38, 0x44, 0x44, 0x44, 0x20,   // c
0x38, 0x44, 0x44, 0x48, 0x7F,   // d
0x38, 0x54, 0x54, 0x54, 0x18,   // e
0x08, 0x7E, 0x09, 0x01, 0x02,   // f
0x18, 0xA4, 0xA4, 0xA4, 0x7C,   // g
0x7F, 0x08, 0x04, 0x04, 0x78,   // h
0x00, 0x44, 0x7D, 0x40, 0x00,   // i
0x40, 0x80, 0x84, 0x7D, 0x00,   // j
0x7F, 0x10, 0x28, 0x44, 0x00,   // k
0x00, 0x41, 0x7F, 0x40, 0x00,   // l
0x7C, 0x04, 0x18, 0x04, 0x78,   // m
0x7C, 0x08, 0x04, 0x04, 0x78,   // n
0x38, 0x44, 0x44, 0x44, 0x38,   // o

0xFC, 0x24, 0x24, 0x24, 0x18,   // p
0x18, 0x24, 0x24, 0x18, 0xFC,   // q
0x7C, 0x08, 0x04, 0x04, 0x08,   // r
0x48, 0x54, 0x54, 0x54, 0x20,   // s
0x04, 0x3F, 0x44, 0x40, 0x20,   // t
0x3C, 0x40, 0x40, 0x20, 0x7C,   // u
0x1C, 0x20, 0x40, 0x20, 0x1C,   // v
0x3C, 0x40, 0x30, 0x40, 0x3C,   // w
0x44, 0x28, 0x10, 0x28, 0x44,   // x
0x1C, 0xA0, 0xA0, 0xA0, 0x7C,   // y
0x44, 0x64, 0x54, 0x4C, 0x44,   // z
0x00, 0x10, 0x7C, 0x82, 0x00,   // {
0x00, 0x00, 0xFF, 0x00, 0x00,   // |
0x00, 0x82, 0x7C, 0x10, 0x00,   // }
0x08, 0x04, 0x08, 0x10, 0x08,   // 7E    126   ~
0x7C, 0x12, 0x11, 0x12, 0x7C,   // А

0x7F, 0x49, 0x49, 0x49, 0x31,   // Б
0x7F, 0x45, 0x45, 0x45, 0x3A,   // В
0x7F, 0x01, 0x01, 0x01, 0x03,   // Г
0x60, 0x3F, 0x21, 0x3F, 0x60,   // Д
0x7F, 0x49, 0x49, 0x49, 0x41,   // Е
0x73, 0x0C, 0x7F, 0x0C, 0x73,   // Ж
0x21, 0x41, 0x49, 0x4D, 0x33,   // З
0x7F, 0x10, 0x08, 0x04, 0x7F,   // И
0x7E, 0x20, 0x11, 0x08, 0x7E,   // Й
0x7F, 0x08, 0x14, 0x22, 0x41,   // К
0x40, 0x3F, 0x01, 0x01, 0x7F,   // Л
0x7F, 0x06, 0x08, 0x06, 0x7F,   // М
0x7F, 0x08, 0x08, 0x08, 0x7F,   // Н
0x3E, 0x41, 0x41, 0x41, 0x3E,   // О
0x7F, 0x01, 0x01, 0x01, 0x7F,   // П
0x7F, 0x09, 0x09, 0x09, 0x06,   // Р

0x3E, 0x41, 0x41, 0x41, 0x22,   // С
0x03, 0x01, 0x7F, 0x01, 0x03,   // Т
0x61, 0x26, 0x18, 0x06, 0x01,   // У
0x1C, 0x22, 0x7F, 0x22, 0x1C,   // Ф
0x63, 0x14, 0x08, 0x14, 0x63,   // Х
0x3F, 0x20, 0x20, 0x3F, 0x60,   // Ц
0x07, 0x08, 0x08, 0x08, 0x7F,   // Ч
0x7F, 0x40, 0x7F, 0x40, 0x7F,   // Ш
0x3F, 0x20, 0x3F, 0x20, 0x7F,   // Щ
0x01, 0x7F, 0x48, 0x48, 0x30,   // Ъ
0x7F, 0x48, 0x78, 0x00, 0x7F,   // Ы
0x7F, 0x48, 0x48, 0x30, 0x00,   // Ь
0x41, 0x49, 0x49, 0x2A, 0x1C,   // Э
0x7F, 0x10, 0x3E, 0x41, 0x3E,   // Ю
0x66, 0x19, 0x09, 0x09, 0x7F,   // Я
0x20, 0x54, 0x54, 0x78, 0x40,   // а

0x3E, 0x49, 0x45, 0x45, 0x38,   // б
0x7E, 0x4A, 0x4A, 0x34, 0x00,   // в
0x7C, 0x04, 0x04, 0x0C, 0x00,   // г
0x38, 0x45, 0x45, 0x49, 0x3E,   // д
0x38, 0x54, 0x54, 0x54, 0x18,   // е
0x4C, 0x30, 0x7C, 0x30, 0x4C,   // ж
0x24, 0x42, 0x4A, 0x34, 0x00,   // з
0x7C, 0x20, 0x10, 0x7C, 0x00,   // и
0x7C, 0x21, 0x11, 0x7C, 0x00,   // й
0x7C, 0x10, 0x28, 0x44, 0x00,   // к
0x40, 0x3C, 0x04, 0x04, 0x7C,   // л
0x7C, 0x08, 0x10, 0x08, 0x7C,   // м
0x7C, 0x10, 0x10, 0x7C, 0x00,   // н
0x38, 0x44, 0x44, 0x44, 0x38,   // о
0x7C, 0x04, 0x04, 0x7C, 0x00,   // п
0xFC, 0x18, 0x24, 0x24, 0x18,   // р

0x38, 0x44, 0x44, 0x44, 0x28,   // с
0x04, 0x04, 0x7C, 0x04, 0x04,   // т
0x4C, 0x90, 0x90, 0x90, 0x7C,   // у
0x18, 0x24, 0x7E, 0x24, 0x18,   // ф
0x44, 0x28, 0x10, 0x28, 0x44,   // х
0x3C, 0x20, 0x20, 0x3C, 0x60,   // ц
0x1C, 0x10, 0x10, 0x7C, 0x00,   // ч
0x7C, 0x40, 0x7C, 0x40, 0x7C,   // ш
0x3C, 0x20, 0x3C, 0x20, 0x7C,   // щ
0x04, 0x7C, 0x50, 0x70, 0x00,   // ъ
0x7C, 0x50, 0x70, 0x00, 0x7C,   // ы
0x7C, 0x50, 0x70, 0x00, 0x00,   // ь
0x42, 0x42, 0x52, 0x52, 0x3C,   // э
0x7C, 0x10, 0x38, 0x44, 0x38,   // ю
0x40, 0x2C, 0x12, 0x7E, 0x00,   // я
0x7E, 0x4B, 0x4A, 0x4B, 0x42,   //            Ё   D0 81

0x38, 0x55, 0x54, 0x55, 0x18,   //            ё   D1 91
0x7C, 0x04, 0x05, 0x04, 0x00,   //81    129   Ѓ   D0 83
0x00, 0x78, 0x0A, 0x09, 0x00,   //83    131   ѓ   D1 93
0x3E, 0x49, 0x49, 0x41, 0x22,   //AA    170   Є   D0 84
0x38, 0x54, 0x54, 0x44, 0x28,   //BA    186   є   D1 94
0x00, 0x41, 0x7F, 0x41, 0x00,   //B2    178   І   D0 86
0x00, 0x44, 0x7D, 0x40, 0x00,   //B3    179   і   D1 96
0x00, 0x45, 0x7C, 0x45, 0x00,   //AF    175   Ї   D0 87
0x00, 0x45, 0x7C, 0x41, 0x00,   //BF    191   ї   D1 97
0x23, 0x44, 0x39, 0x04, 0x03,   //A1    161   Ў   D0 8E
0x24, 0x49, 0x32, 0x09, 0x04,   //A2    162   ў   D1 9E
0x7E, 0x02, 0x02, 0x02, 0x01,   //A5    165   Ґ   D2 90
0x7C, 0x04, 0x04, 0x02, 0x00,   //B4    180   ґ   D2 91
0x00, 0x4A, 0x55, 0x29, 0x00,   //A7    167   §   C2 A7
0x00, 0x06, 0x09, 0x09, 0x06,   //            °   C2 B0
0x44, 0x44, 0x5F, 0x44, 0x44,   //B1    177   ±   C2 B1

0x7C, 0x10, 0x10, 0x3C, 0x40,   //B5    181   µ   C2 B5
};


И демонстрационная картинка (mice.c) - к библиотеке отношения не имеет, просто для иллюстрации:

#if defined(__AVR__)
  #include <avr/pgmspace.h>
  #define fontdatatype const uint8_t
#elif defined(__PIC32MX__)
  #define PROGMEM
  #define fontdatatype const unsigned char
#elif defined(__arm__)
  #define PROGMEM
  #define fontdatatype const unsigned char
#endif

//  mice bitmap 128x64

fontdatatype mice[] PROGMEM={
0x80, 0x40, 0xFF, 0x01,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0010 (16) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,   // 0x0020 (32) pixels
0x3F, 0x3F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0030 (48) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0040 (64) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0050 (80) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0xCF, 0xCF, 0xEF, 0xCF, 0x9F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF,   // 0x0060 (96) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0x3F, 0x9F, 0x9F, 0xDF, 0xCF, 0xCF, 0xCF,   // 0x0070 (112) pixels
0x1F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0080 (128) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0090 (144) pixels
0xFF, 0xFF, 0x0F, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x00A0 (160) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x00B0 (176) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x00C0 (192) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x00D0 (208) pixels
0xFF, 0xFF, 0xFF, 0x07, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xE1, 0x07, 0x3F,   // 0x00E0 (224) pixels
0xFF, 0xFF, 0x7F, 0x1F, 0x47, 0x33, 0x98, 0xCC, 0xE6, 0xF3, 0xF9, 0xFE, 0xFF, 0xFF, 0x3F, 0x07,   // 0x00F0 (240) pixels
0xC0, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0100 (256) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0110 (272) pixels
0xFF, 0xFF, 0xFC, 0xF0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x0120 (288) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0130 (304) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0140 (320) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x0F, 0x07, 0x03, 0x01, 0x01, 0x00,   // 0x0150 (336) pixels
0x00, 0x00, 0xC0, 0xF0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF3, 0xF7, 0xE6, 0x00,   // 0x0160 (352) pixels
0x33, 0xF9, 0xF0, 0x04, 0x0E, 0xCF, 0xEF, 0xE7, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0x00, 0x03,   // 0x0170 (368) pixels
0x03, 0x03, 0x07, 0x07, 0x0F, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0180 (384) pixels
0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0F, 0x1F,   // 0x0190 (400) pixels
0x3F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x1E, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x01A0 (416) pixels
0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF1, 0xC3,   // 0x01B0 (432) pixels
0x87, 0xCF, 0x9F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x01C0 (448) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x01D0 (464) pixels
0x00, 0x00, 0x3F, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0xDF, 0xCF, 0xEF, 0xE7, 0xB7, 0x33, 0x11, 0x30,   // 0x01E0 (480) pixels
0xC6, 0xC7, 0xE3, 0x10, 0x32, 0x17, 0x67, 0xAF, 0xCF, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00, 0x00,   // 0x01F0 (496) pixels
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0200 (512) pixels
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x0210 (528) pixels
0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x0220 (544) pixels
0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x01, 0xC1, 0xF1,   // 0x0230 (560) pixels
0x07, 0x3F, 0x0F, 0x87, 0x0C, 0x01, 0x0F, 0x7F, 0x1F, 0x0F, 0x07, 0x07, 0x07, 0x07, 0x0F, 0xFF,   // 0x0240 (576) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8, 0xF8, 0xF8, 0xF0,   // 0x0250 (592) pixels
0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0x00, 0x3E, 0x3C,   // 0x0260 (608) pixels
0x03, 0x8F, 0x01, 0x3C, 0x3E, 0x00, 0x83, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x70,   // 0x0270 (624) pixels
0xF0, 0xF0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0280 (640) pixels
0xFF, 0xF8, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   // 0x0290 (656) pixels
0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0xE0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0x7E, 0x7C,   // 0x02A0 (672) pixels
0x3C, 0x3C, 0x3C, 0x78, 0x78, 0xF1, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF3, 0xE7,   // 0x02B0 (688) pixels
0xF0, 0xF8, 0xF0, 0xF3, 0xF8, 0xF8, 0xFC, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xFF,   // 0x02C0 (704) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x02D0 (720) pixels
0x80, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0x63, 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x08, 0x00,   // 0x02E0 (736) pixels
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8B, 0xFF, 0xFF, 0x3F, 0x39, 0x78, 0xF8, 0xF8, 0x60, 0x00,   // 0x02F0 (752) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0300 (768) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC, 0xFC, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFC,   // 0x0310 (784) pixels
0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xE7, 0xCF, 0x9F, 0x3F, 0x3F, 0x7F, 0x7F, 0xFF,   // 0x0320 (800) pixels
0xF8, 0xE3, 0xCF, 0xBF, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0330 (816) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x9F, 0xCF, 0xE3, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF,   // 0x0340 (832) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0350 (848) pixels
0xFF, 0xFC, 0xF9, 0xF3, 0xE7, 0xCE, 0xDE, 0x9C, 0xB9, 0x33, 0x67, 0x87, 0x0F, 0x4F, 0x8F, 0x8F,   // 0x0360 (864) pixels
0x8E, 0x8E, 0x8E, 0x8E, 0x07, 0x87, 0xF3, 0x79, 0x7D, 0x3E, 0x9F, 0xCF, 0xE7, 0xF3, 0xF8, 0xFE,   // 0x0370 (880) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0380 (896) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0390 (912) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE,   // 0x03A0 (928) pixels
0xFE, 0xFC, 0xFC, 0xFC, 0xFD, 0xF8, 0xFA, 0xF8, 0xF8, 0xF9, 0xF9, 0xFD, 0xF9, 0xF9, 0xF9, 0xF9,   // 0x03B0 (944) pixels
0xF9, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x03C0 (960) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x03D0 (976) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF9, 0xF8, 0xF0, 0xF1,   // 0x03E0 (992) pixels
0xF1, 0xF1, 0xF1, 0xF8, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x03F0 (1008) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0400 (1024) pixels
};

 

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

andriano пишет:
Так как никакой конструктивной критики моей идеи по использованию кириллицы в Ардуино не последовало

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

Пока с меня только вопросы:

Цитата:
последствия могут быть непредсказуемы.

фильтровать входящее, все недопустимое отбрасывать.

Цитата:
какой вариант удобнее

Второй удобнее, т.к. нагляднее. Кстати, как насчет объединенных строк, типа LD.printStringSmall("Темп. =", temp, "°"); ?

Цитата:
и четыре прочих символа
Чем вызвано ограничение в 4? Да, раз есть градус, то можно и стрелку вверх и вниз (часто нужно тренд - повышение и понижение). Параграф и мю врядли пригодятся.

Библиотека толко текст отображает? Без линий и прямоугольников красивое меню сложно будет нарисовать. Может просто взять этот кусок из тех библиотек? (моему минимализму достаточно только прорисовки горизонтальных линий "от ... и до ...").

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Спасибо за конструктивную критику.

Tomasina пишет:
фильтровать входящее, все недопустимое отбрасывать.

А нужно ли это?

Компьютер с 32 Кбайтами ROM и 2 Кбайтами RAM в принципе неспособен отобразить всю таблицу utf-8. Приходится ограничиваться чем-то существенно меньшим.

Кроме того, это две совершенно разные задачи:

- обрабатывать произвольные ВНЕШНИЕ данные,

- обрабатывать заранее заданный набор ВНУТРЕННИХ данных.

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

Цитата:
Чем вызвано ограничение в 4?

Волюнтаризм в чистом виде. Можно добавить любое количество (пока их общее число не превысит 255), но каждый будет стоить довольно много памяти, т.к. помимо 5 байт в знакогенераторе на каждый дополнительный символ требуется отдельная ветка в коде.

Цитата:
Второй удобнее, т.к. нагляднее. Кстати, как насчет объединенных строк, типа LD.printStringSmall("Темп. =", temp, "°"); ?

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

Цитата:
Да, раз есть градус, то можно и стрелку вверх и вниз (часто нужно тренд - повышение и понижение). Параграф и мю врядли пригодятся.

Кому нравится поп, а кому - попадья.

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

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

Цитата:
Библиотека толко текст отображает? Без линий и прямоугольников красивое меню сложно будет нарисовать. Может просто взять этот кусок из тех библиотек? (моему минимализму достаточно только прорисовки горизонтальных линий "от ... и до ...").

Только текст и вертикальные линии.

Фактически в условиях Arduino может быть только два типа библиотек для подобного дисплея:

1. Допускают попиксельную графику, в частности позволяет рисовать произвольные линии, окружности и т.п. В частности, позволяют вывести букву в любом месте экрана. Отжирают более 2/3 всей доступной оперативной памяти.

2. Позволяют рисовать только символы (и только по сетке в 8 пикселей по вертикали) и вертикальные линии. Имеют довольно скромные запросы по оперативной памати.

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

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

Моя библиотека рассчитана именно на 2-й вариант.

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

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

фиг с ней, это графикой. А будет возможность программно задавать несколько пользовательских символов (как это сделало в библиотеках для текстовых LCD), т.е. без правки библиотечных файлов?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А какой смысл в этих нескольких порльзовательских символах?

И каким образом Вы предлагаете их задавать?

Если Вы знаете, как их нарисовать, не будет ли проще добавить их в существующий знакогенератор (т.е. путем правки библиотеки)?

И еще: должны ли им соответствовать какие-либо utf-8 коды, или основная мысль как раз отображать символы, не имеющие utf-8 кодов?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Немного подрихтовал библиотечку.

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

Демонстрационная программа:

#include <Wire.h>

#include "ASOLED.h"

#include "mice.c"

static const unsigned char PROGMEM Logo_BMP[] =
{ 0x10, 0x10, 0xff, 0x01,
  B00000000,  B00000001,  B00000001,  B00000011,  B11110011,  B11111110,  B01111110,  B00110011,
  B00011111,  B00001101,  B00011011,  B00111111,  B00111111,  B01111100,  B01110000,  B00000000,
  B11000000,  B11000000,  B11000000,  B11100000,  B11100000,  B11111000,  B11111111,  B10011111,
  B11111100,  B01110000,  B10100000,  B11100000,  B11110000,  B11110000,  B01110000,  B00110000 };

const uint8_t pacman[] PROGMEM={
  0x14, 0x18, 0x00, 0x01,
0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x3E, 0x1C,   // 0x0010 (16) pixels
0x0C, 0x00, 0x00, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x00, 0x00, 0x00, 

0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7C,   // 0x0010 (16) pixels
0x7C, 0x38, 0x20, 0x00, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9,   // 0x0020 (32) pixels
0xF9, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, 0x00, 

0x80, 0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFC,   // 0x0010 (16) pixels
0xF8, 0xF0, 0xE0, 0x80, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,   // 0x0020 (32) pixels
0xFF, 0xFF, 0xFF, 0xFF, 0xFB, 0xF9, 0x79, 0x19, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x0F,   // 0x0030 (48) pixels
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 
};   

const uint8_t pacman_clear[] PROGMEM={
  0x03, 0x18, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

const uint8_t pill[] PROGMEM={
  0x05, 0x08, 0x00, 0x01,
0x0E, 0x1F, 0x1F, 0x1F, 0x0E, 
};
 
int State = 0;
long NewTime, OldTime;

void setup()
{
  OldTime = millis();
  LD.init();  //initialze OLED display
  LD.clearDisplay(); 
}


void loop()
{
  int n0 = 123;
  int n1 = -321;
//  byte i;
  float d0 = 456.789;
  float d1 = -0.00789;
  NewTime = millis();
  if ((NewTime - OldTime) > 5000)
  {
    OldTime = NewTime;
    State = ++State % 6;
    LD.clearDisplay();
  }
  byte phase = NewTime/150%4;
  if (phase == 3) phase = 1;
  byte Xpacman = (NewTime-OldTime)/50 + 8;
//  State = 5;
  switch (State)
  {
    case 0:
        LD.printString_6x8("0123456789!\"#$%&'()*+", 0, 0);
        LD.printString_6x8(",-./:;<=>?@[\\]^_`{|}~", 0, 1);
        LD.printString_6x8("ABCDEFGHIJKLMNOPQRSTU", 0, 2);
        LD.printString_6x8("VWXYZabcdefghijklmnop",0, 3);
        LD.printString_6x8("qrstuvwxyzАБВГДЕЁЖЗИЙ", 0, 4);
        LD.printString_6x8("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ", 0, 5);
        LD.printString_6x8("Яабвгдеёжзийклмнопрст", 0, 6);
        LD.printString_6x8("уфхцчшщъыьэюяЇїЎў§°±µ", 0, 7);
        break;
    case 1:
        LD.printString_12x16("012345%&'+", 0, 0);
        LD.printString_12x16("ABCDEFGHIJ", 0, 2);
        LD.printString_12x16("vwxyzАБВЕЁ", 0, 4);
        LD.printString_12x16("юяЇїЎў§°±µ", 0, 6);
        break;
    case 2:
        for (int i = 0; i < 128; i++){
          int j = (int)(sin(i*0.09 + 0.2)*35) + 45;
          LD.VertBar(i, j, 0, 90);
        }
        break;
    case 3:
        LD.printNumber((long)n0, 0, 0);  // 123
        LD.printNumber((long)n1, 0, 2); // -321
        LD.printNumber(d0, 6, 60, 2);     // 456.789
        LD.printNumber(-d0, 6, 48, 0);   // -456.789
        LD.printNumber(d1, 8, 0, 6);     // 0.00789
        LD.printNumber((long)10, 28, 4);        // 10
        LD.printString_6x8("3"); //, 0, 4);  // ^3
        LD.printString_12x16("="); //, 0, 4); // =
        LD.printNumber((long)1000); //, 0, 4);  // 1000
        break;
    case 4 :
        LD.drawBitmap(mice, 0, 0, 128, 8);
        break;
    case 5 :
        for(byte i = 0; i < 5; i++)
          if (i*24 > Xpacman)
            LD.drawBitmap(pill,  26 + i*24, 1, 5, 1);
        LD.drawBitmap(pacman_clear,  Xpacman-3, 0, 3, 2);
        LD.drawBitmap(&pacman[phase*60],  Xpacman, 0, 20, 3);
        LD.drawBitmap(Logo_BMP, 100, 6); //, 16, 2);
        LD.printString_6x8("Small ", 0, 4);  // ^3
        LD.printNumber((long)n0);  // 123
        LD.printNumber(-d0);   // -456.789
        LD.printString_12x16("Big ", 0, 6); // =
        LD.printNumber((long)n0);  // 123
        break;
  }
}

Заголовочный файл (ASOLED.h):

/*
  ASOLED.h - 0.96' I2C 128x64 OLED Driver Library
  ver. 0.2a

  2015 Copyright (c) Sergey Andrianov

  Please, do not distribute this library. 
  It is not ready yet. Work is not complete. 
  It is a preliminary variant exceptionally for testing.
*/

#ifndef ASOLED_data_H
#define ASOLED_data_H

#include <Arduino.h>

#define ASOLED_Max_X				128	//128 Pixels
#define ASOLED_Max_Y				64	//64  Pixels

#define OLED_ADDRESS				0x3C // 0x78
#define I2C_400KHZ					1	// 0 to use default 100Khz, 1 for 400Khz

#define Font_6x8            1
#define Font_12x16          2


class ASOLED {

public:
  void init();
  void setFont(const char font); // set current font size (CurrFont) [Font_6x8 | Font_12x16]
	void printString(const char *String, byte X=255, byte Y=255);  // Current font
	void printString_6x8(const char *String, byte X=255, byte Y=255);  // font 6x8, switch CurrFont to Font_6x8
  void printString_12x16(const char *String, byte X=255, byte Y=255);  // font 12x16, switch CurrFont to Font_12x16

	byte printNumber(long n, byte X=255, byte Y=255); // current font
	byte printNumber(float float_num, byte prec=6, byte Y=255, byte numChar=255); // current font
	void drawBitmap(const byte *bitmaparray, byte X, byte Y, byte width, byte height); // X - in 1 pixel, Y - in 8 pixels
  void drawBitmap(const byte *bitmaparray, byte X, byte Y); // X - in 1 pixel, Y - in 8 pixels unit

	void VertBar(int Num, int Val, int MinVal, int MaxVal); // draw vertical line from bottom, h ~ (Val - MinVal)/(MaxVal - MinVal)

	void clearDisplay();
	
	void setNormalDisplay();
	void setInverseDisplay();
	void setBrightness(byte Brightness);

  void setCursorXY(byte Column, byte Row); // X * 1 pixels, Y * 8 pixels
  byte GetCurrentX();  // get current X position in 1-pixel unit (from 9 to 127)
  byte GetCurrentY();  // get current Y position in 8-pixel unit (from 0 to 7)
private:
  void sendCommand(byte command);
  void sendData(byte Data);

  void printChar(char c);
  void setPowerOff();
  void setPowerOn();
  void setPageMode();
  void setHorizontalMode();

  byte addressingMode;

  char CurrFont = 1; // font size  [Font_6x8 | Font_12x16]
  char NumberString[16]; // 4 print numbers
  byte LenString = 0;   // current length of NumberString
  byte CurrX = 0;   // current position
  byte CurrY = 0;
};

extern ASOLED LD;  // ASOLED object 

#endif

Код библиотеки (ASOLED.cpp):

#include "ASOLED.h"
#include <Wire.h>
#include <avr/pgmspace.h>

#include "a_Small_Rus.c"

// registers
#define ASA_OLED_COMMAND_MODE        0x80
#define ASA_OLED_DATA_MODE        0x40

//==========================================================

unsigned char ASA_utf8_preliminary_byte = 0;

unsigned char RecodeUTF_ASA(unsigned char c)
{
	switch (c)
	{
	case (unsigned char)0xD0:
		ASA_utf8_preliminary_byte = c; // wait second byte
		return 255;
	case (unsigned char)0xD1:
		ASA_utf8_preliminary_byte = c; // wait second byte
		return 255;
  case (unsigned char)0xD2:
    ASA_utf8_preliminary_byte = c; // wait second byte
    return 255;
  case (unsigned char)0xC2:
    ASA_utf8_preliminary_byte = c; // wait second byte
    return 255;
	default:
		if(ASA_utf8_preliminary_byte == 0) // first half of ASCII table or nonsupported symbol
		{
			if((c >= ' ') && (c <= '~')) {
				return c;
			}else{
				return '*';
			}
		}
		else if(ASA_utf8_preliminary_byte == 0xD0) //
		{
			ASA_utf8_preliminary_byte = 0;
			if((c >= 144) && (c <= 191))	{
				return c - 17;
			} else if (c == 129) { // РЃ
				return 191;
      } else if (c == 131) { // Рѓ
        return 193;
      } else if (c == 132) { // Р„
        return 195;
      } else if (c == 134) { // Р†
        return 197;
      } else if (c == 135) { // Р‡
        return 199;
      } else if (c == 142) { // РЋ
        return 201;
			} else {
				return '*';
			}
		}
		else if(ASA_utf8_preliminary_byte == 0xD1) //
		{
			ASA_utf8_preliminary_byte = 0;
			if((c >= 128) && (c <= 143)){
				return c + 47;
			} else if (c == 145) { // С‘
				return 192;
      } else if (c == 147) { // С“
        return 194;
      } else if (c == 148) { // С”
        return 196;
      } else if (c == 150) { // С–
        return 198;
      } else if (c == 151) { // С—
        return 200;
      } else if (c == 158) { // Сћ
        return 202;
			} else {
				return '*';
			}
		}
    else if(ASA_utf8_preliminary_byte == 0xD2) //
    {
      ASA_utf8_preliminary_byte = 0;
      if (c == 144) { // Тђ
        return 203;
      } else if (c == 145) { // Т‘
        return 204;
      } else {
        return '*';
      }
    }
    else if(ASA_utf8_preliminary_byte == 0xC2) //
    {
      ASA_utf8_preliminary_byte = 0;
      if (c == 167) { // В§
        return 205;
      } else if (c == 176) { // В°
        return 206;
      } else if (c == 177) { // В±
        return 207;
      } else if (c == 181) { // Вµ
        return 208;
      } else {
        return '*';
      }
    }
		else {
			return '*';
		}
	}
}

// ====================== LOW LEVEL =========================

void ASOLED::sendCommand(byte command){
	Wire.beginTransmission(OLED_ADDRESS); // begin transmitting
	Wire.write(ASA_OLED_COMMAND_MODE);//data mode
	Wire.write(command);
	Wire.endTransmission();    // stop transmitting
}

void ASOLED::sendData(byte data){
	Wire.beginTransmission(OLED_ADDRESS); // begin transmitting
	Wire.write(ASA_OLED_DATA_MODE);//data mode
	Wire.write(data);
	Wire.endTransmission();    // stop transmitting
}

void ASOLED::printChar(char C){ // write to temp string for numbers
  NumberString[LenString++] = C;
  NumberString[LenString] = 0;
}

void ASOLED::printString_6x8(const char *String, byte X, byte Y){
  CurrFont = Font_6x8;
 	setCursorXY(X, Y);
	while(*String){
		unsigned char c = RecodeUTF_ASA(*String++);
		if (c != 255) {                   //			printChar6(c);
      sendData(0);
      for(byte i=0; i<5; i++)
        sendData(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4]));
      CurrX += 6;
		}
	}
}

unsigned int EnlardeByte2Word(char b)
{
	unsigned int d = 0;
	for (byte i = 0; i < 8; i++)
	{
		unsigned int e = (((unsigned int)b) & (1 << i)) << i;
		d = d | e | (e << 1);
	}
	return d;
}

void ASOLED::printString_12x16(const char *String, byte X, byte Y){
  CurrFont = Font_12x16;
  setCursorXY(X, Y);
  const char *String0 = String;
  unsigned int m = 0;
  byte tmpX = CurrX;
  while(*String){                               // print upper half of the string
    unsigned char c = RecodeUTF_ASA(*String++);
    if (c != 255)
    {
      if(tmpX < (ASOLED_Max_X - 2)) {
        sendData(0);
        sendData(0);
        tmpX += 2;
      }
      for(byte i=0; i<5; i++) {
        if(tmpX < (ASOLED_Max_X - 2)) {
          m = EnlardeByte2Word(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4]));
          sendData(lowByte(m));
          sendData(lowByte(m));
          tmpX += 2;
        }
      }
    } 
  }
  setCursorXY(CurrX, CurrY+1);
  while(*String0){                               // print lower half of the string
    unsigned char c = RecodeUTF_ASA(*String0++);
    if (c != 255)
    {
      if(CurrX < (ASOLED_Max_X - 2)) {
        sendData(0);
        sendData(0);
        CurrX += 2;
      }
      for(byte i=0; i<5; i++) {
        if(CurrX < (ASOLED_Max_X - 2)) {
          m = EnlardeByte2Word(pgm_read_byte(&SmallFont[(c-32)*(int)5 + i + 4]));
          sendData(highByte(m));
          sendData(highByte(m));
          CurrX += 2;
        }
      }
    } 
  }
  setCursorXY(CurrX, CurrY-1);
}

void ASOLED::printString(const char *String, byte X, byte Y)  // Current font
{
  if(CurrFont == Font_6x8)
    printString_6x8(String, X, Y);
  else
    printString_12x16(String, X, Y);
   
}

byte ASOLED::printNumber(long long_num, byte X, byte Y){
  LenString = 0;
	setCursorXY(X, Y);
	byte char_buffer[10] = "";
	byte i = 0;
	byte f = 0; // number of characters
	if (long_num < 0) {
		f++;
		printChar('-');
		long_num = -long_num;
	} 
	else if (long_num == 0) {
		f++;
		printChar('0');
    printString(&NumberString[0]); //, X, Y);
		return f;
	} 
	while (long_num > 0) {
		char_buffer[i++] = long_num % 10;
		long_num /= 10;
	}
	f += i;
	for(; i > 0; i--) 
		printChar('0'+ char_buffer[i - 1]);
  printString(&NumberString[0]); //, X, Y);
	return f;
}

byte ASOLED::printNumber(float float_num, byte prec, byte X, byte Y){
  LenString = 0;
	setCursorXY(X, Y);
// prec - 6 maximum
	byte num_int = 0;
	byte num_frac = 0;
	byte num_extra = 0;
	long d = float_num; // get the integer part
	float f = float_num - d; // get the fractional part
	if (d == 0 && f < 0.0){
		printChar('-');
		num_extra++;
		printChar('0');
		num_extra++;
		f *= -1;
    printString(&NumberString[0]);
    LenString = 0;
	}
	else if (d < 0 && f < 0.0){
		num_int = printNumber(d);  // count how many digits in integer part
    LenString = 0;
		f *= -1;
	}
	else{
		num_int = printNumber(d);  // count how many digits in integer part
    LenString = 0;
	}
	// only when fractional part > 0, we show decimal point
	if (f > 0.0){
		printChar('.');
		num_extra++;
    printString(&NumberString[0]); //, X, Y);
    LenString = 0;
		if (num_int + prec > 8) 
			prec = 8 - num_int;
    for (byte j=0; j<prec; j++){
      f *= 10.0;
      byte dd = f;
      printChar('0' + dd);
      f -= dd;
    }
    printString(&NumberString[0]);
    num_frac = prec;
	}
	return num_int + num_frac + num_extra;
}

void ASOLED::drawBitmap(const byte *bitmaparray, byte X, byte Y, byte width, byte height){
// max width = 128
// max height = 8
  for (int j = 0; j <  height; j++) {
    setCursorXY(X, Y + lowByte(j));
    for (byte i = 0; i < width; i++)    
      sendData(pgm_read_byte(bitmaparray + i + 4 + j*width));
  }
}

void ASOLED::drawBitmap(const byte *bitmaparray, byte X, byte Y){
  byte width  = pgm_read_byte(&bitmaparray[0]);
  byte height = pgm_read_byte(&bitmaparray[1])/8;
  for (int j = 0; j <  height; j++) {
    setCursorXY(X, Y + lowByte(j));
    for (byte i = 0; i < width; i++)    
      sendData(pgm_read_byte(bitmaparray + i + 4 + j*width));
  }
}

void ASOLED::VertBar(int Num, int Val, int MinVal, int MaxVal)
{
	if (Val < MinVal) Val = MinVal;            // consider that Val already scaled
	if (Val > MaxVal) Val = MaxVal;
	Val -= MinVal;
    for (int i = 0; i < 8; i++)              // go from high levels to low ones
	{
		setCursorXY(Num, i);
    int b;                                   // will calc this value for each columns (bars)
		int UpB = (MaxVal - MinVal)*(8-i)/8;
    if (Val <= UpB)                          // top boundary
		{
			int DownB = (MaxVal - MinVal)*(7-i)/8;
      if (Val >= DownB)                      // bottom boundary
      {                                      // Val are in this interval
				int j = (Val - DownB)*8/(UpB - DownB);
				int k = 0xFF00;
				b = (k >> j) & 0xFF;
			}
			else
			{
				b = 0;
			}
		}
		else
		{
			b = 0xFF;
		}
		sendData(b);
	}
  setCursorXY(0, 0);
}

// =================== High Level ===========================

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// commands
#define ASA_OLED_CMD_DISPLAY_OFF      0xAE
#define ASA_OLED_CMD_DISPLAY_ON     0xAF
#define ASA_OLED_CMD_NORMAL_DISPLAY   0xA6
#define ASA_OLED_CMD_INVERSE_DISPLAY    0xA7
#define ASA_OLED_CMD_SET_BRIGHTNESS   0x81

#define ASA_OLED_RIGHT_SCROLL       0x26
#define ASA_OLED_LEFT_SCROLL        0x27
#define ASA_OLED_SET_VERTICAL_SCROLL_AREA 0xA3
#define ASA_OLED_VERTICAL_RIGHT_SCROLL  0x29
#define ASA_OLED_VERTICAL_LEFT_SCROLL   0x2A
#define ASA_OLED_CMD_ACTIVATE_SCROLL    0x2F
#define ASA_OLED_CMD_DEACTIVATE_SCROLL  0x2E

#define HORIZONTAL_ADDRESSING 0x00
#define PAGE_ADDRESSING     0x02

#define Scroll_Left       0x00
#define Scroll_Right      0x01
#define Scroll_Up       0x02
#define Scroll_Down       0x03

#define Scroll_2Frames      0x07
#define Scroll_3Frames      0x04
#define Scroll_4Frames      0x05
#define Scroll_5Frames      0x00
#define Scroll_25Frames     0x06
#define Scroll_64Frames     0x01
#define Scroll_128Frames    0x02
#define Scroll_256Frames    0x03

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SSD1306 Commandset
// ------------------
// Fundamental Commands
#define ASA_DISPLAY_ALL_ON_RESUME	    	0xA4
// Addressing Setting Commands
#define ASA_MEMORY_ADDR_MODE	    		0x20
// Hardware Configuration Commands
#define ASA_SET_START_LINE    			0x40
#define ASA_SET_SEGMENT_REMAP	    		0xA0
#define ASA_SET_MULTIPLEX_RATIO		    	0xA8
#define ASA_COM_SCAN_DIR_DEC			0xC8
#define ASA_SET_DISPLAY_OFFSET    			0xD3
#define ASA_SET_COM_PINS	    			0xDA
#define ASA_CHARGE_PUMP   			0x8D
// Timing & Driving Scheme Setting Commands
#define ASA_SET_DISPLAY_CLOCK_DIV_RATIO		0xD5
#define ASA_SET_PRECHARGE_PERIOD		0xD9
#define ASA_SET_VCOM_DESELECT		    	0xDB

void ASOLED::init(){
	Wire.begin();
	// upgrade to 400KHz! (only use when your other i2c device support this speed)
	if (I2C_400KHZ){
		// save I2C bitrate (default 100Khz)
		byte twbrbackup = TWBR;
		TWBR = 12; 
	}
	
	setPageMode();	// default addressing mode
	clearDisplay();
	setCursorXY(0,0);
	
// Additional command
	LD.setPowerOff();
	LD.sendCommand(ASA_SET_DISPLAY_CLOCK_DIV_RATIO);
	LD.sendCommand(0x80);
	LD.sendCommand(ASA_SET_MULTIPLEX_RATIO);
	LD.sendCommand(0x3F);
	LD.sendCommand(ASA_SET_DISPLAY_OFFSET);
	LD.sendCommand(0x0);
	LD.sendCommand(ASA_SET_START_LINE | 0x0);
	LD.sendCommand(ASA_CHARGE_PUMP);
		LD.sendCommand(0x14);
	LD.sendCommand(ASA_MEMORY_ADDR_MODE);
	LD.sendCommand(0x00);
	LD.sendCommand(ASA_SET_SEGMENT_REMAP | 0x1);
	LD.sendCommand(ASA_COM_SCAN_DIR_DEC);
	LD.sendCommand(ASA_SET_COM_PINS);
	LD.sendCommand(0x12);
	LD.setBrightness(0xCF);
	LD.sendCommand(ASA_SET_PRECHARGE_PERIOD);
		LD.sendCommand(0xF1);
	LD.sendCommand(ASA_SET_VCOM_DESELECT);
	LD.sendCommand(0x40);
	LD.sendCommand(ASA_DISPLAY_ALL_ON_RESUME);
	LD.setNormalDisplay();
	LD.setPowerOn();
}

void ASOLED::setCursorXY(byte X, byte Y){
// Y - 1 unit = 1 page (8 pixel rows)
// X - 1 unit = 1 pixel columns
  if (X < 128)
    if ((X != CurrX) || (Y != CurrY)){
      sendCommand(0x00 + (X & 0x0F)); 		//set column lower address
      sendCommand(0x10 + ((X>>4)&0x0F)); 	//set column higher address
      sendCommand(0xB0 + Y); 					//set page address
      CurrX = X;
      CurrY = Y;
    }
}

void ASOLED::setFont(const char font)
{
  CurrFont = font;
}

void ASOLED::clearDisplay()	{
	for(byte page=0; page<8; page++) {	
		setCursorXY(0, page);     
		for(byte column=0; column<128; column++)  //clear all columns
			sendData(0);    
	}
	setCursorXY(0,0);
}


void ASOLED::setInverseDisplay(){
	sendCommand(ASA_OLED_CMD_INVERSE_DISPLAY);
}

void ASOLED::setNormalDisplay(){
	sendCommand(ASA_OLED_CMD_NORMAL_DISPLAY);
}

void ASOLED::setPowerOff(){
	sendCommand(ASA_OLED_CMD_DISPLAY_OFF);
}

void ASOLED::setPowerOn(){
	sendCommand(ASA_OLED_CMD_DISPLAY_ON);
}

void ASOLED::setBrightness(byte Brightness){
	sendCommand(ASA_OLED_CMD_SET_BRIGHTNESS);
	sendCommand(Brightness);
}

void ASOLED::setPageMode(){
	addressingMode = PAGE_ADDRESSING;
	sendCommand(0x20); 				//set addressing mode
	sendCommand(PAGE_ADDRESSING); 	//set page addressing mode
}

void ASOLED::setHorizontalMode(){
	addressingMode = HORIZONTAL_ADDRESSING;
	sendCommand(0x20); 				//set addressing mode
	sendCommand(HORIZONTAL_ADDRESSING); 	//set page addressing mode
}

ASOLED LD;  // Preinstantiate Objects


Остальные два файла (шрифт и демонстрационный битмап) остались без изменений, так что их можно взять из 5-го поста настоящей темы.

Советую досмотреть демонстрацию до крнца: хотя библиотека формально и не поддерживает графику, но...

alexgum
Offline
Зарегистрирован: 17.07.2015

Спасибо за ответ!

И спасибо за библиотеку! Библиотека понравилась, честно! Спасибо за Ваш труд!

Если позволите, скажу несколько слов про концепцию РУССКОГО ШРИФТА. Я по образованию инженер-электронщик, имею некоторый жизненный опыт и некоторые свои мысли по поводу развития РУССКОГО ПРОЕКТА АРДУИНО, с которыми хочу поделиться.

1) По моему мнению надо сделать революционное решение и перестать тащить за собой "БАБУШКИН САКВОЯЖ", который и выбросить жалко, и пользы от него с гулькин нос. Что я имею в виду? Предлагаю отказаться от полной поддержки кодировки ANSI в проекте РУССКОГО ARDUINO. ПОСЕМУ ПРЕДЛАГАЮ ПЕРЕПИСАТЬ ТАБЛИЦУ СИМВОЛОВ ПОД ПОТРЕБИТЕЛЬСКИЕ НУЖДЫ МАСТЕРОВ ПО ЭЛЕКТРОНИКИ И ВЫКИНУТЬ ИЗ ЭТОЙ ТАБЛИЦЫ ВСЕ ЗАГЛАВНЫЕ АНГЛИЙСКИЕ БУКВЫ, ЗАМЕНИВ ИХ НА ВОСТРЕБОВАННЫЕ СПЕЦИАЛИЗИРОВАННЫЕ СИМВОЛЫ ДЛЯ ИНДИКАЦИИ ДАТЧИКОВ И ИСПОЛНИТЕЛЬНЫХ УСТРОЙСТВ СТАНДАРТНЫМИ СРЕДСТВАМИ ШРИФТА. Предлагаю оставить только малые английские буквы исключительно только для совместимости и интернет шилдами.

2) Создать шрифтовые символы таких элементов как батарейка, термопара, солнечная панель, мотор, насос, реле, автомат, кнопка,  лампа, кран, звонок и т.д. Эти символы должны быть в двух графических видах - активный т.е.(включенный) и неактивный (выключенный). Можно использовать инверсию графического изображения, или еще что.

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

Вот такое мое предложение. Жду ваших коментариев.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

alexgum пишет:

Если позволите, скажу несколько слов про концепцию РУССКОГО ШРИФТА. Я по образованию инженер-электронщик, имею некоторый жизненный опыт и некоторые свои мысли по поводу развития РУССКОГО ПРОЕКТА АРДУИНО, с которыми хочу поделиться.

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

да и обязательно нужно прописать портрет ВВП. на каждом экране по центру что бы был.

alexgum
Offline
Зарегистрирован: 17.07.2015

А может не стоит тролить?!

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

alexgum пишет:

А может не стоит тролить?!

тролить? это вы про свои идеи? давайте прикинем...

с одной стороны, латиница и весь глобус разработчиков...

с вашей стороны, кирилица и 2 с половиной инвалида которым это нужно

нарисовать вы можете все что вам хочеться. вообще без ограничений..

alexgum
Offline
Зарегистрирован: 17.07.2015

Троль тем и отличается, что глобус. Если вам это не нужно - валите из темы в глобус разработчиков.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

alexgum пишет:

Троль тем и отличается, что глобус. Если вам это не нужно - валите из темы в глобус разработчиков.

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

Maverik
Offline
Зарегистрирован: 12.09.2012

да ладно, идея в общем-то здравая. 

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

кстати, интересно. только на мове hello world получается в рифму.  украинский- красивый язык ) 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Maverik пишет:
 

сильно сомневаюсь, что кто-то у нас пишет проекты "на весь глобус".  

вы не поверите :) но таки да пишут. и их много у нас есть.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

alexgum пишет:
Если позволите, скажу несколько слов про концепцию РУССКОГО ШРИФТА. Я по образованию инженер-электронщик, имею некоторый жизненный опыт и некоторые свои мысли по поводу развития РУССКОГО ПРОЕКТА АРДУИНО, с которыми хочу поделиться.

1) По моему мнению надо сделать революционное решение и перестать тащить за собой "БАБУШКИН САКВОЯЖ", который и выбросить жалко, и пользы от него с гулькин нос. Что я имею в виду? Предлагаю отказаться от полной поддержки кодировки ANSI в проекте РУССКОГО ARDUINO. ПОСЕМУ ПРЕДЛАГАЮ ПЕРЕПИСАТЬ ТАБЛИЦУ СИМВОЛОВ ПОД ПОТРЕБИТЕЛЬСКИЕ НУЖДЫ МАСТЕРОВ ПО ЭЛЕКТРОНИКИ И ВЫКИНУТЬ ИЗ ЭТОЙ ТАБЛИЦЫ ВСЕ ЗАГЛАВНЫЕ АНГЛИЙСКИЕ БУКВЫ, ЗАМЕНИВ ИХ НА ВОСТРЕБОВАННЫЕ СПЕЦИАЛИЗИРОВАННЫЕ СИМВОЛЫ ДЛЯ ИНДИКАЦИИ ДАТЧИКОВ И ИСПОЛНИТЕЛЬНЫХ УСТРОЙСТВ СТАНДАРТНЫМИ СРЕДСТВАМИ ШРИФТА. Предлагаю оставить только малые английские буквы исключительно только для совместимости и интернет шилдами.

Скажите, Вы, как инженер, пытались применять в своих проектах ну, скажем, резьюу диаметром 3.6 мм?

Существует такое понятик как стандарт и отход от него (в отсутствие совершенно исключительных причин, а личные амбиции к таковым не относятся) практически однозначно ведет в тупик.

Что касается отказа от латинницы, то, насколько мне известно, именно таковыми и были предыдущие проекты по русификации дисплеев: количество символов сохрянялось постоянным (как наследие ASCII) - 95 штук, но начертание латинницы заменялось на начертание кириллицы. В принципе, подход, имеющий право на существование, но весьма осложняющий процесс программирования, что, на мой взгляд, существенно противоречит идеям проекта Arduino.

Данный проект отличается именно тем, что:

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

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

Кроме того, с какой целью вообще отказываться от каких-то символов? Было 95, я добавил 80 с чем-то, даже до адресации одним байтом еще порядка 80 свободных номеров.

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

И еще: в среде одна кодировка кириллицы, а в консоли - другая. А латинница совпадает. Так что при отладке в консоли все равно альтернаоивы использованию латинницы нет.

Еще, кстати, на днях обнаружил, что Processing не поддерживает киоиллицу даже в IDE.

Так что причин для отказа от латинницы IMHO нет. Никаких.

Цитата:
2) Создать шрифтовые символы таких элементов как батарейка, термопара, солнечная панель, мотор, насос, реле, автомат, кнопка,  лампа, кран, звонок и т.д. Эти символы должны быть в двух графических видах - активный т.е.(включенный) и неактивный (выключенный). Можно использовать инверсию графического изображения, или еще что.

Вам нужны батарейкак, термопара, оеле, музыканту наверняка понадобятся ноты, водителю - дорожные знаки и т.д.

Все это хорошо, но почему для вывода пиктограмм нужно использовать именно оператор print, когда есть гораздо более подходящий drawBitmap? Вы же не собираетесь использовать длинные строки из символов батареек и реле? (кстати, в отличие от музыканта)

А если Вы запускали демонстрационный пример, то видели, что drawBitmap можно при желании применять даже для создании анимации.

Цитата:
3) Считаю, что в шрифт также необходимо добавить фукцию рисования таблиц, в ячейки которых можно раставлять буквенно - численные значения, а также в процессе наладки изделия, выводить матрицы и массивы.
В CP866 есть символы псевдографики, но, почему-то, ею уже давно не пользуются. Наверное, это не слишком большое преимущество.
Цитата:

Вот такое мое предложение. Жду ваших коментариев.

Мне Ваше предложение показалось не слишком продуманным.

alexgum
Offline
Зарегистрирован: 17.07.2015

Не согласен.

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

Но. Эта идея дает только некоторые преимущества, хоть и существенные, но они направлены для возможности, как говорил глобус, реализации проектов как англоязычным потребителям, так и русскоязычным потребителям. То есть и нашим и вашим. В этом подходе есть преимущества и недостатки. Да, существенно упрощается буквенный обмен, но скорость разработок существенно не меняется, так как надо каждый раз рисовать необходимые картинки, без возможности их масштабирования. Если же заменить ненужные в принципе для разработчика заглавные английские буквы наиболее распространенными символами, то процесс разработки существенно ускоряется, так как никто уже не тратит время на придумывание и реализацию картинного творчества.

Кроме того я несколько раз подчеркивал, что это революционное решение и направлено оно именно для развития РУССКОГО АНДРУИНО. Развитие же предполагает простоту и скорость програмной реализации идеи и несовместим с ппотерей времени на рисование необходимых символов и расчета координат их расположения на экране. Только вчера потерял два часа на реализацию на экране вида с символьно-графическим изображением в том представлении, в котором задумал. И сделал вывод - это крайне неудобно.

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

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

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

а что в ардуино русского ты предлагаешь? если убрать латинские символы и в вместо них добавить русские? но от этого русским он не станет)))

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

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

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

jeka_tm пишет:

а что в ардуино русского ты предлагаешь? если убрать латинские символы и в вместо них добавить русские? но от этого русским он не станет)))

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

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

Жень, дык это, цифры то АРАБСКИЕ остануться... че делать то?

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

Блин как будто нам было мало одного Клапауций...

jeka_tm
jeka_tm аватар
Offline
Зарегистрирован: 19.05.2013

точно. и от цифр придется отказаться)))

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

jeka_tm пишет:

точно. и от цифр придется отказаться)))

во блин. что бы там сразу совсем русская была ардуина

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

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

Процессоры из святых мощей не проблема. Спасибо за таблицу перекодировки в церковн-словянские, но остается вопрос отображения шеснадцетиричных. Местные попы не знают, кадилом угрожают. Как 0xff по православному выводить?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

alexgum пишет:

Не согласен.

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

Нет. Концепция состоит в создании библиотеки, которая строится на двух с половиной принципах:

"1". Ограниченная поддержка используемой в Arduino IDE кодировки utf-8 достаточная для русско-/украино-/белорусско-говорящего пользователя объеме.

"2". Компактность, т.е. минимум места занисаемого в оперативной и постоянной памати.

"Половинка". Учитывая весьма скромный размер дисплея, возможность писать шрифтом удвоенного размера с использованием существующего знакогенератора (с целью "2").

Цитата:
Но. Эта идея дает только некоторые преимущества, хоть и существенные, но они направлены для возможности, как говорил глобус, реализации проектов как англоязычным потребителям, так и русскоязычным потребителям. То есть и нашим и вашим. В этом подходе есть преимущества и недостатки. Да, существенно упрощается буквенный обмен, но скорость разработок существенно не меняется, так как надо каждый раз рисовать необходимые картинки, без возможности их масштабирования. Если же заменить ненужные в принципе для разработчика заглавные английские буквы наиболее распространенными символами, то процесс разработки существенно ускоряется, так как никто уже не тратит время на придумывание и реализацию картинного творчества.

Сомнительное преимущество. "Картинное творчество" - один из способов придания законченному изделию индивидуальности.

И потом, я решительно не вижу никаких доводов в пользу упразднения латинницы. Лично мне, например, латинница нужна. Гораздо больше, чем кириллица. Тем более, ВСЕХ проблем предложенная библиотека не решает, например, добиться, чтобы в коде и консоли кириллические тексты выглядели одинаково, все равно не получится. Повторяю, я занялся кириллизацией шрифта по стечению обстоятельств: ждал посылки из Китая с заказанным набором деталей. И за это время обнаружил, что приемлемого решения для кириллизации имеющегося у меня дисплея нет. Причем, написать ее не сложно, проблема в том, что тому, кто способен ее написать, она не нужна, а кто испытывает в ней насущную необходимость (новички), написать ее не способны.

Но в любом случае - идее искоренения латинницы - мое твердое НЕТ.

Цитата:
Кроме того я несколько раз подчеркивал, что это революционное решение и направлено оно именно для развития РУССКОГО АНДРУИНО.
В общем-то, - да. Поскольку немного облегчает жизнь новичкам. Т.е. способствует популяризации Ардуино в России.

Кстати, по-русски пишется "Ардуино". Не нужно пытаться скмбинировать эхотаг с моим ником. Мой ник никакого отношения к эхотагу не имеет - я под ним регистрируюсь на всех форумах.

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

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

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

Привязывать пиктограммы к символам - решение, имеющее целый ряд отрицательных свойств:

1. Новичку трудно разобраться во взаимоотношении  категорий "символ", "ко символа", "число". Если на это еще навесить отношение между символами и пиктограммами, он совершенно запутается. Поэтому лучше пусть выбирает пиктограммы не по коду символа, а по номеру - ему это будет понятнее.

2. На знакоместо у меня отводится 6 пикселов по ширине. А ширина символа в знакогенераторе - 5 пикселов (для экономии): один вертикальный ряд пикселов всегда оставтся пустым и разделяет символы между собой. Для пиктограммы, думаю, это неудобно.

3. Опять же, символ имеет фиксированный размер 5х8, а для пиктограммы может понадобиться большее, например, 8х8, 12х8 или 24х16. Нет смысла ограничивать ее размер форматом символа.

Поэтому я предлагаю следующее решение.

Я усовершенствую drawBitmap, чтобы она могла работать не только с отдельными картинками, но и с целыми библиотеками картинок одинакового размера, будь то набор пиктограмм или несколько кадров анимации для одного (или нескольких) объектов.

Мы с Вами согласовываем формат библиотеки. И Вы занимаетесь уже только библиотеками пиктограмм.

Каждый делает свою работу и все довольны.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Puhlyaviy пишет:
а что делать тем у кого другие дисплеи? другие контролеры? они будут не русскими? как им жить дальше то?

Вопрос резонный.

Но вспомните собственную дату регистрации на форуме и посмотрите на мою - это я еще зарегистрировался за несколько дней до покупки первого контроллера.

Так что я пока не представляю всего разнообразия моделей Ардуино (и родственных проектов) и особенностей их взаимодействия с периферией. Да и в ближайшее время не стремлюсь разобраться - мне бы с Uno освоиться... Знаю только, что особенности есть (если судить по коду просмотренных мною библиотек).

Аналогично с многообразием используемых а Ардуино-проектах дисплеев. Мне OLED понравился тем, что безусловно контрастный и жрет мало электричества. Разбираться с другими начну не раньше, чем они мне понадобятся (хотя пара формата 16х2 символов в запасе имеется).

Но если кому надо - готов оказать содействие.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

andriano пишет:

Puhlyaviy пишет:
а что делать тем у кого другие дисплеи? другие контролеры? они будут не русскими? как им жить дальше то?

Вопрос резонный.

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Puhlyaviy пишет:
это был риторический вопрос...
А я сделал вид, что этого не понял.
Цитата:
...дело не благодарное и сильно безсмысленное.
Я же написал: "Разбираться с другими начну не раньше, чем они мне понадобятся".

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

andriano пишет:

Я же написал: "Разбираться с другими начну не раньше, чем они мне понадобятся".

Вот в этом как раз и проблема. Большинство ( ака товарищ просящий прибить латиницу), не впиливают что все библиотеки, шрифты и железо, сделаны для решения вопросов разработчика. И в большинстве случаев представляет из себя набор костыликов который хоть как то но работает и решает узко поставленую задачу.. И что никто не собираеться перерабатывать эту кучу костыликов что бы кому то там еще стало приятно... :)

alexgum
Offline
Зарегистрирован: 17.07.2015

Согласен.

Давайте подумаем как это сделать. Только вот с масшабированием и форматом 5х8, или 6х9 иконок я бы подумал. Хоть они и масипусинькие, но если испоьлзовать их как колонтиум с последующим увеличением в два раза, то будет стильно. И еще вопрос, можно увеличить шрифт в четыре раза? Этакий SyperBig? Это даст еще больший прирост творчества. :)

alexgum
Offline
Зарегистрирован: 17.07.2015

Вот в этом как раз и проблема. Большинство ( ака товарищ просящий прибить латиницу)

Тамбовский волк тебе товарищъ. Даже не сомневаюсь, что у тебя, деревня все работает через кол да бревно. Лично у меня все шепчет как швейцарские часики. Видно, что у тебя опыта маловато и способностей никаких для творчества, потому ты и отираешься на форумах для подбирания чужих идей и кодов.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

alexgum пишет:

Вот в этом как раз и проблема. Большинство ( ака товарищ просящий прибить латиницу)

Тамбовский волк тебе товарищъ. Даже не сомневаюсь, что у тебя, деревня все работает через кол да бревно. Лично у меня все шепчет как швейцарские часики. Видно, что у тебя опыта маловато и способностей никаких для творчества, потому ты и отираешься на форумах для подбирания чужих идей и кодов.

и что же вы не поделились с сообществом своим шепотом швейцарских часиков? Где оно? где ваши библиотеки разработаные с нуля?

alexgum
Offline
Зарегистрирован: 17.07.2015

Puhlyaviy пишет:

alexgum пишет:

Вот в этом как раз и проблема. Большинство ( ака товарищ просящий прибить латиницу)

Тамбовский волк тебе товарищъ. Даже не сомневаюсь, что у тебя, деревня все работает через кол да бревно. Лично у меня все шепчет как швейцарские часики. Видно, что у тебя опыта маловато и способностей никаких для творчества, потому ты и отираешься на форумах для подбирания чужих идей и кодов.

и что же вы не поделились с сообществом своим шепотом швейцарских часиков? Где оно? где ваши библиотеки разработаные с нуля?

Я же говорил. Пасется деревня на халяву. А сам то всех халявщиками обзывает, халявщик.

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

alexgum пишет:

Я же говорил. Пасется деревня на халяву. А сам то всех халявщиками обзывает, халявщик.


Сходите в наш деревенский проект и попробуйте найти в нем что нибудь с форума.
http://arduino.ru/forum/proekty/vklyuchatel-vyklyuchatel-s-mozgom-i-orga...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

alexgum пишет:

Согласен.

Давайте подумаем как это сделать. Только вот с масшабированием и форматом 5х8, или 6х9 иконок я бы подумал. Хоть они и масипусинькие, но если испоьлзовать их как колонтиум с последующим увеличением в два раза, то будет стильно. И еще вопрос, можно увеличить шрифт в четыре раза? Этакий SyperBig? Это даст еще больший прирост творчества. :)

Иконок 6х9 в данном проекте не будет никогда. Т.к. для этого необходим экранный буфер, что явно противоречит идее минимизации расхода оперативной памяти.

Поэтому все вертикальные размеры кратны 8.

Идея масштабировать иконки мне как-то не нравится. Смволов - около 170, используешь ты их или нет, они занимают чуть меньше Кбайта, а если использовать "родной" шрифт 12х16, это потянет килобайта на 3.5. А иконок в проекте от 0 до ... ну, максимум, десятка. Ну пойдет на все про все 1/4 Кбайта - зато края будут не зазубренные.

Шрифт в принципе можно увеличить и в 4 и в 8 раз. В первом случае будет 2 строки по 5 символов, во втором - 2 символа на весь экран. Оно кому-то надо?

В принципе, можно было бы написать универсальную процедуру, масштабирующую фонт в заданное количество раз, но... сейчас в библиотеке строка удвоенного шрифта выводится не посимвольно, а сначала вся верхняя половина строки, а потом - вся нижняя. Сделано это с точки зрения оптимизации по времени. Даже при работе I2C на частоте 400 КГц заполнение экрана при условии оптимального программирования занимает примерно 120 мс. Если допускать неоптимальность - время возрастает в 3-4 раза. Каждая из половин строки выводится своей процедурой. Если строка будет делиться по вертикали на 4 части, это усложнит логику работы, увеличит объем кода... да и степень угловатости шрифта превысит разумные пределы.

В общем, ничего бесплатного не бывает. Особенно в системах со столь ограниченным объемом памяти. Поэтому я думаю, что попытка "повысить универсальность", вероятнее всего, пойдет во вред.

Во всем необходимо соблюдать баланс. Правда, сам баланс может быть разным, особенно для двух разных классов проектов:

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

- проекты, в которых основная роль выполняется моторами, приводами, датчиками, а экран играет роль лишь вспомогательного индикатора.

Так вот, моя библиотека сбалансирована именно для второго типа задач.

Tekasijimo
Offline
Зарегистрирован: 06.08.2015

Здравствуйте! andriano. Собрал вашу библу, и попробывал в своем проекте. Пользорватся действительно удобнее но возникла сложность...

Суть в этом кусочке кода. 

      byte s = ((time - previousMillis) / 1000ul) % 60;
      byte m  = (((time - previousMillis) / 1000ul) / 60ul) % 60;
      if (s > 0 || m > 0)

Не компилируется когда вывожу на дисплей потому как ругается на невозможность конвертации типов.

Хотя с библиотекой adafruit_gfx работает без проблем. Но в ней нет русского... 

Так вот у меня вопрос, возможно ли добавить возможность работать к BYTE как со STRING?

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

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

как временный костыль: 

byte s = ((time - previousMillis) / 1000UL) % 60;
byte m  = (((time - previousMillis) / 1000UL) / 60ul) % 60;
if (s > 0 || m > 0)
  {
    LD.printString_6x8((String)m, 0, 4);
    LD.printString_6x8((String)s, 10, 4);
  }
NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Недавно получил SSD1306(OLED 128x64) - подключил, залил - работает.

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

Аналогично. Только либа OLED_I2C - чёто с чемто! отжирает 1к RAM под буфер, запрещает прерывания, и содержит кучу лишнего кода, например поддерживая програмный и аппаратный i2c в одной сборке.

Пришлось переписать, попутно разделив на два класса.

Один дает вывод текста без графики и буферов. Разные шрифты и масштабирование. По вертикали выравнивание текста постраничное.

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

Ещё скролинг прилепить интересно.

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

а причем тут либа OLED_I2C?    У andriano вроде либа зовется ASOLED.

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

см. вторую сылку стартоврго поста.

diger67
Offline
Зарегистрирован: 25.07.2015

andriano пишет:

Кириллица на дисплее или что я делаю не так?

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

http://lesson.iarduino.ru/page/urok-8-russkiy-yazyk-na-oled-displee-128x64/

http://arduino-project.net/russkie-ukrainskie-shrifty-oled-i2c/

предлагают использовать ее следующим образом.
Допустим, все библиотеки, шрифты и т.п. скачаны и установлены, переходим к программированию.
Скажем, нужно вывести на экран фразу "Моя Arduino сгорела.". Оказывается, что просто так это сделать нельзя. Следует:
- установить русский фонт,
- вывести "Моя " с нужного места экрана,
- теперь переключить фонт на английский,
- посчитать, сколько символов занимает первая надпись,
- вывести строку с учетом указанного смещения,
- вывести строку "Arduino ",
- снова переключить фонт - обратно на русский,
- снова посчитать смещение,
- вывести "сгорела."

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

То есть это должно выглядеть примерно так:
 

  myOLED.setFont(RusFont);
  myOLED.print("Vjz ", 0, 3); // Выводим надпись "Моя "
  myOLED.setFont(LatFont);
  myOLED.print("Arduino ", 4, 3); // Выводим надпись "Arduino "
  myOLED.setFont(RusFont);
  myOLED.print("cujhtkf/", 12, 3); // Выводим надпись "сгорела."

Я лично делаю так:
 

        LD.printString6("0123456789!\"#$%&'()*+", 0, 0, 21);
        LD.printString6(",-./:;<=>?@[\\]^_`{|}~", 0, 1, 21);
        LD.printString6("ABCDEFGHIJKLMNOPQRSTU", 0, 2, 21);
        LD.printString6("VWXYZabcdefghijklmnop",0, 3, 21);
        LD.printString6("qrstuvwxyzАБВГДЕЁЖЗИЙ", 0, 4, 21);
        LD.printString6("КЛМНОПРСТУФХЦЧШЩЪЫЬЭЮ", 0, 5, 21);
        LD.printString6("Яабвгдеёжзийклмнопрст", 0, 6, 21);
        LD.printString6("уфхцчшщъыьэюяЇїЎў§°±µ", 0, 7, 21);

и получаю на экране:

При этом моя IDE, как и положено, работает в utf-8.

Что я делаю неправильно?

Все гараздо проще. Идем в настройки IDE arduino, меняем значение "preproc.substitute_unicode=false", сохраняем. Потом создаем файл фонт на 255 символов беря за основу таблицу windows cir. Пользуемся. Любят русские люди создавать себе проблеммы. А все гараздо проще. у меня так работает с библиотекой для tft от adafruit.

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

diger67 пишет:

Все гараздо проще. Идем в настройки IDE arduino, меняем значение "preproc.substitute_unicode=false", сохраняем. Потом создаем файл фонт на 255 символов беря за основу таблицу windows cir. Пользуемся. Любят русские люди создавать себе проблеммы. А все гараздо проще. у меня так работает с библиотекой для tft от adafruit.

Похоже не все там так просто. И не от библиотеки зависит.

Вы имеете в виду файл ..\arduino-ххх\lib\preferences.txt и строки в нем должны выглядеть так

# auto-convert non-ascii chars to unicode escape sequences
preproc.substitute_unicode = false

Я и ранее пробовал так делать, и сейчас попробовал ещё раз. Не помогает.

Строка в скетче TestOLED выглядит

myOLED.drawString(1,1,"П",2);

в файле TestOLED.cpp после преобразования

myOLED.drawString(1,1,"\u041f",2);

Как видим опция не отключилась и символ конвертировался. IDE перезапускал конечно.

И на экране получаетсядва символа вида "Pf"

На какой версии у Вас работает? Я пробовал на версии 1.0.6.

Сам решил проблему так. Делаю файл, например resorce.inc, в него пишу в блокноте в кодировке Windows типа  #define RUS_TEXT "краказябры! ". В скетче #include "resorce.inc" и может потребоватся путь указать. В нужном месте   myOLED.drawString(5,7,RUS_TEXT,0); Все нормалек, до "resorce.inc" препроцессор не дотягивается.

diger67
Offline
Зарегистрирован: 25.07.2015

Возможно вы вносите изменеия в файл preferences не выходя из IDE arduino. В таком случае изменения не сохраняются. Если у вас контролер tft из списка поддерживаемых библиотекой adafruit, скачайте у меня библиотеку и файл фонт http://178.130.34.198/adafruit

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

diger67 пишет:

Все гараздо проще. Идем в настройки IDE arduino, меняем значение "preproc.substitute_unicode=false", сохраняем. Потом создаем файл фонт на 255 символов беря за основу таблицу windows cir. Пользуемся. Любят русские люди создавать себе проблеммы. А все гараздо проще. у меня так работает с библиотекой для tft от adafruit.

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

В общем, для меня вопрос стоял только так: "с неизменными настройками IDE".

diger67 пишет:

Возможно вы вносите изменеия в файл preferences не выходя из IDE arduino. В таком случае изменения не сохраняются.

Вообще-то из вашей формулировки "Идем в настройки IDE arduino, меняем значение..." седует, что как раз, не выходя из IDE.

 

PS. Да, я тут пока отлаживал обмен по I2C между двумя Arduino, выяснил, что я все-таки реализовал не самый быстрый способ вывода на экран. Так что, когда дойдут руки, попытаюсь заметно ускорить вывод текста.

diger67
Offline
Зарегистрирован: 25.07.2015

andriano пишет:

diger67 пишет:

Все гараздо проще. Идем в настройки IDE arduino, меняем значение "preproc.substitute_unicode=false", сохраняем. Потом создаем файл фонт на 255 символов беря за основу таблицу windows cir. Пользуемся. Любят русские люди создавать себе проблеммы. А все гараздо проще. у меня так работает с библиотекой для tft от adafruit.

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

В общем, для меня вопрос стоял только так: "с неизменными настройками IDE".

diger67 пишет:

Возможно вы вносите изменеия в файл preferences не выходя из IDE arduino. В таком случае изменения не сохраняются.

Вообще-то из вашей формулировки "Идем в настройки IDE arduino, меняем значение..." седует, что как раз, не выходя из IDE.

 

PS. Да, я тут пока отлаживал обмен по I2C между двумя Arduino, выяснил, что я все-таки реализовал не самый быстрый способ вывода на экран. Так что, когда дойдут руки, попытаюсь заметно ускорить вывод текста.

Менять настройки IDE можно и не выходя, а вот сохранять только выйдя из IDE. Предлогаемая настройка среды разработки подразумевает только допустимость использовать стандартный набор ACII кодировки, т.е. беззнаковое 255 символов таблица. На скетчи, их содержимое и компиляцию воздействия не производит.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

diger67 пишет:
Предлогаемая настройка среды разработки подразумевает только допустимость использовать стандартный набор ACII кодировки, т.е. беззнаковое 255 символов таблица. На скетчи, их содержимое и компиляцию воздействия не производит.

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

PS. Кстати, "стандартный набор ACII кодировки" - это 128 символов (из которых 33 служебных), а не 255.

diger67
Offline
Зарегистрирован: 25.07.2015

Посмотрти вот эту статью по руссификации

http://robocraft.ru/blog/892.html   .

Joiner
Offline
Зарегистрирован: 04.09.2014

diger67 пишет:

Посмотрти вот эту статью по руссификации

http://robocraft.ru/blog/892.html   .

Ошибка: 404

К сожалению, такой страницы не существует. Вероятно, она была удалена с сервера, либо ее здесь никогда не было.

Вернуться назадперейти на главную