Вопросы по OLED-дисплеям на контроллере SSD1306

sokrik

✩✩✩✩✩✩✩
22 Ноя 2021
3
0
Всем доброго времени. Приобрёл я значит 2х-цветный сине-жёлтый oled 128x64. С отображением синего цвета проблем нет. Как переключить на жёлтый не могу найти, библиотека без разницы. Кто знает как ? Подскажите пожаалуйста.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,837
592
44
На сколько помнится, у них отдельные зоны в разных цветах показывают, а по сути он монохромный

Скинь ссылку откуда покупал.
 

Геннадий П

★★★★★★✩
14 Апр 2021
1,837
592
44
@sokrik, Ну, на картинке четко видно, что верхняя строка желтая. И как уже сказали вам, верхняя строка на таком дисплее будет всегда желтой, а остальная часть синей. Если у вас верхняя строка синяя, то подсунули (или просто ошиблись) просто синий дисплей. На самом деле не велика потеря.

1661460559545.png
 

Llmon

✩✩✩✩✩✩✩
17 Сен 2022
2
0
Доброго времени суток, прошу помощи у форумчан в виду малого опыта программирования. Понадобилось на работу сделать анемометры с индикацией на основе датчика холла из компьютерного кулера и arduino nano , в системы вентиляции (скорость потока измерять), был найден скетч который без проблем выводит в последовательный порт данный, дописав скетч для вывода на OLED столкнулся, что на дисплее данные не изменяются.

Скеч:
#include <Math.h>
#include <Wire.h>
#include <GyverOLED.h>
GyverOLED <SSD1306_128x64, OLED_NO_BUFFER> oled;
#define WindSensorPin (2)
volatile unsigned long Rotations;
volatile unsigned long ContactBounceTime;
float WindSpeed;
void setup() {
Serial.begin(9600);
pinMode (WindSensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(WindSensorPin), isr_rotation, FALLING);
Serial.println ("Wind Speed Test");
Serial.println ("Rotations\tM/S");

  oled.init();
  oled.flipV(0);
  oled.clear();
  oled.setScale(2);
  oled.clear();
  oled.setCursor(10, 2);
  oled.print ("M/S");
  oled.setCursor(42, 4);
  oled.print(WindSpeed);
  delay (3000);
}

void loop() {
  Rotations = 0;
  sei();

  delay (3000);
  cli();
  WindSpeed = Rotations*0.12;
   delay (3000);
  Serial.print(Rotations); Serial.print("\t\t");
  Serial.print(WindSpeed);
}
void isr_rotation() {
if ((millis()-ContactBounceTime) > 15){
    Rotations++;
    ContactBounceTime = millis();
  }
}
 

Вложения

Изменено:

Llmon

✩✩✩✩✩✩✩
17 Сен 2022
2
0
@Старик Похабыч,

Попробовал в таком виде, последовательный порт перестал данные видеть, сейчас дисплей малюет только буквы M/S.
Толи лыжи не едут, толи со мной чего - то не так.


Скеч:
#include <Math.h>
#include <Wire.h>
#include <GyverOLED.h>
GyverOLED <SSD1306_128x64, OLED_NO_BUFFER> oled;
#define WindSensorPin (2)
volatile unsigned long Rotations;
volatile unsigned long ContactBounceTime;
float WindSpeed;
void setup() {
Serial.begin(9600);
pinMode (WindSensorPin, INPUT);
attachInterrupt(digitalPinToInterrupt(WindSensorPin), isr_rotation, FALLING);
Serial.println ("Wind Speed Test");
Serial.println ("Rotations\tM/S");
  oled.init();
}
void loop() {
  Rotations = 0;
  sei();
  delay (3000);
  cli();
  WindSpeed = Rotations*0.12;
   delay (3000);
  Serial.print(Rotations); Serial.print("\t\t");
  Serial.print(WindSpeed);
  oled.flipV(0);
  oled.clear();
  oled.setScale(2);   
  oled.clear();
  oled.setCursor(10, 2);
  oled.print ("M/S");
  oled.setCursor(42, 4); 
  oled.print(Rotations);
  delay (3000);
}
void isr_rotation() {
if ((millis()-ContactBounceTime) > 15){
    Rotations++;
    ContactBounceTime = millis();
  }

}
 

poty

★★★★★★✩
19 Фев 2020
2,988
895
Может я, конечно, ничего не понимаю, но для чего выключать прерывания на всё время работы цикла и включать их на время delay? Что за причуды? Не уверен, что при общем запрете прерываний будут нормально действовать функции времени (те же delay), I2C, SPI, UART...
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,192
1,281
Москва
Кстати да. Я просто для себя решил вопрос тем, что 3 сек. собираются данные с ветряка, а потом все выводится. И еще подумал, что можно было бы сделать аттач и детач прерывания. И больше не возвращался к этому вопросу. А вот запрет действительно может навредить выводам.
 

Intagan

✩✩✩✩✩✩✩
21 Авг 2022
33
1
Здраствуйте! Не могу заставить работать экран (SSD1306_128x64) не могу понять проблема в скетчах или в подключении. Оставлю пример одного из скетча который пытался запустить. А сам дисплей я подключал GND - GND, SDA - A4, SCK - A5, VDD - (5V и 3V3) да и по другому тоже пытался и наоборот и SCK к A13 и еще по разному но никаких признаков не подавал перепробовал кучу примеров из библиотеки гайвера тоже ноль результатов пожалуйста кто шарит в чем может быть еще проблема. Скетч загружается без проблем ардуина реагирует нормально все порты исправны.


Посмотреть вложение 38639


C++:
#define OLED_SOFT_BUFFER_64     // Буфер на стороне МК
#include <GyverOLED.h>          // Библиотека дисплея
GyverOLED<SSD1306_128x64> oled; // Обьект дисплея

#include <GyverButton.h>      // Либа кнопок
GButton up(3, HIGH_PULL);     // Кнопки
GButton down(4, HIGH_PULL);
GButton ok(2, HIGH_PULL);

#define ITEMS 24               // Общее кол во пунктов (больше 8 - нужно несколько страниц)

// Битмап с картинкой стрелочки (Если нужен)
const uint8_t ptr_bmp[] PROGMEM = {
  0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0xFF, 0xFF, 0x7E, 0x3C, 0x18,
};

void setup() {
  oled.init();           // Инциализация дисплея
  oled.setContrast(255); // Макс. яркость
}

void loop() {
  static int8_t pointer = 0; // Переменная указатель

  /* Кнопки */
  up.tick();                 // Опрос кнопок
  down.tick();
  ok.tick();

  if (up.isClick() or up.isHold()) {                // Если кнопку нажали или удерживают
    pointer = constrain(pointer - 1, 0, ITEMS - 1); // Двигаем указатель в пределах дисплея
  }

  if (down.isClick() or down.isHold()) {
    pointer = constrain(pointer + 1, 0, ITEMS - 1);
  }

  if (ok.isClick()) {   // Нажатие на ОК - переход в пункт меню
    switch (pointer) {  // По номеру указателей располагаем вложенные функции (можно вложенные меню)
      case 0: func(); break;  // По нажатию на ОК при наведении на 0й пункт вызвать функцию
      case 1: break;
      case 2: break;
      case 3: break;
      case 4: break;
      case 5: break;
      case 6: break;
      case 7: break;
        // И все остальные
    }
  }

  /* меню */
  oled.clear();           // Очищаем буфер
  oled.home();            // Курсор в левый верхний угол

  if (pointer < 8) {      // Первая страница
    oled.print            // Вывод всех пунктов
    (F(
       "  Parameter 0:\n" // Не забываем про '\n' - символ переноса строки
       "  Parameter 1:\n"
       "  Parameter 2:\n"
       "  Parameter 3:\n"
       "  Parameter 4:\n"
       "  Parameter 5:\n"
       "  Parameter 6:\n"
       "  Parameter 7:\n"
     ));
  } else if (pointer < 16) {// Вторая страница
    oled.print
    (F(
       "  Parameter 8:\n"
       "  Parameter 9:\n"
       "  Parameter 10:\n"
       "  Parameter 11:\n"
       "  Parameter 12:\n"
       "  Parameter 13:\n"
       "  Parameter 14:\n"
       "  Parameter 15:\n"
     ));
  } else {                  // Последняя страница
    oled.print
    (F(
       "  Parameter 16:\n"
       "  Parameter 17:\n"
       "  Parameter 18:\n"
       "  Parameter 19:\n"
       "  Parameter 20:\n"
       "  Parameter 21:\n"
       "  Parameter 22:\n"
       "  Parameter 23:\n"
     ));
  }

  printPointer(pointer);  // Вывод указателя
  oled.update();          // Выводим кадр на дисплей
}
void printPointer(uint8_t pointer) {
  // Символьный указатель - лучший выбор в многостраничном меню
  // Указатель в начале строки
  oled.setCursor(0, pointer);
  oled.print(">");
  // Можно еще в конце
  /*oled.setCursor(20, pointer);
    oled.print("<");*/
  // Указатель в виде прямоугольной рамки со скругленными углами
  /*oled.roundRect(0, pointer * 8, 127, (pointer * 8) + 6);*/
  // Указатель в виде битмапа (картинки)
  /*oled.drawBitmap(0, pointer * 8, ptr_bmp, 10, 8);*/
}

/* пример вложеной функции, которую можно вызвать из под меню */
void func(void) {
  oled.clear();
  oled.home();
  oled.print(F("Press OK to return"));
  oled.update();
  while (1) {
    ok.tick();
    if (ok.isClick()) return; // return возвращает нас в предыдущее меню
  }
}
 
Изменено:

Sergo_ST

★★★★★★✩
15 Мар 2020
820
741
Не нужно так часто отрисовывать дисплей, делайте это по таймеру или лучше по флагу изменения состояния какой-либо кнопки:
C++:
void loop() {
  static boolean scr;
  static int8_t pointer = 0; // Переменная указатель

  /* Кнопки */
  up.tick(); // Опрос кнопок
  down.tick();
  ok.tick();

  if (up.isClick() or up.isHold()) { // Если кнопку нажали или удерживают
    scr = 0; //обновили экран
    pointer = constrain(pointer - 1, 0, ITEMS - 1); // Двигаем указатель в пределах дисплея
  }

  if (down.isClick() or down.isHold()) {
    scr = 0; //обновили экран
    pointer = constrain(pointer + 1, 0, ITEMS - 1);
  }

  if (ok.isClick()) { // Нажатие на ОК - переход в пункт меню
    scr = 0; //обновили экран
    switch (pointer) { // По номеру указателей располагаем вложенные функции (можно вложенные меню)
      case 0: func(); break; // По нажатию на ОК при наведении на 0й пункт вызвать функцию
      case 1: break;
      case 2: break;
      case 3: break;
      case 4: break;
      case 5: break;
      case 6: break;
      case 7: break;
        // И все остальные
    }
  }

if (!scr) {
  scr = 1; сбросили флаг обновления экрана
  /* меню */
  oled.clear(); // Очищаем буфер
  oled.home(); // Курсор в левый верхний угол

  if (pointer < 8) { // Первая страница
    oled.print // Вывод всех пунктов
    (F(
       " Parameter 0:\n" // Не забываем про '\n' - символ переноса строки
       " Parameter 1:\n"
       " Parameter 2:\n"
       " Parameter 3:\n"
       " Parameter 4:\n"
       " Parameter 5:\n"
       " Parameter 6:\n"
       " Parameter 7:\n"
     ));
  } else if (pointer < 16) {// Вторая страница
    oled.print
    (F(
       " Parameter 8:\n"
       " Parameter 9:\n"
       " Parameter 10:\n"
       " Parameter 11:\n"
       " Parameter 12:\n"
       " Parameter 13:\n"
       " Parameter 14:\n"
       " Parameter 15:\n"
     ));
  } else { // Последняя страница
    oled.print
    (F(
       " Parameter 16:\n"
       " Parameter 17:\n"
       " Parameter 18:\n"
       " Parameter 19:\n"
       " Parameter 20:\n"
       " Parameter 21:\n"
       " Parameter 22:\n"
       " Parameter 23:\n"
     ));
  }

  printPointer(pointer); // Вывод указателя
  oled.update(); // Выводим кадр на дисплей
 }
}
 
  • Лойс +1
Реакции: Intagan

Intagan

✩✩✩✩✩✩✩
21 Авг 2022
33
1
Господь бог я это сделал проблема была в плохом контакте. Но спасибо всем кто обратил внимание!!!!!
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Доброго дня и здоровья, камрады!

Помогите, плиз, разобраться с библиотекой GyverOLED, решил начать с запуска демо-кода из библиотеки. Подключение по I2C, свободные были только пины 6 и 7 - подключился к ним SDA - 7 SCL -6. При проверке кода выдало ошибку на моменте инициализации.

void setup() {
Serial.begin(9600);
--->>> oled.init(7,6); // инициализация (ругается на мои порты)
}
Или же надо подключать на D0\D1 ?? на Tx\Rx ?!?! и тогда в сетапе уже писать oled.init(); - и он по адресу типо сам найдётся чтоли? - читал, что на эти контакты нельзя ничего подключать иначе перестанет работать чтото..:rolleyes: - кажысь перестанет корректно прошиваться.
И на плате экрана сзади резистор запаян над адресм 0х78 - надо ли его кудато вписать? - а то встречал в описаниях, что передаётся какойто адрес 0х3с.

Еще в интернете видел разные истории про вольтаж - кто-то говорит на 5 вольт садить , кто-то на 3.3в - как правильно - на схеме видно, что установлен транзистор сразу после VCC. Подключил к 5 В - ничего не сгорело и не выпустило "белый дух".
Находил , примеры кода, где люди подключали на свободные пины кроме Д0\Д1! (но там использовали библиотеку AdaFruit)
Отсюда покупал :Экраны с Али - там на последнем фото задняя сторона есть с адресом.

Еще не совсем понятен момент - наличия буфера в программе или без него (комментарий от Алекса - что без буфера почти не теряется функционал - хотелось бы узнать в каких местах проявится это "почти".

Пока вопросы закончились, ибо далее путь пока закрыт :))
 
Изменено:

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
@Старик Похабыч,
Офигеть - первый раз такую инфу узнаю. - благо что А4 и А5 свободны, попробую щас на них кинуть. (Нашел картинку в инете - и действительно...(y)(y)(y))
По адресам пока не замарачиваться?
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Спасибо огромное! Разобрался с подключением, заработало🥳
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
Скажите плиз, как правильно создать код для символа?
Нужен знак алгебраической суммы - по какому принципу идёт рассчёт байтов?
Ятак понимаю , что символ - это матрица , 5х8, надо просто нарисовать символ и вычислить число для конкретного столбика.
Нумерация пикселей идёт вниз-вправо? И степень двойки также возрастает - вниз и вправо?

=============
Разобрался )
снизу еще пустой ряд оставить надо, вроде как
 
Изменено:

Леви

✩✩✩✩✩✩✩
22 Фев 2023
1
0
Долго и муторно подключил я экранчик(0,96" oled Y+B) к стм после минуты работы выключаю, меняю частоту тактирования. все частоты меняются. экран не работает. Подключил к arduino UNO не работает, проверил адрес шины. адреса нет. Причём подключая такой-же дисплей он видит 0x3C по моему. Кто-то встречался с тем, что дисплеи умирали сами собой?
P.s. дисплей я проверил. подключил 100% правильно, даже пропаял всё что можно на модуле
 

Эдуард Анисимов

★★★★★★✩
23 Сен 2019
2,280
945
58
Марий-Эл
@Леви, Эти дисплеи бывают I2C и SPI. Иногда маркируются выводы одинаково, что при одном интерфейсе, что при другом и можно их перепутать. Мне попался дисплей с I2C, хотя я его покупал как SPI. Тоже была проблема с запуском. Из за этого даже пришлось плату переделывать.
 

Mix_man

✩✩✩✩✩✩✩
21 Янв 2020
91
9
А разве они не по количеству пинов различаются - сразу видно . 4pins - I2C , 7pins - SPI

@Леви, а ты на какие пины UNO подключал ?? I2C -свои конкретные пины , А4 А5. в другое место нельзя подключать. Работать не будет.