///////////////////////////////////////////////////////////////////////////////
// Скетч весы с автоматическим определением человека (ВСАОЧ) на Arduino Nano //
///////////////////////////////////////////////////////////////////////////////
// Состав материалов:
// - Arduino Nano
// - Дисплей 128X64 (можно заменить на любой другой поддерживаемый библиотекой U8g2lib.h)
// - Кнопки, 1шт
// - Переключатель
// - Аккумулятор 18532
// Подключение контроллера:
// -
// Инициализация библиотек
#include <Arduino.h>
#include <U8g2lib.h>
#include <GyverHX711.h>
#include <EEPROM.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif
#define SEL1 2
#define ENT1 3
#define hold 1000
#define HX711_SLK A0
#define HX711_DT A1
//U8G2_ST7565_ZOLEN_128X64_F_4W_SW_SPI lcd(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* cs=*/ 10, /* dc=*/ 9, /* reset=*/ 8); //для дисплея V2.2 раскоментировать Flip в библиотеке u8x8_d_st7565.с
U8G2_SSD1306_128X64_NONAME_F_SW_I2C lcd(U8G2_R0, /* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // All Boards without Reset of the Display
GyverHX711 sensor(HX711_DT, HX711_SLK, HX_GAIN64_A); // инициализация весового сенсора
// HX_GAIN128_A - канал А усиление 128
// HX_GAIN32_B - канал B усиление 32
// HX_GAIN64_A - канал А усиление 64
////////////////////////////////////////////////////////////////////////////////////
////////////////////////// обьявления переменных ///////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
int page = 0; // страница меню
int select0 = 0; // выбор 0
int select1 = 0; // выбор 1
float ves_izm = 0; // вес измереный
float ves_izm_new = 0; // вес измереный новый
float ves_izm1[] = {0, 0, 0, 0, 0, 0}; // последние 6 измерений
bool ves_end = 0; // окончание измерения
int delta_v = 2;
String human[] = {"АВТО", "Гость", "Иван", "Гульнара", "Лёня", "Илюша"}; // пользователи
float ves[][6] = {
{ 1, 1, 1, 1, 1, 1}, // архив для пользователя Гость
{97, 98, 99, 99, 99, 92}, // архив для пользователя Иван
{60, 60, 60, 60, 60, 60}, // архив для пользователя Гульнара
{40, 40, 40, 40, 40, 40}, // архив для пользователя Лёня
{18, 18, 18, 18, 18, 18}
}; // архив для пользователя Илюша
float ves_mid[] = {0, 0, 0, 0, 0, 0}; // среднее значение весов
String str1, str2 = "0"; // для преобразования в строку
int nomer = 0; // номер пользователя
bool ENT, SEL = 0; // кнопки
int delta = 5; // погрешность определения пользователя кг
int delta2 = 3;
long timer1 = 0; // таймер включения авто режима после измерения
int delay_otkl = 4000; // Время индикации
int delay_izm = 100; // на одно измерение
int step = 0; // шаги измерения
float ves_res = 0;
////////////////////////// настройки при старте контроллера
void setup() {
lcd.begin(); // инициализация дисплея
lcd.setContrast(50); // контраст дисплея
lcd.enableUTF8Print(); // выбор русской кодировки
Serial1.begin(9600); // открытия порта №1 для вывода отладочной информации
//pinMode(ENT1, INPUT_PULLUP); // подтяжка к питанию входов кнопок
//EEPROM.get(0, ves1); // чтение таблицы с весами из памяти
delay(500); // нужно выждать готовность датчика
sensor.tare(); // калибровка нуля. Устанавливает 0
attachInterrupt(0, isr, CHANGE); //прерывание для кнопки 1
attachInterrupt(1, isr2, CHANGE); //прерывание для кнопки 2
}
volatile uint32_t debounce;
void isr() {
// оставим 100 мс таймаут на гашение дребезга
if (millis() - debounce >= 500 && digitalRead(2)) {
debounce = millis();
SEL = 1;
}
}
volatile uint32_t debounce2;
void isr2() {
// оставим 100 мс таймаут на гашение дребезга
if (millis() - debounce2 >= 500 && digitalRead(3)) {
debounce2 = millis();
ENT = 1;
}
}
void loop() {
////////////////////////// картинки иконок сгенерированы из BMP программой Конвертор by Kinguf
static const unsigned char wave[] U8X8_PROGMEM = {
0xFF, 0x3F, 0x01, 0x20, 0x11, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20, 0x45, 0x20, 0xFD, 0x2F, 0x41, 0x28, 0x81, 0x24, 0x81, 0x24, 0x01, 0x23, 0x01, 0x20, 0xFF, 0x3F,
};
if (sensor.available()) {
ves_izm = sensor.read();
ves_izm = ves_izm * 1.0 / 210;
//Serial1.println(ves_izm);
//EEPROM.put(0, ves1); // считывание с памяти
ves_mid[1] = 0;
ves_mid[2] = 0;
ves_mid[3] = 0;
ves_mid[4] = 0;
ves_mid[5] = 0;
for (int i = 0; i < 6; i++) {
ves_mid[1] = ves_mid[1] + ves[0][i]; // вычисление среднего для 2 пользователя
ves_mid[2] = ves_mid[2] + ves[1][i]; // вычисление среднего для 2 пользователя
ves_mid[3] = ves_mid[3] + ves[2][i]; // вычисление среднего для 3 пользователя
ves_mid[4] = ves_mid[4] + ves[3][i]; // вычисление среднего для 4 пользователя
ves_mid[5] = ves_mid[5] + ves[4][i]; // вычисление среднего для 5 пользователя
}
ves_mid[1] = ves_mid[1] / 6.0;
ves_mid[2] = ves_mid[2] / 6.0;
ves_mid[3] = ves_mid[3] / 6.0;
ves_mid[4] = ves_mid[4] / 6.0;
ves_mid[5] = ves_mid[5] / 6.0;
if ((ves_end == 0) and (timer1 + delay_izm < millis)and (ves_izm>3.5)) {
timer1 = millis;
ves_izm1[step] = ves_izm;
step++;
if (step > 5) {
step = 0;
}
for (int i = 0; i < 6; i++) {
ves_res = ves_res + ves_izm1[i];
}
ves_res = ves_res / 6.0;
if abs(ves_res - ves_izm < delta2) {
ves_end = 1;
}
else {
ves_end = 0;
}
Serial1.println(ves_end);
}
if ((nomer == 0) and (ves_end == 1)) {
if (abs(ves_izm - ves_mid[2]) < delta) {
nomer = 2;
}
if (abs(ves_izm - ves_mid[3]) < delta) {
nomer = 3;
}
if (abs(ves_izm - ves_mid[4]) < delta) {
nomer = 4;
}
if (abs(ves_izm - ves_mid[5]) < delta) {
nomer = 5;
}
}
//if (timer1 + delay_otkl < millis) {}
}
switch (page) {
///////////////////// главное меню
case 0:
if (SEL == 1) {
Serial1.println("SEL-0");
SEL = 0;
nomer++;
if (nomer > 5) {
nomer = 0;
}
}
if (ENT == 1) {
Serial1.println("ENT-0");
ENT = 0;
page = 1;
}
break;
///////////////////// меню настроек
case 1:
if (SEL == 1) {
Serial1.println("SEL-1");
SEL = 0;
}
if (ENT == 1) {
Serial1.println("ENT-1");
ENT = 0;
page = 0;
}
break;
}
lcd.clearBuffer(); // очистка экрана
switch (page) {
////////////////////// главное меню
case 0:
//////lcd.setFont(u8g2_font_haxrcorp4089_t_cyrillic);
{
lcd.setFont(u8g2_font_10x20_t_cyrillic);
lcd.setCursor(0, 18);
lcd.print(human[nomer]);
lcd.setFont(u8g2_font_osb35_tf);
lcd.setCursor(0, 64);
lcd.print(ves_izm, 1);
int x = 0;
if (ves_izm < 10) {
x = 28;
}
else if (ves_izm < 100) {
x = 56;
}
else x = 84;
if (ves_end == 1) {
lcd.drawXBMP(x, 31, 14, 14, wave);//28/56/84
}
if (nomer != 0) {
lcd.drawRFrame(81, 0, 47, 27, 4);
lcd.setFont(u8g2_font_t0_11b_mf);
float reg1 = ves[nomer - 1][1];
float reg2 = ves[nomer - 1][2];
str1 = "1 " + String(reg1, 1);
str2 = "2 " + String(reg2, 1);
lcd.setCursor(84, 12);
lcd.print(str1);
lcd.setCursor(84, 23);
lcd.print(str2);
}
break;
}
///////////////////// меню настройки
case 1:
{
lcd.setFont(u8g2_font_10x20_t_cyrillic);
lcd.setCursor(20, 11);
lcd.print("Настройки");
//lcd.drawXBMP(20, 1, 14, 14, wave);
/*
switch (select1) {
case 0: lcd.drawRFrame(42, 1, 43, 14, 3); break;
case 1: lcd.drawRFrame(42, 17, 37, 14, 3); break;
case 2: lcd.drawRFrame(42, 33, 49, 14, 3); break;
}
*/
break;
}
}
lcd.sendBuffer(); // отрисовка дисплея
}