Как соединить две ардуино
Перейти к содержимому

Как соединить две ардуино

  • автор:

Соединяем две Arduino через Интернет (IOT)

В этом проекте мы соединим две платы Arduino ULTRA/Piranha ULTRA через интернет. Сделаем мы это при помощи сервиса ioControl.

Видео

Подключаем Trema-модуль Кнопка к одному устройству.

Подключаем Trema-модуль Светодиод к другому устройству.

Скетч проекта

Для скетча мы воспользуемся генератором скетча для IDE на сайте ioControl.

Нажмём на кнопку «Генератор скетча для IDE».

Выберем необходимые параметры. В нашем случае это:

Параметр Устройство с кнопкой Устройство со светодиодом
Контроллер Arduino/Piranha ULTRA Arduino/Piranha ULTRA
Shield Ethernet Shield w5500 Ethernet Shield w5500
Вывод SS D10 D10
IP адрес DHCP DHCP
Mac адрес 0xCE 0xCC
Панель панель с переменной myButton панель с переменной myButton
Переменные на чтение myButton
Переменные на запись myButton

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

Так же необходимо установить библиотеку iocontrol. Если Вы не знаете как устанавливать библиотеки в Arduino IDE — Вы можете узнать по этой ссылке

Скетч для кнопки

#include #include #include // Определяем вывод кнопки #define BUT 2 // эту строку мы добавили вручную // Название панели на сайте iocontrol.ru const char* myPanelName = "сюда_необходимо_вставить_название_Вашей_панели"; int status; // Название переменных как на сайте iocontrol.ru const char* VarName_myButton = "myButton"; // Создаём переменную для хранения состояния кнопки bool button = false; // Эту строку мы добавили вручную // Создаём объект клиента класса EthernetClient EthernetClient client; // Создаём объект iocontrol, передавая в конструктор название панели и клиента iocontrol mypanel(myPanelName, client); // MAC адреса Ethernet шилда. Должен быть уникальным в сети byte mac[] = < 0xDE, 0xAD, 0xDE, 0xAD, 0xFA, 0xCE >; void setup() < Serial.begin(9600); Ethernet.init(10); // Инициируем Ethernet Shield с использованием DHCP Ethernet.begin(mac); // Вызываем функцию первого запроса к сервису status = mypanel.begin(); Serial.println((String)"Status mypanel.begin = "+status); >void loop() < // ************************ ЧТЕНИЕ ************************ // Чтение значений переменных из сервиса status = mypanel.readUpdate(); // Если статус равен константе OK. if (status == OK) < // Выводим текст в последовательный порт Serial.println("------- Read OK -------"); // Записываем считанный из сервиса значения в переменные >// ************************ ЗАПИСЬ ************************ // Записываем значение в переменную для отпраки в сервис // Считываем логический уровень кнопки // и меняем значение переменной button на // противоположное if (digitalRead(BUT)) < // Эти строки delay(100); // мы if (digitalRead(BUT)) // добавили button = !button; // вручную >// Записываем значение в переменную на сайте mypanel.write(VarName_myButton, button); // Эту строку мы изменили вручную // Отправляем переменные из контроллера в сервис status = mypanel.writeUpdate(); // Если статус равен константе OK. if (status == OK) < // Выводим текст в последовательный порт Serial.println("------- Write OK -------"); >>

Скетч для светодиода

#include #include #include // Определяем номер вывода светодиода #define LED 2 // Эту строку мы добавили вручную // Название панели на сайте iocontrol.ru const char* myPanelName = "сюда_необходимо_вставить_название_Вашей_панели"; int status; // Название переменных как на сайте iocontrol.ru const char* VarName_myButton = "myButton"; // Создаём объект клиента класса EthernetClient EthernetClient client; // Создаём объект iocontrol, передавая в конструктор название панели и клиента iocontrol mypanel(myPanelName, client); // MAC адреса Ethernet шилда. Должен быть уникальным в сети byte mac[] = < 0xDE, 0xED, 0xDE, 0xAD, 0xFA, 0xCC >; void setup() < Serial.begin(9600); Ethernet.init(10); // Меняем режим вывода светодиода pinMode(LED, OUTPUT); // Эту строку мы добавили вручную // Инициируем Ethernet Shield с использованием DHCP Ethernet.begin(mac); // Вызываем функцию первого запроса к сервису status = mypanel.begin(); Serial.println((String)"Status mypanel.begin = "+status); >void loop() < // ************************ ЧТЕНИЕ ************************ // Чтение значений переменных из сервиса status = mypanel.readUpdate(); // Если статус равен константе OK. if (status == OK) < // Выводим текст в последовательный порт Serial.println("------- Read OK -------"); // Записываем считанный из сервиса значения в переменные bool io_myButton = mypanel.readInt(VarName_myButton); // целочисленная переменна Serial.println((String)"io_myButton = "+io_myButton); // Меняем логический уровень вывода светодиода полученный с сайта digitalWrite(LED, io_myButton); // Эту строку мы добавили вручную >// ************************ ЗАПИСЬ ************************ // Записываем значение в переменную для отправки в сервис // Отправляем переменные из контроллера в сервис status = mypanel.writeUpdate(); // Если статус равен константе OK. if (status == OK) < // Выводим текст в последовательный порт Serial.println("------- Write OK -------"); >>

Ссылки

  • Ethernet Shield W5500
  • Бесплатный сервис ioControl
  • Создание учётной записи в сервисе ioControl
  • Создание панели в ioControl
  • Создание переменных в ioControl
  • Подготовка Arduino к работе с ioControl
  • Библиотека iocontrol
  • Wiki — Установка библиотек в Arduino IDE.

Урок 26.3 Соединяем две arduino по шине I2C

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

В этом уроке мы научимся соединять две arduino по аппаратной шине I2C.

Преимущества:
  • Реализуется возможность подключения до 126 устройств.
    (не рекомендуется присваивать устройствам адреса 0x00 и 0x7F)
  • Не требуются дополнительные модули.
  • Все устройства одинаково подключаются к шине.
  • Каждое ведомое устройство имеет свой уникальный адрес на шине.
Недостатки:
  • Код программы немного сложнее чем для шины UART.
Нам понадобится:
  • Arduino х 3шт.
  • LCD дисплей LCD1602 IIC/I2C(синий) или LCD1602 IIC/I2C(зелёный) х 1шт.
  • Trema Shield х 3шт.
  • Trema кнопка x 2шт.
  • Trema светодиод x 1шт.
  • Trema потенциометр x 1шт.
  • Trema I2C Hub x 1шт.
  • Шлейф «мама-мама» (4 провода) для шины I2С х 4шт.

Для реализации проекта нам необходимо установить библиотеки:

  • Библиотека LiquidCrystal_I2C_V112 (для подключения дисплеев LCD1602 по шине I2C).
  • Библиотека iarduino_I2C_connect (для удобства соединения нескольких arduino по шине I2C).

О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki — Установка библиотек в Arduino IDE, а о том, как работать с LCD дисплеями, на странице Wiki — Работа с символьными ЖК дисплеями.

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

На шине i2С находятся 4 устройства: 3 arduino и 1 LCD дисплей. Все устройства шины I2C соединены через Trema I2C Hub. Для подключения Arduino используются аппаратные выводы шины I2C.

  • Arduino master — к цифровому выводу D2 подключена trema кнопка.
  • Arduino slave 0x01 — к цифровому выводу D2 подключена trema кнопка.
  • Arduino slave 0x02 — к цифровому выводу D13 подключён trema светодиод, к аналоговому выводу A0 подключён Trema потенциометр.
  • LCD I2C дисплей — является устройством slave 0x27.

Схема соединения нескольких Arduino по шине I2C

На шине I2C не используются дополнительные подтягивающие резисторы (для линий SDA и SCL), так как они интегрированы в LDC I2C дисплее.

Код программы:
Arduino master:
// Подключаем библиотеки: #include // подключаем библиотеку для работы с шиной I2C #include // подключаем библиотеку для работы с LCD дисплеем #include // подключаем библиотеку для соединения arduino по шине I2C // Объявляем переменные и константы: iarduino_I2C_connect I2C2; // объявляем переменную для работы c библиотекой iarduino_I2C_connect LiquidCrystal_I2C lcd(0x27,16,2); // объявляем переменную для работы с LCD дисплеем, указывая параметры дисплея (адрес I2C = 0x27, количество столбцов = 16, количество строк = 2) const byte PIN_Button_master = 2; // объявляем константу с указанием номера цифрового вывода, к которому подключена кнопка bool VAR_Button_master = 0; // объявляем переменную для чтения состояний собственной кнопки bool VAR_Button_slave = 0; // объявляем переменную для чтения состояний кнопки ведомого 0x77 int VAR_Potentiometer = 0; // объявляем переменную для чтения значения с потенциометра ведомого 0x77 void setup() < //Wire.setClock(400000); // устанавливаем скорость передачи данных по шине I2C = 400кБит/с Wire.begin(); // инициируем подключение к шине I2C в качестве ведущего (master) устройства pinMode(PIN_Button_master, INPUT); // Устанавливаем режим работы вывода собственной кнопки, как вход //Выводим данные на LCD дисплей: lcd.init(); // инициируем LCD дисплей lcd.backlight(); // включаем подсветку LCD дисплея lcd.setCursor(0, 0); lcd.print("iArduino.ru"); // выводим текст "iArduino.ru" delay(1000); // ждём 1 секунду lcd.setCursor(0, 0); lcd.print("button = "); // выводим текст "button = " lcd.setCursor(0, 1); lcd.print("resistor = "); // выводим текст "resistor = " >void loop() < //Считываем данные: VAR_Button_master = digitalRead(PIN_Button_master);// Считываем состояние собственной кнопки VAR_Button_slave = I2C2.readByte(0x01,0); // Считываем состояние кнопки ведомого (адрес ведомого 0x01, номер регистра 0) VAR_Potentiometer = I2C2.readByte(0x02,1)
Arduino slave 0x01:
// Подключаем библиотеки: #include // подключаем библиотеку для работы с шиной I2C #include // подключаем библиотеку для соединения arduino по шине I2C // Объявляем переменные и константы: iarduino_I2C_connect I2C2; // объявляем переменную для работы c библиотекой iarduino_I2C_connect const byte PIN_Button = 2; // объявляем константу с указанием номера цифрового вывода, к которому подключена кнопка byte REG_Array[1]; // объявляем массив, данные которого будут доступны для чтения/записи по шине I2C void setup() < //Wire.setClock(400000); // устанавливаем скорость передачи данных по шине I2C = 400кБит/с Wire.begin(0x01); // инициируем подключение к шине I2C в качестве ведомого (slave) устройства, с указанием своего адреса на шине. I2C2.begin(REG_Array); // инициируем возможность чтения/записи данных по шине I2C, из/в указываемый массив pinMode(PIN_Button, INPUT); // Устанавливаем режим работы вывода кнопки, как вход >void loop() < REG_Array[0] = digitalRead(PIN_Button); // Сохраняем состояние кнопки в 0 ячейку массива REG_Massive >
Arduino slave 0x02:
// Подключаем библиотеки: #include // подключаем библиотеку для работы с шиной I2C #include // подключаем библиотеку для соединения arduino по шине I2C // Объявляем переменные и константы: iarduino_I2C_connect I2C2; // объявляем переменную для работы c библиотекой iarduino_I2C_connect const byte PIN_Potentiometer = 0; // объявляем константу с указанием номера аналогового вывода, к которому подключён потенциометр const byte PIN_LED = 13; // объявляем константу с указанием номера цифрового вывода, к которому подключен светодиод int VAR_Potentiometer = 0; // объявляем переменную для чтения значения с потенциометра byte REG_Massive[3]; // объявляем массив, данные которого будут доступны для чтения/записи по шине I2C void setup() < //Wire.setClock(400000); // устанавливаем скорость передачи данных по шине I2C = 400кБит/с Wire.begin(0x02); // инициируем подключение к шине I2C в качестве ведомого (slave) устройства, с указанием своего адреса на шине. I2C2.begin(REG_Massive); // инициируем возможность чтения/записи данных по шине I2C, из/в указываемый массив pinMode(PIN_LED, OUTPUT); // Устанавливаем режим работы вывода светодиода, как выход >void loop()< VAR_Potentiometer = analogRead(PIN_Potentiometer); // Считываем значение потенциометра REG_Massive[1] = VAR_Potentiometer>>8; // Сохраняем старший байт значения потенциометра в 1 ячейку массива REG_Massive REG_Massive[2] = VAR_Potentiometer; // Сохраняем младший байт значения потенциометра во 2 ячейку массива REG_Massive digitalWrite(PIN_LED, REG_Massive[0]); // вкл/выкл светодиод в соответствии со значением 0 элемента массива REG_Massive >
Алгоритм работы:
  • Arduino master проверяет состояние собственной кнопки.
  • Arduino master опрашивает две Arduino Slave.
    • Arduino Slave 0x01 возвращает состояние кнопки.
    • Arduino Slave 0x02 возвращает значение падения напряжения плеча потенциометра.
    • Arduino Slave 0x02 включает или выключает светодиод, в соответствии с полученными данными.
    Настройка параметров шины I2C:

    Максимальная, аппаратно реализуемая частота передачи данных, может достигать 1/16 от тактовой частоты.

    Библиотека Wire позволяет устанавливать скорость передачи данных через функцию setClock(), которую требуется вызвать до функции begin().

    Библиотека Wire позволяет аппаратно подключить Arduino к шине I2C с указанием роли Arduino на шине: ведущий или ведомый.

    • Wire.setClock(400000); // скорость передачи данных 400 кБит/с.
    • Wire.begin(); // подключение к шине I2C в роли ведущего.
    • Wire.begin(адрес); // подключение к шине I2C в роли ведомого, с указанием адреса.
    Функции библиотеки iarduino_I2C_connect:

    В библиотеке iarduino_I2C_connect реализованы 4 функции: 2 для ведущего и 2 для ведомого.

    На ведомом устройстве достаточно вызвать функцию begin() с указанием массива, данные которого требуется сделать доступными для мастера. Далее можно работать с этим массивом, «забыв» про шину I2C. Мастер обращаясь к ведомому сможет получать и изменять данные элементов указанного массива (обращаясь к номеру элемента массива как к номеру регистра).

    Если требуется запретить мастеру менять значения некоторых ячеек массива, то достаточно вызвать «необязательную» функцию writeMask() с указанием маскировочного массива, каждый элемент которого является флагом, разрешающим запись в соответствующий элемент массива доступного по шине I2C.

    На ведущем устройстве доступны функции readByte() и writeByte(). Указывая в качестве параметров функций, адрес ведомого устройства и номер регистра, можно побайтно читать и записывать данные.

    Функции для ведомого:

    begin():

    • Назначение: указание массива, элементы которого будут доступны для чтения/записи по шине I2C.
    • Синтаксис: begin(массив); // тип данных массива - byte.
    • Возвращаемые значения: Нет.
    • Примечание: Вызывается 1 раз в коде функции Setup().

    writeMask():

    • Назначение: указание маскировочного массива, каждый элемент которого является флагом разрешения записи по шине I2C.
    • Синтаксис: writeMask(маскировочный_массив); // тип данных массива - bool.
    • Возвращаемые значения: Нет.
    • Примечание: Вызывается 1 раз в коде функции Setup().
    • Пример:
      #include
      #include
      iarduino_I2C_connect ccc;
      byte aaa[5]; // объявляем 5 элементов массива, к которому разрешим доступ.
      bool bbb[5] = ; // объявляем 5 элементов маскировочного массива.
      Wire.begin(0x33); // подключаемся к шине I2C в роли ведомого с адресом 0x33.
      ccc.begin(aaa); // разрешаем доступ к массиву aaa по шине I2C.
      ccc.wtiteMask(bbb); // маскируем разрешение на запись в массив aaa.
      • В соответствии со значениями массива bbb, мастер сможет записывать данные в ячейки 1,2,3 массива aaa, а попытка записи в 0 и 4 элементы будет проигнорирована.
      • Если массив aaa имеет больше элементов чем массив bbb, то попытка мастера записать данные в «лишние» элементы будет проигнорирована.
      • Если не объявлять маскировочный массив (не вызывать функцию writeMask() вообще), то все элементы массива aaa будут доступны для записи мастером.
      Функции для ведущего:

      readByte():

      • Назначение: Чтение одного байта данных из устройства на шине I2C.
      • Синтаксис: readByte(адрес_устройства, адрес_регистра);
      • Возвращаемые значения: uint8_t байт - данные считанные из указанного адреса, указанного устройства.
      • Примечание: Если производится чтение по шине I2C из массива объявленного функцией begin(), то адрес регистра соответствует номеру элемента массива.

      writeByte():

      • Назначение: Запись одного байта данных в устройство на шине I2C.
      • Синтаксис: writeByte(адрес_устройства, адрес_регистра, байт_данных);
      • Возвращаемые значения: uint8_t байт - результат операции записи, соответствует значению возвращаемому функцией Wire.endTransmission().
        • 0 - успех.
        • 1 - переполнение буфера передачи данных.
        • 2 - получен NACK на переданный адрес устройства.
        • 3 - получен NACK на переданный адрес регистра.
        • 4 - неизвестная ошибка.
        Ссылки:
        • Код программы - Arduino master.
        • Код программы - Arduino slave 0x01.
        • Код программы - Arduino slave 0x02.
        • Библиотека LiquidCrystal_I2C_V112.
        • Библиотека iarduino_I2C_connect.
        • Wiki - Установка библиотек в Arduino IDE .
        • Wiki - Работа с символьными ЖК дисплеями.
        • Wiki - Trema Shield.

        Урок 1. Двусторонняя связь между двумя Arduino с использованием I2C.

        При разработке проектов на Arduino часто возникает потребность в увеличении возможности, а пинов не достаточно. Также бывает необходимость объединить несколько работающих узлов для обмена данными, т.е. реализовать двухстороннюю связь между двумя Arduino. Для реализации двусторонней связи между двумя Arduino отлично подойдёт шина I2C.

        Интерфейс I 2 C (или по-другому IIC) — это достаточно широко распространённый сетевой последовательный интерфейс, придуманный фирмой Philips и завоевавший популярность относительно высокой скоростью передачи данных, дешевизной и простотой реализации.

        Шина I2C синхронная, состоит из двух линий: данных (SDA) и тактов (SCL). При проектировании есть 2 типа устройств: ведущий (master) и ведомый (slave). Инициатором обмена всегда выступает ведущий, обмен между двумя ведомыми невозможен. Всего на одной двухпроводной шине может быть до 127 устройств.

        двухстороннюю связь между двумя Arduino

        Такты на линии SCL генерирует ведущий (master). Линией SDA могут управлять как мастер, так и ведомый (slave), в зависимости от направления передачи. Единицей обмена информации является пакет, обрамленный уникальными условиями на шине, именуемыми стартовым и стоповым условиями. Мастер в начале каждого пакета передает один байт, где указывает адрес ведомого и направление передачи последующих данных. Данные передаются 8-битными словами. После каждого слова передается один бит подтверждения приема приемной стороной.

        Ведущее устройство инициирует связь с ведомым устройством. Для начала разговора требуется адрес ведомого устройства. Подчиненное устройство реагирует на ведущее устройство, когда к нему обращается ведущее устройство.

        I 2 C используется во многих приложениях, таких как чтение RTC (часы реального времени), доступ к внешней памяти EEPROM. Он также используется в сенсорных модулях, таких как гироскоп, магнитометр и т. д.

        Контакты Arduino I2C.

        Выводы I2C расположены следующим образом на плате Arduino Uno.

        Выводы I2C расположены следующим образом на плате Arduino Uno.

        Для других моделей плат соответствие выводов такое:

        Плата

        Пин SDA

        Пин SCL

        Connecting Two Nano Every Boards Through I2C

        Learn how to send data from the Nano Every board to another board via I2C.

        Author Benjamin Dannegård
        Last revision 01/24/2024

        In this tutorial we will control the built-in LED of an Arduino Nano Every from another Arduino Nano Every. To do so, we will connect both boards using a wired communication protocol called I2C.

        Note: This example would work connecting an Arduino Nano Every board with any other Arduino board, but be mindful that by using any other board the connections might differ. If the connections vary, it may happen that the code might also need changes to match with the I2C pins of the different boards.

        In this example, we will power both the Arduino boards through a computer, then through the Serial Monitor, we will introduce some commands to turn ON or OFF the LED of the Nano Every board.

        Goals

        The goals of this project are:

        • Understand what I2C protocol is.
        • Use the

        Wire.h

        Hardware & Software Needed

        For this project we will need:

        • Arduino Nano Every
        • Arduino Nano Every (or any other Arduino board that supports I2C)
        • 2 x mini breadboard
        • 10 x jumper wires
        • 2 x 4.7k Ohm resistor

        I2C Protocol

        I2C (Inter Integrated Circuits) is a well known and widely used protocol. It allows us to connect multiple readers to a single writer, meaning that, you could have more than one sensor connected to the same pins of your Arduino board through I2C. The only requisite is that each of those sensors have a unique address.

        The I2C protocol involves using two lines to send and receive data: a serial clock pin (SCL) where the Arduino writer board pulses at a regular interval, and a serial data pin (SDA) over which data is sent between the two devices.

        As the clock line changes from low to high, a single bit of information that will form the address of a specific device, and a command or data is transferred from the board to the I2C device over the SDA line. When this information is sent, the called upon device executes the request and transmits it's data back, if required, to the board over the same line using the clock signal still generated by the writer on SCL.

        If you want to learn more about the I2C protocol and how it works, you can check the I2C standards.

        The Wire Library

        To simplify the use of the I2C protocol, Arduino uses the "Wire" library, which allows you to implement and use this protocol throughout different Arduino boards. This library can only be used on some specific pins of the board, those pins are called SCL and SDA, on the Arduino Nano family boards, the SDA (data line) and SCL (clock line) are on the A4 and A5 pin headers respectively.

        If you want to read more about the

        Wire.h

        library see here.

        Circuit

        In order to communicate both Arduino boards, we will need to connect them as shown in the image below.

        The circuit.

        At the moment of making the connections, we need to remember that this protocol has two dedicated lines SCL (clock) and SDA (data) so we need to make sure to connect the SCL pin, of one of the boards, with the SCL of the other one. The same goes for the SDA as it is shown in the image.

        To finish, we need to connect the GND pins of both boards to each other.

        Note: In order to enable serial communication, both Arduino boards must be connected to your computer via USB.

        Creating the Program

        1. Setting up

        First start by connecting your Arduino Nano Every board to the computer and opening the Arduino Create Web Editor. This board will act as the reader. Start a new sketch and name it Nano_I2C_Reader.

        2. Reader code explanation

        Let's start by adding the

        Wire.h

        library by adding the

        #include 

        statement. Then, in the

        setup()

        we need to add

        Wire.begin(8)

        to initiate the library and give the reader board the address of 8, so the writer can identify who to send or receive data from. We will also use

        Wire.onReceive()

        which gets called every time data is received from the writer.

        1#include
        2
        3 void setup()
        4 Wire.begin(8); // join i2c bus with address #8
        5 Wire.onReceive(receiveEvent); // function that executes whenever data is received from writer
        6 pinMode(LED_BUILTIN,OUTPUT); // sets onBoard LED as output
        7 >
        loop()

        of this code is not as important, since nothing is required to run until we receive something through I2C. Due to this, we will leave the

        loop()

        function empty.

        Instead the focus is on the

        loop()

        where we will create a

        receiveEvent()

        function that is going to run when we get any data received by the board. We can store the data we will receive in the

        variable, for ease of use. The data we will receive will be a character, so we need to compare it as such. The

        statements will check if the character that was sent is a 1 or a 0. It will then turn on or off the built-in LED depending on the received character.

        1void receiveEvent(int howMany)
        2 char c = Wire.read(); // receive a character
        3 if(c == '0')
        4 digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
        5 >
        6 if(c == '1')
        7 digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
        8 >
        9 >

        3. Uploading the code to the reader

        Once we have finished the code, let's upload it to our Arduino Nano Every board. This board is now programmed to act as the reader in this scenario. Once the code is uploaded, let's connect the other board to the computer.

        Note: After uploading the code to the reader board, it is not necessary for it to stay connected to the computer in order to function. However, it needs to be powered in order to work.

        4. Writer code

        It is time to open a new sketch and name it as Nano_I2C_Writer, then let's add the Wire library as we did in the previous code.

        setup()

        we need to add the

        Serial.begin(9600)

        which opens the serial port and sets the data rate to 9600 bits per second (baud). Next we will add the

        while (!Serial);

        which ensures that there is something at the other end of the USB connection, for the Arduino to talk to before it starts sending messages. Otherwise, the message might be sent, but not displayed. We also add

        Wire.begin()

        to initiate the Wire library and join the I2C bus as a writer or reader.

        1#include
        2
        3 void setup()
        4 Serial.begin(9600);
        5 while (!Serial);
        6 Wire.begin(); // join i2c bus (address optional for writer)
        7 >
        loop()

        we first print the message that lets us know what values can be entered. We then define a variable,

        ledVal

        that will hold the value we entered into the Serial Monitor. With the

        readSerial()

        we will take the value entered into the Serial Monitor and store it in the

        ledVal

        variable. We will then begin the I2C communication.

        Wire.beginTransmission(8)

        we designate which reader we will send data to. If you remember, in the reader's code we gave the board the address 8. After communication has been opened we use

        Wire.write()

        to chose what we send to the reader, in this case we send the variable

        ledVal

        After that we simply end the transmission with

        Wire.endTransmission()
        1void loop()
        2 Serial.print("Enter 0 to turn off led, enter 1 to turn it on ");
        3 char ledVal[0];
        4 readSerial(ledVal);
        5 Serial.println(ledVal);
        6 Wire.beginTransmission(8); // transmit to device #8
        7 Wire.write(ledVal); // sends the given value
        8 Wire.endTransmission(); // stop transmitting
        9 delay(500);
        10 >
        readSerial()

        function allows us to take a value that is entered into the Serial Monitor and store it into a variable, enabling us to send it via I2C. The function detects when an entry is sent and takes whatever is typed before the entry and puts it into a variable. It can hold longer strings of characters if needed.

        1int readSerial(char result[])
        2 int i = 0;
        3 while (1)
        4 while (Serial.available() > 0)
        5 char inChar = Serial.read();
        6 if (inChar == '\n')
        7 result[i] = '\0';
        8 Serial.flush();
        9 return 0;
        10 >
        11 if (inChar != '\r')
        12 result[i] = inChar;
        13 i++;
        14 >
        15 >
        16 >
        17 >

        5. Uploading the code to the writer

        Once we have finished the code, let's upload it to our Arduino Nano Every board. This board is now programmed to act as the writer.

        6. Complete code

        If you choose to skip the code building section, the complete code for both the reader and the writer can be found below:

        Reader:

        1#include
        2
        3 void setup()
        4 Wire.begin(8); // join i2c bus with address #8
        5 Wire.onReceive(receiveEvent); // function that executes whenever data is received from writer
        6 pinMode(LED_BUILTIN,OUTPUT); // sets onBoard LED as output
        7 >
        8
        9 void loop()
        10 delay(100);
        11 >
        12
        13 void receiveEvent(int howMany)
        14 char c = Wire.read(); // receive a character
        15 if(c == '0')
        16 digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
        17 >
        18 if(c == '1')
        19 digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
        20 >
        21 >

        Writer:

        1#include
        2
        3 void setup()
        4 Serial.begin(9600);
        5 while (!Serial);
        6 Wire.begin(); // join i2c bus (address optional for writer)
        7 >
        8
        9 void loop()
        10 Serial.print("Enter 0 to turn off led, enter 1 to turn it on ");
        11 char ledVal[0];
        12 readSerial(ledVal);
        13 Serial.println(ledVal);
        14 Wire.beginTransmission(8); // transmit to device #8
        15 Wire.write(ledVal); // sends the given value
        16 Wire.endTransmission(); // stop transmitting
        17 delay(500);
        18 >
        19
        20 /* Read input serial */
        21 int readSerial(char result[])
        22 int i = 0;
        23 while (1)
        24 while (Serial.available() > 0)
        25 char inChar = Serial.read();
        26 if (inChar == '\n')
        27 result[i] = '\0';
        28 Serial.flush();
        29 return 0;
        30 >
        31 if (inChar != '\r')
        32 result[i] = inChar;
        33 i++;
        34 >
        35 >
        36 >
        37 >

        Testing It Out

        After you have successfully verified and uploaded the sketch to the two boards, make sure the writer board is connected, open the Serial Monitor. You will see a text asking for a value of 1 or 0 to be entered. When a value is entered it will be sent to the reader board.

        Nano tutorial I2C serial monitor.

        Troubleshoot

        Sometimes errors occur, if the code is not working there are some common issues we can troubleshoot:

        • Missing a bracket or a semicolon.
        • Arduino board connected to the wrong port.
        • Connection between the Arduino boards are not correct.
        • Accidental interruption of cable connection.

        Conclusion

        In this simple tutorial we learned how to connect two boards so that they can communicate using I2C, with the help of the Wire.h library.

        More Tutorials

        You can find more tutorials for this board in the …

        Author: Benjamin Dannegård

        Date: 20.01.21

        Reviewed by: Jose Garcia, Nefeli Alushi

        Last revision: 03.02.21

        Suggested changes

        The content on docs.arduino.cc is facilitated through a public GitHub repository. You can read more on how to contribute in the contribution policy.

        Need support?
        License

        The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.

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

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