Запись данных с сонора при разных положениях сервы.
- Войдите на сайт для отправки комментариев
Пт, 11/05/2012 - 19:13
#include <Ultrasonic.h>
Ultrasonic ultrasonic(2, 13);
#include <Servo.h>
Servo servoMain;
#include <AFMotor.h>
int LeftStat(0);
int FrontStat(0);
int RightStat(0);
float Stat(0);
int servotime(1000);
void setup()
{
servoMain.attach(9);
Serial.begin(9600);
}
void servoLeft(){
servoMain.write(0);
}
void servoFront(){
servoMain.write(90);
}
void servoRight(){
servoMain.write(180);}
void loop(){
{Stat=ultrasonic.Ranging(CM);
Serial.println(LeftStat);
{servoLeft(); // считываем значение сонора слева
delay(servotime);}
{servoRight();// считываем значение справа
delay(servotime);
}
{servoFront(); //считываем значение сонора в переди
delay(servotime);
}
{if (Stat==0)
{(Stat=LeftStat);}
if (Stat==90)
{(Stat=FrontStat);}
if (Stat==180)
{(Stat=RightStat);}}}
}
В общем попытался сделать так что бы при каждом положение сервы данные заносились в отдельные переменные, но что то не выходит, я не очень хорошо знаю программирование, но смысл понял, в общем при печате какой либо из переменных они все раны нулю. ну кроме Stat.
Подскажите пожалуйста как добиться нужного результата?
Поддержую! так как самому нунжно такое делать скоро
В общем та это чась кода от задуманного робота.
Смысл такой.
Записываем переменные со всех сторон,
Возврашаем сонар в положение прямо,
Выбираем переменную с максимальным значением,
Если это справа(или слева), то разворачиваемся в право(лево), до тех пор пока не получим входное значение с сонора равное или +- какой то процент,
Движемся Вперед, до тех пор пока показание с сонора не достигнут минимума (определенное значение),
Повторяем цикл.
В общем что то такое хотелось бы
Не совсем понял смысл.
Но ничего сложного не вижу.
Поворачиваете серву на заданый угол - опрашиваете датчик - присваиваете его показания переменной
соотсветствующей этому положению. И так для всех трех положений.
Далее (исходя из имеющихся данных) производите вычисление оптимальной траектории движения бота.
В общем смысл такой, что бы робот ездил по максимальному растоянию из имеющихся.
а можно пример, кусок кода?
я вот как то так попробовал но не получается(
{servoRight();
(Stat=RightStat);
delay(servotime);
}
Вроде бы должно быть все правильно? но с RightStat идут нули Stat - это переменная с данными сонора.
#include <Servo.h> Servo myservo; void setup() { myservo.attach(9); } void loop() { myservo.write(0);//поворачиваем серву вправо right=analogRead(14);//читаете ваш датчик delay(1000); myservo.write(90);//поворачиваем серву по центру center=analogRead(14);//читаете ваш датчик delay(1000); myservo.write(180);//поворачиваем серву влево left=analogRead(14);//читаете ваш датчик delay(1000); }Далее вычисляете оптимальную траекторию по показаниям датчика.
А вообще так извращаться смысла особо нет.
Мой робот и без того находил "куда ехать" и не застревал.
Да и еще.
Логичней было-бы действовать
Вы же, похоже, пыталсиь
1. Это начальное значение переменной. Не правильно?
2. Все, понял основную ошибку, надо местами поменять переменные...
1. Это начальное значение переменной. Не правильно?
http://arduino.ru/Tutorial/Variables
#include <Ultrasonic.h> Ultrasonic ultrasonic(2, 13); #include <Servo.h> Servo servoMain; #include <AFMotor.h> AF_DCMotor motor(1); AF_DCMotor motor2(2); AF_DCMotor motor3(3); AF_DCMotor motor4(4); float LeftStat=0; float FrontStat=0; float RightStat=0; float Stat=0; int servotime=1000; void setup() { servoMain.attach(9); Serial.begin(9600); } void Forvard() {motor.run(FORWARD); motor.setSpeed(255); motor2.run(FORWARD); motor2.setSpeed(255); motor3.run(FORWARD); motor3.setSpeed(255); motor4.run(FORWARD); motor4.setSpeed(255);} void Back() {motor.run(BACKWARD); motor.setSpeed(255); motor2.run(BACKWARD); motor2.setSpeed(255); motor3.run(BACKWARD); motor3.setSpeed(255); motor4.run(BACKWARD); motor4.setSpeed(255);} void Left() { motor.run(BACKWARD); motor.setSpeed(255); motor2.run(BACKWARD); motor2.setSpeed(255); motor3.run(FORWARD); motor3.setSpeed(255); motor4.run(FORWARD); motor4.setSpeed(255);} void Right() {motor.run(FORWARD); motor.setSpeed(255); motor2.run(FORWARD); motor2.setSpeed(255); motor3.run(BACKWARD); motor3.setSpeed(255); motor4.run(BACKWARD); motor4.setSpeed(255);} void Stop() {motor.run(RELEASE); motor2.run(RELEASE); motor3.run(RELEASE); motor4.run(RELEASE);} void servoLeft(){ servoMain.write(0); } void servoFront(){ servoMain.write(90); } void servoRight(){ servoMain.write(180);} void loop(){ { Stat=ultrasonic.Ranging(CM); servoLeft();// считываем значение сонора слева delay(servotime); LeftStat=Stat; delay(servotime); servoFront(); //считываем значение сонора в переди delay(servotime); FrontStat=Stat; delay(servotime); servoRight(); delay(servotime); RightStat=Stat; delay(servotime); if (LeftStat>RightStat&&LeftStat>FrontStat) {Left();} else if (Stat>(LeftStat-5)) {Forvard();} else {Stop();} } }Вот что тут не правильно? я ставлю его в угол, с лева свободно. но он все равно едет прямо, а по задуманному должен повернуть налево.
И еще как мне правильно прочитать данные с переменных в сириал мониторе, он почему то всегда пишет значение с правой стороны хотя ухазано например лево или прямо.
Подскажите пожалуйста, уж очень хочется довести до конца задуманное.
Скажите, что, по вашему, происходит в строчках 75, 78 и 82?
ну как я понимаю
75 присваевается значение с далномера переменной Stat
78 записывается и сохраняется показание дальномера слева
82 то же самое только справа
хотя я уже совсем запутался. я так понимаю что в данном примере показания не записывабтся а постаянно меняются? а как записывать тогда?
Вообщем вот что вы сделали.
в строке 75 датчика, сохранили ее в переменную Stat (зачем она вообщем вам?)
Дальше поехали вращать сервой в разные стороны, и время от времени присваивать значение хранящееся в Stat (которое не меняется само по себе) переменным FrontStat, LeftStat, RightStat
В итоге, к концу Loop все переменные у вас имеют одинаковое значение. То что было считаннно в начале Loop.
Поэтому условия их сравнения я уже не вычитывал, они бессмыслены
78 записывается и сохраняется показание дальномера слева
Где в этой строчке вы видите чтения датчика? Там одна переменная присваивается другой.
Ну Stat я использовал для удобства, что бы дальше меньше писать.
Это же не меняет смысл? или для этого надо писать функцию? или я не так что то понимаю?
А скажите пожалуйста как сделать так что бы данные записывались?
Попробую еще раз ( я не даю готовый ответ, потому что хочу что-бы сами поняли).
Представте что у вас есть блокнот с четырьмя листиками. И вас есть часы. Находитесь вы дома. На каждый листик вы можете записать только одно значение "который час".
Вам сказали: Пойди в магазин и запиши "который час" на второй листик, потом пойди на почту и запиши когда ты пришел туда на третий, пойди дай в табло васе и запиши время события на четвертый листик.
Что вы сделали в скетче: Будучи дома: посмотрели на часы и их показания записали на первый листик (пока все правильно), пошли в магазин и вместо того что-бы опять посмотреть на часы (получить данные с сенсора), просто переписали время с первого листка на второй, потом пошли на почту и опять, не глядя на часы, переписали время в первого на третий. И ударив васю опять просто переписали время с первого листа на четвертый.
В результате каждый лист блокнота у вас содержит одно и тоже время: во сколько вы вышли из дома, а не когда вы были в магазине, на почте, у васи. Понять по таким записям, например, сколько заняла ваша дорого от магазина до почты - не возможно.
Что-бы было все правильно, вы должны каждый раз смотреть на часы. Точно так же как вы делали это заполняя первый листик.
------------
Возвращаесь с скетчу: часы- это сонар , "который час" - показания сонара, листики - ваши переменные.
Спасибо вам большое за интересный пример и старания, в общем я понял так:
void loop(){ servoLeft();// считываем значение сонора слева delay(servotime); LeftStat=ultrasonic.Ranging(CM); delay(servotime); servoFront(); //считываем значение сонора в переди delay(servotime); FrontStat=ultrasonic.Ranging(CM); delay(servotime); servoRight(); delay(servotime); RightStat=ultrasonic.Ranging(CM); delay(servotime); {if (LeftStat>RightStat&&LeftStat>FrontStat) {servoFront(); Left();} else if (ultrasonic.Ranging(CM)>(LeftStat-5)) {Forvard();} else {Stop();}} } Вроде уже лучше)Ну да. Так уже больше похоже на правду.
По крайней мере в перменных будут показания сонара слева, справа и впереди.
Теперь с условиями разбирайтесь. Что с чем вы сравниваете и что по этому поводу нужно делать.Как минимум, я вижу, внутри условий вы опять, в строке 18 зачем-то опрашиваете сонар (может это нужно, но я не понял этой логики).
ну по задумке после определения максимального расстояния серва должна встать прямо, робот начать поварачивать в ту сторону на которой сонар определил максимальное растояние, до тех пор пока не полчит показание с сонора приближенное к максимальному значению. далее едет вперед. но тут у меня пока тоже возникают трудности...
void loop(){ servoLeft();// считываем значение сонора слева delay(servotime); LeftStat=ultrasonic.Ranging(CM); delay(servotime); servoFront(); // считываем значение сонора спереди delay(servotime); FrontStat=ultrasonic.Ranging(CM); delay(servotime); servoRight(); // считывание значения сонора справа delay(servotime); RightStat=ultrasonic.Ranging(CM); delay(servotime); if (LeftStat>RightStat&&LeftStat>FrontStat) {Left(); servoFront();} else if (ultrasonic.Ranging(CM)>(LeftStat-5)) {Forvard();} else {Stop();} } по задумке если первое условие верно серва становится прямо а платформа поварачивает на лево, но серва не хочет стоять на месте, тут что не так?Ну чего, подсказать кто может?
Ну вы мысленно прокрутите что ваш скетч делает. Или на бумажке алгоритм нарисуте.
Вот оно же и делает ровно то что вы в скетче написали:
Условия в строчке 22 - даже не проверяется если стработало условие в строчке 19. Почитайте как работает if-else
Заодно и с while познакомтесь раз хотите реализовать что-то типа "до тех пор пока"
По поводу while вроде все ясно но есть одно НО, в описание пишется будет выполняться до тех порка пока выражение не будет ложью а мне надо наоборот, до тех пор пока не будет истина. как этого добиться?
http://arduino.ru/Reference/Boolean
void loop() {Stop(); servoLeft();// считываем значение сонора слева delay(servotime); LeftStat=ultrasonic.Ranging(CM); delay(servotime); servoFront(); // считываем значение сонора спереди delay(servotime); FrontStat=ultrasonic.Ranging(CM); delay(servotime); servoRight(); // считывание значения сонора справа delay(servotime); RightStat=ultrasonic.Ranging(CM); if (LeftStat>RightStat&&LeftStat>FrontStat) { servoFront(); delay(servotime); while (!(ultrasonic.Ranging(CM)>(LeftStat-5))){ Left(); } servoFront(); delay(servotime); while (ultrasonic.Ranging(CM)>=10){ Forvard(); } } }Получилось как то так, но почему то вперед не едет, точнее едет на 1 рывок и все, и начинается по новой, а надо что бы ехал до тех пор пока растояние до препятствия не будет >= 10
вот откуда он получает значение меньше или равное 10 (когда до препятсьвия гаразда больше) ? с кодом же все правильно?
Ну, по скетчу вроде выглядит именно как "ехал до тех пор пока растояние до препятствия не будет >= 10".
Попробуйте сделать вывод в serial.Print что там ваш датчик возвращает. Может он в миллиметрах возврат дает. Или наоборот. Или ловит свои собственные посылки.
МОжете даже отдельный скетч написать что-то типа
void loop(){ Serial.println(ultrasonic.Ranging(CM)); delay(200); }Откройте сериал монитор, помашите перед ним рукой. Посмотрите какие значения с него идут.
И еще. Строчки 28,29 зачем? Ну то есть они не помешают. Просто не нужную задержку дают. У нас же и так серва уже повернута во front в строчках 21,22 и с тех пор мы ее не крутили. Значит 28 вообще не даст никакого видимого эффекта. А 29 - будет просто "стоять тупить".
Вообщем заведите себе привычку. Представте себя сервой и попробуйте выполнить команды скетча (так же как с примером похода в магазин/почту и т.д. делали).
А еще.... возможно есть какое-то ограничение, с какой скоростью датчик данные возвращать умеет. Ему же нужно послать импульс и дождатся ответа.А это время. Или ловит эхо от предыдущего замера. Возможно слишком быстро читаете. Попробуйте после forward, delay какой-нить втыкнуть небольшой (внутри while).