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

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

lilik пишет:

Ждём тетриса!

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

andriano пишет:

Мне кажется, слишком контрастно. 

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

///////////////////стрелочный индикатор уровня сигнала
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);

int t = 50; // пауза между считываниями потенциометра
void setup()
{
  myOLED.begin();
  myOLED.invert(0);//инверсия цвета
}

void loop()
{
  myOLED.clrScr(); // очищаем дисплей
  int x = map(analogRead(A0), 0, 1023, 5, 124); //считывание данных с потенциометра и задание координаты стрелки

  myOLED.drawRect(0, 0, 127, 63); //рамка
  myOLED.drawLine(x, 5, x, 58); // стрелка и её положение
  myOLED.drawRect(5, 22, 90, 42); //шкала прогресса
  myOLED.drawRect(95, 22, 124, 42);
  /////
  for (int j = 0; j < 20; j = j + 3) { // раскраска прямоугольника точками
    for (int i = 0; i < 30; i = i + 2) {
      myOLED.setPixel(95 + i, 22 + j);
    }
  }
  ///
  myOLED.update(); delay(t);
}

Подправил.

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

andriano пишет:

И еще одно замечание: судя по myOLED.upgate(), используется библиотека с буферизацией. Во многих проектах это недопустимо ресурсоемко. Ну и, кроме того, не позволяет подключить к одному контроллеру типа Atmega328 более одного дисплея. 

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

Думал над этим. Нет хороших графических библиотек без буфера у меня на примете, а так да, сразу можно на про мини 168 замахнуться :-)

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

Komandir пишет:

andriano пишет:

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

drawCircle без экранного буфера ?

Что Вы хотели сказать этим вопросом?

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

 

 

lilik пишет:

Думал над этим. Нет хороших графических библиотек без буфера у меня на примете, а так да, сразу можно на про мини 168 замахнуться :-)

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

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

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

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

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

Komandir пишет:

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

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

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

Заготовка под вывод ошибок OBD:

#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 SSD128x64
#define addr 0x3C
#if !defined (SSD128x64)
static const uint8_t PROGMEM init_bytes[]={addr<<1, 0x00,0xAE,0xD5,0x80,0xA8,0x1F,0xD3,0x00,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,
                                                    0xDA,0x02,0xD9,0xF1,0xDB,0x40,0x21,0x00,0x7f,0x22,0x00,0x03,0xA4,0xA6,0xAF};
#else
static const uint8_t PROGMEM init_bytes[]={addr<<1, 0x00,0xAE,0xD5,0x80,0xA8,0x3F,0xD3,0x00,0x40,0x8D,0x14,0x20,0x00,0xA1,0xC8,
                                                    0xDA,0x12,0xD9,0xF1,0xDB,0x40,0xA4,0xA6,0xAF};
#endif

static const uint8_t PROGMEM impreza[] = {
0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x38, 0x70, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0x70, 0x38, 0xF8, 0xF8, 0x00, 0x00, 0xF8, 0xF8, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0, 0xE0, 0x00, 0x00, 0xF8, 0xF8,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0,
0xE0, 0x00, 0x00, 0xE0, 0xF0, 0x38, 0x18, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x18, 0x98, 0x98, 0xD8, 0xD8, 0x78, 0x78, 0x38, 0x38, 0x18, 0x18, 0x00, 0x00, 0xE0, 0xF0, 0x38,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0xF0, 0xE0,
0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0E, 0x1C, 0x0E, 0x07,
0x03, 0x01, 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x06, 0x06, 0x06,
0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00, 0x1F, 0x1F,
0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0E, 0x1F, 0x1B,
0x11, 0x00, 0x00, 0x07, 0x0F, 0x1C, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x00, 0x00, 0x18, 0x18, 0x1C, 0x1C, 0x1E, 0x1E, 0x1B, 0x1B,
0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x1F, 0x1F, 0x00,
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1F, 0x1F};
static const uint8_t PROGMEM pbcu[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 
0xff, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x87, 0xfe, 
0xfc, 0x00, 0x00, 0xfc, 0xfe, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x07, 0xfe, 0xfc, 0x00, 0x00, 0xfc, 0xfe, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0xfe, 0xfc, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x87, 0xfe, 0xfc, 0x00, 0x00, 0xfc, 
0xfe, 0x07, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 0xfe, 
0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 
0x00, 0x00, 0x00, 0x3f, 0x7f, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xe0, 0x7f, 0x3f, 0x00, 0x00, 0x3f, 0x7f, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 
0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0x7f, 0x3f, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc3, 
0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xe7, 0x7f, 0x3c, 0x00, 0x00, 0x3f, 
0x7f, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0x7f, 
0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x84, 0xb4, 0xb4, 0x84, 0xfc, 0x00, 
0x00, 0xfc, 0x84, 0x84, 0x84, 0x84, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void setup() {
  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() {
  for (uint8_t c=0;c<=16;c++) {
    for (uint8_t s=0;s<=16;s++) {
      for(uint8_t e=0;e<(c+s);e++) {
        for(uint8_t i=0;i<(128-c*8)/2;i++) i2c_write(0x00);
        for(uint8_t i=0;i<c;i++) {
          i2c_write(0x00);i2c_write(0x3F);i2c_write(0x21);
          if (i==e) {i2c_write(0x2D);i2c_write(0x2D);}
          else {i2c_write(0x21);i2c_write(0x21);};
          i2c_write(0x21);i2c_write(0x3F);i2c_write(0x00);
        };
        for(uint8_t i=0;i<(128-c*8)/2;i++) i2c_write(0x00);
        for(uint8_t i=0;i<128;i++) i2c_write(pgm_read_byte(pbcu+i));
        for(uint8_t i=0;i<128;i++) i2c_write(pgm_read_byte(pbcu+i+128));
        for(uint8_t i=0;i<(128-s*8)/2;i++) i2c_write(0x00);
        for(uint8_t i=0;i<s;i++) {
          i2c_write(0x00);i2c_write(0xFC);i2c_write(0x84);
          if (i==(e-c)) {i2c_write(0xB4);i2c_write(0xB4);}
          else {i2c_write(0x84);i2c_write(0x84);};
          i2c_write(0x84);i2c_write(0xFC);i2c_write(0x00);
        };
        for(uint8_t i=0;i<(128-s*8)/2;i++) i2c_write(0x00);
#if defined (SSD128x64)
        for(uint16_t i=0;i<512;i++) i2c_write(0x00);
#endif
      };
    };
  };
}

Квадратики внизу - количество ошибок

Квадратик с точкой - отображаемая

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

lilik пишет:

void OLED::_initTWI()
{
	// activate internal pullups for twi.
	digitalWrite(SDA, HIGH);
	digitalWrite(SCL, HIGH);
	//delay(1);  // Workaround for a linker bug

	// initialize twi prescaler and bit rate
	__cbi2(TWSR, TWPS0);
	__cbi2(TWSR, TWPS1);
	TWBR = ((F_CPU / TWI_FREQ) - 16) / 2;

	// enable twi module, acks, and twi interrupt
	TWCR = _BV(TWEN) | _BV(TWIE)/* | _BV(TWEA)*/;

Тёмный лес. Нашёл в файлах библиотеки используемой вот этот фрагмент. Строка для изменений 11 ?

Это не Wire, это прямое обращение к железу через порты ! С Wire было бы совсем все плохо - пришлось бы делить посылки на размер буфера Wire.

Да можно пробовать записывать в TWBR 0, 1, 2, ... Или найти где определяется TWI_FREQ и менять частоту.

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

Komandir пишет:

Или найти где определяется TWI_FREQ и менять частоту.

Попробую в библиотеке OLED_I2C.

 

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

Как в принципе можно обойтись без буфера? Предположим есть функция математическая как строить фигуру по точкам. "Одну точку" не передать в экран, а только 8 "одного байта" по конкретному адресу. Если точек 200 - это 200 передач по адресам. Они быстрее чем 1 по всем адресам?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ну, еще не забуть, прежде чем рисовать новую фигуру, надо старую стереть, т.е + еще 200 передач 

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

lilik пишет:

Как в принципе можно обойтись без буфера? Предположим есть функция математическая как строить фигуру по точкам. "Одну точку" не передать в экран, а только 8 "одного байта" по конкретному адресу. Если точек 200 - это 200 передач по адресам. Они быстрее чем 1 по всем адресам?

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

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

Komandir пишет:

lilik пишет:

Как в принципе можно обойтись без буфера? Предположим есть функция математическая как строить фигуру по точкам. "Одну точку" не передать в экран, а только 8 "одного байта" по конкретному адресу. Если точек 200 - это 200 передач по адресам. Они быстрее чем 1 по всем адресам?

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

Для спрайтов кратных 8 должно быть легко.

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

lilik пишет:

Как в принципе можно обойтись без буфера? Предположим есть функция математическая как строить фигуру по точкам. "Одну точку" не передать в экран...

Правильно рассуждаешь.

Но медленно. На каждый маленький шажочек нужен очередной толчок.

Раз "одну точку не передать на экран", значит, следует принципиально избавляться от попиксельной графики. Т.е. рассматривать экран не как набор пикселей, а как набор более крупных примитивов. Хотя бы 8-пиксельных. А желательно - больше. Скажем N*M, где N - кратно 8, а M - больше 1.

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

andriano пишет:

 А желательно - больше. Скажем N*M, где N - кратно 8, а M - больше 1.

Так можно реализовывать вывод текста, имея в постоянной памяти картинки букв размером N*M, но в графике как , например, вывести отрезок заданной длины, под заданным углом? Мне кажется, в общем случае без буфера, хоть и скромного размера, не обойтись. Кстати если бы в используемой мной библиотеке буфер сократили в 2 раза, а вывод разделили на 2 части - про мини 168 справилась бы уже. "Вообщем" тема "безбуферных графических библиотек" для ssd1306 не мой уровень творчества :-(

Пришёл таки второй экранчик. От радости захотелось узоров.

////////////// генератор узоров для ковра
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);

int t = 1000; // пауза между сменой рисунка ковра
int uz = 1000; // плотность узора ковра

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

void loop()
{
  myOLED.clrScr(); // очищаем дисплей
  int p = map(analogRead(A0), 0, 1023, 0, 100); //размер ковра

  /////

  for (int i = 0; i < uz; i++) {
    int x = random(0, 128);
    int y = random(0, 64);
    if (x * x + y * y < p * p) {//вышиваем, выплетаем узоры
      myOLED.setPixel(x + 63, y + 32);
      myOLED.setPixel(x + 63, -y + 32);
      myOLED.setPixel(-x + 63, -y + 32);
      myOLED.setPixel(-x + 63, y + 32);
    }
  }

  ///
  myOLED.update(); delay(t);
}

 

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

Ползунок прогресса. Управлять кнопкой конечно будет ловчее.

/////////////////// индикатор "ползунок прогресса"
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);

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

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

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

  myOLED.drawRect(0, 30, 127, 36); //канал ползунка
  myOLED.drawRect(x + 2, 20, x + 25, 44); // тело ползунка
  myOLED.clrRect(x + 2, 30, x + 25, 36);
  myOLED.printNumI(x, x + 6 , 30 ); // числовое значение к положению ползунка

  myOLED.update(); delay(t);
}

 

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

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

lilik пишет:

Так можно реализовывать вывод текста, имея в постоянной памяти картинки букв размером N*M, но в графике как , например, вывести отрезок заданной длины, под заданным углом?

Другими словами, Вы согласны решать исключительно тривиальные задачи?

Цитата:

Мне кажется, в общем случае без буфера, хоть и скромного размера, не обойтись.

В общем случае - да.

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

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Господа! Я решил вашу задачку! ;))))))

Берем OLED128х64, Цепляем к нему Нанку, общаемся по I2C, на Нанке - драйвер со всеми примитивами графики, анимации, 3Д элементов. И уже это "бутерброд" используем как экран для своей поделки, в которой уже не нужен будет буфер.

Вот тока не надо говорить, что я изобрел Некстион! ;))) Моя идея дешевше будет!

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

andriano пишет:

Другими словами, Вы согласны решать исключительно тривиальные задачи?

 :-)

Природа не сильно интересовалась моим мнением.

 

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

wdrakula пишет:

Господа! Я решил вашу задачку! ;))))))

Берем OLED128х64, Цепляем к нему Нанку, общаемся по I2C, на Нанке - драйвер со всеми примитивами графики, анимации, 3Д элементов. И уже это "бутерброд" используем как экран для своей поделки, в которой уже не нужен будет буфер.

Вот тока не надо говорить, что я изобрел Некстион! ;))) Моя идея дешевше будет!

С практической точки зрения это вариант.

 

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

Индикация это ~5-10% от задач.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Komandir пишет:

Индикация это ~5-10% от задач.

Я вроде писал уже, что (чисто ИМХО, не настаиваю! ...ну кроме как на перце и зубровке ;)) ) что кнопки и индикацию отмел для себя полностью. Если забыть про 8ми битный "ужОс" в виде АВР, то ESP дает возможность сделать веб-морду, а тилипон всегда в кармане. ;))) Да и памяти там побольше и частота повыше. АВР-ки в автомобиль оставляю - 5В немного более устойчивы к помехам и интерфейс мне там не нужен никакой.

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

/////////////////// индикатор наполнения ёмкости жидкостью
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);
extern const unsigned char schkala_A[];

int t = 30; // пауза между считываниями потенциометра
int pp = 0; // переменная для хранения предыдущего значения уровня

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

void loop()
{
  myOLED.drawBitmap(0, 0, schkala_A, 128, 64); // рисование картинки ёмкости
  int p = map(analogRead(A0), 0, 1023, 15, 122); // считывание потенциометра и определение высоты уровня жидкости
  if (abs(p - pp) > 1) { //если значение уровня поменялось выше порогового в 1 единицу
    myOLED.drawRect(p, 8, 122, 54); // прорисовка контура столба жидкости
    for (int i = 0; i < 2000 - p * 15; i++) { // прорисовка столба жидкости
      int x = random(p, 122);
      int y = random(8, 54);
      myOLED.setPixel(x , y );
    }
    myOLED.update(); delay(t);
    pp = p; //запоминание "нового предыдущего" значения
  }
}
#include <avr/pgmspace.h>



const unsigned char schkala_A[]PROGMEM = {
0X00,0X00,0X00,0X80,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0XF0,0XF8,0XFC,0XFC,0X1C,
0X0C,0X0C,0X1C,0XFC,0XFC,0XF8,0XF0,0X60,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,
0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X60,0X60,0XF0,0XF8,0XFC,
0XFC,0X1C,0X0C,0X0C,0X0C,0X1C,0XFC,0XF8,0XF0,0X60,0X70,0X70,0X70,0X70,0X70,0X70,
0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X60,0XF0,
0XF8,0XFC,0XFC,0X1C,0X0C,0X0C,0X0C,0X1C,0XFC,0XFC,0XF8,0XF0,0X60,0X70,0X70,0X70,
0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,0X70,
0X60,0X60,0XF8,0XF8,0XFC,0X1C,0X0C,0X0C,0X0C,0X1C,0XFC,0XFC,0XF8,0XF0,0X00,0X00,
0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X0E,0X0E,0X0E,0X0E,0X0E,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFC,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0XFC,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X3F,0X3F,0X3F,0X3F,0X1C,0X1C,0X1C,0X1C,0X1C,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,
0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,
0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0X1F,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0XFF,
0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,
0X00,0X1F,0XFF,0XFF,0XFF,0X00,0X00,0X00,0X00,0X00,0XFF,0XFF,0XFF,0XFF,0X00,0X00,
0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X07,0X0F,0X1F,0X1F,0X38,
0X38,0X38,0X38,0X1F,0X1F,0X0F,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,
0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X0F,0X1F,
0X1F,0X3C,0X38,0X38,0X38,0X1C,0X1F,0X1F,0X0F,0X07,0X07,0X07,0X07,0X07,0X07,0X07,
0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,
0X0F,0X1F,0X1F,0X1C,0X38,0X38,0X38,0X3C,0X1F,0X1F,0X0F,0X07,0X07,0X07,0X07,0X07,
0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,0X07,
0X07,0X07,0X0F,0X1F,0X1F,0X1C,0X38,0X38,0X38,0X3C,0X1F,0X1F,0X0F,0X07,0X00,0X00
};

Индикатор уровня жидкости. С библиотекой, как и с индикаторами-шкалами в принципе ясно, можно добавить ещё функций построения графических примитивов. 

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

Потестил схему двумя экранами, вроде всё работает.

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

andriano пишет:

В общем случае - да.

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

Я придумал общий алгоритм для графической библиотеки совсем без буфера экрана. Но реализовать его сам едва ли смогу. Да и Ардуино тоже :-) Попробую изложить его простым языком, если получится, может сведущие разберутся.  

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

Бочка в разрезе жаркого лета будет весьма актуальна

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

Бутылка. В проект наливатора. Тамошние алкаши будут рады

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

Для "наливатора нужен струемер-каплемер" :-)

Этот вариант сразу на три экрана (в наличии правда только два).

/////////////проверка одновременной работы 3 экранов на 3 разных индикаторах-шкалах
#include <OLED_I2C.h>
OLED  myOLED(SDA, SCL);
#define disp_1 12 // управляющие дисплееями выводы 
#define disp_2 11
#define disp_3 10
extern const unsigned char schkala_A[];
extern const unsigned char schkala_B[];
int t = 25; // пауза между считываниями потенциометра
int dlina_1 = 30;
int tabl_[10];//массив хранения данных с потенциометра
int kap=55;//

extern uint8_t MediumNumbers[];
void setup()
{
  ////// подключение всех дисплеев
  pinMode(disp_1, OUTPUT);
  digitalWrite(disp_1, HIGH);
  myOLED.begin();
  digitalWrite(disp_1, LOW);
  delay(50);
  //////
  pinMode(disp_2, OUTPUT);
  digitalWrite(disp_2, HIGH);
  myOLED.begin();
  digitalWrite(disp_2, LOW);
  delay(50);
  ////////
  pinMode(disp_3, OUTPUT);
  digitalWrite(disp_3, HIGH);
  myOLED.begin();
  digitalWrite(disp_3, LOW);
  delay(50);
  ////////

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

}

void loop()
{
  pribor_1(); dis_1(); //обработка и обновление данных на 1 индикаторе
  pribor_2(); dis_2(); //обработка и обновление данных на 2 индикаторе
  pribor_3(); dis_3(); //обработка и обновление данных на 3 индикаторе
  delay(t);
}
////////////////////////////
void dis_1() { //функции обновления изображений на экранах
  digitalWrite(disp_1, HIGH); myOLED.update(); digitalWrite(disp_1, LOW);
}
void dis_2() {
  digitalWrite(disp_2, HIGH); myOLED.update(); digitalWrite(disp_2, LOW);
}
void dis_3() {
  digitalWrite(disp_3, HIGH); myOLED.update(); digitalWrite(disp_3, LOW);
}
/////////////////////////
void pribor_1() { //индикатор "текущий кран"
 myOLED.clrScr(); // очищаем дисплей 
 myOLED.drawBitmap(0, 0, schkala_A, 64, 64); // рисование картинки
 int p = map(analogRead(A0), 0, 1023, 0, 200); // считывание потенциометра и задаём скорость капели
 
  myOLED.drawBitmap(kap, 45, schkala_B, 16, 16);
  myOLED.drawBitmap(kap+20, 45, schkala_B, 16, 16);  
  kap=kap+20;if(kap>150){kap=55;}
  delay(p);
 
  

}
/////////////////////////////////
void pribor_2() { // индикатор построения графика онлайн

  int h = map(analogRead(A0), 0, 1023, 0, 63); //считывание данных с потенциометра и запись в массив данных на последнюю позицию

  for (int i = 0; i < 10; i++) {
    if (i != 9) {
      tabl_[i] = tabl_[i + 1];
    } else {
      tabl_[i] = h;
    }
  }
  myOLED.clrScr(); // очищаем дисплей

  for (int i = 0; i < 10; i++) {//прорисовка кадра
    myOLED.drawLine(i * 13 + 5, 63, i * 13 + 5, tabl_[i]); //каскад отрезков вертикальных высотой h
    if (i < 9) {
      myOLED.drawLine((i + 1) * 13 + 5, tabl_[i + 1] , i * 13 + 5, tabl_[i]); // цепочка отрезков между соседними вершинами - линия графика
    }
  }


}

///////////////////////////////////////
void pribor_3() { //стрелочный индикатор уровня сигнала

  myOLED.clrScr(); // очищаем дисплей
  int x = map(analogRead(A0), 0, 1023, 5, 124); //считывание данных с потенциометра и задание координаты стрелки

  myOLED.drawRect(0, 0, 127, 63); //рамка
  myOLED.drawLine(x, 5, x, 58); // стрелка и её положение
  myOLED.drawRect(5, 22, 90, 42); //шкала прогресса
  myOLED.drawRect(95, 22, 124, 42);
  /////
  for (int j = 0; j < 20; j = j + 3) { // раскраска прямоугольника точками
    for (int i = 0; i < 30; i = i + 2) {
      myOLED.setPixel(95 + i, 22 + j);
    }
  }
  ///

}

 

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

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

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

Rumata пишет:

(степень готовости), с учетом типа напитка и массы тушки поциЭнта


Типа как с бочкой, но с фигуркой человека?

Rumata
Rumata аватар
Offline
Зарегистрирован: 29.03.2019

sadman41 пишет:
Rumata пишет:

(степень готовости), с учетом типа напитка и массы тушки поциЭнта

Типа как с бочкой, но с фигуркой человека?

Можно и так. А можно угол наклона

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

тема из полезной медленно дрейфует в фарс. Перенесли в "Проекты", скоро придется в "Отвлеченные" переносить :)

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

Подправил - к изменению скорости капели добавляется изменение высоты стакана :-)

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

b707 пишет:

тема из полезной медленно дрейфует в фарс. Перенесли в "Проекты", скоро придется в "Отвлеченные" переносить :)

Я сейчас добавлю грусти про универсальную безбуферную графическую библиотеку.

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

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

где x,y координаты подходящих отрезку точек.

  Заполнение экрана светящимися (не светящимися) пикселями происходит сначала по столбцам, потом по страницам. Проблема в том, что столбец из 8 точек надо заполнить один раз, зная какие точки в нём принадлежат хотя бы одному из отрезков и потом отправить в экран. То есть каждый текущий бит-точку с координатами x,y надо проверять на принадлежность всем отрезкам картинки. Например, картинка состоит из 100 отрезков, значит Ардуино должна пересчитать 100 условий. А всего около 800000 на картинку прежде чем весь экран отрисуется. Вот и получается, что вместо буфера МК нужен быстро считающий МК.

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

Поэтому люди буфер и придумали ;)

Гриша
Offline
Зарегистрирован: 27.04.2014

b707 пишет:

тема из полезной медленно дрейфует в фарс. Перенесли в "Проекты", скоро придется в "Отвлеченные" переносить :)

ИМХО. тема раскрыта почти полностью - происходит обсуждение по применению... и ТС не виноват, что народ на больную тему понесло. Если чего и переносить, то отдельные посты :)))))

lilik пишет:

...значит Ардуино должна пересчитать 100 условий. А всего около 800000 на картинку прежде чем весь экран отрисуется. Вот и получается, что вместо буфера МК нужен быстро считающий МК.

как-то даже и не удивительно... может видеокарту для ардуино пора придумать? :))))  

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

lilik, библиотека OLED вот эта используется?

https://github.com/jlegas/OLED_I2C

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

http://www.rinkydinkelectronics.com/library.php?id=79

Вот отсюда качал по моему.

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

lilik пишет:

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

НизачОт!

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

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

andriano пишет:

нужно рисовать конкретную картинку. Без буфера. И без универсальных примитивов. 

Картинка это множество хаотично расположенных  точек, координаты которых где то должны храниться?

Какой промежуточный вариант между крайностями?

 

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

lilik пишет:

А прогресс ли это? Все шрифты набиты картинками в библиотеках под экранчики. Буквы-цифры не повернуть и не масштабировать. И тем не менее по другому не делают.

та конечно! ))))

Уже столько лет как решено. А начало http://arduino.ru/forum/programmirovanie/krivye-beze?page=1 там и про безбуферную работу с экраном есть маленько.

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

В коде я конечно не понял ничего, но подход ясен - буфер  размером с символ, символ это отрезки-кривые, масштабирование, повороты. Вот мне и интересно, почему авторы библиотеки OLED_I2C не делали векторные шрифты в довесок к "картиночным"?

Примитивов могли добавить - эллипсов, звёзд,многоугольников, дуг, спиралей и т.д.

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

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

//Вот мне и интересно, почему авторы библиотеки OLED_I2C не делали векторные шрифты в довесок к "картиночным"?

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

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

lilik пишет:

Вот мне и интересно, почему авторы библиотеки OLED_I2C не делали векторные шрифты в довесок к "картиночным"?

сложность кода на порядок выше

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

Мне кажется, что "математическое" хранение символа предпочтительнее "картиночного". А вот такой вариант не

облегчает кодирование?

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

lilik пишет:

 Вот мне и интересно, почему авторы библиотеки OLED_I2C не делали векторные шрифты в довесок к "картиночным"?

Они задали себе вопрос "наюха?" и совершенно правильно на него ответили - "нахнесдалось!".

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

lilik пишет:

А вот такой вариант не

облегчает кодирование?

попробуйте вписать в него "Д" или "Й", я уж не говорю про буквы арабского алфавита.

Или даже проще - изобразите своим вариантом фонты bold и italic, так чтобы они четко отличались от plain

 

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

не думаю что символ '@' сюда влезет ))) Использую для символа 9*17