Автомат розлива жидкостей на TM1637 и матричной клавиатуре

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

  1. aleksunches

    aleksunches Нуб

    Есть задача создать автомат для разлива жидкостей. Часть кода с обработкой и подсчетом импульсов хоть и коряво, но вроде работает.
    Код (C++):
    #include "TM1637.h"

    void DispUpdate(void);
    boolean DebounceButton(int ScanPort, boolean last);

    #define INC 2 //Пин подключения датчика готовой продукции
    #define RES 3 //Пин подключения кнопки сброса счетчика
    #define LED 13
    #define LEK 12

    #define CLK 4 //TM1637 CLK
    #define DIO 5 //TM1637 DIO

    int8_t CountDisp[] = {0x00,0x00,0x00,0x00};

    static int Counter = 0; //Значение счетчика будет сохраняться здесь
    float indata;

    bool INCCurr = false;
    bool INCPrev = false;

    /*
    * Создаем объект tm1637 класса TM1637
    * в качестве параметров передаём ему
    * номера пинов к которым подключен модуль
    * с дисплеем
    */

    TM1637 tm1637(CLK, DIO);

    void setup()
    {
      Serial.begin(9600);
      pinMode(INC, INPUT);  //Определяем пины подключения кнопки сброса
      pinMode(RES, INPUT);  //и датчика готовой продукции как входные
      pinMode(LED, OUTPUT);
      pinMode(LEK, OUTPUT);

      //Инициализация дисплея на базе драйвера TM1637
      tm1637.init();
      /*
       * Установка яркости свечения сегментов
       * возможные значения:  BRIGHT_TYPICAL либо 2
       *                      BRIGHT_DARKEST либо 0
       *                      BRIGHTEST      либо 7
       * Также можно вводить значения от 0 до 4
       * при вводе начения свыше 4 визуального различия  
       * в яркости свечения не наблюдается поэтому решено
       * остановиться на 3
       */

      tm1637.set(2);
    }

    void loop()
    {
      if (Serial.available() > 0)
      {
        indata = Serial.parseFloat();
        Serial.println(indata);
      }
      //Обнуление счетчика
      if(digitalRead(RES))
      {
        Counter = 0;
      }
     
      //Проверка кнопки инкремента - нажатие и обработка "Антидребезг"
      INCCurr = DebounceButton(INC, INCPrev);
      if (Counter > (indata)*100)
    {
      if (Counter = (indata)*100)
    {
    Counter=0;
    }
      digitalWrite(LED,1);
      digitalWrite(LEK,1);
    }
    else
    {
      digitalWrite(LED,0);
      digitalWrite(LEK,0);
    }

      if(INCPrev == false && INCCurr == true)
      {
        if(Counter == 9999)
        {
          Counter = 0;
        }
        else
        {
          Counter ++;
        }
      }
      INCPrev = INCCurr;
     
      DispUpdate();
    }

    //Функция подавления дребезга контактов концевого датчика
    boolean DebounceButton(int ScanPort, boolean last)
    {
      boolean current = digitalRead(ScanPort);
      if(current != last)
      {
        delay(5);
        current = digitalRead(ScanPort);
      }
      return current;
    }

    //Функция обновления дисплея
    //Вывод значения счетчика на дисплей
    void DispUpdate(void)
    {
      int intValue = Counter;
      int divValue;
     
      for(int i = 3; i >= 0; i --)
      {
        divValue = intValue % 10;
        intValue = intValue / 10;
       
        CountDisp[i] = divValue;
      }
      tm1637.display(CountDisp);
    }
    Сейчас проблема в том чтобы с помощью матричной клавиатуры 3х4, ввести число с десятичной точкой, вывести его на ТМ1637 и уже затем включить обратный отсчет. Никак не могу понять как обработать знак десятичной точки и в каком формате должны быть данные для вывода на дисплей. Вот код обработки клавиатуры
    Код (C++):
    #include "Keypad.h"
    #include "TM1637.h"

    #define CLK 4 //TM1637 CLK
    #define DIO 5 //TM1637 DIO
    const byte ROWS = 4;  //  количество рядов
    const byte COLS = 3;  //  количество столбцов
    char keys[ROWS][COLS] = {
    {'7','8','9'},
    {'4','5','6'},
    {'1','2','3'},
    {'0','0','.'}
    };

    TM1637 tm1637(CLK, DIO);
    byte rowPins[ROWS] = {12, 11, 10, 9};  //  контакты для рядов:
                                        //  R1 = D8, R2 = D7,
                                        //  R3 = D6, R4 = D5
    byte colPins[COLS] = {6, 7, 8};     //  контакты для столбцов:
                                        //  C1 = D4, C2 = D3, C3 = D2
    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
    int n = 0;//номер текущей цифры
    char str[5]; // тут положим трехзначное число. 4 элемента в массиве так как в с++ строка должна кончаться 0
    void setup()
    {
      tm1637.init();
      tm1637.set(2);
      Serial.begin(9600);
    }
    void loop(){
      char c = keypad.getKey(); // считываем код символа с клавы
      if(c){// что-то прочитали
          str[n++] = c; //положим в позицию n и увеличим счетчик
          if(n == 4){ // все цифры введены
                str[4] = 0; //положим завершающий 0
                Serial.print("вы ввели:");
                Serial.println(str);
                n = 0;
                tm1637.displayInt(str);
          }
      }
      }
     
  2. DetSimen

    DetSimen Guest

    дак на этой матричной клавиатуре и точки-то нет
     
  3. aleksunches

    aleksunches Нуб

    Вместо знака # будет знак десятичной точки
     
  4. Airbus

    Airbus Радиохулиган Модератор

    Внимательно слежу.С пивом и рыбой
     
  5. parovoZZ

    parovoZZ Гуру

    вотка и селетка
     
    Airbus нравится это.
  6. Airbus

    Airbus Радиохулиган Модератор

    Не увидел розлива пива в коде.Какие то странные движухи .Тема про розлив пива уже была и про водосчетчики тоже.Поэтому с интересом наблюдаю как снова изобретают велосипед.
     
  7. aleksunches

    aleksunches Нуб

    Подсчет импульсов я нашел и наладил. А вот с вводом числа с десятичной точкой и отображением его на индикаторе запутался. Чего глумится то сразу?
     
  8. Ariadna-on-Line

    Ariadna-on-Line Гуру

    Точка обычно - старший бит байта знакоместа. Если единица - b00000110, то единица с точкой - b10000110 (b00000110 + 128), В библиотеке - точки знакомест - вроде как не задействованы. А в микре - есть, но не факт, что есть в матрицах. Поэтому сначала надо прозванивать схему модуля, чтоб принимать решение.
     
    Последнее редактирование: 27 мар 2019
    arkadyf нравится это.
  9. DetSimen

    DetSimen Guest

    Пропробуй, это ввод числа с плавающей точкой

    Код (C++):
    void loop() {
        char buf[20];
        char ch;
        uint8_t idx = 0;

        while ((ch = keypad.getKey()) != '#') {      // считываем код символа с клавы
        if (ch == '*') ch = '.';
        buf[idx++] = ch;
        }

        buf[idx] = 0;

        float number = strtod(buf, NULL);

        Serial.print("Your input = ");
        Serial.println(number);

    }
     
    десятичная точка - символ "*" на твоей клавиатуре
    ввод происходит пока не нажмешь "#". Типа, оналог "Enter".
    не проверял. если работает, так, как нада, принимаюца всяческие плюшки и блаадарности.
     
    Последнее редактирование модератором: 27 мар 2019
    Andrey12 нравится это.
  10. aleksunches

    aleksunches Нуб

    Не работает. В терминал ничего не выводится.
     
  11. DetSimen

    DetSimen Guest

    в последней строчке надо оставить как было {'*','0','#'}
     
  12. DetSimen

    DetSimen Guest

    ввод завершается '#', десятичная точка - '*'
     
  13. aleksunches

    aleksunches Нуб

    Я догадался и сразу так сделал, но не работает. Вот полный код.
    Код (C++):
    #include "Keypad.h"
    #include "TM1637.h"

    #define CLK 4 //TM1637 CLK
    #define DIO 5 //TM1637 DIO
    const byte ROWS = 4;  //  количество рядов
    const byte COLS = 3;  //  количество столбцов
    char keys[ROWS][COLS] = {
    {'7','8','9'},
    {'4','5','6'},
    {'1','2','3'},
    {'*','0','#'}
    };

    TM1637 tm1637(CLK, DIO);
    byte rowPins[ROWS] = {12, 11, 10, 9};  //  контакты для рядов:
                                        //  R1 = D8, R2 = D7,
                                        //  R3 = D6, R4 = D5
    byte colPins[COLS] = {6, 7, 8};     //  контакты для столбцов:
                                        //  C1 = D4, C2 = D3, C3 = D2
    Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
    void setup()
    {
      tm1637.init();
      tm1637.set(2);
      Serial.begin(9600);
    }
    void loop() {
        char buf[20];
        char ch;
        uint8_t idx = 0;

        while ((ch = keypad.getKey()) != '#') {      // считываем код символа с клавы
        if (ch == '*') ch = '.';
        buf[idx++] = ch;
        }

        buf[idx] = 0;

        float number = strtod(buf, NULL);

        Serial.print("Your input = ");
        Serial.println(number);

    }
     
  14. DetSimen

    DetSimen Guest

    ну, будем считать, я збадуна х-ню сморозил-с, в который раз. Жди более грамматнава
     
  15. aleksunches

    aleksunches Нуб

    Вставил волшебную строчку преобразования char в float в свой код, и заработало. Но беда в том что после второго - третьего ввода числа ардуинка виснет наглухо.
    Код (C++):
    void loop(){
      char c = keypad.getKey(); // считываем код символа с клавы
      if(c){// что-то прочитали
          str[n++] = c; //положим в позицию n и увеличим счетчик
          if(n == 4){ // все цифры введены
                str[4] = 0; //положим завершающий 0
                float number = strtod(str, NULL);
                Serial.print("вы ввели:");
                int pokaz = number;
                Serial.println(pokaz);
                tm1637.displayInt(pokaz);
                n = 0;
          }
      }
      }
     
  16. DetSimen

    DetSimen Guest

    а getKey() чо отдает, когда ничо не нажато? Если #0, то яво пропускать надо

    Код (C++):
    void loop() {
        char buf[20];
        char ch;
        uint8_t idx = 0;

        while ((ch = keypad.getKey()) != '#') {      // считываем код символа с клавы
         if (ch==0) continue;
         if (ch == '*') ch = '.';
        buf[idx++] = ch;
        }

        buf[idx] = 0;

        float number = strtod(buf, NULL);

        Serial.print("Your input = ");
        Serial.println(number);

    }
     
    Последнее редактирование модератором: 27 мар 2019
    aleksunches нравится это.
  17. aleksunches

    aleksunches Нуб

    если убрать строчку displayInt() то ардуинка не виснет
     
  18. DetSimen

    DetSimen Guest

    Бывает...
     
  19. aleksunches

    aleksunches Нуб

    Что-то не так в библиотеке ТМ1637 или я просто её не правильно использую?
     
  20. DetSimen

    DetSimen Guest

    ну дак ты запустил код из #16?