Проблемы с motor shield V3 и Servo
- Войдите на сайт для отправки комментариев
Добрый день.
Имеется:
Arduino uno v3
motor shield V3 http://www.ebay.com/itm/V3-Motor-controller-Shield-L298N-2-motors-Arduino-compatible-/180882914565?pt=LH_DefaultDomain_0&hash=item2a1d763d05
Sensor Shield V4.0 http://www.odduino.com/shop/82/desc/arduino-sensor-shield-v4-0
Еще дополнительно подключен HC-SR04, с ним проблем нет.
Если использовать ШИМ для управления DC моторами то проблем нет, скорость регулируется, направления вращения меняются.
Если же задействовать библиотеку Servo.h, то двигатели перестают стартовать. Отловил это специально, отключая все используемые надстройки.
Т.е. проблемы в конфликте ШИМ для motor shield и библиотеки Servo.
Пробовав вешать сервомашинку на другие порты, результата не дало. В датащите на ATmega328 и описании Arduino Uno черным по английски три независимых таймера и возможностью генерировать ШИМ на 6 выходах.
motor shield V3 использует выходы с 13 по 8 включительно, ШИМ подается на 9 и 10. Сервомашинка работает на пинах с 1 по 7 но при этом не работают DC моторы.
Весь код скетча ниже, что предложите для запуска управления DC моторами с регулировкой скорости и использования одной сервомашинки?
// motor A int dir1PinA = 13; int dir2PinA = 12; int speedPinA = 10; // motor B // motor A int dir1PinB = 11; int dir2PinB = 8; int speedPinB = 9; unsigned long time; int speed; int dir; int delay_count; int left_distance; int rigth_distance; int front_distance; #include <Servo.h> #include <Ultrasonic.h> Servo myservo; // create servo object to control a servo // a maximum of eight servo objects can be created Ultrasonic ultrasonic(6, 5); // номера пинов к которым подключены выводы Trig и Echo, соответственно void setup() { pinMode(dir1PinA, OUTPUT); pinMode(dir2PinA, OUTPUT); pinMode(speedPinA, OUTPUT); pinMode(dir1PinB, OUTPUT); pinMode(dir2PinB, OUTPUT); pinMode(speedPinB, OUTPUT); time = millis(); speed = 0; // максимум 255 dir = 1; delay_count=0; myservo.attach(1); // attaches the servo on pin 7 to the servo object myservo.write(90); // ставим сервопривод смотрящим вперед Serial.begin(9600); // start the serial port Serial.println("START"); } void forward() { digitalWrite(dir1PinA, HIGH); digitalWrite(dir2PinA, LOW); digitalWrite(dir1PinB, HIGH); digitalWrite(dir2PinB, LOW); } void back() { digitalWrite(dir1PinA, LOW); digitalWrite(dir2PinA, HIGH); digitalWrite(dir1PinB, LOW); digitalWrite(dir2PinB, HIGH); } void stop_dc() { analogWrite(speedPinA,0); analogWrite(speedPinB,0); // digitalWrite(dir1PinA, LOW); // digitalWrite(dir2PinA, LOW); // digitalWrite(dir1PinB, LOW); // digitalWrite(dir2PinB, LOW); } void left() { digitalWrite(dir1PinA, HIGH); digitalWrite(dir2PinA, LOW); digitalWrite(dir1PinB, LOW); digitalWrite(dir2PinB, HIGH); } void rigth() { digitalWrite(dir1PinA, LOW); digitalWrite(dir2PinA, HIGH); digitalWrite(dir1PinB, HIGH); digitalWrite(dir2PinB, LOW); } void loop() { //delay(1000); analogWrite(speedPinA,speed); analogWrite(speedPinB,speed); // set direction if (1 == dir) { forward(); } else if (0 == dir) { back(); } else if (2 == dir) { left(); } else if (3 == dir) { rigth(); } if (millis() - time > 5000) { time = millis(); speed += 20; if (speed > 255) { speed = 0; } } front_distance=ultrasonic.Ranging(CM); // получаем расстояние до объекта в сантиметрах Serial.write("FRONT: "); Serial.println(front_distance); // print the distance if ((front_distance<=30) && (front_distance!=0)) { Serial.write("SPEED: "); Serial.println(speed); stop_dc(); // останавливаем робота myservo.write(0); // ставим сервопривод смотрящим влево delay(500); left_distance=ultrasonic.Ranging(CM); // получаем расстояние до объекта в сантиметрах //delay(30); Serial.write("LEFT: "); Serial.println(left_distance); // print the distance myservo.write(180); // ставим сервопривод смотрящим влево delay(500); rigth_distance=ultrasonic.Ranging(CM); // получаем расстояние до объекта в сантиметрах //delay(30); Serial.write("RIGTH: "); Serial.println(rigth_distance); // print the distance myservo.write(90); // ставим сервопривод смотрящим вперед delay(500); if (left_distance>rigth_distance) { Serial.println("TURN_LEFT START"); left(); //поворачиваем влево delay(1000); stop_dc(); // останавливаем робота dir=1; // едем прямо Serial.println("TURN_LEFT STOP"); }else { Serial.println("TURN_RIGTH START"); rigth(); //поворачиваем влево delay(1000); stop_dc(); // останавливаем робота dir=1; // едем прямо Serial.println("TURN_RIGTH STOP"); } } }
Так почему бы не соеденить 10 вывод с любым другим ШИМ выводом?
Так почему бы не соеденить 10 вывод с любым другим ШИМ выводом?
Я же не против соеденить, только как?
При настройке бибилиотек или создании классов "соединение" уже прописано в коде, у меня почемуто возникает конфликт и понять что не так делаю не получается.
Еще забыл написать, что в текущей ситуации можно включить DC двигатели на максимум оборотов или выключить совсем, например вот так:
Т.е. не рабтаешь ШИМ регулирование оборотов на motor shield V3 и пины на неё переназначить нельзя.
Не программно соединить, а физически - проводами. Соединяете проводами 6 вывод с 10 выводом и 5 с 9. Переподключаете сонар на другие выводы.
Есть конечно и программные решения, но они более сложные и не желательные:
1. Найти (или написать) библиотеку типа Servo для 8-ми битного таймера - что снизит точность позиционирования сервы.
2. Сгенерить программный ШИМ на другом таймере - что тоже не есть хорошо ,так как такой ШИМ на больших частотах съедает очень много процессорного времени - http://arduino.ru/forum/programmirovanie/analogwrite-na-lyubom-vyvode данная либа использует TIMER2 и не конфликтует с библиотекой Servo.
Есть конечно и программные решения, но они более сложные и не желательные:
1. Найти (или написать) библиотеку типа Servo для 8-ми битного таймера - что снизит точность позиционирования сервы.
2. Сгенерить программный ШИМ на другом таймере - что тоже не есть хорошо ,так как такой ШИМ на больших частотах съедает очень много процессорного времени - http://arduino.ru/forum/programmirovanie/analogwrite-na-lyubom-vyvode данная либа использует TIMER2 и не конфликтует с библиотекой Servo.
в wiring_analog.c для функции analogWrite используется функция digitalPinToTimer(pin), где посомтреть её код и что она делает?
Для servo.h нашел запуск таймера timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
а вот для управления моторами через analogWrite где поискать какой таймер используется?
Не программно соединить, а физически - проводами. Соединяете проводами 6 вывод с 10 выводом и 5 с 9. Переподключаете сонар на другие выводы.
Пины перекомутировал, в результате заработало, но осталось 3 цифровых порта, энкодеры на 4 колеса или компас уже не подключить.
Если вы не знали, то на Uno все аналоговые выводы могут работать как цифровые, и более того компасы обычно общаются по I2C.
Если вы не знали, то на Uno все аналоговые выводы могут работать как цифровые, и более того компасы обычно общаются по I2C.
С этим разобрался. Остается вопрос по теме: как понять какие ШИМ на каких пинах работают от каких таймеров?
Чтобы больше на такие грабли не наступать.
http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry
У mega328 такая же последовательность подключения к arduino, т.е. слева на право, сверху в низ?
ATmega48, ATmega88, ATmega168, ATmega328 - суть одна и та же модель микроконтроллера. Отличаются друг от друга они лишь размером Flash/EEPROM/RAM. Отличия в распиновке - по вполне естественной причине - имеются между различными вариантами корпусов: DIP28/MLF28/MLF32/TQFP32.
Так что для DIP-корпуса ответом будет - да.
Последний вопрос, но не в тему: как правльнее отпределить, что робот повернулся на нужный угол, беря в расчет разнородность поверхности и возможность проскальзывания/стопора колес?
Энкодеры на всех четырех колесах не дадут нужного результата, так как колеса проскалзывают или наоборот стопорятся.
Почитал про компас (HMC5883L), пишут что не хватит разрешение и позицировать компас нужно строго вертикально.
GPS не предлагать, робот только для дома.
Последний вопрос, но не в тему: как правльнее отпределить, что робот повернулся на нужный угол, беря в расчет разнородность поверхности и возможность проскальзывания/стопора колес?
гироскоп
Последний вопрос, но не в тему: как правльнее отпределить, что робот повернулся на нужный угол, беря в расчет разнородность поверхности и возможность проскальзывания/стопора колес?
гироскоп
Одного гироскопа будет недостаточно. Скинте почитать если есть соответствующие топики, желательно с отлаженой реализацией.
Вот уж, нет - тыкайте палкой дохлого админа сего форума, пусть делает нормальный поиск... или
https://www.google.com/search?hl=ru&q=arduino+%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D1%8F+%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0+%D0%B2+%D0%BF%D1%80%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D1%81%D1%82%D0%B2%D0%B5
Вот уж, нет - тыкайте палкой дохлого админа сего форума, пусть делает нормальный поиск... или
https://www.google.com/search?hl=ru&q=arduino+%D0%BE%D1%80%D0%B8%D0%B5%D0%BD%D1%82%D0%B0%D1%86%D0%B8%D1%8F+%D0%BE%D0%B1%D1%8A%D0%B5%D0%BA%D1%82%D0%B0+%D0%B2+%D0%BF%D1%80%D0%BE%D1%81%D1%82%D1%80%D0%B0%D0%BD%D1%81%D1%82%D0%B2%D0%B5
ок. на этом форуме и такой гуг я уже читал.
Добрый день! Наткнулся на эту тему. У меня проблема с тем же оборудованием - Серво и мотор шилд.
Я убрал шилд с ардуинки УНО, кинул на него 8, 11, 12, 13 пины на двигатели, а шим взял с 3 и 5 пина. Еще перебросил землю.
Запитал Уно и шилд параллельно с аккумуляторов 7,2 В.
Двигатели заработали нормально, а вот серва глючит - уперлась в крайнее положение 180 и стоит.
Причем, в отдельных скетчах все нормально.
Вот отдельный скетч для сервы:
В скетче с двигателями (использована библиотека #include "MotorDriver.h") все работает до и после слияния.
Когда соединяю, серва нервно дергается и сразу падает в сторону 180 градусов, после этого стоит. После перезагрузки не шевелится. Загружаю отдельный скетч для нее - работает.
Что тут может быть? Мотор шилд же не работает с таймером 1 напрямую? Ему только шим нужен.
Да, серва у меня 120 градусная, диапазон управления 900- 2100мкс указан верный, думаю ничего страшного, если ей программно задаются углы более 120 градусов, библиотека Серво все равно же пересчитывает диапазоны.