У вас переменная position объявлена, но ей нигде не присваивается значение. Зачем ее выводить в монитор и зачем она вообще нужна? Ваш код никогда ничего не выведет в порт, если в каждом проходе цикла будет срабатывать оператор continue. Отладочный вывод нужно писать так, чтобы в монитор выводилась информация из всх мест программы, в которых может измениться ход ее выполнения. Вот это запустите: Код (C++): #include <Servo.h> #define MOTOR_PIN 9 #define FIRST_BUTTON_PIN 5 #define BUTTON_COUNT 3 #define SPEED_STEP (255 / (BUTTON_COUNT - 1)) Servo myServo; void setup() { Serial.begin(9600); pinMode(MOTOR_PIN, OUTPUT); for (int i = 0; i < BUTTON_COUNT; ++i) pinMode(i + FIRST_BUTTON_PIN, INPUT_PULLUP); myServo.attach(11); } void loop() { Serial.println("for"); for (int i = 0; i < BUTTON_COUNT; ++i) { Serial.print("i="); Serial.println(i); if (digitalRead(i + FIRST_BUTTON_PIN)) { Serial.print("continue"); continue; } int speed = i * SPEED_STEP; analogWrite(MOTOR_PIN, speed); Serial.print("speed="); Serial.println(speed); } Serial.println("end for"); myServo.write(90); delay(150); myServo.write(0); delay(5000); }
Вот что он пишет: Код (Text): i=0 continuei=1 continuei=2 continueend for for i=0 continuei=1 continuei=2 speed=254 end for
Если почитать программу, то получается, что в теории при нажатии на кнопку, подключенную к пину 5, мотор должен останавливаться (скорость 0), при нажатии на кнопку, подключенную к пину 6, должен вращаться (при условии, что характеристики мотора позволяют ему стронуться с места при уровне 128 для ШИМ), а при нажатии на кнопку, подключенную к пину 7, должен вращаться еще шустрее. Но на практике вероятность попадания самого факта нажатия на кнопку на тот момент, когда она опрашивается, весьма невелика, поскольку большую часть времени (больше 5 секунд) программа проводит в ожидании на вызовах delay. Вариантов, чтобы мотор в конце концов закрутился (при условии правильной физической сборки конструкции, в смысле, если все подключено как надо), получается два. Или зажать кнопку секунд на шесть, дабы гарантированно совпали проверка кнопки и ее нажатость, или выкинуть delay, Если будет принято решение выкинуть delay. Поскольку на delay завязано поведение сервы, то при простом выкидывании означенных delay серва практически не будет отрабатывать. Разве что нервно дергаться (если вообще успеет отреагировать на столь быстрые изменения). Потому, если желательно сохранить поведение сервы, придется не просто выкинуть delay, а перевести выполнение задержки на использование вызовов millis, дабы сравнивать текущее значение, возвращаемое этой функцией, с тем, что засекли при предыдущем дергании сервы.
Если была такая строка в мониторе последовательного порта, и не было строки speed=0, а двигатель не заработал, то проблема где-то в сборке конструкции. Либо мотор подключен не к девятому пину (исходя из кода требуется подключать именно к нему), либо мотор подключен как-то неправильно. Правильное подключение предусматривает подключение не мотора напрямую, а использование какого-нибудь промежуточного управляющего устройства, например, полевого транзистора или драйвера мотора с соответствующей обвязкой (защитные диоды, конденсаторы, резисторы, дабы ничего не спалить ненароком).
Я так понял должно получиться что-то вроде этого: Код (Text): myServo.write(90); millis(); myServo.write(0); delay(5000);
Еще раз просмотрел монитор последовательного порта и обнаружил, что если нажать кнопку в момент поворачивания сервопривода печатает скорость. Вот то, что он пишет. Код (Text): for i=0 continuei=1 speed=127 i=2 continueend for for i=0 speed=0 i=1 continuei=2 continueend for for i=0 continuei=1 continuei=2 speed=254 end for
А вы понимаете, как ваш код вообще работает? Какие операторы в каких условиях будут выполняться и почему?
Совсем не так. Можно, например, примерно так (писалось теоретически, возможны ошибки и опечатки): Код (Text): static int servo0=2; //2 - неопределенное состояние, 0 - серва на 90, 1 - серва на 0 stftic unsigned long int servotime; // последнее время поворота сервы if (servo0) { // когда серва на 0 градусов или в неопределенном состоянии (когда флаг не 0) if ((servo0==2)||((millis()-servotime)>5000)) // если неопределенное состояние (первый раз) или если прошло 5 с после поворота на 0 { servotime=millis(); // фиксируем время поворота myServo.write(90); // поворачиваем servo0=0; // устанавливаем состояние серва на 90 } } else { // когда серва на 90 грудусов if ((millis()-servotime)>150)) // если если прошло 150 мс после поворота на 90 { servotime=millis(); // фиксируем время поворота myServo.write(0); // поворачиваем servo0=1; // устанавливаем состояние серва на 0 } }
Физическая коммутация на фото вроде верная (навскидку, глубоко не вникал, мог и пропустить что-нибудь),
Получилось у меня, вот что: Код (Text): #include <Servo.h> #define MOTOR_PIN 9 #define FIRST_BUTTON_PIN 5 #define BUTTON_COUNT 3 #define SPEED_STEP (255 / (BUTTON_COUNT - 1)) Servo myServo; void setup() { pinMode(MOTOR_PIN, OUTPUT); for (int i = 0; i < BUTTON_COUNT; ++i) pinMode(i + FIRST_BUTTON_PIN, INPUT_PULLUP); { Serial.begin(9600); } myServo.attach(11); } void loop() { int position; for (int i = 0; i < BUTTON_COUNT; ++i) { if (digitalRead(i + FIRST_BUTTON_PIN)) continue; int speed = i * SPEED_STEP; analogWrite(MOTOR_PIN, speed); } { static int servo0=2; static unsigned long int servotime; if (servo0) { if ((servo0==2)||((millis()-servotime)>5000)) { servotime=millis(); myServo.write(90); servo0=0; } } else { // когда серва на 90 грудусов if ((millis()-servotime)>150) { servotime=millis(); myServo.write(0); servo0=1; } } } } Я понял, что нужно сделать немного по другому ,так как при нажатии кнопки двигается сервопривод на положение 0, вместо кручения мотора.