Подключенный по I2C OLED дисплей SSD1306 останавливается на заставке

Здравствуйте.Файл с исходником
Помогите пожалуйста заставить дисплей отображать данные параллельно с их трансляцией по порту UART. Вынутые из примера команды не помогают. Отдельно пример Adafruit на дисплее работает.

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

  1. Что хотите получить.
  2. Что для этого делаете.
  3. Чем то, что получается, отличается от 1.

Ну и привести в сообщении схему и скетч полностью (именно те, что у Вас, а не похожие из И-нета).

#include "HX711.h"                 // Подключаем библиотеку HX711

HX711 scale;                       // Создаём объект scale 

#define DT  7                      // Указываем номер вывода, к которому подключен вывод DT  датчика HX711
#define SCK 6                      // Указываем номер вывода, к которому подключен вывод SCK датчика HX711

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128           // OLED display width, in pixels
#define SCREEN_HEIGHT 32           // OLED display height, in pixels
#define OLED_RESET -1        // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C  ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

float calibration_factor = 1936.24;  // Вводим калибровочный коэффициент
float units;                       // Задаём переменную для измерений в граммах
float ounces;                      // Задаём переменную для измерений в унциях
int buttonPin = 2;                  // Кнопка - к D2
int currentButtonState = 1;         // Потенциал на кнопке

void setup()
{
  Serial.begin(9600);             // Инициируем работу последовательного порта на скорости 9600 бод
  scale.begin(DT, SCK, 128);            // Инициируем работу с датчиком с усилением 128
  scale.set_scale(calibration_factor); // Устанавливаем калибровочный коэффициент
  pinMode(buttonPin, INPUT_PULLUP);   // Задаем режим работы пина как вход с подтягивающим резистором
  scale.tare(10);

  Wire.begin();                       //Begins I2C communication at pin (A4,A5)

  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;  // Don't proceed, loop forever
  }
 // display.display();
 // delay(1000);  // Pause
  display.clearDisplay();         // Clear the buffer
  display.cp437(true);
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
}

void loop() {
  currentButtonState = digitalRead(buttonPin);
  if (currentButtonState == LOW)
  {
    // Кнопка нажата
    scale.tare(10);
  } 
  Serial.print("Вес: ");         // Выводим текст в монитор последовательного порта
  display.print("Вес: ");
  ounces = scale.get_units(10);     // Осредняем показания 10 замеров
  units = ounces * 28.35;
  Serial.print(units);              // Выводим в монитор последовательного порта вес в граммах
  display.print(units);
  Serial.println(" грамм");          // Выводим текст в монитор последовательного порта
  display.println(" грамм");
  }

Подключение дисплея:
SDA - A4
SCL - A5
VCC - +5V
GND - GND

SH711 на пинах:
DAT - D7
CLK - D6

Вы забыли подробно описать проблему.

Ну и сразу совет: раз в названии темы фигурирует слово “останавливается”, следовало бы указать строку скетча, на которой эта “остановка” происходит.
Для начала вставьте строку
Serial.println("Start");
между строками 28 и 29.
Ну и желательно также вставить какую-нибудь диагностическую печать где-то в районе строк 33, 41 и 48.

И еще подумайте, с какой частотой Вы опрашиваете датчик, и с какой его следует опрашивать.

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

Заставка - это что?
Т.е. что в приведенном коде выполняется, а что - нет?
И, кстати, я не увидел инициализации дисплея.

И еще:
Обычно для работы с 1306 используется буфер. Соответственно, все рисование осуществляется в буфере, а для вывода на экран вызывается функция, копирующая содержимое экрана в буфер. Ее у Вас я также не увидел.

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

В опубликованном исходники нет никаких намеков на рисование какой-либо заставки.
У вас точно OLED использован, а не LSD?

1 лайк

Да, у начинающих обычно LSD.

У адафрута в этой либе , заставка изначально в самой библиотеке в буфер забита.
Как то так:

Ну и собственно проблема ТС заключается в том, что он забыл саму команду вывода буфера на дисплей прописать:

display.display();

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

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "HX711.h"                 // Подключаем библиотеку HX711

HX711 scale;                       // Создаём объект scale 

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define DT  7                      // Указываем номер вывода, к которому подключен вывод DT  датчика HX711
#define SCK 6                      // Указываем номер вывода, к которому подключен вывод SCK датчика HX711

float calibration_factor = 1936.24;  // Вводим калибровочный коэффициент
float units;                       // Задаём переменную для измерений в граммах
float ounces;                      // Задаём переменную для измерений в унциях
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  
  pinMode(2, INPUT_PULLUP);          // Инициализируем кнопку сброса тары
  Serial.begin(9600);             // Инициируем работу последовательного порта на скорости 9600 бод
  scale.begin(DT, SCK, 128);            // Инициируем работу библиотеки с датчиком
  scale.set_scale(calibration_factor); // Устанавливаем калибровочный коэффициент
  scale.tare(10);                     // Сбрасываем значения веса на датчике в 0
 
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever

  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(1000); // Pause for 2 seconds

  // Clear the buffer
  display.clearDisplay();
  display.setTextSize(2);             // Normal 1:1 pixel scale
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner
}

void loop() {

 if(digitalRead(2) == LOW) {
     scale.tare(10); 
  };
  Serial.print("Вес: ");         // Выводим текст в монитор последовательного порта
  ounces = scale.get_units(10);     // Осредняем показания 10 замеров
  units = ounces * 28.35;
  Serial.print(units);              // Выводим в монитор последовательного порта вес в граммах
  Serial.println(" грамм");          // Выводим текст в монитор последовательного порта
  display.println(units);
  display.println("    world!");
  display.display();
  
}```

Программа правильно заработала только после указаний об очистке / буфере экрана и позиционировании начала.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "HX711.h"                 // Подключаем библиотеку HX711

HX711 scale;                       // Создаём объект scale 

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
#define DT  7                      // Указываем номер вывода, к которому подключен вывод DT  датчика HX711
#define SCK 6                      // Указываем номер вывода, к которому подключен вывод SCK датчика HX711

float calibration_factor = 1936.24;  // Вводим калибровочный коэффициент
float units = 0;                       // Задаём переменную для измерений в граммах
float units10 = 0;                     // Задаем переменную для осредненных измерений в граммах
float ounces = 0;                      // Задаём переменную для измерений в унциях
float ounces10 = 0;                     // Задаем переменную для осредненных измерений в унциях
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  
  pinMode(2, INPUT_PULLUP);          // Инициализируем кнопку сброса тары
  Serial.begin(9600);             // Инициируем работу последовательного порта на скорости 9600 бод
  scale.begin(DT, SCK, 128);            // Инициируем работу библиотеки с датчиком
  scale.set_scale(calibration_factor); // Устанавливаем калибровочный коэффициент
  scale.tare(10);                     // Сбрасываем значения веса на датчике в 0
 
 // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(1000); // Pause for 2 seconds
  display.clearDisplay();           // Clear display buffer
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  display.cp437(true);
  }

void loop() {
 
 // Serial.print("Вес: ");         // Выводим текст в монитор последовательного порта
 for (int i = 0; i < 10; i ++) {    // Усредняем показания, считав значения датчика 10 раз
    if(digitalRead(2) == LOW) {
     scale.tare(4); 
     };
    ounces = scale.get_units();
    units = ounces * 28.35;
    Serial.println(units);        // Отправляем в монитор порта неосредненные данные
    ounces10 = ounces10 + ounces; // Суммируем показания 10 замеров
  }
  ounces10 = ounces10 / 10;                // Усредняем показания, разделив сумму значений на 10
  units10 = ounces10 * 28.35;  
 // ounces = scale.get_units(10);     // Осредняем показания 10 замеров
 // Serial.println(units);              // Выводим в монитор последовательного порта вес в граммах
 // Serial.println(" грамм");          // Выводим текст в монитор последовательного порта
  display.clearDisplay();           // Clear display buffer
  display.setCursor(0,0);
  display.setTextSize(3);             // 3:3 pixel scale
  display.println(units10);
  display.setTextSize(1);             // 1:1 pixel scale
  display.println(utf8rus("усилие в граммах"));
  display.display();
  ounces10 = 0;
  units10 = 0;
}

/* Recode russian fonts from UTF-8 to Windows-1251 */
String utf8rus(String source)
{
  int i,k;
  String target;
  unsigned char n;
  char m[2] = { '0', '\0' };
  k = source.length(); i = 0;
  while (i < k) {
    n = source[i]; i++;
    if (n >= 0xC0) {
      switch (n) {
        case 0xD0: {
          n = source[i]; i++;
          if (n == 0x81) { n = 0xA8; break; }
          if (n >= 0x90 && n <= 0xBF) n = n + 0x30;
          break;
        }
        case 0xD1: {
          n = source[i]; i++;
          if (n == 0x91) { n = 0xB8; break; }
          if (n >= 0x80 && n <= 0x8F) n = n + 0x70;
          break;
        }
      }
    }
    m[0] = n; target = target + String(m);
  }
return target;
}
1 лайк