Управление шаговым двигателем
- Войдите на сайт для отправки комментариев
Пт, 19/07/2013 - 14:52
Управляю шаговиком с помощью трёх кнопок (лево, стоп, право) , библиотека AccelStepper. Проблем нет. Ввёл в пограмму lcd и меню для изменения параметров движения и сразу возникли тормоза - скорость упала в разы. Как то можно решить подобную проблему? Может вывести дисплей и меню из loop в отдельную функцию и потом вызывать?
Как то можно решить подобную проблему?
Можно, но только как-то и никак по-другому.
Может вывести дисплей и меню из loop в отдельную функцию и потом вызывать?
Да может, например, послезавтра вызвать, тогда точно до послезавтра тормозов не будет и скорость у двигателя нормальная будет.
Вы вроде не первый день на форуме...
Вы вроде не первый день на форуме...
maksim, я не программист и просто не знаю куда рыть дальше. Вот и прошу подсказки. Что lcd 16x2 тормозит шаговый двигатель я прочитал. Примеров "борьбы" с этим не нашёл.
Я к тому что здесь по прежнему нет экстрасенсов и без кода обсуждать нечего.
void setup() { stepper.setMaxSpeed(1600); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); } void loop() { if(ButtonLeftState == HIGH ) { stepper.setSpeed(1000); stepper.setAcceleration(500); stepper.moveTo(64000L); } else if(ButtonRightState == HIGH ) { stepper.setSpeed(500); stepper.setAcceleration(500); stepper.moveTo(-64000L); } else if(ButtonStopState == HIGH ) { stepper.stop(); } stepper.run(); }С таким кодом крутится шустро
void setup() { stepper.setMaxSpeed(1600); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); lcd.begin(16, 2); lcd.clear(); } void loop() { lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); if(ButtonLPinLeft == HIGH ) { stepper.setSpeed(1000); stepper.setAcceleration(500); stepper.move(64000L); } else if(ButtonPinRight) { stepper.setSpeed(500); stepper.setAcceleration(300); stepper.move(-64000L); } else if(ButtonPinStop == HIGH ) { stepper.stop(); } stepper.run(); }Теперь тормоза
Что за переменные valM, valSPEED, valACCEL ??? код весь покажите.
valM режим микрошага- ещё не реализовал.
valSPEED и valACCEL скорость и ускорение шагового двигателя , будут регулироваться в меню ( в процессе разработки).
Тогда выводите данные на дисплей только при их изменении
void loop() { static long sumPrev; if((valM^valSPEED^valACCEL) != sumPrev) { sumPrev = valM^valSPEED^valACCEL; lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } if(ButtonLPinLeft == HIGH ) { stepper.setSpeed(1000); stepper.setAcceleration(500); stepper.move(64000L); } else if(ButtonPinRight) { stepper.setSpeed(500); stepper.setAcceleration(300); stepper.move(-64000L); } else if(ButtonPinStop == HIGH ) { stepper.stop(); } stepper.run(); }Спасибо. Сейчас попробую.
А как тогда работать с меню?
Не знаю, не вижу никакого меню.
Код выводит на дисплей всю нужную мне информацию, но тормозит двигатель
void setup() { stepper.setMaxSpeed(1000); pinMode(ButtonPinMode, INPUT); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); lcd.begin(16, 2); lcd.clear(); A = 5; lastbutton = 0; } void loop() { if (A == 5) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } else if (A == 6) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M < Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } else if (A == 7) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M > Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } else if (A == 10) /// SpeedMenu() { lcd.setCursor(0,0); lcd.print("SPEED "); lcd.setCursor(9,0); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } else if (A == 15) /// RampMenu() { lcd.setCursor(0,0); lcd.print("RAMP "); lcd.setCursor(9,0); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } //////////////////////////////////////////// МОТОР if(ButtonLeftState == HIGH && A == 5) { A = 6; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(64000L); lastbutton = 1; } else if(ButtonRightState == HIGH && A == 5) { A = 7; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(-64000L); lastbutton = 2; } else if(ButtonStopState == HIGH && ( A == 6 || A == 7)) { A = 5; stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// МЕНЮ if(ButtonModeState==HIGH ) { if((A == 5) || (A == 10)) { A = A + 5; } else if(A == 15){ A = 10; } } else if(ButtonLeftState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED--; if(valSPEED <= 0) { valSPEED = 0; } } else if((A == 15)) { valACCEL--; if(valACCEL <= 0) { valACCEL = 0; } } } else if(ButtonRightState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED++; if(valSPEED >= 100) { valSPEED = 100; } } else if((A == 15)) { valACCEL++; if(valACCEL >= 100) { valACCEL = 100; } } } if(ButtonStopState==HIGH && ((A == 10) || (A == 15)) ) { EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); A = 5; } }Попробовал во время вращения мотора вызывать показания на дисплей с помощью функций. Работает и не тормозит мотор. А вот как теперь из menuStop() перейти в меню для установки параметров двигателя и потом вернуться в menuStop()? Пока не получается
void setup() { stepper.setMaxSpeed(1000); pinMode(ButtonPinMode, INPUT); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); lcd.begin(16, 2); lcd.clear(); menuStop(); lastbutton = 0; } void loop() { if (A == 10) /// SpeedMenu() { lcd.setCursor(0,0); lcd.print("SPEED "); lcd.setCursor(9,0); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } else if (A == 15) /// RampMenu() { lcd.setCursor(0,0); lcd.print("RAMP "); lcd.setCursor(9,0); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } ////////////////////////////////////////////////////////////// КНОПКИ УПРАВЛЕНИЕ if(ButtonLeftState == HIGH && lastbutton == 0) { menuLeft(); stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(64000L); lastbutton = 1; } else if(ButtonRightState == HIGH && lastbutton == 0 ) { menuRight(); stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(-64000L); lastbutton = 2; } else if(ButtonStopState == HIGH && (lastbutton == 1 || lastbutton == 2)) { menuStop(); stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// МЕНЮ if(ButtonModeState==HIGH && lastbutton == 0 ) { A = 10; } else if(ButtonModeState==HIGH && A == 10 ){ A = 15; } else if(ButtonModeState==HIGH && A == 15 ){ A = 10; } } else if(ButtonLeftState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED--; if(valSPEED <= 0) { valSPEED = 0; } } else if((A == 15)) { valACCEL--; if(valACCEL <= 0) { valACCEL = 0; } } } else if(ButtonRightState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED++; if(valSPEED >= 100) { valSPEED = 100; } } else if((A == 15)) { valACCEL++; if(valACCEL >= 100) { valACCEL = 100; } } } if(ButtonStopState==HIGH && ((A == 10) || (A == 15)) ) { EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); menuStop(); } } void menuStop() { valSPEED = EEPROM.read(70); valSPEEDA = EEPROM.read(80); valSPEEDB = EEPROM.read(90); valACCEL = EEPROM.read(100); valACCELA = EEPROM.read(110); valACCELB = EEPROM.read(120); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuLeft() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M < Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuRight() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M > Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); }Не проще ли купить готовый драйвер шаговика, а ардуине дать делать всю остальную работу
Я же вам уже показывал как это делается - выводите на дисплей только тогда когда есть изменения, плюс ко всему вы так еще и ЕЕПРОМ запорите очень быстро.
void setup() { stepper.setMaxSpeed(1000); pinMode(ButtonPinMode, INPUT); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); lcd.begin(16, 2); lcd.clear(); A = 5; lastbutton = 0; } void loop() { static long sumPrev; if((A^valM^valSPEED^valACCEL) != sumPrev) { sumPrev = A^valM^valSPEED^valACCEL; if (A == 5) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } else if (A == 6) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M < Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } else if (A == 7) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M > Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } else if (A == 10) /// SpeedMenu() { lcd.setCursor(0,0); lcd.print("SPEED "); lcd.setCursor(9,0); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } else if (A == 15) /// RampMenu() { lcd.setCursor(0,0); lcd.print("RAMP "); lcd.setCursor(9,0); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } } //////////////////////////////////////////// МОТОР if(ButtonLeftState == HIGH && A == 5) { A = 6; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(64000L); lastbutton = 1; } else if(ButtonRightState == HIGH && A == 5) { A = 7; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(-64000L); lastbutton = 2; } else if(ButtonStopState == HIGH && ( A == 6 || A == 7)) { A = 5; stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// МЕНЮ if(ButtonModeState==HIGH ) { if((A == 5) || (A == 10)) { A = A + 5; } else if(A == 15){ A = 10; } } else if(ButtonLeftState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED--; if(valSPEED <= 0) { valSPEED = 0; } } else if((A == 15)) { valACCEL--; if(valACCEL <= 0) { valACCEL = 0; } } } else if(ButtonRightState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED++; if(valSPEED >= 100) { valSPEED = 100; } } else if((A == 15)) { valACCEL++; if(valACCEL >= 100) { valACCEL = 100; } } } if(ButtonStopState==HIGH && ((A == 10) || (A == 15)) ) { EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); A = 5; } }Не проще ли купить готовый драйвер шаговика, а ардуине дать делать всю остальную работу
Так у меня готовый драйвер и ардуина, которая делает всю остальную работу.
Спасибо maksim. Всё отлично, только при включении пустой экран до нажатия кнопок - как то непривычно.
static long sumPrev = 1431655765; дисплей пустой.
static long sumPrev;
sumPrev = 1431655765; дисплей высвечивает меню A=5 и тормоза
Засуньте все "меню" по фунциям и вызовите меню А в сетапе.
Веселье продолжается.
Всё меню в функциях - при изменении valSPEED и valACCEL визуально на дисплее значения не меняются, но в память записываются и считываются изменённые.
void setup() { stepper.setMaxSpeed(1000); pinMode(ButtonPinMode, INPUT); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); lcd.begin(16, 2); lcd.clear(); menuStop(); lastbutton = 0; } void loop() { if(ButtonModeState==HIGH ) { if( lastbutton == 0 ) { menuSpeed(); lastbutton = 3; } else if( lastbutton == 3 ) { menuRamp(); lastbutton = 4; } else if( lastbutton == 4 ) { menuSpeed(); lastbutton = 3; } } else if(ButtonLeftState == HIGH ) { if( lastbutton == 0 ) { menuLeft(); stepper.setSpeed(SPEED); stepper.setAcceleration(ACCEL); stepper.move(64000L); lastbutton = 1; } else if( lastbutton == 3 ) ////////////// визуально не считает { valSPEED--; if(valSPEED <= 0) { valSPEED = 0; } } else if( lastbutton == 4 ) //////////////// визуально не считает { valACCEL--; if(valACCEL <= 0) { valACCEL = 0; } } } else if(ButtonRightState == HIGH ) { if( lastbutton == 0 ) { menuRight(); stepper.setSpeed(SPEED); stepper.setAcceleration(ACCEL); stepper.move(-64000L); lastbutton = 2; } else if( lastbutton == 3 ) /////////////////// визуально не считает { valSPEED++; if(valSPEED >= 100) { valSPEED = 100; } } else if( lastbutton == 4 ) ///////////////// визуально не считает { valACCEL++; if(valACCEL >= 100) { valACCEL = 100; } } } else if(ButtonStopState == HIGH ) { if( lastbutton == 1 || lastbutton == 2 ) { menuStop(); stepper.stop(); lastbutton = 0; } else if (lastbutton == 3 || lastbutton == 4) { EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); EEPROM.write(130, valM); delay(15); menuStop(); lastbutton = 0; } } stepper.run(); } ////////////////////////////////////////////////////////////////////// void menuStop() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuLeft() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M < Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuRight() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M > Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuSpeed() { valSPEED = EEPROM.read(70); lcd.setCursor(0,0); lcd.print("SPEED "); lcd.setCursor(9,0); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } void menuRamp() { valACCEL = EEPROM.read(100); lcd.setCursor(0,0); lcd.print("RAMP "); lcd.setCursor(9,0); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); }Попробовал оставить часть кода, где происходит изменение скорости и ускорения A=10 и A=15 как было раннее - теперь визуально все хорошо, но при сохранении параметров не выходит в menuStop().
void setup() { stepper.setMaxSpeed(1000); pinMode(ButtonPinMode, INPUT); pinMode(ButtonPinLeft, INPUT); pinMode(ButtonPinRight, INPUT); pinMode(ButtonPinStop, INPUT); lcd.begin(16, 2); lcd.clear(); menuStop(); lastbutton = 0; } void loop() { if (A == 10) /// SpeedMenu() { lcd.setCursor(0,0); lcd.print("SPEED "); lcd.setCursor(9,0); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } else if (A == 15) /// RampMenu() { lcd.setCursor(0,0); lcd.print("RAMP "); lcd.setCursor(9,0); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(12,0); lcd.print(" "); lcd.setCursor(0,1); lcd.print(" 100 = max value "); } ////////////////////////////////////////////////////////////// КНОПКИ УПРАВЛЕНИЕ if(ButtonLeftState == HIGH && lastbutton == 0) { menuLeft(); stepper.setSpeed(SPEED); stepper.setAcceleration(ACCEL); stepper.move(64000L); lastbutton = 1; } else if(ButtonRightState == HIGH && lastbutton == 0 ) { menuRight(); stepper.setSpeed(SPEED); stepper.setAcceleration(ACCEL); stepper.move(-64000L); lastbutton = 2; } else if(ButtonStopState == HIGH && (lastbutton == 1 || lastbutton == 2)) { menuStop(); stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// КНОПКИ МЕНЮ if(ButtonModeState==HIGH ) { if( lastbutton == 0 ) { A = 10; lastbutton = 3; } else if( lastbutton == 3 ) { A = 15; lastbutton = 4; } else if( lastbutton == 4 ) { A = 10; lastbutton = 3; } } ///////////////////////////////////////////////////////////////////////////// else if(ButtonLeftState==HIGH && lastbutton == 3) { valSPEED--; if(valSPEED <= 0) { valSPEED = 0; } } else if(ButtonLeftState==HIGH && lastbutton == 4) { valACCEL--; if(valACCEL <= 0) { valACCEL = 0; } } ///////////////////////////////////////////////////////////////////////// else if(ButtonRightState==HIGH && lastbutton == 3) { valSPEED++; if(valSPEED >= 100) { valSPEED = 100; } } else if(ButtonRightState==HIGH && lastbutton == 4) { valACCEL++; if(valACCEL >= 100) { valACCEL = 100; } } //////////////////////////////////////////////////////////// не выходит в menuStop() else if(ButtonStopState==HIGH && (lastbutton == 3 || lastbutton == 4)) { lcd.setCursor(0, 0); lcd.print(" Settings "); lcd.setCursor(0, 1); lcd.print(" done saving "); delay(1500); EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); EEPROM.write(130, valM); delay(15); menuStop(); lastbutton = 0; } } ////////////////////////////////////////////////////////////////////// void menuStop() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuLeft() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M < Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void menuRight() { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M > Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); }Нестал создавать новую тему - спрошу в этой , если надо перенесу.
Имеем:
Cтандартную ШИМ с дуни " A " и естественно при увиличении скважности импульса он увеличивается по направлении стрелки " + "
Возникла необходимость управлять двигателем постоянного тока через H-мост на полевиках и одно из условий чтобы двигатель не вращался - но при этом стоял в возбуждении для сопротивления вращения его сторонними силами .
И для этого надо на него подавать сразу две ШИМ прямой и обратной полярности - ну и естественно надо чтобы их импульсы непересикались.
Отсюда вопрос:
Как сделать сдвиг ШИМ " B "на одном и более выводах дуни относительно линии " S " и соответственно нарастание импульса ШИМ нужно в обратную сторону от стандартного как показано на стрелке " - "
Не знаю что вы там пытались сделать, но я имел ввиду это:
void setup() { stepper.setMaxSpeed(1000); lcd.begin(16, 2); lcd.clear(); A = 5; lastbutton = 0; MenuDir(' '); } void loop() { static long sumPrev; if((A^valM^valSPEED^valACCEL) != sumPrev) { sumPrev = A^valM^valSPEED^valACCEL; if (A == 5) MenuDir(' '); else if (A == 6) MenuDir('<'); else if (A == 7) MenuDir('>'); else if (A == 10) SpeedRampMenu(1); else if (A == 15) SpeedRampMenu(0); } //////////////////////////////////////////// МОТОР if(ButtonLeftState == HIGH && A == 5) { A = 6; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(64000L); lastbutton = 1; } else if(ButtonRightState == HIGH && A == 5) { A = 7; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(-64000L); lastbutton = 2; } else if(ButtonStopState == HIGH && ( A == 6 || A == 7)) { A = 5; stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// МЕНЮ if(ButtonModeState==HIGH ) { if((A == 5) || (A == 10)) A = A + 5; else if(A == 15) A = 10; } else if(ButtonLeftState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED--; if(valSPEED <= 0) valSPEED = 0; } else if((A == 15)) { valACCEL--; if(valACCEL <= 0) valACCEL = 0; } } else if(ButtonRightState==HIGH && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED++; if(valSPEED >= 100) valSPEED = 100; } else if((A == 15)) { valACCEL++; if(valACCEL >= 100) valACCEL = 100; } } if(ButtonStopState==HIGH && ((A == 10) || (A == 15)) ) { EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); A = 5; } } void MenuDir(char dir) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M "); lcd.print(dir); lcd.print(" Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void SpeedRampMenu(bool sa) { lcd.setCursor(0,0); lcd.print(sa ? "SPEED " : "RAMP "); lcd.setCursor(9,0); lcd.print(sa ? valSPEED : valACCEL); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" 100 = max value "); }Плюс ко всему получилось свернуть все отображение меню всего в две функции.
Нестал создавать новую тему - спрошу в этой , если надо перенесу.
Спасимо maksim - прочитал всю тему по вашей ссылке - но вопрос не отпал.
Мотивировал вопрос именно здесь по тому , что именно работу шагового двигателя мне нужно имитировать на моем двигателе ( ход якоря 100 !!! градусов всего ) паральлельно которому стоит резистор для обратной связи , да н-мосты похожи , но в моем случае на один мост подаются именно два ШИМ ( сдвинутые по переуду ) минимальной скважности одновременно для удержание якоря в том или ином положении и при увеличении одного из ШИМ происходит поворот этого якоря на 10-ки градусов всего в одну или другую сторону в зависимости от того какой ШИМ используется.
На аппаратном уровне буду тринироваться позже - двигатель огромный , токи до 40А , пока хочу на програмном получить то что описывал в посте выше.
Есть возможность управления ШИМ как показано на диограме " В " в дуне или нет ?
Есть, в самом простом случае это можно реализовать программно. Не совсем ясно что вы хотите реализовать...
Каждый из выводов управляет одной половиной Н-моста. Когда на одном из выводов лог.1, а на втором лог.0 двигатель крутится в одну сторону и когда наоборот - в другую. Когда на обоих выводах одинаковые логические уровни, то двигатель не крутится. Так?
И вы хотите реализовать что-то типа микрошага как у шаговых двигателей?
Ну логические нули и еденицы - это не решение этой задачи.( Поэтому я к вам и обратился )
Каждый из двух-ШИМ 1, и ШИМ 2 управляет естественно своей половинкой моста , используя ШИМ 1 и минимальный переид импульса мы заставляем крутится двигатель в одну сторону , а если подать такиеже импульсы в обратной полярности и сдвинуть их чтобы они невстретелись - то двигатель встанет и увеличивая Шим до 127 на каждом из ШИМ он так и будет стоять и при этом механическое усилие на его скручивание тоже будет меняться в зависимости от периуда ШИМ , так как параллельно валу стоит резистор мы естественно отслеживаем его положение и если механически применить силу к валу и чуть повернув его то дуня увеличивая тот или иной ШИМ - ставит его наместо и опять удерживает!
Так до ШИМ 127 мы можем упралять сдвинув один ШИМ относительно другого на 1/2 периуда далее они пересекуться и КЗ в H-мосте , а если ШИМ 2 сдвинуть на 2/255 назад и инвертировать наростание импульса во временном периуде как в первом моем посте то в нашем распоряжении 253 градации в каждое из направлений.
Вот так мне надо.
Только смог вернуться к теме. Спасибо maksim, ваш пример отлично работает.
Теперь двигаюсь дальше - хочу добавить новые переменные. Попробовал по подобию
void loop() { static long sumPrev; if((A^valM^valSPEED^valACCEL^valSPEEDA^valACCELA^valSPEEDB^valACCELB) != sumPrev) { sumPrev = A^valM^valSPEED^valACCEL^valSPEEDA^valACCELA^valSPEEDB^valACCELB; if (A == 5) MenuDir(' '); else if (A == 6) MenuDir('<'); else if (A == 7) MenuDir('>'); else if (A == 10) SpeedRampMenu(1); else if (A == 15) SpeedRampMenu(0); else if (A == 20) SpeedARampAMenu(1); else if (A == 25) SpeedARampAMenu(0); else if (A == 30) SpeedBRampBMenu(1); else if (A == 35) SpeedBRampBMenu(0); } //////////////////////////////////////////// МОТОР if(ButtonLeftState == HIGH && A == 5) { A = 6; stepper.setSpeed(SPEED); stepper.setAcceleration(ACCEL); stepper.move(64000L); lastbutton = 1; } else if(ButtonRightState == HIGH && A == 5) { A = 7; stepper.setSpeed(SPEED); stepper.setAcceleration(ACCEL); stepper.move(-64000L); lastbutton = 2; } else if(ButtonStopState == HIGH && ( A == 6 || A == 7)) { A = 5; stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// МЕНЮ if(ButtonModeState==HIGH ) { if((A == 5) || (A == 10) || (A == 15) || (A == 20)|| (A == 25) || (A == 30)) A = A + 5; else if(A == 35) { A = 10; } else if(ButtonLeftState==HIGH && ((A == 10) || (A == 15) || (A == 20) || (A == 25) || (A == 30) || (A == 35) )) { if((A == 10)) { valSPEED--; if(valSPEED <= 0) valSPEED = 0; } else if((A == 15)) { valACCEL--; if(valACCEL <= 0) valACCEL = 0; } else if((A == 20)) { valSPEEDA--; if(valSPEEDA <= 0) valSPEEDA = 0; } else if((A == 25)) { valACCELA--; if(valACCELA <= 0) valACCELA = 0; } else if((A == 30)) { valSPEEDB--; if(valSPEEDB <= 0) valSPEEDB = 0; } else if((A == 35)) { valACCELB--; if(valACCELB <= 0) valACCELB = 0; } } else if(ButtonRightState==HIGH && ((A == 10) || (A == 15) || (A == 20) || (A == 25) || (A == 30) || (A == 35) )) { if((A == 10)) { valSPEED++; if(valSPEED >= 100) valSPEED = 100; } else if((A == 15)) { valACCEL++; if(valACCEL >= 100) valACCEL = 100; } else if((A == 20)) { valSPEEDA++; if(valSPEEDA >= 100) valSPEEDA = 100; } else if((A == 25)) { valACCELA++; if(valACCELA >= 100) valACCELA = 100; } else if((A == 30)) { valSPEEDB++; if(valSPEEDB >= 100) valSPEEDB = 100; } else if((A == 35)) { valACCELB++; if(valACCELB >= 100) valACCELB = 100; } } if(ButtonStopState==HIGH && ((A == 10) || (A == 15) || (A == 20) || (A == 25) || (A == 30) || (A == 35)) ) { lcd.setCursor(0, 0); lcd.print(" Settings "); lcd.setCursor(0, 1); lcd.print(" done saving "); delay(1500); EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); EEPROM.write(80, valSPEEDA); delay(15); EEPROM.write(110, valACCELA); delay(15); EEPROM.write(90, valSPEEDB); delay(15); EEPROM.write(120, valACCELB); delay(15); EEPROM.write(130, valM); delay(15); A = 5; lastbutton = 0; } } } void MenuDir(char dir) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); valM = EEPROM.read(130); lcd.setCursor(0, 0); lcd.print("M "); lcd.print(dir); lcd.print(" Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void SpeedRampMenu(bool sa) { lcd.setCursor(0,0); lcd.print(sa ? "SPEED " : "RAMP "); lcd.setCursor(9,0); lcd.print(sa ? valSPEED : valACCEL); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" 100 = max value "); } void SpeedARampAMenu(bool sa) { lcd.setCursor(0,0); lcd.print(sa ? "SPEEDA " : "RAMPA "); lcd.setCursor(9,0); lcd.print(sa ? valSPEEDA : valACCELA); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" 100 = max value "); } void SpeedBRampBMenu(bool sa) { lcd.setCursor(0,0); lcd.print(sa ? "SPEEDB " : "RAMPB "); lcd.setCursor(9,0); lcd.print(sa ? valSPEEDB : valACCELB); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" 100 = max value "); }Теперь никакие параметры не меняются и нет выхода из меню в MenuDir(' ')
Доброго времени суток !
2vvadim: у меня тоже были проблеммы с заиканием двигателя при использовании стандартной библиотеки с lcd1602
по этому я написал свою библиотеку, которая использует паузы только на этапе инициализации. В процессе работы работает по прерыванию не занимая процессорного времени:https://github.com/Void1509/lcdLib1602
очень простая, но есть несколько НО. Буфер строки ограничен 48 символами, по этому за один раз больше лучше не выводить(лишнии будут игнорироваться). Спецфункций (установка, отображение курсора и т.д.) я не делал, вместо этого сделал управляющие последовательности чарез 0x1B(27). К примеру lcdChr(0x1b);lcdChr(0x85); установит курсор в 5 позицию верхней строки, а lcdChr(0x1b);lcdChr(0xc5); в 5 позицию нижней строки. Коды управления можно почитать в даташит на контролер.
2sp34: Вам необходимо настроить таймер (к примеру 2) в режим fastPWM и настроить выходы oc2a в неинверсный, а oc2b в инверсный режимы. Таким образом длина импульса 1 будет в регистре ocr2a, а содержимое регистра ocr2b будет 255 - (длина импульса 2). Оверфлоу таймера - точка S. Если возникнут проблемы распишу подробней, но недолжны - даташит очень подробный.
sva1509, спасибо за участие. На досуге я обязательно попробую разобраться с вашей библиотекой, хотя без примеров такому , ну скажем, очень слабенькому программисту как я будет не просто, но интересно.
Сейчас есть пример от maksim, который работает. Теперь нужно ввести дополнительные переменные и добавить потом 2 кнопки. Думаю так будет проще.
С дополнительными переменными разобрался. Теперь добавлю новые кнопки с новыми функциями.
maksim, не могли бы Вы мне помочь. Мне очень нужен ваш код, но я пока новичок и мало что понимаю. Я попыталась использовать код, но он у меня не компилируется. До этого я нашла библиотеку AccelStepper, скачала и вроде бы она подсвечивается. а при компилляции пишет ошибку на строчке stepper.setMaxSpeed(1000). Ошибка звучит так: "stepper" was not declared in this scope. Не могли бы Вы мне подсказать причину такой ошибки. Вы меня очень бы выручили!!!
Хотя я и не maksim. но и он вам напишет - покажите код и напишите в чём проблема.
Ну и перед написанием вопроса было бы неплохо внимательно почить библу и поиграться с примерами.
vvadim, я взяла код из 20 сообщения. Он приведен неполностью?
а насчет примеров - они у меня также не работают, тоже ошибки появляются.
Видимо я как-то неправильно библиотеку подключаю
и еще вопрос, если можно! подойдет ли этот код, если двигатель подключен через микросхему ULN2003
Код там естественно не весь, поэтому и не компилируется
#include <EEPROM.h> #include <LiquidCrystal.h> #include <AccelStepper.h> LiquidCrystal lcd(12, 11, 10, 9, 8, 7); AccelStepper stepper(4, 2, 3, 4, 5); // двигатель подключается к 2, 3, 4 и 5 выводам #define ButtonLeft A0 #define ButtonRight A1 #define ButtonMode A2 #define ButtonStop A3 long A, valM, valSPEED, valACCEL, lastbutton; void setup() { digitalRead(ButtonLeft); digitalRead(ButtonRight); digitalRead(ButtonMode); digitalRead(ButtonStop); stepper.setMaxSpeed(1000); lcd.begin(16, 2); lcd.clear(); A = 5; lastbutton = 0; MenuDir(' '); } void loop() { static long sumPrev; if((A^valM^valSPEED^valACCEL) != sumPrev) { sumPrev = A^valM^valSPEED^valACCEL; if (A == 5) MenuDir(' '); else if (A == 6) MenuDir('<'); else if (A == 7) MenuDir('>'); else if (A == 10) SpeedRampMenu(1); else if (A == 15) SpeedRampMenu(0); } //////////////////////////////////////////// МОТОР if(digitalRead(ButtonLeft) == LOW && A == 5) { A = 6; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(64000L); lastbutton = 1; } else if(digitalRead(ButtonRight) == LOW && A == 5) { A = 7; stepper.setSpeed(valSPEED); stepper.setAcceleration(valACCEL); stepper.move(-64000L); lastbutton = 2; } else if(digitalRead(ButtonStop) == LOW && ( A == 6 || A == 7)) { A = 5; stepper.stop(); lastbutton = 0; } stepper.run(); ///////////////////////////////////////////////////////////// МЕНЮ if(digitalRead(ButtonLeft) == LOW) { if((A == 5) || (A == 10)) A = A + 5; else if(A == 15) A = 10; } else if(digitalRead(ButtonLeft) == LOW && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED--; if(valSPEED <= 0) valSPEED = 0; } else if((A == 15)) { valACCEL--; if(valACCEL <= 0) valACCEL = 0; } } else if(digitalRead(ButtonRight) == LOW && ((A == 10) || (A == 15) )) { if((A == 10)) { valSPEED++; if(valSPEED >= 100) valSPEED = 100; } else if((A == 15)) { valACCEL++; if(valACCEL >= 100) valACCEL = 100; } } if(digitalRead(ButtonStop) == LOW && ((A == 10) || (A == 15)) ) { EEPROM.write(70, valSPEED); delay(15); EEPROM.write(100, valACCEL); delay(15); A = 5; } } void MenuDir(char dir) { valSPEED = EEPROM.read(70); valACCEL = EEPROM.read(100); lcd.setCursor(0, 0); lcd.print("M "); lcd.print(dir); lcd.print(" Speed Ramp"); lcd.setCursor(0, 1); lcd.print(valM); lcd.setCursor(1, 1); lcd.print(" "); lcd.setCursor(5, 1); lcd.print(valSPEED); lcd.print(" "); lcd.setCursor(8,1); lcd.print(" "); lcd.setCursor(12, 1); lcd.print(valACCEL); lcd.print(" "); lcd.setCursor(15,1); lcd.print(" "); } void SpeedRampMenu(bool sa) { lcd.setCursor(0,0); lcd.print(sa ? "SPEED " : "RAMP "); lcd.setCursor(9,0); lcd.print(sa ? valSPEED : valACCEL); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.print(" 100 = max value "); }Если у вас с примерами из библиотеки проблема, то и ничего не выйдет. Установите правильно библиотеку и примеры должны все работать. Скачайте последнюю версию AccslStepper 1.38
maksim, спасибо большое!
а Вы не могли бы мне подсказать, у меня такая же задача, я попробовала соединить два кода для lcd и stepper motor, но естественно не работает, как мне надо :) приведу код
#include <Wire.h> // добавляем необходимые библиотеки #include <LiquidCrystal.h> #include <Stepper.h> #define STEPS 48 LiquidCrystal lcd(8, 9, 4, 5, 6, 7 ); Stepper stepper(STEPS, 30, 31, 32, 33); // Нажатые кнопки int button; const int BUTTON_NONE = 0; const int BUTTON_RIGHT = 1; const int BUTTON_UP = 2; const int BUTTON_DOWN = 3; const int BUTTON_LEFT = 4; const int BUTTON_SELECT = 5; int getPressedButton() { int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0) if (buttonValue < 100) { return BUTTON_RIGHT; } else if (buttonValue < 200) { return BUTTON_UP; } else if (buttonValue < 400){ return BUTTON_DOWN; } else if (buttonValue < 600){ return BUTTON_LEFT; } else if (buttonValue < 800){ return BUTTON_SELECT; } return BUTTON_NONE; } int speedmean; void setup() { lcd.begin(16, 2); lcd.print("hello! )"); speedmean=40; stepper.setSpeed(speedmean); } void loop() { button = getPressedButton(); switch (button) { case BUTTON_RIGHT: // при нажатии кнопки выводим следующий текст do{ lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); lcd.print("START"); stepper.step(1*STEPS); button=getPressedButton(); }while (button!=BUTTON_LEFT); break; case BUTTON_LEFT: lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); lcd.print("STOP"); stepper.step(0); break; case BUTTON_UP: lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); speedmean=speedmean+1; lcd.print(speedmean); stepper.setSpeed(speedmean); break; } }и загвоздка в том, что когда я добавляю кнопку вверх, то у меня она работает как кнопка вправо. кнопку вниз я еще не добавляла пока. даже только когда у меня запрограммированы только 2 кнопки правая и левая, верхняя у меня все равно работает как правая, хотя я её не программировала. с чем это может быть связано?
Как у вас подключены кнопки?
lcd сверху вставлена на платформу MEGA 2560
наверно стоит уточнить, что пример просто для lcd у меня работает, нажатие каждой кнопки выводит нужное сообщение на экране
я на картинке пометила, какие входы-выходы задействованы
Данный код предназначен для аналоговой клавиатуры, подключенной к одному аналоговому выводу:
// Нажатые кнопки int button; const int BUTTON_NONE = 0; const int BUTTON_RIGHT = 1; const int BUTTON_UP = 2; const int BUTTON_DOWN = 3; const int BUTTON_LEFT = 4; const int BUTTON_SELECT = 5; int getPressedButton() { int buttonValue = analogRead(0); // считываем значения с аналогового входа(A0) if (buttonValue < 100) { return BUTTON_RIGHT; } else if (buttonValue < 200) { return BUTTON_UP; } else if (buttonValue < 400){ return BUTTON_DOWN; } else if (buttonValue < 600){ return BUTTON_LEFT; } else if (buttonValue < 800){ return BUTTON_SELECT; } return BUTTON_NONE; }Если вы подключаете каждую кнопку к своему выводу, то необходимо пользоваться функцией digitalRead() для каждой кнопки.
И вы так и не описали как у вас подключены кнопки, а аналоговых входов указали 6, а кнопок всего 5.
maksim, спасибо за разъяснения! а как мне подключить клавиатуру к одному аналоговому выводу? или это невозможно?
В этом есть смысл если она (клавиатура) у вас уже есть всборе, иначе логичнее и проще подключать на каждый вывод свою кнопку.
// Нажатые кнопки int button; const int BUTTON_NONE = 0; const int BUTTON_RIGHT = 1; const int BUTTON_UP = 2; const int BUTTON_DOWN = 3; const int BUTTON_LEFT = 4; const int BUTTON_SELECT = 5; int getPressedButton() { if (digitalRead(A0) == HIGH) { return BUTTON_RIGHT; } else if (digitalRead(A1) == HIGH) { return BUTTON_UP; } else if (digitalRead(A2) == HIGH){ return BUTTON_DOWN; } else if (digitalRead(A3) == HIGH){ return BUTTON_LEFT; } else if (digitalRead(A4) == HIGH){ return BUTTON_SELECT; } return BUTTON_NONE; }Подключаете кнопки с А0 по А4.
maksim, клавиатура у меня на lcd keypad shild, и кажется уже в сборе. вот такая
а остальной код прежний останется?
maksim, неожиданно работает. теперь начального сообщения нет, а работает так, как если бы была нажата правая кнопка. остальные кнопки вообще не работают
Ну так потому что у вас и есть аналоговая клавиатура.
#include <Wire.h> // добавляем необходимые библиотеки #include <LiquidCrystal.h> #include <Stepper.h> #define STEPS 48 LiquidCrystal lcd(8, 9, 4, 5, 6, 7 ); Stepper stepper(STEPS, 30, 31, 32, 33); #define BUTTON_NONE 0 #define BUTTON_RIGHT 1 #define BUTTON_UP 2 #define BUTTON_DOWN 3 #define BUTTON_LEFT 4 #define BUTTON_SELECT 5 int speedmean = 40; void setup() { lcd.begin(16, 2); lcd.print("hello! )"); stepper.setSpeed(speedmean); } void loop() { int button = get_key(); switch (button) { case BUTTON_RIGHT: // при нажатии кнопки выводим следующий текст do{ lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); lcd.print("START"); stepper.step(STEPS); } while(get_key() != BUTTON_LEFT); break; case BUTTON_LEFT: lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); lcd.print("STOP"); stepper.step(0); delay(50); break; case BUTTON_UP: lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(0, 0); speedmean++; lcd.print(speedmean); stepper.setSpeed(speedmean); delay(50); break; } } // Convert ADC value to key number int get_key() { if(analogRead(0) > 760) return 0; delay(50); int adc_key_val[5] ={30, 150, 360, 535, 760}; unsigned int input = analogRead(0); for (byte k = 0; k < 5; k++) if (input < adc_key_val[k]) return k + 1; return 0; }maksim, я не знаю, что сказать. одни восторги! спасибо большое Вам за помощь. теперь моя кандидатская продвинулась еще дальше, благодаря Вам :)
maksim, я не знаю, что сказать. одни восторги! спасибо большое Вам за помощь. теперь моя кандидатская продвинулась еще дальше, благодаря Вам :)
надеюсь, что юзер форума http://arduino.ru/ maksim займёт засслуженное место в списке соавторов какдитатской.
maksim, у меня еще один вопрос возник, надеюсь, что последний. как заставить двигатель вращаться назад? я почему-то думала, что достаточно поставить минус перед числом в скобках у функции stepper.step(), но это не сработало.