Несколько_библиотек_найдено_для_wire_h

Библиотеки в Arduino IDE

Среди всего разнообразия библиотек можно выделить 3 основных группы:

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

Самым простым способом работы с библиотеками в ардуино является использование встроенных возможностей среды разработки Arduino IDE. Об этом мы поговорим в отдельной статье.

Как подключить нескольких устройств по I2C Arduino

В следующем примере к шине IIC Arduino будет подключено сразу три устройства — текстовый дисплей 1602, датчик давления bmp180 и RTC модуль часов. После сборки схемы можно сделать предварительное сканирование шины, но адреса у всех устройств разные и изменить адрес можно только у дисплея. У других устройств адреса «вшиты» производителем и используются в библиотеках по умолчанию.

Скетч. Подключение нескольких устройств к шине i2c

I2C интерфейс: подключение нескольких устройств

После сборки схемы, убедитесь, что у вас установлены необходимые библиотеки для работы с устройствами по IIC протоколу, и загрузите следующий пример кода в микроконтроллер. Данная программа будет выводить на текстовый экран текущую дату и время суток (устанавливаются в процедуре void setup и время можно поменять), а также данные о температуре воздуха и атмосферном давлении.

#include <Wire.h>  // подключаем библиотеку для интерфейса I2C 

#include <LiquidCrystal_I2C.h>  // подключаем библиотеку для 1602
LiquidCrystal_I2C LCD(0x27, 16, 2);  // создаем объект LCD

#include <SFE_BMP180.h>  // подключаем библиотеку для bmp180
SFE_BMP180 pressure;  // создаем объект pressure

#include <iarduino_RTC.h>  // подключаем библиотеку для часов
iarduino_RTC time(RTC_DS1307);  // создаем объект time

void setup() {
  LCD.init();  // инициализация дисплея
  LCD.backlight();  // включение подсветки

  pressure.begin();  // запускаем датчик давления

  time.begin();  // запускаем модуль часов
  time.settime(0, 30, 16, 1, 4, 21, 5);  // сек, мин, часы, дата, мес, год, день недели
}

void loop() {
  char status;
  double T, P, p0, a;

  // если прошла 1 секунда обновляем информацию
  if (millis() % 1000 == 0) {

    // выводим время с секундами и дату (день, месяц)
    LCD.setCursor(0, 0);
    LCD.print(time.gettime("H:i:s - d.m"));

    // узнаем температуру и выводим на дисплей
    status = pressure.startTemperature();
    if (status != 0) {
      delay(status);
      status = pressure.getTemperature(T);
      if (status != 0) {
        LCD.setCursor(0, 1);
        LCD.print("T:");
        LCD.print(T, 2);

        // узнаем давление и выводим на дисплей
        status = pressure.startPressure(3);
        if (status != 0) {
          delay(status);
          status = pressure.getPressure(P, T);
          if (status != 0) {
            p0 = pressure.sealevel(P, 1655.0);
            LCD.print(" D:");
            LCD.print(p0, 2);

          }
          else { LCD.setCursor(0, 1); LCD.print("error retrieving pressure"); }
        }
        else { LCD.setCursor(0, 1); LCD.print("error starting pressure"); }
      }
      else { LCD.setCursor(0, 1); LCD.print("error retrieving temperature"); }
    }
    else { LCD.setCursor(0, 1); LCD.print("error starting temperature"); }
  }

}

Пояснения к коду:

  1. обновление информации на текстовом экране происходит каждую секунду, данный интервал можно увеличить по своему желанию;
  2. время выводится с секундами, формат вывода времени и даты также можно изменить в строчке

Пример

Остальные примеры смотри в examples!

#define CLK 2
#define DT 3
#define SW 4

#include "GyverEncoder.h"
Encoder enc1(CLK, DT, SW);  // для работы c кнопкой

void setup() {
  Serial.begin(9600);
  enc1.setType(TYPE2);
}

void loop() {
	// обязательная функция отработки. Должна постоянно опрашиваться
  enc1.tick();
  
  if (enc1.isTurn()) {     // если был совершён поворот (индикатор поворота в любую сторону)
    // ваш код
  }
  
  if (enc1.isRight()) Serial.println("Right");         // если был поворот
  if (enc1.isLeft()) Serial.println("Left");
  
  if (enc1.isRightH()) Serial.println("Right holded"); // если было удержание + поворот
  if (enc1.isLeftH()) Serial.println("Left holded");
  
  //if (enc1.isPress()) Serial.println("Press");         // нажатие на кнопку (+ дебаунс)
  //if (enc1.isRelease()) Serial.println("Release");     // то же самое, что isClick
  
  if (enc1.isClick()) Serial.println("Click");         // одиночный клик
  if (enc1.isSingle()) Serial.println("Single");       // одиночный клик (с таймаутом для двойного)
  if (enc1.isDouble()) Serial.println("Double");       // двойной клик
  
  
  if (enc1.isHolded()) Serial.println("Holded");       // если была удержана и энк не поворачивался
  //if (enc1.isHold()) Serial.println("Hold");         // возвращает состояние кнопки
}

Объяснение программы для ведомой (Slave) платы Arduino

1. Как и в ведущей плате, первым делом в программе мы должны подключить библиотеку Wire для задействования возможностей протокола I2C и библиотеку для работы с ЖК дисплеем. Также нам необходимо сообщить плате Arduino к каким ее контактам подключен ЖК дисплей.

Arduino

#include<Wire.h>
#include<LiquidCrystal.h>
LiquidCrystal lcd(2, 7, 8, 9, 10, 11);

1
2
3

#include<Wire.h>    
#include<LiquidCrystal.h>      

LiquidCrystallcd(2,7,8,9,10,11);

  1. В функции void setup():

—  мы инициализируем последовательную связь со скоростью 9600 бод/с;

Arduino

Serial.begin(9600);

1 Serial.begin(9600);

— далее мы инициализируем связь по протоколу I2C на контактах A4 и A5

В качестве адреса ведомого мы будем использовать значение 8 – очень важно здесь указать адрес ведомого;. Arduino

Wire.begin(8);

Arduino

Wire.begin(8);

1 Wire.begin(8);

После этого мы должны вызвать функцию в которой ведомый принимает значение от ведущего и функцию в которой ведущий запрашивает значение от ведомого.

Arduino

Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);

1
2

Wire.onReceive(receiveEvent);

Wire.onRequest(requestEvent);

— затем мы инициализируем ЖК дисплей для работы в режиме 16х2, отображаем на нем приветственное сообщение и очищаем его экран через 5 секунд.

Arduino

lcd.begin(16,2); //Initilize LCD display
lcd.setCursor(0,0); //Sets Cursor at first line of Display
lcd.print(«Circuit Digest»); //Prints CIRCUIT DIGEST in LCD
lcd.setCursor(0,1); //Sets Cursor at second line of Display
lcd.print(«I2C 2 ARDUINO»); //Prints I2C ARDUINO in LCD
delay(5000); //Delay for 5 seconds
lcd.clear(); //Clears LCD display

1
2
3
4
5
6
7

lcd.begin(16,2);//Initilize LCD display

lcd.setCursor(,);//Sets Cursor at first line of Display

lcd.print(«Circuit Digest»);//Prints CIRCUIT DIGEST in LCD

lcd.setCursor(,1);//Sets Cursor at second line of Display

lcd.print(«I2C 2 ARDUINO»);//Prints I2C ARDUINO in LCD

delay(5000);//Delay for 5 seconds

lcd.clear();//Clears LCD display

3. Затем нам будут необходимы две функции: одна для события запроса (request event) и одна для события приема (receive event).

Для события запроса:

Эта функция будет выполняться когда ведущий будет запрашивать значение от ведомого. Эта функция будет считывать значение с потенциометра, подключенного к ведомой плате Arduino, преобразовывать его в диапазон 0-127 и затем передавать его ведущей плате.

Arduino

void requestEvent()
{
int potvalue = analogRead(A0);
byte SlaveSend = map(potvalue,0,1023,0,127);
Wire.write(SlaveSend);
}

1
2
3
4
5
6

voidrequestEvent()

{

intpotvalue=analogRead(A0);

byteSlaveSend=map(potvalue,,1023,,127);

Wire.write(SlaveSend);

}

Для события приема:

Эта функция будет выполняться когда ведущий будет передавать данные ведомому с адресом 8. Эта функция считывает принятые значения от ведущего и сохраняет ее в переменной типа byte.

Arduino

void receiveEvent (int howMany)
{
SlaveReceived = Wire.read();
}

1
2
3
4

voidreceiveEvent(inthowMany)

{

SlaveReceived=Wire.read();

}

4. В функции Void loop():

Мы будем непрерывно отображать принятые от ведущей платы значения на экране ЖК дисплея.

Arduino

void loop(void)
{
lcd.setCursor(0,0); //Sets Currsor at line one of LCD
lcd.print(«>> Slave <<«); //Prints >> Slave << at LCD
lcd.setCursor(0,1); //Sets Cursor at line two of LCD
lcd.print(«MasterVal:»); //Prints MasterVal: in LCD
lcd.print(SlaveReceived); //Prints SlaveReceived value in LCD received from Master
Serial.println(«Slave Received From Master:»); //Prints in Serial Monitor
Serial.println(SlaveReceived);
delay(500);
lcd.clear();
}

1
2
3
4
5
6
7
8
9
10
11
12

voidloop(void)

{

lcd.setCursor(,);//Sets Currsor at line one of LCD

lcd.print(«>>  Slave  <<«);//Prints >> Slave << at LCD

lcd.setCursor(,1);//Sets Cursor at line two of LCD

lcd.print(«MasterVal:»);//Prints MasterVal: in LCD

lcd.print(SlaveReceived);//Prints SlaveReceived value in LCD received from Master

Serial.println(«Slave Received From Master:»);//Prints in Serial Monitor

Serial.println(SlaveReceived);

delay(500);

lcd.clear();

}

После того как вы соберете всю схему проекта и загрузите обе программы в платы Arduino вы можете приступать к тестированию работы проекта. Вращая потенциометр на одной стороне вы должны увидеть изменяющиеся значения на экране ЖК дисплея на другой стороне.

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

Аппаратный модуль TWI

Смотрите следующую схему потока для записи на шину I2C:

Взаимодействие приложения с шиной TWI (I2C) во время типовой передачи

Ссылаясь на таблицу регистров, приведенную выше, операция записи I2C с использованием аппаратного модуля TWI вкратце будет выглядеть следующим образом:

  • Библиотека конфигурирует микросхему ATmega так, что внутренний аппаратный модуль TWI использует свои выводы, которые жестко привязаны к двум аналоговым выводам (4 и 5 на Duemilanove).
  • Библиотека устанавливает значение регистра TWCR для создания состояния .
    • Сначала она проверяет шину I2C, чтобы убедиться, что она свободна. Шина свободна, когда на обеих линиях и SDA, и SCL установлен высокий логический уровень (потому что устройство по умолчанию устанавливает выводы на шине в третье состояние «не подключено». Общий резистор подтягивает сигнал на шине к высокому уровню).
    • Что такое состояние ? Линия тактового сигнала SCL остается в состоянии логической 1, а мастер в это время меняет состояние на линии SDA на логический 0. Это уникальный момент, поскольку во время обычной передачи данных линии SDA изменяет состояние только тогда, когда на линии SCL установлен низкий логический уровень. Момент, когда сигнал на линии данных изменяется на логический 0, а на SCL логическая 1, является сигналом для всех устройств на шине I2C, с которыми мастер собирается начать взаимодействовать.
  • Аппаратный модуль TWI при завершении выполнения действия вызывает прерывание процессора.
  • Библиотека e проверяет состояние по регистру . Предположим, что всё хорошо.
  • Библиотека загружает в регистр адрес ведомого устройства плюс бит «запись». Вместе это значение известно как «SLA+W» («SLave Address plus Write»).
  • Библиотека устанавливает значение регистра для передачи .
  • В случае успеха, библиотека загружает данные в регистр , устанавливает , и данные передаются.
  • Библиотека проверяет состояние по регистру . Предположим, что всё хорошо.
  • Библиотека устанавливает значение регистра для передачи состояния . В состоянии линия SCL освобождается (переходит в высокий логический уровень), и затем линия SDA переходит в состояние логической 1. Обычно линия SDA должна оставаться неизменной, когда на линии SCL установлен высокий логический уровень.

Операция чтения выполняется похожим образом.

Примеры из библиотек:

Большинство библиотек содержат примеры. Это небольшие скетчи (программы) которые раскрывают функционал библиотеки. Наиболее удобный способ просмотра примеров, с помощью средств Arduino IDE. Выберите пункт меню: Файл > Примеры, откроется список с названиями библиотек у которых есть примеры. Наведите курсор на название библиотеки и Вы увидите список примеров содержащихся в ней, клик на примере приведёт к появлению нового окна Arduino IDE со скетчем примера.

Альтернативный способ просмотра примеров заключается в запуске файлов скетчей из папки:путь > libraries > название библиотеки > examples > название примера.

Внутри ATmega328

В основе данного подраздела лежит техническое описание на ATmega328 версии Rev. 8271C – 08/10. Приводимые мной страницы могут немного отличаться от текущей версии.

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

Просмотр технического описания на микроконтроллер показывает нам, как работает двухпроводная (Two Wire) система. Стоит отметить:

Микроконтроллер включает в себя аппаратный модуль TWI, который обрабатывает связь через шину I2C. … Интересно, что это означает, что связь не обрабатывается библиотекой исключительно программно, как вы могли бы подумать! Другими словами, библиотека сама в программе не создает битовый поток. Библиотека взаимодействует с аппаратным компонентом, который выполняет тяжелую работу. Смотрите страницу 222 технического описания.
«AVR TWI работает с байтами и основывается на прерываниях…» (раздел 21.6 на странице 224)

Это ключевой момент; это означает, что
вы настраиваете регистры;
вы позволяете TWI модулю осуществлять связь;
вы можете делать в это время что-то еще; ваш микроконтроллер с тактовой частотой 16 МГц не занят управлением последовательной связью на 100 кГц;
TWI модуль вызывает прерывание, когда заканчивает работу, чтобы уведомить процессор об изменениях состояния (включая успешность операций и/или ошибки).

Однако обратите внимание, что библиотека блокирует ввод/вывод. Это означает, что он переходит в цикл ожидания и ждет завершения связи I2C

Ваше приложение не может ничего делать, пока модуль TWI общается по шине I2C. Обратите внимание, что это может быть не то, чего бы вы хотели: если ваша программа критична ко времени, то ваш 16-мегагерцовый процессор, застрявший в цикле ожидания и ждущий 100-килогерцового потока связи, будет не эффективен. Возможно, вам лучше написать собственный код I2C. В исходном коде avr-libc есть пример в ./doc/examples/twitest/twitest.c (смотрите http://www.nongnu.org/avr-libc/). Вы можете найти версию avr-libc, используемую вашей конкретной IDE Arduino, посмотрев файл versions.txt в каталоге установки Arduino IDE. Это будет где-то в Java/hardware/tools/avr. На Mac полный путь будет следующим /Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/versions.txt; путь у вас будет другим, но схожим.

Подключение библиотеки в проекте

Для того чтобы подключить ранее скаченную и установленную библиотеку в ваш проект, нужно прописать команду в исполнительной строке в начальном модуле скетча: «include <файл.h>«.

Некоторые виды библиотек склонны к использованию «соседних» файлов схожего типа в качестве вспомогательных. В подобном случае стоит производить подключение сразу двух разных типов одновременно. Алгоритм не нарушится.

Далее создаём объект класса, через который будет осуществлён доступ к функциям.

Можно указать как параметр LCD, так и абсолютно любое сочетание цифровых знаков и букв. Единственная особенность состоит в том, что путь к такому файлу будет осуществляться в строгом соответствии с названием, к примеру ourLCD.print («my text»).

Общие сведения:

Многие скетчи (программы) работают с библиотеками. Библиотека облегчает работу с определённым модулем или одним из типов модулей. Например, если Вы хотите вывести текст на LCD дисплей без подключения библиотеки, то Вам нужно передать ему несколько байт команд и данных, что займет несколько строк кода, а главное, что Вам нужно знать тип микроконтроллера под управлением которого работает LCD дисплей, назначение команд которыми он управляется, знать архитектуру его памяти, адреса и назначение регистров, для чего потребуется найти и перечитать его datasheet. В то время как при написании кода с использованием библиотеки (например LiquidCrystal_I2C.h) Вы сможете вывести текст на дисплей вызвав всего одну функцию библиотеки: lcd.print(«my text»);

Перед тем как начать пользоваться методами и функциями библиотеки, её нужно скачать (загрузить на Ваш компьютер), установить (разместить в нужной папке) и подключить (вставить текст «#include » в скетч).

Калибровка pH электрода

Калибровка pH электрода играет существенную роль в нашем проекте. Для проведения калибровки нам будет нужна жидкость (вещество) с известным значением pH, будем называть эту жидкость контрольным раствором.

Предположим, что у нас есть жидкость, значение pH которой равно 7 (дистиллированная вода). К примеру, при погружении в эту жидкость мы получим на экране ЖК дисплея значение 6.5. В данном случае для осуществления калибровки нам будет необходимо просто добавить значение 7-6.5=0.5 к значению калибровочной переменной (“calibration_value”) в коде нашей программы, то есть получим ее значение равное 21.34 + 0.5=21.84. После внесения этих изменений в код программы ее необходимо заново загрузить в плату Arduino и снова проверить работу устройства путем погружения электрода в контрольный раствор (с известным значением pH). Теперь на экране ЖК дисплея мы должны увидеть уже точное значение pH равное 7. Если оно будет все равно немного отличаться от своего истинного значения, то снова корректируем калибровочное значение в коде программы и снова тестируем работу проекта.

Способ 2: чтение датчика DS18B20 по адресу

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

Поиск адресов датчиков DS18B20s на шине

Следующий скетч обнаруживает все DS18B20, присутствующие на шине, и печатает их адреса на 1-Wire в монитор последовательного порта.

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

Теперь откройте монитор последовательного порта. Вы должны получить что-то подобное:

Рисунок 6 – Нахождение адресов 1-Wire всех датчиков DS18B20 на шине

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

Чтение показаний датчиков DS18B20 по адресу

Следующий скетч считывает температуру датчиков DS18B20 по их адресам. Прежде чем приступить к загрузке скетча, вам нужно изменить адреса датчиков DS18B20 на те, которые вы определили в предыдущем скетче.

Вывод вышеприведенного эскиза выглядит так

Рисунок 7 – Вывод показаний нескольких датчиков DS18B20 методом адреса

Объяснение кода

Как обычно, скетч начинается с включения библиотек, объявления вывода, к которому подключена шина датчиков, и создания объекта библиотеки .

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

Во фрагменте настройки мы инициализируем библиотеку путем вызова функции и инициализируем последовательную связь с ПК.

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

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

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

Объяснение программы для Arduino

Полный код программы для нашего pH метра на основе Arduino приведен в конце статьи, здесь же мы кратко рассмотрим его основные фрагменты.

Первым делом в программе мы должны подключить все используемые библиотеки. В нашем случае мы подключили библиотеку “LiquidCrystal_I2C.h” для использования интерфейса I2C с целью обмена данными с ЖК дисплеем и библиотеку “Wire.h” для использования функционала интерфейса I2C в плате Arduino.

Arduino

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

1
2
3

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2Clcd(0x27,16,2);

Далее определим калибровочное значение, которое в дальнейшем можно будет изменить (переопределить, откалибровать) для получения более точных значений pH.

Arduino

float calibration_value = 21.34;

1 floatcalibration_value=21.34;

Внутри функции setup() мы будем отображать на экране ЖК дисплея приветственное сообщение.

Arduino

lcd.init();
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(» Welcome to «);
lcd.setCursor(0, 1);
lcd.print(» Circuit Digest «);
delay(2000);
lcd.clear();

1
2
3
4
5
6
7
8
9

lcd.init();

lcd.begin(16,2);

lcd.backlight();

lcd.setCursor(,);

lcd.print(»   Welcome to      «);

lcd.setCursor(,1);

lcd.print(» Circuit Digest    «);

delay(2000);

lcd.clear();

Внутри функции loop() мы будем считывать 10 аналоговых значений (отсчетов) и сохранять их в массив – это необходимо для сглаживания результата измерений.

Arduino

for(int i=0;i<10;i++)
{
buffer_arr=analogRead(A0);
delay(30);
}

1
2
3
4
5

for(inti=;i<10;i++)

{

buffer_arri=analogRead(A0);

delay(30);

}

Затем мы отсортируем принятые аналоговые значения по возрастанию. Это необходимо для расчета скользящего среднего отсчетов на более поздней стадии (в дальнейшем).

Arduino

for(int i=0;i<9;i++)
{
for(int j=i+1;j<10;j++)
{
if(buffer_arr>buffer_arr)
{
temp=buffer_arr;
buffer_arr=buffer_arr;
buffer_arr=temp;
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12

for(inti=;i<9;i++)

{

for(intj=i+1;j<10;j++)

{

if(buffer_arri>buffer_arrj)

{

temp=buffer_arri;

buffer_arri=buffer_arrj;

buffer_arrj=temp;

}

}

}

Наконец, мы рассчитаем среднее 6-ти центральных отсчетов в наших аналоговых значениях. Затем это рассчитанное среднее мы преобразуем (конвертируем) в значение pH и выводим его на экран ЖК дисплея.

Arduino

for(int i=2;i<8;i++)
avgval+=buffer_arr;
float volt=(float)avgval*5.0/1024/6;
float ph_act = -5.70 * volt + calibration_value;
lcd.setCursor(0, 0);
lcd.print(«pH Val:»);
lcd.setCursor(8, 0);
lcd.print(ph_act);
delay(1000);
}

1
2
3
4
5
6
7
8
9
10

for(inti=2;i<8;i++)

avgval+=buffer_arri;

floatvolt=(float)avgval*5.010246;

floatph_act=-5.70*volt+calibration_value;

lcd.setCursor(,);

lcd.print(«pH Val:»);

lcd.setCursor(8,);

lcd.print(ph_act);

delay(1000);

}

Схема проекта

Схема управляемой жестами роботизированной руки на основе платы Arduino представлена на следующем рисунке.

В следующей таблице представлены соединения между датчиком MPU6050 и платой Arduino Nano.

Датчик MPU6050 Плата Arduino Nano
VCC +5V
GND GND
SDA A4
SCL A5

В следующей таблице представлены соединения между сервомоторами и платой Arduino Nano.

Плата Arduino Nano Сервомоторы Адаптер питания
D2 Servo 1 Orange (PWM Pin)
D3 Servo 2 Orange (PWM Pin)
D4 Servo 3 Orange (PWM Pin)
D5 Servo 4 Orange (PWM Pin)
GND Servo 1,2,3,4 Brown (GND Pin) GND
Servo 1,2,3,4 Red (+5V Pin) +5V

Гибкий датчик имеет 2 контакта – они не имеют полярности. Поэтому один контакт датчика подключен через подтягивающий резистор 10 кОм к контакту A0 платы Arduino, а другой – к контакту земли платы Arduino.

Basic Usage

VirtualWire works somewhat differently than most Arduino libraries. Many individual functions are used, and their names are somewhat different. Fortunately, each one is simple.

Configuration Functions

Configure the transmit pin. Default is pin 12.

Configure the receive pin, Default is pin 11. On Teensy 2.0, pin 11 should not be used because most receiver modules can not work correctly with the orange LED on that pin.

Configure the transmit enable pin, or «push to talk». Default is pin 10.

Configure the «push to talk» polarity.

Begin using all settings and initialize the library. This is similar to the «begin» function of other libraries. All pins should be configured before calling this function.

Transmission Functions

Transmit a message. «message» is an array of the bytes to send, and «length» is the number of bytes stored in the array. This function returns immediately and the message is sent slowly by an interrupt-based background process.

Returns true if the message is being sent, or false if the transmitter is not active. You can use this after sending a message to test when it has finished being transmitted.

Wait for a message to be fully transmitted. Often the simplest approach is to call this after vw_send.

Reception Functions

Activate the receiver process. You must call this function before any reception can occur. An interrupt-based background process is started which monitors the reception of data.

Returns true if message has been received. This is similar to the «available» function of most other libraries.

Wait for a message to be received. This will only return when a message has been received, otherwise it will wait forever.

Wait for a message, but give up after «timeout_ms». Returns true if a message was received, or false if the timeout period elapsed.

Read the last received message. This should be called only when a message is known to be received with any of the 3 functions above. «buf» is an array where the message is copied. «buflen» should have the array’s maximum size upon input, and upon return the number of bytes actually copied is retured. The function itself returns true if the message was verified correct, or false if a message was received but appears to have been corrupted.

Disable the receiver process.

Исходный код программы (скетча)

Arduino

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
float calibration_value = 21.34;
int phval = 0;
unsigned long int avgval;
int buffer_arr,temp;
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.begin(16, 2);
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print(» Welcome to «);
lcd.setCursor(0, 1);
lcd.print(» Circuit Digest «);
delay(2000);
lcd.clear();
}
void loop() {
for(int i=0;i<10;i++)
{
buffer_arr=analogRead(A0);
delay(30);
}
for(int i=0;i<9;i++)
{
for(int j=i+1;j<10;j++)
{
if(buffer_arr>buffer_arr)
{
temp=buffer_arr;
buffer_arr=buffer_arr;
buffer_arr=temp;
}
}
}
avgval=0;
for(int i=2;i<8;i++)
avgval+=buffer_arr;
float volt=(float)avgval*5.0/1024/6;
float ph_act = -5.70 * volt + calibration_value;
lcd.setCursor(0, 0);
lcd.print(«pH Val:»);
lcd.setCursor(8, 0);
lcd.print(ph_act);
delay(1000);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2Clcd(0x27,16,2);

floatcalibration_value=21.34;

intphval=;

unsignedlongintavgval;

intbuffer_arr10,temp;

voidsetup()

{

Serial.begin(9600);

lcd.init();

lcd.begin(16,2);

lcd.backlight();

lcd.setCursor(,);

lcd.print(»   Welcome to      «);

lcd.setCursor(,1);

lcd.print(» Circuit Digest    «);

delay(2000);

lcd.clear();

}

voidloop(){

for(inti=;i<10;i++)

{

buffer_arri=analogRead(A0);

delay(30);

}

for(inti=;i<9;i++)

{

for(intj=i+1;j<10;j++)

{

if(buffer_arri>buffer_arrj)

{

temp=buffer_arri;

buffer_arri=buffer_arrj;

buffer_arrj=temp;

}

}

}

avgval=;

for(inti=2;i<8;i++)

avgval+=buffer_arri;

floatvolt=(float)avgval*5.010246;

floatph_act=-5.70*volt+calibration_value;

lcd.setCursor(,);

lcd.print(«pH Val:»);

lcd.setCursor(8,);

lcd.print(ph_act);

delay(1000);

}