Электронное приложение к набору «IO.KIT Сонар»
На этой странице ты найдёшь все нужные материалы для сборки мини-проектов набора Сонар из серии IO.KIT:
- Схемы проектов в электронном виде.
- Исходный код программ (копируй его в редактор Arduino IDE).
- Дополнительные материалы: программные библиотеки, даташиты и т. п.
Обрати внимание
Для сборки и функционирования сонара тебе понадобится IO.KIT Базовый!
Проекты
Прежде чем приступать к экспериментам, нужно подготовить свой компьютер:
- Установи среду программирования Arduino IDE и копируй туда готовый код проектов.
- Установи дополнительные библиотеки для Arduino IDE, пользуясь нашим руководством.
Драйвер чипа CH340
Установи драйвер CH340 для Windows или Linux, чтобы твой компьютер мог корректно распознать и прошить плату Iskra Nano.
№1. Счётчик чисел
- CounterDigit.ino
- // Подключаем библиотеку для работы со светодиодной матрицей
- #include <TroykaLedMatrix.h>
- // Создаём объект матрицы
- TroykaLedMatrix matrix;
- void setup() {
- // Инициализируем матрицу
- matrix.begin();
- // Очищаем матрицу
- matrix.clear();
- // Устанавливаем шрифт
- matrix.selectFont(FONT_8X8_BASIC);
- }
- void loop() {
- // Перечисляем символы от 0 до 9
- for (char i = '0'; i <= '9'; i++) {
- // Выводим текущий символ на матрицу
- matrix.drawSymbol(i);
- // Ждём 500 мс
- delay(500);
- }
- }
№2. Бегущая строка
- Ticker.ino
- // Подключаем библиотеку для работы со светодиодной матрицей
- #include <TroykaLedMatrix.h>
- // Создаём объект матрицы
- TroykaLedMatrix matrix;
- // Создаём массив с текстом для бегущей строки
- char str[] = " Amperka";
- // Вычисляем длину массива
- constexpr int LEN_STR = sizeof(str);
- // Создаём переменную для хранения смещение бегущей строги
- uint8_t shift = 0;
- void setup() {
- // Инициализируем матрицу
- matrix.begin();
- // Очищаем матрицу
- matrix.clear();
- // Устанавливаем шрифт
- matrix.selectFont(FONT_8X8_BASIC);
- }
- void loop() {
- // Печатаем текст бегущей строкой
- matrix.marqueeText(str, LEN_STR, shift++);
- // Если смещение строки достигло конца
- if (shift == LEN_STR * 8) {
- // Обнуляем смещение строки
- shift = 0;
- }
- // Ждём 75 мс
- delay(75);
- }
№3. Дыхание Амперки
- Bitmap.ino
- // Подключаем библиотеку для работы со светодиодной матрицей
- #include <TroykaLedMatrix.h>
- // Создаём объект матрицы
- TroykaLedMatrix matrix;
- // Даём понятное имя пину A2 с потенциометром
- constexpr int POT_PIN = A2;
- // Создаём иконку лого Амперки в двоичной системе BIN
- const uint8_t amperka[] {
- 0b00011000,
- 0b00100100,
- 0b10011001,
- 0b01000010,
- 0b10011001,
- 0b10011001,
- 0b01000010,
- 0b00111100
- };
- // Создаём иконку сердца в двоичной системе BIN
- const uint8_t heart[] {
- 0b00000000,
- 0b01100110,
- 0b11111111,
- 0b11111111,
- 0b11111111,
- 0b01111110,
- 0b00111100,
- 0b00011000
- };
- // Создаём иконку смайлика в двоичной системе BIN
- const uint8_t smile[] {
- 0b00111100,
- 0b01000010,
- 0b10100101,
- 0b10000001,
- 0b10100101,
- 0b10011001,
- 0b01000010,
- 0b00111100
- };
- void setup() {
- // Настраиваем пин с потенциометром в режим входа
- pinMode(POT_PIN, INPUT);
- // Инициализируем матрицу
- matrix.begin();
- // Очищаем матрицу
- matrix.clear();
- // Устанавливаем ориентацию матрицы на 0 градусов (по умолчанию)
- matrix.setRotation(ROTATION_0);
- // Отображаем на матрице лого Амперки
- matrix.drawBitmap(amperka);
- }
- void loop() {
- // Считываем значение с потенциометра
- int brightness = readPot(POT_PIN);
- // Отражаем показания с потенциометра на яркости матрице
- updateBrightnessMatrix(brightness);
- }
- // Функция считывания показаний с потенциометра
- int readPot(int pin) {
- // Создаём переменную для хранения
- // аналогового сигнала с потенциометра в отчётах АЦП
- int sensorADC = 0;
- // Создаём переменную для хранения
- // преобразованных показаний с потенциометра
- int sensorValue = 0;
- // Считываем аналоговый сигнал с потенциометра
- sensorADC = analogRead(pin);
- // Преобразуем диапазон значений с потенциометра [0;1023]
- // в диапазон значений для выбора яркости матрицы [0;9]
- sensorValue = map(sensorADC, 0, 1023, 0, 9);
- // Возвращаем полученное значение
- return sensorValue;
- }
- // Функция обновления яркости матрицы
- void updateBrightnessMatrix(int value) {
- switch (value) {
- case 0: matrix.setCurrentLimit(ROW_CURRENT_05MA); break;
- case 1: matrix.setCurrentLimit(ROW_CURRENT_10MA); break;
- case 2: matrix.setCurrentLimit(ROW_CURRENT_15MA); break;
- case 3: matrix.setCurrentLimit(ROW_CURRENT_20MA); break;
- case 4: matrix.setCurrentLimit(ROW_CURRENT_25MA); break;
- case 5: matrix.setCurrentLimit(ROW_CURRENT_30MA); break;
- case 6: matrix.setCurrentLimit(ROW_CURRENT_35MA); break;
- case 7: matrix.setCurrentLimit(ROW_CURRENT_40MA); break;
- case 8: matrix.setCurrentLimit(ROW_CURRENT_45MA); break;
- case 9: matrix.setCurrentLimit(ROW_CURRENT_50MA); break;
- }
- }
№4. Управление углом
- ServoSwitch.ino
- // Подключаем библиотеку для работы с сервоприводом
- #include <Servo.h>
- // Создаём объект сервопривода
- Servo servo;
- // Даём понятное имя пину 5 с сервоприводом
- constexpr uint8_t SERVO_PIN = 5;
- // Задаём минимальный и максимальный угол поворота сервопривода
- constexpr uint8_t MIN_ANGLE = 0;
- constexpr uint8_t MAX_ANGLE = 180;
- // Вычисляем средний угол сервопривода
- constexpr uint8_t MID_ANGLE = (MIN_ANGLE + MAX_ANGLE) / 2;
- void setup() {
- // Подключаем сервомотор
- servo.attach(SERVO_PIN);
- }
- void loop() {
- // Устанавливаем вал сервопривода в минимальный угол
- servo.write(MIN_ANGLE);
- // Ждём 1 секунду
- delay(1000);
- // Устанавливаем вал сервопривода в среднее положение
- servo.write(MID_ANGLE);
- // Ждём 1 секунду
- delay(1000);
- // Устанавливаем вал сервопривода в максимальный угол
- servo.write(MAX_ANGLE);
- // Ждём 1 секунду
- delay(1000);
- // Устанавливаем вал сервопривода в среднее положение
- servo.write(MID_ANGLE);
- // Ждём 1 секунду
- delay(1000);
- }
№5. Штурвал
- ControlWheel.ino
- // Подключаем библиотеку для работы с сервоприводом
- #include <Servo.h>
- // Создаём объект сервопривода
- Servo servo;
- // Даём понятное имя пину 5 с сервоприводом
- constexpr uint8_t SERVO_PIN = 5;
- // Даём понятное имя пину A2 с потенциометром
- constexpr uint8_t POT_PIN = A2;
- void setup() {
- // Настраиваем пин с потенциометром в режим входа
- pinMode(POT_PIN, INPUT);
- // Подключаем сервомотор
- servo.attach(SERVO_PIN);
- }
- void loop() {
- // Считываем аналоговый сигнал с потенциометра
- int rotation = analogRead(POT_PIN);
- // Преобразуем диапазон значений с потенциометра [0;1023]
- // в диапазон значений для угла вала сервопривода [0;180]
- int position = map(rotation, 0, 1023, 0, 180);
- // Выдаём результат на сервопривод
- servo.write(position);
- }
№6. Замок
- SwitchLock.ino
- // Подключаем библиотеку для работы с сервоприводом
- #include <Servo.h>
- // Подключаем библиотеку для работы с кнопкой
- #include <TroykaButton.h>
- // Подключаем библиотеку для работы со светодиодной матрицей
- #include <TroykaLedMatrix.h>
- // Создаём объект сервопривода
- Servo servo;
- // Создаём объект кнопки на пине A2
- TroykaButton button(A2);
- // Создаём объект матрицы
- TroykaLedMatrix matrix;
- // Даём понятное имя пину 5 с сервоприводом
- constexpr uint8_t SERVO_PIN = 5;
- // Задаём минимальный и максимальный угол поворота сервопривода
- constexpr uint8_t MIN_ANGLE = 0;
- constexpr uint8_t MAX_ANGLE = 180;
- // Создаём переменную для хранения состояние замка
- bool lockState;
- // Создаём иконку закрытого замка в двоичной системе BIN
- const uint8_t lockClosed[] {
- 0b00110000,
- 0b01001000,
- 0b01001000,
- 0b11111100,
- 0b10000100,
- 0b10000100,
- 0b10000100,
- 0b11111100
- };
- // Создаём иконку открытого замка в двоичной системе BIN
- const uint8_t lockOpen[] {
- 0b00000110,
- 0b00001001,
- 0b00001001,
- 0b11111100,
- 0b10000100,
- 0b10000100,
- 0b10000100,
- 0b11111100
- };
- void setup() {
- // Подключаем сервомотор
- servo.attach(SERVO_PIN);
- // Инициализируем матрицу
- matrix.begin();
- // Очищаем матрицу
- matrix.clear();
- // Устанавливаем состояние открытого замка
- lockState = true;
- // Отображаем на матрице иконку открытого замка
- matrix.drawBitmap(lockOpen);
- // Устанавливаем вал сервопривода в минимальный угол
- servo.write(MIN_ANGLE);
- }
- void loop() {
- // Считываем состояние с кнопки
- button.read();
- // Определяем нажатие кнопки
- if (button.justPressed()) {
- // Если замок открыт
- if (lockState) {
- // Устанавливаем вал сервопривода в максимальный угол
- servo.write(MAX_ANGLE);
- // Отображаем на матрице иконку закрытого замка
- matrix.drawBitmap(lockClosed);
- } else {
- // Устанавливаем вал сервопривода в минимальный угол
- servo.write(MIN_ANGLE);
- // Отображаем на матрице иконку открытого замка
- matrix.drawBitmap(lockOpen);
- }
- // Инвертируем переменную состояние замка
- lockState = !lockState;
- }
- }
№7. Консольный дальномер
- LidarConsole.ino
- // Подключаем библиотеку для работы с дальномером
- #include <EasyUltrasonic.h>
- // Создаём объект дальномера
- EasyUltrasonic distSensor;
- // Даём понятные имена пинам дальномера TRIG и ECHO
- constexpr uint8_t TRIG_PIN = 11;
- constexpr uint8_t ECHO_PIN = 10;
- void setup() {
- // Открываем монитор Serial-порта
- Serial.begin(9600);
- // Инициализируем дальномер
- distSensor.attach(TRIG_PIN, ECHO_PIN);
- }
- void loop() {
- // Считываем расстояние до объекта в см
- float distance = distSensor.getDistanceCM();
- // Выводим результат в консоль
- Serial.print(distance);
- Serial.println(" cm");
- // Ждём 100 мс
- delay(100);
- }
№8. Графический дальномер
- LidarDrawing.ino
// Подключаем библиотеку для работы с дальномером #include <EasyUltrasonic.h> // Подключаем библиотеку для работы со светодиодной матрицей #include <TroykaLedMatrix.h> // Создаём объект дальномера EasyUltrasonic distSensor; // Создаём объект матрицы TroykaLedMatrix matrix; // Даём понятное имя пину A2 с пищалкой constexpr uint8_t BUZZER_PIN = A2; // Даём понятные имена пинам дальномера TRIG и ECHO constexpr uint8_t TRIG_PIN = 11; constexpr uint8_t ECHO_PIN = 10; // Задаём минимальное и максимальное детектируемое расстояние дальномера в см constexpr uint8_t MIN_DIST = 5; constexpr uint8_t MAX_DIST = 30; // Создаём константу для хранения паузы между кадрами анимации constexpr int DELAY_FRAME = 500; // Создаём константу для хранения тригера сигнализации в см constexpr int ALARM_DIST = 30; // Создаём массив для хранения расстояния до объекта в матричном представлении byte distMatrix[8]; void setup() { // Настраиваем пин с пищалкой в режим выхода pinMode(BUZZER_PIN, OUTPUT); // Инициализируем дальномер distSensor.attach(TRIG_PIN, ECHO_PIN, MIN_DIST, MAX_DIST); // Инициализируем матрицу matrix.begin(); // Очищаем матрицу matrix.clear(); // Устанавливаем ориентацию матрицы на 90 градусов matrix.setRotation(ROTATION_90); } void loop() { // Считываем расстояние до объекта в см int dist = distSensor.getDistanceCM(); // Преобразуем диапазон значений с дальномера [MIN_DIST;MAX_DIST] // в графический диапазон значений для столбца матрицы от 0 до 8 точек distMatrix[0] = matrix.map(dist, MIN_DIST, MAX_DIST); // Отображаем все столбцы на матрице matrix.drawBitmap(distMatrix); // Обновляем звуковую сигнализацию updateAlarm(dist); // Сдвигаем кадр на один столбец shiftMatrixImage(); // Ждём 500 мс delay(DELAY_FRAME); } // Функция сдвига кадра по столбцам void shiftMatrixImage() { for (int i = 7; i > 0; i--) { distMatrix[i] = distMatrix[i - 1]; } } // Функция обновления звуковой сигнализации void updateAlarm(int dist) { // Если текущее расстояние до препятствия меньше тригера if (dist < ALARM_DIST) { // Включаем звуковую сигнализацию tone(BUZZER_PIN, 1000, 100); } else { // Выключаем звуковую сигнализацию noTone(BUZZER_PIN); } }
№9 Сонар
- Sonar.ino
- // Подключаем библиотеку для работы с дальномером
- #include <EasyUltrasonic.h>
- // Подключаем библиотеку для работы с сервоприводом
- #include <Servo.h>
- // Подключаем библиотеку для работы со светодиодной матрицей
- #include <TroykaLedMatrix.h>
- // Создаём объект дальномера
- EasyUltrasonic distSensor;
- // Создаём объект сервопривода
- Servo servo;
- // Создаём объект матрицы
- TroykaLedMatrix matrix;
- // Даём понятное имя пину A2 с пищалкой
- constexpr uint8_t BUZZER_PIN = A2;
- // Даём понятные имена пинам дальномера TRIG и ECHO
- constexpr uint8_t TRIG_PIN = 11;
- constexpr uint8_t ECHO_PIN = 10;
- // Даём понятное имя пину 5 с сервоприводом
- constexpr uint8_t SERVO_PIN = 5;
- // Задаём минимальный и максимальный угол поворота сервопривода
- constexpr uint8_t MIN_ANGLE = 0;
- constexpr uint8_t MAX_ANGLE = 180;
- // Вычисляем количество градусов в каждом секторе,
- // делим диапазон угла сервопривода на 8 равных секторов
- constexpr uint8_t STEP_ANGLE = (MAX_ANGLE - MIN_ANGLE) / 7;
- // Задаём минимальное и максимальное детектируемое расстояние дальномера в см
- constexpr uint8_t MIN_DIST = 5;
- constexpr uint8_t MAX_DIST = 30;
- // Создаём константу для хранения тригера сигнализации в см
- constexpr int ALARM_DIST = 30;
- // Создаём константу для хранения паузы между поворотом вала сервопривода
- constexpr int DELAY_SWEEP = 50;
- // Создаём массив для хранения расстояния до объекта в матричном представлении
- byte distMatrix[8];
- void setup() {
- // Настраиваем пин с пищалкой в режим выхода
- pinMode(BUZZER_PIN, OUTPUT);
- // Инициализируем дальномер
- distSensor.attach(TRIG_PIN, ECHO_PIN, MIN_DIST, MAX_DIST);
- // Подключаем сервомотор
- servo.attach(SERVO_PIN);
- // Инициализируем матрицу
- matrix.begin();
- // Очищаем матрицу
- matrix.clear();
- // Устанавливаем ориентацию матрицы на 90 градусов
- matrix.setRotation(ROTATION_90);
- }
- void loop() {
- // Перебираем значения угла сервопривода от min до max
- for (int angle = MIN_ANGLE; angle <= MAX_ANGLE; angle++) {
- // Вызываем функцию обновления состояние сонара
- updateSonar(angle);
- }
- // Перебираем значения угла сервопривода от max до min
- for (int angle = MAX_ANGLE; angle >= MIN_ANGLE; angle--) {
- // Вызываем функцию обновления состояние сонара
- updateSonar(angle);
- }
- }
- // Функция обновления состояния сонара
- void updateSonar(int angle) {
- // Отправляем текущий угол на сервопривод
- servo.write(angle);
- // Выжидаем паузу
- delay(DELAY_SWEEP);
- // Если вал мотора достиг нового сектора
- if (angle % STEP_ANGLE == 0) {
- // Вычисляем номер сектора от 0 до 7
- int colMatrix = angle / STEP_ANGLE;
- // Считываем расстояние до объекта в см
- int dist = distSensor.getDistanceCM();
- // Преобразуем диапазон значений с дальномера [MIN_DIST;MAX_DIST]
- // в графический диапазон значений для столбца матрицы от 0 до 8 точек
- distMatrix[colMatrix] = matrix.map(dist, MIN_DIST, MAX_DIST);
- // Отображаем все столбцы на матрице
- matrix.drawBitmap(distMatrix);
- // Обновляем звуковую сигнализацию
- updateAlarm(dist);
- }
- }
- // Функция обновления звуковой сигнализации
- void updateAlarm(int dist) {
- // Если текущее расстояние до препятствия меньше тригера
- if (dist < ALARM_DIST) {
- // Включаем звуковую сигнализацию
- tone(BUZZER_PIN, 1000, 100);
- } else {
- // Выключаем звуковую сигнализацию
- noTone(BUZZER_PIN);
- }
- }
Ресурсы
- Наборы IO.KIT в магазине