Управление шаговым двигателем

vvadim
Offline
Зарегистрирован: 23.05.2012

Управляю шаговиком с помощью трёх кнопок (лево, стоп, право) , библиотека AccelStepper. Проблем нет. Ввёл в пограмму lcd и меню для изменения параметров движения и сразу возникли тормоза - скорость упала в разы. Как то можно решить подобную проблему? Может вывести дисплей и меню из loop в отдельную функцию и потом вызывать?

maksim
Offline
Зарегистрирован: 12.02.2012

vvadim пишет:

Как то можно решить подобную проблему?

Можно, но только как-то и никак по-другому.

vvadim пишет:

Может вывести дисплей и меню из loop в отдельную функцию и потом вызывать?

Да может, например, послезавтра вызвать, тогда точно до послезавтра тормозов не будет и скорость у двигателя нормальная будет.

Вы вроде не первый день на форуме...

vvadim
Offline
Зарегистрирован: 23.05.2012

maksim пишет:

 

Вы вроде не первый день на форуме...

 

maksim, я не программист и просто не знаю куда рыть дальше. Вот и прошу подсказки. Что lcd 16x2 тормозит шаговый двигатель я  прочитал. Примеров "борьбы" с этим не нашёл. 

maksim
Offline
Зарегистрирован: 12.02.2012

Я к тому что здесь по прежнему нет экстрасенсов и без кода обсуждать нечего.

vvadim
Offline
Зарегистрирован: 23.05.2012


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();
}
   

Теперь тормоза

maksim
Offline
Зарегистрирован: 12.02.2012

Что за переменные valMvalSPEEDvalACCEL ??? код весь покажите.

vvadim
Offline
Зарегистрирован: 23.05.2012

valM режим микрошага- ещё не реализовал.

valSPEED и valACCEL скорость и ускорение шагового двигателя , будут регулироваться в меню ( в процессе разработки).

 

maksim
Offline
Зарегистрирован: 12.02.2012

Тогда выводите данные на дисплей только при их изменении

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();
}

 

vvadim
Offline
Зарегистрирован: 23.05.2012

Спасибо. Сейчас попробую.

vvadim
Offline
Зарегистрирован: 23.05.2012

А как тогда работать с меню?

maksim
Offline
Зарегистрирован: 12.02.2012

Не знаю, не вижу никакого меню.

vvadim
Offline
Зарегистрирован: 23.05.2012

Код выводит на дисплей всю нужную мне информацию, но тормозит двигатель





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(" ");
} 




















 

Kislorof
Offline
Зарегистрирован: 30.10.2012

Не проще ли купить готовый драйвер шаговика, а ардуине дать делать всю остальную работу

maksim
Offline
Зарегистрирован: 12.02.2012

Я же вам уже показывал как это делается - выводите на дисплей только тогда когда есть изменения, плюс ко всему вы так еще и ЕЕПРОМ запорите очень быстро.




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; 
  } 
}

 

vvadim
Offline
Зарегистрирован: 23.05.2012

Kislorof пишет:

Не проще ли купить готовый драйвер шаговика, а ардуине дать делать всю остальную работу

Так у меня готовый драйвер и ардуина, которая делает всю остальную работу.

 

Спасибо maksim. Всё отлично, только при включении пустой экран до нажатия кнопок - как то непривычно.

maksim
Offline
Зарегистрирован: 12.02.2012
static long sumPrev = 1431655765;

 

vvadim
Offline
Зарегистрирован: 23.05.2012

static long sumPrev = 1431655765;  дисплей пустой.

static long sumPrev;

sumPrev = 1431655765;   дисплей высвечивает меню A=5  и тормоза

maksim
Offline
Зарегистрирован: 12.02.2012

Засуньте все "меню" по фунциям и вызовите меню А в сетапе.

vvadim
Offline
Зарегистрирован: 23.05.2012

Веселье продолжается.

Всё меню в функциях - при изменении 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(" ");
} 

 

sp34
Offline
Зарегистрирован: 05.03.2013

 

Нестал создавать новую тему - спрошу в этой , если надо перенесу.

 

Имеем:

Cтандартную ШИМ с дуни " A " и естественно при увиличении скважности импульса он увеличивается по направлении стрелки " + "

Возникла необходимость управлять двигателем постоянного тока через H-мост на полевиках и одно из условий  чтобы двигатель не вращался - но при этом стоял в возбуждении для сопротивления вращения его сторонними силами .

И для этого надо на него подавать сразу две ШИМ прямой и обратной полярности - ну и естественно надо чтобы их импульсы непересикались.

Отсюда вопрос:

 Как сделать сдвиг ШИМ " B "на одном и более выводах дуни относительно линии " S " и  соответственно нарастание импульса ШИМ нужно в обратную сторону от стандартного как показано на стрелке " - "

 

maksim
Offline
Зарегистрирован: 12.02.2012

Не знаю что вы там пытались сделать, но я имел ввиду это:

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
Offline
Зарегистрирован: 12.02.2012

sp34 пишет:

Нестал создавать новую тему - спрошу в этой , если надо перенесу.

Не знаю чем вы мотивировались задавая этот вопрос здесь, но лучше будет спросить здесь http://arduino.ru/forum/proekty/arduino-draiver-motora-dlya-robota, а может и вопрос отпадет после прочтения этой темы.

sp34
Offline
Зарегистрирован: 05.03.2013

Спасимо maksim - прочитал всю тему по вашей ссылке - но вопрос не отпал.

Мотивировал вопрос именно здесь по тому , что именно работу шагового двигателя мне нужно имитировать на моем двигателе ( ход якоря 100 !!! градусов всего ) паральлельно которому стоит резистор для обратной связи , да н-мосты похожи , но в моем случае на один мост подаются именно два ШИМ ( сдвинутые по переуду ) минимальной скважности одновременно для удержание якоря в том или ином положении и при увеличении одного из ШИМ происходит поворот этого якоря на 10-ки градусов всего в одну или другую сторону в зависимости от того какой ШИМ используется.

На аппаратном уровне буду тринироваться позже - двигатель огромный , токи до 40А , пока хочу на програмном получить то что описывал в посте выше.

Есть возможность управления ШИМ как показано на диограме " В " в дуне или нет ?

maksim
Offline
Зарегистрирован: 12.02.2012

Есть, в самом простом случае это можно реализовать программно. Не совсем ясно что вы хотите реализовать...
Каждый из выводов управляет одной половиной Н-моста. Когда на одном из выводов лог.1, а на втором лог.0 двигатель крутится в одну сторону и когда наоборот - в другую. Когда на обоих выводах одинаковые логические уровни, то двигатель не крутится. Так?

И вы хотите реализовать что-то типа микрошага как у шаговых двигателей?

sp34
Offline
Зарегистрирован: 05.03.2013

Ну логические нули и еденицы - это не решение этой задачи.( Поэтому я к вам и обратился )

Каждый из двух-ШИМ 1, и ШИМ 2 управляет естественно своей половинкой моста  , используя ШИМ 1 и минимальный переид импульса мы заставляем крутится двигатель в одну сторону , а если подать такиеже импульсы в обратной полярности и сдвинуть их чтобы они невстретелись - то двигатель встанет и увеличивая Шим до 127 на каждом из ШИМ он так и будет стоять и при этом механическое усилие на его скручивание тоже будет меняться в зависимости от периуда ШИМ , так как параллельно валу стоит резистор мы естественно отслеживаем его положение и если механически применить силу к валу и чуть повернув его то дуня увеличивая тот или иной ШИМ - ставит его наместо и опять удерживает!

Так до ШИМ 127 мы можем упралять сдвинув один ШИМ относительно другого на 1/2 периуда далее они пересекуться и КЗ в H-мосте , а если ШИМ 2 сдвинуть на 2/255 назад и инвертировать наростание импульса во временном периуде как в первом моем посте то в нашем распоряжении 253 градации в каждое из направлений.

Вот так мне надо.

vvadim
Offline
Зарегистрирован: 23.05.2012

Только смог вернуться к теме. Спасибо 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(' ')

sva1509
Offline
Зарегистрирован: 07.12.2012

Доброго времени суток !

2vvadim: у меня тоже были проблеммы с заиканием двигателя при использовании стандартной библиотеки с lcd1602

по этому я написал свою библиотеку, которая использует паузы только на этапе инициализации. В процессе работы работает по прерыванию не занимая процессорного времени:https://github.com/Void1509/lcdLib1602

очень простая, но есть несколько НО. Буфер строки ограничен 48 символами, по этому за один раз больше лучше не выводить(лишнии будут игнорироваться). Спецфункций (установка, отображение курсора и т.д.) я не делал, вместо этого сделал управляющие последовательности чарез 0x1B(27). К примеру lcdChr(0x1b);lcdChr(0x85); установит курсор в 5 позицию верхней строки, а lcdChr(0x1b);lcdChr(0xc5); в 5 позицию нижней строки. Коды управления можно почитать в даташит на контролер.

 

sva1509
Offline
Зарегистрирован: 07.12.2012

2sp34: Вам необходимо настроить таймер (к примеру 2) в режим fastPWM и настроить выходы oc2a в неинверсный, а oc2b в инверсный режимы. Таким образом длина импульса 1 будет в регистре ocr2a, а содержимое регистра ocr2b будет 255 - (длина импульса 2). Оверфлоу таймера - точка S. Если возникнут проблемы распишу подробней, но недолжны - даташит очень подробный.

vvadim
Offline
Зарегистрирован: 23.05.2012

sva1509, спасибо за участие. На досуге я обязательно попробую разобраться с вашей библиотекой, хотя без примеров такому , ну скажем, очень слабенькому программисту как я будет не просто, но интересно.

Сейчас есть пример от maksim, который работает. Теперь нужно ввести дополнительные переменные  и добавить потом 2 кнопки. Думаю так будет проще.

 

vvadim
Offline
Зарегистрирован: 23.05.2012

С дополнительными переменными разобрался. Теперь добавлю новые кнопки с новыми функциями.

Melissa
Offline
Зарегистрирован: 11.01.2014

maksim, не могли бы Вы мне помочь. Мне очень нужен ваш код, но я пока новичок и мало что понимаю. Я попыталась использовать код, но он у меня не компилируется. До этого я нашла библиотеку AccelStepper, скачала и вроде бы она подсвечивается. а при компилляции пишет ошибку на строчке stepper.setMaxSpeed(1000). Ошибка звучит так: "stepper" was not declared in this scope. Не могли бы Вы мне подсказать причину такой ошибки. Вы меня очень бы выручили!!!

vvadim
Offline
Зарегистрирован: 23.05.2012

Хотя я и не maksim. но и он вам напишет - покажите код и напишите в чём проблема.

Ну и перед написанием вопроса было бы неплохо внимательно почить библу и поиграться с примерами.

Melissa
Offline
Зарегистрирован: 11.01.2014

vvadim, я взяла код из 20 сообщения. Он приведен неполностью?

а насчет примеров - они у меня также не работают, тоже ошибки появляются.

Видимо я как-то неправильно библиотеку подключаю

Melissa
Offline
Зарегистрирован: 11.01.2014

и еще вопрос, если можно! подойдет ли этот код, если двигатель подключен через микросхему ULN2003

maksim
Offline
Зарегистрирован: 12.02.2012

Код там естественно не весь, поэтому и не компилируется

#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 ");
}

 

vvadim
Offline
Зарегистрирован: 23.05.2012

Если у вас с примерами из библиотеки проблема, то и ничего не выйдет. Установите правильно библиотеку и примеры должны все работать. Скачайте последнюю версию AccslStepper  1.38

Melissa
Offline
Зарегистрирован: 11.01.2014

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 кнопки правая и левая, верхняя у меня все равно работает как правая, хотя я её не программировала. с чем это может быть связано?

maksim
Offline
Зарегистрирован: 12.02.2012

Как у вас подключены кнопки?

Melissa
Offline
Зарегистрирован: 11.01.2014

lcd сверху вставлена на платформу MEGA 2560

наверно стоит уточнить, что пример просто для lcd у меня работает, нажатие каждой кнопки выводит нужное сообщение на экране

Melissa
Offline
Зарегистрирован: 11.01.2014

я на картинке пометила, какие входы-выходы задействованы

maksim
Offline
Зарегистрирован: 12.02.2012

Данный код предназначен для аналоговой клавиатуры, подключенной к одному аналоговому выводу:

// Нажатые кнопки
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.

Melissa
Offline
Зарегистрирован: 11.01.2014

maksim, спасибо за разъяснения! а как мне подключить клавиатуру к одному аналоговому выводу? или это невозможно?

maksim
Offline
Зарегистрирован: 12.02.2012

В этом есть смысл если она (клавиатура) у вас уже есть всборе, иначе логичнее и проще подключать на каждый вывод свою кнопку.

maksim
Offline
Зарегистрирован: 12.02.2012
// Нажатые кнопки
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.

Melissa
Offline
Зарегистрирован: 11.01.2014

maksim, клавиатура у меня на lcd keypad shild, и кажется уже в сборе. вот такая

Melissa
Offline
Зарегистрирован: 11.01.2014

а остальной код прежний останется?

Melissa
Offline
Зарегистрирован: 11.01.2014

maksim, неожиданно работает. теперь начального сообщения нет, а работает так, как если бы была нажата правая кнопка. остальные кнопки вообще не работают

maksim
Offline
Зарегистрирован: 12.02.2012

Ну так потому что у вас и есть аналоговая клавиатура.

#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; 
}

 

Melissa
Offline
Зарегистрирован: 11.01.2014

maksim, я не знаю, что сказать. одни восторги! спасибо большое Вам за помощь. теперь моя кандидатская продвинулась еще дальше, благодаря Вам :)

Клапауций
Offline
Зарегистрирован: 10.02.2013

Melissa пишет:

maksim, я не знаю, что сказать. одни восторги! спасибо большое Вам за помощь. теперь моя кандидатская продвинулась еще дальше, благодаря Вам :)

надеюсь, что юзер форума http://arduino.ru/ maksim займёт засслуженное место в списке соавторов какдитатской.

Melissa
Offline
Зарегистрирован: 11.01.2014

maksim, у меня еще один вопрос возник, надеюсь, что последний. как заставить двигатель вращаться назад? я почему-то думала, что достаточно поставить минус перед числом в скобках у функции stepper.step(), но это не сработало.