Содержание

Электронное приложение к набору «IO.KIT Сонар»

На этой странице ты найдёшь все нужные материалы для сборки мини-проектов набора «Сонар» из серии IO.KIT:

Обрати внимание

Для сборки сонара IO.KIT тебе понадобится «IO.KIT Базовый»!

Эксперименты

№1. Счётчик чисел

CounterDigit.ino
  1. // Подключаем библиотеку для работы со светодиодной матрицей
  2. #include <TroykaLedMatrix.h>
  3.  
  4. // Создаём объект матрицы
  5. TroykaLedMatrix matrix;
  6.  
  7. void setup() {
  8. // Инициализируем матрицу
  9. matrix.begin();
  10. // Очищаем матрицу
  11. matrix.clear();
  12. // Устанавливаем шрифт
  13. matrix.selectFont(FONT_8X8_BASIC);
  14. }
  15.  
  16. void loop() {
  17. // Перечисляем символы от 0 до 9
  18. for (char i = '0'; i <= '9'; i++) {
  19. // Выводим текущий символ на матрицу
  20. matrix.drawSymbol(i);
  21. // Ждём 500 мс
  22. delay(500);
  23. }
  24. }

№2. Бегущая строка

Ticker.ino
  1. // Подключаем библиотеку для работы со светодиодной матрицей
  2. #include <TroykaLedMatrix.h>
  3.  
  4. // Создаём объект матрицы
  5. TroykaLedMatrix matrix;
  6.  
  7. // Создаём массив с текстом для бегущей строки
  8. char str[] = " Amperka";
  9. // Вычисляем длину массива
  10. constexpr int LEN_STR = sizeof(str);
  11. // Создаём переменную для хранения смещение бегущей строги
  12. uint8_t shift = 0;
  13.  
  14. void setup() {
  15. // Инициализируем матрицу
  16. matrix.begin();
  17. // Очищаем матрицу
  18. matrix.clear();
  19. // Устанавливаем шрифт
  20. matrix.selectFont(FONT_8X8_BASIC);
  21. }
  22.  
  23. void loop() {
  24. // Печатаем текст бегущей строкой
  25. matrix.marqueeText(str, LEN_STR, shift++);
  26. // Если смещение строки достигло конца
  27. if (shift == LEN_STR * 8) {
  28. // Обнуляем смещение строки
  29. shift = 0;
  30. }
  31. // Ждём 75 мс
  32. delay(75);
  33. }

№3. Дыхание Амперки

Bitmap.ino
  1. 0b00111100,
  2. 0b00011000
  3. };
  4.  
  5. // Создаём иконку смайлика в двоичной системе BIN
  6. const uint8_t smile[] {
  7. 0b00111100,
  8. 0b01000010,
  9. 0b10100101,
  10. 0b10000001,
  11. 0b10100101,
  12. 0b10011001,
  13. 0b01000010,
  14. 0b00111100
  15. };
  16.  
  17. void setup() {
  18. // Настраиваем пин с потенциометром в режим входа
  19. pinMode(POT_PIN, INPUT);
  20. // Инициализируем матрицу
  21. matrix.begin();
  22. // Очищаем матрицу
  23. matrix.clear();
  24. // Устанавливаем ориентацию матрицы на 0 градусов (по умолчанию)
  25. matrix.setRotation(ROTATION_0);
  26. // Отображаем на матрице лого Амперки
  27. matrix.drawBitmap(amperka);
  28. }
  29.  
  30. void loop() {
  31. // Считываем значение с потенциометра
  32. int brightness = readPot(POT_PIN);
  33. // Отражаем показания с потенциометра на яркости матрице
  34. updateBrightnessMatrix(brightness);
  35. }
  36.  
  37. // Функция считывания показаний с потенциометра
  38. int readPot(int pin) {
  39. // Создаём переменную для хранения
  40. // аналогового сигнала с потенциометра в отчётах АЦП
  41. int sensorADC = 0;
  42. // Создаём переменную для хранения
  43. // преобразованных показаний с потенциометра
  44. int sensorValue = 0;
  45. // Считываем аналоговый сигнал с потенциометра
  46. sensorADC = analogRead(pin);
  47. // Преобразуем диапазон значений с потенциометра [0;1023]
  48. // в диапазон значений для выбора яркости матрицы [0;9]
  49. sensorValue = map(sensorADC, 0, 1023, 0, 9);
  50. // Возвращаем полученное значение
  51. return sensorValue;
  52. }
  53.  
  54. // Функция обновления яркости матрицы
  55. void updateBrightnessMatrix(int value) {
  56. switch (value) {
  57. case 0: matrix.setCurrentLimit(ROW_CURRENT_05MA); break;
  58. case 1: matrix.setCurrentLimit(ROW_CURRENT_10MA); break;
  59. case 2: matrix.setCurrentLimit(ROW_CURRENT_15MA); break;
  60. case 3: matrix.setCurrentLimit(ROW_CURRENT_20MA); break;
  61. case 4: matrix.setCurrentLimit(ROW_CURRENT_25MA); break;
  62. case 5: matrix.setCurrentLimit(ROW_CURRENT_30MA); break;
  63. case 6: matrix.setCurrentLimit(ROW_CURRENT_35MA); break;
  64. case 7: matrix.setCurrentLimit(ROW_CURRENT_40MA); break;
  65. case 8: matrix.setCurrentLimit(ROW_CURRENT_45MA); break;
  66. case 9: matrix.setCurrentLimit(ROW_CURRENT_50MA); break;
  67. }
  68. }

№4. Управление углом

ServoSwitch.ino
  1. // Подключаем библиотеку для работы с сервоприводом
  2. #include <Servo.h>
  3.  
  4. // Создаём объект сервопривода
  5. Servo servo;
  6.  
  7. // Даём понятное имя пину 5 с сервоприводом
  8. constexpr uint8_t SERVO_PIN = 5;
  9.  
  10. // Задаём минимальный и максимальный угол поворота сервопривода
  11. constexpr uint8_t MIN_ANGLE = 0;
  12. constexpr uint8_t MAX_ANGLE = 180;
  13. // Вычисляем средний угол сервопривода
  14. constexpr uint8_t MID_ANGLE = (MIN_ANGLE + MAX_ANGLE) / 2;
  15.  
  16. void setup() {
  17. // Подключаем сервомотор
  18. servo.attach(SERVO_PIN);
  19. }
  20.  
  21. void loop() {
  22. // Устанавливаем вал сервопривода в минимальный угол
  23. servo.write(MIN_ANGLE);
  24. // Ждём 1 секунду
  25. delay(1000);
  26. // Устанавливаем вал сервопривода в среднее положение
  27. servo.write(MID_ANGLE);
  28. // Ждём 1 секунду
  29. delay(1000);
  30. // Устанавливаем вал сервопривода в максимальный угол
  31. servo.write(MAX_ANGLE);
  32. // Ждём 1 секунду
  33. delay(1000);
  34. // Устанавливаем вал сервопривода в среднее положение
  35. servo.write(MID_ANGLE);
  36. // Ждём 1 секунду
  37. delay(1000);
  38. }

№5. Штурвал

ControlWheel.ino
  1. // Подключаем библиотеку для работы с сервоприводом
  2. #include <Servo.h>
  3.  
  4. // Создаём объект сервопривода
  5. Servo servo;
  6.  
  7. // Даём понятное имя пину 5 с сервоприводом
  8. constexpr uint8_t SERVO_PIN = 5;
  9.  
  10. // Даём понятное имя пину A2 с потенциометром
  11. constexpr uint8_t POT_PIN = A2;
  12.  
  13. void setup() {
  14. // Настраиваем пин с потенциометром в режим входа
  15. pinMode(POT_PIN, INPUT);
  16. // Подключаем сервомотор
  17. servo.attach(SERVO_PIN);
  18. }
  19.  
  20. void loop() {
  21. // Считываем аналоговый сигнал с потенциометра
  22. int rotation = analogRead(POT_PIN);
  23. // Преобразуем диапазон значений с потенциометра [0;1023]
  24. // в диапазон значений для угла вала сервопривода [0;180]
  25. int position = map(rotation, 0, 1023, 0, 180);
  26. // Выдаём результат на сервопривод
  27. servo.write(position);
  28. }

№6. Замок

SwitchLock.ino
  1. // Подключаем библиотеку для работы с сервоприводом
  2. #include <Servo.h>
  3.  
  4. // Подключаем библиотеку для работы с кнопкой
  5. #include <TroykaButton.h>
  6.  
  7. // Подключаем библиотеку для работы со светодиодной матрицей
  8. #include <TroykaLedMatrix.h>
  9.  
  10. // Создаём объект сервопривода
  11. Servo servo;
  12.  
  13. // Создаём объект кнопки на пине A2
  14. TroykaButton button(A2);
  15.  
  16. // Создаём объект матрицы
  17. TroykaLedMatrix matrix;
  18.  
  19. // Даём понятное имя пину 5 с сервоприводом
  20. constexpr uint8_t SERVO_PIN = 5;
  21.  
  22. // Задаём минимальный и максимальный угол поворота сервопривода
  23. constexpr uint8_t MIN_ANGLE = 0;
  24. constexpr uint8_t MAX_ANGLE = 180;
  25.  
  26. // Создаём переменную для хранения состояние замка
  27. bool lockState;
  28.  
  29. // Создаём иконку закрытого замка в двоичной системе BIN
  30. const uint8_t lockClosed[] {
  31. 0b00110000,
  32. 0b01001000,
  33. 0b01001000,
  34. 0b11111100,
  35. 0b10000100,
  36. 0b10000100,
  37. 0b10000100,
  38. 0b11111100
  39. };
  40.  
  41. // Создаём иконку открытого замка в двоичной системе BIN
  42. const uint8_t lockOpen[] {
  43. 0b00000110,
  44. 0b00001001,
  45. 0b00001001,
  46. 0b11111100,
  47. 0b10000100,
  48. 0b10000100,
  49. 0b10000100,
  50. 0b11111100
  51. };
  52.  
  53. void setup() {
  54. // Подключаем сервомотор
  55. servo.attach(SERVO_PIN);
  56. // Инициализируем матрицу
  57. matrix.begin();
  58. // Очищаем матрицу
  59. matrix.clear();
  60. // Устанавливаем состояние открытого замка
  61. lockState = true;
  62. // Отображаем на матрице иконку открытого замка
  63. matrix.drawBitmap(lockOpen);
  64. // Устанавливаем вал сервопривода в минимальный угол
  65. servo.write(MIN_ANGLE);
  66. }
  67.  
  68. void loop() {
  69. // Считываем состояние с кнопки
  70. button.read();
  71. // Определяем нажатие кнопки
  72. if (button.justPressed()) {
  73. // Если замок открыт
  74. if (lockState) {
  75. // Устанавливаем вал сервопривода в максимальный угол
  76. servo.write(MAX_ANGLE);
  77. // Отображаем на матрице иконку закрытого замка
  78. matrix.drawBitmap(lockClosed);
  79. } else {
  80. // Устанавливаем вал сервопривода в минимальный угол
  81. servo.write(MIN_ANGLE);
  82. // Отображаем на матрице иконку открытого замка
  83. matrix.drawBitmap(lockOpen);
  84. }
  85. // Инвертируем переменную состояние замка
  86. lockState = !lockState;
  87. }
  88. }

№7. Консольный дальномер

LidarConsole.ino
  1. // Подключаем библиотеку для работы с дальномером
  2. #include <EasyUltrasonic.h>
  3.  
  4. // Создаём объект дальномера
  5. EasyUltrasonic distSensor;
  6.  
  7. // Даём понятные имена пинам дальномера TRIG и ECHO
  8. constexpr uint8_t TRIG_PIN = 11;
  9. constexpr uint8_t ECHO_PIN = 10;
  10.  
  11. void setup() {
  12. // Открываем монитор Serial-порта
  13. Serial.begin(9600);
  14. // Инициализируем дальномер
  15. distSensor.attach(TRIG_PIN, ECHO_PIN);
  16. }
  17.  
  18. void loop() {
  19. // Считываем расстояние до объекта в см
  20. float distance = distSensor.getDistanceCM();
  21. // Выводим результат в консоль
  22. Serial.print(distance);
  23. Serial.println(" cm");
  24. // Ждём 100 мс
  25. delay(100);
  26. }

№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
  1. // Подключаем библиотеку для работы с дальномером
  2. #include <EasyUltrasonic.h>
  3. // Подключаем библиотеку для работы с сервоприводом
  4. #include <Servo.h>
  5. // Подключаем библиотеку для работы со светодиодной матрицей
  6. #include <TroykaLedMatrix.h>
  7.  
  8. // Создаём объект дальномера
  9. EasyUltrasonic distSensor;
  10.  
  11. // Создаём объект сервопривода
  12. Servo servo;
  13.  
  14. // Создаём объект матрицы
  15. TroykaLedMatrix matrix;
  16.  
  17. // Даём понятное имя пину A2 с пищалкой
  18. constexpr uint8_t BUZZER_PIN = A2;
  19.  
  20. // Даём понятные имена пинам дальномера TRIG и ECHO
  21. constexpr uint8_t TRIG_PIN = 11;
  22. constexpr uint8_t ECHO_PIN = 10;
  23.  
  24. // Даём понятное имя пину 5 с сервоприводом
  25. constexpr uint8_t SERVO_PIN = 5;
  26.  
  27. // Задаём минимальный и максимальный угол поворота сервопривода
  28. constexpr uint8_t MIN_ANGLE = 0;
  29. constexpr uint8_t MAX_ANGLE = 180;
  30.  
  31. // Вычисляем количество градусов в каждом секторе,
  32. // делим диапазон угла сервопривода на 8 равных секторов
  33. constexpr uint8_t STEP_ANGLE = (MAX_ANGLE - MIN_ANGLE) / 7;
  34.  
  35. // Задаём минимальное и максимальное детектируемое расстояние дальномера в см
  36. constexpr uint8_t MIN_DIST = 5;
  37. constexpr uint8_t MAX_DIST = 30;
  38.  
  39. // Создаём константу для хранения тригера сигнализации в см
  40. constexpr int ALARM_DIST = 30;
  41.  
  42. // Создаём константу для хранения паузы между поворотом вала сервопривода
  43. constexpr int DELAY_SWEEP = 50;
  44.  
  45. // Создаём массив для хранения расстояния до объекта в матричном представлении
  46. byte distMatrix[8];
  47.  
  48. void setup() {
  49. // Настраиваем пин с пищалкой в режим выхода
  50. pinMode(BUZZER_PIN, OUTPUT);
  51. // Инициализируем дальномер
  52. distSensor.attach(TRIG_PIN, ECHO_PIN, MIN_DIST, MAX_DIST);
  53. // Подключаем сервомотор
  54. servo.attach(SERVO_PIN);
  55. // Инициализируем матрицу
  56. matrix.begin();
  57. // Очищаем матрицу
  58. matrix.clear();
  59. // Устанавливаем ориентацию матрицы на 90 градусов
  60. matrix.setRotation(ROTATION_90);
  61. }
  62.  
  63. void loop() {
  64. // Перебираем значения угла сервопривода от min до max
  65. for (int angle = MIN_ANGLE; angle <= MAX_ANGLE; angle++) {
  66. // Вызываем функцию обновления состояние сонара
  67. updateSonar(angle);
  68. }
  69. // Перебираем значения угла сервопривода от max до min
  70. for (int angle = MAX_ANGLE; angle >= MIN_ANGLE; angle--) {
  71. // Вызываем функцию обновления состояние сонара
  72. updateSonar(angle);
  73. }
  74. }
  75.  
  76. // Функция обновления состояния сонара
  77. void updateSonar(int angle) {
  78. // Отправляем текущий угол на сервопривод
  79. servo.write(angle);
  80. // Выжидаем паузу
  81. delay(DELAY_SWEEP);
  82. // Если вал мотора достиг нового сектора
  83. if (angle % STEP_ANGLE == 0) {
  84. // Вычисляем номер сектора от 0 до 7
  85. int colMatrix = angle / STEP_ANGLE;
  86. // Считываем расстояние до объекта в см
  87. int dist = distSensor.getDistanceCM();
  88. // Преобразуем диапазон значений с дальномера [MIN_DIST;MAX_DIST]
  89. // в графический диапазон значений для столбца матрицы от 0 до 8 точек
  90. distMatrix[colMatrix] = matrix.map(dist, MIN_DIST, MAX_DIST);
  91. // Отображаем все столбцы на матрице
  92. matrix.drawBitmap(distMatrix);
  93. // Обновляем звуковую сигнализацию
  94. updateAlarm(dist);
  95. }
  96. }
  97.  
  98. // Функция обновления звуковой сигнализации
  99. void updateAlarm(int dist) {
  100. // Если текущее расстояние до препятствия меньше тригера
  101. if (dist < ALARM_DIST) {
  102. // Включаем звуковую сигнализацию
  103. tone(BUZZER_PIN, 1000, 100);
  104. } else {
  105. // Выключаем звуковую сигнализацию
  106. noTone(BUZZER_PIN);
  107. }
  108. }

Оглавление

Ресурсы

Софт

Библиотеки