Весовой дозатор на ардуино для трех компонентов

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

  1. Professor

    Professor Нуб

    Доброго времени суток! Создал проект весового дозатора тремя компонентами на ардуино.
    платформа Arduino nano
    АЦП xh711
    дисплей LCD2004
    три кнопки для управления и энкодер
    подключалось все вот так
    1)
    Энкодер ардуина
    CLK D2
    DT D3
    SW D4
    + VCC
    GND GND

    2) 4 кнопки, одним контактом все кнопки к GND ардуины,
    вторые контакты кнопок к D5, D6, D7, D8

    3) экран подключается по шине i2c,
    Экран Ардуина
    GND GND
    VCC VCC
    SDA A4
    SCL A5

    4) Пять реле
    подключаются минусом к GND ардуины,
    а плюсы к контактам D9, D10, D11,D12,D13


    5) Тензорный датчик НХ711 как на картинке подключается
    http://arduinolab.pw/wp-content/uploads/2017/07/04d2c560-8723-447a-a8ef-33f8a02f18cd.jpg
    DT в A1
    CLK в A0


    Сам я побольше части радиолюбитель чем программист. Поэтому обратился за помощью в написании кода к знакомому. Единственный вопрос оставшийся не решённым это при перезагрузки ардуины вес обнуляеться, что не нужно. И калибровка производится подстройкой дискреты. а хотелось бы по двум точкам. Можно ли реализовать данное с XH711 или нужно использовать другое ацп?
     

    Вложения:

    • Pr_001.ino
      Размер файла:
      22,9 КБ
      Просмотров:
      433
  2. b707

    b707 Гуру

    Реализовать что? - сохранение веса между выключениями и подстройку по двум точкам? - и то и другое реализуется в программе и от модели АЦП не зависит
     
  3. Professor

    Professor Нуб

    именно это и нужно. Можете подсказать как сделать
     
  4. Airbus

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

    Если вставите код и схему правильно то да.А так ни одно ни другое не читается.
     
    NikitOS нравится это.
  5. Professor

    Professor Нуб

    не могу вставить код так как он более 10000 символов
    я поэтому его и прикрепил файлом
     
  6. b707

    b707 Гуру

    я рад за вас.
    Вы правда думаете, что кто-то будет скачивать весь ваш код и разбираться в нем бесплатно?

    Если у вас есть конкретный вопрос - попробуйте сократить код до того размера, что допускает форум и обсудить проблему на сокращенном коде
     
  7. Professor

    Professor Нуб

    это кусочки из программы что касается весов и калибровки
    Код (C++):
    int FIRST_INIT = 1; //для записи начальных данных в программы поставить =1 и прошить, потом вернуть в =0 и прошить еще раз


    #include "HX711.h"
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>

    HX711 scale;
    // HX711 circuit wiring
    float mytare = 0;
    float Calibration_Factor = 240.0;
    const int LOADCELL_DOUT_PIN = A1;
    const int LOADCELL_SCK_PIN = A0;
    bool BAUTO = false;

    float current_mass = 0;
    float mass[3] = {0, 0, 0};

    #define CLK 2
    #define DT 3
    #define SW 4
    #include "GyverEncoder.h"
    Encoder enc1(CLK, DT, SW);

    //LiquidCrystal_I2C lcd(0x3F, 20, 4);   // Задаем адрес и размерность дисплея
    LiquidCrystal_I2C lcd(0x27, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display



    int menuWindows = 0; //текущее меню
    int menuY = 0;//выбранная строка меню
    int menuDY = 0; //сдвиг экрана в меню

    long delay_Micros = 1800; // Set value
    long currentMicros = 0;
    long previousMicros = 0;

    byte btStart = 8;
    byte btStop = 7;
    byte btGerkon = 6;
    byte btScores = 5;

    byte CurProgram = 1;
    byte MaxProgram = 3;
    float ttime = 0;

    int State = 0;
    bool bLeft = 0;
    bool bRight = 0;
    bool bPress = 0;
    bool bPressButton = 0;
    int menuState = 1; //1-меняем строку, 2- меняем значение параметра в строке
    int BUTTON_PAUSE = 300; //время деактивации кнопки после нажатия.
    unsigned long lastTurn = 0;
    unsigned long last_lcd = 0;
    unsigned long last_lcd_menu1 = 0;
    unsigned long last = 0;
    unsigned long State_start = 0;
    unsigned long Start_main = 0;
    unsigned long count_turn = 0;
    unsigned long stepper_count = 0;
    unsigned long lcd_time_init = 0;

    unsigned long lastCheckMass = 0; //время последней проверки веса
    struct sbt {
      byte pin;
      String caption;
      unsigned long lastpressed;
      bool laststate;
      bool ispressed;
      int add_value;
    };

    sbt button[4] = {
      {btStart, "btStart", 0, 0, 0, +1},
      {btStop, "btStop", 0, 0, 0, -1},
      {btGerkon, "btGerkon", 0, 0, 0, +1},
      {btScores, "btScores", 0, 0, 0, -1}
    };

    struct smenu {
      String nname;
      String caption;
      int value;
      int valuePlus;
      int amin;
      int amax;
      int eepromadres;
    };
    //***********************************************************************************************************************************************************
    struct srele {
      byte pin;
      String caption; //подпись
      int value; //состояние
      int nextvalue; //текущий режим?
      unsigned long nexttime;
      int zadergkado; //задержка до включения
      int zadergkaposle;  //задержка до выключения
      byte normvalue; //нормально открыт/закрыт
    };
    //***********************************************************************************************************************************************************
    srele RELE[5] = {
      {9, "R1", 0, 0, 0, 0, 0, 0},//реле 1
      {10, "R2", 0, 0, 0, 0, 0, 0},//реле 2
      {11, "R3", 0, 0, 0, 0, 0, 0},//реле 3
      {12, "R4", 0, 0, 0, 0, 0, 0},//реле 4
      {13, "R5", 0, 0, 0, 0, 0, 0} //реле 5
    };
    void setup()
    {
      Serial.begin(57600);
      scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
      delay(100);
      scale.read();
      delay(100);
      scale.set_scale();
      scale.tare(); //Сбросьте масштаб до 0
      delay(100);
      scale.read();
      delay(100);
      scale.set_scale(Calibration_Factor);

      //mytare = scale.get_units(5);
      mytare = 0;
    void loop()
    {

      if (millis() - lastCheckMass > 100)
      {
        if (scale.is_ready()) {

          current_mass = round(scale.get_units(2));
          //long reading = scale.read();
          //Serial.print("HX711 reading: ");
          //Serial.println(reading);
        } else {
          //Serial.println("HX711 not found.");
        }
        lastCheckMass = millis();
      }

      enc1.tick();
      {
    {
                  Calibration_Factor = MENU1[menuY].value;
                  scale.set_scale(Calibration_Factor);
                  delay(100);
                  current_mass = round(scale.get_units(2));
                }
     
  8. b707

    b707 Гуру

    вопрос по калибровке - а реально нужна калибровка по двум точкам?
    Стандартная весовая ячейка и правильно настроенный модуль HX711 должны работать таким образом, чтобы у них не было зависимости погрешности от веса. Если это так - калибровка по двум точкам не нужна, достаточно только смещения нуля.
    Я собирал весы на HX711, кроме начальной поправки ничего не вводил - точность была постоянная во всем диапазоне
     
  9. Professor

    Professor Нуб

    я так понимаю. что один раз подстроил дискрету и сколько гирек не клади он будет показывать точно
     
  10. Professor

    Professor Нуб

    Если оно так и будет то можно и оставить. Самый главный вопрос это в обнуленеии после reset ардуины. Нужно чтобы она после перезагрузки считывала показания на весах. Просто если во время дозирования перезагрузили ардуину, и материал остался на весах она его за ноль посчитает и будут проблеммы с отгрузкой материала
     
  11. b707

    b707 Гуру

    Так не обнуляйте :) Вы же его сами обнуляете....
    У вас сейчас в коде в setup() стоит строчка scale.tare() - именно она отвечает за то, что начальный вес на весах принимается за ноль. И у вас это делается при каждом ресете.

    Правильно сделать так - обнулять вес на весах только при нажатии какой-то кнопки. При этом высчитывать то, что вы называете "дискретой" и записывать в ЕЕПРОМ. А при запуске не тарировать весы заново, а читать дискрету из ЕЕПРОМа. Тогда у вас весы всегда будут считать вес от нуля.
     
  12. parovoZZ

    parovoZZ Гуру

    кому он нужен-то??? Рисуй алгоритм работы программы и выкладывай.
     
  13. Professor

    Professor Нуб

    что-то типо такого смог изобрести
    Код (C++):
    void setup()
    {
      pinMode(BUT, INPUT);
      Serial.begin(57600);
      scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
      delay(100);
      scale.read();
      delay(100);
      scale.set_scale();
      delay(100);
      scale.read();
      delay(100);
      scale.set_scale(Calibration_Factor);

      //mytare = scale.get_units(5);

     

    void loop()
    if (BUT HIGH);
    scale.set_scale();
    scale.tare()
    mytare = 0;

    }
     
  14. b707

    b707 Гуру

    Этого недостаточно. Вы сделали обнуление по кнопке.
    Теперь надо еще добавить считывание дискреты из весов, сохранение в ЕЕПРОМ, а после рестарта - перекалибровка весов дискретой из ЕЕПРОМа
     
  15. Professor

    Professor Нуб

    я не умею работать с EEprom
     
  16. parovoZZ

    parovoZZ Гуру

    ищи поиском. Всплывает раз в месяц.
     
  17. b707

    b707 Гуру

    и что вы хотите от форума?
    Есть библиотека ЕЕПРОМ с примерами. есть куча гайдов в сети. Начните с того, что изучите хоть одно описание, попробуйте примерчик запустить. Потом вставить этот пример в свой код.
    Будут вопросы - приходите.
    "Я не умею работать с..." - это не вопрос.
     
    issaom нравится это.
  18. Un_ka

    Un_ka Гуру

    Что может быть в коде на 10000 строк ? Вы по дополнительным фаилам пробывали его распихивать?
     
  19. b707

    b707 Гуру

    10 тыс символов
     
    DetSimen и Daniil нравится это.