Arduino i2c сколько можно подключить устройств
Перейти к содержимому

Arduino i2c сколько можно подключить устройств

  • автор:

Arduino.ru

Подключение нескольких I2C устройств с одинаковыми адресами

  • Войдите на сайт для отправки комментариев

Пт, 11/11/2016 — 20:15
Зарегистрирован: 06.11.2016

При проектировании генератора, возникла проблема — необходимо вывести на индикатор 8 разрядов, а вналичии есть два четырехразрядных индикатора на микросхемах TM 1650 или FD650В. Проблема в том, что они управляются по шине I2C и имеют одинаковые адреса. Для решения конкретной задачи (генератор до 4000 Гц), это вполне устраивало, и первый вариант успешно со своей задачей справился http://arduino.ru/forum/programmirovanie/kontroller-led-i-klaviatury-fd650v-kak-im-upravlyat#comment-232263Далее захотелось использовать генератор по максимуму (до 8 МГц), для этого нужно было увеличить число разрядов до 8. Порывшись в инете нашел в основном теорию и использование специальных микросхем, которых в наличии нет. В результате появилась такая конструкция:

Подключается к аппаратному порту I2C ардуино, а дисплеи к выходному разъему. CSL идет напрямую, а SDA rjvvкоммутируются транзисторами Q1 и Q2. Переключение осуществляется логическими 0 или 1 с пина А3. В принципе можно поменять CSL и SDA при этом работоспособность сохраняется. Управление можно тоже взять с любого свободного выхода. Остальные I2C устройства с уникальными адресами подключаются стандартно.

При необходимости количество устройств с одинаковыми адресами можно увеличить используя дешифратор.

Пример применения в скетче. Отличия от скетча с четырехразрядной индикации в строках 24,62,66,70,138-157

#include long rez; byte scan_code,dl; byte sr[8];// массив разрядов индикатора //массив изображений 7 сегментных символов от 0 до 9 и пустота byte simv[11]=< B00111111, //0 B00000110, //1 B01011011, //2 B01001111, //3 B01100110, //4 B01101101, //5 B01111101, //6 B00000111, //7 B01111111, //8 B01101111, //9 B00000000, //пустота >; void setup() < //Serial.begin(9600); pinMode(A3, OUTPUT);// *********** ПОРТ УПРАВЛЕНИЯ I2C ХАБОМ ************* Wire.begin(); // *********инициализация таймеров генератора************ pinMode (9,OUTPUT); // выход генератора TCCR1A=1void loop() < //********************* чтение клавиатуры ************************* readkl: Wire.beginTransmission(0x25); // обращаемся к клавиатуре(к любому порту 0х24-0х27) Wire.requestFrom((0x25), 1); //запрашиваем один байт scan_code = Wire.read(); // читаем скан код Wire.endTransmission(); // закрываем сессию if (scan_code <69) goto readkl; if (scan_code ==70 )scan_code =1; if (scan_code ==69 )scan_code =2; if (scan_code ==79 )scan_code =3; if (scan_code ==101)scan_code =4; if (scan_code ==87 )scan_code =5; if (scan_code ==117)scan_code =6; if (scan_code ==103)scan_code =7; if (scan_code ==102)scan_code =8; if (scan_code ==119)scan_code =9; if (scan_code ==78 )scan_code =0; if (scan_code ==110)rez=0;sr[1]=0;sr[2]=0;sr[3]=0;sr[4]=0; // обнулить if (scan_code ==94 )// коррекция if (scan_code wuw: //Serial.println(rez); //Выделяем разряды и записываем их в массив разрядов индикатора sr[0]=(rez%10); sr[1]=(rez%100/10); sr[2]=(rez%1000/100); sr[3]=(rez%10000/1000); sr[4]=(rez%100000/10000); sr[5]=(rez%1000000/100000); sr[6]=(rez%10000000/1000000); sr[7]=(rez%100000000/10000000); // адреса разрядов индикатора // 1-0х34 // 2-0х35 // 3-0х36 // 4-0х37 // ******** ПИШЕМ В ОСНОВНОЙ ДИСПЛЕЙ ********* Wire.beginTransmission(0x37);//Пишем в 4 разряд Wire.write(simv[sr[0]]); Wire.endTransmission(); // закрываем сессию Wire.beginTransmission(0x36);//Пишем в 3 разряд Wire.write(simv[sr[1]]); Wire.endTransmission(); // закрываем сессию Wire.beginTransmission(0x35);//Пишем вo 2 разряд Wire.write (simv[sr[2]]); Wire.endTransmission(); // закрываем сессию Wire.beginTransmission(0x34);//Пишем в 1 разряд Wire.write(simv[sr[3]]);// Wire.endTransmission(); // закрываем сессию digitalWrite(A3, 0);// ********* ПЕРЕКЛЮЧАЕМСЯ НА ВТОРОЙ ДИСПЛЕЙ ********** Wire.beginTransmission(0x37);//Пишем в 4 разряд Wire.write(simv[sr[4]]); Wire.endTransmission(); // закрываем сессию Wire.beginTransmission(0x36);//Пишем в 3 разряд Wire.write(simv[sr[5]]); Wire.endTransmission(); // закрываем сессию Wire.beginTransmission(0x35);//Пишем вo 2 разряд Wire.write (simv[sr[6]]); Wire.endTransmission(); // закрываем сессию Wire.beginTransmission(0x34);//Пишем в 1 разряд Wire.write(simv[sr[7]]);// Wire.endTransmission(); // закрываем сессию digitalWrite(A3, 1);// ********** ВОЗВРАЩАЕМСЯ НА ОСНОВНОЙ ДИСПЛЕЙ ************ delay(200); //_________________ * ГЕНЕРАТОР * _________________ //http://arduino.ru/forum/proekty/generator-s-reguliruemoei-chastotoi-na-arduino?page=3 static uint32_t enc=1; //переменная счёта энкодера uint32_t ocr; uint32_t divider; float freq; enc = rez; //передаем значение частоты в герцах в ГЕНЕРАТОР //расчёт прескалера и OCR по нужной частоте divider=1; ocr = (F_CPU / enc /2 /divider); if (ocr >65536) < divider=8; ocr = F_CPU / enc /2 /divider; if (ocr >65536) < divider=64; ocr = F_CPU / enc /2 /divider; if (ocr >65536) 65536) < divider=1024; ocr = F_CPU / enc /2 /divider; if (ocr >65536)>>>> OCR1A=ocr-1; //запись в регистр прескалера switch (divider) < case 1: TCCR1B=1|(1<>
  • Войдите на сайт для отправки комментариев

Интерфейс I2C в Arduino

Как расширить функциональность разрабатываемой системы на основе микроконтроллера? Да, этот вопрос интересует многих схемотехников, работающими над прототипами электронных устройств. Удивительно, но добавить к системе новые блоки, не изменяя схемы, позволит шина, разработанная инженерами Philips более 30 лет назад.

Благодаря интерфейсу I2C можно превратить микроконтроллер в простой конструктор, к которому можно подключить несколько сотен микросхем. Сразу стоит отметить, что их количество ограничивается емкостью шины в 400 пФ, но это один из немногих недостатков I2C.

Схема внутренней связи – так можно расшифровать название шины, которую сегодня можно встретить практически в каждом электронном устройстве. Стоит отметить, что в Philips запатентовали столь удачное в практическом плане решение и другие производители дублировали I2C под другими названиями.

Именно эта шина устанавливается для связи с внешним миром дисплеев, камер, сотовых телефонов. Количество периферических устройств, подключаемых к устройствам с помощью I2C, вообще не поддается учету. В чем же преимущества интерфейса?

Основные достоинства и недостатки I2C

I2C – последовательная асимметричная шина для связи между интегральными схемами внутри электронных приборов. Использует две двунаправленные линии связи (SDA и SCL).

Шина представляет собой два проводника, а для управления интерфейсом достаточно одного микроконтроллера. Удивительно, но подобная простота позволяет производить отключение микросхем в процессе работы. Специальный встроенный фильтр способен справляться с всплесками, гарантируя сохранность обрабатываемой информации.

Среди недостатков I2C, кроме ограниченной емкости, сложность программирования и трудность с определением неисправности в ситуации с состоянием низкого уровня.

Изначально скорость шины была всего 100 кбит, а подключить к ней было можно всего 120 устройств. В 90-х годах стандарты изменились и скорость передачи данных увеличилась в 4 раза и появилась возможность подключения до 1000 микросхем.

Однако большинство производителей интерфейса зациклились на 400 кбит с подключением 120 устройств.

Принцип подключения и работы

Интерфейс I2C в Arduino

Проводники шины подсоединены к плюсу резисторами 1-10к, один из проводников является шиной данных, другой – тактирование. Работает такая схема просто: на линии есть одно ведущее устройство (микроконтроллер) и несколько периферийных устройств. Так как линии запитаны на плюсе, то подключенному слейву (ведомому элементу) достаточно прижать провод к земле и передать тем самым 0.

Когда периферическое устройство отпускает провод, по проводнику передается 1. Все элементарно, но если при совместной работе один из слейвов выдал 0, то остальным подключенным к шине устройствам придется подождать. Осуществляет тактирование и передачу микроконтроллер, предварительно уточнив, свободна ли линия. Для этого передается 1 на SCL и SDA, после чего создается старт-условие – прижимается линия SDA при значении SCL равном 1.

Следующим этапом работы является передача адреса того устройства, к которому нужно обратиться.

При этом нужно помнить, что считывание данных осуществляется при SCL =1, а передача идет вперед старшим битом.

Первые 7 бит – адрес устройства, 8 – команда записать (0) или читать (1).

Слейв получит все восемь сигналов, прижмет линию SDA на девятом такте SCL если ему все понятно. Если нет – то формируется сигнал стоп и передача данных осуществляется снова. При завершении работы отпускается линия SDA, при этом SCL не трогают.

Даже в том случае, если подключенная микросхема медленно обрабатывает сигнал, все равно она придержит SCL.

Режим работы multi-master

I2C - режим работы multi-master

Вопросы демократии в схемотехнике регламентируются правилом монтажного И. В его основе лежит способность ведущего устройства контролировать результат работы. Обязательно перепроверяется – отпущена линия или нет, если она отпустилась – то мастер на данный момент ведущий, если нет – то что-то более важное пока держит линию. В этом случае нужно подождать просвет и сделать свою работу, когда таковой появится.

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

Четырехразрядный индикатор LED, FLASH-I2C

Модуль относится к серии «Flash», а значит к одной шине I2C можно подключить более 100 модулей, так как их адрес на шине I2C (по умолчанию 0x09), хранящийся в энергонезависимой памяти, можно менять программно.

Модуль является устройством вывода информации, его можно использовать для отображения чисел (в том числе и отрицательных), времени, температуры и некоторых символов.

Видео:

Подключение:

Перед подключением модуля ознакомьтесь с разделом «Смена адреса модуля на шине I2C» в данной статье.

На плате модуля расположен разъем из 4 выводов для подключения к шине I2C.

  • SCL — вход/выход линии тактирования шины I2C.
  • SDA — вход/выход линии данных шины I2C.
  • Vcc — вход питания 3,3 или 5 В.
  • GND — общий вывод питания.

Модуль удобно подключать 3 способами, в зависимости от ситуации:

Способ — 1 : Используя проводной шлейф и Piranha UNO

Используя провода «Папа — Мама», подключаем напрямую к контроллеру Piranha UNO.

Способ — 2 : Используя Trema Set Shield

Модуль можно подключить в любую верхнюю колодку Trema Set Shield.

Способ — 3 : Используя проводной шлейф и Shield

Используя 3-х проводной шлейф, к Trema Shield, Trema-Power Shield, Motor Shield, Trema Shield NANO и тд.

Подключение к Raspberry Pi Pico

Для работы с Pi Pico необходимо установить поддержку платы в Arduino IDE. Нажмите здесь для перехода на подробную статью о том, как это сделать.

В этом случае логическую часть модуля необходимо питать от 3-х вольт Pi Pico

Для работы с Pi Pico версия установленной библиотеки должна быть 1.0.1 и выше

Модуль Pi Pico
SDA GP6
SCL GP7
Vcc 3V3(OUT)
GND GND

Питание:

Входное напряжение питания модуля 3,3В или 5В постоянного тока (поддерживаются оба напряжения питания), подаётся на выводы Vcc и GND.

Подробнее о модуле:

Модуль построен на базе четырёхразрядного светодиодного индикатора, микроконтроллера STM32F030K6 и снабжён собственным стабилизатором напряжения. Модуль способен выводить числа, время, температуру и некоторые символы.

  • Менять свой адрес на шине I2C.
  • Управлять внутренней подтяжкой линий шины I2C (по умолчанию включена).
  • Выводить числа, время, температуру и некоторые символы.
  • Выравнивать выводимые числа по любой из 4 позиций.
  • Определять направление сдвига числа от позиции по которой выполнено выравнивание.
  • Задавать частоту обновления информации дисплея, от 1 до 255 Гц.
  • Указывать яркость свечения всех сегментов дисплея, от 0 до 7.
  • Поворачивать изображение индикатора на 180°.
  • Указывать любому разряду индикатора мигать включёнными сегментами с заданной частотой.

Специально для работы с Trema модулем — Четырехразрядный индикатор LED, FLASH-I2C, нами разработана библиотека iarduino_I2C_4LED которая позволяет реализовать все функции модуля.

Подробнее про установку библиотеки читайте в нашей инструкции.

Смена адреса модуля на шине I2C:

По умолчанию все модули FLASH-I2C имеют установленный адрес 0х09. Если вы планируете подключать более 1 модуля на шину I2C, необходимо изменить адреса модулей таким образом, чтобы каждый из них был уникальным. Более подробно о том, как изменить адрес, а также о многом другом, что касается работы FLASH-I2C модулей, вы можете прочесть в этой статье.

В первой строке скетча необходимо записать в переменную newAddress адрес, который будет присвоен модулю. После этого подключите модуль к контроллеру и загрузите скетч. Адрес может быть от 0х07 до 0х7F.

uint8_t newAddress = 0x09; // Назначаемый модулю адрес (0x07 < адрес < 0x7F). // #include // Подключаем библиотеку для работы с аппаратной шиной I2C. #include // Подключаем библиотеку для работы с индикатором I2C-flash. iarduino_I2C_4LED dispLED; // Объявляем объект dispLED для работы с функциями и методами библиотеки iarduino_I2C_4LED. // Если при объявлении объекта указать адрес, например, dispLED(0xBB), то пример будет работать с тем модулем, адрес которого был указан. void setup()< // Serial.begin(9600); // if( dispLED.begin() )< // Инициируем работу с мотором. Serial.print("Найден LED индикатор 0x"); // Serial.println( dispLED.getAddress(), HEX ); // Выводим текущий адрес модуля. if( dispLED.changeAddress(newAddress) )< // Меняем адрес модуля на newAddress. Serial.print("Адрес изменён на 0x"); // Serial.println(dispLED.getAddress(),HEX ); // Выводим текущий адрес модуля. >else < // Serial.println("Адрес не изменён!"); // >// >else < // Serial.println("LED индикатор не найден!"); // >// > // // void loop() < // >//

Данный пример использует библиотеку iarduino_I2C_4LED, которая работает только с модулями четырехразрядных LED индикаторов, а значит позволяет менять только их адреса.

Смена и сортировка адресов на шине I2C:

Изменить адрес любого I2C модуля серии «Flash» можно аппаратно, используя установщик адресов FLASH-I2C. Это модуль подключаемый к шине I2C, на плате которого размещён дисплей и кнопки управления, при помощи которых можно узнать количество любых устройств на шине I2C, и менять адреса модулей Flash-I2C не отключая их от шины, что значительно сократит время сборки ваших проектов. Модуль оснащён разъемом USB через который можно запитать как сам модуль, так и шину I2C, или можно запитать шину I2C без использования разъема USB на плате модуля. Установщик адресов пригодиться в проектах с большим количеством модулей Flash-I2C.

Изменить адрес любого I2C модуля серии «Flash» можно программно, о том как это сделать рассказано в статье Wiki — Программная установка адресов модулей FLASH-I2C. В этой статье рассмотрены примеры с использованием библиотеки iarduino_I2C_Address, которая позволяет получать адреса любых устройств на шине I2C, менять адреса модулей Flash-I2C не отключая их от шины, получать название, номер модели, версию прошивки модулей Flash-I2C, а главное — автоматически сортировать адреса модулей Flash-I2C даже если на шине есть устройства с одинаковыми адресами.

Примеры:

В данном разделе раскрыты примеры работы с модулем по шине I2C с использованием библиотеки iarduino_I2C_4LED. Сама библиотека содержит больше примеров, доступных из меню Arduino IDE: Файл / Примеры / iarduino_I2C_4LED.

Вывод времени прошедшего с момента старта скетча:

Пример выводит время в минутах и секундах.

#include // Подключаем библиотеку для работы с аппаратной шиной I2C. #include // Подключаем библиотеку для работы с индикатором I2C-flash. iarduino_I2C_4LED dispLED(0x09); // Объявляем объект dispLED для работы с функциями и методами библиотеки iarduino_I2C_4LED, указывая адрес модуля на шине I2C. // Если объявить объект без указания адреса (iarduino_I2C_4LED dispLED;), то адрес будет найден автоматически. int i, j; // Объявляем переменные для хранения числа минут и секунд прошедших с момента старта скетча. // void setup() < // dispLED.begin(); // Инициируем работу с индикатором. dispLED.blink(0,true); // Указываем двоеточию мигать (если оно выводится на индикатор). >// // void loop() < // i = millis()/1000 / 60 % 60; // Получаем минуты прошедшие с момента старта скетча. j = millis()/1000 % 60; // Получаем секунды прошедшие с момента старта скетча. dispLED.print(i, j, TIME); // Выводим значения i и j как время (через двоеточие). >//

После загрузки данного примера, на дисплее начнут высвечиваться минуты и секунды прошедшие с момента старта скетча.

Описание функций библиотеки:

Функции данной библиотеки полностью совместимы с библиотекой iarduino_4LED используемой для управления Trema четырёхразрядным LED индикатором который подключается к Arduino без использования шины I2C.

Библиотека iarduino_I2C_4LED может использовать как аппаратную, так и программную реализацию шины I2C. О том как выбрать тип шины I2C рассказано в статье Wiki — расширенные возможности библиотек iarduino для шины I2C.

Подключение библиотеки:

  • Если адрес модуля известен (в примере используется адрес 0x09):
#include // Подключаем библиотеку для работы с модулем. iarduino_I2C_4LED dispLED(0x09); // Создаём объект dispLED для работы с функциями и методами библиотеки iarduino_I2C_4LED, указав адрес модуля на шине I2C (0x09).
  • Если адрес модуля неизвестен (адрес будет найден автоматически):
#include // Подключаем библиотеку для работы с модулем. iarduino_I2C_4LED dispLED; // Создаём объект dispLED для работы с функциями и методами библиотеки iarduino_I2C_4LED, без указания адреса.
  • При создании объекта без указания адреса, на шине должен находиться только один модуль.

Функция begin();

  • Назначение: Инициализация работы с модулем.
  • Синтаксис: begin();
  • Параметры: Нет.
  • Возвращаемое значение: bool — результат инициализации (true или false).
  • Примечание: По результату инициализации можно определить наличие модуля на шине.
  • Пример:

if( dispLED.begin() ) < Serial.print( "Модуль найден и инициирован!" ); >else

Функция reset();

  • Назначение: Перезагрузка модуля.
  • Синтаксис: reset();
  • Параметры: Нет.
  • Возвращаемое значение: bool — результат перезагрузки (true или false).
  • Пример:

if( dispLED.reset() ) < Serial.print( "Модуль перезагружен" ); >else

Функция changeAddress();

  • Назначение: Смена адреса модуля на шине I2C.
  • Синтаксис: changeAddress( АДРЕС );
  • Параметр:
    • uint8_t АДРЕС — новый адрес модуля на шине I2C (целое число от 0x08 до 0x7E)
    • Адрес модуля сохраняется в энергонезависимую память, а значит будет действовать и после отключения питания.
    • Текущий адрес модуля можно узнать функцией getAddress().

    if( dispLED.changeAddress(0x12) ) < Serial.print( "Адрес модуля изменён на 0x12" ); >else

    Функция getAddress();

    • Назначение: Запрос текущего адреса модуля на шине I2C.
    • Синтаксис: getAddress();
    • Параметры: Нет.
    • Возвращаемое значение: uint8_t АДРЕС — текущий адрес модуля на шине I2C (от 0x08 до 0x7E)
    • Примечание: Функция может понадобиться если адрес модуля не указан при создании объекта, а обнаружен библиотекой.
    • Пример:
    Serial.print( "Адрес модуля на шине I2C = 0x" ); Serial.println( dispLED.getAddress(), HEX );

    Функция getVersion();

    • Назначение: Запрос версии прошивки модуля.
    • Синтаксис: getVersion();
    • Параметры: Нет
    • Возвращаемое значение: uint8_t ВЕРСИЯ — номер версии прошивки от 0 до 255.
    • Пример:
    Serial.print( "Версия прошивки модуля " ); Serial.println( dispLED.getVersion() );

    Функция setPullI2C();

    • Назначение: Управление внутрисхемной подтяжкой линий шины I2C.
    • Синтаксис: setPullI2C( [ФЛАГ] );
    • Параметр:
      • bool ФЛАГ требующий установить внутрисхемную подтяжку линий шины I2C (true или false).
      • bool — результат включения / отключения внутрисхемной подтяжки (true или false).
      • Вызов функции без параметра равносилен вызову функции с параметром true — установить.
      • Флаг установки внутрисхемной подтяжки сохраняется в энергонезависимую память модуля, а значит будет действовать и после отключения питания.
      • Внутрисхемная подтяжка линий шины I2C осуществляется до уровня 3,3 В, но допускает устанавливать внешние подтягивающие резисторы и иные модули с подтяжкой до уровня 3,3 В или 5 В, вне зависимости от состояния внутрисхемной подтяжки модуля.

      if( dispLED.setPullI2C(true ) ) < Serial.print( "Внутрисхемная подтяжка установлена." ); >if( dispLED.setPullI2C(false) )

      Функция getPullI2C();

      • Назначение: Запрос состояния внутрисхемной подтяжки линий шины I2C.
      • Синтаксис: getPullI2C();
      • Параметры: Нет.
      • Возвращаемое значение: bool — ФЛАГ включения внутрисхемной подтяжки (true или false).
      • Пример:

      if( dispLED.getPullI2C() ) < Serial.print( "Внутрисхемная подтяжка включена." ); >else

      Функция clear();

      • Назначение: очистка индикатора
      • Синтаксис: clear();
      • Параметры: Нет.
      • Возвращаемые значения: Нет.
      • Пример:
      dispLED.clear(); // Чистим LED индикатор (все диоды выключатся).

      Функция light();

      • Назначение: Установка яркости свечения индикатора.
      • Синтаксис: light( ЧИСЛО );
      • Параметры:
        • uint8_t ЧИСЛО — целое число, определяющее яркость, от 0 до 7 (максимальная яркость).
        dispLED.light(7); // Устанавливаем максимальную яркость свечения LED индикатора.

        Функция point();

        • Назначение: Установка точек.
        • Синтаксис: point( ПОЗИЦИЯ , СОСТОЯНИЕ );
        • Параметры:
          • uint8_t ПОЗИЦИЯ — целое число, указывающее позицию точки: 1, 2, 3, 4 или 0 для двоеточия.
          • bool СОСТОЯНИЕ — флаг может принимать значение 0 (выключить) или 1 (включить).
          • Если первый параметр ПОЗИЦИЯ больше 4, то СОСТОЯНИЕ применяется ко всем точкам и двоеточию индикатора.
          • Функция управляет только точками и не влияет на ранее установленные цифры.
          dispLED.point(0, true); // Включаем двоеточие (светится только двоеточие). dispLED.point(1, true); // Включаем первую точку (светится и двоеточие и самая левая точка). dispLED.point(0, false); // Выключаем двоеточие (светится только самая левая точка).

          Функция blink();

          • Назначение: Управление миганием цифр и символов в указанных позициях.
          • Синтаксис: blink( ПОЗИЦИЯ , СОСТОЯНИЕ );
          • Параметры:
            • uint8_t ПОЗИЦИЯ — целое число, указывающее позицию цифры: 1, 2, 3, 4 или 0 для двоеточия.
            • bool СОСТОЯНИЕ — флаг может принимать значение 0 (не мигать) или 1 (мигать).
            • Если первый параметр ПОЗИЦИЯ больше 4, то СОСТОЯНИЕ применяется ко всему индикатору.
            • Функция управляет только миганием и не влияет на ранее установленные цифры, символы и точки.
            • Частота миганий задаётся функцией frequ() .
            dispLED.blink(0, true); // Заставляем мигать двоеточие (если двоеточие включено). dispLED.blink(1, true); // Заставляем мигать первую цифру или символ, включая её точку (теперь будет мигать и двоеточие, и символ находящийся в первой позиции). dispLED.blink(0, false); // Отключаем мигание двоеточия (теперь будет мигать только цифра или символ находящаяся в первой позиции).

            Функция frequ();

            • Назначение: Установка частоты миганий цифр и символов указанных функцией blink(); .
            • Синтаксис: frequ( ЧАСТОТА );
            • Параметр:
              • uint8_t ЧАСТОТА — целое число, указывающее частоту в Гц, от 1 до 4.
              • Частота миганий цифр и символов позиция которых указана функцией blink(); не зависит от частоты обновления дисплея указанной функцией fps(); .
              • Частота по умолчанию = 1 Гц.
              dispLED.frequ(1); // Цифры и символы индикатора определённые функцией blink() будут мигать с частотой 1 Гц.

              Функция turn();

              • Назначение: Разворот изображения индикатора.
              • Синтаксис: turn( ФЛАГ );
              • Параметр:
                • bool ФЛАГ — может принимать значение 0 (без разворота) или 1 (повернуть на 180°).
                • Если на индикаторе есть точки и они физически расположены только снизу цифр, то при развороте изображения, точки окажутся вверху и перед цифрами.
                dispLED.turn(1); // Развернуть изображение индикатора на 180°.

                Функция setLED();

                • Назначение: Установка светодиодов (сегментов) индикатора по битам.
                • Синтаксис: setLED ( [[[[[ БАЙТ_№1 ] , БАЙТ_№2 ] , БАЙТ_№3 ] , БАЙТ_№4 ] , ФЛАГ ] );
                • Параметры:
                  • БАЙТ_№1 — каждый бит этого байта включает свой светодиод (сегмент) в 1 позиции.
                  • БАЙТ_№2 — каждый бит этого байта включает свой светодиод (сегмент) в 2 позиции.
                  • БАЙТ_№3 — каждый бит этого байта включает свой светодиод (сегмент) в 3 позиции.
                  • БАЙТ_№4 — каждый бит этого байта включает свой светодиод (сегмент) в 4 позиции.
                  • bool ФЛАГ — включает двоеточие.
                • Возвращаемые значения: Нет.
                • Примечание:
                  • Каждый бит байта соответствует одному светодиоду (сегменту) в следующем порядке: hgfedcba (старший бит управляет сегментом «h», а младший бит управляет сегментом «a»).
                  • Все параметры являются необязательными, отсутствие параметра означает что все светодиоды (сегменты) в данной позиции будут выключены.
                • Пример:
                dispLED.setLED(B00000110, B01100011); // В 1 позиции включены сегменты «c» и «b» (как у цифры 1), а во 2 разряде включены сегменты «g»«f»«b»«a» (как у символа градуса), остальные разряды индикатора выключены.

                Функция print();

                • Назначение: Вывод числа, массива чисел, текста, времени или температуры.
                • Синтаксис: print ( ЗНАЧЕНИЕ , ПАРАМЕТРЫ_ВЫВОДА_ЧИСЛА );
                • Параметры:
                  • ЗНАЧЕНИЕ — то, что требуется вывести на индикатор, это может быть:
                    • Целое число (как положительное, так и отрицательное).
                    • Дробное число (как положительное, так и отрицательное).
                    • Массив (из 4 положительных целых чисел, от 0 до 9)
                    • Текст (из следующих символов «0123456789 abcdefghijlnopstu . ;*-_»)
                    • LEN1, LEN2, LEN3 или LEN4 — количество символов в выводимом числе (включая знак минус).
                    • POS1, POS2, POS3 или POS4 — позиция от левого края, к которой привязывается выводимое число.
                    • LEFT или RIGHT — направление вывода относительно указанной позиции.
                    • DEC или HEX — система счисления для выводимого числа.
                    • TIME или TEMP — отображение чисел в виде времени или числа в виде температуры.
                    • символ типа char — для заполнения им недостающих разрядов
                    • Параметры указываются только если значением является число (целое или с плавающей точкой).
                    • Если первым параметром (после значения) указать число, то оно будет означать количество выводимых разрядов после запятой.
                    dispLED.print( 12345.6789 , 2 , POS1 , LEN3 , RIGHT ); // Число 12345.6789 будет выведено как 5.67

                    Вывод без форматирования:

                    dispLED.print( 1 ); // Вывод целого числа 1.
                    dispLED.print( 3.45 ); // Вывод дробного числа 3.45 (по умолчанию выводится 1 знак после запятой)
                    dispLED.print( -12 ); // Вывод отрицательного целого числа -12.
                    dispLED.print( -3.45 ); // Вывод отрицательного дробного числа -3.45
                    dispLED.print( 250 , HEX ); // Вывод числа 250 в шестнадцатиричной системе счисления
                    int a[4]=; dispLED.print( a ); // Вывод массива из 4 положительных цифр от 0 до 9
                    dispLED.print( 23 , TEMP ); // Вывод температуры
                    dispLED.print( 23.6 , TEMP ); // Вывод температуры
                    dispLED.print( 4 , 5 , TIME ); // Вывод времени
                    dispLED.print( «67» ); // Вывод текста
                    dispLED.print( «OFF» ); // Вывод текста из букв латинского алфавита
                    dispLED.print( «8:9» ); // Вывод текста с двоеточием

                    Вывод чисел с указанием количества знаков после запятой:

                    dispLED.print( 1 , 2 ); // Вывод целого числа 1 с 2 знаками после запятой
                    dispLED.print( -2 , 1 ); // Вывод отрицательного целого числа -2 с 1 знаком после запятой
                    dispLED.print( 3.45 , 2 ); // Вывод дробного числа 3.45 с 2 знаками после запятой
                    dispLED.print( -3.45 , 0 ); // Вывод отрицательного дробного числа -3.45 без знаков после запятой

                    Вывод чисел с указанием их размерности:

                    dispLED.print( 1 , LEN2 ); // Вывод целого числа 1 в 2 разрядах
                    dispLED.print( -1 , LEN3 ); // Вывод отрицательного целого числа -1 в 3 разрядах
                    dispLED.print( 2.3 , LEN3 ); // Вывод дробного числа 2.3 в 3 разрядах
                    dispLED.print( -4.567 , 1 , LEN4 ); // Вывод дробного числа -4.567 в 4 разрядах , с 1 знаком после запятой
                    dispLED.print( 8901 , LEN1 ); // Вывод целого числа 8901 в 1 разряде
                    dispLED.print( 7 , LEN3 , ‘-‘ ); // Вывод числа 7 в 3 разрядах, с заполнением пустых разрядов символом ‘-‘

                    Указание направления сдвига чисел:

                    dispLED.print( 1 , RIGHT ); // Вывод целого числа 1 со сдвигом вправо от старшего разряда
                    dispLED.print( 12 , RIGHT ); // Вывод целого числа 12 со сдвигом вправо от старшего разряда
                    dispLED.print( 12.3 , RIGHT ); // Вывод дробного числа 12.3 со сдвигом вправо от старшего разряда
                    dispLED.print( 1 , LEFT ); // Вывод целого числа 1 со сдвигом влево (по умолчанию) от младшего разряда
                    dispLED.print( 12 , LEFT ); // Вывод целого числа 12 со сдвигом влево (по умолчанию) от младшего разряда
                    dispLED.print( 12.3 , LEFT ); // Вывод дробного числа 12.3 со сдвигом влево (по умолчанию) от младшего разряда

                    Вывод чисел с привязкой к определённой позиции от левого края:

                    dispLED.print( 74 , POS4 ); // Вывод целого числа 74 со сдвигом влево (по умолчанию) от 4 позиции
                    dispLED.print( 74 , POS3 ); // Вывод целого числа 74 со сдвигом влево (по умолчанию) от 3 позиции
                    dispLED.print( 74 , POS2 ); // Вывод целого числа 74 со сдвигом влево (по умолчанию) от 2 позиции
                    dispLED.print( 74 , POS1 ); // Вывод целого числа 74 со сдвигом влево (по умолчанию) от 1 позиции
                    dispLED.print( 74 , POS4 , RIGHT ); // Вывод целого числа 74 со сдвигом вправо от 4 позиции
                    dispLED.print( 74 , POS3 , RIGHT ); // Вывод целого числа 74 со сдвигом вправо от 3 позиции
                    dispLED.print( 74 , POS2 , RIGHT ); // Вывод целого числа 74 со сдвигом вправо от 2 позиции
                    dispLED.print( 74 , POS1 , RIGHT ); // Вывод целого числа 74 со сдвигом вправо от 1 позиции

                    Параметры вывода числа можно комбинировать в любой последовательности:

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

                    dispLED.print( 12345.6789 , 2 , POS1 , LEN3 , RIGHT );
                    // Вывод дробного числа 12345.6789
                    // выводить 2 знака после запятой
                    // POS1 — число вывести на дисплей начиная с 1 позиции от левого края
                    // LEN3 — размерность выводимого числа 3 разряда
                    // RIGHT — число сдвигать вправо от указанной позиции.

                    Дополнительные функции библиотеки:

                    В библиотеке реализованы две дополнительные функции, применение которых может быть интересно в познавательных целях.

                    Функция fps();

                    • Назначение: Установка частоты обновления всего изображения индикатора.
                    • Синтаксис: fps( ЧАСТОТА );
                    • Параметр:
                      • bool ЧАСТОТА — значение от 1 до 255 Гц.
                      • Светодиоды индикатора светятся не одновременно, а поочерёдно включаются и выключаются так, что в любой момент времени может светиться только один светодиод.
                      • Частота заданная данной функцией аналогична частоте кадровой развёртки дисплея, она определяет сколько раз в секунду обновится всё изображение индикатора.
                      • На частотах ниже 30 Гц заметно мерцание, а на частотах ниже 10 Гц можно отследить в каком порядке включаются светодиоды.
                      dispLED.fps(2); // Обновлять изображение индикатора всего 2 раза в секунду.

                      Функция scheme();

                      • Назначение: Установка схемы включения светодиодов.
                      • Синтаксис: scheme( СХЕМА );
                      • Параметр:
                        • uint8_t СХЕМА — может принимать одно из двух значений:
                          • LED_CA — светодиоды индикатора включены по схеме с общим анодом.
                          • LED_CC — светодиоды индикатора включены по схеме с общим катодом.
                          • Изменение схемы включения светодиодов может быть полезно только при замене индикатора на плате модуля.
                          dispLED.scheme(LED_CA); // Указываем модулю управлять индикатором собранном по схеме с общими анодами. dispLED.scheme(LED_CC); // Указываем модулю управлять индикатором собранном по схеме с общими катодом.

                          Ссылки:

                          • Trema модуль — Четырехразрядный индикатор LED, FLASH-I2C.
                          • Wiki — Четырехразрядный индикатор LED, FLASH-I2C — Datasheet.
                          • Библиотека iarduino_I2C_4LED.
                          • Расширенные возможности библиотек iarduino для шины I2C.
                          • Wiki — Установка библиотек в Arduino IDE.
                          • Wiki — Программная установка адресов модулей FLASH-I2C.

                          Arduino i2c сколько можно подключить устройств

                          Віримо в перемогу ЗСУ!
                          Працюємо з 09:00 до 18:00 Пн-Сб Працюємо з 09:00 до 19:00 Пн-Пт —> Магазин у відпустці до 19.08.2023 —>

                          • Ваша корзина пуста!
                          • Главная
                          • Статьи
                          • Arduino Nano I2C связь между контроллерами

                          Давайте разберемся с самой удобной коммуникацией физически заложенной в контроллеры Arduino

                          I2C это последовательная асимметричная шина для связи между интегральными схемами внутри электронных приборов. Тоесть данный протокол связи был разработан для внутренней связи внутри коробки устройства или внутри щита. Перед ним не ставилось задание передавать данные на большие расстояния, поэтому ходит множество мифов о максимальной дальности связи — у кого-то плохо работает уже при 50см, у кого-то при 2м.

                          На шине I2C может сидеть до 128 устройств. Адреса от 0 до 127.

                          В контроллерах Arduino заложена физическая коммуникация I2C, которая позволяет по двум информационным проводам подключать к ним как различные датчики, расширители дискретных входов-выходов, цифро-аналоговые и аналого-цифровые преобразователи, так и другие контроллеры.

                          О скорости передачи на сайте производителя не пишут. Но по общей документации на протокол она должна составлять как минимум 100 кбит/с

                          Теперь хотелось бы потестировать на сколько действительно хороша шина I2C, и на сколько сложно по ней обмениваться данными между несколькими контроллерами Arduino

                          Я возьму три контроллера Arduino Nano, объединю их шиной I2C, и разберусь, как по ней обмениваться данными. Первый контроллер будет выполнять роль ведущего, а остальные два — роль ведомого.

                          Для отображения данных буду использовать LCD-индикатор 1602 с модулем I2C, который будет подключен на ту же коммуникационную шину.

                          Ведущий контроллер будет последовательно опрашивать второго и третьего контроллера. Принятые данные первый контроллер должен выводить на индикатор. Опрос ведомых Arduino Nano будет проводиться с частотой 1 раз/сек.

                          Схема подключения

                          Четыре провода от каждого из 4-х устройств нужно соединить параллельно. Вывод А4 платы Arduino Nano — это шина SDA протокола I2C, а А5 — это SCL.

                          Я буду использовать монтажные шилды под контроллеры Nano для удобства соединений.

                          Питание будет подаваться просто на один из контроллеров через mini USB вход.

                          У LCD адрес в сети I2C по умолчанию 27. У второго контроллера установим адрес 2 и у третьего 3. У ведущего первого контроллера адрес не нужен.

                          Программа контроллера — мастера.

                          #include #include // Set the LCD address to 0x27 for a 16 chars and 2 line display LiquidCrystal_I2C lcd(0x27, 16, 2); int nano1=0; int nano2; int nano3; void setup() < Wire.begin(); Serial.begin(9600); // initialize the LCD lcd.begin(); // Turn on the blacklight and print a message. lcd.backlight(); >void loop() < lcd.setCursor(0, 0); lcd.print(nano1); Wire.requestFrom(2, 2); // request 6 bytes from slave device #8 int i=0;nano2=0; while (Wire.available()) < // slave may send less than requested byte c = Wire.read(); // receive a byte as character Serial.print(c); if (i==0) nano2 = ((c & 0xff) Serial.println(""); Serial.println(nano2); lcd.setCursor(9, 0); lcd.print(nano2); delay(100); Wire.requestFrom(3, 2); // request 6 bytes from slave device #8 i=0;nano3=0; while (Wire.available()) < // slave may send less than requested byte c = Wire.read(); // receive a byte as character Serial.print(c); if (i==0) nano3 = ((c & 0xff) lcd.setCursor(0, 1); lcd.print(nano3); delay(100); nano1++; delay(800); >

                          Первый контроллер изменяет свою переменную типа integer и выводит ее значение на индикатор. Так же он поочереди опрашивает слейв со 2-м и 3-м адресом. Запрашивает у них два байта информации, преобразовывает их в переменную integer. В результате в первом контроллере крутятся три переменные с трёх Nano и он может вывести их на индикатор.

                          Программа второго контроллера

                          #include int nano2=0; byte high[2]; void setup() < Wire.begin(2); // join i2c bus with address #8 Wire.onRequest(requestEvent); // register event >void loop() < delay(1000); nano2--; >// function that executes whenever data is requested by master // this function is registered as an event, see setup() void requestEvent() < high[0] = (nano2 >> 8); high[1] = (nano2 & 0xff); Wire.write(high[0]); // respond with message of 2 bytes Wire.write(high[1]); >

                          Программа третьего Arduino Nano

                          #include int nano2=0; byte high[2]; void setup() < Wire.begin(3); // join i2c bus with address #8 Wire.onRequest(requestEvent); // register event >void loop() < delay(1500); nano2--; >// function that executes whenever data is requested by master // this function is registered as an event, see setup() void requestEvent() < high[0] = (nano2 >> 8); high[1] = (nano2 & 0xff); Wire.write(high[0]); // respond with message of 2 bytes Wire.write(high[1]); >

                          Отличаются последние две программы просто адресом в функции Wire.begin(3); и частотой изменения переменной.

                          Эти программы постоянно изменяют переменную integer и ожидают запроса от мастера. При запросе эта переменная раскладывается на два байта и отправляется как ответ на запрос ведущему контроллеру.

                          Таким образом работу связи по I2C можно контролировать по изменяющимся значениям трех переменных на жидкокристаллическом индикаторе.

                          Выводы

                          Прекрасно все работает — цифры на дисплее меняются. Я попробовал удлиннять шлейф проводов между вторым и третьим контроллерами Arduino. Проверил работу шины связи при длине 3 м — без притензий. Длиннее не пробовал, но многие мне утверждали, что I2C не работает дальше 0,5 . 2 м и меня воодушевила длина 3 м.

                          Для себя я уже вижу, где применю такую связь именно между тремя Nano.

                          Я здесь ещё не попробовал передачу данных от мастера слейву. Если попробуете — отпишитесь.

                          Недостатков здесь на небольших расстояниях ощутимо меньше чем превосходств.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *