Установка значений с помощью кнопок для весового дозатора
- Войдите на сайт для отправки комментариев
Сделал весовой дозатор для воды, не без помощи форумчан (за что отдельная благодарность).
Нажимаю кнопку, через реле включается помпа, качающая воду. Когда необходимый вес набирается, помпа выключается.
Все отлично работает.
Но хочется добавить возможность программирования необходимого веса с помощью кнопок, а не прибегать к постоянному перезаливанию скетчей с новым весом для дозирования.
Для этого я решил разбить значение (00.00 грамм) на отдельные 4 цифры. Где, как вы уже наверняка догадались, первая цифра отвечает за значения кратные 10 грамм, вторая за кратные 1 грамму, третья за 0.1, четвертая цифра за 0.01 грамм. Но это так, легкое отступление. Если есть предложение лучше, буду только рад!
А для начала, я хочу разобраться как изменять значение хотя бы одной цифры.
void loop() {
lcd.setCursor(7, 1);
lcd.print(numb);
if (digitalRead(butA) == HIGH) {
countOn();
}
}
int countOn() {
if (digitalRead (butB) == HIGH && numb < 9) {
numb = numb + 1;
delay(300);
}
if (digitalRead(butB) == HIGH && numb == 9) {
numb = 0;
delay(300);
lcd.clear();
}
}
В данном отрезке кода на экран выводится цифра 0. Затем, пока я держу кнопку (butА), при каждом нажатии кнопки (butВ) цифра на экране изменяется на +1. Все замечательно, но менять эту цифру я могу только пока кнопка (butA) зажата.
Так вот, как сделать так, чтобы по одному нажатию кнопки (butA) включалась возможность изменения цифр кнопкой (butB), а по следующему отключалась?
P.S.: Опыт программирования меньше 10 дней, поэтому прошу отнестись с пониманием.
Проще всего по длительности нажатия. Короткое-изменение параметра. Длинное - допустим 0,5-1 секунда переход к следующему. Очень длинное > 2 секунд выход и запись в память.
Спасибо! Это отличный вариант!
А можете подсказать код, или где его поискать? Даже не знаю что у гугла спрашивать.
Спасибо! Это отличный вариант!
А можете подсказать код, или где его поискать? Даже не знаю что у гугла спрашивать.
Поищите здесь на форуме, работа с кнопками. А может кто и готовый кусочек подкинет. Я у себя нашел только замороченные. Лучше их не смотреть. Вот примерно, что Вам нужно http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku?page=2#comment-48930 ну и дальше должны попадаться примеры, возможно более подходящие. Кроме того есть еще и библиотеки для кнопок.
4 кнопки.
Перебором по кругу.
Как во всех автомобильных приёмниках вводится код.
Спасибо большое! Тут нашел все что надо!
Все, как менять значения с помощью кнопок я разобрался.
А вот как теперь сохранять значения в памяти контроллера, чтобы они не сбрасывались к 00.00 при каждой перезагрузки, не могу найти информацию.
Подскажите пожалуйста.
Подскажите пожалуйста.
/**/ #include "eeprom_Ref.h" int* adr = (int*)0; eeprom_int aaa(adr); int i = 0; //--------------------------------------- void setup() { Serial.begin(9600); } void loop() { Serial.print("\n Read=");// прочитать из EEPROM Serial.print(aaa[0]); Serial.print(" "); Serial.print(aaa[1]); aaa[0] = i; aaa[1] = i + 5; i++;// записать в EEPROM Serial.print("\n Write=");// проверить запись в EEPROMе Serial.print(aaa[0]); Serial.print(" "); Serial.print(aaa[1]); delay(500); }eeprom_Ref.h
/* eeprom_Ref.h */ #ifndef EEPROM_REF_H #define EEPROM_REF_H //Ref.h----------------------- #include <Arduino.h> #include <avr/eeprom.h> template <typename T> class Ref { protected: T* pointer; void set(T data); T get(); public: ~Ref(); Ref() = delete; Ref(T* a); Ref(const Ref& other) = delete; Ref(Ref&& other); Ref& operator=(const Ref& other) = delete; Ref& operator=(Ref&& other); // operator T(); Ref& operator=(T&& d); Ref& operator=(const T& d); Ref operator[] (const int index); Ref& operator +=(T&& d); Ref& operator -=(T&& d); }; //Ref.cpp----------------------- /* uint8_t */ template <> void Ref<uint8_t>::set(uint8_t data) { eeprom_write_byte(pointer, data); } template <> uint8_t Ref<uint8_t>::get() { return eeprom_read_byte(pointer); } /* int */ template <> void Ref<int>::set(int data) { eeprom_write_word((uint16_t*)pointer, (uint16_t)data); } template <> int Ref<int>::get() { return eeprom_read_word((uint16_t*)pointer); } /* uint16_t*/ template <> void Ref<uint16_t>::set(uint16_t data) { eeprom_write_word(pointer, data); } template <> uint16_t Ref<uint16_t>::get() { return eeprom_read_word(pointer); } /* uint32_t*/ template <> void Ref<uint32_t>::set(uint32_t data) { eeprom_write_dword(pointer, data); } template <> uint32_t Ref<uint32_t>::get() { return eeprom_read_dword(pointer); } /* float*/ template <> void Ref<float>::set(float data) { eeprom_write_float(pointer, data); } template <> float Ref<float>::get() { return eeprom_read_float(pointer); } /*общее*/ template <typename T> Ref<T>::~Ref() {} template <typename T> Ref<T>::Ref(T* a): pointer(a) {} template <typename T> Ref<T>::Ref(Ref<T>&& other) { pointer = other.pointer; } template <typename T> Ref<T>& Ref<T>::operator=(Ref<T>&& other) { if (pointer != other.pointer) set(other.get()); return *this; } template <typename T> Ref<T>::operator T() { return get(); } template <typename T> Ref<T>& Ref<T>::operator=(T&& d) { set(d); return *this; } template <typename T> Ref<T>& Ref<T>::operator=(const T& d) { set(d); return *this; } template <typename T> Ref<T> Ref<T>::operator[] (const int index) { return Ref<T>(pointer + index); } template <typename T> Ref<T>& Ref<T>::operator +=(T&& d) { set(get() + d); return *this; } template <typename T> Ref<T>& Ref<T>::operator -=(T&& d) { set(get() - d); return *this; } using eeprom_int = Ref<int> ; using eeprom_uint8_t = Ref<uint8_t>; using eeprom_uint16_t = Ref<uint16_t>; using eeprom_uint32_t = Ref<uint32_t>; using eeprom_float = Ref<float>; //pRef.h----------------------------- #include <avr/pgmspace.h> template <typename T> class pRef { protected: const T* pointer; T get(); public: ~pRef(); pRef() = delete; pRef(const T* a); pRef(const pRef& other) = delete; pRef(pRef&& other); pRef& operator=(const pRef& other) = delete; pRef& operator=(pRef&& other); // operator T(); pRef operator[] (const int index); }; //pRef.cpp----------------------------- /*uint8_t*/ template <> uint8_t pRef<uint8_t>::get() { return pgm_read_byte(pointer); } /* int */ template <> int pRef<int>::get() { return pgm_read_word((uint16_t*)pointer); } /* uint16_t*/ template <> uint16_t pRef<uint16_t>::get() { return pgm_read_word(pointer); } /* uint32_t*/ template <> uint32_t pRef<uint32_t>::get() { return pgm_read_dword(pointer); } /* float*/ template <> float pRef<float>::get() { return pgm_read_float(pointer); } /*String*/ template <> String pRef<String>::get() { return String(reinterpret_cast<const __FlashStringHelper *>(pointer)); } template <> pRef<String> pRef<String>::operator[] (const int index) { char *p = (char*)pointer; int i = index; while (i != 0) { p = (char*)strchrnul_P(p, 0); p++; i--; } return pRef<String>((String*)p); } /*общее*/ template <typename T> pRef<T>::~pRef() {} template <typename T> pRef<T>::pRef(const T* a): pointer(a) {} template <typename T> pRef<T>::pRef(pRef<T>&& other) : pointer(other.pointer) {} template <typename T> pRef<T>& pRef<T>::operator=(pRef<T>&& other) { pointer = other.pointer; return *this; } template <typename T> pRef<T>::operator T() { return get(); } template <typename T> pRef<T> pRef<T>::operator[] (const int index) { return pRef<T>(pointer + index); } //------------------------------------------------- using pgm_int = pRef<int>; using pgm_uint8_t = pRef<uint8_t>; using pgm_uint16_t = pRef<uint16_t>; using pgm_uint32_t = pRef<uint32_t>; using pgm_float = pRef<float>; using pgm_String = pRef<String>; #endifНа самом деле не знал куда копать. Много натыкался на "запись на внешнюю память", но ничего того что нужно (на первый взгляд) не мог найти. А потом уже увидел "EEPROM", понял что это такое и после этого уже достаточно быстро разобрался.
Но тем не менее, за ответ спасибо!
Все, как менять значения с помощью кнопок я разобрался.
А вот как теперь сохранять значения в памяти контроллера, чтобы они не сбрасывались к 00.00 при каждой перезагрузки, не могу найти информацию.
Подскажите пожалуйста.
Гугли "Ардуино EEPROM"
Спасибо! Это отличный вариант!
А можете подсказать код, или где его поискать? Даже не знаю что у гугла спрашивать.
Пробовал код QWONE
/*** Обработчик кнопки ***/ //------Cl_Btn---------------------- enum {sbNONE = 0, sbClick, sbLong}; /*состояние не изменилось/клик/долгое нажатие*/ class Cl_Btn { protected: const byte pin; byte state; bool bounce = 0; bool btn = 1, oldBtn; unsigned long past; const uint32_t time = 500 ; bool flag = 0; uint32_t past_flag = 0 ; public: Cl_Btn(byte p): pin(p) {} /*инициализация-вставить в setup()*/ void init() { pinMode(pin, INPUT_PULLUP); } /*работа-вставить в loop()*/ void run() { state = sbNONE; bool newBtn = digitalRead(pin); if (!bounce && newBtn != btn) { bounce = 1; past = mill; } if (bounce && mill - past >= 10) { bounce = 0 ; oldBtn = btn; btn = newBtn; if (!btn && oldBtn) { flag = 1; past_flag = mill; } if (!oldBtn && btn && flag && mill - past_flag < time ) { flag = 0; state = sbClick; } } if (flag && mill - past_flag >= time ) { flag = 0; state = sbLong; } } byte read() { return state; } }; #ifdef GYVER GButton Btn1(BUTTON); #else Cl_Btn Btn1(/*пин*/BUTTON); //Экземпляр обработчика для кнопки #endifи библиотеку Алекса Гайвера, зачёт для этих целей