Есть несколько вопросов по коду.
- Войдите на сайт для отправки комментариев
Здравствуйте! Хочу сделать робота, объезжающего препятствия исходя из покааний двух фиксированных УЗ дальномеров + возможность управления с джойстика. Привожу далее код целиком, затем выделю отдельно куски с вопросами.
Полный:
#define fwd {digitalWrite(7, 0); analogWrite(6, 255); digitalWrite(2, 0); analogWrite(3, 255);} // полный вперёд #define fl {digitalWrite(7, 0); analogWrite(6, 127); digitalWrite(2, 0); analogWrite(3, 255);} // поворот налево #define fr {digitalWrite(7, 0); analogWrite(6, 255); digitalWrite(2, 0); analogWrite(3, 127);} // поворот направо #define rl {digitalWrite(7, 1); analogWrite(6, 127); digitalWrite(2, 0); analogWrite(3, 127);} // разворот налево #define rr {digitalWrite(7, 0); analogWrite(6, 127); digitalWrite(2, 1); analogWrite(3, 127);} // разворот направо #define stp {digitalWrite(7, 0); analogWrite(6, 0); digitalWrite(2, 0); analogWrite(3, 0);} // стоп int Um1 = A3; // задаём пин измерения напряжения int Um2 = A2; // задаём пин измерения напряжения int ledPin = 10; //задаём пин со светодиодом int LSpot = A0; // пин среднего отвода потенциометра левого стика int RSpot = A1; // пин среднего отвода потенциометра правого стика int LS; // переменная для хранения значения положения левого стика int RS; // переменная для хранения значения положения правого стика int LMpwm; // значение ШИМ для левого мотора(положительное заполнение для "вперёд") int LMfwd; // значение определяющее обратное врещение(0=вперёд,1=реверс) левого мотора int RMpwm; // значение ШИМ для правого мотора(положительное заполнение для "вперёд") int RMfwd; // значение определяющее обратное врещение(0=вперёд,1=реверс) правого мотора int Apilot = 4; // пин кнопки автопилот(замыкаем на землю и автопилот вкл) const int ltrig = 12; // левый тригер const int lecho = 11; // левое эхо const int rtrig = 9; // правый тригер const int recho = 8; // правое эхо unsigned int ldist=0; // тут храним левую дистанцию в см unsigned int rdist=0; // тут храним правую дистанцию в см double mnog1; // делитель напряжения первой банки(после, заменить числом в расчёте) double mnog2; // делитель напряжения второй банки(после, заменить числом в расчёте) void setup() { pinMode(ltrig, OUTPUT); // указываем что является вводом, а что выводом сигналов pinMode(lecho, INPUT); pinMode(rtrig, OUTPUT); pinMode(recho, INPUT); pinMode(Apilot, INPUT); digitalWrite(Apilot, HIGH); // включаем поддяжку кнопки автопилот ldist=leftUS(); // первичный опрос УЗ дальномеров(левый) rdist=rightUS(); // первичный опрос УЗ дальномеров(правый) pinMode(ledPin, OUTPUT); // указываем режим работы пина светодиода-индикатора } void loop() { switch(digitalRead(Apilot)) // считываем положение кнопки автопилот и ветвим программу { case 1: // если кнопка автопилот выключена LS = analogRead(LSpot); // считываем значение напряжения с левого стика if(LS>591 || LS<431) // если левый стик вышел из dead-зоны { LMpwm = map(LS, 591, 1023, 50, 255); // если наклон вперёд, то присваиваем положительное заполнение ШИМ левого мотора LMpwm = map(LS, 0, 431, 0, 205); // если наклон назад, то присваиваем отрицательное заполнение ШИМ левого мотора LMfwd = map(LS, 0, 1023, 1, 0); // выставляем направление вращения левого мотора в зависимости от наклона л.стика } else{ LMpwm = 0; // иначе останавливаем LMfwd = 0; // иначе останавливаем } RS = analogRead(RSpot); // считываем значение напряжения с правого стика if(RS>591 || RS<431) // если правый стик вышел из dead-зоны { RMpwm = map(RS, 591, 1023, 50, 255); // если наклон вперёд, то присваиваем положительное заполнение ШИМ правого мотора RMpwm = map(RS, 0, 431, 0, 205); // если наклон назад, то присваиваем отрицательное заполнение ШИМ правого мотора RMfwd = map(RS, 0, 1023, 1, 0); // выставляем направление вращения левого мотора в зависимости от наклона п.стика } else{ RMpwm = 0; // иначе останавливаем RMfwd = 0; // иначе останавливаем } analogWrite(6, LMpwm); // задаём значение ШИМ вывода для левого двигателя digitalWrite(7, LMfwd); // задаём напрявление вращение для левого двигателя analogWrite(3, RMpwm); // задаём значение ШИМ вывода для правого двигателя digitalWrite(2, RMfwd); // задаём напрявление вращение для правого двигателя voltage(); // обращаемся к функции, возвращающей минимальное напряжение акб case 0: // если кнопка автопилот включена(на землю) while(ldist>=15 && rdist >= 15) // если места впереди >15см по обоим дальномерам { fwd; // едем вперёд ldist=leftUS(); // переспрашиваем датчик левый rdist=rightUS(); // переспрашиваем датчик правый } while(ldist>=15 && rdist<15 && rdist >10) // если слева >15см, а справа от 10 до 15 { fl; // уплываем влево ldist=leftUS(); // переспрашиваем датчик левый rdist=rightUS(); // переспрашиваем датчик правый } while(rdist>=15 && ldist<15 && ldist>10) // если справа >15см, а слева от 10 до 15 { fr; // уплываем вправо ldist=leftUS(); // переспрашиваем датчик левый rdist=rightUS(); // переспрашиваем датчик правый } while(ldist<15 && rdist<15 && ldist>5 && rdist>5 && (ldist<rdist)) // если по обоим датчикам от 5 до 15, при этом справа больше { rr; // разворачиваемся на месте направо ldist=leftUS(); // переспрашиваем датчик левый rdist=rightUS(); // переспрашиваем датчик правый } while(ldist<15 && rdist<15 && ldist>5 && rdist>5 && (ldist>rdist)) // если по обоим датчикам от 5 до 15, при этом слева больше { rl; // разворачиваемся на месте налево ldist=leftUS(); // переспрашиваем датчик левый rdist=rightUS(); // переспрашиваем датчик правый } while(ldist<=5 || rdist<=5) // если оба дальномера показывают <=5см { stp; // стоим и ждём помощи ldist=leftUS(); // переспрашиваем датчик левый rdist=rightUS(); // переспрашиваем датчик правый digitalWrite(ledPin, HIGH); // включаем сд } voltage(); // обращаемся к функции, возвращающей минимальное напряжение акб } } int leftUS() // функция возвращающая дистанцию по левому дальномеру в см { unsigned int lechot; // тут храним время левого эхо digitalWrite(ltrig, HIGH); // включаем левый тригер delayMicroseconds(10); // ждём 10 микросекунд digitalWrite(ltrig, LOW); // выключаем левый тригер lechot=pulseIn(lecho, HIGH); // считаем время импульса по левому эхо ldist=lechot/58; // получаем расстояние слева в см return ldist; // возвращаем значение в см левого датчика } int rightUS() // функция возвращающая дистанцию по правому дальномеру в см { unsigned int rechot=0; // тут храним время правого эхо digitalWrite(rtrig, HIGH); // включаем правый тригер delayMicroseconds(10); // ждём 10 микросекунд digitalWrite(rtrig, LOW); // выключаем правый тригер rechot=pulseIn(recho, HIGH); // считаем время импульса по правому эхо rdist=rechot/58; // получаем расстояние справа в см return rdist; // возвращаем значение в см правого датчика } void voltage() // функция, возвращающая минимальное напряжение на акб { double U, U1, U2; // вводим локальные переменные напряжений U1=analogRead(Um1)/mnog1; // вычисляем реальное значение напряжения первой банки U2=analogRead(Um2)/mnog2-U1; // вычисляем реальное значение напряжения второй банки U=min(U1,U2); // присваиваем минимальное значение if(U<3.2) // если напряжение в нагрузке меньше 3.2 вольт на какую либо банку { digitalWrite(ledPin, HIGH); // включаем сд if(U<3) // если напряжение в нагрузке меньше 3 вольт на какую либо банку { batterylow : // метка для зацикливания digitalWrite(ledPin, LOW); // выключаем светодиод stp; // останавливаем движки delay(500); // ждём пол секунды digitalWrite(ledPin, HIGH); // снова включаем сд delay(500); // снова ждём { goto batterylow; // входим в бесконечный цикл } } } }
Вопросы и куски:
1) Возможно ли использовать такую форму записи и далее так обращаться к ней для исполнения? Определяю направление движения, робот управляется двумя моторчиками по два провода на каждый. Один провод под шим, другой под задание направления движения(Я понимаю, что при смене направления у меня будет инверсироваться ШИМ сигнал).
#define fwd {digitalWrite(7, 0); analogWrite(6, 255); digitalWrite(2, 0); analogWrite(3, 255);} // полный вперёд fwd; // едем вперёд
2) Можно ли кидать несколько условий мапинга на одно значение, притом, что значение будет выходить за границы условия мапинга(ерунду написал какую-то..)
RMpwm = map(RS, 591, 1023, 50, 255); // если наклон вперёд, то присваиваем положительное заполнение ШИМ правого мотора RMpwm = map(RS, 0, 431, 0, 205); // если наклон назад, то присваиваем отрицательное заполнение ШИМ правого мотора RMfwd = map(RS, 0, 1023, 1, 0); // выставляем направление вращения левого мотора в зависимости от наклона п.стика
3) Можно ли вообще писать такое сложное условие?
while(ldist<15 && rdist<15 && ldist>5 && rdist>5 && (ldist<rdist)) // если по обоим датчикам от 5 до 15, при этом справа больше
4)Обращение к ножкам arduino uno. К аналоговым я обращаюсь как A1(например), к цифровым как 3 или, скажем 5.
int Um1 = A3; // задаём пин измерения напряжения analogWrite(3, RMpwm); // задаём значение ШИМ вывода для правого двигателя
1) Возможно ли использовать такую форму записи и далее так обращаться к ней для исполнения? Определяю направление движения, робот управляется двумя моторчиками по два провода на каждый. Один провод под шим, другой под задание направления движения(Я понимаю, что при смене направления у меня будет инверсироваться ШИМ сигнал).
Можно, но вместо fwd лучше писат FWD (просто полезное соглашение, чтобы дефайны легко отличались на взгляд от недефайнов.)
Хотя вместо
#define action {something; something_else;}
Чаще встречатеся форма
#define action do{something; something_else;} while(0);
Правда, примера, где разница окажется важной, я навскидку не придумал.
3) Можно ли вообще писать такое сложное условие?
Можно, но с целью минимизации возможных ошибок все скобки лучше расставить явно, дабы в случае чего не оказалось, что у компилятора и у программиста разные представления о приоритете вычесления конкретного выражения.
4)Обращение к ножкам arduino uno. К аналоговым я обращаюсь как A1(например), к цифровым как 3 или, скажем 5.
Форма обозначения пина A1 - это не более, чем дефайн, определенный в arduino.h (точнее в платвормозависимых файлах, подклучаемых из нее). Так что так обращаться можно, хотя опять же создает поле для ошибок. Как по мне, так лучше все пины указывать цифрами в начале скетча в виде
(цифра "15" взята "от балды", если что)
Спасибо!
Это первая моя программа, да и ардуина ещё не пришла, поэтому и вопросы на уровне будет ли работать, т.к проверить не могу.