не могу понять в чем дело.

Тема в разделе "Arduino & Shields", создана пользователем An4ous, 2 авг 2019.

  1. An4ous

    An4ous Нерд

    Доброго времени суток. Делаю контактную сварку на ардуино, совместно с энкодером и цифровым индикатором. сварка имеет 2 режима. Первый режим это одиночный импульс, второй режим двойной импульс.Проблема в том что при активации двойного импульса происходит своего радо баг, при выставлении задержки в 180мс и более программа скидывается на одиночный режим, при более меньшей задержке проблемы не надлюдается.
    Я предполагаю что баг кроется в библиотеке, прошу глянуть кто понимает, я вот ничего не понимаю, хотя библиотека очень маленькая. Возможно я что то или где то упустил
    Код (C++):

    //enc-
    #define SW  6
    #define CLK 5
    #define DT  4

    //digit
    #define CLKL 3
    #define DIO 2

    #include "Encoder.h"
    #include "TM1637.h"
    TM1637 disp(CLKL, DIO);
    Encoder enc1(CLK, DT, SW);

    boolean DoubleImpilse = false; //режим сварки, 0- одиночный импульс 1-двойной импульс.
    int fire = 8;      //на этом пине выход на релле
    int start = 300;   //стартовое значение выдержки
    int Step = 5;    //шаг при обороте энкодера


    //--- ОБЪЯВЛЕНИЕ ---

    void setup() {
      Serial.begin(9600);
      pinMode(fire, OUTPUT);// устанавливаем пин 8 как выход
      digitalWrite(fire, HIGH);
      disp.clear();
      disp.brightness(7);  // яркость, 0 - 7 (минимум - максимум)
      disp.displayInt(start);
    }

    void loop() {
      // обязательная функция отработки. Должна постоянно опрашиваться
      enc1.tick();

      // если была удержана и энк не поворачивался
      if (enc1.isHolded())
      {
        enc1.isHold();
        if (!DoubleImpilse) {
          DoubleImpilse = true;
          disp.displayInt(start);
        }
        else if (DoubleImpilse)
        {
          DoubleImpilse = false;
          disp.displayInt(start);
        }
      }


      // если был поворот
      if (enc1.isRight())
      {
        start = start - Step;
        if (start < 10) start = 10;
        if (start > 995)start = 990;
        disp.displayInt(start);
      }


      if (enc1.isLeft())
      {
        start = start + Step;
        if (start < 10) start = 10;
        if (start > 995)start = 990;
        disp.displayInt(start);

      }

      if (enc1.isPress()) {   // Если было одиночное нажатие то.

        if (!DoubleImpilse) {
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
        }

        if (DoubleImpilse) {
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
          delay(start);
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
        }
      }

      if (DoubleImpilse) {
        disp.displayByte(0, 0x40);
      }
      else {
        disp.displayByte(0, 0x00);
      }
    }
     
    Последнее редактирование: 3 авг 2019
  2. ostrov

    ostrov Гуру

    Я перечитал раз пять, но так и не понял в чем проблема. Вот этот кусок не отрабатывается что ли?
    Код (C++):
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
          delay(start);
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
    Вообще, единственное место, где происходит смена режима это:
    Код (C++):
    // если была удержана и энк не поворачивался
      if (enc1.isHolded())
      {
        enc1.isHold();
        if (!DoubleImpilse) {
          DoubleImpilse = true;
          disp.displayInt(start);
        }
        else if (DoubleImpilse)
        {
          DoubleImpilse = false;
          disp.displayInt(start);
        }
      }
    То есть, пауза при выполнении двойного импульса превышает некое время, которое считается удержанием энкодера нажатым в библиотеке (180х3 > 500). Значит, либо увеличить ее, либо написать программу по уму, без делеев и сторонних библиотек.
     
    arkadyf и NikitOS нравится это.
  3. An4ous

    An4ous Нерд

    Описать детально проблему сложновато. но все же попробую.
    При долгом нажатии кнопки энкодера я попадаю сюда enc1.isHolded(),
    так как у меня DoubleImpilse =false то соответственно флаг меняется на true под этим флагом второй режим сварки
    Код (C++):
    if (enc1.isHolded())
      {
        enc1.isHold();
        if (!DoubleImpilse) {
          DoubleImpilse = true;
          disp.displayInt(start);
        }
        else if (DoubleImpilse)
        {
          DoubleImpilse = false;
          disp.displayInt(start);
        }
      }
    теперь у меня включен режим двойного импульса. и при одиночном нажатии на кнопку выполняется следующий код
    Код (C++):

    if (enc1.isPress()) {   // Если было одиночное нажатие то.

        if (!DoubleImpilse) {
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
        }

        if (DoubleImpilse) {// конкретно это условие будет выполняться так как DoubleImpilse=true
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
          delay(start);
          digitalWrite(fire, LOW);
          delay(start);
          digitalWrite(fire, HIGH);
        }
      }
    все работает прекрасно, но стоит мне подкрутить выдержку более 180ms то после повторного нажатия автоматически срабатывает условие enc1.isHold();( долгое нажатие на энк), соответственно в переменой DoubleImpilse меняется флаг на false и режим скидывается на одиночный импульс. . при более меньших задержках проблем нет. поэтому предполагаю что баг заключается в библиотеке, но я там ничего не понимаю.
    Я уже думал что библиотека не дружит с Delay, и в этом суть проблемы.
     
  4. An4ous

    An4ous Нерд

    Спасибо, действительно увеличить время было проще всего.