Для данной статье я рассматриваю схему из статьи Arduino. Управление сервоприводом, на примере SG90.
Мы используем:
- Плата Arduino. x1
- Компьютер(для написания и загрузке кода, а так же мы будем брать с него электричество и общаться с ним). x1
- Провод для соединения компьютера и платы. x1
- Сервопривод. x1
Конкретно для взаимодействия с компьютером он не нужен, просто я считаю что это статья продолжение статьи Arduino. Управление сервоприводом, на примере SG90. - Провода. x3-4
- Есть схемы с внешним источником питания, но можно взять питание и с платы.
Схемы подключения:
Рассмотренный в статье Arduino. Управление сервоприводом, на примере SG90 скетч. По мне не очень интересен, так как не даёт полного представления о том, для чего использовать сервопривод. А серво привод это не просто туда сюда, это точные сильные движения. За одно мы рассмотрим, как взаимодействовать с платой Arduino через USB.
Рассмотрим следующий скетч:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#include <Servo.h> Servo myservo; int pos = 0; int incomingByte = 0; void setup() { Serial.begin(9600); myservo.attach(9); } void loop() { if (Serial.available() > 0) { incomingByte = Serial.read()-48; if (incomingByte>=0 and incomingByte<=9) { pos=pos*10+incomingByte; Serial.println(pos, DEC); } else { if (pos>=1 and pos<=180){ Serial.print("move: ");Serial.println(pos, DEC); myservo.write(pos); } pos=0; } } } |
Этот скетч будет выставлять позицию сервопривода на позицию, переданную с компьютера на плату.
Рассмотрим данный скетч:
1 |
#include <Servo.h> |
Нам так же понадобится библиотека Servo.h
Мы объявляем так же переменные:
1 2 |
Servo myservo; int pos = 1; |
С объектом Servo myservo. И переменная pos в которую мы будем записывать позицию, на которую надо установить сервопривод.
Так же нам понадобится переменная
1 |
int incomingByte = 0; |
Сюда мы будем заносить данные поступающие с порта USB на плату.
В блоке setup:
1 2 |
myservo.attach(9); Serial.begin(9600); |
Мы так же задаём, что общаться с серво приводом мы будем через 9 ножку (myservo.attach(9);)
1 |
Serial.begin(9600); |
Все действия с портом USB проходят через объект Serial. Функция объекта Serial begin() выставляет скорость передачи данных по порту usb. в нашем случае begin(9600) означает, что скорость передачи данных с портом USB будет 9600 бод(бит/c).
Дальше начинается самое интересное, блок loop:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if (Serial.available() > 0) { incomingByte = Serial.read()-48; if (incomingByte>=0 and incomingByte<=9) { pos=pos*10+incomingByte; Serial.println(pos, DEC); } else { if (pos>=1 and pos<=180){ Serial.print("move: ");Serial.println(pos, DEC); myservo.write(pos); } pos=0; } } |
1 |
if (Serial.available() > 0) { |
Конструкция if(если выполняется условие){выполняется данный блок кода}. В нашем случае Serial.available() возвращает кол-во байт доступных для чтения. соответственно если их больше нуля, выполняем блок кода внутри if.
1 |
incomingByte = Serial.read()-48; |
Раз у нас есть данные для чтения начнём их читать, Serial.read() — считываем 1 байт из буфера. После мы ожидаем цифровое значение для ввода позиции.. а следующие коды соответсвуют следующим цифрам на клавиатуре:
48=»0″; 49=»1″ ;50=»2″; 51=»3″; 52=»4″; 53=»5″; 54=»6″; 55=»7″; 56=»8″; 57=»9″
Откуда я взял эти значения? это просто расширенная кодировка ASCII — cp1251
соответственно если мы ожидаем только цифры и какое нибудь значение обозначающее окончание ввода, то можно из кода вводимого символа вычесть 48 и у нас будет цифровое значение.
Данное значение мы помещаем в переменную incomingByte.
То есть в переменной incomingByte будет находится либо цифра или число большее 10 или меньшее 0.
запишем это следующей конструнцией if(условие){блок кода который выполняется когда условие истинно} else {блок кода который выполняется когда условие ложно}. В нашем случае:
if (incomingByte>=0 and incomingByte<=9) {..} else {…}
тоесть если incomingByte больше или равно 0 и меньше или равно 9 то это число. Рассмотрим что мы будем делать если во входящем байте закодирована цифра:
1 2 |
pos=pos*10+incomingByte; Serial.println(pos, DEC); |
Данной командой:
1 |
pos=pos*10+incomingByte; |
мы умножаем значение позиции pos на 10 и прибавляем знчение цифры. По сути прибавляем новое число с права. например если сейчас pos=1 и мы ввели 2 то pos=12.
1 |
Serial.println(pos, DEC); |
Для наглядности выводим данные в переменной pos на USB порт. Для этого у объекта Serial есть функция print и println. print и println различаются тем, что по завершению вывода данных println посылает код перевода каретки на новую строку. Как то не понятно получилось…Раньше использовались два символа CR код 13 и LF код 10 .CR с кодом 13 возвращает каретку на начало строки, то есть переводит фокус ввода на начало строки. LF c кодом 10 переводит коретку на новую строку. Сейчас в основном принято при получении символа CR с кодом 13 переводить каретку на новую строку.
Рассмотрим нашу команду Serial.println(pos, DEC); в функции println у нас два параметра, первая это значение которое надо выводить, у нас там стоит переменная pos следовательно её значение и будет выводиться, вторая переменная у целых и вещественных чисел имеет разное значение. У целых чисел BYTE и BIN двоичный вывод, OCT восьмеричный вывод, DEC десятеричный вывод, HEX шестнадцатеричный вывод. У вещественных второй параметр числовой, который указывает сколько цифр после запятой выводить. В нашем случае pos целое число (тип int) и второй параметр DEC значить выводить данные мы будет в десятеричной системе исчисления.
На этом код если закончился перейдём к коду иначе (else).
1 2 3 4 5 |
if (pos>=1 and pos<=180){ Serial.print("move: ");Serial.println(pos, DEC); myservo.write(pos); } pos=0; |
Этот код выполняется если incomingByte выходит из диапазона от 0 до 9 это означает, что ввод цифр закончен и надо действовать.
1 |
if (pos>=1 and pos<=180){ |
Проводим проверку, если pos лежит в диапазоне от 1 до 180 то
1 2 |
Serial.print("move: ");Serial.println(pos, DEC); myservo.write(pos); |
1 |
Serial.print("move: ");Serial.println(pos, DEC); |
Выводим следующее сначала строку «move: «, а потом значение pos с переводом каретки.
После
1 |
myservo.write(pos); |
устанавливаем сервопривод в позицию pos (myservo.write(pos);)
1 |
pos=0; |
осталось занулить значение pos в любом случае выходит pos из диапазона значений или не выходит.
Скетч закончился.
После загрузки данного наброска на плату, переходим вследующий пункт меню:
Инструменты->Мониторинг порта
В открывшемся окне, в правом нижнем углу есть выпадающий список со скоростью взаимодействия с платой. Выставляем 9600 бод, как указано в нашем скетче.
Теперь мы готовы для ввода параметров.
Введём значение «123-» и нажмём «Enther»:
на экране выведется:
1 2 3 4 |
1 12 123 move: 123 |
а потом сервопривод перейдёт в позицию 123.
Из этого примера видно, что Arduino не обрабатывает всю строку сразу, а берёт данные побитово, сначала обработался код символа «1». потом код симовла «2» и т.д. пока наша строка не закончилась.
Видео процесса:
Другие статьи по программированию плат Arduino можно посмотреть здесь.
Комментарии: