Вот код, который я написал: Код (C++): #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 5 Adafruit_SSD1306 display(OLED_RESET); int am = 0; int lm = 0; int aim = 0; int info = 0; int intens = 0; int intensS = 0; int item = 1; int menuLevel = 1; int ledI = 0; int limit = 0; int LedOn = 0; int buttonState = 2000; int autoMode = 0; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); pinMode(4, INPUT_PULLUP); } byte Key() { if (analogRead(0) < 2) return 6;// вправо 0 else if (analogRead(0) < 150) return 2;// вверх 144 else if (analogRead(0) < 170) return 3;// вниз 164 else if (analogRead(0) < 500) return 4;// влево 416 else if (analogRead(0) < 800) return 1;// выбрать 718 else if (analogRead(0) < 1023) return 0;// ничего не нажато } void loop() { Serial.println(Key()); if(menuLevel == 1 && item == 1) { if(am == 0) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->Led | Off | "); display.println(ledI); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoMode); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); info = 1; lm = 0; intens = 0; aim = 0; } else if (am == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->Led | On | "); display.println(ledI); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoMode); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); info = 1; lm = 0; intens = 0; aim = 0; } } else if(menuLevel == 1 && item == 2) { if(am == 0) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | Off | "); display.println(ledI); display.setCursor(0, 10); display.print("->Auto mode | "); display.println(autoMode); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); info = 0; lm = 0; intens = 0; aim = 1; } else if (am == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | On | "); display.println(ledI); display.setCursor(0, 10); display.print("->Auto mode | "); display.println(autoMode); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); info = 0; lm = 0; intens = 0; aim = 1; } } else if(menuLevel == 1 && item == 3) { if(am == 0) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | Off | "); display.println(ledI); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoMode); display.setCursor(0, 20); display.print("->Limit | "); display.println(limit); display.display(); info = 0; lm = 1; intens = 0; aim = 0; } else if (am == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | On | "); display.println(ledI); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoMode); display.setCursor(0, 20); display.print("->Limit | "); display.println(limit); display.display(); info = 0; lm = 1; intens = 0; aim = 0; } } else if(menuLevel == 1 && item == 4) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Auto mode | "); display.println(autoMode); display.setCursor(0, 10); display.print(" Limit | "); display.println(limit); display.setCursor(0, 20); display.print("->Intensity | "); display.println(intensS); display.display(); info = 0; lm = 0; intens = 1; aim = 0; } else if(menuLevel == 2 && item == 1 && aim == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->On"); display.setCursor(0, 10); display.print(" Off"); display.display(); } else if(menuLevel == 2 && item == 2 && aim == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" On"); display.setCursor(0, 10); display.print("->Off"); display.display(); } else if(menuLevel == 2 && item == 1 && lm == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(limit); display.display(); } else if(menuLevel == 2 && item == 1 && intens == 1) { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(intensS); display.display(); } switch(Key()) { case 2: if(menuLevel == 2 && lm == 1) { if(menuLevel == 2 && lm == 1 && item != 1) { item = 1; } if (menuLevel == 2 && item == 1 && lm == 1) { limit++; } if(limit > 1023) { limit = 0; } else if(menuLevel == 2 && intens == 1) { if(menuLevel == 2 && intens == 1 && item != 1) { item = 1; } if (menuLevel == 2 && item == 1 && intens == 1) { intensS++; } if(intensS > 1023) { intensS = 0; } } else { if(item != 1) { item--; delay(250); } else if(item == 1) { item = 1; delay(250); } } } break; case 3: if(menuLevel == 2 && lm == 1) { if(menuLevel == 2 && lm == 1 && item != 1) { item = 1; } if (menuLevel == 2 && item == 1 && lm == 1) { limit--; } if(limit < 0) { limit = 1023; } } else if(menuLevel == 2 && intens == 1) { if(menuLevel == 2 && intens == 1 && item != 1) { item = 1; } if (menuLevel == 2 && item == 1 && intens == 1) { intensS--; } if(intensS < 0) { intensS = 1023; } } else { if(item != 4) { item++; delay(250); } else if(item == 4) { item = 4; delay(250); } } break; case 1: if(menuLevel != 2) { menuLevel++; item = 1; } else if(menuLevel == 2) { menuLevel = 2; } delay(250); break; case 4: if(menuLevel == 1 && item == 1) { am = 0; } else if(menuLevel == 1 && item == 2) { am = 0; } if(menuLevel != 1) { menuLevel--; item = 1; } else if(menuLevel == 1) { menuLevel = 1; } delay(250); break; case 6: if(menuLevel == 2 && item == 1 && aim == 1) { menuLevel = 1; item = 2; autoMode = 1; } if(menuLevel == 2 && item == 2 && aim == 1) { menuLevel = 1; item = 2; autoMode = 0; } if(menuLevel == 2 && lm == 1) { menuLevel = 1; item = 3; } if(menuLevel == 2 && intens == 1) { menuLevel = 1; item = 4; } delay(250); break; } } Это проект дистанционного управления лампой в зависимости от фоторезистора. Модули ещё не подключал, пока делаю меню. Вопросы такие: 1. Почему, если доходишь до вкладки Intensity в первом меню, то вверх она не хочет идти? 2. Почему значение intensS при выборе Intenity изменяется только в меньшую сторону, в большую не реагирует? В дальнейшем приёмник и передатчик будут общаться с помощью модулей nrf24l01+. Заранее спасибо)
На такой код смотреть глазам больно. Сплошная лапша с ифами. У меня когда-то был работник с такими же замашками - выгнал от греха подальше. В его коде через неделю он сам же не мог разобраться - печатал на рулоне, раскладывал на полу и лазил на коленках с карандашиком в руках
>> 2. Почему значение intensS при выборе Intenity изменяется только в меньшую сторону, в большую не реагирует? Потому что функции меню нужно сгруппировать не по кнопкам, а по меню. Вышли в функцию текущего меню и в ней разбираем что делать с кнопкой, а не наоборот. Чтобы в вашем коде найти intensS++ и intensS-- нужно пролистать два экрана. Сделайте так, чтобы intensS++ и intensS-- находились рядом, а лучше в одной функции.
Я сделал код понятным и исправил все ошибки и недочётыправда пришлось использовать delay, но пока что это не столь важно...) Код (C++): #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 5 Adafruit_SSD1306 display(OLED_RESET); int intensity = 0; int item = 1; int menuLevel = 1; int limit = 0; int ledOn = 0; int autoModeOn = 0; int pos1 = 0; int pos2 = 0; int pos3 = 0; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); pinMode(4, INPUT_PULLUP); } byte Key() { if (analogRead(0) < 2) return 5;// вправо 0 else if (analogRead(0) < 150) return 2;// вверх 144 else if (analogRead(0) < 170) return 3;// вниз 164 else if (analogRead(0) < 500) return 4;// влево 416 else if (analogRead(0) < 800) return 1;// выбрать 718 else if (analogRead(0) < 1023) return 0;// ничего не нажато } void loop() { Serial.println(Key()); if(menuLevel == 1 && item == 1) { M1I1(); } else if(menuLevel == 1 && item == 2) { M1I2(); pos1 = 1; pos2 = 0; pos3 = 0; } else if(menuLevel == 1 && item == 3) { M1I3(); pos1 = 0; pos2 = 1; pos3 = 0; } else if(menuLevel == 1 && item == 4) { M1I4(); pos1 = 0; pos2 = 0; pos3 = 1; } else if(menuLevel == 2 && item == 1 && pos1 == 1) { M2I1P1(); } else if(menuLevel == 2 && item == 2 && pos1 == 1) { M2I2P1(); } else if(menuLevel == 2 && item == 1 && pos2 == 1) { M2I1P2(); } else if(menuLevel == 2 && item == 1 && pos3 == 1) { M2I1P3(); } switch(Key()) { case 1: if(menuLevel == 2 && item == 1 && pos1 == 1) { autoModeOn = 1; menuLevel = 1; item = 2; delay(250); } else if(menuLevel == 2 && item == 2 && pos1 == 1) { autoModeOn = 0; menuLevel = 1; item = 2; delay(250); } else if(menuLevel == 2 && item == 1 && pos2 == 1) { menuLevel = 1; item = 3; delay(250); } else if(menuLevel == 2 && item == 1 && pos3 == 1) { menuLevel = 1; item = 4; delay(250); } else if(menuLevel != 2) { menuLevel++; item = 1; delay(250); } break; case 2: if(menuLevel == 2 && item == 1 && pos2 == 1) { limit++; } else if(menuLevel == 2 && item == 1 && pos3 == 1) { intensity++; } else if(item != 1) { item--; delay(250); } break; case 3: if(menuLevel == 2 && pos1 == 1) { if(item != 2) { item++; } } else if(menuLevel == 2 && item == 1 && pos2 == 1) { limit--; } else if(menuLevel == 2 && item == 1 && pos3 == 1) { intensity++; } else if(item != 4) { item++; delay(250); } break; case 4: if(menuLevel != 1) { menuLevel--; delay(250); } break; } } void M1I1() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->Led | On | "); display.println(intensity); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoModeOn); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); } void M1I2() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | On | "); display.println(intensity); display.setCursor(0, 10); display.print("->Auto mode | "); display.println(autoModeOn); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); } void M1I3() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | On | "); display.println(intensity); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoModeOn); display.setCursor(0, 20); display.print("->Limit | "); display.println(limit); display.display(); } void M1I4() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Auto mode | "); display.println(autoModeOn); display.setCursor(0, 10); display.print(" Limit | "); display.println(limit); display.setCursor(0, 20); display.print("->Intensity | "); display.println(intensity); display.display(); } void M2I1P1() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->On"); display.setCursor(0, 10); display.print(" Off"); display.display(); } void M2I2P1() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" On"); display.setCursor(0, 10); display.print("->Off"); display.display(); } void M2I1P2() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(limit); display.display(); } void M2I1P3() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(intensity); display.display(); }
Я доделал проект, всё отлично работает: Код передатчика: Код (C++): #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 5 #include <nRF24L01.h> #include <RF24.h> Adafruit_SSD1306 display(OLED_RESET); RF24 radio(9, 10); int intensity = 0; int item = 1; int menuLevel = 1; int limit = 0; int ledOn = 0; int autoModeOn = 0; int pos1 = 0; int pos2 = 0; int pos3 = 0; int data[3]; void setup() { Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); radio.begin(); radio.setChannel(5); radio.setDataRate (RF24_1MBPS); radio.setPALevel (RF24_PA_HIGH); radio.openWritingPipe (0x1234567890LL); } byte Key() { if (analogRead(0) < 2) return 5;// вправо 0 else if (analogRead(0) < 150) return 2;// вверх 144 else if (analogRead(0) < 170) return 3;// вниз 164 else if (analogRead(0) < 500) return 4;// влево 416 else if (analogRead(0) < 800) return 1;// выбрать 718 else if (analogRead(0) < 1023) return 0;// ничего не нажато } void loop() { Serial.println(Key()); Serial.println(data[2]); if(menuLevel == 1 && item == 1) { M1I1(); } else if(menuLevel == 1 && item == 2) { M1I2(); pos1 = 1; pos2 = 0; pos3 = 0; } else if(menuLevel == 1 && item == 3) { M1I3(); pos1 = 0; pos2 = 1; pos3 = 0; } else if(menuLevel == 1 && item == 4) { M1I4(); pos1 = 0; pos2 = 0; pos3 = 1; } else if(menuLevel == 2 && item == 1 && pos1 == 1) { M2I1P1(); } else if(menuLevel == 2 && item == 2 && pos1 == 1) { M2I2P1(); } else if(menuLevel == 2 && item == 1 && pos2 == 1) { M2I1P2(); } else if(menuLevel == 2 && item == 1 && pos3 == 1) { M2I1P3(); } switch(Key()) { case 1: if(menuLevel == 2 && item == 1 && pos1 == 1) { autoModeOn = 1; menuLevel = 1; item = 2; delay(250); } else if(menuLevel == 2 && item == 2 && pos1 == 1) { autoModeOn = 0; menuLevel = 1; item = 2; delay(250); } else if(menuLevel == 2 && item == 1 && pos2 == 1) { menuLevel = 1; item = 3; delay(250); } else if(menuLevel == 2 && item == 1 && pos3 == 1) { menuLevel = 1; item = 4; delay(250); } else if(menuLevel != 2) { menuLevel++; item = 1; delay(250); } break; case 2: if(menuLevel == 2 && item == 1 && pos2 == 1) { limit++; if(limit > 1023) { limit = 0; } } else if(menuLevel == 2 && item == 1 && pos3 == 1) { intensity++; if(intensity > 1023) { intensity = 0; } } else if(item != 1) { item--; delay(250); } break; case 3: if(menuLevel == 2 && pos1 == 1) { if(item != 2) { item++; } } else if(menuLevel == 2 && item == 1 && pos2 == 1) { limit--; if(limit < 0) { limit = 1023; } } else if(menuLevel == 2 && item == 1 && pos3 == 1) { intensity--; if(intensity < 0) { intensity = 1023; } } else if(item != 4) { item++; delay(250); } break; case 4: if(menuLevel != 1) { menuLevel--; delay(250); } break; } data[0] = autoModeOn; data[1] = limit; data[2] = intensity; radio.write(&data, sizeof(data)); } void M1I1() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->Led | On | "); display.println(intensity); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoModeOn); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); } void M1I2() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | On | "); display.println(intensity); display.setCursor(0, 10); display.print("->Auto mode | "); display.println(autoModeOn); display.setCursor(0, 20); display.print(" Limit | "); display.println(limit); display.display(); } void M1I3() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Led | On | "); display.println(intensity); display.setCursor(0, 10); display.print(" Auto mode | "); display.println(autoModeOn); display.setCursor(0, 20); display.print("->Limit | "); display.println(limit); display.display(); } void M1I4() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" Auto mode | "); display.println(autoModeOn); display.setCursor(0, 10); display.print(" Limit | "); display.println(limit); display.setCursor(0, 20); display.print("->Intensity | "); display.println(intensity); display.display(); } void M2I1P1() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print("->On"); display.setCursor(0, 10); display.print(" Off"); display.display(); } void M2I2P1() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(" On"); display.setCursor(0, 10); display.print("->Off"); display.display(); } void M2I1P2() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(limit); display.display(); } void M2I1P3() { display.clearDisplay(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(0, 0); display.print(intensity); display.display(); } Код приёмника: Код (C++): #include <SPI.h> // Подключаем библиотеку для работы с шиной SPI #include <nRF24L01.h> // Подключаем файл настроек из библиотеки RF24 #include <RF24.h> // Подключаем библиотеку для работы с nRF24L01+ RF24 radio(9, 10); // Создаём объект radio для работы с библиотекой RF24, указывая номера выводов nRF24L01+ (CE, CSN) int data[3]; // Создаём массив для приёма данных void setup(){ Serial.begin(9600); delay(1000); radio.begin(); // Инициируем работу nRF24L01+ radio.setChannel(5); // Указываем канал приёма данных (от 0 до 127), 5 - значит приём данных осуществляется на частоте 2,405 ГГц (на одном канале может быть только 1 приёмник и до 6 передатчиков) radio.setDataRate (RF24_1MBPS); // Указываем скорость передачи данных (RF24_250KBPS, RF24_1MBPS, RF24_2MBPS), RF24_1MBPS - 1Мбит/сек radio.setPALevel (RF24_PA_HIGH); // Указываем мощность передатчика (RF24_PA_MIN=-18dBm, RF24_PA_LOW=-12dBm, RF24_PA_HIGH=-6dBm, RF24_PA_MAX=0dBm) radio.openReadingPipe (1, 0x1234567890LL); // Открываем 1 трубу с идентификатором 0x1234567890 для приема данных (на ожном канале может быть открыто до 6 разных труб, которые должны отличаться только последним байтом идентификатора) radio.startListening (); // Включаем приемник, начинаем прослушивать открытую трубу // radio.stopListening (); // Выключаем приёмник, если потребуется передать данные } void loop() { Serial.println(analogRead(A0)); if(radio.available()) { radio.read( &data, sizeof(data) ); } if(data[0] == 1) { if(analogRead(A0) > data[1]) { analogWrite(6, data[2]); } else { analogWrite(6, 0); } } else { analogWrite(6, 0); } }
Странно... Тут если analogRead(0) = 1023 какая кнопка будет нажата? Код (C++): byte Key() { if (analogRead(0) < 2) return 5;// вправо 0 else if (analogRead(0) < 150) return 2;// вверх 144 else if (analogRead(0) < 170) return 3;// вниз 164 else if (analogRead(0) < 500) return 4;// влево 416 else if (analogRead(0) < 800) return 1;// выбрать 718 else if (analogRead(0) < 1023) return 0;// ничего не нажато } analogRead выполняется 0.1 мс. Код (C++): byte Key() { int val = analogRead(0); if (val < 2) return 5; // вправо 0. Что то тут запас маленький совсем. 0, 1. else if (val < 150) return 2;// вверх 144 else if (val < 170) return 3;// вниз 164 else if (val < 500) return 4;// влево 416 else if (val < 800) return 1;// выбрать 718 return 0;// ничего не нажато }
Если 0, то нажата кнопка вправо, но она у меня в скетче не используется, она только в key() объявлена.
Код (C++): byte Key() { const static int grade = { 0, 2, 150, 170, 500, 800 }; int val = analogRead(0); for ( byte i = 6; val < grade[--i] ; ) ; return 5 - i; } Тут коды Key отличаются от ваших. Но смысл должен быть понятен.
Я писал что надо делать Помогите!! Задержка у кнопок на аналоговом. http://forum.amperka.ru/threads/Помогите-Задержка-у-кнопок-на-аналоговом.11335/page-2#post-109865