В этой статье рассказывается о том, как сделать радиоуправляемую платформу. Роль пульта дистанционного управления будет выполнять передатчик HobbyKing HK6S Transmitter. Приемником в данном случае может быть только HobbyKing HK6DF 6 Channel 2.4GHz Receiver. Однако, есть основания полагать, что подойдет любая RC аппаратура (с соответствующим приемником разумеется). Распознавание сигналов приемника и управление драйвером двигателей, в данном проекте, осуществляется ардуино. В статье приведено подробное описание всего железа и скетч.
Начну с краткого описания аппаратуры.
Продается передатчик вместе с приемником. Но если приемник сломается, то сильно горевать не стоит. Приемник можно купить отдельно.
В продаже есть два типа таких передатчиков: Mode1 и Mode2. Аппаратура Mode2 более распространена и я купил её. В дальнейшем я не буду специально указывать тип аппаратуры, но будет подразумеваться, что речь идет именно о Mode2.
В этом проекте я использовал Arduino Nano с USB UART преобразователем на микросхеме CH340.
Компактная, недорогая и живучая :)
Драйвер двигателей необходимо подбирать исходя из характеристик моторов. Основными параметрами влияющими на выбор драйвера являются напряжение и максимальный ток.
Напряжение подаваемое на электрические двигатели будет в районе 5 вольт. Этот параметр зависит скорее от источника тока (аккумулятор).
Максимальный ток использованных мной моторов составляет около 0.6 ампера. Этот параметр измеряется амперметром при заблокированном вале моторчика. Подключаете амперметр последовательно с мотором. Подаете питание. И руками осторожно останавливаете вал. Смотрите показания прибора. Долго блокировать вал моторчика нельзя.
Описанная методика подходит для маломощных коллекторных моторчиков. Прежде чем производить какие либо манипуляции с моторами смотрите документацию на них.
Сразу скажу, что аккумулятор должен быть способен отдать необходимый моторам ток. Иначе просядет напряжение и ардуино перезагрузится.
И ещё. В реальной эксплуатации до блокировки моторы лучше не доводить. Это может привести к их выходу из строя.
Подходящий под мои требования драйвер двигателей изображен на картинке ниже.
Этот драйвер изготовлен на двух микросхемах L9110S. Работает в пределах от 2.5 вольт до 12 вольт. Максимальный допустимый ток для этой микросхемы составляет 0.8 ампера.
Источником тока у меня служат четыре последовательно соединенных NiMH аккумулятора AAA. В полностью заряженном состоянии они выдают немного больше 5 вольт. Поэтому в проекте не должно быть деталей не способных пережить это. Для ATmega328, CH340 и L9110S проблем быть не должно.
Сама платформа та же, что и в статье http://justforduino.blogspot.ru/2014/02/blog-post_23.html
В собранном виде это все выглядит как то так.
Подключается все просто.
Левый электродвигатель платформы подключаются к клеммам драйвера MOTOR-A. Правый электродвигатель платформы подключается к клеммам драйвера MOTOR-B.
Arduino --- Motor Driver
GND --- GND
VCC --- VCC
D8 --- A-IA
D9 --- A-IB
D10 --- B-IA
D11 --- B-IB
Arduino --- Receiver
GND --- GND
VCC --- VCC
D6 --- CH1
D7 --- CH2
Для управления платформой достаточно двух каналов. Я выбрал aileron и elevator. Это правый стик моей аппаратуры. У приемника aileron соответствует первый канал (CH1), а elevator соответствует второй канал (CH2).
Значение управляющего импульса на первом канале (aileron) изменяется при перемещении стика по горизонтали. В крайнем левом положении управляющий импульс составляет 1914 миллисекунд. В среднем положении управляющий импульс составляет 1525 миллисекунд. В крайнем правом положении управляющий импульс составляет 1119 миллисекунд.
Значение управляющего импульса на втором канале (elevator) изменяется при перемещении стика по вертикали. В крайнем верхнем положении управляющий импульс составляет 1905 миллисекунд. В среднем положении управляющий импульс составляет 1507 миллисекунд. В крайнем нижнем положении управляющий импульс составляет 1114 миллисекунд.
Эти цифры получены с помощью приборов описанных в http://justforduino.blogspot.ru/2015/01/blog-post.html и http://justforduino.blogspot.ru/2014/12/blog-post.html
Измерение длительности управляющего импульса в скетче будет осуществляться стандартной функцией ардуино pulseIn(pin, value, timeout) У этой функции три параметра. Первый это ножка ардуино на которой производится измерение. Для ардуино нано значение этого параметра может быть от 0 до 19. Второй параметр определяет измеряемый логический уровень. Возможно всего два варианта. Это HIGH или LOW. Последний параметр не обязателен. Функцию можно вызвать без указания этого параметра. timeout определяет в течении какого времени функция pulseIn пытается измерить длительность импульса. По умолчанию это одна секунда. Функция возвращает значение длительности измеренного импульса в миллисекундах (unsigned long int).
Как именно реализована эта функция можно посмотреть в файле wiring_pulse.c У меня этот файл находится по адресу D:\arduino-1.0.6\hardware\arduino\cores\arduino\wiring_pulse.c
Осталось разобраться с управлением моторами. В теории все просто. Выводы ардуино подключенные к драйверу моторов настраиваются как выходы. В зависимости от логического уровня установленного на этих выводах моторы крутятся в одну сторону, другую сторону или стоят. Для наглядности я составил пару табличек.
Для левого мотора.
Для правого мотора.
Теперь нужно выяснить в какую сторону крутится левый и правый мотор в каждом конкретном случае. Вариантов масса. Я решил проблему с помощью специальных скетчей. Перед загрузкой скетчей нужно зафиксировать платформу так, чтобы колесики могли свободно вращаться, но платформа при этом оставалась неподвижной.
Первый скетч для левого мотора.
После загрузки этого скетча левый мотор должен начать вращаться вперед. Однако у меня он начал крутится назад. Эту проблему также можно решить множеством способов. Я просто переписал скетч.
Второй скетч для левого мотора.
С этим скетчем все заработало как надо. Мотор крутится вперед.
Теперь проверочный скетч для правого мотора.
У меня все получилось с первого раза. Правый мотор крутится вперед.
Теперь известна вся необходимая информация и можно написать скетч радиоуправляемой платформы.
Работать все должно так как описано ниже. Когда правый стик находится в центре, платформа неподвижна. При перемещении стика вперед, платформа должна двигаться вперед. При перемещении стика вперед и влево, левый моторчик двигает платформу вперед. При перемещении стика вперед и вправо, правый моторчик двигает платформу вперед. При перемещении стика назад, платформа должна двигаться назад. При перемещении стика назад и влево, левый моторчик двигает платформу назад. При перемещении стика назад и вправо, правый моторчик двигает платформу назад.
При повторении проекта возможно немного иное поведение платформы. Причина в том, что каждый мотор можно подключить к драйверу двумя способами. Тут следует либо поменять местами провода на "неправильном" моторе, либо подредактировать скетч. Последнее описано в статье достаточно подробно. Думаю проблем быть не должно.
Начну с краткого описания аппаратуры.
Продается передатчик вместе с приемником. Но если приемник сломается, то сильно горевать не стоит. Приемник можно купить отдельно.
В продаже есть два типа таких передатчиков: Mode1 и Mode2. Аппаратура Mode2 более распространена и я купил её. В дальнейшем я не буду специально указывать тип аппаратуры, но будет подразумеваться, что речь идет именно о Mode2.
В этом проекте я использовал Arduino Nano с USB UART преобразователем на микросхеме CH340.
Компактная, недорогая и живучая :)
Драйвер двигателей необходимо подбирать исходя из характеристик моторов. Основными параметрами влияющими на выбор драйвера являются напряжение и максимальный ток.
Напряжение подаваемое на электрические двигатели будет в районе 5 вольт. Этот параметр зависит скорее от источника тока (аккумулятор).
Максимальный ток использованных мной моторов составляет около 0.6 ампера. Этот параметр измеряется амперметром при заблокированном вале моторчика. Подключаете амперметр последовательно с мотором. Подаете питание. И руками осторожно останавливаете вал. Смотрите показания прибора. Долго блокировать вал моторчика нельзя.
Описанная методика подходит для маломощных коллекторных моторчиков. Прежде чем производить какие либо манипуляции с моторами смотрите документацию на них.
Сразу скажу, что аккумулятор должен быть способен отдать необходимый моторам ток. Иначе просядет напряжение и ардуино перезагрузится.
И ещё. В реальной эксплуатации до блокировки моторы лучше не доводить. Это может привести к их выходу из строя.
Подходящий под мои требования драйвер двигателей изображен на картинке ниже.
Этот драйвер изготовлен на двух микросхемах L9110S. Работает в пределах от 2.5 вольт до 12 вольт. Максимальный допустимый ток для этой микросхемы составляет 0.8 ампера.
Источником тока у меня служат четыре последовательно соединенных NiMH аккумулятора AAA. В полностью заряженном состоянии они выдают немного больше 5 вольт. Поэтому в проекте не должно быть деталей не способных пережить это. Для ATmega328, CH340 и L9110S проблем быть не должно.
Сама платформа та же, что и в статье http://justforduino.blogspot.ru/2014/02/blog-post_23.html
В собранном виде это все выглядит как то так.
Подключается все просто.
Левый электродвигатель платформы подключаются к клеммам драйвера MOTOR-A. Правый электродвигатель платформы подключается к клеммам драйвера MOTOR-B.
Arduino --- Motor Driver
GND --- GND
VCC --- VCC
D8 --- A-IA
D9 --- A-IB
D10 --- B-IA
D11 --- B-IB
Arduino --- Receiver
GND --- GND
VCC --- VCC
D6 --- CH1
D7 --- CH2
Для управления платформой достаточно двух каналов. Я выбрал aileron и elevator. Это правый стик моей аппаратуры. У приемника aileron соответствует первый канал (CH1), а elevator соответствует второй канал (CH2).
Значение управляющего импульса на первом канале (aileron) изменяется при перемещении стика по горизонтали. В крайнем левом положении управляющий импульс составляет 1914 миллисекунд. В среднем положении управляющий импульс составляет 1525 миллисекунд. В крайнем правом положении управляющий импульс составляет 1119 миллисекунд.
Значение управляющего импульса на втором канале (elevator) изменяется при перемещении стика по вертикали. В крайнем верхнем положении управляющий импульс составляет 1905 миллисекунд. В среднем положении управляющий импульс составляет 1507 миллисекунд. В крайнем нижнем положении управляющий импульс составляет 1114 миллисекунд.
Эти цифры получены с помощью приборов описанных в http://justforduino.blogspot.ru/2015/01/blog-post.html и http://justforduino.blogspot.ru/2014/12/blog-post.html
Измерение длительности управляющего импульса в скетче будет осуществляться стандартной функцией ардуино pulseIn(pin, value, timeout) У этой функции три параметра. Первый это ножка ардуино на которой производится измерение. Для ардуино нано значение этого параметра может быть от 0 до 19. Второй параметр определяет измеряемый логический уровень. Возможно всего два варианта. Это HIGH или LOW. Последний параметр не обязателен. Функцию можно вызвать без указания этого параметра. timeout определяет в течении какого времени функция pulseIn пытается измерить длительность импульса. По умолчанию это одна секунда. Функция возвращает значение длительности измеренного импульса в миллисекундах (unsigned long int).
Как именно реализована эта функция можно посмотреть в файле wiring_pulse.c У меня этот файл находится по адресу D:\arduino-1.0.6\hardware\arduino\cores\arduino\wiring_pulse.c
Осталось разобраться с управлением моторами. В теории все просто. Выводы ардуино подключенные к драйверу моторов настраиваются как выходы. В зависимости от логического уровня установленного на этих выводах моторы крутятся в одну сторону, другую сторону или стоят. Для наглядности я составил пару табличек.
Для левого мотора.
D8 (A-IA) | D9 (A-IB) | |
0 (LOW) | 0 (LOW) | мотор не крутится |
1 (HIGH) | 1 (HIGH) | мотор не крутится |
0 (LOW) | 1 (HIGH) | мотор крутится в одну сторону |
1 (HIGH) | 0 (LOW) | мотор крутится в другую сторону |
Для правого мотора.
D10 (B-IA) | D11 (B-IB) | |
0 (LOW) | 0 (LOW) | мотор не крутится |
1 (HIGH) | 1 (HIGH) | мотор не крутится |
0 (LOW) | 1 (HIGH) | мотор крутится в одну сторону |
1 (HIGH) | 0 (LOW) | мотор крутится в другую сторону |
Теперь нужно выяснить в какую сторону крутится левый и правый мотор в каждом конкретном случае. Вариантов масса. Я решил проблему с помощью специальных скетчей. Перед загрузкой скетчей нужно зафиксировать платформу так, чтобы колесики могли свободно вращаться, но платформа при этом оставалась неподвижной.
Первый скетч для левого мотора.
//////////////////////// // // Arduino // //////////////////////// // // Sketch: // const unsigned char A_IA = 8; const unsigned char A_IB = 9; const unsigned char B_IA = 10; const unsigned char B_IB = 11; void forward_stop( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, HIGH); digitalWrite(B_IA, LOW); digitalWrite(B_IB, LOW); } void setup() { pinMode(A_IA, OUTPUT); pinMode(A_IB, OUTPUT); pinMode(B_IA, OUTPUT); pinMode(B_IB, OUTPUT); forward_stop(); } void loop() { } // // End // ////////////////////////
После загрузки этого скетча левый мотор должен начать вращаться вперед. Однако у меня он начал крутится назад. Эту проблему также можно решить множеством способов. Я просто переписал скетч.
Второй скетч для левого мотора.
//////////////////////// // // Arduino // //////////////////////// // // Sketch: // const unsigned char A_IA = 8; const unsigned char A_IB = 9; const unsigned char B_IA = 10; const unsigned char B_IB = 11; void forward_stop( void ) { digitalWrite(A_IA, HIGH); digitalWrite(A_IB, LOW); digitalWrite(B_IA, LOW); digitalWrite(B_IB, LOW); } void setup() { pinMode(A_IA, OUTPUT); pinMode(A_IB, OUTPUT); pinMode(B_IA, OUTPUT); pinMode(B_IB, OUTPUT); forward_stop(); } void loop() { } // // End // ////////////////////////
С этим скетчем все заработало как надо. Мотор крутится вперед.
Теперь проверочный скетч для правого мотора.
//////////////////////// // // Arduino // //////////////////////// // // Sketch: // const unsigned char A_IA = 8; const unsigned char A_IB = 9; const unsigned char B_IA = 10; const unsigned char B_IB = 11; void stop_forward( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, LOW); digitalWrite(B_IA, HIGH); digitalWrite(B_IB, LOW); } void setup() { pinMode(A_IA, OUTPUT); pinMode(A_IB, OUTPUT); pinMode(B_IA, OUTPUT); pinMode(B_IB, OUTPUT); stop_forward(); } void loop() { } // // End // ////////////////////////
У меня все получилось с первого раза. Правый мотор крутится вперед.
Теперь известна вся необходимая информация и можно написать скетч радиоуправляемой платформы.
//////////////////////// // // Arduino // //////////////////////// // // Sketch: RC car // const unsigned char A_IA = 8; const unsigned char A_IB = 9; const unsigned char B_IA = 10; const unsigned char B_IB = 11; const unsigned char CH1 = 6; // Aileron const unsigned char CH2 = 7; // Elevator unsigned long int ail = 0; unsigned long int ele = 0; void forward_forward( void ) { digitalWrite(A_IA, HIGH); digitalWrite(A_IB, LOW); digitalWrite(B_IA, HIGH); digitalWrite(B_IB, LOW); } void backward_backward( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, HIGH); digitalWrite(B_IA, LOW); digitalWrite(B_IB, HIGH); } void forward_stop( void ) { digitalWrite(A_IA, HIGH); digitalWrite(A_IB, LOW); digitalWrite(B_IA, LOW); digitalWrite(B_IB, LOW); } void stop_forward( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, LOW); digitalWrite(B_IA, HIGH); digitalWrite(B_IB, LOW); } void backward_stop( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, HIGH); digitalWrite(B_IA, LOW); digitalWrite(B_IB, LOW); } void stop_backward( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, LOW); digitalWrite(B_IA, LOW); digitalWrite(B_IB, HIGH); } void stop_stop( void ) { digitalWrite(A_IA, LOW); digitalWrite(A_IB, LOW); digitalWrite(B_IA, LOW); digitalWrite(B_IB, LOW); } void setup() { pinMode(CH1, INPUT); pinMode(CH2, INPUT); pinMode(A_IA, OUTPUT); pinMode(A_IB, OUTPUT); pinMode(B_IA, OUTPUT); pinMode(B_IB, OUTPUT); stop_stop(); } void loop() { ele = pulseIn(CH2, HIGH); ail = pulseIn(CH1, HIGH); if ( ail == 0 ) { ail = 1500; ele = 1500; } if ( ele == 0 ) { ail = 1500; ele = 1500; } if ( ail > 1700 && ele > 1700 ) forward_stop(); if ( ail < 1300 && ele > 1700 ) stop_forward(); if ( ail > 1700 && ele < 1300 ) backward_stop(); if ( ail < 1300 && ele < 1300 ) stop_backward(); if ( ail > 1700 && ele < 1700 && ele > 1300 ) stop_stop(); if ( ail < 1300 && ele < 1700 && ele > 1300 ) stop_stop(); if ( ail < 1700 && ail > 1300 && ele > 1700 ) forward_forward(); if ( ail < 1700 && ail > 1300 && ele < 1300 ) backward_backward(); if ( ail < 1700 && ail > 1300 && ele < 1700 && ele > 1300 ) stop_stop(); } // // End // ////////////////////////
Работать все должно так как описано ниже. Когда правый стик находится в центре, платформа неподвижна. При перемещении стика вперед, платформа должна двигаться вперед. При перемещении стика вперед и влево, левый моторчик двигает платформу вперед. При перемещении стика вперед и вправо, правый моторчик двигает платформу вперед. При перемещении стика назад, платформа должна двигаться назад. При перемещении стика назад и влево, левый моторчик двигает платформу назад. При перемещении стика назад и вправо, правый моторчик двигает платформу назад.
При повторении проекта возможно немного иное поведение платформы. Причина в том, что каждый мотор можно подключить к драйверу двумя способами. Тут следует либо поменять местами провода на "неправильном" моторе, либо подредактировать скетч. Последнее описано в статье достаточно подробно. Думаю проблем быть не должно.
Комментариев нет:
Отправить комментарий