Проблема с меню.

Здесь обсуждаем Arduino
Ответить
Аватара пользователя
GhostX
Сообщения: 1115
Зарегистрирован: 07 дек 2015, 14:40
Откуда: Рязань

Проблема с меню.

Сообщение GhostX » 19 фев 2016, 12:53

Сидел вчера голову ломал.
На данный момент структура такая
Старт
Установки

Установки- установка температуры- установка влажности- установка поворото.
В старте функция чтения параметпов из еепром запись в который происходи при переходах в установках.
И функция основной программы.
Сделано все циклами проверки кнопок. И при нажатии одной из вызываются те или иные функции и меняются значения переменных, у всех подменю по разному все. Общее только цикл проверки кнопок.
И тут пришло время допилить эти установки, что фактически увеличивает это самое меню в 3 раза.
Есть только одна идея, тупо накопировать и подправить значения, визуально это увеличит код, строк так на 200 наверное. И мне такой вариант не нравится.
Как нормальные люди менюшки пишут?
Структура кода интерисует.

Аватара пользователя
gurvinok
Сообщения: 1484
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: Проблема с меню.

Сообщение gurvinok » 19 фев 2016, 21:00

Сначала нужно все меню нарисовать квадратиками и стрелочками на бумаге. Затем сфоткать и выложить сюда. Я после прочтения вопроса вообще непонял как что должно быть.
Если долго мучиться, может быть получится.

Аватара пользователя
GhostX
Сообщения: 1115
Зарегистрирован: 07 дек 2015, 14:40
Откуда: Рязань

Re: Проблема с меню.

Сообщение GhostX » 19 фев 2016, 22:24

меню было.jpg
Вот это на каждое окошко было.
привел пример

Код: Выделить всё

//********************************************
void ustTemp(){ // установка температуры
	lcd.createChar(1, degree); // Создаем символ под номером 1
	lcd.createChar(2, PE_lit); // создаем букву п
	lcd.clear();
	lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
	lcd.print(" TEM\2EPAT\6PA"); // Выводим текст температура
	tEkran();//вызвать функцию вывода текста на экран значения записанные в пзу
	a = true;
	while(a) {
		LokalKey();
		if (!UP && !keyUP) keyUP = true;
		if (UP && keyUP){
			/*(">")
			  (" ")*/
			  tNorm += 1;
			  if (tNorm >= 40) tNorm = 39;
			  tEkran();//вызвать функцию вывода текста на экран обновленные значения
			  keyUP = false;
		}
		if (!DOWN && !keyDOWN) keyDOWN = true;
		if (DOWN && keyDOWN){
			/*(" ")
			  (">")*/
			  tNorm -= 1;
			  if (tNorm <= 21) tNorm = 22;
			  tEkran();	//вызвать функцию вывода текста на экран обновленные значения
			  keyDOWN = false;
		}
		if (!SELECT && !keySELECT) keySELECT = true;
		if (SELECT && keySELECT){
			keySELECT = false;
			addr = 0;
			EEPROM.write(addr, tNorm); //записываем значение переменной макс температуры// адрес в 0 ячейку
			lcd.clear();
			ustVlaj();
			a = false;
		}
	}	
}
void tEkran(){//функция вывода текста на экран
			  lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
			  lcd.print("      HOPMA   \1C"); //чистим нижнюю строку
			  lcd.setCursor(12, 1); // Устанавливаем курсор в 8 ячейку 2 строки
			  lcd.print(tNorm); // Выводим значение температуры мин или макс
}
меню стало.jpg
Не красивый код, но работает.

Код: Выделить всё

// функции меню
void memu(){
	lcd.clear();
	lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
	lcd.print("  CTAPT"); // Выводим текст меню СТАРТ
	lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
	lcd.print("> \6CTAHOBKA"); // Выводим текст меню УСТАНОВКА	
	a = true;
	dva = true;
	odin = false;
	while(a) {
		//PrevMenu = millis();
		LokalKey(); //Вызвать функцию проверки состояния кнопок.
		
		if (UP){
			lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
			lcd.print(">"); // рисуем стрелочку
			lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
			lcd.print(" "); // стираем стрелочку
			dva = false;
			odin = true;
		}
		if (DOWN){
			lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
			lcd.print(" "); // стираем стрелочку
			lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
			lcd.print(">"); // рисуем стрелочку
			dva = true;
			odin = false;
		}
		if (!SELECT && !keySELECT) keySELECT = true;
		if (SELECT && keySELECT){
			keySELECT = false;
			if(dva){
				ustTemp();
				a = false;
			}
			if (odin){
				getDateDs3231(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
				
				EEPROM.write(10, year); //записываем в память дату и время начала инкубации.
				EEPROM.write(11, month); 
				EEPROM.write(12, dayOfMonth); 
				EEPROM.write(13, dayOfWeek); 
				EEPROM.write(14, hour); 
				EEPROM.write(15, minute); 
				readEeprom(); //вызов чтения функции записи переменных из памяти EEPROM
				start();
			}
		}
	}
}
//********************************************
void ustTemp(){ // установка температуры
	lcd.createChar(1, degree); // Создаем символ под номером 1
	lcd.createChar(2, PE_lit); // создаем букву П
	lcd.createChar(3, D_lit); // создаем букву Д
	lcd.clear();
	lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
	lcd.print(" TEM\2EPAT\6PA"); // Выводим текст температура
    KeyTemp = 0x01;
	tEkran();//вызвать функцию вывода текста на экран значения записанные в пзу
	krutim_knopki(); // вызываем просмотр, что с кнопками	
}
void tEkran(){//функция вывода текста на экран
			 lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
			if ((KeyTemp & 0x01)&&!(KeyTemp & 0x80)){ //0000 0001 и 0000 0001
				lcd.print("1-7\3  HOPMA   \1C");
				tNorm = tNorm7;
			}
			if (KeyTemp & 0x02){ //
				lcd.print("8-14\3 HOPMA   \1C"); 
				tNorm = tNorm14;				
			}
			if (KeyTemp & 0x04){ //
				lcd.print("15-17\3 HOPMA  \1C");
				tNorm = tNorm17;
			}
			lcd.setCursor(12, 1); // Устанавливаем курсор в 8 ячейку 2 строки
			lcd.print(tNorm); // Выводим значение температуры мин или макс
}
//********************************************
void ustVlaj(){ // установка влажности
	lcd.clear();
	lcd.createChar(2, D_lit); // создаем букву Д
	lcd.createChar(3, EL_lit); // создаем букву л
	lcd.createChar(4, ZH_lit); // создаем букву ж
	lcd.createChar(5, MZ_lit); // создаем букву ь
	lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
	lcd.print(" B\3A\4HOCT\5"); // Выводим текст температура
	vEkran();//вызвать функцию вывода текста на экран
}
void vEkran(){//функция вывода текста на экран
			if(KeyTemp & 0x08){
				lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print(" 1- 7\2   %      "); //чистим нижнюю строку
				vNorm = vNorm7;
			} 
			if(KeyTemp & 0x10){
				lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print(" 8-14\2   %      "); //чистим нижнюю строку
				vNorm = vNorm14;
			}
			if(KeyTemp & 0x20){
				lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print("15-17\2   %      "); //чистим нижнюю строку
				vNorm = vNorm17;
			}
			lcd.setCursor(7, 1); // Устанавливаем курсор в начало 2 строки
	        lcd.print(vNorm); // Выводим значение температуры макс
}
//********************************************
void ustPerevorot(){
	lcd.clear();
	lcd.createChar(2, PE_lit); // создаем букву П
	lcd.createChar(3, EL_lit); // создаем букву Л
	lcd.createChar(4, CH_lit); // Создаем символ Ч
	lcd.createChar(5, D_lit); // создаем букву Д
	lcd.setCursor(0, 0); // Устанавливаем курсор в начало 1 строки
	lcd.print("\2EPEBOPOT \3OTKA "); // Выводим текст температура
	pEkran();
}
void pEkran(){//функция вывода текста на экран
			if(KeyTemp & 0x40){	
				lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print("1-7\5      \4AC(A)"); //чистим нижнюю строку
				pNorm = pNorm7;
			}
			if(KeyTemp & 0x80){	
				lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print("8-14\5     \4AC(A)"); //чистим нижнюю строку
				pNorm = pNorm14;
			}
			if(KeyTemp == 0x00){	
				lcd.setCursor(0, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print("15-17\5    \4AC(A)"); //чистим нижнюю строку
				pNorm = pNorm17;
			}
				lcd.setCursor(7, 1); // Устанавливаем курсор в начало 2 строки
				lcd.print(pNorm); // Выводим значение времени переворота	
}
//********************************************
void krutim_knopki(){

a = true;
	while(a) {
		LokalKey();
		if (!UP && !keyUP) keyUP = true;
		if (UP && keyUP){
			//---температура---
			if ((KeyTemp & 0x01)&&!(KeyTemp & 0x80)){ //первые 7 дней температура//ключ 0000 1111 и 0000 0001 дает true то заходим
				tNorm7 += 1;
				if (tNorm7 >= 40) tNorm7 = 39;
				tEkran();//вызвать функцию вывода текста на экран обновленные значения
			}
			else if (KeyTemp & 0x02){ // с 7 по 14 день температура//ключ 0000 1111 и 0000 0010 дает true то заходим
				tNorm14 += 1;
				if (tNorm14 >= 40) tNorm14 = 39;
				tEkran();//вызвать функцию вывода текста на экран обновленные значения
			}
			else if (KeyTemp & 0x04){ // с 15 по 17 день температура//ключ 0000 1111 и 0000 0100 дает true то заходим
				tNorm17 += 1;
				if (tNorm17 >= 40) tNorm17 = 39;
				tEkran();//вызвать функцию вывода текста на экран обновленные значения
			}
			//---влажность---
			else if (KeyTemp & 0x08){ //первые 7 дней влажность//ключ 0000 1111 и 0000 0100 дает true то заходим
				vNorm7 += 5;
				if (vNorm7 >= 80) vNorm7 = 80;
				vEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp & 0x10){ //первые 7 дней влажность//ключ 0000 1111 и 0000 0100 дает true то заходим
				vNorm14 += 5;
				if (vNorm14 >= 80) vNorm14 = 80;
				vEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp & 0x20){ //первые 7 дней влажность//ключ 0000 1111 и 0000 0100 дает true то заходим
				vNorm17 += 5;
				if (vNorm17 >= 80) vNorm17 = 80;
				vEkran();//вызвать функцию вывода текста на экран
			}
			//---поворот---
			else if (KeyTemp & 0x40){ //первые 7 дней поворот//ключ 0000 1111 и 0000 0100 дает true то заходим
				pNorm7 += 1;
				if (pNorm7 >= 8) pNorm7 = 8;
				pEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp & 0x80){ //первые 7 дней поворот//ключ 0000 1111 и 0000 0100 дает true то заходим
				pNorm14 += 1;
				if (pNorm14 >= 8) pNorm14 = 8;
				pEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp == 0x00){ //первые 7 дней поворот//ключ 0000 1111 и 0000 0100 дает true то заходим
				pNorm17 += 1;
				if (pNorm17 >= 8) pNorm17 = 8;
				pEkran();//вызвать функцию вывода текста на экран
			}
			keyUP = false;
		}
		if (!DOWN && !keyDOWN) keyDOWN = true;
		if (DOWN && keyDOWN){
			//---температура---
			if ((KeyTemp & 0x01)&&!(KeyTemp & 0x80)){ //первые 7 дней температура//ключ 0000 1111 и 0000 0001 дает true то заходим
				tNorm7 -= 1;
				if (tNorm7 <= 21) tNorm7 = 22;
				tEkran();	//вызвать функцию вывода текста на экран обновленные значения
			}
			else if (KeyTemp & 0x02){ // с 7 по 14 день температура//ключ 0000 1111 и 0000 0010 дает true то заходим
				tNorm14 -= 1;
				if (tNorm14 <= 21) tNorm14 = 22;
				tEkran();	//вызвать функцию вывода текста на экран обновленные значения
			}
			else if (KeyTemp & 0x04){ // с 15 по 17 день температура//ключ 0000 1111 и 0000 0100 дает true то заходим
				tNorm17 -= 1;
				if (tNorm17 <= 21) tNorm17 = 22;
				tEkran();	//вызвать функцию вывода текста на экран обновленные значения
			}
			//---влажность---
			else if (KeyTemp & 0x08){ //первые 7 дней влажность//ключ 0000 1111 и 0000 0100 дает true то заходим
				vNorm7 -= 5;
				if (vNorm7 <= 40) vNorm7 = 40;
				vEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp & 0x10){ //первые 7 дней влажность//ключ 0000 1111 и 0000 0100 дает true то заходим
				vNorm14 -= 5;
				if (vNorm14 <= 40) vNorm14 = 40;
				vEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp & 0x20){ //первые 7 дней влажность//ключ 0000 1111 и 0000 0100 дает true то заходим
				vNorm17 -= 5;
				if (vNorm17 <= 40) vNorm17 = 40;
				vEkran();//вызвать функцию вывода текста на экран
			}
			//---поворот---
			else if (KeyTemp & 0x40){ //первые 7 дней поворот//ключ 0000 1111 и 0000 0100 дает true то заходим
				pNorm7 -= 1;
				if ((pNorm7 <= 0) || (pNorm7 == 255)) pNorm7 = 0;
				pEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp & 0x80){ //первые 7 дней поворот//ключ 0000 1111 и 0000 0100 дает true то заходим
				pNorm14 -= 1;
				if ((pNorm14 <= 0) || (pNorm14 == 255)) pNorm14 = 0;
				pEkran();//вызвать функцию вывода текста на экран
			}
			else if (KeyTemp == 0x00){ //первые 7 дней поворот//ключ 0000 1111 и 0000 0100 дает true то заходим
				pNorm17 -= 1;
				if ((pNorm17 <= 0) || (pNorm17 == 255)) pNorm17 = 0;
				pEkran();//вызвать функцию вывода текста на экран
			}
			keyDOWN = false;
		}
		if (!SELECT && !keySELECT) keySELECT = true;
		if (SELECT && keySELECT){
			keySELECT = false;
			//---температура---
			if((KeyTemp & 0x01)&&!(KeyTemp & 0x80)){
				EEPROM.write(0, tNorm7); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 0); // Сбросили флаг 0000 0001 > 0000 0001 > 1111 1110 в сочетании с ключем 0000 0001 даст 0000 0000
				KeyTemp |= 0x02; //  0000 0000 или 0000 0010 в сочетании с ключем 0000 0000 даст 0000 0010
				tEkran();//вызвать функцию вывода текста на экран значения чтоб поменялось значение дней
			}	
			else if(KeyTemp & 0x02){
				EEPROM.write(1, tNorm14); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 1); // Сбросили флаг 0000 0001 > 0000 0010 > 1111 1101 в сочетании с ключем 0000 0010 даст 0000 0000
				KeyTemp |= 0x04; //  0000 0000 или 0000 0100 в сочетании с ключем 0000 0000 даст 0000 0100
				tEkran();//вызвать функцию вывода текста на экран значения чтоб поменялось значение дней
			}	
			else if(KeyTemp & 0x04){
				EEPROM.write(2, tNorm17); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 2); // Сбросили флаг 0000 0001 > 0000 0100 > 1111 1011 в сочетании с ключем 0000 0100 даст 0000 0000
				KeyTemp |= 0x08; //  0000 0000 или 0000 1000 в сочетании с ключем 0000 0000 даст 0000 1000
				lcd.clear();
				ustVlaj();
			}
			//---влажность---
			else if(KeyTemp & 0x08){
				EEPROM.write(3, vNorm7); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 3); // Сбросили флаг 0000 0001 > 0000 1000 > 1111 0111 в сочетании с ключем 0000 1000 даст 0000 0000
				KeyTemp |= 0x10; //  0000 0000 или 0001 0000 в сочетании с ключем 0000 0000 даст 0001 0000
				vEkran();//вызвать функцию вывода текста на экран значения чтоб поменялось значение дней
			}	
			else if(KeyTemp & 0x10){
				EEPROM.write(4, vNorm14); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 4); // Сбросили флаг 0000 0001 > 0001 0000 > 1110 1111 в сочетании с ключем 0000 1000 даст 0000 0000
				KeyTemp |= 0x20; //  0000 0000 или 0010 0000 в сочетании с ключем 0000 0000 даст 0010 0000
				vEkran();//вызвать функцию вывода текста на экран значения чтоб поменялось значение дней
			}	
			else if(KeyTemp & 0x20){
				EEPROM.write(5, vNorm17); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 5); // Сбросили флаг 0000 0001 > 0010 0000 > 1101 1111 в сочетании с ключем 0010 0000 даст 0000 0000
				KeyTemp |= 0x40; //  0000 0000 или 0100 0000 в сочетании с ключем 0000 0000 даст 0100 0000
				lcd.clear();
				ustPerevorot();
				
			}
			//---поворот---
			else if(KeyTemp & 0x40){
				EEPROM.write(6, pNorm7); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp &= ~(1 << 6); // Сбросили флаг 0000 0001 > 0100 0000 > 1011 1111 в сочетании с ключем 0100 0000 даст 0000 0000
				KeyTemp |= 0x80; //  0000 0000 или 1000 0000 в сочетании с ключем 0000 0000 даст 1000 0000
				pEkran();//вызвать функцию вывода текста на экран
			}	
			else if(KeyTemp & 0x80){
				EEPROM.write(7, pNorm14); //записываем значение переменной макс температуры// адрес в 0 ячейку
				KeyTemp = 0x00; //  1000 0000 = 0000 0000 
				pEkran();//вызвать функцию вывода текста на экран
			}	
			else if(KeyTemp == 0x00){
				EEPROM.write(8, pNorm17); //записываем значение переменной макс температуры// адрес в 0 ячейку
				a = false;
			}
			
		}
	}
	lcd.clear();
	SredZnach();
}

	 
//--------------------------------------------------------------------------------

Аватара пользователя
gurvinok
Сообщения: 1484
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: Проблема с меню.

Сообщение gurvinok » 20 фев 2016, 16:47

Ух ты....
А почему бы не сделать меню так:
menu.jpg
Если долго мучиться, может быть получится.

Аватара пользователя
GhostX
Сообщения: 1115
Зарегистрирован: 07 дек 2015, 14:40
Откуда: Рязань

Re: Проблема с меню.

Сообщение GhostX » 20 фев 2016, 17:01

А смысл? Все равно нужно зайти в каждое окошко и нельзя ни одного пропустить.
Единственное что не предусмотрел возможность возвращения назад, если в последний момент заметил ошибку, но уже нажал далее. и единственный выход прокрутить еще раз настройки по кругу. а с другой стороны, ими один раз выставил и забыл об них вообще на очень долго. Они в пзу записываются и следующий цикл если запустить, начнется с ними же, по умолчанию. Там вопрос больше не по расположению окошек, а как в коде это должно выглядеть.
толи один сетап и вызовы из него в разные функции, толи одна функция и там все по порядку, как я сделал...
Я всю голову сломал как лучше сделать. в итоге сделал как получилось.
Это переписывать уже не стану, все работает и эти 6 доп. окна занимают всего 200 байт, и меня это полностью устраивает.
Но на будущее интересно было бы знать.
Каков этикет у программистов в этой области?

Аватара пользователя
gurvinok
Сообщения: 1484
Зарегистрирован: 02 мар 2013, 09:18
Откуда: Москва

Re: Проблема с меню.

Сообщение gurvinok » 20 фев 2016, 17:24

Этикета нет. Прокрутки меню пишутся на флагах, а потом по флагам выполняются действия из меню.
Если долго мучиться, может быть получится.

Аватара пользователя
GhostX
Сообщения: 1115
Зарегистрирован: 07 дек 2015, 14:40
Откуда: Рязань

Re: Проблема с меню.

Сообщение GhostX » 20 фев 2016, 21:45

Ну в принципе ничего хитрого нету. Я тоже ничего умнее не придумал.)))

Ответить