Потенциометр + Servo в фиксированных положениях.
- Войдите на сайт для отправки комментариев
Пнд, 16/03/2015 - 23:09
Всем привет.
Есть задача фиксировать серву в 7-ми положениях, в зависимости от положения потенциометра. Получился код:
#include <Servo.h> Servo myservo; int val; int vol = 0; // переменная для приема данных и отправки на серв void setup() { myservo.attach(5); } void loop() { val = analogRead(0); // считываем уровень на 0-м пине 0-1024 val = val/10; //округляем //всего 7 положений сервы от 0 до 90 градусов: if (val <= 13) {myservo.write(0);} else if (val > 13 && val <= 29 ) {myservo.write(15);} else if (val > 29 && val <= 44) {myservo.write(30);} else if (val > 45 && val <= 58) {myservo.write(45);} else if (val > 58 && val <= 74) {myservo.write(60);} else if (val > 75 && val <= 88) {myservo.write(75);} else if (val > 90){myservo.write(90);} delay(350); // ждем чтобы серв докрутил }
На Proteuse мотор ведет себя как то не совсем адекватно. Углы не те, что заданы.
Посколько реальное железо пока летит, прошу посмотреть код на предмет ошибок-подводных камней. Спасибо.
17 строка val = map(val, 0, 1023, 0, 179); // scale it to use it with the servo (value between 0 and 180)
и у вас "полный" оборот потенциометра будет 0-180, но уже в градусах. Так самому понятнее будет.
А на " докрутку" можно и 20-50 давать. Дёргаться меньше будет.
А на " докрутку" можно и 20-50 давать. Дёргаться меньше будет.А на " докрутку" можно и 20-50 давать.
...а можно посчитать исходя из скорооборотности сервы ( датаШит ) + нагрузка на вал - по максимуму угла отработки
val = analogRead(0);
// считываем уровень на 0-м пине 0-1024
нет - считываем уровень на 0-м пине 0-1023
А на " докрутку" можно и 20-50 давать. Дёргаться меньше будет.
...а можно посчитать исходя из скорооборотности сервы ( датаШит ) + нагрузка на вал - по максимуму угла отработки
Всё не так, даже совсем не так.
Серва едет к тому положению куда ей указали только то время когда подан импульс.
Даже точнее- то время которое получилось от разности длины нашего импульса и того импульса который выдал внутренний одновибратор на основании потенциометра положения.
И чисто теоретически она никогда не сможет по одному импульсу приехать в заданное положение.
Она не запоминает то положение куда ей надо ехать. От слова совсем.
Почему? Потому что если наш импульс - это что-то кратковременно стабильное, то импульс внутренний- нет.
Он начинал формироваться при одном положении потенциометра, но в процессе движения потенциометр изменил сопротивление, а как, и с какой скоростью он это сделал и как поменялась (заметьте - на ходу) длительность внутреннего импульса сильно зависит от напряжения питания ( мощьности на валу ) и нагрузки на вал.
Поэтому подав один импульс и если серва по каким-то причинам не доехала до желаемого нами положения,
то следующая попытка сделать зто произойдёт только тогда, когда прийдет второй импульс. Даже если через неделю.
Чаще подаём- быстрее доедем. И, доехав, будем дрожать вокруг конечной точки с каждым импульсом.
Но слишком часто тоже нельзя- надо чтобы "восстановился" внутренний одновибратор и был готов к перезапуску. Поэтому часто считается 20 миллисекунд- стандарт на период импульсов. Хотя и 5-10 обычно работает.
Всё это относится к "старым", "аналоговым" сервам.
А как работают " цифровые" - не знаю и пока не хочу знать.... Цены у них не гуманные.
0-1023
Опять увидел призрак Leshak a... ;) Здоров ли? Или вырос до 32-ух бит?
P.S. А как цифры в зелёный цвет красить? А буквы как?
Немного обновил код. Попробовал избежать лишних дрожаний мотора и избыточного опроса потенциометра.
PS. Для чего это надо. Вместо потенциометра может быть датчик или пульт ДУ. Серопривод, в свою очередь, соединяется шестерней с ручкой управления конечным прибором-устройством.
Вопрос. Понимаю что все ручки на устройствах разные, но все таки. Какую серву заказать, чтоб она могла крутить не очень тугую ручку?
Вы можете сразу получать с аналогового входа чёткие значения от 0 до 7, смещением результата чтения на 7 бит, останутся соответсвенно 3 бита для 8 градаций. analogRead(0)>>7. Дальнейший код можно облегчить от двойного сравнения. (if val == 0; и так далее) Или перейти на свитч-кейс.
зачем всё это, если у сервы нормальное питание и сама не убитая то стандартный пример knob работает на ура
С использованием сдвига код:
Ну и контороль на терминал