Arduino IDE

Начнём знакомство с написания простой программы, которая выведет в последовательный порт сырые данные с датчика QTR.

Используем библиотеку qtr-sensors-arduino от Pololu, которую можно найти в репозитории Arduino IDE или скачать с github.

Сначала подключаем библиотеку для работы с QTR:

#include <QTRSensors.h>

Затем создаём объект класса QTRSensors:

QTRSensors qtr;

Далее все операции с модулем будут доступны через объект с именем qtr.

Внутри функции setup настроим датчик. setTypeRC — определяет тип датчика: RC или аналоговый. С помощью setSensorPins указываем контакты, к которым подключены отдельные датчики отражения. setEmitterPin — задаёт контакт общего включения всех датчиков отражения.

Чтение показаний датчиков осуществляется при помощи функции read.

#include <QTRSensors.h>

QTRSensors qtr;

const uint8_t SensorCount = 4; // количество датчиков отражения
uint16_t sensorValues[SensorCount]; // массива для хранения данных

void setup() {
    // настройка датчика
    qtr.setTypeRC(); // тип - RC
    qtr.setSensorPins((const uint8_t[]){2, 3, 4, 5}, SensorCount); // контакты
    qtr.setEmitterPin(6); // контакт общего включения ENO/ENE

    Serial.begin(9600);
}


void loop() {
    qtr.read(sensorValues); // чтение сырых данных

    for (uint8_t i = 0; i < SensorCount; i++) {
        Serial.print(sensorValues[i]);
        Serial.print('\t');
    }
    Serial.println();

    delay(250);
}

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

Калибровка

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

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

Весь этот алгоритм уже реализован в функции calibrate библиотеки qtr. Напишем программу, которая в начале своей работы проведет калибровку с использованием этой функции.

Процедура длится 5 секунд. Во время калибровки нужно будет навести датчики на черную поверхность, затем на белую. Повторить это несколько раз. При этом, расстояние до поверхности не должно меняться!

#include <QTRSensors.h>

QTRSensors qtr;

const uint8_t SensorCount = 4;
uint16_t sensorValues[SensorCount];

void setup() {
    qtr.setTypeRC();
    qtr.setSensorPins((const uint8_t[]){2,3,4,5}, SensorCount);
    qtr.setEmitterPin(6);

    delay(500);
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH); // включение 13-го светодиода

    // 400 вызовов функции calibrate
    // каждый вызов calibrate занимает около 25 мс (2.5мс*10)
    for (uint16_t i = 0; i < 200; i++) {
        qtr.calibrate();
    }
    digitalWrite(LED_BUILTIN, LOW); // выключение светодиода

    Serial.begin(9600);
    // вывод минимальных значений, полученных во время калибровки
    for (uint8_t i = 0; i < SensorCount; i++) {
        Serial.print(qtr.calibrationOn.minimum[i]);
        Serial.print(' ');
    }
    Serial.println();

    // вывод максимальных значений, полученных во время калибровки
    for (uint8_t i = 0; i < SensorCount; i++) {
      Serial.print(qtr.calibrationOn.maximum[i]);
      Serial.print(' ');
    }
    Serial.println();
    Serial.println();
    delay(1000);
}

void loop() {
    // вывод текущих значений
    for (uint8_t i = 0; i < SensorCount; i++)  {
      Serial.print(sensorValues[i]);
      Serial.print('\t');
    }

    delay(250);
}

Изменено: