Доброго времени суток! Создал проект весового дозатора тремя компонентами на ардуино. платформа 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 или нужно использовать другое ацп?
Реализовать что? - сохранение веса между выключениями и подстройку по двум точкам? - и то и другое реализуется в программе и от модели АЦП не зависит
я рад за вас. Вы правда думаете, что кто-то будет скачивать весь ваш код и разбираться в нем бесплатно? Если у вас есть конкретный вопрос - попробуйте сократить код до того размера, что допускает форум и обсудить проблему на сокращенном коде
это кусочки из программы что касается весов и калибровки Код (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)); }
вопрос по калибровке - а реально нужна калибровка по двум точкам? Стандартная весовая ячейка и правильно настроенный модуль HX711 должны работать таким образом, чтобы у них не было зависимости погрешности от веса. Если это так - калибровка по двум точкам не нужна, достаточно только смещения нуля. Я собирал весы на HX711, кроме начальной поправки ничего не вводил - точность была постоянная во всем диапазоне
Если оно так и будет то можно и оставить. Самый главный вопрос это в обнуленеии после reset ардуины. Нужно чтобы она после перезагрузки считывала показания на весах. Просто если во время дозирования перезагрузили ардуину, и материал остался на весах она его за ноль посчитает и будут проблеммы с отгрузкой материала
Так не обнуляйте Вы же его сами обнуляете.... У вас сейчас в коде в setup() стоит строчка scale.tare() - именно она отвечает за то, что начальный вес на весах принимается за ноль. И у вас это делается при каждом ресете. Правильно сделать так - обнулять вес на весах только при нажатии какой-то кнопки. При этом высчитывать то, что вы называете "дискретой" и записывать в ЕЕПРОМ. А при запуске не тарировать весы заново, а читать дискрету из ЕЕПРОМа. Тогда у вас весы всегда будут считать вес от нуля.
что-то типо такого смог изобрести Код (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; }
Этого недостаточно. Вы сделали обнуление по кнопке. Теперь надо еще добавить считывание дискреты из весов, сохранение в ЕЕПРОМ, а после рестарта - перекалибровка весов дискретой из ЕЕПРОМа
и что вы хотите от форума? Есть библиотека ЕЕПРОМ с примерами. есть куча гайдов в сети. Начните с того, что изучите хоть одно описание, попробуйте примерчик запустить. Потом вставить этот пример в свой код. Будут вопросы - приходите. "Я не умею работать с..." - это не вопрос.