Нахожусь в стадии изучения Ардуино и в связи с этим прошу совета опытных пользователей.
Если есть возможность, проконтролируйте мой код, мне просто хотелось бы понять,
где нужно пойти другим путем, как оптимизировать, ну в общем что бы при дальнейшем
обучении не тащить за собой изначально не правильное понимание. На данный момент
вопросы по созданию глобальных, локальных переменных, возвращение типов результатов функций (как
из функции вернуть текстовое сообщение), и работа с указателями.
Логика программки следующая:
- Есть трехразрядный семисегментный Led индикатор и я пытаюсь на нем реализовать
ввод нескольких параметров.
1. при включении устройства по индикаторам пробегает змейка (взято из урока)
2. далее индикаторы гасятся.
3. при нажатии на кнопку (меню) активируются на всех разрядах G - сегмент (черточка)
4. далее плюсом или минусом выбираем номер параметра (левый разряд отвечает за номер параметра)
(при этом на среднем и правом разрядах отображается значение параметра под данным номером)
5. При нажатии на кнопку (меню) заходим в редактирование данного параметра (в левом разряде при этом загорается
точка, указывает что мы находимся в редактировании)
6. плюсом или минусом редактируем параметр
7. при нажатии на меню записываем параметр в память и выходим в начало меню.
(при бездействии 10 сек выходим в начало и гасим индикаторы)
Библиотека управления индикатором и кнопками взята у Эдуарда (сам пока не осилил), но пользовался только отображением сегментов.
Код: Выделить всё
#include <FlexiTimer2.h>
#include <Led4Digits.h>
#include <Button.h>
// тип индикатора 1; выводы разрядов 5,4,3,2; выводы сегментов 6,7,8,9,10,11,12,13
Led4Digits disp(2, 4,3,2,255, 6,7,8,9,10,11,12,13);
//-------------------------------------------------------------------------------
Button buttonMinus(16, 10); // кнопка МИНУС, вывод 16 (A2)
Button buttonMenu(17, 10); // кнопка МЕНЮ, вывод 17 (A3)
Button buttonPlus(18, 10); // кнопка ПЛЮС, вывод 18 (A4)
#define MENU_TIME 5000 // время цикла тамера отображения меню ( * 2 = 1 сек)
unsigned int countIdleTime = 0; // счетчик времени отображения меню в бездействии
byte statMenu = 0; // режим, 0 - не активно, 1 - активно, 2 - ввод параметра, 3 - запись параметра в память и переход в начало меню
byte numberParam = 0; // номер параметра
struct Menu {
byte itemNom; // выбранный номер меню
byte parameter; // значение выбраного по номеру параметра
};
// пока не знаю как читать из памяти, присвою начальные параметры тут
Menu paramValue[3] = {{1, 21}, {2, 5}, {3, 10}};
//---------------
void setup() {
FlexiTimer2::set(2, timerInterrupt); // прерывания по таймеру 2 мс
FlexiTimer2::start(); // разрешение прерывания
// чтение переменных из памяти
// 1. - температура в комнате
// 2. - время между измерениями
// 3. - пока не знаю
//----------
// скопировано из урока
for (int i = 0; i < 32; i++) {
if ( i == 0) disp.digit[0]= 1;
else if ( i == 8) disp.digit[1]= 1;
else if ( i == 16) disp.digit[2]= 1;
else if ( i == 24) disp.digit[3]= 1;
else {
disp.digit[0] = disp.digit[0] << 1;
disp.digit[1] = disp.digit[1] << 1;
disp.digit[2] = disp.digit[2] << 1;
disp.digit[3] = disp.digit[3] << 1;
}
delay(100);
}
}
void loop() {
static byte valueIndikator[4]= {0,0,0,0};
//----нажатие кнопки МЕНЮ ----
if ( buttonMenu.flagClick == true ) {
buttonMenu.flagClick = false; // сброс признака
countIdleTime = 0; // сброс счетчика
if ((statMenu == 0 && numberParam == 0) || (statMenu > 0 && statMenu < 4 && numberParam > 0)) {
statMenu ++; // выходим в режим выбора меню
}
}
// ----фиксация в памяти введенного параметра----
if (statMenu == 3) {
// записываем параметр в память
//пока не знаю как-
//---------
statMenu = 1; numberParam = 0;
}
// ---- выбираем номер меню (кнопка плюс)----
if ( buttonPlus.flagClick == true ) {
buttonPlus.flagClick = false; // сброс признака
countIdleTime = 0; // сброс счетчика
if (statMenu == 1 && numberParam < 3) numberParam ++; // повышаем номер меню
else if (statMenu == 2) {
paramValue[numberParam-1].parameter ++; // повышаем значение параметра
}
}
// ---- выбираем номер меню (кнопка минус)----
if ( buttonMinus.flagClick == true ) {
buttonMinus.flagClick = false; // сброс признака
countIdleTime = 0; // сброс счетчика
if(statMenu == 1 && numberParam > 0) numberParam --; // понижаем номер меню
else if (statMenu == 2) {
paramValue[numberParam-1].parameter --; // понижаем значение параметра
}
}
// ---- отображение меню на индикаторах----
// делим значение параметра на десятки и единицы и выводим на 2 и 3 разрядах, на 1 разряде отображаем номер параметра.
// При редактировании параметра отображаем на первом разряде точку.
byte var1 = paramValue[numberParam-1].parameter / 10;
byte var2 = paramValue[numberParam-1].parameter % 10;
if (statMenu == 0) {
// гасим индикаторы
valueIndikator[0] = 88;
valueIndikator[1] = 88;
valueIndikator[2] = 88;
valueIndikator[3] = 0;
}
else if (statMenu == 1 && numberParam == 0) {
// выподим тире (режим ожидания)
valueIndikator[0] = 99;
valueIndikator[1] = 99;
valueIndikator[2] = 99;
valueIndikator[3] = 0;
}
else if (statMenu == 1 && numberParam > 0 ) {
valueIndikator[0] = numberParam; // выводим показания параметров (номер параметра)
valueIndikator[1] = var1; // выводим показания параметров (значение десятков параметра)
valueIndikator[2] = var2; // выводим показания параметров (значение едениц параметра)
valueIndikator[3] = 0; // выводим показания параметров (отображение точки)
}
else if (statMenu == 2) {
valueIndikator[0] = numberParam; // выводим показания параметров (номер параметра)
valueIndikator[1] = var1; // выводим показания параметров (значение десятков параметра)
valueIndikator[2] = var2; // выводим показания параметров (значение едениц параметра)
valueIndikator[3] = 1; // выводим показания параметров (отображение точки)
}
for (byte i=0; i<=2 ;i++) {
if (valueIndikator[i] == 88) disp.digit[2-i]= B00000000; // (i разряд) гасим
else if (valueIndikator[i] == 99) disp.digit[2-i]= B01000000; // (i разряд) знак (- ожидание выбра номера параметра)
else if (2-i==2 && valueIndikator[3]==1) {
byte tempNumber = getNumberInd(valueIndikator[i]);
disp.digit[2-i] = bitSet(tempNumber,7); //включаем бит точки на индикаторе и выводим значение номера параметра и значение самого параметра
}
else disp.digit[2-i] = getNumberInd(valueIndikator[i]); //выводим значение номера параметра и значение самого параметра
}
}
// --------- конвертация десятичного числа в двоичное
int getNumberInd(byte indCifra) {
byte indByte = B00000000;
if (indCifra == 1) indByte = B00000110;
else if (indCifra == 2) indByte = B01011011;
else if (indCifra == 3) indByte = B01001111;
else if (indCifra == 4) indByte = B01100110;
else if (indCifra == 5) indByte = B01101101;
else if (indCifra == 6) indByte = B01111101;
else if (indCifra == 7) indByte = B00000111;
else if (indCifra == 8) indByte = B01111111;
else if (indCifra == 9) indByte = B01101111;
else if (indCifra == 0) indByte = B00111111;
return indByte;
}
//----------- обработчик прерывания 2 мс
void timerInterrupt()
{
disp.regen(); // регенерация индикатора
buttonMinus.filterAvarage(); // сканирование кнопки МИНУС, метода фильтрации по среднему
buttonMenu.filterAvarage(); // сканирование кнопки МЕНЮ, метода фильтрации по среднему
buttonPlus.filterAvarage(); // сканирование кнопки ПЛЮС, метода фильтрации по среднему
if (statMenu > 0) {
countIdleTime++; // + 1 к счетчику таймера отображения меню
}
if (countIdleTime >= MENU_TIME ) {
countIdleTime = 0; // сброс счетчика
statMenu = 0;
numberParam = 0;
// код программы вызывается каждые 1000 мс
}
}