КОРЗИНА
магазина
8 (499) 500-14-56 | ПН. - ПТ. 12:00-18:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"

Бампер с 9 датчиками линий, FLASH-I2C



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

Модуль - Бампер с 9 датчиками линий с шагом 14мм или шагом 7мм, I2C-flash - предназначен для установки на подвижные механизмы (машины, тракторы, танки, роботы) для их движения по линии без участия оператора. Модуль снабжен световой индикацией наличия линии и поворотниками.

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

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

Видео:

Редактируется ...

Спецификация:

  • Напряжение питания: 3,3 В или 5 В (постоянного тока).
  • Потребляемый ток: до 20 мА (все светодиоды включены).
  • Расстояние от трассы до датчиков: от 2 до 50 мм.
  • Максимальная скорость движения бампера (м/с): ширина линии (мм) / 3.
  • Интерфейс: I2C.
  • Скорость шины I2C: 100 кбит/с.
  • Адрес на шине I2C: устанавливается программно (по умолчанию 0x09).
  • Уровень логической 1 на линиях шины I2C: Vcc.
  • Рабочая температура: от -20 до +70 °С.
  • Габариты модуля с шагом 14мм: 119 x 25 мм (без креплений), 119 x 35 мм (с креплениями).
  • Габариты модуля с шагом 7мм: 59 x 25 мм (без креплений), 59 x 35 мм (с креплениями).
  • Вес: 10 г.

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

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

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

Модуль подключается по шине I2C, все выводы которой (GND, Vcc, SDA, SCL) размещены на двух одинаковых колодках.

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

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

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

Способ - 1: Используя провода и Piranha UNO

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

Вывод Arduino Вывод модуля
SDA (A4) SDA
SCL (A5) SCL
5V 5V
GND GND

Способ - 2: Используя провода и Shield

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

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

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

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

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

Модуль
Pi Pico
SDA
GP6
SCLGP7
Vcc3V3(OUT)
GNDGND

Питание:

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

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

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

Модуль позволяет:

      • Изменить свой адрес на шине I2C, временно (пока есть питание) или постоянно.
      • Получать аналоговые значения (АЦП) с датчиков линий.
      • Получать цифровые значения с датчиков линий (есть линия под датчиком или нет).
      • Выполнить калибровку для цветов линий и фона используемых на трассе.
      • Узнать тип трассы для которой откалиброван модуль (трасса со светлой или тёмной линией).
      • Изменить тип трассы (считать фон как линию, а линию как фон).
      • Задать скорость мигания поворотников.
      • Управлять поворотниками самостоятельно, или указать им работать в автоматическом режиме.

      Специально для работы с модулем - Бампер с 9 датчиками линий с шагом 14мм или шагом 7мм, I2C-flash, нами разработана библиотека iarduino_I2C_Bumper которая позволяет реализовать все функции модуля.

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

      Калибровка:

      Калибровка модуля может быть запущена методами библиотеки iarduino_I2C_Bumper, или нажатием на кнопку «калибровка».

      Калибровка позволяет модулю отличать линии трассы от фона. Автоматическая калибровка состоит из двух этапов: чтение количества отражённого света от поверхности линии и чтение количества отражённого света от поверхности фона трассы. Результаты калибровки сохраняются в энергонезависимую память модуля, а значит модуль будет отличать линии от фона и после отключения питания.

      Установите модуль так, что бы все его датчики находились над линией трассы и нажмите на кнопку «калибровка», или обратитесь к методу setCalibrationRun(). О начале калибровки сигнализирует включение левого поворотника и поочерёдное включение светодиодов расположенных перед датчиками линий, далее светодиоды отключатся, после чего все светодиоды начнут мигать в шахматном порядке, информируя о необходимости перехода к чтению фона трассы для завершения калибровки.

      Установите модуль так, что бы все его датчики находились над фоном трассы и нажмите на кнопку «калибровка», или обратитесь к методу setCalibrationEnd(). О начале калибровки сигнализирует включение правого поворотника и поочерёдное включение светодиодов расположенных перед датчиками линий, далее светодиоды отключатся, после чего все светодиоды расположенные перед датчиками одновременно включатся на пол секунды или быстро мигнут три раза, информируя о результате калибровки.

      Успех калибровки определяется модулем по контрасту между фоном и линией, при малой контрастности калибровка будет считаться неудачной, а её результаты не сохранятся в памяти модуля. Если калибровка закончилась провалом, то все светодиоды расположенные перед датчиками линий быстро мигнут три раза. Если калибровка закончилась успехом, то все светодиоды расположенные перед датчиками линий включатся на пол секунды. Так же о результате калибровки можно судить по флагам возвращаемым методами setCalibrationRun() и setCalibrationEnd(), или по значению статуса калибровки, возвращаемому методом getCalibrationStage().

      В результате калибровки модуль не только сможет отличать линии от фона, но и определит тип трассы (трасса с тёмной линией на светлом фоне, или со светлой линией на тёмном фоне). Тип линии трассы можно узнать методом getLineType(). Если на трассе есть участки, где цвет линии меняется с цветом фона, то достаточно сменить тип линии трассы методом setLineType().

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

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

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

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

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

      Смена и сортировка адресов на шине 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_Bumper. Сама библиотека содержит больше примеров, доступных из меню Arduino IDE: Файл / Примеры / iarduino_I2C_Bumper.

      Чтение линий под датчиками модуля:

      #include <Wire.h>                                          //   Подключаем библиотеку для работы с аппаратной шиной I2C.
      #include <iarduino_I2C_Bumper.h>                           //   Подключаем библиотеку для работы с бампером I2C-flash.
      iarduino_I2C_Bumper bum(0x09);                             //   Объявляем объект bum для работы с функциями и методами библиотеки iarduino_I2C_Bumper, указывая адрес модуля на шине I2C.
                                                                 //   Если объявить объект без указания адреса (iarduino_I2C_Bumper bum;), то адрес будет найден автоматически.
      void setup(){                                              //
           Serial.begin(9600);                                   //   Инициируем передачу данных в монитор последовательного порта на скорости 9600 бит/сек.
           bum.begin();                                          //   Инициируем работу с бампером.
      }                                                          //
                                                                 //
      void loop(){                                               //
           Serial.print( "Линия находится под датчиком:" );      //   Выводим текст.
           if( bum.getLineDigital(1) ){ Serial.print(" 1"); }    //   Выводим номер 1 датчика, если под ним находится линия.
           if( bum.getLineDigital(2) ){ Serial.print(" 2"); }    //   Выводим номер 2 датчика, если под ним находится линия.
           if( bum.getLineDigital(3) ){ Serial.print(" 3"); }    //   Выводим номер 3 датчика, если под ним находится линия.
           if( bum.getLineDigital(4) ){ Serial.print(" 4"); }    //   Выводим номер 4 датчика, если под ним находится линия.
           if( bum.getLineDigital(5) ){ Serial.print(" 5"); }    //   Выводим номер 5 датчика, если под ним находится линия.
           if( bum.getLineDigital(6) ){ Serial.print(" 6"); }    //   Выводим номер 6 датчика, если под ним находится линия.
           if( bum.getLineDigital(7) ){ Serial.print(" 7"); }    //   Выводим номер 7 датчика, если под ним находится линия.
           if( bum.getLineDigital(8) ){ Serial.print(" 8"); }    //   Выводим номер 8 датчика, если под ним находится линия.
           if( bum.getLineDigital(9) ){ Serial.print(" 9"); }    //   Выводим номер 9 датчика, если под ним находится линия.
           Serial.println(".");                                  //   Завершаем строку.
           delay(200);                                           //   Задержка позволяет медленнее заполнять монитор последовательного порта.
      }                                                          //
      

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

      В примере Arduino IDE: Файл / Примеры / iarduino I2C Bumper (бампер) / getLineDigitalFast показано как считать состояние всех датчиков одним запросом к модулю, что резко увеличивает скорость работы с ним.

      Чтение аналоговых значений с датчиков модуля:

      #include <Wire.h>                                          //   Подключаем библиотеку для работы с аппаратной шиной I2C.
      #include <iarduino_I2C_Bumper.h>                           //   Подключаем библиотеку для работы с бампером I2C-flash.
      iarduino_I2C_Bumper bum(0x09);                             //   Объявляем объект bum для работы с функциями и методами библиотеки iarduino_I2C_Bumper, указывая адрес модуля на шине I2C.
                                                                 //   Если объявить объект без указания адреса (iarduino_I2C_Bumper bum;), то адрес будет найден автоматически.
      void setup(){                                              //
           Serial.begin(9600);                                   //   Инициируем передачу данных в монитор последовательного порта на скорости 9600 бит/сек.
           bum.begin();                                          //   Инициируем работу с бампером.
      }                                                          //
                                                                 //
      void loop(){                                               //
           Serial.print( "Аналоговые значения датчиков 1-9: " ); //   Выводим текст.
           Serial.print( (String) bum.getLineAnalog(1) + ", " ); //   Выводим значение АЦП снятое с 1 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(2) + ", " ); //   Выводим значение АЦП снятое с 2 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(3) + ", " ); //   Выводим значение АЦП снятое с 3 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(4) + ", " ); //   Выводим значение АЦП снятое с 4 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(5) + ", " ); //   Выводим значение АЦП снятое с 5 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(6) + ", " ); //   Выводим значение АЦП снятое с 6 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(7) + ", " ); //   Выводим значение АЦП снятое с 7 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(8) + ", " ); //   Выводим значение АЦП снятое с 8 датчика линии и текст ", ".
           Serial.print( (String) bum.getLineAnalog(9) + ".\n"); //   Выводим значение АЦП снятое с 9 датчика линии и текст ".\n".
           delay(200);                                           //   Задержка позволяет медленнее заполнять монитор последовательного порта.
      }                                                          //
      

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

      Аналоговыми значениями датчиков линий являются показания АЦП (аналого-цифрового преобразователя). Чем светлее объект находящийся под датчиком линий, тем выше показания АЦП. Оперируя аналоговыми значениями бампера, можно использовать трассы с разметками разных цветов.

      Чтение ошибки центрирования линии для ПИД регулятора:

      #include <Wire.h>                                          //   Подключаем библиотеку для работы с аппаратной шиной I2C.
      #include <iarduino_I2C_Bumper.h>                           //   Подключаем библиотеку для работы с бампером I2C-flash.
      iarduino_I2C_Bumper bum(0x09);                             //   Объявляем объект bum для работы с функциями и методами библиотеки iarduino_I2C_Bumper, указывая адрес модуля на шине I2C.
                                                                 //   Если объявить объект без указания адреса (iarduino_I2C_Bumper bum;), то адрес будет найден автоматически.
      float val_Speed   = ЗНАЧЕНИЕ;                              //   Скорость движения машины.
      float pid_KP      = ЗНАЧЕНИЕ;                              //   Коэффициент пропорциональной обратной связи ПИД регулятора.
      float pid_KI      = ЗНАЧЕНИЕ;                              //   Коэффициент интегральной     обратной связи ПИД регулятора.
      float pid_KD      = ЗНАЧЕНИЕ;                              //   Коэффициент дифференциальной обратной связи ПИД регулятора.
      float arr_ERR[10] = {0,0,0,0,0,0,0,0,0,0};                 //   Массив последних ошибок для формирования интегральной составляющей ПИД регулятора.
      uint8_t i, j;                                              //   Переменные для работы с массивом последних ошибок «arr_ERR».
                                                                 //
      void setup(){                                              //
           bum.begin();                                          //   Инициируем работу с бампером.
      }                                                          //
                                                                 //
      void loop(){                                               //
           i++; i%=10; j=10;                                     //   Определяем значения переменных.
      //   Получаем текущую ошибку центрирования линии:          //
           arr_ERR[i] = bum.getErrPID();                         //   Функция getErrPID() возвращает ошибку от 0 до ±4.5, где 0 - линия по центру, ±4.0 - линия на крайнем датчике, ±4.5 - линия потеряна.
      //   Вычисляем все составляющие ПИД регулятора:            //
           float pid_P = arr_ERR[i];                             //   Пропорциональная составляющая «pid_P» представлена величиной текущей ошибки «ARR_ERR[i]».
           float pid_I = 0.0f; while(j--){pid_I+=arr_ERR[j-1];}  //   Интегральная     составляющая «pid_I» представлена суммой последних ошибок взятых из массива «arr_ERR».
           float pid_D = arr_ERR[i]-arr_ERR[(i+9)%10];           //   Дифференциальная составляющая «pid_D» представлена разницей между текущей «ARR_ERR[i]» и предыдущей «arr_ERR[(i+9)%10]» ошибкой.
           float PID   = pid_P*pid_KP+pid_I*pid_KI+pid_D*pid_KD; //   Вычисляем результат ПИД регулирования.
      //   Устанавливаем скорость вращения колёс:                //
           setSpeedL( val_Speed + PID );                         //   Устанавливаем скорость мотора левого  колеса.
           setSpeedR( val_Speed - PID );                         //   Устанавливаем скорость мотора правого колеса.
      }

      Данный скетч демонстрирует возможность получения ошибки центрирования линии getErrPID(), для движения машины по линии с использованием ПИД регулятора. Для маневрирования на перекрёстках, функцию getErrPID() можно вызвать с числом и знаком поворота. Число определяет толщину линии (сколько датчиков умещается над линией), а знак определяет направление поворота (-влево,+вправо).

      Для работы скетча необходимо указать скорость val_Speed, коэффициенты обратной связи ПИД регулятора (pid_KP, pid_KI, pid_KD) и определить функции управления моторами setSpeedL() и setSpeedR().

      Управление поворотниками:

      #include <Wire.h>                                          //   Подключаем библиотеку для работы с аппаратной шиной I2C.
      #include <iarduino_I2C_Bumper.h>                           //   Подключаем библиотеку для работы с бампером I2C-flash.
      iarduino_I2C_Bumper bum(0x09);                             //   Объявляем объект bum для работы с функциями и методами библиотеки iarduino_I2C_Bumper, указывая адрес модуля на шине I2C.
                                                                 //   Если объявить объект без указания адреса (iarduino_I2C_Bumper bum;), то адрес будет найден автоматически.
      void setup(){                                              //
           bum.begin();                                          //   Инициируем работу с бампером.
           bum.setTurnPeriod(BUM_TURN_200);                      //   Задаём скорость мигания поворотников в 200мс. Возможные значения: BUM_TURN_100, BUM_TURN_200, BUM_TURN_400 и BUM_TURN_800.
      }                                                          //
                                                                 //
      void loop(){                                               //
           bum.setTurnSignal(BUM_TURN_LEFT);      delay(5000);   //   Включаем левый поворотник и ждём 5 секунд.
           bum.setTurnSignal(BUM_TURN_RIGHT);     delay(5000);   //   Включаем правый поворотник и ждём 5 секунд.
           bum.setTurnSignal(BUM_TURN_EMERGENCY); delay(5000);   //   Включаем поворотниками аварийный сигнал и ждём 5 секунд.
           bum.setTurnSignal(BUM_TURN_POLICE);    delay(5000);   //   Включаем поворотники в полицейский режим и ждём 5 секунд.
           bum.setTurnSignal(BUM_TURN_OFF);       delay(5000);   //   Отключаем поворотники и ждём 5 секунд.
      }                                                          //
      

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

      • 5 секунд мигает левый поворотник;
      • 5 секунд мигает правый поворотник;
      • 5 секунд мигают оба поворотника - аварийный сигнал;
      • 5 секунд поворотники работают в режиме полицейской машины;
      • 5 секунд поворотники не мигают.

      В примере Arduino IDE: Файл / Примеры / iarduino I2C Bumper (бампер) / setTurnSignalAuto показано как заставить поворотники включаться и отключаться в автоматическом режиме (по положению линии под датчиками).

      Калибровка модуля:

      #include <Wire.h>                                          //   Подключаем библиотеку для работы с аппаратной шиной I2C.
      #include <iarduino_I2C_Bumper.h>                           //   Подключаем библиотеку для работы с бампером I2C-flash.
      iarduino_I2C_Bumper bum(0x09);                             //   Объявляем объект bum для работы с функциями и методами библиотеки iarduino_I2C_Bumper, указывая адрес модуля на шине I2C.
                                                                 //   Если объявить объект без указания адреса (iarduino_I2C_Bumper bum;), то адрес будет найден автоматически.
      void setup(){                                              //
           Serial.begin(9600);                                   //   Инициируем передачу данных в монитор последовательного порта на скорости 9600 бит/сек.
           bool f;                                               //   Объявляем флаг для отслеживания результатов калибровки.
           bum.begin();                                          //   Инициируем работу с бампером.
           Serial.println("Установите бампер над линией трассы");//   Выводим текст.
           Serial.println("У Вас есть 5 секунд...\r\n");         //   Выводим текст.
           delay(5000);                                          //   Ждём 5 секунд.
           Serial.println("Запускаем калибровку.\r\nЖдите.\r\n");//
           f = bum.setCalibrationRun();                          //   Запускаем калибровку.
           Serial.println( f? "Линия считана!":"Ошибка!.");      //   Выводим текст зависящий от флага f.
           Serial.println("\r\nУстановите бампер над фоном");    //   Выводим текст.
           Serial.println("У Вас есть 5 секунд...\r\n");         //   Выводим текст.
           delay(5000);                                          //   Ждём 5 секунд.
           Serial.println("Завершаем калибровку.\r\nЖдите.\r\n");//   Выводим текст.
           f = bum.setCalibrationEnd();                          //   Завершаем калибровку.
           Serial.println( f? "Фон считан!":"Ошибка!.");         //   Выводим текст зависящий от флага f.
      }                                                          //
                                                                 //
      void loop(){}                                              //
      

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

      Через 5 секунд произойдёт обращение к функции setCalibrationRun() которая запустит калибровку и модуль считает данные с датчиков. Функция может выполняться до 5 секунд, после чего в мониторе появится результат чтения линий.

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

      Через 5 секунд произойдёт обращение к функции setCalibrationEnd() которая инициирует завершение калибровки и модуль считает данные с датчиков. Функция может выполняться до 5 секунд, после чего в мониторе появится результат чтения фона.

      Если при выполнении всего скетча в мониторе не появилась надпись «Ошибка!», значит модуль откалиброван и способен отличать линии данной трассы от фона.

      Вместо обращения к функциям setCalibrationRun() и setCalibrationEnd(), на любом этапе калибровки, можно просто нажать на кнопку «калибровка».

        В примере Arduino IDE: Файл / Примеры / iarduino I2C Bumper (бампер) / setCalibrationManual показано как выполнить калибровку в ручном режиме. Такая калибровка выполняется за 100 мс, при этом датчики модуля могут находиться даже вне трассы.

        Автоматическая смена типа линии на трассе:

        #include <Wire.h>                                          //   Подключаем библиотеку для работы с аппаратной шиной I2C.
        #include <iarduino_I2C_Bumper.h>                           //   Подключаем библиотеку для работы с бампером I2C-flash.
        iarduino_I2C_Bumper bum;                                   //   Объявляем объект bum для работы с функциями и методами библиотеки iarduino_I2C_Bumper.
                                                                   //   Если при объявлении объекта указать адрес, например, bum(0xBB), то пример будет работать с тем модулем, адрес которого был указан.
        void setup(){                                              //
             bum.begin();                                          //   Инициируем работу с бампером.
        }                                                          //
                                                                   //
        void loop(){                                               //
             if( bum.getLineSum() > 4 ){                           //   Если больше 4 датчиков бампера фиксируют линию, то ...
                 bum.setLineType(BUM_LINE_CHANGE);                 //   Меняем тип линии трассы.
             }                                                     //
        }                                                          //
        

        Данный пример сменит тип линии трассы если более 4 датчиков бампера одновременно фиксируют линию. Это значит, что если ширина линии используемой вами трассы уже чем расстояние между 4 датчиками, то скетч будет корректно определять линию, даже если на трассе есть места где цвет линии меняется с цветом фона.

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

        В данном разделе описаны функции библиотеки iarduino_I2C_Bumper для работы с модулем - Бампер с 9 датчиками линий с шагом 14мм или шагом 7мм, I2C-flash.

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

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

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

        При создании объекта без указания адреса, на шине должен находиться только один модуль.

        Функция begin();

        • Назначение: Инициализация работы с модулем.
        • Синтаксис: begin();
        • Параметры: Нет.
        • Возвращаемое значение: bool - результат инициализации (true или false).
        • Примечание: По результату инициализации можно определить наличие модуля на шине.
        • Пример:
        if( bum.begin() ){ Serial.print( "Модуль найден и инициирован!" ); }
        else             { Serial.print( "Модуль не найден на шине I2C" ); }

        Функция reset();

        • Назначение: Перезагрузка модуля.
        • Синтаксис: reset();
        • Параметры: Нет.
        • Возвращаемое значение: bool - результат перезагрузки (true или false).
        • Пример:
        if( bum.reset() ){ Serial.print( "Модуль    перезагружен" ); }
        else             { Serial.print( "Модуль не перезагружен" ); }

        Функция changeAddress();

        • Назначение: Смена адреса модуля на шине I2C.
        • Синтаксис: changeAddress( АДРЕС );
        • Параметр: uint8_t АДРЕС - новый адрес модуля на шине I2C (целое число от 0x08 до 0x7E)
        • Возвращаемое значение: bool - результат смены адреса (true или false).
        • Примечание: Текущий адрес модуля можно узнать функцией getAddress().
        • Пример:
        if( bum.changeAddress(0x12) ){ Serial.print( "Адрес модуля изменён на 0x12" ); }
        else                         { Serial.print( "Не удалось изменить адрес"    ); }

        Функция getAddress();

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

        Функция getVersion();

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

        Функция setTurnSignal();

        • Назначение: Указание режима работы поворотников.
        • Синтаксис: setTurnSignal( РЕЖИМ );
        • Параметр: uint8_t РЕЖИМ работы поворотников, может принимать следующие значения:
          • BUM_TURN_OFF - поворотники отключены.
          • BUM_TURN_LEFT - включён (мигает) левый поворотник.
          • BUM_TURN_RIGHT - включён (мигает) правый поворотник.
          • BUM_TURN_EMERGENCY - поворотники работают в режиме аварийного сигнала.
          • BUM_TURN_POLICE - поворотники работают в режиме полицейской машины.
          • BUM_TURN_AUTO - поворотники работают в автоматическом режиме.
        • Возвращаемое значение: bool - результат применения нового режима (true или false).
        • Примечание: Параметры автоматического режима задаются функцией settingsTurnAuto().
        • Пример:
        bum.setTurnSignal(BUM_TURN_LEFT ); // Включить только левый  поворотник.
        bum.setTurnSignal(BUM_TURN_RIGHT); // Включить только правый поворотник.
        

        Функция setTurnPeriod();

        • Назначение: Указание периода мигания поворотников.
        • Синтаксис: setTurnPeriod( ПЕРИОД );
        • Параметр: uint8_t ПЕРИОД мигания поворотников, может принимать следующие значения:
          • BUM_TURN_100 - период мигания равен 100мс (10Гц) 50мс вкл / 50мс выкл.
          • BUM_TURN_200 - период мигания равен 200мс (5Гц) 100мс вкл / 100мс выкл.
          • BUM_TURN_400 - период мигания равен 400мс (2,5Гц) 200мс вкл / 200мс выкл.
          • BUM_TURN_800 - период мигания равен 800мс (1,25Гц) 400мс вкл / 400мс выкл.
        • Возвращаемое значение: bool - результат применения нового периода (true или false).
        • Примечание: Функцию можно вызывать как до включения поворотников, так и во время их работы.
        • Пример:
        bum.setTurnPeriod(BUM_TURN_800); // Задать период мигания поворотников равен 800 мс.
        

        Функция settingsTurnAuto();

        • Назначение: Указание условий работы поворотников в автоматическом режиме.
        • Синтаксис: settingsTurnAuto( ВКЛ , ВЫКЛ [, ФЛАГ] );
        • Параметры:
          • uint8_t ВКЛ - условие включения поворотников, может принимать следующие значения:
            • BUM_AUTO_ON_1 - Линия под любым из двух самых крайних датчиков.
            • BUM_AUTO_ON_2 - Линия под любым из трёх самых крайних датчиков.
            • BUM_AUTO_ON_3 - Линия под любым из четырёх датчиков со стороны поворотника.
          • uint8_t ВЫКЛ - условие отключения поворотников, может принимать следующие значения:
            • BUM_AUTO_OFF_CEN - Под центральным датчиком есть линия.
            • BUM_AUTO_OFF_ANY - Линия есть под любым датчиком кроме указанных в условии включения.
          • bool ФЛАГ - значение true или false указывающее добавить 2 мигания перед отключением. Данный параметр является необязательным, если он не указан, значит ФЛАГ = false.
        • Возвращаемое значение: bool - результат применения новых настроек (true или false).
        • Примечание: Функцию можно вызывать как до включения поворотников, так и во время их работы в автоматическом режиме.
        • Пример:
        bum.settingsTurnAuto(BUM_AUTO_ON_2, BUM_AUTO_OFF_ANY, true); // Условие работы поворотников в автоматическом режиме.
        
        • Разбор примера:
          • В условии включения указан параметр BUM_AUTO_ON_2, значит поворотник будет включаться когда линия находится под любым из трёх самых крайних датчиков со стороны поворотника.
            • Для левого поворотника это датчики № 1, 2 и 3.
            • Для правого поворотника это датчики № 7, 8 и 9.
          • В условии отключения указан параметр BUM_AUTO_OFF_ANY, значит поворотник будет отключаться если линия находится под любым датчиком (или датчиками) бампера, при условии что не соблюдается условие для включения этого поворотника.
          • В качестве третьего (необязательного) параметра указано значение true, значит при наступлении условия отключения поворотника он выключится не сразу, а спустя 2 мигания.

        Функция setCalibrationRun();

        • Назначение: Запуск автоматической калибровки модуля.
        • Синтаксис: setCalibrationRun();
        • Параметры: Нет.
        • Возвращаемое значение: bool - результат запуска калибровки (true или false).
        • Примечание:
          • Обращение к данной функции равносильно первому нажатию на кнопку «калибровка».
          • Во время выполнения функции все датчики должны находиться над линией трассы.
          • Запуск автоматической калибровки приводит к началу чтения показаний АЦП со всех датчиков линий, этот процесс занимает до 5 секунд.
          • По завершению чтения показаний датчиков, модуль перейдёт в стадию ожидания завершения калибровки. Инициировать завершение калибровки можно нажатием на кнопку «калибровка» или обращением к функции setCalibrationEnd().
        • Пример:
        bum.setCalibrationRun(); // Начать калибровку.
        

        Функция setCalibrationEnd();

        • Назначение: Завершение автоматической калибровки модуля.
        • Синтаксис: setCalibrationEnd( [ ФЛАГ ] );
        • Параметр: bool ФЛАГ - значение true указывает на то что датчики требуется откалибровать не по отдельности, а определить одно общее значение для всех датчиков.
        • Возвращаемое значение: bool - результат инициализации завершения калибровки (true или false).
        • Примечание:
          • Обращение к данной функции равносильно второму нажатию на кнопку «калибровка».
          • Во время выполнения функции все датчики должны находиться над фоном трассы.
          • Инициализация завершения автоматической калибровки приводит к началу чтения показаний АЦП со всех датчиков линий, этот процесс занимает до 5 секунд.
          • По завершению чтения показаний датчиков, модуль рассчитает граничные значения АЦП датчиков между фоном и линией трассы, определит тип линии трассы и сохранит результаты в энергонезависимую память.
          • Если функция вызвана без параметра (или с параметром false), то модуль рассчитает граничные значения АЦП для каждого датчика в отдельности (как при нажатии на кнопку «калибровка»).
          • Если функция вызвана с параметром true, то модуль рассчитает общее граничное значение АЦП, одинаковое для всех датчиков (может помочь при сильной боковой засветке трассы).
          • По сохранённым граничным значениям АЦП (между линией и фоном) модуль будет определять наличие линии под датчиками.
          • Более подробно про граничные значения АЦП рассказано в пояснении к ручной калибровке.
        • Пример:
        bum.setCalibrationEnd(); // Завершить калибровку.
        

        Функция setCalibrationManual();

        • Назначение: Выполнение ручной калибровки модуля.
        • Синтаксис: setCalibrationManual( АЦП [, АЦП, АЦП, АЦП, АЦП, АЦП, АЦП, АЦП, АЦП ] );
        • Параметры:
          • uint16_t АЦП - число (0...4095) соответствующее граничному значению АЦП датчика.
        • Возвращаемое значение: bool - результат записи калибровочных значений (true или false).
        • Примечание:
          • Функция принимает 9 граничных значений АЦП для каждого датчика модуля, или одно граничное значение АЦП для всех датчиков модуля.
          • Граничное значение АЦП является средним значением между АЦП датчика для линии и АЦП датчика для фона.
          • АЦП любого датчика, для линии и фона, можно получить функцией getLineAnalog().
          • Указанные значения сохраняются в энергонезависимую память модуля и используются им в последствии для определения наличия линий под датчиками.
          • При ручной калибровке, помимо указания значений АЦП, может понадобится указание типа используемой линии при помощи функции setLineType().
        • Пример:
        bum.setCalibrationManual( 700 );                                          // Применить граничное значение 700 для всех датчиков модуля.
        bum.setCalibrationManual( 710, 770, 750, 899, 900, 700, 800, 650, 1000 ); // Применить граничное значение 710 для 1 датчика, 770 для второго и т.д.
        • Пояснение ручной калибровки:
          • Предположим что нами используется трасса с тёмной линией на светлом фоне, это можно указать модулю обратившись к функции setLineType( BUM_LINE_BLACK );
          • Предположим что при помощи функции getLineAnalog( 1 ); мы выяснили, что АЦП первого датчика для линии равно 500, а для фона 2500. Значит граничное значение АЦП для первого датчика равно 1500 (среднее значение). Аналогичным образом рассчитываются граничные значения АЦП для остальных датчиков.
          • После выполнения ручной калибровки, модуль будет знать что граничное значение АЦП первого датчика равно 1500. Так как мы указали модулю, что линия трассы темнее её фона, то все значения датчика ниже граничного, модуль будет воспринимать как линия, а выше граничного - как фон. Чем светлее поверхность под датчиком, тем выше значение АЦП.
          • Стоит учесть что зона в ±30 значений АЦП возле границы является гистерезисом.

        Функция getCalibrationStage();

        • Назначение: Получение текущего статуса автоматической калибровки.
        • Синтаксис: getCalibrationStage();
        • Параметры: Нет.
        • Возвращаемое значение: uint8_t СТАТУС - одно из возможных значений:
          • BUM_STAGE_READ_LN - выполняется чтение АЦП с датчиков над линией трассы.
          • BUM_STAGE_WAITING - модуль ожидает поступления команды на чтение фона.
          • BUM_STAGE_READ_BG - выполняется чтение АЦП с датчиков над фоном трассы.
          • BUM_STAGE_OFF_ERR - калибровка завершена провалом.
          • BUM_STAGE_OFF_OK - калибровка завершена успехом.
        • Примечание:
          • Функцию можно использовать для контроля выполнения и результата автоматической калибровки, запускаемой как функциями, так и нажатием кнопки «калибровка».
          • В примере Arduino IDE: Файл / Примеры / iarduino I2C Bumper (бампер) / controlCalibrationButton показан пример контроля за ходом выполнения калибровки с кнопки.
        • Пример:
        if(bum.getCalibrationStage()==BUM_STAGE_OFF_OK){Serial.println("Калибровка выполнена успешно");}
        

        Функция getLineDigital();

        • Назначение: Чтение линий под датчиками модуля.
        • Синтаксис: getLineDigital( НОМЕР );
        • Параметр: uint8_t НОМЕР датчика, может принимать значение от 1 до 9.
        • Возвращаемое значение: uint16_t - флаг наличия линии под датчиком (true или false).
        • Примечание:
          • Если в качестве параметра НОМЕР указать не число, а значение BUM_LINE_ALL, то функция вернёт не флаг, а число состоящее из 9 бит, где каждый бит (кроме нулевого) является флагом наличия линии под датчиком, номер которого совпадает с номером бита.
        • Пример:
        bool i = bum.getLineDigital( 5 );                     // Если под 5 датчиком есть линия, то i = true.
        bool i = bum.getLineDigital( BUM_LINE_ALL ) & bit(5); // Если под 5 датчиком есть линия, то i = true.
        

        Функция getLineAnalog();

        • Назначение: Чтение значений АЦП снятых с датчиков модуля.
        • Синтаксис: getLineAnalog( НОМЕР );
        • Параметр: uint8_t НОМЕР датчика, может принимать значение от 1 до 9.
        • Возвращаемое значение: uint16_t - число от 0 до 4096 соответствующее значению АЦП датчика.
        • Примечание:
          • Обращение к функции позволяет получить значение АЦП того датчика номер которого был указан в качестве параметра.
          • Чем светлее поверхность под датчиком, тем выше значение АЦП.
        • Пример:
        uint16_t i = bum.getLineAnalog( 5 ); // Получить значение АЦП с 5 датчика в переменную i.
        

        Функция getErrPID();

        • Назначение: Чтение ошибки центрирования линии для ПИД регулятора.
        • Синтаксис: getErrPID();
        • Параметры: Нет.
        • Возвращаемое значение: float - значение ошибки центрирования от 0 до ±4,5.
        • Примечание:
          • Обращение к функции позволяет получить ошибку центрирования линии.
          • Функция возвращает отрицательные значения если центр линии находится левее центра бампера.
          • Функция возвращает положительные значения если центр линии находится правее центра бампера.
            • 0 - нет ошибки, линия находится под центральным датчиком бампера.
            • ±0,5 - линия находится между центральным и соседним с ним датчиком.
            • ±1.0 - линия находится под датчиком соседним с центральным.
            • ±3.5 - линия находится между самым крайним и соседним с ним датчиком.
            • ±4.0 - линия находится под самым крайним датчиком.
            • ±4.5 - линия потеряна, знак указывает на сторону потери линии.
          • Функция позволяет работать с линиями ширина которых находится в диапазоне от 1 до 7 дистанций между датчиками линий.
          • Функция позволяет двигаться по линии и проезжать перекрёстки в прямом направлении. Для осуществления поворотов на перекрёстках воспользуйтесь функцией getSidePID().
        • Пример:
        float i = bum.getErrPID(); // Получить ошибку центрирования линии в переменную i.
        

        Функция getSidePID();

        • Назначение: Чтение ошибки центрирования края линии для ПИД регулятора.
        • Синтаксис: getSidePID( [КРАЙ] );
        • Параметры: int8_t КРАЙ - число отличное от 0 со знаком края линии (-левый, +правый).
        • Возвращаемое значение: float - значение ошибки центрирования края от 0 до ±4,5.
        • Примечание:
          • Обращение к функции позволяет получить ошибку центрирования края линии.
          • Функция возвращает отрицательные значения если край линии находится левее центра бампера.
          • Функция возвращает положительные значения если край линии находится правее центра бампера.
            • 0 - нет ошибки, край линии находится под центральным датчиком бампера.
            • ±0,5 - край линии находится между центральным и соседним с ним датчиком.
            • ±1.0 - край линии находится под датчиком соседним с центральным.
            • ±3.5 - край линии находится между самым крайним и соседним с ним датчиком.
            • ±4.0 - край линии находится под самым крайним датчиком.
            • ±4.5 - край линии потерян, знак указывает на сторону потери линии.
          • Функция позволяет работать с линиями ширина которых находится в диапазоне от 1 до 7 дистанций между датчиками линий.
          • Функция позволяет двигаться по краю линии и осуществлять повороты на перекрёстках, для проезда перекрёстков в прямом направлении воспользуйтесь функцией getErrPID().
        • Пример:
        float i = bum.getSidePID(-1); // Получить ошибку центрирования левого  края линии в переменную i.
        float i = bum.getSidePID( 1); // Получить ошибку центрирования правого края линии в переменную i.
        

        Функция getCross();

        • Назначение: Обнаружение перекрёстков и крутых поворотов.
        • Синтаксис: getCross( ШИРИНА, [ВРЕМЯ] );
        • Параметры:
          • Параметры: uint8_t ШИРИНА - количество датчиков, расположенных над линией вне перекрёстка.
          • Параметры: uint32_t ВРЕМЯ - количество мс требуемое для преодоления перекрёстка.
        • Возвращаемое значение: bool - флаг наличия перекрёстка под бампером.
        • Примечание:
          • Обращение к функции позволяет определить наличие перекрёстка.
          • Если функция вызвана с параметром ВРЕМЯ, то она будет возвращать true в течении этого времени, уже после преодоления перекрёстка.
          • Функцию getCross() удобно использовать для перехода с getSidePID() на getErrPID().
        • Пример:
        bool i = bum.getCross(3); // Получить флаг наличия перекрёстка. Толщина линии равна 3 датчикам бампера.
        

        Функция getLineSum();

        • Назначение: Запрос количества датчиков находящихся над линией.
        • Синтаксис: getLineSum( [ПЕРЕМЕННАЯ] );
        • Параметр: uint16_t ПЕРЕМЕННАЯ для получения флагов наличия линий.
        • Возвращаемое значение: uint8_t - число от 0 до 9 соответствующее количеству датчиков находящихся над линией.
        • Примечание:
          • Данная функция позволяет получить не только количество датчиков находящихся над линией (в качестве возвращаемого значения), но и флаги наличия линий (если в качестве необязательного параметра указана переменная для получения этих флагов).
          • Флаги возвращаемые параметру соответствуют значению возвращаемому функцией getLineDigital( BUM_LINE_ALL ).
        • Пример:
        uint8_t i = bum.getLineSum( ); // Получить количество датчиков которые находятся над линией.
        uint8_t i = bum.getLineSum(j); // «i» получает количество датчиков над линией, а «j» получает флаги наличия линий под датчиками, как если написать j=getLineDigital(BUM_LINE_ALL);.
        

        Функция getLineType();

        • Назначение: Запрос типа линии трассы для которой откалиброван модуль.
        • Синтаксис: getLineType();
        • Параметры: Нет.
        • Возвращаемое значение: uint8_t - ТИП лини, может принимать следующие значения:
          • BUM_LINE_BLACK - модуль откалиброван для трассы с тёмной линией на светлом фоне.
          • BUM_LINE_WHITE - модуль откалиброван для трассы со светлой линией на тёмном фоне.
        • Пример:
        if( bum.getLineType() == BUM_LINE_BLACK ){ Serial.println("Трасса с  тёмной  линией"); }
        else                                     { Serial.println("Трасса со светлой линией"); }
        

        Функция setLineType();

        • Назначение: Установка типа линии трассы.
        • Синтаксис: setLineType( ТИП );
        • Параметры: uint8_t ТИП лини, может принимать следующие значения:
          • BUM_LINE_BLACK - указать модулю что трасса использует тёмную линию.
          • BUM_LINE_WHITE - указать модулю что трасса использует светлую линию.
          • BUM_LINE_CHANGE - изменить тип линии трассы на противоположный.
        • Возвращаемое значение: bool - результат записи нового типа линии в модуль (true или false).
        • Примечание:
          • Тип используемой линии сохраняется в энергонезависимую память модуля, а значит модуль будет работать с данным типом трассы и после отключения питания.
          • Функцию удобно использовать с параметром BUM_LINE_CHANGE, если на трассе есть участки, где цвет линии и фона резко меняют друг друга.
        • Пример:
        bum.setLineType(BUM_LINE_BLACK); // Указываем модулю что на трассе используется тёмная линия на светлом фоне.

          Ссылки:




          Обсуждение

          Гарантии и возврат Используя сайт Вы соглашаетесь с условями