управление сервой на заданный угол

OnePointer
Offline
Зарегистрирован: 24.09.2012

Хотел сделать программу для управленией сервой через последовательный порт,что-бы серва становилась в положение от 0 до 180 ,так как новичок с ходу написать ее не вышло...нашел похожую программу, но она устанавливает положение по 9 точкам,пытался заменить строку  int pos = map(data, 0, 9, 0, 180); на  int pos = map(data, 0, 180, 0, 180); и простj убрать эту строку пробовал управляя через переменную data .

#include <Servo.h>

int servoPin = 9;

//Create Servo Object
Servo myServo;

void setup()
{
 //Start Serial
 Serial.begin(9600);

  myServo.attach(servoPin);
  
  delay(500);
}

void loop()
{  

  while( Serial.available() == 0);
  int data = Serial.read() -'0';

  int pos = map(data, 0, 9, 0, 180);
  pos = constrain(pos, 0, 180);

  Serial.println(pos);
  myServo.write(pos);
  Serial.flush();  
  
  
}

 

ich
Offline
Зарегистрирован: 10.06.2012

Как-то так:

#include <servo.h>
Servo motor;
 
void setup()
{
   motor.attach(10); // Подключаем серву на 10 пин
}
 
void loop()
{
   motor.write(0);		// Устанавливаем серву на 0°
   delay(1000);			// Пауза 1 сек.
   motor.write(90);		// Устанавливаем серву на 90°
   delay(1000);         // Пауза 1 сек.
   motor.write(180);	// Устанавливаем серву на 180°
   delay(1000);			// Пауза 1 сек.
}

 

#include <servo.h>
Servo motor;
int angle;
 
void setup()
{
	Serial.begin(9600);
	motor.attach(10); // Подключаем серву на 10 пин
}
 
void loop()
{
	if(Serial.available()){
		angle = Serial.read();
		motor.write(angle);		// Устанавливаем серву на angle°
		delay(1000);			// Пауза 1 сек.
   }
}

 В нижнем примере за угал отвечает Номкр символа из ASCII-Таблици.

Тут описание библиотеки Servo.h

OnePointer
Offline
Зарегистрирован: 24.09.2012

 спасибо !Опробую вечером добавив constrain и '0' ,тогда поидее угол будет не выходить за рамки 0 и 180 и числа в нужной кодировке придут.я правильно понимаю?

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

А я тут недавно прочитал, что у Serial есть метод Serial.parceInt() и Serial.parceFloat(), правда, сам еще не пробовал. Поставте вместо Serial.read().

OnePointer
Offline
Зарегистрирован: 24.09.2012

 а можете по простому объяснить что они делают я на ардуино первый день программирую ,не понял что-то.Спасибо

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Чего же проще? Первая декодирует из входного потока целое число (иначе вы получаете строку "23" вместо ожидаемого числа), вторая - число с плавающей запятой. И основной цикл будет выглядеть так:

void loop()
{  

  while( Serial.available() == 0);
  pos = Serial.parceInt();

  Serial.println(pos);
  myServo.write(pos);
  Serial.flush();  
  
  
}

 

leshak
Offline
Зарегистрирован: 29.09.2011

OnePointer пишет:

 а можете по простому объяснить что они делают я на ардуино первый день программирую ,не понял что-то.Спасибо

По простому читает строку из сериал и пытается перевести ее int

OnePointer
Offline
Зарегистрирован: 24.09.2012

 спасибо большое,все понятно.

leshak
Offline
Зарегистрирован: 29.09.2011

 Ага. Их, кажись, только в 1.0 ввели. Поэтому и руско-язычной доке про них вообще не упоминается.

А еще они имеют побочный эффект в виде "остановки скетча". Так что не всегда можно их применить (но для данной задачи - вроде можно).

P.S. только Serial.parseInt

leshak
Offline
Зарегистрирован: 29.09.2011

AlexFisher пишет:

И основной цикл будет выглядеть так:

А еще при этом, желательно в Serial мониторе выставить LineEnding например в NL (добавлять символ "конец строки" ко всему что вы шлете).

То есть работать будет и без этого, но может "чуть подтупливать". Так как понимать что "ввод числа закончился" он будет по TimeOut. А line ending - сразу после отсылки поймет (первый же символ не цифровой, означает "число приехало целиком и можно начинать парсить его").

А можно без Line эндинга. Добится того же эффекта. Просто, когда отправляете, добавлять в конце одну букву (любую). Как признак "конец числа".

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Постоянно букву в этом слове путаю :)

А тормозят они скетч, потому что ждут конца строки из потока или окончания таймаута (он по умолчанию 1с, настраивается через setTimeout()) Так что если критично, лучше поток сложить в буферную String и применить String.toInt(), которая, кстати, на аглицком сайте до сих пор не описана. 

leshak
Offline
Зарегистрирован: 29.09.2011

AlexFisher пишет:

Постоянно букву в этом слове путаю :)

У меня такая же беда с Serial.avaliable() - без copy-paste или интелесенса не могу его написать впринципе :)

AlexFisher пишет:

А тормозят они скетч, потому что ждут конца строки из потока или окончания таймаута (он по умолчанию 1с, настраивается через setTimeout())

Не, ну "почему" - это понятно :) (вот поэтому я и вел речь про посылать буквенный символ, что-бы не ждать этого timeout).

AlexFisher пишет:

Так что если критично, лучше поток сложить в буферную String и применить String.toInt(), которая, кстати, на аглицком сайте до сих пор не описана. 

Хе... не знал.  Хотя не полюбляю я этот String :(   Сразу куча библиотек всяких отлетает которые умеют только с C-шными строками работать. Поэтому либо "ручками" либо atoi функция.

OnePointer
Offline
Зарегистрирован: 24.09.2012

спасибо вы конечно помогли ,буду пробовать но последнии три ваших сообщения не совсем понял,я ж ламер еще.ну надеюсь со временем придет, надо что-то читать.

OnePointer
Offline
Зарегистрирован: 24.09.2012

 можете поподробнее об string.tolnt() по простому))

OnePointer
Offline
Зарегистрирован: 24.09.2012
#include &lt;Servo.h&gt;
 int pos = 0;
int servoPin = 9;
Servo myServo;
  void setup()
{
Serial.begin(9600);
myServo.attach(servoPin); // Подключаем серву на 10 пин
}
void loop()
{
while( Serial.available() == 0);
pos = Serial.parseInt();
pos = constrain(pos, 0, 180);
Serial.println(pos);
myServo.write(pos);
Serial.flush();
}

дописал с вашей помощью работает как хотел спасибо!

следующим шагом хочу сделать соединение с другим ардуио который будет использоваться как пульт и передавать сигнал через сериал порт по этому передатчику который куплюю через пару дней http://www.electronshik.ru/card/modul-radiotransivera-apc220-114373 

leshak
Offline
Зарегистрирован: 29.09.2011

OnePointer пишет:

 можете поподробнее об string.tolnt() по простому))

Не можете. Так как string.toInt() - не существует. Пойдите в раздел "Програмирования" и, для начала, почитайте про string и String. Выясните чем они отличаются. Причем, я бы советовал, несмотря на то что String будет выглядеть проще в использовании, все-таки разобратся именно со string. Так как сталкиватся с ним будете гораздо чаще (можно еще какой-нибудь учебник по C посмотреть, работу со строками).

Можете по форуму попробовать поискать. Вопрос - регулярно всплывает. Например вот http://arduino.ru/forum/programmirovanie/perevod-prinyatogo-simvola-s-com-porta-v-chislo

Там можно найти "как это работает". Как самому "переводить". без использования функций (их раньше небыло). Ну или полезть в исходники ардуины и посмотретьк как этот toInt реализован.

OnePointer
Offline
Зарегистрирован: 24.09.2012

#include <Servo.h> //подключение библиотеки
int pos = 0; //угол сервы
int servoPin = 9; //пин сервы
Servo myServo; //заданное пмя сервы
void setup()
{
Serial.setTimeout(100);
Serial.begin(9600); //скорость соединения
myServo.attach(servoPin); // Подключаем серву на 9 пин
}
void loop()
{
while( Serial.available() == 0); //ожидание данных с порта
pos = Serial.parseInt(); //прием и перевод в integer
pos = constrain(pos, 0, 180); //ограничение от 0 до 180
Serial.println(pos); //передача задаваемого угла обратно
myServo.write(pos); //установка угла
Serial.flush(); //фильтр мусора
}
/*********************
КОНЕЦ
**********************/ 

с таймаутом классно не тупит совсем

Dikon
Offline
Зарегистрирован: 28.11.2012

ich пишет:

Как-то так:

#include <servo.h>
Servo motor;
 
void setup()
{
   motor.attach(10); // Подключаем серву на 10 пин
}
 
void loop()
{
   motor.write(0);		// Устанавливаем серву на 0°
   delay(1000);			// Пауза 1 сек.
   motor.write(90);		// Устанавливаем серву на 90°
   delay(1000);         // Пауза 1 сек.
   motor.write(180);	// Устанавливаем серву на 180°
   delay(1000);			// Пауза 1 сек.
}

 

#include <servo.h>
Servo motor;
int angle;
 
void setup()
{
	Serial.begin(9600);
	motor.attach(10); // Подключаем серву на 10 пин
}
 
void loop()
{
	if(Serial.available()){
		angle = Serial.read();
		motor.write(angle);		// Устанавливаем серву на angle°
		delay(1000);			// Пауза 1 сек.
   }
}

 В нижнем примере за угал отвечает Номкр символа из ASCII-Таблици.

Тут описание библиотеки Servo.h

У вас ошибка!!!! библиотека Servo.h у вас объявлена как servo.h (с маленькой буквы),в итоге будет выдавать ошибку servo does not name a type при компиляции . Простите это мой первый опыт в программировании