Имитация различных шкал на дисплее 128*64

lilik
Offline
Зарегистрирован: 19.10.2017

При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)

И их тоже как то надо выбирать сообразно фигурам.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

lilik пишет:

с заметной глазу отрисовкой экрана

Через Wire так и должно быть - Вы на каждый байт команды или данных организуете:

Старт - Байт признака команды/данные - Сам байт - Стоп (Избыточность около х3)

В эти дисплеи нужно слать ИНАЧЕ (если аппаратную прокрутку не используем-команды только для инициализации дисплея):

Старт - Байт признака команды - ВСЕ БАЙТЫ КОМАНД подряд - Стоп

Старт - Байт признака данные - ВСЕ БАЙТЫ ДАННЫХ ... ... ... 

Стоп уже не нужен.

p.s. Сама Wire имеет буфер :-)

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

lilik пишет:

При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)

И их тоже как то надо выбирать сообразно фигурам.

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

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

lilik пишет:

При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)

А что, "различные одновременные комбинации фигур" - это обязательно для данного проекта?

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

Цитата:

И их тоже как то надо выбирать сообразно фигурам.

Да - для каждого проекта свои примитивы. Не нужно только пытаться создать единые примитивы универсальные для всех проектов одновременно. Ну не будут они все на одном экране. Сам формат 128х64 этого не позволяет.

lilik
Offline
Зарегистрирован: 19.10.2017

Komandir пишет:

lilik пишет:

с заметной глазу отрисовкой экрана

Через Wire так и должно быть - Вы на каждый байт команды или данных организуете:

Старт - Байт признака команды/данные - Сам байт - Стоп (Избыточность около х3)

В эти дисплеи нужно слать ИНАЧЕ (если аппаратную прокрутку не используем-команды только для инициализации дисплея):

Старт - Байт признака команды - ВСЕ БАЙТЫ КОМАНД подряд - Стоп

Старт - Байт признака данные - ВСЕ БАЙТЫ ДАННЫХ ... ... ... 

Стоп уже не нужен.

p.s. Сама Wire имеет буфер :-)

Попробовал вот так для основного блока (как мне кажется сообразно предлагаемой логике) - не работает.

///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
  /////////////////////

 oledCommand(0x21);//установка столбца
 oledCommand(0);//Начальный столбец.
 oledCommand(127);//Конечный столбец.
 oledCommand(0x22);//установка страницы
 oledCommand(0);//Начальная страница.
 oledCommand(7);//Конечная страница.
 
  //////////////////////
   
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
  
  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R/*&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)*/  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
      }
    }
   
  Wire.write(K); K = 0; // отправляем "число-столбик в экран"
  
  }
  Wire.endTransmission();//Завершаем передачу данных. 
}

 

lilik
Offline
Зарегистрирован: 19.10.2017

Пардон, набрехал в 15 строке надо другое число.

lilik
Offline
Зарегистрирован: 19.10.2017
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
  /////////////////////

 oledCommand(0x21);//установка столбца
 oledCommand(0);//Начальный столбец.
 oledCommand(127);//Конечный столбец.
 oledCommand(0x22);//установка страницы
 oledCommand(0);//Начальная страница.
 oledCommand(7);//Конечная страница.
 
  //////////////////////
   
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные.
  
  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R/*&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)*/  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
      }
    }
   
  Wire.write(K); K = 0; // отправляем "число-столбик в экран"
  
  }
  Wire.endTransmission();//Завершаем передачу данных. 
}

 

lilik
Offline
Зарегистрирован: 19.10.2017

b707 пишет:

lilik пишет:

При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)

И их тоже как то надо выбирать сообразно фигурам.

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

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

lilik
Offline
Зарегистрирован: 19.10.2017

andriano пишет:

lilik пишет:

При различных одновременных комбинациях фигур на экране число "столбцовых примитивов" будет доходить до 256 :-)

А что, "различные одновременные комбинации фигур" - это обязательно для данного проекта?

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

Цитата:

И их тоже как то надо выбирать сообразно фигурам.

Да - для каждого проекта свои примитивы. Не нужно только пытаться создать единые примитивы универсальные для всех проектов одновременно. Ну не будут они все на одном экране. Сам формат 128х64 этого не позволяет.

Стратегию я понял, но морально к ней не готов.

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

lilik пишет:

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

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

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

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

lilik пишет:

не работает

Буфер Wire по умолчанию 32 байта.
После 32 посылок надо Wire.endtransmission(false)
т.е. посылать буфер физически без посыла Stop.

lilik
Offline
Зарегистрирован: 19.10.2017

Komandir пишет:
lilik пишет:
не работает
Буфер Wire по умолчанию 32 байта. После 32 посылок надо Wire.endtransmission(false) т.е. посылать буфер физически без посыла Stop.

#include <Wire.h>//Подключаю библиотеку протокола I2C.

int K = 0; // переменная хранения числа-столбца 8 пикселей
int st=0;

//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
  Wire.write(comm);//Передаем команду.
  Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
  Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
  Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
  Wire.write(data);//Передаем данные.
  Wire.endTransmission();//Завершаем передачу данных.
}

/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  Wire.begin();

  //процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
  oledCommand(0xAE);//выключение дисплея
  oledCommand(0xD5);// Частота обновления экрана
  oledCommand(0x80);
  oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
  oledCommand(0x0);
  oledCommand(0x40);
  oledCommand(0x8D);//включение емкостного умножителя
  oledCommand(0x14);
  oledCommand(0x20);//настройка адресации
  oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
  oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
  oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
  //Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
  oledCommand(0xDA);
  oledCommand(0x12);
  oledCommand(0x81);//установка контрастности дисплея
  oledCommand(0xCF);
  oledCommand(0xD9);
  oledCommand(0xF1);
  oledCommand(0xDB); // установка Vcomh(влияет на яркость)
  // oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
  oledCommand(0x40);
  oledCommand(0xA4);
  oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
  oledCommand(0xAF);//включение дисплея

  Wire.setClock( 400000L );

}

void loop() {

  int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром координаты центра фигуры - двигаем её по экрану
  krug_(63, 32, R); //круг в центре экрана переменного радиуса

  delay(25);
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
  /////////////////////

 oledCommand(0x21);//установка столбца
 oledCommand(0);//Начальный столбец.
 oledCommand(127);//Конечный столбец.
 oledCommand(0x22);//установка страницы
 oledCommand(0);//Начальная страница.
 oledCommand(7);//Конечная страница.
 
  //////////////////////
   for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
   if(st>15){st=0; Wire.endTransmission(); Wire.beginTransmission(0x3C);Wire.write(0x40);}st++;
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      bool sbros=true;
      ///
      if (sbros==true &&((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros=false; 
      }
      ///
      if (sbros==true &&((x+10 - X) * (x+10 - X)) + ((y - Y) * (y - Y)) <= R * R&&((x+10 - X) * (x+10 - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros=false; 
      }
      /// 
    }
   
  Wire.write(K); K = 0; // отправляем "число-столбик в экран"
  
  }
 Wire.endTransmission(); //Завершаем передачу данных. 
}

Если не тяжело поправьте в скетче. Этот работает, но только при 16 числах-столбцах в одной передаче, иначе начинает картинка чудить. Смысл деяний моих в строках 82 и 105.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

lilik в 107 сообщении возьмите код.
Там без буфера-каждый байт улетает в железо на максимальной скорости для АВР.

lilik
Offline
Зарегистрирован: 19.10.2017

Komandir пишет:
lilik в 107 сообщении возьмите код. Там без буфера-каждый байт улетает в железо на максимальной скорости для АВР.

 :-)

Я вообще ничего в нём не понимаю, что брать, куда вставлять и т.д.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

:-) :-) :-)

Какой ваш код работает, но с фризами? В 197 сообщении ?

lilik
Offline
Зарегистрирован: 19.10.2017
#include <Wire.h>//Подключаю библиотеку протокола I2C.

int K = 0; // переменная хранения числа-столбца 8 пикселей


//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
  Wire.write(comm);//Передаем команду.
  Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
  Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
  Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
  Wire.write(data);//Передаем данные.
  Wire.endTransmission();//Завершаем передачу данных.
}

/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  Wire.begin();

  //процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
  oledCommand(0xAE);//выключение дисплея
  oledCommand(0xD5);// Частота обновления экрана
  oledCommand(0x80);
  oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
  oledCommand(0x0);
  oledCommand(0x40);
  oledCommand(0x8D);//включение емкостного умножителя
  oledCommand(0x14);
  oledCommand(0x20);//настройка адресации
  oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
  oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
  oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
  //Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
  oledCommand(0xDA);
  oledCommand(0x12);
  oledCommand(0x81);//установка контрастности дисплея
  oledCommand(0xCF);
  oledCommand(0xD9);
  oledCommand(0xF1);
  oledCommand(0xDB); // установка Vcomh(влияет на яркость)
  // oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
  oledCommand(0x40);
  oledCommand(0xA4);
  oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
  oledCommand(0xAF);//включение дисплея

  Wire.setClock( 400000L );

}

void loop() {

  int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром координаты центра фигуры - двигаем её по экрану
  krug_(63, 32, R); //круг в центре экрана переменного радиуса

  delay(25);
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {
  /////////////////////

 oledCommand(0x21);//установка столбца
 oledCommand(0);//Начальный столбец.
 oledCommand(127);//Конечный столбец.
 oledCommand(0x22);//установка страницы
 oledCommand(0);//Начальная страница.
 oledCommand(7);//Конечная страница.
 
  //////////////////////
   
  
  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
      }
    }
   
 oledData(K); K = 0; // отправляем "число-столбик в экран"
  
  }
  
}

Вот отрисовка окружности, если быстро-быстро крутить потенциометр, то видно чётко две окружности - новая и старая.

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
#define SCL0PORT PORTC
#define SCL0PIN PORTC5
#define SDA0PORT PORTC
#define SDA0PIN PORTC4
#define SCL1PORT PORTB
#define SCL1PIN PORTB3
#define SDA1PORT PORTB
#define SDA1PIN PORTB4
#include <avr/pgmspace.h>
void __attribute__ ((noinline)) i2c_init(uint8_t device=0) {
  asm volatile(
    "TST %8\n\t"
    "BRNE i2c_init_1\n\t"
    "CBI %0-1,%1\n\t"
    "CBI %2-1,%3\n\t"
    "CBI %2,%3\n\t"
    "CBI %0,%1\n\t"
    "RJMP i2c_init_2\n\t"
    "i2c_init_1:\n\t"
    "CBI %4-1,%5\n\t"
    "CBI %6-1,%7\n\t"
    "CBI %6,%7\n\t"
    "CBI %4,%5\n\t"
    "NOP\n\t"
    "i2c_init_2:\n\t"
    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN), 
      "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
      "r" (device)
  );
}
void __attribute__ ((noinline)) i2c_start(uint8_t device=0) {
  asm volatile(
    "SBRS %4,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %4,0\n\t"
    "SBI %2-1,%3\n\t"
    ::"I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
      "r" (device)
  );
}
void __attribute__ ((noinline)) i2c_write(uint8_t data, uint8_t device=0) {
  uint8_t b,i;
  asm (
    "LDI %10,8\n\t"
    "i2c_write_1:"
    "SBRS %8,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "SBI %4-1,%5\n\t"
    "ROL %9\n\t"
    "BRCS i2c_write_2\n\t"
    "SBRS %8,0\n\t"
    "SBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "SBI %6-1,%7\n\t"
    "RJMP i2c_write_3\n"
    "i2c_write_2:\n\t"
    "SBRS %8,0\n\t"
    "CBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "CBI %6-1,%7\n\t"
    "NOP\n"
    "i2c_write_3:\n\t"
    "LDI %11,4\n"
    "i2c_write_4:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_4\n\t"
    "SBRS %8,0\n\t"
    "CBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "CBI %4-1,%5\n\t"
    "LDI %11,2\n"
    "i2c_write_5:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_5\n\t"
    "DEC %10\n\t"
    "BRNE i2c_write_1\n\t"
    "NOP\n\t"
    "SBRS %8,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "SBI %4-1,%5\n\t"
    "SBRS %8,0\n\t"
    "CBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "CBI %6-1,%7\n\t"
    "TST %8\n\t"
    "BRNE i2c_write_6\n\t"
    "NOP\n"
    "i2c_write_7:\n\t"
    "SBIC %2-2,%3\n\t"
    "RJMP i2c_write_7\n\t"
    "RJMP i2c_write_8\n"
    "i2c_write_6:\n\t"
    "SBIC %6-2,%7\n\t"
    "RJMP i2c_write_6\n\t"
    "NOP\n\t"
    "NOP\n"
    "i2c_write_8:\n\t"
    "LDI %11,3\n\t"
    "i2c_write_9:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_9\n\t"
    "SBRS %8,0\n\t"
    "CBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "CBI %4-1,%5\n\t"
    "LDI %11,3\n"
    "i2c_write_10:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_10\n\t"
    "SBRS %8,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "SBI %4-1,%5\n\t"
    "LDI %11,4\n"
    "i2c_write_11:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_11\n\t"
    "NOP\n\t"
    "NOP\n\t"
    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN), 
      "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
      "r" (device), "r" (data), "r" (b), "r" (i)
  );
}
void __attribute__ ((noinline)) i2c_stop(uint8_t device=0) {
  uint8_t i;
  asm volatile(
    "SBRS %8,0\n\t"
    "SBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "SBI %6-1,%7\n\t"
    "LDI %9,6\n"
    "i2c_stop_1:\n\t"
    "DEC %9\n\t"
    "BRNE i2c_stop_1\n\t"
    "SBRS %8,0\n\t"
    "CBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "CBI %4-1,%5\n\t"
    "LDI %9,2\n\t"
    "i2c_stop_2:\n\t"
    "DEC %9\n\t"
    "BRNE i2c_stop_2\n\t"
    "SBRS %8,0\n\t"
    "CBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "CBI %6-1,%7\n\t"
    "LDI %9,3\n"
    "i2c_stop_3:\n\t"
    "DEC %9\n\t"
    "BRNE i2c_stop_3\n\t"
    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN), 
      "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
      "r" (device), "r" (i)
  );
}
#define addr 0x3C
static const uint8_t PROGMEM init_bytes[]={addr<<1,0x00,0xAE,0xD5,0x80,0xD3,0x0,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDB,0x40,0xA4,0xA6,0xAF};



int K = 0; // переменная хранения числа-столбца 8 пикселей


/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  i2c_init();
  i2c_start();
  for(uint8_t i=0;i<sizeof(init_bytes);i++) i2c_write(pgm_read_byte(init_bytes+i));
  asm volatile ("nop\n\t""nop");
  i2c_stop();
  i2c_start();
  i2c_write(addr<<1);
  asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
  i2c_write(0x40);
  asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
}

void loop() {

  int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром координаты центра фигуры - двигаем её по экрану
  krug_(63, 32, R); //круг в центре экрана переменного радиуса

  delay(25);
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {

  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R/*&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)*/  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
      }
    }
    i2c_write(K); K = 0; // отправляем "число-столбик в экран"
  }
}

Это из 197. Оказывается в 107 версия на 1 МГц, но за то на два девайса на разных пинах !

 

А вот FULL SPEED:

#define SCLPORT PORTC
#define SCLPIN PORTC5
#define SDAPORT PORTC
#define SDAPIN PORTC4
#include <avr/pgmspace.h>
void __attribute__ ((noinline)) i2c_init() {
  asm volatile(
    "CBI %0-1,%1\n\t"
    "CBI %2-1,%3\n\t"
    "CBI %2,%3\n\t"
    "CBI %0,%1\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN) 
  );
}
void __attribute__ ((noinline)) i2c_start() {
  asm volatile(
    "SBI %0-1,%1\n\t"
    ::"I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}
uint8_t __attribute__ ((noinline)) i2c_write(uint8_t data) {
  uint8_t result;
  uint8_t i=8;
  asm  volatile(
    "i2c_write_loop:"
    "SBI %1-1,%2\n\t"
    "SBRC %5,7\n\t"
    "CBI %3-1,%4\n\t"
    "SBRS %5,7\n\t"
    "SBI %3-1,%4\n\t"
    "ROL %5\n\t"
    "CBI %1-1,%2\n\t"
    "i2c_write_loop1:"
    "SBIS %1-2,%2\n\t"
    "RJMP i2c_write_loop1\n\t"
    "NOP\n\t"
    "DEC %6\n\t"
    "BRNE i2c_write_loop\n\t"
    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    "CBI %3-1,%4\n\t"
    "CBI %3-1,%4\n\t"
    "CBI %3-1,%4\n\t"
    "CBI %1-1,%2\n\t"
    "CLR %0\n\t"
    "SBIS %3-2,%4\n\t"
    "INC %0\n\t"
    "CBI %1-1,%2\n\t"
    "NOP\n\t"
    "SBI %1-1,%2\n\t"
    : "=r" (result)
    : "I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN), 
      "r" (data), "r" (i)
  );
  return result;
}
void __attribute__ ((noinline)) i2c_stop() {
  asm volatile(
    "SBI %2-1,%3\n\t"
    "CBI %0-1,%1\n\t"
    "CBI %0-1,%1\n\t"
    "CBI %2-1,%3\n\t"
    ::"I" (_SFR_IO_ADDR(SCLPORT)), "I" (SCLPIN), "I" (_SFR_IO_ADDR(SDAPORT)), "I" (SDAPIN)
  );
}
#define addr 0x3C
static const uint8_t PROGMEM init_bytes[]={addr<<1,0x00,0xAE,0xD5,0x80,0xD3,0x0,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDB,0x40,0xA4,0xA6,0xAF};



int K = 0; // переменная хранения числа-столбца 8 пикселей


/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  i2c_init();
  i2c_start();
  for(uint8_t i=0;i<sizeof(init_bytes);i++) i2c_write(pgm_read_byte(init_bytes+i));
  asm volatile ("nop\n\t""nop");
  i2c_stop();
  i2c_start();
  i2c_write(addr<<1);
  asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
  i2c_write(0x40);
  asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
}

void loop() {

  int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром координаты центра фигуры - двигаем её по экрану
  krug_(63, 32, R); //круг в центре экрана переменного радиуса

  delay(25);
}
///////////////////////////////////////////////////////
void krug_(int X, int Y, int R) {

  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R/*&&((x - X) * (x - X)) + ((y - Y) * (y - Y)) >=( R-1)*(R-1)*/  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
      }
    }
    i2c_write(K); K = 0; // отправляем "число-столбик в экран"
  }
}

 

lilik
Offline
Зарегистрирован: 19.10.2017

Работает, но вместо 1 шара два.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Логику я вроде не менял и байты инициализации Ваши скопировал...

lilik
Offline
Зарегистрирован: 19.10.2017

Из 216 поста  скетч пожалуйста трансформируйте, кажется в моих ранних версиях надо обязательно добавлять про установку страниц и столбцов всего экрана, это строки 73-78 из 216 поста. Ну принцип вашей "вставки" я наверное пойму :-) 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Вы байты из этих строк:

oledCommand(0x21);//установка столбца
74  oledCommand(0);//Начальный столбец.
75  oledCommand(127);//Конечный столбец.
76  oledCommand(0x22);//установка страницы
77  oledCommand(0);//Начальная страница.
78  oledCommand(7);//Конечная страница.

добавьте в массив инициализации ...

получим:

static const uint8_t PROGMEM init_bytes[]={addr<<1,0x00,0xAE,0xD5,0x80,0xD3,0x0,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDB,0x40,0x21,0,127,0x22,0,7,0xA4,0xA6,0xAF};

lilik
Offline
Зарегистрирован: 19.10.2017

Попробую.

lilik
Offline
Зарегистрирован: 19.10.2017

Спасибо, всё сработало!

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Фризы пропали ?

lilik
Offline
Зарегистрирован: 19.10.2017

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

lilik
Offline
Зарегистрирован: 19.10.2017

#include <Wire.h>//Подключаю библиотеку протокола I2C.

int K = 0; // переменная хранения числа-столбца 8 пикселей
int st = 0;//счётчик числа пересылаемых байт данных за 1 сеанс (16 байт)

//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
  Wire.write(comm);//Передаем команду.
  Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
  Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
  Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
  Wire.write(data);//Передаем данные.
  Wire.endTransmission();//Завершаем передачу данных.
}

/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  Wire.begin();

  //процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
  oledCommand(0xAE);//выключение дисплея
  oledCommand(0xD5);// Частота обновления экрана
  oledCommand(0x80);
  oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
  oledCommand(0x0);
  oledCommand(0x40);
  oledCommand(0x8D);//включение емкостного умножителя
  oledCommand(0x14);
  oledCommand(0x20);//настройка адресации
  oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
  oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
  oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
  //Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
  oledCommand(0xDA);
  oledCommand(0x12);
  oledCommand(0x81);//установка контрастности дисплея
  oledCommand(0xCF);
  oledCommand(0xD9);
  oledCommand(0xF1);
  oledCommand(0xDB); // установка Vcomh(влияет на яркость)
  // oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
  oledCommand(0x40);
  oledCommand(0xA4);
  oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
  oledCommand(0xAF);//включение дисплея


  Wire.setClock( 400000L );

}

void loop() {
  /////////////////////
  oledCommand(0x21);//установка столбца
  oledCommand(0);//Начальный столбец.
  oledCommand(127);//Конечный столбец.
  oledCommand(0x22);//установка страницы
  oledCommand(0);//Начальная страница.
  oledCommand(7);//Конечная страница.
  //////////////////////

  int R = map(analogRead(A0), 0, 1020, 0, 63);// выставляем потенциометром выбранный параметр в фигуре

  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    if (st > 15) {
      st = 0;
      Wire.endTransmission();
      Wire.beginTransmission(0x3C);
      Wire.write(0x40);
    } st++;
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      bool sbros = true;
      ///
      if (sbros == true && figura_1(x, y,63,32, R)  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_1(x, y,80,20, R/2)  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
       if (sbros == true && figura_1(x, y,40,45, 2*R/3)  ) { // проверяем принадлежит ли пиксель данной фигуре (круг или //окружность)
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
    }

    Wire.write(K); K = 0; // отправляем "число-столбик в экран"

  }
  Wire.endTransmission(); //Завершаем передачу данных.


  delay(25);
}
////////////////////// функция отрисовки окружности или круга
bool figura_1(int x, int y, int X,int Y,int R) {
  if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R && ((x - X) * (x - X)) + ((y - Y) * (y - Y)) >= ( R - 1) * (R - 1)) {
    return true;
  } else {
    return false;
  }
}

Вот вариант "архитектуры" скетча - можно задавать фигуры с разными аргументами для анимации. Пока только из фигур окружность и круг можно.

 

lilik
Offline
Зарегистрирован: 19.10.2017

/////шкала индикатор уровня сигнала
#include <Wire.h>//Подключаю библиотеку протокола I2C.

int K = 0; // переменная хранения числа-столбца 8 пикселей
int st = 0;//счётчик числа пересылаемых байт данных за 1 сеанс (16 байт)

//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
  Wire.write(comm);//Передаем команду.
  Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
  Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
  Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
  Wire.write(data);//Передаем данные.
  Wire.endTransmission();//Завершаем передачу данных.
}

/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  Wire.begin();

  //процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
  oledCommand(0xAE);//выключение дисплея
  oledCommand(0xD5);// Частота обновления экрана
  oledCommand(0x80);
  oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
  oledCommand(0x0);
  oledCommand(0x40);
  oledCommand(0x8D);//включение емкостного умножителя
  oledCommand(0x14);
  oledCommand(0x20);//настройка адресации
  oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
  oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
  oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
  //Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
  oledCommand(0xDA);
  oledCommand(0x12);
  oledCommand(0x81);//установка контрастности дисплея
  oledCommand(0xCF);
  oledCommand(0xD9);
  oledCommand(0xF1);
  oledCommand(0xDB); // установка Vcomh(влияет на яркость)
  // oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
  oledCommand(0x40);
  oledCommand(0xA4);
  oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
  oledCommand(0xAF);//включение дисплея


  Wire.setClock( 400000L );

}

void loop() {
  /////////////////////
  oledCommand(0x21);//установка столбца
  oledCommand(0);//Начальный столбец.
  oledCommand(127);//Конечный столбец.
  oledCommand(0x22);//установка страницы
  oledCommand(0);//Начальная страница.
  oledCommand(7);//Конечная страница.
  //////////////////////

  int R = map(analogRead(A0), 0, 1020, 2, 125);// выставляем потенциометром выбранный параметр в фигуре

  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    if (st > 15) {
      st = 0;
      Wire.endTransmission();
      Wire.beginTransmission(0x3C);
      Wire.write(0x40);
    } st++;
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      bool sbros = true;
      ///
      if (sbros == true && figura_2(x, y, R, 32, 1, 24, true)  ) { // указатель-стрелка
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_2(x, y, 40, 32, 35 , 10, false)  ) { // шкала
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_2(x, y, 100, 32, 20 , 10, false)  ) { //шкала
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_2(x, y, 63, 32, 63, 31, false)  ) { // шкала
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
    }

    Wire.write(K); K = 0; // отправляем "число-столбик в экран"

  }
  Wire.endTransmission(); //Завершаем передачу данных.


  delay(25);
}
////////////////////// функция отрисовки окружности или круга
bool figura_1(int x, int y, int X, int Y, int R, bool f) { //проверяет принадлежит ли пиксель с координатами x,y окружности/кругу (false/true)с координатами X,Y центра и радиуса R
  if (f == false) {
    if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R && ((x - X) * (x - X)) + ((y - Y) * (y - Y)) >= ( R - 1) * (R - 1)) {//окружность
      return true;
    } else {
      return false;
    }
  }
  else {
    if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R ) {//круг
      return true;
    } else {
      return false;
    }
  }
}
///////////////////////////////
////////////////////// функция отрисовки прямоугольника закрашенного или нет
bool figura_2(int x, int y, int X, int Y, int R1, int R2 , bool f) { //проверяет принадлежит ли пиксель с координатами x,y прямоугольнику незакрашенному/закрашенному (false/true)с координатами центра X,Y и длинами полусторон R1,R2.
  if (f == false) {
    if (((x <= X + R1 && x > X + R1 - 1 || x >= X - R1 && x < X - R1 + 1 ) && (y <= Y + R2 && y >= Y - R2)) || (x <= X + R1 && x >= X - R1 && (y <= Y + R2 && y > Y + R2 - 1 || y >= Y - R2 && y < Y - R2 + 1)) ) { //прямоугольник
      return true;
    } else {
      return false;
    }
  }
  else {
    if (x <= X + R1 && x >= X - R1 && y <= Y + R2 && y >= Y - R2 ) { //прямоугольник закрашенный
      return true;
    } else {
      return false;
    }
  }
}
///////////////////////////////
/////шкала индикатор уровня сигнала
#define SCL0PORT PORTC
#define SCL0PIN PORTC5
#define SDA0PORT PORTC
#define SDA0PIN PORTC4
#define SCL1PORT PORTB
#define SCL1PIN PORTB3
#define SDA1PORT PORTB
#define SDA1PIN PORTB4
#include <avr/pgmspace.h>
void __attribute__ ((noinline)) i2c_init(uint8_t device = 0) {
  asm volatile(
    "TST %8\n\t"
    "BRNE i2c_init_1\n\t"
    "CBI %0-1,%1\n\t"
    "CBI %2-1,%3\n\t"
    "CBI %2,%3\n\t"
    "CBI %0,%1\n\t"
    "RJMP i2c_init_2\n\t"
    "i2c_init_1:\n\t"
    "CBI %4-1,%5\n\t"
    "CBI %6-1,%7\n\t"
    "CBI %6,%7\n\t"
    "CBI %4,%5\n\t"
    "NOP\n\t"
    "i2c_init_2:\n\t"
    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
    "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
    "r" (device)
  );
}
void __attribute__ ((noinline)) i2c_start(uint8_t device = 0) {
  asm volatile(
    "SBRS %4,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %4,0\n\t"
    "SBI %2-1,%3\n\t"
    ::"I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
    "r" (device)
  );
}
void __attribute__ ((noinline)) i2c_write(uint8_t data, uint8_t device = 0) {
  uint8_t b, i;
  asm (
    "LDI %10,8\n\t"
    "i2c_write_1:"
    "SBRS %8,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "SBI %4-1,%5\n\t"
    "ROL %9\n\t"
    "BRCS i2c_write_2\n\t"
    "SBRS %8,0\n\t"
    "SBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "SBI %6-1,%7\n\t"
    "RJMP i2c_write_3\n"
    "i2c_write_2:\n\t"
    "SBRS %8,0\n\t"
    "CBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "CBI %6-1,%7\n\t"
    "NOP\n"
    "i2c_write_3:\n\t"
    "LDI %11,4\n"
    "i2c_write_4:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_4\n\t"
    "SBRS %8,0\n\t"
    "CBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "CBI %4-1,%5\n\t"
    "LDI %11,2\n"
    "i2c_write_5:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_5\n\t"
    "DEC %10\n\t"
    "BRNE i2c_write_1\n\t"
    "NOP\n\t"
    "SBRS %8,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "SBI %4-1,%5\n\t"
    "SBRS %8,0\n\t"
    "CBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "CBI %6-1,%7\n\t"
    "TST %8\n\t"
    "BRNE i2c_write_6\n\t"
    "NOP\n"
    "i2c_write_7:\n\t"
    "SBIC %2-2,%3\n\t"
    "RJMP i2c_write_7\n\t"
    "RJMP i2c_write_8\n"
    "i2c_write_6:\n\t"
    "SBIC %6-2,%7\n\t"
    "RJMP i2c_write_6\n\t"
    "NOP\n\t"
    "NOP\n"
    "i2c_write_8:\n\t"
    "LDI %11,3\n\t"
    "i2c_write_9:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_9\n\t"
    "SBRS %8,0\n\t"
    "CBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "CBI %4-1,%5\n\t"
    "LDI %11,3\n"
    "i2c_write_10:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_10\n\t"
    "SBRS %8,0\n\t"
    "SBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "SBI %4-1,%5\n\t"
    "LDI %11,4\n"
    "i2c_write_11:\n\t"
    "DEC %11\n\t"
    "BRNE i2c_write_11\n\t"
    "NOP\n\t"
    "NOP\n\t"
    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
    "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
    "r" (device), "r" (data), "r" (b), "r" (i)
  );
}
void __attribute__ ((noinline)) i2c_stop(uint8_t device = 0) {
  uint8_t i;
  asm volatile(
    "SBRS %8,0\n\t"
    "SBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "SBI %6-1,%7\n\t"
    "LDI %9,6\n"
    "i2c_stop_1:\n\t"
    "DEC %9\n\t"
    "BRNE i2c_stop_1\n\t"
    "SBRS %8,0\n\t"
    "CBI %0-1,%1\n\t"
    "SBRC %8,0\n\t"
    "CBI %4-1,%5\n\t"
    "LDI %9,2\n\t"
    "i2c_stop_2:\n\t"
    "DEC %9\n\t"
    "BRNE i2c_stop_2\n\t"
    "SBRS %8,0\n\t"
    "CBI %2-1,%3\n\t"
    "SBRC %8,0\n\t"
    "CBI %6-1,%7\n\t"
    "LDI %9,3\n"
    "i2c_stop_3:\n\t"
    "DEC %9\n\t"
    "BRNE i2c_stop_3\n\t"
    ::"I" (_SFR_IO_ADDR(SCL0PORT)), "I" (SCL0PIN), "I" (_SFR_IO_ADDR(SDA0PORT)), "I" (SDA0PIN),
    "I" (_SFR_IO_ADDR(SCL1PORT)), "I" (SCL1PIN), "I" (_SFR_IO_ADDR(SDA1PORT)), "I" (SDA1PIN),
    "r" (device), "r" (i)
  );
}
#define addr 0x3C
static const uint8_t PROGMEM init_bytes[] = {addr << 1, 0x00, 0xAE, 0xD5, 0x80, 0xD3, 0x0, 0x40, 0x8D, 0x14, 0x20, 0x00, 0xA1, 0xC8, 0xDA, 0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6, 0xAF, 0x21, 0, 127, 0x22, 0, 7};


/////////////////////////////////////////////////////////
int K = 0; // переменная хранения числа-столбца 8 пикселей



/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  delay(100);
  ///////////////////
  i2c_init();
  i2c_start();
  for (uint8_t i = 0; i < sizeof(init_bytes); i++) i2c_write(pgm_read_byte(init_bytes + i));
  asm volatile ("nop\n\t""nop");
  i2c_stop();
  i2c_start();
  i2c_write(addr << 1);
  asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
  i2c_write(0x40);
  asm volatile ("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop");
}

void loop() {


  int R = map(analogRead(A0), 0, 1020, 1, 126);// выставляем потенциометром выбранный параметр в фигуре

  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      bool sbros = true;
      ///
      if (sbros == true && figura_2(x, y, R, 32, 1, 24, true)  ) { // указатель-стрелка
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_2(x, y, 40, 32, 35 , 10, false)  ) { // шкала
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_2(x, y, 100, 32, 20 , 10, false)  ) { //шкала
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
      if (sbros == true && figura_2(x, y, 63, 32, 63, 31, false)  ) { // шкала
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        sbros = false;
      }
      ///
    }

    i2c_write(K); K = 0; // отправляем "число-столбик в экран"

  }



  delay(25);
}
////////////////////// функция отрисовки окружности или круга
bool figura_1(int x, int y, int X, int Y, int R, bool f) {
  if (f == false) {
    if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R && ((x - X) * (x - X)) + ((y - Y) * (y - Y)) >= ( R - 1) * (R - 1)) {//окружность
      return true;
    } else {
      return false;
    }
  }
  else {
    if (((x - X) * (x - X)) + ((y - Y) * (y - Y)) <= R * R ) {//круг
      return true;
    } else {
      return false;
    }
  }
}
///////////////////////////////
////////////////////// функция отрисовки прямоугольника закрашенного или нет
bool figura_2(int x, int y, int X, int Y, int R1, int R2 , bool f) {
  if (f == false) {
    if (((x <= X + R1 && x > X + R1 - 1 || x >= X - R1 && x < X - R1 + 1 ) && (y <= Y + R2 && y >= Y - R2)) || (x <= X + R1 && x >= X - R1 && (y <= Y + R2 && y > Y + R2 - 1 || y >= Y - R2 && y < Y - R2 + 1)) ) { //прямоугольник
      return true;
    } else {
      return false;
    }
  }
  else {
    if (x <= X + R1 && x >= X - R1 && y <= Y + R2 && y >= Y - R2 ) { //прямоугольник закрашенный
      return true;
    } else {
      return false;
    }
  }
}
///////////////////////////////

Вот она, первая шкала. Всего четыре вызова одной функции с разными аргументами. Оба варианта скетча работают визуально одинаково, второй не использует динамическую память (пишет 0 процентов) и весит минимум. Фризы (слово новое узнал :-) на стрелке видны одинаково. В общем путь  к про мини 168 и 17 экранчикам на ней - открыт :-)

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

lilik
Offline
Зарегистрирован: 19.10.2017
/////шкала приёмника
#include <Wire.h>//Подключаю библиотеку протокола I2C.

int K = 0; // переменная хранения числа-столбца 8 пикселей
int st = 0;//счётчик числа пересылаемых байт данных за 1 сеанс (16 байт)
extern const unsigned char schkala_A[];
extern const unsigned char schkala_B[];

//////////////////////////////////////////////////////////////////////
//Предварительно создам функции ввода команд и данных в дисплей.
void oledCommand(int comm) {
  Wire.beginTransmission(0x3C);//Начинаем передачу команд устройству с адресом 0x3C.
  Wire.write(0x00);//Сообщаем дисплею, что следующее передаваемое значение - команда.
  Wire.write(comm);//Передаем команду.
  Wire.endTransmission();//Завершаем передачу данных.
}
///////////////////////////////////////////////////////////////////////
void oledData(int data) {
  Wire.beginTransmission(0x3C);//Начинаем передачу данных устройству с адресом 0x3C.
  Wire.write(0x40);//Сообщаем дисплею, что следующее передаваемое значение - данные, которые необходимо вывести на дисплей.
  Wire.write(data);//Передаем данные.
  Wire.endTransmission();//Завершаем передачу данных.
}

/////////////////////////////////////////////////////////////////////
void setup() {
  ///////////////////
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);
  pinMode(10, OUTPUT);
  digitalWrite(10, HIGH);
  delay(100);
  ///////////////////
  Wire.begin();

  //процесс инициализации частично команды необязательны, т.к. имеют выбранное значение после RESET
  oledCommand(0xAE);//выключение дисплея
  oledCommand(0xD5);// Частота обновления экрана
  oledCommand(0x80);
  oledCommand(0xD3);// Смещение изображения на дисплее (Offset)
  oledCommand(0x0);
  oledCommand(0x40);
  oledCommand(0x8D);//включение емкостного умножителя
  oledCommand(0x14);
  oledCommand(0x20);//настройка адресации
  oledCommand(0x00);// 0х00 для горизонтальной, 0х01 для вертикальной, 0х02 для постраничной адресации
  oledCommand(0xA1);//отражение по горизонтали, для отображения справа налево необходимо использовать команду 0xA0
  oledCommand(0xC8);//отражение по вертикали, 0xC0 для переворота изображения по вертикали.
  //Одновременное использование команд 0xC8 и 0xA1 или 0xA0 и 0xC0 позволяет повернуть изображение на 180 градусов.
  oledCommand(0xDA);
  oledCommand(0x12);
  oledCommand(0x81);//установка контрастности дисплея
  oledCommand(0xCF);
  oledCommand(0xD9);
  oledCommand(0xF1);
  oledCommand(0xDB); // установка Vcomh(влияет на яркость)
  // oledCommand (0x30); // 0x00 - 0,65Vcc; 0x20 - 0,77Vcc; 0x30 - 0,83Vcc
  oledCommand(0x40);
  oledCommand(0xA4);
  oledCommand(0xA6);//инверсия дисплея, 0xA6 для отключения инверсии, 0xA7 для включения инверсии цвета.
  oledCommand(0xAF);//включение дисплея


  Wire.setClock( 400000L );

}

void loop() {
  /////////////////////
  oledCommand(0x21);//установка столбца
  oledCommand(0);//Начальный столбец.
  oledCommand(127);//Конечный столбец.
  oledCommand(0x22);//установка страницы
  oledCommand(0);//Начальная страница.
  oledCommand(7);//Конечная страница.
  //////////////////////

  int R = map(analogRead(A0), 0, 1023, 0, 265);// выставляем потенциометром выбранный параметр в фигуре
  bool fl_;
  if(R<133){digitalWrite(10, HIGH);digitalWrite(11, LOW);fl_=true;}else{digitalWrite(10, LOW);digitalWrite(11, HIGH);fl_=false;R=R-140;}//
 
  for ( int i = 0; i < 1024; i++) { //перебираем все столбики экрана
    if(fl_==true){K=pgm_read_byte(&schkala_A[i]);}else{K=pgm_read_byte(&schkala_B[i]);}
    if (st > 15) {
      st = 0;
      Wire.endTransmission();
      Wire.beginTransmission(0x3C);
      Wire.write(0x40);
    } st++;
    int N = i / 128; // определяем номер страницы экраны по значению счётчика столбиков
    int x = i - 128 * N; // определяем координату всех пикселей в столбике текущем
    for (int y = 8 * N; y < 8 * N + 8; y++) { // перебираем координаты всех пикселей столбика
      
     
      if ( figura_2(x, y, R, 32, 2, 24, false)  ) { // указатель-стрелка
        int bi = y % 8;
        K = K | (1 << bi); // или bitSet(K, bi);- вносим бит 1 в число-столбик если принадлежит пиксель фигуре
        
      }
     
    }

    Wire.write(K); // отправляем "число-столбик в экран"

  }
  Wire.endTransmission(); //Завершаем передачу данных.


  delay(25);
}

////////////////////// функция отрисовки прямоугольника закрашенного или нет
bool figura_2(int x, int y, int X, int Y, int R1, int R2 , bool f) { //проверяет принадлежит ли пиксель с координатами x,y прямоугольнику незакрашенному/закрашенному (false/true)с координатами центра X,Y и длинами полусторон R1,R2.
  if (f == false) {
    if (((x <= X + R1 && x > X + R1 - 1 || x >= X - R1 && x < X - R1 + 1 ) && (y <= Y + R2 && y >= Y - R2)) || (x <= X + R1 && x >= X - R1 && (y <= Y + R2 && y > Y + R2 - 1 || y >= Y - R2 && y < Y - R2 + 1)) ) { //прямоугольник
      return true;
    } else {
      return false;
    }
  }
  else {
    if (x <= X + R1 && x >= X - R1 && y <= Y + R2 && y >= Y - R2 ) { //прямоугольник закрашенный
      return true;
    } else {
      return false;
    }
  }
}
///////////////////////////////
#include <avr/pgmspace.h>



const unsigned char schkala_A[]PROGMEM = {
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3E,0X77,0X43,0X63,0XFE,0X00,
0X00,0X0C,0X8E,0XC3,0X63,0X3E,0X1C,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X1C,0XBE,0X63,0X23,0XFF,0XFE,0X00,0X00,0XF0,0XDC,0XCF,0XFF,0XC0,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XBE,0XB7,
0X21,0X23,0XFE,0X00,0X00,0XFE,0XFF,0X13,0X1B,0XF6,0XE0,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X3E,0XBF,0X63,0X63,0XFF,0XFC,0X00,
0X00,0XFE,0X33,0X13,0XFF,0XEE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X04,0XFE,0XFE,0X00,0X00,0XFE,0XFF,0X03,0X03,0XFE,0XFC,0X00,0X00,
0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X31,0X23,0X32,0X3B,0X39,0X38,
0X38,0X39,0X3B,0X33,0X23,0X23,0X33,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,
0X30,0X30,0X30,0X30,0X23,0X23,0X32,0X3B,0X39,0X38,0X38,0X38,0X38,0X30,0X23,0X20,
0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X21,0X23,
0X33,0X3B,0X39,0X38,0X38,0X38,0X39,0X33,0X23,0X23,0X31,0X30,0X30,0X30,0X30,0X30,
0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X21,0X23,0X33,0X3B,0X39,0X38,0X38,
0X38,0X39,0X3B,0X33,0X23,0X31,0X30,0X70,0X70,0X30,0X30,0X30,0X30,0X30,0X30,0X30,
0X30,0X30,0X30,0X30,0X33,0X33,0X30,0X20,0X31,0X39,0X3B,0X3B,0X39,0X39,0X38,0X30,
0X06,0X06,0X06,0X86,0XE6,0X66,0X46,0X0E,0X0E,0XCE,0X6E,0XCE,0X8E,0X0E,0XC6,0X66,
0X66,0XC6,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,
0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,
0X26,0X26,0XE6,0X46,0X0E,0XCE,0X4E,0X6E,0XCE,0X0E,0X06,0XC6,0X66,0XE6,0XC6,0X06,
0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0XC6,
0X46,0XC6,0X0E,0X0E,0XCE,0X4E,0XCE,0XCE,0X0E,0X06,0XC6,0X46,0XC6,0XC6,0X06,0X06,
0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,
0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X86,0XC6,0X06,0XC6,0XE6,
0X00,0X00,0X00,0X03,0X0F,0X09,0X0F,0X00,0X00,0X0F,0X08,0X0F,0X0F,0X00,0X0F,0X0C,
0X08,0X0F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X08,0X0F,0X01,0X00,0X00,0X0F,0X0C,0X08,0X0F,0X00,0X00,0X0F,0X08,0X0F,0X0F,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X0F,
0X09,0X0F,0X00,0X00,0X0F,0X08,0X0C,0X0F,0X00,0X00,0X0F,0X08,0X0F,0X0F,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X08,0X0F,0X00,0X0F,0X0D,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
};
const unsigned char schkala_B[]PROGMEM = {
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0XFE,0X83,0X03,0X1F,0XFE,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X04,0XFE,0XFF,0X00,0X00,0XFC,0XFE,0X03,0X03,0XFE,0XFC,0X00,0X00,0X0E,0X8F,0XE3,
0X7F,0X3E,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X04,0XFE,0XFF,0X86,0X00,
0X00,0XFE,0X03,0X03,0XFF,0XFE,0X00,0X00,0XC0,0XF0,0X9C,0XFF,0XFE,0X80,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X06,0XFF,0XFE,0X00,0X00,0XFE,0XBF,
0X03,0X87,0XFE,0X00,0X00,0X00,0XFE,0X13,0X13,0XF7,0XF6,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X04,0XFE,0XFE,0X00,0X00,0XFE,
0X03,0X03,0XFF,0XFE,0X00,0X00,0XEE,0XFE,0X13,0X3B,0XFE,0X00,0X00,0X00,0X00,0X80,
0X31,0X33,0X32,0X33,0X31,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,
0X30,0X33,0X33,0X30,0X30,0X31,0X39,0X3B,0X3B,0X39,0X39,0X38,0X38,0X33,0X33,0X33,
0X33,0X33,0X32,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X33,0X33,0X31,0X30,
0X30,0X39,0X3B,0X3A,0X3B,0X39,0X38,0X38,0X30,0X30,0X30,0X33,0X33,0X30,0X30,0X30,
0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X33,0X33,0X30,0X30,0X39,0X39,
0X3B,0X39,0X39,0X38,0X38,0X30,0X33,0X33,0X33,0X33,0X31,0X30,0X30,0X30,0X30,0X30,
0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X30,0X33,0X33,0X30,0X30,0X39,
0X3B,0X3B,0X39,0X39,0X38,0X38,0X31,0X33,0X33,0X33,0X31,0X30,0X30,0X30,0X30,0X33,
0X6E,0XCE,0X0E,0X0E,0XCE,0X6E,0XCE,0X8E,0X06,0XC6,0X66,0X66,0XC6,0X06,0X06,0X06,
0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X86,0XC6,
0X06,0XC6,0XE6,0X66,0XCE,0X0E,0X8E,0XCE,0X6E,0XCE,0X0E,0X06,0XC6,0X66,0X66,0XC6,
0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,
0XC6,0XE6,0X06,0X06,0X06,0XC6,0XEE,0X0E,0X0E,0XCE,0X6E,0X6E,0XCE,0X06,0XC6,0XE6,
0X66,0XC6,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,
0X46,0XE6,0X06,0X06,0XE6,0XA6,0X6E,0X0E,0X0E,0XCE,0X2E,0XEE,0XCE,0X06,0XC6,0X66,
0X66,0XC6,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,0X06,
0X08,0X0F,0X00,0X00,0X0F,0X08,0X0F,0X07,0X00,0X0F,0X08,0X08,0X0F,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X08,0X0F,
0X00,0X08,0X0C,0X0F,0X09,0X00,0X07,0X0F,0X08,0X0F,0X00,0X00,0X0F,0X08,0X0C,0X0F,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X0C,0X0F,0X00,0X00,0X00,0X08,0X0F,0X00,0X00,0X0F,0X08,0X0C,0X0F,0X00,0X0F,0X0D,
0X08,0X0F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X0F,0X00,0X00,0X0F,0X09,0X0F,0X00,0X00,0X0F,0X08,0X0F,0X07,0X00,0X0F,0X0C,
0X0C,0X0F,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,0X0C,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
};

Вот ещё пример "безбуферного функционального рисования". В принципе использовать можно, но с классической библиотекой будет проще.

lilik
Offline
Зарегистрирован: 19.10.2017

///////////// шкала "по типу микрометра"
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);

int t = 25; // пауза между считываниями потенциометра
extern uint8_t RusFont[];

void setup()
{
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);

  myOLED.begin();
  myOLED.invert(0);//инверсия цвета
  myOLED.setFont(RusFont);
}

void loop()
{
  myOLED.clrScr(); // очищаем дисплей
  int X = map(analogRead(A0), 0, 1023, 0, 127); //считывание данных с потенциометра и перевод в координату положения нониуса
  int D = map(X, 0, 127, 0, 105); // вычисление значений величины для  шкалы

  myOLED.print("| | | | | | | | | | |", -3, 20);//горизонтальная основная шкала
  myOLED.print(" 0 1 2 3 4 5 6 7 8 9 ", -3, 28);//горизонтальная основная шкала
  myOLED.print("                     ", X + 1, 20); // тень от нониуса на основной шкале
  myOLED.print("                     ", X + 1, 28); // тень от нониуса на основной шкале
  myOLED.print("Y J Y B E C", X + 20, 38); //надпись
  ///
  myOLED.drawLine(X, 0, X, 63); // линия нониуса вертикальная
  myOLED.drawLine(X + 13, 28, X + 13, 63); // линия нониуса вертикальная
  myOLED.drawLine(X + 13, 17, X + 13, 0); // линия нониуса вертикальная
  myOLED.drawLine(X + 13, 22, 127, 22); // линия нониуса горизонтальная
  myOLED.drawLine(X - 3, 42, 0, 42); // линия шкалы горизонтальная
  ///
  myOLED. printNumI((D - 1) % 10, X + 3, -10 + 5 * (D % 3)); // значение по шкале нониуса
  myOLED. printNumI((D + 10) % 10, X + 3, 15 + 5 * (D % 3)); // значение по шкале нониуса - для замера
  myOLED. printNumI((D + 21) % 10, X + 3, 40 + 5 * (D % 3)); // значение по шкале нониуса
  myOLED.update(); delay(t);
}

Шкала с нониусом, по типу как у микрометра.

lilik
Offline
Зарегистрирован: 19.10.2017

/////////////////// индикатор - яркость лампочки
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);
extern const unsigned char schkala_A[];// лампа включена
extern const unsigned char schkala_B[];// лампа не горит
int t = 50; // пауза между считываниями потенциометра
bool fl_ = true; // флаг для "мерцания"

void setup()
{
  pinMode(11, OUTPUT);
  digitalWrite(11, HIGH);

  myOLED.begin();
  myOLED.invert(0);//инверсия цвета
}

void loop()
{
  int svet = map(analogRead(A0), 0, 1023, 0, 55); //считывание данных с потенциометра и задание длины лучей
  myOLED.clrScr(); // очищаем дисплей
  if (svet <= 5) {
    myOLED.drawBitmap(60, 0, schkala_B, 64, 64); // рисование контура лампы
  }
  else {
    myOLED.drawBitmap(60, 0, schkala_A, 64, 64); // рисование контура лампы
    if (fl_ == true) {
      primitiv_1(80, 32, 25, 35 + svet, 20, 0.6, 0.8); // лучи от лампы...
    }
    else {
      primitiv_1(80, 32, 18, 35 + svet, 18, 0.6, 0.8); //...сияющие
    }
    fl_ = !fl_; // мерцаем
  }
  myOLED.update(); delay(t);
}
///////////////////////// ЗВЕЗДА ////////////////////////////////
void primitiv_1(int x, int y, int r1, int r2, int n, float rotor, float segm) { //x,y координаты центра фигуры; r1,r2 радиусы зубцов и впадин фигуры;
  //n число зубцов; rotor угол поворота фигуры в долях от Пи;segm часть сегмента звезды в долях от Пи (от 0.00 до 2.00)
  for (float i = (0 + rotor) * PI; i < (segm + rotor)*PI; i = i + 2 * PI / n) {
    myOLED.drawLine(x + r1 * cos(i) , y + r1 * sin(i), x + r2 * cos(i + PI / n) , y + r2 * sin(i + PI / n) );
    myOLED.drawLine(x + r2 * cos(i + PI / n) , y + r2 * sin(i + PI / n), x + r1 * cos(i + 2 * PI / n) , y + r1 * sin(i + 2 * PI / n));
  }
}
///////////////////////////////////
#include <avr/pgmspace.h>



const unsigned char schkala_A[]PROGMEM = {
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X80,0X80,0X80,0X80,0XC0,0X40,0X40,0X40,0X40,0XC0,0XC0,0XC0,0X80,0X80,0X80,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0XE0,0X30,0X18,0X0C,0X06,0X02,0X03,
0XC1,0X81,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X01,
0X03,0X06,0X06,0X0C,0X18,0X30,0X30,0X20,0X60,0X60,0X60,0X40,0X40,0XC0,0XC0,0X80,
0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X7F,0X03,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X01,0X01,0X03,0X03,0X06,0X06,0X0C,0X0C,0X18,0X18,0X30,0X30,0X60,0X40,0XC0,
0X80,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0X00,0X03,0XFF,0X00,0X00,0XFF,0XE0,0X00,0XFF,0XFE,0X00,0X0C,0X18,0X30,0XC0,
0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFC,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0XC0,0X60,0X30,0X18,0X0C,0X06,
0X03,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0X00,0X00,0XFF,0XF0,0X00,0XFF,0XFF,0X00,0X07,0XFF,0X00,0X30,0X18,0X0C,0X03,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X07,0X0C,0X18,0X30,0X60,0X40,0XC0,
0X80,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X80,
0XC0,0X60,0X60,0X30,0X18,0X0C,0X0C,0X04,0X06,0X06,0X06,0X02,0X02,0X03,0X03,0X01,
0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X01,0X01,0X01,0X03,0X03,0X03,0X02,0X02,0X02,0X03,0X03,0X03,0X03,0X01,0X01,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
};
const unsigned char schkala_B[]PROGMEM = {
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X80,0X80,0X80,0X80,0XC0,0X40,0X40,0X40,0X40,0XC0,0XC0,0XC0,0X80,0X80,0X80,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XC0,0XE0,0X30,0X18,0X0C,0X06,0X02,0X03,
0X01,0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X01,
0X03,0X06,0X06,0X0C,0X18,0X30,0X30,0X20,0X60,0X60,0X60,0X40,0X40,0XC0,0XC0,0X80,
0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0XF8,0X7F,0X03,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0X00,0X03,0XFF,0X00,0X00,0XFF,0XE0,0X00,0XFF,0XFE,0X00,0X0C,0X18,0X30,0XC0,
0X00,0X00,0X00,0X00,0X00,0X00,0X3F,0XFC,0XC0,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0X00,0X00,0XFF,0XF0,0X00,0XFF,0XFF,0X00,0X07,0XFF,0X00,0X30,0X18,0X0C,0X03,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X03,0X07,0X0C,0X18,0X30,0X60,0X40,0XC0,
0X80,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X80,
0XC0,0X60,0X60,0X30,0X18,0X0C,0X0C,0X04,0X06,0X06,0X06,0X02,0X02,0X03,0X03,0X01,
0X01,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X01,0X01,0X01,0X03,0X03,0X03,0X02,0X02,0X02,0X03,0X03,0X03,0X03,0X01,0X01,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00
};

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

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

lilik
Offline
Зарегистрирован: 19.10.2017

 :-)

Хорошо.

 Есть ещё революционная идея с графической кнопкой-дисплеем, электронным калейдоскопом и т.д.

 

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

Я же говорю, множества Мандельброта!

lilik
Offline
Зарегистрирован: 19.10.2017

Вот такая, с утра смотрел (не могу найти ссылку), 183 бакса. Грех не попробовать на экранчике 0,96.

lilik
Offline
Зарегистрирован: 19.10.2017

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

Я же говорю, множества Мандельброта!

Да...аааа, хотел просто 3 зеркала на дисплей водрузить :-)

lilik
Offline
Зарегистрирован: 19.10.2017

Только проводов многовато, как то надо схемно разрулить.

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

пока есть хоть какие идеи останавливаться нельзя

lilik
Offline
Зарегистрирован: 19.10.2017

ua6em пишет:

пока есть хоть какие идеи останавливаться нельзя

Да сама идея не нова, но просто купить совсем не просто. Нашёл 1 ссылку всего и без ценника.

https://www.e3-keys.com/index.html

Если бы китайцы подрезали платку до границ экранчика хоть бы в 3 линиях, а не 2 - "былоб красивше".

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

https://www.artlebedev.ru/optimus/mini-six/

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

lilik
Offline
Зарегистрирован: 19.10.2017

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

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

Микрое делает такое. Вроде как $99 за девкит просят.

lilik
Offline
Зарегистрирован: 19.10.2017

sadman41 пишет:
Микрое делает такое. Вроде как $99 за девкит просят.

Посмотрю, полажу по роликам на ютубе :-) 

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

Как изящно, прям до слёз. Почему цену сразу не пишут?, чтобы "синтементы" отбить.

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

Почему не пишут... $74.25 только сегодня.

В чипдипе - 14+ тыщ рэ.

lilik
Offline
Зарегистрирован: 19.10.2017

:-))))

Разглядел!

Анатолий89
Offline
Зарегистрирован: 16.03.2021

А в какой программе вы рисуете?

Мне охота будильник механический нарисовать для своих часов (дисплей 128*64,но ST7565)

lilik
Offline
Зарегистрирован: 19.10.2017

Анатолий89 пишет:

А в какой программе вы рисуете?

Мне охота будильник механический нарисовать для своих часов (дисплей 128*64,но ST7565)

Нет смысла рисовать. Проще в поисковике вбить "иконки будильник". Выбрать например:

 Используя paint.net затереть стрелки, уменьшить размер картинки до 64*64 пикселя. Затем с помощью image2LCD превратить картинку в массив чисел и вставить в скетч часов как просто фоновую картинку. Если это получится на ваших часах - расскажу дальше.

Анатолий89
Offline
Зарегистрирован: 16.03.2021

ДА-ДА!Именно это я и хотел!

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

 

Анатолий89
Offline
Зарегистрирован: 16.03.2021