Как правильно подключить устройства I2C к Arduino Nano. Какие выводы на Arduino Nano используются для SDA и SCL. Как настроить и использовать интерфейс I2C на Arduino Nano. Какие распространенные проблемы возникают при работе с I2C на Arduino Nano и как их решить.
Что такое I2C и зачем он нужен на Arduino Nano
I2C (Inter-Integrated Circuit) — это последовательный протокол связи, разработанный компанией Philips для соединения микроконтроллеров и периферийных устройств на короткие расстояния. Он использует всего два провода для передачи данных между устройствами:
- SDA (Serial Data) — линия для передачи данных
- SCL (Serial Clock) — линия тактового сигнала
I2C позволяет подключить к Arduino Nano множество различных датчиков, дисплеев, модулей памяти и других устройств, используя минимальное количество проводов. Это делает его очень удобным для создания компактных проектов.
Расположение выводов SDA и SCL на Arduino Nano
На Arduino Nano выводы для I2C расположены следующим образом:
- A4 — вывод SDA (линия данных)
- A5 — вывод SCL (линия тактового сигнала)
Эти выводы имеют встроенные подтягивающие резисторы, поэтому в большинстве случаев не требуется подключать внешние резисторы. Однако при использовании длинных проводов или подключении нескольких устройств может потребоваться добавить внешние подтягивающие резисторы номиналом 4.7-10 кОм.
Подключение устройств I2C к Arduino Nano
Для подключения устройства I2C к Arduino Nano необходимо выполнить следующие шаги:
- Подключить вывод SDA устройства к выводу A4 Arduino Nano
- Подключить вывод SCL устройства к выводу A5 Arduino Nano
- Подключить питание устройства (обычно 3.3В или 5В) к соответствующему выводу Arduino Nano
- Подключить GND устройства к GND Arduino Nano
Если подключается несколько устройств I2C, их выводы SDA и SCL подключаются параллельно к одним и тем же выводам Arduino Nano.
Настройка и использование I2C на Arduino Nano
Для работы с I2C на Arduino Nano используется библиотека Wire. Вот основные шаги по настройке и использованию I2C:
- Подключить библиотеку Wire в начале скетча:
#include <Wire.h>
- Инициализировать I2C в функции setup():
Wire.begin();
- Для отправки данных на устройство:
Wire.beginTransmission(address); Wire.write(data); Wire.endTransmission();
- Для чтения данных с устройства:
Wire.requestFrom(address, bytesToRead); while(Wire.available()) { byte data = Wire.read(); }
Здесь address — это 7-битный адрес I2C устройства, который обычно указан в документации к нему.
Сканирование шины I2C для поиска подключенных устройств
Чтобы определить адреса подключенных устройств I2C, можно использовать сканер шины. Вот пример кода для сканирования:
#include <Wire.h>
void setup() {
Wire.begin();
Serial.begin(9600);
Serial.println("I2C Scanner");
}
void loop() {
byte error, address;
int nDevices = 0;
Serial.println("Scanning...");
for(address = 1; address < 127; address++ ) {
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0) {
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000);
}
Этот код проверяет все возможные адреса I2C и выводит найденные устройства в Serial Monitor.
Распространенные проблемы при работе с I2C на Arduino Nano
При работе с I2C на Arduino Nano могут возникнуть следующие проблемы:
- Устройство не обнаруживается: проверьте правильность подключения и адрес устройства
- Ошибки передачи данных: убедитесь, что длина проводов не слишком большая и используются подтягивающие резисторы
- Конфликты адресов: убедитесь, что все устройства на шине имеют уникальные адреса
- Проблемы с питанием: некоторые устройства требуют отдельного стабильного питания
В случае с AW9523B важно обратить внимание на вывод RSTN (Reset). Он должен быть подтянут к высокому уровню через резистор 10 кОм, чтобы микросхема вышла из состояния сброса и начала работать.
Особенности работы с расширителем ввода-вывода AW9523B
AW9523B - это 16-канальный расширитель ввода-вывода с интерфейсом I2C. При работе с ним на Arduino Nano следует учитывать несколько моментов:
- Подключение RSTN: Вывод RSTN (23) должен быть подтянут к VCC через резистор 10 кОм. Это выводит микросхему из состояния сброса.
- Адресация: AW9523B имеет два адресных вывода AD0 и AD1, позволяющих задать один из четырех возможных адресов устройства.
- Питание: Убедитесь, что питание подается стабильно. Рекомендуется использовать конденсатор 0.1 мкФ между VCC и GND рядом с микросхемой.
- Инициализация: После подачи питания требуется некоторое время для инициализации микросхемы. Рекомендуется добавить задержку около 1 мс после Wire.begin() перед началом обмена данными.
Вот пример базовой инициализации AW9523B на Arduino Nano:
#include <Wire.h>
#define AW9523B_ADDR 0x58 // Базовый адрес, может меняться в зависимости от AD0 и AD1
void setup() {
Wire.begin();
Serial.begin(9600);
delay(1); // Задержка для инициализации AW9523B
// Проверка связи с AW9523B
Wire.beginTransmission(AW9523B_ADDR);
byte error = Wire.endTransmission();
if (error == 0) {
Serial.println("AW9523B найден!");
} else {
Serial.println("AW9523B не обнаружен. Проверьте подключение.");
}
}
void loop() {
// Ваш код для работы с AW9523B
}
Практические примеры использования I2C на Arduino Nano
Рассмотрим несколько практических примеров использования I2C на Arduino Nano:
1. Считывание данных с датчика температуры и влажности DHT20
#include <Wire.h> #define DHT20_ADDR 0x38 void setup() { Wire.begin(); Serial.begin(9600); } void loop() { Wire.beginTransmission(DHT20_ADDR); Wire.write(0xAC); // Команда на измерение Wire.write(0x33); Wire.write(0x00); Wire.endTransmission(); delay(80); // Ожидание измерения Wire.requestFrom(DHT20_ADDR, 7); if (Wire.available() == 7) { Wire.read(); // Пропускаем первый байт uint32_t hum = Wire.read(); hum = (hum << 8) | Wire.read(); hum = (hum << 4) | (Wire.read() >> 4); float humidity = hum / 1048576.0 * 100; uint32_t temp = Wire.read() & 0x0F; temp = (temp << 8) | Wire.read(); temp = (temp << 8) | Wire.read(); float temperature = temp / 1048576.0 * 200 - 50; Serial.print("Влажность: "); Serial.print(humidity); Serial.print("%, Температура: "); Serial.print(temperature); Serial.println("°C"); } delay(2000); }
2. Вывод текста на OLED-дисплей SSD1306
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Wire.begin();
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println("Hello, World!");
display.display();
}
void loop() {
// Дополнительный код
}
3. Сохранение данных в EEPROM AT24C256
#include <Wire.h>
#define EEPROM_ADDR 0x50
void writeEEPROM(unsigned int address, byte data) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((int)(address > > 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
Wire.write(data);
Wire.endTransmission();
delay(5); // Задержка для завершения записи
}
byte readEEPROM(unsigned int address) {
Wire.beginTransmission(EEPROM_ADDR);
Wire.write((int)(address >> 8)); // MSB
Wire.write((int)(address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(EEPROM_ADDR, 1);
if (Wire.available())
return Wire.read();
else
return 0xFF;
}
void setup() {
Wire.begin();
Serial.begin(9600);
// Пример записи и чтения
writeEEPROM(0, 123);
byte readValue = readEEPROM(0);
Serial.print("Read value: ");
Serial.println(readValue);
}
void loop() {
// Дополнительный код
}
Эти примеры демонстрируют различные способы использования I2C на Arduino Nano для работы с распространенными устройствами. Они показывают, как инициализировать связь, отправлять команды и читать данные с использованием протокола I2C.
Как использовать связь I2C на Arduino? Arduino I2C Tutorial
В этом руководстве мы увидим, как настроить и использовать связь I2C на Arduino. В этом руководстве по Arduino I2C объясняются выводы I2C в Arduino, настройка главного и подчиненного устройств и, наконец, простая демонстрация, в которой две платы Arduino UNO обмениваются данными через I2C.
Схема
Что такое I2C?
I2C или I 2 C — это сокращение от Inter-Integrated Circuit, протокола синхронной последовательной связи, разработанного Phillips для связи между быстрым микроконтроллером и относительно медленными периферийными устройствами (такими как память или датчики) с использованием всего двух проводов. Следовательно, его иногда также называют TWI (двухпроводной интерфейс).
Используя I2C, вы можете передавать данные со скоростью 100 кбит/с (тактовая частота 100 кГц — стандартный режим), 400 кбит/с (тактовая частота 400 кГц — быстрый режим), 1 Мбит/с (тактовая частота 1 МГц — быстрый режим Plus) и 3,4 Мбит/с (тактовая частота 3,4 МГц — режим высокой скорости).
Это может показаться немного, но этого достаточно для сопряжения датчиков, памяти и дисплеев на небольших расстояниях.
Шина I2C
Шина I2C состоит из двух проводов, называемых последовательными данными (SDA) и последовательными часами (SCL). Данные передаются по линии SDA, а линия SCL используется для синхронизации устройств с тактовым сигналом.
Обе эти линии шины являются драйверами с открытым стоком, и поэтому вы должны использовать подтягивающие резисторы, чтобы поддерживать их ВЫСОКИЙ уровень.
Существует два типа устройств, которые подключаются к шине I2C: Master и Slave. Мастера шины отвечают за отправку и получение данных на ведомые устройства и с них. Тактовый сигнал также подается мастером.
Сеть I2C поддерживает несколько мастеров и несколько ведомых (но обычно мы видим одного ведущего и несколько ведомых). Каждое ведомое устройство, подключенное к шине I2C, имеет уникальный 7-битный адрес.
Используя этот адрес, ведущее устройство выбирает конкретное ведомое устройство для передачи данных (отправки или получения), и выбранное ведомое устройство отвечает в соответствии с запросом.
Я сделал подробное руководство по основам I 2 C Связь. Для получения дополнительной информации посетите « Основы связи I2C ».
I2C в Arduino
Arduino поддерживает связь I2C. Если вы посмотрите на распиновку Arduino UNO из руководства « ARDUINO UNO PINOUT », вы увидите, что контакты аналогового входа A4 и A5 имеют альтернативную функцию I2C.
Контакт A4 действует как SDA, а контакт A5 действует как SCL. В R3 оригинальной Arduino UNO есть еще два контакта рядом с выводом 13 цифрового ввода-вывода (рядом с разъемом USB), предназначенными для SDA и SCL.
Если вы используете любую другую плату, вам будет полезна следующая таблица, так как в ней описаны выводы I2C на всех популярных платах Arduino.
Доска | Контакты SDA и SCL |
Ардуино УНО | А4 и А5 |
Ардуино Нано | А4 и А5 |
Ардуино Мега 2560 | 20 и 21 |
Ардуино Микро | 2 и 3 |
Ардуино Леонардо | 2 и 3 |
Микроконтроллер ATmega328P, используемый в Arduino UNO и Nano, поддерживает скорость передачи данных I2C до 400 кГц.
Как использовать интерфейс Arduino I2C?
Чтобы продемонстрировать работу I2C в Arduino, давайте создадим небольшую схему. В этой демонстрации я соединил две платы Arduino UNO для связи по шине I2C. Чтобы сделать все интереснее и на самом деле увидеть связь, я добавил пару светодиодов и потенциометров (по одному набору для каждой платы UNO).
Потенциометры подключены к соответствующим контактам аналогового входа (A0), а светодиоды подключены к контакту цифрового ввода-вывода с ШИМ (контакт 9). Одна плата UNO настроена как ведущая шина I2C, а другая UNO настроена как ведомое устройство.
Когда я настраиваю потенциометр, подключенный к Master Arduino UNO, он захватывает аналоговое показание с POT, преобразует его в цифровое значение (в диапазоне 0–1023), сопоставляет его с правильным значением ШИМ (в диапазон от 0 до 255) и передает это значение на ведомое устройство Arduino по шине I2C.
Подчиненное устройство Arduino, получив значение ШИМ, регулирует яркость своего светодиода. Кроме того, ведомая плата Arduino отправляет значение собственного потенциометра, преобразованное в число ШИМ, в ведущую плату Arduino (по запросу ведущей).
Мастер Arduino затем считывает значение ШИМ с ведомого устройства Arduino и регулирует яркость своего светодиода в соответствии с этим значением. Эта связь продолжается и беспрепятственно повторяется по шине I2C.
Это простая схема для понимания коммуникации Arduino I2C. Вы можете изменить схему, чтобы создать сложную шинную сеть I2C с различными ведомыми устройствами, такими как ЖК-дисплей I2C, микросхема EEPROM, датчик атмосферного давления BMP180 и т. д. (метеостанция с регистрацией данных).
Необходимые компоненты
- Arduino UNO x 2
- Потенциометр 10 кОм x 2
- Светодиод 5 мм x 2
- Резистор 330 Ом x 2
- Макет
- Соединительные провода
- Блок питания макетной платы (дополнительно)
Принципиальная схема
На следующем изображении показана принципиальная схема для демонстрации Arduino I2C между двумя платами Arduino UNO.
Код
Чтобы запрограммировать периферийное устройство I2C в Arduino, вам необходимо разобраться в библиотеке Wire. Это основная библиотека, которая позволяет вам взаимодействовать с устройствами I2C или TWI через шину I2C (линии SDA и SCL).
Wire Library
Он поставляется с Arduino IDE, и вам не нужно ничего загружать дополнительно. Все, что вам нужно сделать, это включить библиотеку Wire для работы с I2C в Arduino.
#include
Библиотека Wire предоставляет вам 10 функций для разработки приложений, связанных с I2C. Это:
- Wire.begin()
- Wire.requestFrom()
- Wire.beginTransmission()
- Wire.endTransmission()
- Wire.write()
- Провод.доступный()
- Wire. read()
- Wire.SetClock()
- Wire.onReceive()
- Wire.onRequest()
Теперь давайте подробно рассмотрим некоторые важные функции Wire Library.
Функции библиотеки проводов
Wire.begin()
Используйте эту функцию для запуска связи I2C. Если вы передадите 7-битный адрес устройства в качестве аргумента этой функции, то устройство присоединится к шине I2C как ведомое, иначе оно присоединится как ведущее.
- Wire.begin() — Мастер
- Wire.begin(адрес) – Ведомый
Wire.beginTransmission(address)
Используйте эту функцию, чтобы начать передачу данных на ведомое устройство с указанным адресом.
Wire.write()
Как только вы начнете передачу с помощью вышеуказанной функции, вы можете начать отправку фактических данных с помощью функции Wire. write().
Вы также можете использовать эту функцию для записи данных от ведомого устройства к ведущему, когда ведущее устройство использует функцию Wire.RequestFrom().
- Wire.write(value) — Отправить однобайтовое значение
- Wire.write(string) — Отправить серию байтов в виде строки
- Wire.write(data, length) — Отправить массив данных указанной длины
Wire.endTransmission()
Чтобы завершить передачу данных I2C, используйте функцию Wire.endTransmission().
Wire.read()
Используйте эту функцию для чтения байта данных, которые были переданы от ведущего к ведомому или от ведомого к ведущему, когда мастер вызывает функцию Wire.requestFrom().
Wire.requestFrom()
Ведущее устройство I2C использует эту функцию для запроса байтов данных от ведомого устройства. Используйте функцию Wire.read() для получения данных.
- Wire.requestFrom(адрес, количество) – Запрос количества байтов данных, указанных количеством, от ведомого устройства с адресом, указанным в поле адреса.
Wire.onReceive()
Это функция-обработчик, используемая для определения функции, которая вызывается, когда ведомое устройство получает данные от ведущего устройства.
Wire.onRequest()
Это функция-обработчик, используемая для определения функции, которая вызывается, когда мастер запрашивает данные у ведомого.
Master Code
Используя вышеупомянутые функции, я написал простой код для Master Arduino, чтобы отправить значение PWM, а также запросить байт данных от Slave.
Код ведомого устройства
В коде ведомого устройства Arduino я определил адрес ведомого устройства как 0x14. Это может быть любое значение меньше 128. Важно отметить, что в ArduinoI2C Wire Library I используется 7-битный адрес I2C без бита чтения/записи.
Итак, если у вас есть 8-битный адрес (который включает в себя бит R/W), сдвиньте адрес вправо на 1 и затем используйте его в Wire Library. Библиотека автоматически изменит адрес в зависимости от операции чтения или записи.
Кроме того, убедитесь, что адрес ведомого устройства уникален и никакие два ведомых устройства не должны иметь одинаковый адрес.
Возвращаясь к коду, я объявил две функции «DataReceive» и «DataRequest», которые будут вызываться при получении данных ведомым устройством или при запросе данных от ведомого устройства. Данные, полученные Ведомым в функции DataReceive, содержат значение ШИМ, отправленное Ведущим.
Данные, которые должны быть переданы через функцию DataRequest, представляют собой значение ШИМ от ведомого к ведущему.
Заключение
В этом руководстве демонстрируется простая двусторонняя связь между двумя платами Arduino с использованием связи I2C. Вы узнали о периферийном устройстве Arduino I2C, нескольких важных основах связи I2C, библиотеке проводов, а также о том, как настроить и использовать связь Arduino I2c.
AW9523B I2C на Arduino Nano
Задавать вопрос
спросил
Изменено 1 год, 6 месяцев назад
Просмотрено 157 раз
Я тестирую расширитель ввода-вывода AW9523B с Arduino Nano. У меня не получается распознать устройство.
Использование сканера I2C для поиска всех подключенных устройств I2C.
Я подключил AW9523B к правильным выводам к контактам SDA/SCL Arduino с подтяжкой 5K. INTN подключен к GND.
EEPROM также подключен к шине. EEPROM распознается на шине. Я поменял местами контакты SDA/SCL, чтобы убедиться, но AW9523B по-прежнему не был обнаружен на шине.
Я пробовал менять контакты AD0 и AD1, но безрезультатно.
У меня есть конденсатор 22 мкФ на VCC.
Изменение вывода AD0 изменяет состояние подключенного светодиода по умолчанию, поэтому я вполне уверен, что микросхема не умерла.
Я также попробовал два скетча из примера:
https://github.com/mrmx/AW9523B
Любопытно, удалось ли кому-нибудь заставить работать AW9523B.
Обновленная рабочая схема
- ардуино-нано
- i2c
6
Расшифровка и добавление к ответу из комментариев.
AW9523B имеет контакт 23 сброса (RSTN), на который внутренне подается низкий уровень резистором 100 кОм (т. е. по умолчанию = сброс). @Majenko предлагает подключить подтягивающий резистор 10 кОм к + 5 В (т. Е. Без сброса), чтобы включить чип.
Схемы листа данных и раздел, описывающий функцию сброса (стр. 14), по-видимому, предполагают, что контакт RSTN будет подключен к контакту MCU GPO, используемому для динамического управления функцией сброса.