Последовательный порт и I2C не работают вместе
У меня есть проблема поважнее. Когда я запускаю этот код, SSD1306 не инициализируется. Выход на последовательной консоли: 20:26:33.194 -> MPU6050 OLED demo
20:26:33.532 -> Ошибка выделения SSD1306>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея, в пикселях
#define OLED_RESET 4 // Reset pin # (или -1 при совместном использовании Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int count =0;
void setup() {
Serial.begin(9600);
while (!Serial);
Serial.println("MPU6050 OLED demo");
if (!mpu.begin()) {
Serial.println("Sensor init failed");
while (1)
yield();
}
Serial.println("Found a MPU-6050 sensor");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
delay(500); // Pause for 2 seconds
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
display.clearDisplay();
display.setCursor(0, 0);
display.println("Accelerometer - m/s^2");
display.print(a.acceleration.x, 1);
display.print(", ");
display.print(a.acceleration.y, 1);
display.print(", ");
display.print(a.acceleration.z, 1);
display.println("");
display.println("Gyroscope - rps");
display.print(g.gyro.x, 1);
display.print(", ");
display.print(g.gyro.y, 1);
display.print(", ");
display.print(g.gyro.z, 1);
display.println("");
display.display();
delay(100);
}
Но когда я запускаю этот код, без отображения гироскопа все работает нормально. Отображается логотип Adafruit, а затем следуют регулярные данные акселерометра.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_Sensor.h>
#define SCREEN_WIDTH 128 // Ширина OLED-дисплея в пикселях
#define SCREEN_HEIGHT 64 // Высота OLED-дисплея, в пикселях
#define OLED_RESET 4 // Reset pin # (или -1 при совместном использовании Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_MPU6050 mpu;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int count =0;
void setup() {
//Serial.begin(9600);
//while (!Serial);
//Serial.println("MPU6050 OLED demo");
if (!mpu.begin()) {
//Serial.println("Sensor init failed");
while (1)
yield();
}
//Serial.println("Found a MPU-6050 sensor");
// SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Address 0x3C for 128x32
Serial.println(F("SSD1306 allocation failed"));
for (;;)
; // Don't proceed, loop forever
}
display.display();
delay(500); // Pause for 2 seconds
display.setTextSize(1);
display.setTextColor(WHITE);
display.setRotation(0);
}
void loop() {
sensors_event_t a, g, temp;
mpu.getEvent(&a, &g, &temp);
display.clearDisplay();
display.setCursor(0, 0);
display.println("Accelerometer - m/s^2");
display.print(a.acceleration.x, 1);
display.print(", ");
display.print(a.acceleration.y, 1);
display.print(", ");
display.print(a.acceleration.z, 1);
display.println("");
display.println("Gyroscope - rps");
display.print(g.gyro.x, 1);
display.print(", ");
display.print(g.gyro.y, 1);
display.print(", ");
display.print(g.gyro.z, 1);
display.println("");
display.display();
delay(100);
}
Теперь, во время отладки, когда я отключаю серийные журналы и комментирую все Serial.print, то приведенный выше код работает правильно, отображается логотип, акселерометр и гироскоп оба данных отображаются на OLED правильно.
Журнал компилятора для нерабочего кода таков: Sketch использует 21980 байт (71%) пространства для хранения программ. Максимум-30720 байт. Глобальные переменные используют 761 байт (37%) динамической памяти, оставляя 1287 байт для локальных переменных. Максимум-2048 байт.
Установка, которую я использую как Arduino Nano, MPU6050 подключена через I2C (адрес 0x68), SSD1306 основан на 0.96" 128x64 дисплее через I2C (адрес 0x3D). Я использую контакты A4 и A5 Arduino Nano в качестве I2C. Оба устройства подключены по одной шине. Я использую макетную плату для тестирования.
PS: Оба кода компилируются без ошибок и предупреждений
@Pankaj, 👍0
Обсуждение2 ответа
SSD1306 использует много оперативной памяти. Почти вся твоя оперативка. Serial также использует довольно много оперативной памяти. Эти двое изо всех сил стараются работать вместе.
Существует специальная библиотека SSD1306 "только текст", которая использует значительно меньше оперативной памяти: https://github.com/greiman/SSD1306Ascii
Спасибо тебе, Маенко...
Это была проблема низкой оперативной памяти. SSD1306 занимает 1K, с MPU6050 и последовательной печатью, которую я включил, оставшаяся оперативная память составляет всего 5 байт, отсюда и проблема инициализации. Я следовал простым рекомендациям по уменьшению объема оперативной памяти
Прочтите эту тему https://stackoverflow.com/questions/8649174/checking-memory-footprint-in-arduino
Код для печати доступного SRAM.
Serial.print(availableMemory());
// проверка свободной ОЗУ для отладки. SRAM для ATmega328P = 2048 Кб.
int availableMemory() {
// Use 1024 with ATmega168
int size = 2048;
byte *buf;
while ((buf = (byte *) malloc(--size)) == NULL);
free(buf);
return size;
}
- Как подключить MPU9250 к NodeMCU с помощью SPI или I2C Slave?
- Последовательная связь между несколькими устройствами (или ардуино)
- Изменение адреса I2C MPU-6050
- MPU6050 не выдает выход
- MPU-9250 IMU на SPI, внешнем датчике или магнитометре с использованием мастера I2C
- Проблемы с I2C и Wire.Available()
- Параллельная связь между несколькими Ардуино
- Использование MPU-6050 без I2C
В чем разница между этими скетчами?, @Sim Son
Внес исправления, я допустил ошибку при копировании и вставке комментариев, @Pankaj