Вообщем пытался написать код управления моторами.Но запутался. 1 мотор вкл в лево и потом сразо в право. Код (Text): int ldrlt = 0; //LDR top left int ldrrt = 1; //LDR top rigt int ldrld = 2; //LDR down left int ldrrd = 3; //ldr down rigt int i; void setup() { Serial.begin(9600); pinMode (9, OUTPUT); //enable 1 pinMode (8, OUTPUT); //input 1| 1motor pinMode (7, OUTPUT); //input 2| 1motor pinMode (6, OUTPUT); //enable 2 pinMode (4, OUTPUT); //input 3| 2motor pinMode (2, OUTPUT); //input 4| 2 motor delay (2000); } void loop() { int lt = analogRead(ldrlt); // top left int rt = analogRead(ldrrt); // top right int ld = analogRead(ldrld); // down left int rd = analogRead(ldrrd); // down rigt int avt = (lt + rt) / 2; // average value top int avd = (ld + rd) / 2; // average value down int avl = (lt + ld) / 2; // average value left int avr = (rt + rd) / 2; // average value right { if (avt < avd) //сравнение значений верх низ { if ((avt-avd)<15 ) //РАзница и промежуток 15 { delay(200); } else { digitalWrite (4, LOW); // digitalWrite (2, HIGH); // ЗАПУСК 2 МОТОРА В ПРАВО for (i = 50; i <= 100; ++i)// { // analogWrite(6, i); // delay(30); // } // analogWrite (6, 0); // } } else { digitalWrite (4, HIGH); // digitalWrite (2, LOW); // for (i = 50; i <= 100; ++i)// ЗАПУСК 2 МОТРА В ЛЕВО { // analogWrite(6, i); // delay(30); // } // analogWrite (9, 0); // } { if (avl > avr) //сравнение значений лево право { if ((avl-avr)<15 )//РАзница и промежуток 15 { delay(200); } else { digitalWrite (8, HIGH); // digitalWrite (7, LOW); // for (i = 50; i <= 180; ++i)// { // analogWrite(9, i); // ЗАПУСК 1 МОТОРА В ПРАВО delay(30); // } // analogWrite (9, 0); // } } else { digitalWrite (8, LOW); // digitalWrite (7, HIGH); // for (i = 50; i <= 100; ++i) // { // analogWrite(9, i); // ЗАПУСК 2 МОТОРА В ЛЕВО delay(30); // } // analogWrite (9, 0); // } // delay(500); // }}}
Возможно проблема в этом куске ? Код (Text): for (i = 50; i <= 100; ++i)// ЗАПУСК 2 МОТРА В ЛЕВО { // analogWrite(6, i); // delay(30); // } // analogWrite (9, 0); // В частности место analogWrite (9, 0); Как я заметил, у вас в коде, этот кусок повторяется 4 раза и в каждому куске в обоих функциях вы используется одинаковый номер пина, а тут получилось иначе в одной функции 6 а в следующей 9. Так же дальше в коде есть такая строка: for (i = 50; i <= 180; ++i) Опять же везде у вас используется 100 а тут 180, возможно тут тоже есть ошибка а может так и задумано. Вообще у вас много повторяющихся кусков, задумайтесь о вынесении повторяющегося кода в отдельные функции, это сделает код более читабельным, понятным и сократит шансы на ошибки.
Давайте попробуем избавиться от "магических" чисел в программе. Читать код и постоянно помнить, что к какой ножке подключено - не есть хорошо. Заведите константы с понятными именами. Например: MOTOR1_EN, MOTOR1_IN1, MOTOR1_IN2. Не стремитесь к излишним сокращениям и аббревиатурам, понятным только Вам. Через 2 месяца откроете код и не вспомните, кто там что обозначает. Сокращать нужно код, а длина имен переменных к длине кода никакого отношения не имеет, для компилятора любая переменная - адрес ячейки памяти, это мы для себя имена пишем. Советую прислушаться и принять данный совет за правило. Еще и память более эффективно использовать станете за счет вызова функций
Сделаем.совет ваш нужен как лучше мотором управлять?может у вас есть готовые решения? библиотеки?или лучше выбранным методом делать.Просто если не ставить плавный набор скорости.то повороты дерганные получаются. Да и почему то после выполнения условия поворота в лево сразо же поворачивается в право.мотор пищит
Делайте частями. Напишите функцию, которая поворачивает один мотор с заданной скоростью на заданный угол. Если функция будет работать правильно, оставьте ее в покое и начинайте заниматься следующим куском - реакцией на датчики. А что за устройство у Вас? Какие датчики? Может, алгоритм изначально неверно составлен?
У меня была проблема с писком/гудением моторов. Проблема у меня была в том что шилда подавала мало напряжения на мотор. К примеру шилда принимает значения от 0 до 255 из которого она определяет какое напряжение будет подано на мотор от 0В (0) до максимума (255). К примеру к шилде подключено 6В питания для моторов, мы вписываем значение в пин скажем 100 это даже меньше 50% отсюда на мотор будет подано около 2В .. что маловато и мотор может вообще не крутится в зависимости от нагрузки на него а только гудеть. Таким образом моя платформа только трогаться начинала когда в пин попадало значение 120 из 255 возможных. Все что было ниже 120 было гудение и никакой движухи. Если я подавал питание для моторов в 9В ... тогда платформа начинала шевелится уже с 90 значения на пине. Таким образом вам надо определиться в зависимости от питания и нагрузки на моторы минимальное значение для пина когда мотор начинает шевелится, его принять за начальное значения для движения а промежуток от этого значения до 255 к примеру и будет тем промежутком в котором вы будите регулировать скорость поворота. Ну а НОЛЬ он всегда НОЛь, нулем будите делать СТОП.
Не стал создавать новую тему.Подскажите пожалуйста как лучше сделать этот кусок кода с условиями. ато уменя условия дальше if ((avl-avr)<15 ) не проходят( Код (Text): { if (avl > avr) { if ((avl-avr)<15 ) { delay(200); } else { digitalWrite(en2, HIGH); // turn the en1 on (HIGH is the voltage level) robot.motor_forward(2,150); // 1 вперёд :) delay(30); // wait for a second digitalWrite(en2, LOW); // turn the en1 off by making the voltage L } } else { digitalWrite(en2, HIGH); // turn the en1 on (HIGH is the voltage level) robot.motor_back(2,150); // delay(30); // wait for a second digitalWrite(en2, LOW); // turn the en1 off by making the voltage LO } delay(500);
Код (Text): if(avl > avr) { Serial.println("avl > avr: YES"); ... } else { Serial.println("avl > avr: NO"); ... } И далее в том же духе... Останется только проанализировать ход выполнения программы и сравнить с желаемым.
Все время avl- avr<20: YES HTML: #include <robocraft.h> MOTOR MOTOR1 = { 3, 4, 1 }; MOTOR MOTOR2 = { 7, 8, 2}; int ldrlt = 4; //LDR top left int ldrrt = 1; //LDR top rigt int ldrld = 2; //LDR down left int ldrrd = 3; //ldr down rigt int en1 = 6; int en2 = 7; void setup() { Serial.begin(9600); pinMode(en1, OUTPUT); pinMode(en2, OUTPUT); } RoboCraft robot(&MOTOR1, &MOTOR2); void loop() { int lt = analogRead(ldrlt); // top left int rt = analogRead(ldrrt); // top right int ld = analogRead(ldrld); // down left int rd = analogRead(ldrrd); // down rigt lt=lt/3; int avt = (lt + rt) / 2; // average value top int avd = (ld + rd) / 2; // average value down int avl = (lt + ld) / 2; // average value left int avr = (rt + rd) / 2; // average value right int dvert = avt - avd; // check the diffirence of up and down int dhoriz = avl - avr;// check the diffirence og left and rigt { if (avt < avd) { if ((avt-avd)<20 ) { Serial.println("avl- avr<20: YES"); } else { digitalWrite(en1, HIGH); // turn the en1 on (HIGH is the voltage level) robot.motor_back(1,250); // 1 вперёд :) delay(40); // wait for a second digitalWrite(en1, LOW); // turn the en1 off by making the voltage LO Serial.println("avl < avr: YES"); } } else { digitalWrite(en1, HIGH); // turn the en1 on (HIGH is the voltage level) robot.motor_forward(1,250); // delay(40); // wait for a second digitalWrite(en1, LOW); // turn the en1 off by making the voltage Serial.println("avl < avr: NO"); } } }
Если avt < avd, то, вычитая из меньшего большее, всегда получим отрицательную величину, поэтому оно всегда будет меньше, чем 20. Код работает правильно, неправильно составлен алгоритм. Почему бы не дать переменным более читаемые имена? topLeft, topRight, bottomLeft, bottomRight, averageTop, averageBottom, averageLeft, averageRight - код будет читаться гораздо легче, по крайней мере на мой взгляд Есть поговорка: "хорошо написанный код в комментариях не нуждается". Она, конечно, весьма спорна, но зерно истины в ней определенно есть.
Если верх освещен больше, чем низ, то поворачивать вверх. Если право право освещено больше, чем лево, то поворачивать вправо. Код (Text): if((top > bottom) && ((top - bottom) > 20) // повернуть вверх; if((left > right) && ((left - right) > 20) // повернуть влево; Так должно работать?