Ви не увійшли.

Допоможіть! 
Переробляю скетч i2c на дисплей SPI OLED. Була бібліотека GyverOLED. Переробляю під Adafruit SSD1306. Виникла така проблема: є курсор такого типу ">", який переміщається по меню з 8 рядків при натисканні на кнопку. У старому коді з Гувер бібліотекою можна встановлювати курсор рядками:
void printPointer(uint8_t pointer) { // Навігація по меню 
if (flag) {                                     // Якщо прапор встановлено 
oled.setCursor(0, pointer);            // Вказуємо на параметр 
oled.print(">"); 
} else {                                       // Інакше 
oled.setCursor(124, pointer);        // Вказуємо значення параметра 
oled.print("<"); 
}
}
В Adafruit SSD1306 курсор можна встановлювати тільки за координатами х і у. Як зробити переміщення курсору рядками
Неактивний

В Adafruit SSD1306 у мене так виходить:
void printPointer(uint8_t pointer) {          // Навигация по меню
  if (flag) {                                             // Если флаг установлен
    display.setCursor(0, pointer);               // Указываем на параметр
    display.print(">");
  } else {                                                 // Иначе
    display.setCursor(116, pointer);            // Указываем на значение параметра
    display.print("<");
  }
}
Але тут курсор встановлюється на піксель. У гувері є дві можливості встановлення на піксель та на рядок: oled.setCursorXY и
 oled.setCursor
Неактивний

Намалюйте пару рядків на листочку а клітинку. Порахуйте клітинки. 
Якщо потрібна функція як у Гувера - ну, напишіть  Можна навіть успадкувати свій клас від тої ліби і зробити як у Гувера.
 Можна навіть успадкувати свій клас від тої ліби і зробити як у Гувера.

Але тут курсор встановлюється на піксель.
Що у вас є `pointer` в `void printPointer(uint8_t pointer)`? Номер рядка? Так помножте номер рядка на висоту рядка в пікселях, отримаєте координату в пікселях:
void printPointer(uint8_t pointer) {
  if (flag) {
    display.setCursor(0, pointer * 8);
    display.print(">");
  } else {
    display.setCursor(116, pointer * 8);
    display.print("<");
  }
}А краще спочатку обчисліть координату в пікселях, потім передавайте її в setCursor():
void printPointer(uint8_t pointer) {
  int y = pointer * 8;
  if (flag) {
    display.setCursor(0, y);
    display.print(">");
  } else {
    display.setCursor(116, y);
    display.print("<");
  }
}У гувері є дві можливості встановлення на піксель та на рядок: oled.setCursorXY и oled.setCursor
У гувері робиться те ж саме: GyverOLED.h:361:
void setCursor(int x, int y) { setCursorXY(x, y << 3); }`<< 3` - це те ж саме множення на 8.
Неактивний

ІЧСХ, такий запис множення тільки збиває з пантелику, смислу в ньому немає. Спеціально перевірив, в які команди проца компілюється ця конструкція.
    int y = 7;
    return y * 8
        ldi r24,lo8(7)
        ldi r25,hi8(7)
        std Y+2,r25
        std Y+1,r24
        ldd r24,Y+1
        ldd r25,Y+2
        lsl r24
        rol r25
        lsl r24
        rol r25
        lsl r24
        rol r25        
        
     int y = 5;
    return y << 3;
        ldi r24,lo8(5)
        ldi r25,hi8(5)
        std Y+2,r25
        std Y+1,r24
        ldd r24,Y+1
        ldd r25,Y+2
        lsl r24
        rol r25
        lsl r24
        rol r25
        lsl r24
        rol r25 Для проца різниці ніякої. А для людини є
    return y << 3 /* це множення чи зсув? треба врюхувати що курив автор */
    return y * 8 /* 8 - що за магічна константа? 
   особливо збс коли десь в іншому місці з"являється магічна константа 7, 
   і треба врюхувати, це 8-1 чи 0b0111 ци ще щось */
    return y * ROW_HEIGTH /* очевидно, це пов"язане з висотою рядка */Короче, не треба писати незрозуміло.
Неактивний

Спеціально перевірив, в які команди проца компілюється ця конструкція.
Така перевірка не має сенсу, бо по-перше, ви множите константу на константу, по-друге, компілювали, мабуть, без оптимізації. З увімкненою оптимізацією константи помножаться під час компіляції, і буде повертатись просто константа.
Ардуіно фреймворк компілює з -Os. Обидва варіанти:
int mul8(uint8_t n)
{
    return n * 8;
}
int shl3(uint8_t n)
{
    return n << 3;
}з оптимізацією по розміру (-Os) компілюються в однаковий код, який використовує інструкцію mul:
00000000 <_Z4mul8h>:
   0:   28 e0           ldi     r18, 0x08       ; 8
   2:   82 9f           mul     r24, r18
   4:   c0 01           movw    r24, r0
   6:   11 24           eor     r1, r1
   8:   08 95           ret
0000000a <_Z4shl3h>:
   a:   28 e0           ldi     r18, 0x08       ; 8
   c:   82 9f           mul     r24, r18
   e:   c0 01           movw    r24, r0
  10:   11 24           eor     r1, r1
  12:   08 95           retЗ оптимізацюєю по швидкодії (-O2) компілюються теж в однаковий код:
00000000 <_Z4mul8h>:
   0:   90 e0           ldi     r25, 0x00       ; 0
   2:   88 0f           add     r24, r24
   4:   99 1f           adc     r25, r25
   6:   88 0f           add     r24, r24
   8:   99 1f           adc     r25, r25
   a:   88 0f           add     r24, r24
   c:   99 1f           adc     r25, r25
   e:   08 95           ret
00000010 <_Z4shl3h>:
  10:   90 e0           ldi     r25, 0x00       ; 0
  12:   88 0f           add     r24, r24
  14:   99 1f           adc     r25, r25
  16:   88 0f           add     r24, r24
  18:   99 1f           adc     r25, r25
  1a:   88 0f           add     r24, r24
  1c:   99 1f           adc     r25, r25
  1e:   08 95           retАле вважаючи, що фреймворк також використовує оптимізацію на етапі лінковки (-flto), кінцевий код може бути зовсім іншим.
ІЧСХ, такий запис множення тільки збиває з пантелику, смислу в ньому немає.
Саме так. Гувер думав, що він розумніший за компілятор, але компілятор виявився розумніший. Компілятор знає, що у AVR нема інструкцій зсуву окрім як на один біт, зате є апаратний мультиплікатор.
Хоча загалом у gcc теж достатньо проблем з генерацією оптимального коду для AVR.  
Така "оптимізація" мала би сенс років 30 тому, і то тільки для процесорів, у яких або взагалі нема інструкцій множення, або якщо вони виконуються набагато довше ніж зсуви (як у 8086, наприклад).
Неактивний

З оптимізацюєю по швидкодії (-O2) компілюються теж в однаковий код:
00000000 <_Z4mul8h>: 0: 90 e0 ldi r25, 0x00 ; 0 2: 88 0f add r24, r24 4: 99 1f adc r25, r25 6: 88 0f add r24, r24 8: 99 1f adc r25, r25 a: 88 0f add r24, r24 c: 99 1f adc r25, r25 e: 08 95 ret
Цікаво, що цей код виконується навіть довше ніж той, що з -Os  Схоже, розробники gcc зовсім забили на -O2/O3 для AVR. Все одно всі компілять з -Os.
 Схоже, розробники gcc зовсім забили на -O2/O3 для AVR. Все одно всі компілять з -Os.
Неактивний