Проблема с шаговым двигателем.

Тема в разделе "Моторы, сервоприводы, робототехника", создана пользователем IgOrKIPiA, 31 окт 2017.

  1. IgOrKIPiA

    IgOrKIPiA Нуб

    Здравствуйте! На днях приобрёл Mega 2560. В программировании я пока что полный фонарь. Сейчас пытаюсь создать небольшой проект и столкнулся вот с такой проблемой:
    при нажатии кнопки "Enter "двигатель начинает вращаться, при достижении концевика "brake" движок останавливается (концевиком "brake" устанавливается начальное положение), далее выполняется ряд одинаковых переключений и в конце мы возвращаемся к кнопке "Enter ". Проблема заключается в том, что при достижении концевика "brake" движок останавливается и на этом всё; если концевик "brake" зажать кратковременно то всё идёт по плану (правда есть и минус если кратковременно нажать концевик "brake" пока всё идёт по плану, весь ряд переключений начинается с начала). Концевик "brake" сейчас выполнен кнопкой и нажимается в ручную, в идеале вместо кнопки будет геркон , а на валу двигателя магнит. Не могли бы вы исправить мой код или предложить свой c любой подходящей для вас библиотекой. За ранее спасибо!!!!
    Двигатель 28BYJ-48 с драйвером ULN 2003

    Код (C++):
     #include <CustomStepper.h>
    CustomStepper stepper(4, 5, 6, 7);        // Входа IN1 - 4;IN2 - 5;IN3 - 6;IN4 - 7
    int buttonPush = 0,                       // Переменная для кнопки Enter
         start = 0,                            // Переменная для условия while        
         Enter = 8,                            // Кнопка для начала движения.
         brake = 9,                            // Пока кнопка, в дальнейшем будет геркон.
         rotateend = 0;                        // Переменная для перехода с одного задания на другое
    void setup() {
    pinMode(Enter, INPUT_PULLUP);
    pinMode(brake, INPUT_PULLUP);
    stepper.setRPM(10);
    stepper.setSPR(4097);

    }

    void loop() {                          
    buttonPush = digitalRead(Enter);
    if(buttonPush == LOW)
    {
    start = 1;
    }
      while(start == 1)
    {
    if (stepper.isDone() && rotateend == 0)
    {    
    stepper.rotate();
    }  
    if (stepper.isDone() == false && digitalRead(brake)== LOW)
    // Здесь начинаются проблемы:
    // Если кнопка нажата кратковременно код выполняется полностью (если кратковременно нажать в дальнейшей части кода (код возвращается к этому месту т.е. начинает с начала)
    // Если нажать и держать то движок стоит( на ULN 2003 горят светодиоды).
    // Так как в дальнейшем будет стоять геркон, а на двигателе будет магнит, при достижении геркона движок остановиться и дальнейшая часть кода выполняться не будет.    
    {
    delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 1;
    }  

    if (stepper.isDone() && rotateend ==1 )
    {
    delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 2;  }
    if (stepper.isDone() && rotateend == 2 )
    {
    delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 3;  }
    if (stepper.isDone() && rotateend ==3 )
    {
      delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 4;  }
    if (stepper.isDone() && rotateend ==4 )
    {
    delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 5;  }
    if (stepper.isDone() && rotateend ==5 )
    {
    delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 6;  }
    if (stepper.isDone() && rotateend ==6 )
    {
    delay(2000);
    stepper.setDirection(CW);
    stepper.rotateDegrees(45);
    rotateend = 7;
    }
    if (stepper.isDone() && rotateend ==7 )
    {
      delay(5000);
    rotateend = 8;        
    }
    if (stepper.isDone() && rotateend ==8 )
    {
    start = 0;
    rotateend = 0;
    }
    stepper.run();
    }
    }
     
  2. sslobodyan

    sslobodyan Гик

    Ниасилил :)
    Напишите четко как ДОЛЖЕН работать ваш автомат. Буквально по шагам.
     
  3. IgOrKIPiA

    IgOrKIPiA Нуб

    Спасибо что ответили:
    1. При нажатии кнопки двигатель начинает вращаться.
    2. На валу двигателя находится магнит, который перемещается по кругу вместе с валом.
    3. При достижении магнитом геркона, геркон замыкается и двигатель останавливается на 3-5 секунд (это будет нулевая позиция двигателя).
    4. После 3-5 секундной остановки двигатель выполняет перемещение на угол примерно в 45 градусов и ждёт примерно 2-3 секунды ( повторяет последнее действие 7 раз).
    5. возврат к пункту 1.
    Вечером скину фото проекта и кодовой маски. Хочу сделать тестер для проверки кодовой маски с выводом на LCD 1602.
    Принцип действия кодовой маски заключается в двоичном коде:
    2^0 ;2 ^1 ;2^2 ; 2^4. Существуют 8, 10 и 14 герконовые кодовые маски, у всех герконов общий + . Пин 1 подключен к 1-му геркону (2^0 ), пин 2 ко второму геркону(2^1), пин 3 к четвёртому (2^2), пин 4 к восьмому геркону (2^3). Остальные герконы соеденены диодами, например третий геркон соеденён с первым и со вторым герконом через диоды и если мы магнитом замыкаем третий геркон , то общий + приходит на пин 1 и пин 2 (2^0 + 2^1)=3.
    Мне необходимо чтобы на герконе 1 двигатель остановился и т.к. герконов 8 (360/8 =45) при прохождении 45 градусов магнит должен остановиться напротив следующего геркона (высчитать код и вывести на дисплей) и так пока не пройдёт все герконы.
    Из библиотек пробовал CustomStepper и AccelStepper, c последней больно намудрено (для меня, я только начал осваивать arduino), может ещё что-нибудь предложите.
    За ранее благодарю!!!!
     
  4. sslobodyan

    sslobodyan Гик

    Код (C++):
    #include <Stepper.h>

    #define ENTER 8 // кнопка
    #define BREAK 9 // геркон

    #define NUM_CYCLES 7 // количество циклов по 45 градусов

    const int stepsPerRevolution = 2038;  // сколько шагов на 1 оборот у движка

    // управляющие выводы
    Stepper myStepper(stepsPerRevolution, 4, 5, 6, 7);

    void setup() {
      // скорость вращения в об/мин
      myStepper.setSpeed(10);
      pinMode(ENTER, INPUT_PULLUP);
      pinMode(BREAK, INPUT_PULLUP);
    }

    void loop() {
      // ждем отпускания кнопки
      while ( !digitalRead(ENTER) ) delay(50);

      // ждем нажатие кнопки
      while ( digitalRead(ENTER) ) delay(50);

      // делаем шажки пока не упремся в геркон
      while ( digitalRead(BREAK) ) {
        myStepper.step( 1 );
      }
      delay(5000);

      // несколько циклов поворота на 45 градусов и остановки на 3 секунды
      for(byte i=0; i<NUM_CYCLES; i++) {
        myStepper.step( (long) 45 * stepsPerRevolution / 360 );
        delay(3000);
      }

    }
     
    Предполагается что кнопка и геркон подтянуты к питанию и при включении прижимаются к земле.
    Именно с этим движком не работал, естественно скетч не проверял. Но идея должна быть понятна :)
     
    IgOrKIPiA нравится это.
  5. IgOrKIPiA

    IgOrKIPiA Нуб

    Спасибо большое! Завтра попробую и напишу что получилось. Я не пробовал stepper, так как она не работает с полушаговым режимом, а двигатель работает. В полношаговом 2048 в полушаговом 4096 соответственно),но это не кретично мне идеальная точность не нужна, так как каждый новый круг он будет позиционироваться.
     

    Вложения:

  6. IgOrKIPiA

    IgOrKIPiA Нуб

     

    Вложения:

  7. sslobodyan

    sslobodyan Гик

    Не забудьте подставить свои значения шагов\оборот и пины подключения. Ну и если нужно что-то делать после остановки, то пропишите это внутри цикла for.
     
  8. IgOrKIPiA

    IgOrKIPiA Нуб

    Спасибо большое так и сделаю!
     
  9. IgOrKIPiA

    IgOrKIPiA Нуб



    С библиотекой Stepper двигатель дёргался и не выполнялось условие 45 градусов.
    Заменил библиотеку на Stepper_28BYJ.h установил 4096 шагов для полушагового режима, скорость 3 об/мин. и всё завертелось как по маслу)))!
    Огромное вам спасибо!!!!!
    Можно ли будет обратиться к вам если возникнут вопросы в дальнейшем построении этого кода?
    Код (C++):
    #include <Stepper_28BYJ.h>
    #define ENTER 8 // кнопка
    #define BREAK 9 // геркон
    #define NUM_CYCLES 7 // количество циклов по 45 градусов
    // количество шагов на один оборот
    const int stepsPerRevolution = 4096;
    Stepper_28BYJ myStepper_28BYJ(stepsPerRevolution, 4,5,6,7);
    void setup() {
    // установим скорость 3 об/мин
    myStepper_28BYJ.setSpeed(3);
    pinMode(ENTER, INPUT_PULLUP);
    pinMode(BREAK, INPUT_PULLUP);
    }

    void loop() {
    // ждем отпускания кнопки
    while ( !digitalRead(ENTER) ) delay(50);

    // ждем нажатие кнопки
    while ( digitalRead(ENTER) ) delay(50);

    // делаем шажки пока не упремся в геркон
    while ( digitalRead(BREAK) ) {
    myStepper_28BYJ.step( 1 );
    }
    delay(5000);

    // несколько циклов поворота на 45 градусов и остановки на 3 секунды
    for(byte i=0; i<NUM_CYCLES; i++) {
    myStepper_28BYJ.step( (long) 45 * stepsPerRevolution / 360 );
    delay(3000);
    }
     
  10. sslobodyan

    sslobodyan Гик

    Для этого достаточно кнопочки "Мне нравится"
    За спрос не бьют в нос :)
     
    IgOrKIPiA нравится это.
  11. IgOrKIPiA

    IgOrKIPiA Нуб

    Ну это всегда пожалуйста
     
  12. IgOrKIPiA

    IgOrKIPiA Нуб

    Вот и вопрос назрел))). Вопрос заключается в том, как правильнее оформить вывод информации на дисплей LCD 1602 при нажатии кнопок ( замыкании герконов)?
    Пример:
    int pin1 = 9, // геркон 1
    pin2 = 10, // геркон 2
    pin4 = 11, // геркон 4
    pin8 = 12 // геркон 8
    Когда замыкается pin1 на дисплее пишется "gerkon=1"
    Когда замыкается pin2 на дисплее пишется "gerkon=2"
    Когда замыкается pin1 и pin2 на дисплее пишется "gerkon=3" (1+2)
    Когда замыкается pin4 на дисплее пишется "gerkon=4"
    Когда замыкается pin1 и pin4 на дисплее пишется "gerkon=5" (1+4)
    Когда замыкается pin2 и pin4 на дисплее пишется "gerkon=6" (2+4)
    Когда замыкается pin1, pin2 и pin4 на дисплее пишется "gerkon=7" (1+2+4)
    и так до "gerkon=15"
    Я хочу выводить информацию с герконов в цикле for, в скетче приведённом вами выше,
    т.е. нажали кнопку ENTER двигатель крутится, нажали BRAKE (он же pin1 у меня) двигатель остановился,здесь я могу вывести "gerkon=1" (раз двигатель стоит значит pin1 замкнут),дальше цикл for двигатель запускается 7 раз на 45 градусов и при каждой остановке магнит встаёт напротив определённого геркона (при каждой остановке необходимо вывести информацию с геркона на LCD т.е. проверять какие из 4-х пинов замкнуты).
    За ранее благодарю!!!
     
  13. sslobodyan

    sslobodyan Гик

    Покажите свой скетч где вы пытаетесь вывести информацию, я подправлю. В этом разделе форума принято помогать, но не писать готовое решение. Готовые решения в разделе "Закажу проект" ;)
     
  14. IgOrKIPiA

    IgOrKIPiA Нуб


    Вот полный скетч, после решения последней проблемы проект можно считать законченным. Ниже после условия switch(x) начиная с case1:
    не могу понять как мне вывести на дисплей текущее положение пинов, нужно высчитать какие замкнуты, а какие разомкнутые и исходя из ихнего положения вывести информацию.
    (PIN_1-замкнут;PIN_2-разомкнут;PIN_4-разомкнут;PIN_8-разомкнут)=1
    (PIN_1-разомкнут;PIN_2-замкнут;PIN_4-разомкнут;PIN_8-разомкнут)=2
    (PIN_1-замкнут;PIN_2-замкнут;PIN_4-разомкнут;PIN_8-разомкнут)=3......
    .......
    (PIN_1-замкнут;PIN_2-замкнут;PIN_4-замкнут;PIN_8-замкнут)=15
    Мне хотя бы образец от чего оттолкнутся.
    Извиняюсь за море писанины. Пытаюсь как можно яснее отобразить свой вопрос.
    В самом коде я отметил где нужен вывод информации:
    Код (C++):
     #include <LiquidCrystal_I2C.h>
    #include <Wire.h>
    #include <RotaryEncoder.h>
    #include <Stepper_28BYJ.h>
    RotaryEncoder encoder(56, 57);                             // аналоговые входы (mega2560) энкодера
    LiquidCrystal_I2C lcd(0x27,16,2);                          // адрес, кол-во символов, кол-во строк
    #define ENTER 8                                             // кнопка энкодера
    #define PIN_1 9                                             // геркон 1
    #define PIN_2 10                                            // геркон 2
    #define PIN_4 11                                            // геркон 4
    #define PIN_8 12                                            // геркон 8
    #define NUM_CYCLES1 7                                       // количество циклов по 45 градусов
    #define NUM_CYCLES2 9                                       // количество циклов по 36 градусов
    #define NUM_CYCLES3 13                                      // количество циклов по 26 градусов
    int result = 1;                                             // переменная для энкодера
    const int stepsPerRevolution = 4096;                        // количество шагов на один оборот
    Stepper_28BYJ myStepper_28BYJ(stepsPerRevolution, 4,5,6,7); // цифровые входы ( IN_1 = 4; IN_2 = 5;IN_3 = 6; IN_4 = 7 ) на ULN 2003    
    void setup() {
    myStepper_28BYJ.setSpeed(3);                                // скорость двигателя 3 об/мин
    pinMode(ENTER, INPUT_PULLUP);
    pinMode(PIN_1, INPUT_PULLUP);
    pinMode(PIN_2, INPUT_PULLUP);
    pinMode(PIN_4, INPUT_PULLUP);
    pinMode(PIN_8, INPUT_PULLUP);
    lcd.init();                                                // инициализация LCD 1602
    lcd.backlight();                                           // включаем подсветку дисплея                                                                  
    lcd.setCursor(0, 0);                                       // устанавливаем курсор в начало 1-ой строки
    lcd.print("      TEST      ");                             // выводим надпись в 1-ой строке
    lcd.setCursor(0, 1);                                       // устанавливаем курсор в начало 2-ой строки
    lcd.print(" Kodovoi maski! ");                             // выводим надпись во 2-ой строке
    delay(3000);                                               // ждём
    lcd.setCursor(0, 1);                                       // устанавливаем курсор в начало 2-ой строки
    lcd.print("                ");                             // выводим надпись во 2-ой строке
    }
    void loop() {
      lcd.setCursor(0, 0);
    lcd.print(" Please Select: ");
    static int pos = 0;
    encoder.tick();
    int newPos = encoder.getPosition();
    if (pos < newPos) result++;
    if (pos > newPos) result--;
    if (result > 3) result = 1;
    if (result < 1) result = 3;
    if (pos != newPos) pos = newPos;
    if (result == 1)
    {
    lcd.setCursor(0, 1);
    lcd.print("        8        ");    
    }
    if (result == 2)
    {
    lcd.setCursor(0, 1);
    lcd.print("       10       ");    
    }
    if (result == 3)
    {
    lcd.setCursor(0, 1);
    lcd.print("       14       ");    
    }
     
        // ждем отпускания кнопки
      while ( !digitalRead(ENTER) ) delay(50);

      // ждем нажатие кнопки
      while ( digitalRead(ENTER) ) delay(50);
    lcd.setCursor(0, 0);
      lcd.print("POZICIONIROVANIE");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      // делаем шажки пока не упремся в геркон
      while ( digitalRead(PIN_1) )
      {
        myStepper_28BYJ.step( 1 );
      }
      switch(result)
    {
    case 1:
      lcd.setCursor(0, 0);
      lcd.print("     Otvod 1    ");      // позиция магнита
      lcd.setCursor(0, 1);
      lcd.print("     gerkon=1   ");    //  сработал концевик PIN_1, он же первый по порядку геркон.
      delay(3000);
      // несколько циклов поворота на 45 градусов и остановки на 3 секунды
      for(byte x=0; x<NUM_CYCLES1; x++) {
        switch(x)
        {
          case 0:
          {
          lcd.setCursor(0, 0);
          lcd.print("     Otvod 2    ");  // магнит отправился ко второму геркону
          }
          break;
          case 1:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("     Otvod 3    "); // магнит отправился к третьему геркону
          }
          break;
           case 2:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("     Otvod 4    ");  // магнит отправился к четвёртому геркону
          }
          break;
           case 3:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("     Otvod 5    ");  // магнит отправился ко пятому геркону
          }
          break;
           case 4:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("     Otvod 6    "); // магнит отправился к шестому геркону
          }
          break;
           case 5:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("     Otvod 7    ");  // магнит отправился к седьмому геркону
          }
          break;
           case 6:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("     Otvod 8    ");  // магнит отправился к восьмому геркону
          }
          break;
           case 7:
          {
    /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" ,
    если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/

          lcd.setCursor(0, 0);
          lcd.print("         ");
          }
          break;
        }
        myStepper_28BYJ.step( -(long) 45 * stepsPerRevolution / 360 );
        delay(3000);
      }
     

    }
    }
     
  15. IgOrKIPiA

    IgOrKIPiA Нуб

    Весь код не влез, но там всё то-же самое, только больше переключений 9 раз на 36 градусов и 13 раз на 26 градусов. Как вариант можно выводить сразу после цикла for не углубляясь в switch(x), но опять же я не знаю как ☹️☹️☹️.
     
  16. sslobodyan

    sslobodyan Гик

    1. Посмотрите на куски кода в switch. Не кажется ли вам, что они все похожи? Разница только в одном числе, которое напрямую зависит от Х? Давайте их сразу заменим одним куском вот так:
    Код (C++):
    for(byte x=0; x<NUM_CYCLES1; x++) {
          lcd.setCursor(0, 0);
          lcd.print("     Otvod ");
          lcd.print(x+2);
          lcd.print("    ");  // магнит отправился к X геркону
          /* здесь нужно условие для вывода инфы (если замкнут PIN_1 , то"GERKON=1", если PIN_2 ,то"GERKON=2" , если PIN_1 && PIN_2 , то"GERKON=3", если PIN_4 ,то"GERKON=4" и т.д. (GERKON=15 максимальное значение замкнуты все 4 пина 1+2+4+8=15).*/
    }
    Теперь составляем таблицу соответствия состояния пинов и вывода номера геркона.
    4 3 2 1 - пины
    0 0 0 1 геркон1
    0 0 1 0 геркон2
    0 0 1 1 геркон3
    0 1 0 0 геркон4 и так далее.
    Ничего не напоминает? Я вижу запись целого числа в бинарной форме. Вот вам и разгадка как вывести номер вашего геркона по состоянию пинов - умножьте состояние каждого геркона на степень двойки номера пина. То есть Пин4*8+Пин3*4+Пин2*2+Пин1 и будет ваш искомый номер. Напомню, что чтение состояния пина дает 1 когда на пине высокий уровень. У нас получается что геркон замыкается и на входе низкий уровень. Так мы его просто инвертируем. Итого предложу вот такой вариант цикла:
    Код (C++):
    for(byte x=0; x<NUM_CYCLES1; x++) {
          lcd.setCursor(0, 0);
          lcd.print("     Otvod ");
          lcd.print(x+2);
          lcd.print("    ");  // магнит отправился к X геркону

          lcd.setCursor(1, 0); // забыл что первое - строка или колонка - подправьте сами
          lcd.print("Gerkon ");
          byte g=(!digitalRead(PIN_4)*8) + (!digitalRead(PIN_3)*4)  + (!digitalRead(PIN_2)*2) + (!digitalRead(PIN_1));
          lcd.print(g);
    }
    Пробуйте.
     
    IgOrKIPiA нравится это.
  17. IgOrKIPiA

    IgOrKIPiA Нуб

    Огромное спасибо!!! Пришёл с работы сразу начал пробовать. Всё встало идеально ,единственное только сейчас понял ,что в момент позиционирования двигатель остановиться когда замкнётся PIN_1 и в предыдущей версии он бы останавливался на 1; 3; 5; 7; 9; 11; 13; герконах, поэтому поменял
    while ( digitalRead(PIN_1)) на
    while ( digitalRead(PIN_1)+!digitalRead(PIN_8) + !digitalRead(PIN_4) + !digitalRead(PIN_2)).
    теперь срабатывает только при условии PIN_1 замкнут, остальные разомкнуты. Благодаря вам я много нового подчерпнул для себя спасибо большое!!!
    Код (C++):
       // ждем отпускания кнопки
      while ( !digitalRead(ENTER) ) delay(50);
      // ждем нажатие кнопки
      while ( digitalRead(ENTER) ) delay(50);
    lcd.setCursor(0, 0);
      lcd.print("POZICIONIROVANIE");
      lcd.setCursor(0, 1);
      lcd.print("                ");
      // делаем шажки пока не упремся в геркон
      while ( digitalRead(PIN_1)+!digitalRead(PIN_8) + !digitalRead(PIN_4)  + !digitalRead(PIN_2))
      {
        myStepper_28BYJ.step( 1 );
      }
       lcd.setCursor(0, 0);
         lcd.print("     Otvod 1    ");
          lcd.setCursor(0, 1);
          lcd.print("Gerkon=1 ");
      delay(3000);
      for(byte x=0; x<NUM_CYCLES1; x++) {
          lcd.setCursor(0, 0);
          lcd.print("     Otvod ");
          lcd.print(x+2);
          lcd.print("    ");  // магнит отправился к X геркону
          lcd.setCursor(0, 1); // забыл что первое - строка или колонка - подправьте сами
          lcd.print("Gerkon=");
          byte g=(!digitalRead(PIN_8)*8) + (!digitalRead(PIN_4)*4)  + (!digitalRead(PIN_2)*2) + (!digitalRead(PIN_1));
          lcd.print(g);
          myStepper_28BYJ.step( -(long) 45 * stepsPerRevolution / 360 );
          delay(3000);
    }
    }
     
  18. sslobodyan

    sslobodyan Гик

    Рад помочь :cool:
     
  19. IgOrKIPiA

    IgOrKIPiA Нуб

    При выводе символов выше 10 остаются лишние цифры. Поэтому после lcd.print(g); ввёл lcd.print(" ");
    и всё стало отлично ни лишних, нолей ни единиц....)))
    Код (C++):
     for(byte x=0; x<NUM_CYCLES1; x++)
    {
    lcd.setCursor(0, 0);
    lcd.print("     Otvod ");
    lcd.print(x+1);
    lcd.print("    ");  // магнит отправился к X геркону
    lcd.setCursor(0, 1);
    lcd.print("Gerkon=");
    byte g=(!digitalRead(PIN_8)*8) + (!digitalRead(PIN_4)*4)  + (!digitalRead(PIN_2)*2) + (!digitalRead(PIN_1));
    lcd.print(g);
    lcd.print("   ");
    myStepper_28BYJ.step( -(long) 45 * stepsPerRevolution / 360 );
    delay(3000);
    }
     
  20. IgOrKIPiA

    IgOrKIPiA Нуб

    И снова здравствуйте! Столкнулся с такой проблемой. Собрал проект по написанному с вашим непосредственным участием коду))), всё как бы работает, кроме энкодера (у энкодера работает только кнопка). Если закомментировать предложенный вами код, энкодер работает. Собирал проект на Arduino nano. Места много скетч не занимает (
    Sketch uses 6 732 bytes (21%) of program storage space. Maximum is 30 720 bytes.
    Global variables use 671 bytes (32%) of dynamic memory, leaving 1 377 bytes for local variables. Maximum is 2 048 bytes.)
    Попробовал ускорить ардуинку с помощью #include <CyberLib.h> не помогает.
    Не подскажете в чём беда?
    Код (C++):
    #include <CyberLib.h>
    #include <LiquidCrystal_I2C.h>
    #include <Wire.h>
    #include <RotaryEncoder.h>
    #include <Stepper_28BYJ.h>
    RotaryEncoder encoder(16,17);                               // аналоговые входы энкодера
    LiquidCrystal_I2C lcd(0x3F,16,2);                           // адрес, кол-во символов, кол-во строк
    #define ENTER 2                                             // кнопка энкодера
    #define PIN_1 3                                             // геркон 1
    #define PIN_2 4                                             // геркон 2
    #define PIN_4 5                                             // геркон 4
    #define PIN_8 6                                             // геркон 8
    #define NUM_CYCLES1 8                                       // количество циклов по 45 градусов
    #define NUM_CYCLES2 10                                      // количество циклов по 36 градусов
    #define NUM_CYCLES3 14                                      // количество циклов по 26 градусов
    int result = 1;                                             // переменная для энкодера
    const int stepsPerRevolution = 4096;                        // количество шагов на один оборот
    Stepper_28BYJ myStepper_28BYJ(stepsPerRevolution, 9,10,11,12);
    //long lcdUpdate;  

    void setup()
    {
    myStepper_28BYJ.setSpeed(3);                               // скорость двигателя 3 об/мин
      D2_In;                                                    // pinMode(ENTER, INPUT);  
      D3_In;                                                    // pinMode(PIN_1, INPUT);
      D4_In;                                                    // pinMode(PIN_2, INPUT);
      D5_In;                                                    // pinMode(PIN_4, INPUT);
      D6_In;                                                    // pinMode(PIN_8, INPUT);
    lcd.init();                                                // инициализация LCD 1602
    lcd.backlight();                                           // включаем подсветку дисплея
    lcd.setCursor(4, 1);                                       // устанавливаем курсор после 4-го символа 2-ой строки
    lcd.print("PRESENT");                                      // выводим надпись во 2-ой строке
    delay_ms(4000);                                            // ждём
    lcd.setCursor(0, 0);                                       // устанавливаем курсор в начало 1-ой строки
    lcd.print("   TECT MACOK   ");                             // выводим надпись в 1-ой строке
    lcd.setCursor(0, 1);
    lcd.print("8; 10; 14; OTB-B");

    delay_ms(4000);                                            // ждём
    }
    void loop()
    {
    lcd.setCursor(0, 0);
    lcd.print(" Please Select: ");
    static int pos = 0;
    encoder.tick();
    int newPos = encoder.getPosition();
    if (pos < newPos) result++;
    if (pos > newPos) result--;
    if (result > 3) result = 1;
    if (result < 1) result = 3;
    if (pos != newPos) pos = newPos;
    if (result == 1)
    {
    lcd.setCursor(0, 1);
    lcd.print("        8        ");    
    }
    if (result == 2)
    {
    lcd.setCursor(0, 1);
    lcd.print("       10       ");    
    }
    if (result == 3)
    {
    lcd.setCursor(0, 1);
    lcd.print("       14       ");    
    }
    // ждем отпускания кнопки
    while ( !D2_Read ) delay_ms(50);
    // ждем нажатие кнопки
    while ( D2_Read ) delay_ms(50);
    lcd.setCursor(0, 0);
    lcd.print("POZICIONIROVANIE");
    // делаем шажки пока не упремся в геркон
    while ( !D3_Read +D4_Read + D5_Read  + D6_Read)
    {
    myStepper_28BYJ.step( 1 );
    }
    lcd.setCursor(0, 0);
    lcd.print("     Otvod 1    ");
    lcd.setCursor(0, 1);
    lcd.print("Gerkon=1 ");
    delay_ms(3000);
    switch(result)
    {
    case 1:
    for(byte x=0; x<NUM_CYCLES1; x++)
    {
    lcd.setCursor(0, 0);
    lcd.print("     Otvod ");
    lcd.print(x+1);
    lcd.print("    ");  // магнит отправился к X геркону
    lcd.setCursor(0, 1);
    lcd.print("Gerkon=");
    byte g=(D6_Read*8 + D5_Read*4  + D4_Read*2 + D3_Read);
    lcd.print(g);
    lcd.print("   ");
    myStepper_28BYJ.step( -(long) 45 * stepsPerRevolution / 360 );
    delay_ms(3000);
    }
    break;
    case 2:
    for(byte x=0; x<NUM_CYCLES2; x++)
    {
    lcd.setCursor(0, 0);
    lcd.print("     Otvod ");
    lcd.print(x+1);
    lcd.print("    ");  // магнит отправился к X геркону
    lcd.setCursor(0, 1);
    lcd.print("Gerkon=");
    byte g=(D6_Read*8 + D5_Read*4  + D4_Read*2 + D3_Read);
    lcd.print(g);
    lcd.print("   ");
    myStepper_28BYJ.step( -(long) 36 * stepsPerRevolution / 360 );
    delay_ms(3000);
    }
    break;
    case 3:
    for(byte x=0; x<NUM_CYCLES3; x++)
    {
    lcd.setCursor(0, 0);
    lcd.print("     Otvod ");
    lcd.print(x+1);
    lcd.print("    ");  // магнит отправился к X геркону
    lcd.setCursor(0, 1);
    lcd.print("Gerkon=");
    byte g=(D6_Read*8 + D5_Read*4  + D4_Read*2 + D3_Read);
    lcd.print(g);
    lcd.print("   ");
    myStepper_28BYJ.step( -(long) 26 * stepsPerRevolution / 360 );
    delay_ms(3000);
    }
      break;
    }
    }