Подключите переменный резистор ко входу АЦП. Подключите сервопривод к выходу с ШИМ. Прочитайте значение с АЦП. Приведите значение к интервалу [0: 255]. Установите полученное значение на выходе ШИМ. Если на входе АЦП значение будет меняться в пределах [0..1023], достаточно будет написать analogWrite(SERVO_PIN, analogRead(POT_PIN) / 4);
Решил управлять сервой с помощью ультразвукового дальномера. Возникли проблемы с кодом . Дальномер посылает данные единым потоком. Вот код Код (Text): #include <Servo.h> int inputPin=4; // Echo int outputPin=5; // Trig int ledpin=13; Servo myservo; void setup() { Serial.begin(9600); pinMode(ledpin,OUTPUT); pinMode(inputPin, INPUT); pinMode(outputPin, OUTPUT); myservo.attach(9); } void loop() { digitalWrite(outputPin, LOW); delayMicroseconds(2); digitalWrite(outputPin, HIGH); delayMicroseconds(10); digitalWrite(outputPin, LOW); int distance = pulseIn(inputPin, HIGH); distance= distance/58; Serial.print(distance); delay(1000); myservo.write( analogRead(distance) ); delay(100); }
А как сделать чтобы ардуина запоминала последние значение в пределах рабочей зоны и серва удерживала его?
как только в пределах рабочей зоны (4-22 см) появляется объект, серва принимает соответствующее, положение, и удерживает это положение до появление другого объекта в указанной зоне.
А как дальномер будет определять, что в зоне его действия появился еще один объект? Дальномеру без разницы, он определяет расстояние до ближайшего. Или Вы хотите, чтобы серва реагировала только на приближение объекта, а на удаление не реагировала? Приблизился один раз - серва повернулась. Отдалился - серве пофиг. приблизился еще раз - серва повернулась обратно. Так, что ли?
В моем проекте движение объекта роли не играет. Важно только текущее положение. Алгоритм действий будет таким: допустим, серва повернута на 180 град. Если мне нужно его изменить подношу руку к дальномеру на расстояние 10 см серва принимает положение 60 градусов я убираю руку и серва сохраняет положение 60 градусов. Когда мне нужно изменить его все повторяется. А сейчас как только я убираю руку Дальномер замечает противоположную стены и серва поворачивается на 180 , а мне этого совсем не надо.
Ну и проверяйте в своем коде показания дальномера. Пускай реагирует только на расстояние меньше 10см, а остальное игнорирует. Условным оператором пользоваться умеете?
вот собственно что получилось. Код (Text): #include <Servo.h> #define coef 10 //(коэффициент соответствия 10 градусов на 1см) #define dead_zone 4 #define max_value 22 #define servoPin 9 #define Trig 5 #define Echo 4 #define ledPin 13 Servo myservo; void setup() { pinMode(Trig, OUTPUT); //инициируем как выход pinMode(Echo, INPUT); //инициируем как вход pinMode(ledPin, OUTPUT); myservo.attach(servoPin); myservo.write(0); } unsigned int impulseTime=0; unsigned int distance_sm=0; void loop() { digitalWrite(Trig, HIGH); /* Подаем импульс на вход trig дальномера */ delayMicroseconds(10); // равный 10 микросекундам digitalWrite(Trig, LOW); // Отключаем impulseTime = pulseIn(Echo, HIGH); // Замеряем длину импульса distance_sm = impulseTime/58; // Пересчитываем в сантиметры if (distance_sm >= dead_zone && distance_sm <= max_value) { myservo.write(coef * (distance_sm - dead_zone)); } } Все равно как только я убираю руку серва упорно занимает 180 град.
Поставьте в код отладочный вывод проанализируйте то, что увидите в мониторе порта. Примерно так: Код (Text): #include <Servo.h> #define coef 10 //(коэффициент соответствия 10 градусов на 1см) #define dead_zone 4 #define max_value 22 #define servoPin 9 #define Trig 5 #define Echo 4 Servo myservo; unsigned int impulseTime=0; unsigned int distance_sm=0; void setup() { Serial.begin(9600); pinMode(Trig, OUTPUT); //инициируем как выход pinMode(Echo, INPUT); //инициируем как вход myservo.attach(servoPin); myservo.write(0); } void loop() { digitalWrite(Trig, HIGH); // Подаем импульс на вход trig дальномера delayMicroseconds(10); // равный 10 микросекундам digitalWrite(Trig, LOW); // Отключаем impulseTime = pulseIn(Echo, HIGH); // Замеряем длину импульса Serial.print("impulseTime: "); Serial.println(impulseTime); distance_sm = impulseTime/58; // Пересчитываем в сантиметры Serial.print("distance_sm: "); Serial.println(distance_sm); if (distance_sm >= dead_zone && distance_sm <= max_value) { int value = coef * (distance_sm - dead_zone); myservo.write(value); Serial.print("value: "); Serial.println(value); } }
До вашего последнего комментария не получалось. Сейчас прочитал что достаточно закомментировать или убрать строку "myservo.write(0); в исходном коде
Так ведь эта строка в функции setup() была, т.е. она должна выполняться всего один раз по включении питания. Во время работы зеленый светодиод (питание) случайно не моргает?