Неустранимая ошибка Adafruit_SSD1306.cpp: pgmspace.h: нет такого файла или каталога с использованием SSD1306 на Arduino Nano RP2040
В настоящее время я пытаюсь заставить дисплей SBC-OLED01 работать под управлением моего Arduino Nano RP2040. Я использую официальный пример Adafruit, прикрепленный код.
/*************************************************** **********************************
Это пример для наших монохромных OLED-дисплеев на основе драйверов SSD1306.
Возьмите один сегодня в магазине Adafruit!
------> http://www.adafruit.com/category/63_98
Этот пример относится к дисплею с разрешением 128x64 пикселей, использующему I2C для связи.
Для интерфейса требуется 3 контакта (два I2C и один сброс).
Adafruit инвестирует время и ресурсы, предоставляя этот открытый
исходный код, пожалуйста, поддержите Adafruit и открытый исходный код
оборудование, покупая продукты у Adafruit!
Написано Лимором Фридом/Ладьядой для Adafruit Industries,
при участии сообщества открытого исходного кода.
Лицензия BSD, дополнительную информацию см. в файле license.txt.
Весь текст выше и заставка ниже должны быть
включены в любое перераспределение.
******************************************************* ************************/
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея в пикселях
// Объявление для дисплея SSD1306, подключенного к I2C (контакты SDA, SCL)
// Пины для I2C определяются Wire-библиотекой.
// На Arduino UNO: A4(SDA), A5(SCL)
// На Arduino MEGA 2560: 20(SDA), 21(SCL)
// На Arduino LEONARDO: 2(SDA), 3(SCL), ...
#define OLED_RESET -1 // Номер вывода сброса (или -1, если общий вывод сброса Arduino)
#define SCREEN_ADDRESS 0x3C ///< См. спецификацию для адреса; 0x3D для 128x64, 0x3C для 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define NUMFLAKES 10 // Количество снежинок в примере анимации
#define LOGO_HEIGHT 16
#define LOGO_WIDTH 16
static const unsigned char PROGMEM logo_bmp[] =
{ 0b00000000, 0b11000000,
0b00000001, 0b11000000,
0b00000001, 0b11000000,
0b00000011, 0b11100000,
0b11110011, 0b11100000,
0b11111110, 0b11111000,
0b01111110, 0b11111111,
0b00110011, 0b10011111,
0b00011111, 0b11111100,
0b00001101, 0b01110000,
0b00011011, 0b10100000,
0b00111111, 0b11100000,
0b00111111, 0b11110000,
0b01111100, 0b11110000,
0b01110000, 0b01110000,
0b00000000, 0b00110000 };
void setup() {
Serial.begin(9600);
// SSD1306_SWITCHCAPVCC = генерировать внутреннее напряжение дисплея от 3,3 В
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Не продолжать, цикл навсегда
}
// Показать содержимое буфера начального отображения на экране --
// библиотека инициализирует это с помощью экрана-заставки Adafruit.
display.display();
delay(2000); // Пауза на 2 секунды
// Очистить буфер
display.clearDisplay();
// Рисуем один пиксель белым цветом
display.drawPixel(10, 10, SSD1306_WHITE);
// Показать буфер отображения на экране. Вы ДОЛЖНЫ вызывать display() после
// команды рисования, чтобы сделать их видимыми на экране!
display.display();
delay(2000);
// display.display() НЕ требуется после каждой отдельной команды рисования,
// если это то, что вы хотите... скорее, вы можете собрать кучу
// операции рисования, а затем сразу обновить весь экран, вызвав
// дисплей.дисплей(). Эти примеры демонстрируют оба подхода...
testdrawline(); // Рисуем много линий
testdrawrect(); // Рисуем прямоугольники (контуры)
testfillrect(); // Рисуем прямоугольники (заполненные)
testdrawcircle(); // Рисуем круги (контуры)
testfillcircle(); // Рисуем круги (заполненные)
testdrawroundrect(); // Рисуем прямоугольники со скругленными углами (контуры)
testfillroundrect(); // Рисуем прямоугольники со скругленными углами (заполненные)
testdrawtriangle(); // Рисуем треугольники (контуры)
testfilltriangle(); // Рисуем треугольники (закрашенные)
testdrawchar(); // Рисуем символы шрифта по умолчанию
testdrawstyles(); // Рисуем "стилизованные" символы
testscrolltext(); // Рисуем прокручиваемый текст
testdrawbitmap(); // Рисуем маленькое растровое изображение
// Инвертировать и восстановить отображение с паузой между ними
display.invertDisplay(true);
delay(1000);
display.invertDisplay(false);
delay(1000);
testanimate(logo_bmp, LOGO_WIDTH, LOGO_HEIGHT); // Анимация растровых изображений
}
void loop() {
}
void testdrawline() {
int16_t i;
display.clearDisplay(); // Очистить буфер дисплея
for(i=0; i<display.width(); i+=4) {
display.drawLine(0, 0, i, display.height()-1, SSD1306_WHITE);
display.display(); // Обновляем экран с каждой вновь нарисованной линией
delay(1);
}
for(i=0; i<display.height(); i+=4) {
display.drawLine(0, 0, display.width()-1, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=0; i<display.width(); i+=4) {
display.drawLine(0, display.height()-1, i, 0, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=display.height()-1; i>=0; i-=4) {
display.drawLine(0, display.height()-1, display.width()-1, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=display.width()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, i, 0, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=display.height()-1; i>=0; i-=4) {
display.drawLine(display.width()-1, display.height()-1, 0, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(250);
display.clearDisplay();
for(i=0; i<display.height(); i+=4) {
display.drawLine(display.width()-1, 0, 0, i, SSD1306_WHITE);
display.display();
delay(1);
}
for(i=0; i<display.width(); i+=4) {
display.drawLine(display.width()-1, 0, i, display.height()-1, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000); // Пауза на 2 секунды
}
void testdrawrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2; i+=2) {
display.drawRect(i, i, display.width()-2*i, display.height()-2*i, SSD1306_WHITE);
display.display(); // Обновляем экран с каждым вновь нарисованным прямоугольником
delay(1);
}
delay(2000);
}
void testfillrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2; i+=3) {
// Цвет INVERSE используется, поэтому прямоугольники чередуются белый/черный
display.fillRect(i, i, display.width()-i*2, display.height()-i*2, SSD1306_INVERSE);
display.display(); // Обновляем экран с каждым вновь нарисованным прямоугольником
delay(1);
}
delay(2000);
}
void testdrawcircle(void) {
display.clearDisplay();
for(int16_t i=0; i<max(display.width(),display.height())/2; i+=2) {
display.drawCircle(display.width()/2, display.height()/2, i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfillcircle(void) {
display.clearDisplay();
for(int16_t i=max(display.width(),display.height())/2; i>0; i-=3) {
// Используется ИНВЕРСНЫЙ цвет, поэтому круги чередуются белыми и черными
display.fillCircle(display.width() / 2, display.height() / 2, i, SSD1306_INVERSE);
display.display(); // Обновляем экран с каждым вновь нарисованным кругом
delay(1);
}
delay(2000);
}
void testdrawroundrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2-2; i+=2) {
display.drawRoundRect(i, i, display.width()-2*i, display.height()-2*i,
display.height()/4, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfillroundrect(void) {
display.clearDisplay();
for(int16_t i=0; i<display.height()/2-2; i+=2) {
// Цвет INVERSE используется, поэтому круглые прямоугольники чередуются белый/черный
display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i,
display.height()/4, SSD1306_INVERSE);
display.display();
delay(1);
}
delay(2000);
}
void testdrawtriangle(void) {
display.clearDisplay();
for(int16_t i=0; i<max(display.width(),display.height())/2; i+=5) {
display.drawTriangle(
display.width()/2 , display.height()/2-i,
display.width()/2-i, display.height()/2+i,
display.width()/2+i, display.height()/2+i, SSD1306_WHITE);
display.display();
delay(1);
}
delay(2000);
}
void testfilltriangle(void) {
display.clearDisplay();
for(int16_t i=max(display.width(),display.height())/2; i>0; i-=5) {
// Используется инвертированный цвет, поэтому треугольники чередуются белыми и черными.
display.fillTriangle(
display.width()/2 , display.height()/2-i,
display.width()/2-i, display.height()/2+i,
display.width()/2+i, display.height()/2+i, SSD1306_INVERSE);
display.display();
delay(1);
}
delay(2000);
}
void testdrawchar(void) {
display.clearDisplay();
display.setTextSize(1); // Обычный масштаб пикселя 1:1
display.setTextColor(SSD1306_WHITE); // Рисуем белый текст
display.setCursor(0, 0); // Начинаем с верхнего левого угла
display.cp437(true); // Использовать полный 256-символьный шрифт «Кодовая страница 437»
// Не все символы поместятся на дисплее. Это нормально.
// Библиотека нарисует то, что может, а остальное будет обрезано.
for(int16_t i=0; i<256; i++) {
if(i == '\n') display.write(' ');
else display.write(i);
}
display.display();
delay(2000);
}
void testdrawstyles(void) {
display.clearDisplay();
display.setTextSize(1); // Обычный масштаб пикселя 1:1
display.setTextColor(SSD1306_WHITE); // Рисуем белый текст
display.setCursor(0,0); // Начинаем с верхнего левого угла
display.println(F("Hello, world!"));
display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Рисуем «инверсный» текст
display.println(3.141592);
display.setTextSize(2); // Рисуем текст в масштабе 2X
display.setTextColor(SSD1306_WHITE);
display.print(F("0x")); display.println(0xDEADBEEF, HEX);
display.display();
delay(2000);
}
void testscrolltext(void) {
display.clearDisplay();
display.setTextSize(2); // Рисуем текст в масштабе 2X
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 0);
display.println(F("scroll"));
display.display(); // Показать исходный текст
delay(100);
// Прокрутка в разных направлениях с паузами между ними:
display.startscrollright(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrollleft(0x00, 0x0F);
delay(2000);
display.stopscroll();
delay(1000);
display.startscrolldiagright(0x00, 0x07);
delay(2000);
display.startscrolldiagleft(0x00, 0x07);
delay(2000);
display.stopscroll();
delay(1000);
}
void testdrawbitmap(void) {
display.clearDisplay();
display.drawBitmap(
(display.width() - LOGO_WIDTH ) / 2,
(display.height() - LOGO_HEIGHT) / 2,
logo_bmp, LOGO_WIDTH, LOGO_HEIGHT, 1);
display.display();
delay(1000);
}
#define XPOS 0 // индексирует массив 'icons' в функции ниже
#define YPOS 1
#define DELTAY 2
void testanimate(const uint8_t *bitmap, uint8_t w, uint8_t h) {
int8_t f, icons[NUMFLAKES][3];
// Инициализировать позиции «снежинки»
for(f=0; f< NUMFLAKES; f++) {
icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
icons[f][YPOS] = -LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
Serial.print(F("x: "));
Serial.print(icons[f][XPOS], DEC);
Serial.print(F(" y: "));
Serial.print(icons[f][YPOS], DEC);
Serial.print(F(" dy: "));
Serial.println(icons[f][DELTAY], DEC);
}
for(;;) { // Цикл навсегда...
display.clearDisplay(); // Очистить буфер отображения
// Рисуем каждую снежинку:
for(f=0; f< NUMFLAKES; f++) {
display.drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, SSD1306_WHITE);
}
display.display(); // Показать буфер отображения на экране
delay(200); // Пауза на 1/10 секунды
// Затем обновляем координаты каждой чешуйки...
for(f=0; f< NUMFLAKES; f++) {
icons[f][YPOS] += icons[f][DELTAY];
// Если снежинка находится за пределами нижней части экрана...
if (icons[f][YPOS] >= display.height()) {
// Повторная инициализация в случайном месте, чуть выше
icons[f][XPOS] = random(1 - LOGO_WIDTH, display.width());
icons[f][YPOS] = -LOGO_HEIGHT;
icons[f][DELTAY] = random(1, 6);
}
}
}
}
Я скачал оптимизированную библиотеку Adafruit GFX с github и установил ее, как описано. В качестве платы я использую Arduino Nano RP2040 из ОС Arduino Mbed версии 3.4.1.
Теперь, когда я компилирую код, я получаю следующую ошибку:
[...]Arduino\libraries\Adafruit_SSD1306\Adafruit_SSD1306.cpp:42:10: fatal error: pgmspace.h: No such file or directory
#include <pgmspace.h>
^~~~~~~~~~~~
compilation terminated.
exit status 1
Compilation error: exit status 1
К сожалению, я не нашел в сети решения, как решить проблему, поэтому сейчас написал этот вопрос. Я попробовал "нормальный" Библиотека GFX из менеджера пакетов вместо оптимизированной, с тем же результатом. Я предполагаю, что ошибка в библиотеке Adafruit_SSD1306, так что в любом случае это не имеет никакого значения.
@JohnDizzle, 👍2
Обсуждение1 ответ
Происходит следующее: в включенной вами библиотеке есть другая библиотека: есть два решения: удалить #include pgmspace.h в одной из этих библиотек или просто получить pgmspace.h. Надеюсь, это поможет!
- Одинаковый вывод на дисплеях с разными I2C-адресами (библиотека AdaFruit, ESP32)
- Ошибка компиляции для платы Arduino Nano при использовании Adafruit GFX
- Не нашел датчик отпечатков пальцев :( Arduino Mega 2560 Adafruit Fingerprint Sensor
- Почему Adafruit motor shield не крутит моторы?
- Какие компоненты мне нужны маленького GPS-трекера
- Статус выхода 1 ожидаемое первичное выражение перед ']' Arduino
- Есть ли функция Adafruit для инвертирования цветов моего экрана для языка Arduino?
- Библиотека программных материалов для плат SAMD
Первая запись, которая появилась у меня в Google, касается той же проблемы с другой библиотекой того же разработчика. См. [https://github.com/Bodmer/TFT_eSPI/issues/1148](https://github.com/Bodmer/TFT_eSPI/issues/1148). Обходной путь/решение здесь, по-видимому, состоит в том, чтобы закомментировать строку
#include <pgmspace.h>
в Adafruit_SSD1306.cpp., @StarCatв
Adafruit_SSD1306.cpp
попробуйте удалить|| определено (ARDUINO_ARCH_RP2040)
в строке 41, которое, я думаю, было добавлено для «пикоядра», которое Adafruit предпочитает для своих плат RP2040., @Juraj