Ви не увійшли.
Лучше и проще решать такую задачу в 2 вычислительных потока. 1 - поток задаваемая функция, 2 сьем информации с потенциометров и перевод в переменные.
Вот примерно шаблон для создания такой программы.
ПС: Пока мешать не буду вашему творчеству своим кодом.
//#1
void setup1(){
}
void loop1(){
}
//#2
void setup2(){
}
void loop2(){
}
//#3
void setup3(){
}
void loop3(){
}
void setup() {
//#1
setup1();
//#2
setup2();
//#3
setup3();
}
void loop() {
static uint32_t MILLIS ;
MILLIS = millis() ;
//#1 1000 миллисекунд вычислит. поток 1
static uint32_t future1 = 0 ;
if (MILLIS>=future1) {
future1 = MILLIS + 1000 ;
loop1();
MILLIS = millis() ;
}
//#2 200 миллисекунд вычислит. поток 2
static uint32_t future2 = 0 ;
if (MILLIS>=future2) {
future2 = MILLIS + 200 ;
loop2();
MILLIS = millis() ;
}
//#3 100 миллисекунд вычислит. поток 3
static uint32_t future3 = 0 ;
if (MILLIS>=future3) {
future3 = MILLIS + 100 ;
loop3();
}
}
Где-то это уже было . только с другими наименованиями. Плагиат?
Нет. Просто своя разработка. Разумеется сейчас я создаю код в другом виде. Но тоже в несколько вычислительных потоков. Так алгоритм и взаимодействие частей программы проще.
const int Led_Pin = 13; // нога светодиода
void flashing_non_stop_program(uint16_t time_0,uint16_t time_1 ) {
static bool state = 0;
static uint32_t timing = 0;
if (millis()<timing) return;
state = !state;
timing += state ? time_0 : time_1 ;
digitalWrite(Led_Pin, state);
}
void setup() {
pinMode(Led_Pin, OUTPUT);
}
void loop() {
flashing_non_stop_program(100,900);// 0.1 сек горит 0.9 сек нет
// идет продолжение программы без задержки на millis()
}
Что бы гнуть ложку , надо поверить что Нет никакой ложки.
Ну вот структура дающая "псевдомногопоточность". Но ведь вы не увидете , потому что вы сказали в 8 битовой архитектуре АРМа (без ДМА и пр.) без "оси" пытаться создать "псевдомногопоточность" lol . "Пупок" в АРМа не развяжется?
uint8_t non_stop_program1(uint16_t span) {
static uint32_t future = 0;
if (millis()<future) return 0;
future += span;
return 1;
}
uint8_t non_stop_program2(uint16_t span) {
static uint32_t future = 0;
if (millis()<future) return 0;
future += span;
return 1;
}
uint8_t non_stop_program3(uint16_t span) {
static uint32_t future = 0;
if (millis()<future) return 0;
future += span;
return 1;
}
void setup() {
Serial.begin(9600);
}
void loop() {
if (non_stop_program1(500)) {
// Здесь вы организовываете вывод на экран. Вызывается раз в 0.5 сек
Serial.println("knok");
}
if (non_stop_program2(200)) {
// Здесь вы организовываете ввод с клавиатуры. Вызывается раз в 0.2 сек
}
if (non_stop_program3(100)) {
// Здесь сама работа устройства не зависимая от вашего ввода и показа на экран. Вызывается раз в 0.1 сек(может быть по желанию другим)
}
}
"День мы сидим, другой день сидим, а на третий день Орлиный Глаз заметил, что у сарая нет одной стены."
А для тех кто сидит в сарае повторю. Старые библиотеки и старый стиль программирования тут не работает. Здесь немного другой принцип.
С использование энкодера и маленькой хитрости, можно вообще обойтись без длиного нажатия.
Знаю что есть такие. Просто пишу свой код.
/* Схема подключения
I2C LCD1602 GND -> GND
+5V -> +5V
SDA -> A4(SDA)
SCL -> A5(SCL)
* Ардуино энкодер CLK -> A2 CLK_Pin 0 нажата 1 нет
DT -> A1 DT_Pin 0 нажата 1 нет
SW -> A0 SW_Pin 0 нажата 1 нет
GND -> GND
+5V -> +5V
*/
// ============= Переменные ====================================
// системные переменые
uint8_t mode_viev ; // 0 режим показа / 1 режим редактирования
uint8_t stat_blink_mode_viev ; // мигалка mode_viev
uint8_t screen_number ; // номер текущего демонстрируемого окна
const int number_of_screen = 9 ; // количество окон
uint8_t SW_data ; // результат функции SW_botton()
uint8_t Encoder_data ; // результат функции Encoder()
uint8_t screen_number_inc(){
if (screen_number < (number_of_screen-1)) screen_number++;
}
uint8_t screen_number_dec(){
if (screen_number > 0) screen_number--;
}
// технологические переменые
uint8_t Var_V1 = 50 ; // Переменная 1
const uint8_t Var_V1_min = 0 ; // Переменная 1 min
const uint8_t Var_V1_max = 100 ; // Переменная 1 maх
void Var_V1_inc(){
if (Var_V1 < Var_V1_max) Var_V1++;
};
void Var_V1_dec(){
if (Var_V1 > Var_V1_min) Var_V1--;
};
uint8_t Var_V2 = 50 ; // Переменная 2
const uint8_t Var_V2_min = 0 ; // Переменная 2 min
const uint8_t Var_V2_max = 100 ; // Переменная 2 maх
void Var_V2_inc(){
if (Var_V2 < Var_V2_max) Var_V2++;
};
void Var_V2_dec(){
if (Var_V2 > Var_V2_min) Var_V2--;
};
uint8_t Var_V3 = 50 ; // Переменная 3
uint8_t Var_V3_min = 0 ; // Переменная 3 min
uint8_t Var_V3_max = 100 ; // Переменная 3 maх
void Var_V3_inc(){
if (Var_V3 < Var_V3_max) Var_V3++;
};
void Var_V3_dec(){
if (Var_V3 > Var_V3_min) Var_V3--;
};
void Edit_Encoder_inc(){ // режим редактирования, энкодер в +
switch (screen_number) {
case 0:Var_V1_inc();break; // инкремент переменой на экране 0
case 1:Var_V2_inc();break; // инкремент переменой на экране 1
case 2:Var_V3_inc();break; // инкремент переменой на экране 2
case 3:;break; // инкремент переменой на экране 3
case 4:;break; // инкремент переменой на экране 4
case 5:;break; // инкремент переменой на экране 5
case 6:;break; // инкремент переменой на экране 6
case 7:;break; // инкремент переменой на экране 7
case 8:Dev3_com();break; // инкремент переменой на экране 8
}
}
void Edit_Encoder_dec(){ // режим редактирования, энкодер в -
switch (screen_number) {
case 0:Var_V1_dec() ;break; // декремент переменой на экране 0
case 1:Var_V2_dec() ;break; // декремент переменой на экране 1
case 2:Var_V3_dec() ;break; // декремент переменой на экране 2
case 3:;break; // декремент переменой на экране 3
case 4:;break; // декремент переменой на экране 4
case 5:;break; // декремент переменой на экране 5
case 6:;break; // декремент переменой на экране 6
case 7:;break; // декремент переменой на экране 7
case 8:Dev3_com();break; // декремент переменой на экране 8
}
}
// ============= Устройство 1 =====================================
const int Dev1_Pin = 3 ; // вывод устройствa 1
void Dev1_ini(){ // инициализация устройствa 1
}
// ============= Устройство 2 =====================================
const int Dev2_Pin = 4 ; // вывод устройствa 2
void Dev2_ini(){ // инициализация устройствa 2
}
// ============= Устройство 3 =====================================
const int Dev3_Pin = 13; // нога устройствa 3
uint8_t Dev3_stat ; // состояние светодиода
void Dev3_ini(){ // инициализация устройствa 3
pinMode(Dev3_Pin, OUTPUT);
Dev3_stat =0;
digitalWrite(Dev3_Pin, Dev3_stat);
}
void Dev3_com(){ // исполнение команды устройством 3
Dev3_stat = !Dev3_stat;
digitalWrite(Dev3_Pin, Dev3_stat);
}
// ============= Подключение LCD1602 по I2C =====================
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
void LCD_ini(){ // инициализация дисплея
mode_viev = 0 ; // установить режим редактирования
stat_blink_mode_viev=0 ;
screen_number = 0 ; // показать экран 0
lcd.init() ;
lcd.backlight() ; // Включаем подсветку дисплея
}
void Stat_viev() { // показать на экране режим и номер окна
lcd.setCursor(15, 0) ;
if (stat_blink_mode_viev&&mode_viev) lcd.print("E"); // показ значка обычный режим
else lcd.print(" "); // показ значка режим редактирования
lcd.setCursor(15, 1) ;
lcd.print(screen_number) ;
}
// ================ Экран 0 =======================================
void Screen0_viev() { // показать экран 0
lcd.clear();
lcd.print("V1 ") ;
lcd.print(Var_V1) ;
}
// ================ Экран 1 =================================
void Screen1_viev() { // показать экран 1
lcd.clear();
lcd.print("V2 ") ;
lcd.print(Var_V2) ;
}
// ================ Экран 2 ===================================
void Screen2_viev() { // показать экран 2
lcd.clear() ;
lcd.print("V3 ") ;
lcd.print(Var_V3) ;
}
// ================ Экран 3 ====================================
void Screen3_viev() { // показать экран 3
lcd.clear();
lcd.print("*** ");
}
// ================ Экран 3 ====================================
void Screen4_viev() { // показать экран 4
lcd.clear();
lcd.print("*** ");
}
// ============= Экран 5 ======================================
void Screen5_viev() { // показать экран 5
lcd.clear();
lcd.print("*** ");
}
// =============== Экран 6 =====================================
void Screen6_viev() { // показать экран 6
lcd.clear();
lcd.print("*** ");
}
// ================== Экран 7 ====================================
void Screen7_viev() { // показать экран 7
lcd.clear();
lcd.print("*** ");
}
// ====================== Экран 8 ==================================
void Screen8_viev() { // показать экран 8
lcd.clear();
lcd.print("VD13 ");
lcd.print(Dev3_stat);
}
void Viev(){
switch (screen_number) {
case 0:Screen0_viev();break; // показать экран устройствa 0
case 1:Screen1_viev();break; // показать экран устройствa 1
case 2:Screen2_viev();break; // показать экран устройствa 2
case 3:Screen3_viev();break; // показать экран устройствa 3
case 4:Screen4_viev();break; // показать экран устройствa 4
case 5:Screen5_viev();break; // показать экран устройствa 5
case 6:Screen6_viev();break; // показать экран устройствa 6
case 7:Screen7_viev();break; // показать экран устройствa 7
case 8:Screen8_viev();break; // показать экран устройствa 8
}
stat_blink_mode_viev = !stat_blink_mode_viev ;
Stat_viev();
}
// ========== обработчик энкодера ===========================
const int CLK_Pin=A2 ; // вывод CLK кнопки 0 нажата 1 нет
const int DT_Pin=A1 ; // вывод DT кнопки 0 нажата 1 нет
const int SW_Pin=A0 ; // вывод кнопки 0 нажата 1 нет
uint8_t statCLK,statCLK_old ; // переменные: состояние CLK вывода сейчас и раньше
uint32_t last_millis ; // переменные: последний millis
void Encoder_ini() { // инициализация энкодера и кпопки в нем
pinMode(SW_Pin, INPUT_PULLUP) ; // вывод на ввод с подтягивающим резистром
pinMode(CLK_Pin, INPUT);
pinMode(DT_Pin, INPUT);
statCLK_old = digitalRead(CLK_Pin);
last_millis = millis();
}
uint8_t Encoder(){
statCLK = digitalRead(CLK_Pin);
if ((statCLK == 0)&&(statCLK_old ==1 )){ // счет по фронту
statCLK_old=statCLK;
return (digitalRead(DT_Pin)+1);
};
statCLK_old=statCLK;
return 0;
}
uint8_t SW_botton(){
if (digitalRead(SW_Pin)) { // кнопка не нажата
last_millis = millis();
return 0;
}
delay(30);
while (digitalRead(SW_Pin) == 0);
delay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
last_millis = millis();
return 0;
}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
last_millis = millis();
return 1;
}
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
}
// ========== функция выполнение без остановки программы ==================
uint8_t non_stop_program(uint16_t span) {
static uint32_t future = 0;
if (millis()<future) return 0;
future += span;
return 1;
}
// ======================= главная часть программы ========================
void setup()
{
Serial.begin(9600) ; // Запускаем последовательный порт
Encoder_ini() ; // инициализация энкодера и кпопки в нем
LCD_ini() ; // инициализация дисплея
}
void loop() {
if (non_stop_program(500)) Viev() ; // обновлять показание на экране раз 0.5 сек
SW_data = SW_botton() ;
Encoder_data = Encoder() ;
if ((mode_viev == 0)&&(Encoder_data == 1)) screen_number_inc() ;
if ((mode_viev == 0)&&(Encoder_data == 2)) screen_number_dec();
if ((mode_viev == 1)&&(Encoder_data == 1)) Edit_Encoder_inc() ;
if ((mode_viev == 1)&&(Encoder_data == 2)) Edit_Encoder_dec();
if (SW_data == 1) mode_viev = ! mode_viev;
if (SW_data == 2) { mode_viev = 0 ;
screen_number = 0; }
}
Ну да. Я шизофенией не страдаю. Как знаю, как думаю, так и пишу. Или у вас ваши мысли по алгоритму и ваш код различаются. Хотя если у вас нет кода, тогда и разницы нет. Логично.
Ох и любит народ из простого делать сложное. Прям, тащатся от собственной заумности!
Обхожусь без millis-ов. Короткое нажатие определяю в момент отжатия, длинное - по продолжительности нажатия, отжатие не волнует.
Ну да. Сказал бы прямо. Для трепа на форуме вам рабочий код не надо. Мол обхожусь без него.
Вы ничего там не поняли. Как определить кнопка нажата или не нажата. Просто уровень вывода. Как определить вот только что произошло нажатие, отжатие . Понятно что померить уровень до и после нажатия с учетом дребезга. А вот "танцы с бубном" начинаются если надо создать функцию которая определяет. 0 - кнопка не нажата, 1 кнопка нажата была не долго. и 2 кнопка нажата была долго. И при наличии дребезга. Так что last_millis это не последний millis , а последний millis когда кнопка была не нажата . Точнее последнее измерение, которое показало, что кнопка была не нажата. И это зафиксировано в last_millis. Разумеется можно было назвать переменную "последний millis когда была кнопка не нажата и близкое к будущему нажатию кнопки". Чтобы по разнице и опредилить, что кнопка долго или коротко была нажата.
Я не понял, что вы хотели сказать в последнем сообщении?
Мне эта команда не мешает.
Тем более она короче при компиляции.
голый загрузчик 450 байт
antidelay() 552 байт
delay() 612 байт
/* Программа : Разработка Модульного и структурного строительства программ
* Система: 9 экранов или 1+4+4 экрана разумеется
* Написал : qwone. Не для своей гордыни, а так что бы люди знали с кого спрашивать за это.
*
* Схема подключения
* Ардуино джойстик GND -> GND
+5V -> +5V
VRx -> A0
VRy -> A1
SW -> A2
I2C LCD1602 GND -> GND
+5V -> +5V
SDA -> A4(SDA)
SCL -> A5(SCL)
пьезопищалку - -> GND
+ -> не подключен
S -> pin 12
Устройство 1 PIN -> 2
Устройство 2 PIN -> 3
Устройство 3 PIN -> 13
*/
// ============= Переменные ====================================
// системные переменые
uint8_t mode_viev ; // 1 режим показа / 0 режим редактирования
uint8_t N_screen ; // номер текущего демонстрируемого окна
uint8_t botton_data ; // результат функции botton()
uint8_t AnalogRd_data ; // результат функции AnalogRd();
// технологические переменые
uint8_t Var_V1 = 50 ; // Переменная 1
const uint8_t Var_V1_min = 0 ; // Переменная 1 min
const uint8_t Var_V1_max = 100 ; // Переменная 1 maх
void Var_V1_inc(){
if (Var_V1 < Var_V1_max) Var_V1++;
};
void Var_V1_dec(){
if (Var_V1 > Var_V1_min) Var_V1--;
};
uint8_t Var_V2 = 50 ; // Переменная 2
const uint8_t Var_V2_min = 0 ; // Переменная 2 min
const uint8_t Var_V2_max = 100 ; // Переменная 2 maх
void Var_V2_inc(){
if (Var_V2 < Var_V2_max) Var_V2++;
};
void Var_V2_dec(){
if (Var_V2 > Var_V2_min) Var_V2--;
};
uint8_t Var_V3 = 50 ; // Переменная 3
uint8_t Var_V3_min = 0 ; // Переменная 3 min
uint8_t Var_V3_max = 100 ; // Переменная 3 maх
void Var_V3_inc(){
if (Var_V3 < Var_V3_max) Var_V3++;
};
void Var_V3_dec(){
if (Var_V3 > Var_V3_min) Var_V3--;
};
// ============= Устройство 1 =====================================
const int Dev1_Pin = 3 ; // вывод устройствa 1
void Dev1_ini(){ // инициализация устройствa 1
}
// ============= Устройство 2 =====================================
const int Dev2_Pin = 4 ; // вывод устройствa 2
void Dev2_ini(){ // инициализация устройствa 2
}
// ============= Устройство 3 =====================================
const int Dev3_Pin = 13; // нога устройствa 3
uint8_t Dev3_stat ; // состояние светодиода
void Dev3_ini(){ // инициализация устройствa 3
pinMode(Dev3_Pin, OUTPUT);
Dev3_stat =0;
digitalWrite(Dev3_Pin, Dev3_stat);
}
void Dev3_com(){ // исполнение команды устройством 3
Dev3_stat = !Dev3_stat;
digitalWrite(Dev3_Pin, Dev3_stat);
}
// === функция обработки кнопки джойстика Arduino ===
const int SW_Pin=A2;// вывод SW кнопки джойстика Arduino 0 нажата 1 нет
uint32_t last_millis; // переменные: последний millis
uint8_t botton(){
if (digitalRead(SW_Pin) == 1){ // кнопка не нажата
last_millis = millis();
return 0;}
antidelay(30);
while (digitalRead(SW_Pin) == 0);
antidelay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
last_millis = millis();
return 0;}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
last_millis = millis();
return 1;}
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
};
void Edit_Short(){ // действие режим редактирование короткое нажатие
Serial.println(AnalogRd_data+9*N_screen);
switch (AnalogRd_data+9*N_screen) {
case 0: // 0 экран влево-вверх
break;
case 1: // 0 экран вверх
break;
case 2: // 0 экран вправо-вверх
break;
case 3: Var_V1_dec(); // 0 экран влево
break;
case 4: Var_V1_inc(); // 0 экран центр
break;
case 5: Var_V1_inc(); // 0 экран вправо
break;
case 6: // 0 экран влево-вниз
break;
case 7: // 0 экран вниз:
break;
case 8: // 0 экран вправо-вниз
break;
case 9: // 1 экран влево-вверх
break;
case 9+3: Var_V2_dec(); // 1 экран влево
break;
case 9+4: Var_V2_inc(); // 1 экран центр
break;
case 9+5: Var_V2_inc(); // 1 экран вправо
break;
case 18+3: Var_V3_dec(); // 2 экран влево
break;
case 18+4: Var_V3_inc(); // 2 экран центр
break;
case 18+5: Var_V3_inc(); // 2 экран вправо
break;
case 76: Dev3_com(); // 8 экран центр
break;
}
}
// ============= Подключение LCD1602 по I2C =====================
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
void LCD_ini(){ // инициализация дисплея
mode_viev = 1; // установить режим показа
N_screen = 4; // показать экран 4
lcd.init();
lcd.backlight(); // Включаем подсветку дисплея
}
// ================ Экран 0 =======================================
void Screen0_viev(){// показать экран 0
lcd.clear();
if (mode_viev) lcd.print(" "); // показ значка обычный режим
else lcd.print("E"); // показ значка режим редактирования
lcd.print(" V1 ") ;
lcd.print(Var_V1) ;
lcd.setCursor(0, 1) ;
lcd.print(N_screen) ;
lcd.print(" ") ;
}
// ================ Экран 1 =================================
void Screen1_viev(){// показать экран 1
lcd.clear();
if (mode_viev) lcd.print(" "); // показ значка обычный режим
else lcd.print("E"); // показ значка режим редактирования
lcd.print(" V2 ") ;
lcd.print(Var_V2) ;
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// ================ Экран 2 ===================================
void Screen2_viev(){// показать экран 2
lcd.clear();
if (mode_viev) lcd.print(" "); // показ значка обычный режим
else lcd.print("E"); // показ значка режим редактирования
lcd.print(" V3 ") ;
lcd.print(Var_V3) ;
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// ================ Экран 3 ====================================
void Screen3_viev(){// показать экран 3
lcd.clear();
if (mode_viev) lcd.print(" ");
else lcd.print("E");
lcd.print(" *** ");
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// ================ Экран 3 ====================================
void Screen4_viev(){// показать экран 4
lcd.clear();
if (mode_viev) lcd.print(" ");
else lcd.print("E");
lcd.print(" *** ");
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// ============= Экран 5 ======================================
void Screen5_viev(){// показать экран устройствa 5
lcd.clear();
if (mode_viev) lcd.print(" ");
else lcd.print("E");
lcd.print(" *** ");
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// =============== Экран 6 =====================================
void Screen6_viev(){ // показать экран устройствa 6
lcd.clear();
if (mode_viev) lcd.print(" ");
else lcd.print("E");
lcd.print(" *** ");
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// ================== Экран 7 ====================================
void Screen7_viev(){ //показать экран устройствa 7
lcd.clear();
if (mode_viev) lcd.print(" ");
else lcd.print("E");
lcd.print(" *** ");
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" ");
}
// ====================== Экран 8 ==================================
void Screen8_viev(){// показать экран устройствa 8
lcd.clear();
if (mode_viev) lcd.print(" ");
else lcd.print("E");
lcd.print(" *** ");
lcd.setCursor(0, 1);
lcd.print(N_screen) ;
lcd.print(" VD13 ");
lcd.print(Dev3_stat);
}
// ============= Подключение пьезопищалку =====================
const int Beep_Pin=12;// вывод пьезопищалки S
void Short_press_Beep(){
tone(Beep_Pin,700,100);
}
void Long_press_Beep(){
tone(Beep_Pin,1000,100);
}
void alarm_Beep(){
tone(Beep_Pin,2000, 1000);
}
// ========== базовый класс "согласовки" ==================
class qw_basic {
public:
qw_basic(uint32_t span);
virtual uint8_t go();
protected:
uint32_t span; // интервал гашения или включения
uint32_t future; // время сменить состояние гашения или включения
};
qw_basic::qw_basic(uint32_t span){
this->span = span ;
future = span + millis();
}
uint8_t qw_basic::go() { // конструктор qw_basic
if (millis() < future) return 1;
future = span + millis();
return 0;
}
qw_basic Time_per_500msec(500); // создание объекта представителя Делать раз в 0.5 сек
// ============ функция обработки аналоговой части джойстика Arduino =====
const int VRx_Pin=A0;// аналоговый вывод VRx джойстика Arduino
const int VRy_Pin=A1;// аналоговый вывод VRy джойстика Arduino
uint16_t VRx;
uint16_t VRy;
uint8_t AnalogRd(){
VRx = analogRead(VRx_Pin);
VRy = analogRead(VRy_Pin);
return((VRx>340)+(VRx>680)+3*(VRy>340)+3*(VRy>680));
};
// ================== antidelay замена обычного delay =================
void antidelay(uint32_t timing){
timing += millis();
while(millis()<=timing);
};
// ======================= главная часть программы ========================
void setup()
{
Serial.begin(9600); // Запускаем последовательный порт
LCD_ini() ; // инициализация LCD1602 по I2C
Dev1_ini(); // инициализация устройствa 1
Dev2_ini(); // инициализация устройствa 2
Dev3_ini(); // инициализация устройствa 3
pinMode(SW_Pin, INPUT_PULLUP); // вывод на ввод с подтягивающим резистром
last_millis = millis();
}
void loop(){
if ( ! Time_per_500msec.go()) { // выполнять под условием раз 0.5 сек
switch (N_screen) {
case 0:Screen0_viev();break; // показать экран устройствa 0
case 1:Screen1_viev();break; // показать экран устройствa 1
case 2:Screen2_viev();break; // показать экран устройствa 2
case 3:Screen3_viev();break; // показать экран устройствa 3
case 4:Screen4_viev();break; // показать экран устройствa 4
case 5:Screen5_viev();break; // показать экран устройствa 5
case 6:Screen6_viev();break; // показать экран устройствa 6
case 7:Screen7_viev();break; // показать экран устройствa 7
case 8:Screen8_viev();break; // показать экран устройствa 8
}
}
botton_data = botton(); // 0 не нажата / 1 короткое нажатие / 2 длиное нажатие
// mode_viev 1 режим показа / 0 режим редактирования
AnalogRd_data = AnalogRd();
if ( botton_data == 1 )Short_press_Beep();
if ( botton_data == 2 ) Long_press_Beep();
if (mode_viev){ // mode_viev =1 режим показа / 0 режим редактирования
if (botton_data == 1 ) N_screen = AnalogRd_data;
if ((botton_data == 2 )&& (AnalogRd_data == 7)) mode_viev = 0 ;
}
else {
if (botton_data == 1 ) Edit_Short() ;
if ((botton_data == 2 )&& (AnalogRd_data == 7)) mode_viev = 1 ;
};
}
/* Выбор экрана - положение джойстика + короткое нажатие
* Вход в режим редактирования - джойстик вниз + длиноеое нажатие
* Редактирование джойстик влево + короткое нажатие = декримент
* Редактирование джойстик центр + короткое нажатие = инкремент
* Выход из режима редактирования - джойстик вниз + длиное нажатие
*/
delay () рубит прерывание. antidelay() этого не делает,просто делает задержку.Хотя в даном случае программа работает и так и так. Может кому-то понадобиться делать прерывание.Вот я и воткнул antidelay(). Продолжаю писать программу.
Яндекс диск https://yadi.sk/d/mP2rplQNu868x
Ну и сам текст. И да появился еще один трюк. Так что собирайте схему, загружайте программу и разбирайтесь если кому интересно. А если нет, то и делать этого не надо.
/* Программа : Разработка Модульного и структурного строительства программ
* Система: 9 экранов или 1+4+4 экрана разумеется
* Написал : qwone. Не для своей гордыни, а так что бы люди знали с кого спрашивать за это.
*
* Схема подключения
* Ардуино джойстик GND -> GND
+5V -> +5V
VRx -> A0
VRy -> A1
SW -> A2
I2C LCD1602 GND -> GND
+5V -> +5V
SDA -> A4(SDA)
SCL -> A5(SCL)
пьезопищалку - -> GND
+ -> не подключен
S -> pin 12
Устройство 0 PIN -> 2
Устройство 1 PIN -> 3
Устройство 2 PIN -> 4
Устройство 3 PIN -> 5
Устройство 4 PIN -> 6
Устройство 5 PIN -> 7
Устройство 6 PIN -> 8
Устройство 7 PIN -> 9
Устройство 8 PIN -> 13
*/
// ========== базовый класс "согласовки" ==================
class qw_basic {
public:
qw_basic(uint32_t span);
virtual uint8_t go();
protected:
uint32_t span; // интервал гашения или включения
uint32_t future; // время сменить состояние гашения или включения
};
qw_basic::qw_basic(uint32_t span){
this->span = span ;
future = span + millis();
}
uint8_t qw_basic::go() { // конструктор qw_basic
if (millis() < future) return 1;
future = span + millis();
return 0;
}
qw_basic Time_per_500msec(500); // создание объекта представителя Делать раз в 0.5 сек
// ============= Подключение пьезопищалку =====================
const int Beep_Pin=12;// вывод пьезопищалки S
void Short_press_Beep(){
tone(Beep_Pin,700,100);
}
void Long_press_Beep(){
tone(Beep_Pin,1000,100);
}
void alarm_Beep(){
tone(Beep_Pin,2000, 1000);
}
// ============= Подключение LCD1602 по I2C =====================
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
uint8_t N_screen; // номер текущего демонстрируемого окна
LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
void LCD_ini(){ // инициализация устройствa 0
N_screen = 9; // сделать показать главное окно (окно 4)
lcd.init();
lcd.backlight(); // Включаем подсветку дисплея
}
void Start_viev(){ // Показать заставку
lcd.clear();
lcd.print("system 1+4+4");
lcd.setCursor(0, 1);
lcd.print("qwone");
}
// ================ Устройство 0 =================================
const int Dev0_Pin=2;// вывод устройствa 0
void Dev0_ini(){ // инициализация устройствa 0
}
void Dev0_viev(){// показать экран устройствa 0
lcd.clear();
lcd.print("Device 0");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev0_Short(){ // действие устройствa 0 при коротком нажатии
N_screen = 0 ; // установить экран устройства 0
Serial.println("Short press 0");
}
void Dev0_Long(){ // инициализация устройствa 0 при длином нажатии
N_screen = 0 ; // установить экран устройства 0
Serial.println("Long press 0");
}
// ============= Устройство 1 =====================================
const int Dev1_Pin=3;// вывод устройствa 1
void Dev1_ini(){ // инициализация устройствa 1
}
void Dev1_viev(){// показать экран устройствa 1
lcd.clear();
lcd.print("Device 1");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev1_Short(){ // действие устройствa 1 при коротком нажатии
N_screen = 1 ; // установить экран устройства 1
Serial.println("Short press 1");
}
void Dev1_Long(){ // инициализация устройствa 1 при длином нажатии
N_screen = 1 ; // установить экран устройства 1
Serial.println("Long press 1");
}
// ================ Устройство 2 ===================================
const int Dev2_Pin=4;// вывод устройствa 2
void Dev2_ini(){ // инициализация устройствa 2
}
void Dev2_viev(){// показать экран устройствa 2
lcd.clear();
lcd.print("Device 2");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev2_Short(){ // действие устройствa 2 при коротком нажатии
N_screen = 2 ; // установить экран устройства 2
Serial.println("Short press 2");
}
void Dev2_Long(){ // инициализация устройствa 2 при длином нажатии
N_screen = 2 ; // установить экран устройства 2
Serial.println("Long press 2");
}
// ================ Устройство 3 ====================================
const int Dev3_Pin=5;// вывод устройствa 3
void Dev3_ini(){ // инициализация устройствa 3
}
void Dev3_viev(){// показать экран устройствa 3
lcd.clear();
lcd.print("Device 3");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev3_Short(){ // действие устройствa 3 при коротком нажатии
N_screen = 3 ; // установить экран устройства 3
Serial.println("Short press 3");
}
void Dev3_Long(){ // инициализация устройствa 3 при длином нажатии
N_screen = 3 ; // установить экран устройства 3
Serial.println("Long press 3");
}
// =========== Устройство 4 ========================================
const int Dev4_Pin=6;// вывод устройствa 4
void Dev4_ini(){ // инициализация устройствa 4
}
void Dev4_viev(){// показать экран устройствa 4
lcd.clear();
lcd.print("General screen");
lcd.setCursor(0, 1);
lcd.print("Device 4");
}
void Dev4_Short(){ // действие устройствa 4 при коротком нажатии
N_screen = 4 ; // установить экран устройства 4
Serial.println("Short press 4");
}
void Dev4_Long(){ // инициализация устройствa 4 при длином нажатии
N_screen = 4 ; // установить экран устройства 4
Serial.println("Long press 4");
}
// ============= Устройство 5 ======================================
const int Dev5_Pin=7;// вывод устройствa 5
void Dev5_ini(){ // инициализация устройствa 5
}
void Dev5_viev(){// показать экран устройствa 5
lcd.clear();
lcd.print("Device 5");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev5_Short(){ // действие устройствa 5 при коротком нажатии
N_screen = 5 ; // установить экран устройства 5
Serial.println("Short press 5");
}
void Dev5_Long(){ // инициализация устройствa 5 при длином нажатии
N_screen = 5 ; // установить экран устройства 5
Serial.println("Long press 5");
}
// =============== Устройство 6 =====================================
const int Dev6_Pin=8;// вывод устройствa 6
void Dev6_ini(){ // инициализация устройствa 6
}
void Dev6_viev(){// показать экран устройствa 6
lcd.clear();
lcd.print("Device 6");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev6_Short(){ // действие устройствa 6 при коротком нажатии
N_screen = 6 ; // установить экран устройства 6
Serial.println("Short press 6");
}
void Dev6_Long(){ // инициализация устройствa 6 при длином нажатии
N_screen = 6 ; // установить экран устройства 6
Serial.println("Long press 6");
}
// ================== Устройство 7 ====================================
const int Dev7_Pin=9;// вывод устройствa 7
void Dev7_ini(){ // инициализация устройствa 7
}
void Dev7_viev(){//показать экран устройствa 7
lcd.clear();
lcd.print("Device 7");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev7_Short(){ // действие устройствa 7 при коротком нажатии
N_screen = 7 ; // установить экран устройства 7
Serial.println("Short press 7");
}
void Dev7_Long(){ // инициализация устройствa 7 при длином нажатии
N_screen = 7 ; // установить экран устройства 7
Serial.println("Long press 7");
}
// ====================== Устройство 8 ==================================
const int Dev8_Pin=13;// вывод устройствa 8
void Dev8_ini(){ // инициализация устройствa 8
pinMode(Dev8_Pin, OUTPUT);
}
void Dev8_viev(){// показать экран устройствa 8
lcd.clear();
lcd.print("Device 8");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev8_Short(){ // действие устройствa 8 при коротком нажатии
N_screen = 8 ; // установить экран устройства 8
digitalWrite(Dev8_Pin, HIGH);
Serial.println("Short press 8");
}
void Dev8_Long(){ // инициализация устройствa 8 при длином нажатии
N_screen = 8 ; // установить экран устройства 8
digitalWrite(Dev8_Pin, LOW);
Serial.println("Long press 8");
}
// ============ функция обработки аналоговой части джойстика Arduino =====
const int VRx_Pin=A0;// аналоговый вывод VRx джойстика Arduino
const int VRy_Pin=A1;// аналоговый вывод VRy джойстика Arduino
uint16_t VRx;
uint16_t VRy;
uint8_t AnalogRd(){
VRx = analogRead(VRx_Pin);
VRy = analogRead(VRy_Pin);
return((VRx>340)+(VRx>680)+3*(VRy>340)+3*(VRy>680));
};
void DoShort(){ // делать при коротком нажатии
switch (AnalogRd()) {
case 0: Dev0_Short();//делать когда равно 0
break;
case 1: Dev1_Short();//делать когда равно 1
break;
case 2: Dev2_Short();//делать когда равно 2
break;
case 3: Dev3_Short();//делать когда равно 3
break;
case 4: Dev4_Short();//делать когда равно 4
break;
case 5: Dev5_Short();//делать когда равно 5
break;
case 6: Dev6_Short();//делать когда равно 6
break;
case 7: Dev7_Short();//делать когда равно 7
break;
case 8: Dev8_Short();//делать когда равно 8
break;
}
}
void DoLong(){ // делать при длином нажатии
switch (AnalogRd()) {
case 0: Dev0_Long();//делать когда равно 0
break;
case 1: Dev1_Long();//делать когда равно 1
break;
case 2: Dev2_Long();//делать когда равно 2
break;
case 3: Dev3_Long();//делать когда равно 3
break;
case 4: Dev4_Long();//делать когда равно 4
break;
case 5: Dev5_Long();//делать когда равно 5
break;
case 6: Dev6_Long();//делать когда равно 6
break;
case 7: Dev7_Long();//делать когда равно 7
break;
case 8: Dev8_Long();//делать когда равно 8
break;
}
}
// ================== antidelay замена обычного delay =================
void antidelay(uint32_t timing){
timing += millis();
while(millis()<=timing);
};
// === функция обработки кнопки джойстика Arduino ===
const int SW_Pin=A2;// вывод SW кнопки джойстика Arduino 0 нажата 1 нет
uint32_t last_millis; // переменные: последний millis
uint8_t botton(){
if (digitalRead(SW_Pin) == 1){ // кнопка не нажата
last_millis = millis();
return 0;}
antidelay(30);
while (digitalRead(SW_Pin) == 0);
antidelay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
last_millis = millis();
return 0;}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
last_millis = millis();
return 1;}
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
};
// ======================= главная часть программы ========================
void setup()
{
Serial.begin(9600); // Запускаем последовательный порт
LCD_ini() ; // инициализация LCD1602 по I2C
Dev0_ini(); // инициализация устройствa 0
Dev1_ini(); // инициализация устройствa 1
Dev2_ini(); // инициализация устройствa 2
Dev3_ini(); // инициализация устройствa 3
Dev4_ini(); // инициализация устройствa 4
Dev5_ini(); // инициализация устройствa 5
Dev6_ini(); // инициализация устройствa 6
Dev7_ini(); // инициализация устройствa 7
Dev8_ini(); // инициализация устройствa 8
pinMode(SW_Pin, INPUT_PULLUP); // вывод на ввод с подтягивающим резистром
last_millis = millis();
}
void loop()
{
if ( ! Time_per_500msec.go()) { // выполнять под условием раз 0.5 сек
switch (N_screen) {
case 0:Dev0_viev(); // показать экран устройствa 0
break;
case 1:Dev1_viev(); // показать экран устройствa 1
break;
case 2:Dev2_viev(); // показать экран устройствa 2
break;
case 3:Dev3_viev(); // показать экран устройствa 3
break;
case 4:Dev4_viev(); // показать экран устройствa 4
break;
case 5:Dev5_viev(); // показать экран устройствa 5
break;
case 6:Dev6_viev(); // показать экран устройствa 6
break;
case 7:Dev7_viev(); // показать экран устройствa 7
break;
case 8:Dev8_viev(); // показать экран устройствa 8
break;
case 9:Start_viev();// показать заставку
break;
}
}
switch (botton()) {
case 1: Short_press_Beep();
DoShort();
break;
case 2: Long_press_Beep();
DoLong();
break;
}
}
Продолжаю выкладывать программу. Конечно лучше для некоторых выложить готовую. Но я показываю, как писать структурированые программы, и модульное проектирование. Это лучше, чем сделать "простыню салата", а потом орать на форуме:"найдите ошибку в программе"
Яндекс диск. http://yadi.sk/d/5ZM2ROz6u7g3A
/* Программа : Разработка Модульного и структурного строительства программ
* Система: 9 экранов или 1+4+4 экрана разумеется
* Написал : qwone. Не для своей гордыни, а так что бы люди знали с кого спрашивать за это.
*
* Схема подключения
* Ардуино джойстик GND -> GND
+5V -> +5V
VRx -> A0
VRy -> A1
SW -> A2
I2C LCD1602 GND -> GND
+5V -> +5V
SDA -> A4(SDA)
SCL -> A5(SCL)
пьезопищалку - -> GND
+ -> не подключен
S -> pin 12
Устройство 0 PIN -> 2
Устройство 1 PIN -> 3
Устройство 2 PIN -> 4
Устройство 3 PIN -> 5
Устройство 4 PIN -> 6
Устройство 5 PIN -> 7
Устройство 6 PIN -> 8
Устройство 7 PIN -> 9
Устройство 8 PIN -> 13
*/
// ============= Подключение пьезопищалку =====================
const int Beep_Pin=12;// вывод пьезопищалки S
void Short_press_Beep(){
tone(Beep_Pin,700,100);
}
void Long_press_Beep(){
tone(Beep_Pin,1000,100);
}
void alarm_Beep(){
tone(Beep_Pin,2000, 1000);
}
// ============= Подключение LCD1602 по I2C =====================
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,16,2); // Устанавливаем дисплей
void LCD_ini(){ // инициализация устройствa 0
lcd.init();
lcd.backlight(); // Включаем подсветку дисплея
lcd.print("system 1+4+4");
lcd.setCursor(0, 1);
lcd.print("qwone");
}
// ================ Устройство 0 =================================
const int Dev0_Pin=2;// вывод устройствa 0
void Dev0_ini(){ // инициализация устройствa 0
}
void Dev0_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 0");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev0_Short(){ // действие устройствa 0 при коротком нажатии
Dev0_viev();
Serial.println("Short press 0");
}
void Dev0_Long(){ // инициализация устройствa 0 при длином нажатии
Serial.println("Long press 0");
}
// ============= Устройство 1 =====================================
const int Dev1_Pin=3;// вывод устройствa 1
void Dev1_ini(){ // инициализация устройствa 1
}
void Dev1_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 1");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev1_Short(){ // действие устройствa 1 при коротком нажатии
Dev1_viev();
Serial.println("Short press 1");
}
void Dev1_Long(){ // инициализация устройствa 1 при длином нажатии
Serial.println("Long press 1");
}
// ================ Устройство 2 ===================================
const int Dev2_Pin=4;// вывод устройствa 2
void Dev2_ini(){ // инициализация устройствa 2
}
void Dev2_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 2");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev2_Short(){ // действие устройствa 2 при коротком нажатии
Dev2_viev();
Serial.println("Short press 2");
}
void Dev2_Long(){ // инициализация устройствa 2 при длином нажатии
Serial.println("Long press 2");
}
// ================ Устройство 3 ====================================
const int Dev3_Pin=5;// вывод устройствa 3
void Dev3_ini(){ // инициализация устройствa 3
}
void Dev3_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 3");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev3_Short(){ // действие устройствa 3 при коротком нажатии
Dev3_viev();
Serial.println("Short press 3");
}
void Dev3_Long(){ // инициализация устройствa 3 при длином нажатии
Serial.println("Long press 3");
}
// =========== Устройство 4 ========================================
const int Dev4_Pin=6;// вывод устройствa 4
void Dev4_ini(){ // инициализация устройствa 4
}
void Dev4_viev(){// экран устройствa 0
lcd.clear();
lcd.print("General screen");
lcd.setCursor(0, 1);
lcd.print("Device 4");
}
void Dev4_Short(){ // действие устройствa 4 при коротком нажатии
Dev4_viev();
Serial.println("Short press 4");
}
void Dev4_Long(){ // инициализация устройствa 4 при длином нажатии
Serial.println("Long press 4");
}
// ============= Устройство 5 ======================================
const int Dev5_Pin=7;// вывод устройствa 5
void Dev5_ini(){ // инициализация устройствa 5
}
void Dev5_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 5");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev5_Short(){ // действие устройствa 5 при коротком нажатии
Dev5_viev();
Serial.println("Short press 5");
}
void Dev5_Long(){ // инициализация устройствa 5 при длином нажатии
Serial.println("Long press 5");
}
// =============== Устройство 6 =====================================
const int Dev6_Pin=8;// вывод устройствa 6
void Dev6_ini(){ // инициализация устройствa 6
}
void Dev6_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 6");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev6_Short(){ // действие устройствa 6 при коротком нажатии
Dev6_viev();
Serial.println("Short press 6");
}
void Dev6_Long(){ // инициализация устройствa 6 при длином нажатии
Serial.println("Long press 6");
}
// ================== Устройство 7 ====================================
const int Dev7_Pin=9;// вывод устройствa 7
void Dev7_ini(){ // инициализация устройствa 7
}
void Dev7_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 7");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev7_Short(){ // действие устройствa 7 при коротком нажатии
Dev7_viev();
Serial.println("Short press 7");
}
void Dev7_Long(){ // инициализация устройствa 7 при длином нажатии
Serial.println("Long press 7");
}
// ====================== Устройство 8 ==================================
const int Dev8_Pin=13;// вывод устройствa 8
void Dev8_ini(){ // инициализация устройствa 8
pinMode(Dev8_Pin, OUTPUT);
}
void Dev8_viev(){// экран устройствa 0
lcd.clear();
lcd.print("Device 8");
lcd.setCursor(0, 1);
lcd.print("none");
}
void Dev8_Short(){ // действие устройствa 8 при коротком нажатии
Dev8_viev();
digitalWrite(Dev8_Pin, HIGH);
Serial.println("Short press 8");
}
void Dev8_Long(){ // инициализация устройствa 8 при длином нажатии
digitalWrite(Dev8_Pin, LOW);
Serial.println("Long press 8");
}
// ============ функция обработки аналоговой части джойстика Arduino =====
const int VRx_Pin=A0;// аналоговый вывод VRx джойстика Arduino
const int VRy_Pin=A1;// аналоговый вывод VRy джойстика Arduino
uint16_t VRx;
uint16_t VRy;
uint8_t AnalogRd(){
VRx = analogRead(VRx_Pin);
VRy = analogRead(VRy_Pin);
return((VRx>340)+(VRx>680)+3*(VRy>340)+3*(VRy>680));
};
void DoShort(){ // делать при коротком нажатии
switch (AnalogRd()) {
case 0: Dev0_Short();//делать когда равно 0
break;
case 1: Dev1_Short();//делать когда равно 1
break;
case 2: Dev2_Short();//делать когда равно 2
break;
case 3: Dev3_Short();//делать когда равно 3
break;
case 4: Dev4_Short();//делать когда равно 4
break;
case 5: Dev5_Short();//делать когда равно 5
break;
case 6: Dev6_Short();//делать когда равно 6
break;
case 7: Dev7_Short();//делать когда равно 7
break;
case 8: Dev8_Short();//делать когда равно 8
break;
}
}
void DoLong(){ // делать при длином нажатии
switch (AnalogRd()) {
case 0: Dev0_Long();//делать когда равно 0
break;
case 1: Dev1_Long();//делать когда равно 1
break;
case 2: Dev2_Long();//делать когда равно 2
break;
case 3: Dev3_Long();//делать когда равно 3
break;
case 4: Dev4_Long();//делать когда равно 4
break;
case 5: Dev5_Long();//делать когда равно 5
break;
case 6: Dev6_Long();//делать когда равно 6
break;
case 7: Dev7_Long();//делать когда равно 7
break;
case 8: Dev8_Long();//делать когда равно 8
break;
}
}
// ================== antidelay замена обычного delay =================
void antidelay(uint32_t timing){
timing += millis();
while(millis()<=timing);
};
// === функция обработки кнопки джойстика Arduino ===
const int SW_Pin=A2;// вывод SW кнопки джойстика Arduino 0 нажата 1 нет
uint32_t last_millis; // переменные: последний millis
uint8_t botton(){
if (digitalRead(SW_Pin) == 1){ // кнопка не нажата
last_millis = millis();
return 0;}
antidelay(30);
while (digitalRead(SW_Pin) == 0);
antidelay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
last_millis = millis();
return 0;}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
last_millis = millis();
return 1;}
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
};
// ======================= главная часть программы ========================
void setup()
{
Serial.begin(9600); // Запускаем последовательный порт
LCD_ini(); // инициализация LCD1602 по I2C
Dev0_ini(); // инициализация устройствa 0
Dev1_ini(); // инициализация устройствa 1
Dev2_ini(); // инициализация устройствa 2
Dev3_ini(); // инициализация устройствa 3
Dev4_ini(); // инициализация устройствa 4
Dev5_ini(); // инициализация устройствa 5
Dev6_ini(); // инициализация устройствa 6
Dev7_ini(); // инициализация устройствa 7
Dev8_ini(); // инициализация устройствa 8
pinMode(SW_Pin, INPUT_PULLUP); // вывод на ввод с подтягивающим резистром
last_millis = millis();
}
void loop()
{
switch (botton()) {
case 1: Short_press_Beep();
DoShort();
break;
case 2: Long_press_Beep();
DoLong();
break;
}
}
lkj , думаешь меня интересует мнение трепла.
Продолжаю программы с использование короткого и длиного нажатия
С помощью этого джойстика http://greenchip.com.ua/23-0-146-0.html и программы можно подавать команды на 9 устройств(левовверх-0 ,, правовниз 8) Для примера 8 устройство это светодиод 13 короткое включить длиное выключить
Место для скачки программы https://yadi.sk/d/SYEYuaJ0u5mAr
// == Устройство 0 =================================================
const int Dev0_Pin=2;// вывод устройствa 0
void Dev0_ini(){ // инициализация устройствa 0
}
void Dev0_Short(){ // действие устройствa 0 при коротком нажатии
Serial.println("Short press 0");
}
void Dev0_Long(){ // инициализация устройствa 0 при длином нажатии
Serial.println("Long press 0");
}
// == Устройство 1 ==================================================
const int Dev1_Pin=3;// вывод устройствa 1
void Dev1_ini(){ // инициализация устройствa 1
}
void Dev1_Short(){ // действие устройствa 1 при коротком нажатии
Serial.println("Short press 1");
}
void Dev1_Long(){ // инициализация устройствa 1 при длином нажатии
Serial.println("Long press 1");
}
// == Устройство 2 ===================================================
const int Dev2_Pin=4;// вывод устройствa 2
void Dev2_ini(){ // инициализация устройствa 2
}
void Dev2_Short(){ // действие устройствa 2 при коротком нажатии
Serial.println("Short press 2");
}
void Dev2_Long(){ // инициализация устройствa 2 при длином нажатии
Serial.println("Long press 2");
}
// == Устройство 3 ==================================================
const int Dev3_Pin=5;// вывод устройствa 3
void Dev3_ini(){ // инициализация устройствa 3
}
void Dev3_Short(){ // действие устройствa 3 при коротком нажатии
Serial.println("Short press 3");
}
void Dev3_Long(){ // инициализация устройствa 3 при длином нажатии
Serial.println("Long press 3");
}
// == Устройство 4 ==================================================
const int Dev4_Pin=6;// вывод устройствa 4
void Dev4_ini(){ // инициализация устройствa 4
}
void Dev4_Short(){ // действие устройствa 4 при коротком нажатии
Serial.println("Short press 4");
}
void Dev4_Long(){ // инициализация устройствa 4 при длином нажатии
Serial.println("Long press 4");
}
// == Устройство 5 ===================================================
const int Dev5_Pin=7;// вывод устройствa 5
void Dev5_ini(){ // инициализация устройствa 5
}
void Dev5_Short(){ // действие устройствa 5 при коротком нажатии
Serial.println("Short press 5");
}
void Dev5_Long(){ // инициализация устройствa 5 при длином нажатии
Serial.println("Long press 5");
}
// == Устройство 6 ===================================================
const int Dev6_Pin=8;// вывод устройствa 6
void Dev6_ini(){ // инициализация устройствa 6
}
void Dev6_Short(){ // действие устройствa 6 при коротком нажатии
Serial.println("Short press 6");
}
void Dev6_Long(){ // инициализация устройствa 6 при длином нажатии
Serial.println("Long press 6");
}
// == Устройство 7 ====================================================
const int Dev7_Pin=9;// вывод устройствa 7
void Dev7_ini(){ // инициализация устройствa 7
}
void Dev7_Short(){ // действие устройствa 7 при коротком нажатии
Serial.println("Short press 7");
}
void Dev7_Long(){ // инициализация устройствa 7 при длином нажатии
Serial.println("Long press 7");
}
// == Устройство 8 ====================================================
const int Dev8_Pin=13;// вывод устройствa 8
void Dev8_ini(){ // инициализация устройствa 8
pinMode(Dev8_Pin, OUTPUT);
}
void Dev8_Short(){ // действие устройствa 8 при коротком нажатии
digitalWrite(Dev8_Pin, HIGH);
Serial.println("Short press 8");
}
void Dev8_Long(){ // инициализация устройствa 8 при длином нажатии
digitalWrite(Dev8_Pin, LOW);
Serial.println("Long press 8");
}
// === функция обработки аналоговой части джойстика Arduino ===
const int VRx_Pin=A0;// аналоговый вывод VRx джойстика Arduino
const int VRy_Pin=A1;// аналоговый вывод VRy джойстика Arduino
uint16_t VRx;
uint16_t VRy;
uint8_t AnalogRd(){
VRx = analogRead(VRx_Pin);
VRy = analogRead(VRy_Pin);
return((VRx>340)+(VRx>680)+3*(VRy>340)+3*(VRy>680));
};
void DoShort(){ // делать при коротком нажатии
switch (AnalogRd()) {
case 0: Dev0_Short() ;//делать когда равно 0
break;
case 1: Dev1_Short(); //делать когда равно 1
break;
case 2: Dev2_Short(); //делать когда равно 2
break;
case 3: Dev3_Short(); //делать когда равно 3
break;
case 4: Dev4_Short(); //делать когда равно 4
break;
case 5: Dev5_Short(); //делать когда равно 5
break;
case 6: Dev6_Short(); //делать когда равно 6
break;
case 7: Dev7_Short(); //делать когда равно 7
break;
case 8: Dev8_Short(); //делать когда равно 8
break;
}
}
void DoLong(){ // делать при длином нажатии
switch (AnalogRd()) {
case 0: Dev0_Long(); //делать когда равно 0
break;
case 1: Dev1_Long(); //делать когда равно 1
break;
case 2: Dev2_Long(); //делать когда равно 2
break;
case 3: Dev3_Long(); //делать когда равно 3
break;
case 4: Dev4_Long(); //делать когда равно 4
break;
case 5: Dev5_Long(); //делать когда равно 5
break;
case 6: Dev6_Long(); //делать когда равно 6
break;
case 7: Dev7_Long(); //делать когда равно 7
break;
case 8: Dev8_Long(); //делать когда равно 8
break;
}
}
// === antidelay замена обычного delay ===
void antidelay(uint32_t timing){
timing += millis();
while(millis()<=timing);
};
// === функция обработки кнопки джойстика Arduino ===
const int SW_Pin=A2;// вывод SW кнопки джойстика Arduino 0 нажата 1 нет
uint32_t last_millis; // переменные: последний millis
uint8_t botton(){
if (digitalRead(SW_Pin) == 1){ // кнопка не нажата
last_millis = millis();
return 0;}
antidelay(30);
while (digitalRead(SW_Pin) == 0);
antidelay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
//Serial.println(millis()-last_millis);
last_millis = millis();
return 0;}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
//Serial.println(millis()-last_millis);
last_millis = millis();
return 1;}
//Serial.println(millis()-last_millis);
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
};
// === главная часть программы ===
void setup()
{
Serial.begin(9600); // Запускаем последовательный порт
Dev0_ini(); // инициализация устройствa 0
Dev1_ini(); // инициализация устройствa 1
Dev2_ini(); // инициализация устройствa 2
Dev3_ini(); // инициализация устройствa 3
Dev4_ini(); // инициализация устройствa 4
Dev5_ini(); // инициализация устройствa 5
Dev6_ini(); // инициализация устройствa 6
Dev7_ini(); // инициализация устройствa 7
Dev8_ini(); // инициализация устройствa 8
pinMode(SW_Pin, INPUT_PULLUP); // вывод на ввод с подтягивающим резистром
last_millis = millis();
}
void loop()
{
switch (botton()) {
case 1: // Serial.println("Short press");
DoShort();
break;
case 2: // Serial.println("Long press");
DoLong();
break;
}
}
Если надо найти ошибку, а идей нет. Начни с постепеного выбрасывания неважных или маловажных команд. Скорее в программе стоит "замок". Вот при 21 он защелкивается.
А теперь тоже самое но на базе Енкодера http://www.banggood.com/ru/KY-040-Rotar … 14010.html
"Короткое нажатие" "длиное нажатие" "по часовой" и "против часовой".
Код на диске http://yadi.sk/d/iZ7XcUs-u3ss7
// обработчик кнопки
const int buttonPin=A0;// вывод кнопки 0 нажата 1 нет
uint32_t last_millis; // переменные: последний millis
uint8_t botton(){
if (digitalRead(buttonPin) == 1){ // кнопка не нажата
last_millis = millis();
return 0;}
delay(30);
while (digitalRead(buttonPin) == 0);
delay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
//Serial.println(millis()-last_millis);
last_millis = millis();
return 0;}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
//Serial.println(millis()-last_millis);
last_millis = millis();
return 1;}
//Serial.println(millis()-last_millis);
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
};
// обработчик энкодера
const int CLK_Pin=A2;// вывод CLK кнопки 0 нажата 1 нет
const int DT_Pin=A1; // вывод DT кнопки 0 нажата 1 нет
uint8_t statCLK,statCLK_old; // переменные: состояние CLK вывода сейчас и раньше
uint8_t Encoder(){
statCLK = digitalRead(CLK_Pin);
if ((statCLK == 0)&&(statCLK_old ==1 )){ // счет по фронту
statCLK_old=statCLK;
return (digitalRead(DT_Pin)+1);
};
statCLK_old=statCLK;
return 0;
};
void setup()
{
Serial.begin(9600); // Запускаем последовательный порт
pinMode(buttonPin, INPUT_PULLUP); // вывод на ввод с подтягивающим резистром
last_millis = millis();
pinMode(CLK_Pin, INPUT);
pinMode(DT_Pin, INPUT);
statCLK_old = digitalRead(CLK_Pin);
}
void loop()
{
switch (botton()) {
case 1: Serial.println("Short press");
break;
case 2: Serial.println("Long press");
break;
}
switch (Encoder()) {
case 1: Serial.println("clockwise");
break;
case 2: Serial.println("counter-clockwise");
break;
}
}
Нажимаешь коротко сообщение "Short press" длиное "Long press".
Это яндекс диск с программой http://yadi.sk/d/B-xRa1fXu3aEq
const int buttonPin=2;// вывод кнопки 0 нажата 1 нет
uint32_t last_millis; // переменные: последний millis
uint8_t botton(){
if (digitalRead(buttonPin) == 1){ // кнопка не нажата
last_millis = millis();
return 0;}
delay(30);
while (digitalRead(buttonPin) == 0);
delay(30);
if (last_millis+65 > millis()){ // ложное срабатывание
//Serial.println(millis()-last_millis);
last_millis = millis();
return 0;}
if (last_millis+300 > millis()){ // короткое нажатие меньше 0.30 сек
//Serial.println(millis()-last_millis);
last_millis = millis();
return 1;}
//Serial.println(millis()-last_millis);
last_millis = millis(); // длинное нажатие больше 0.30 сек
return 2;
};
void setup()
{
Serial.begin(9600); // Запускаем последовательный порт
pinMode(buttonPin, INPUT_PULLUP); // вывод на ввод с подтягивающим резистром
last_millis = millis();
}
void loop()
{
switch (botton()) {
case 1: Serial.println("Short press");
break;
case 2: Serial.println("Long press");
break;
}
}
Конечно это не совсем меню, но построить что то полезное и при этом не запутаться в коде можно.
https://yadi.sk/d/NbavqlJ_tpkgd
Проще говоря там на входы А1-А5 подкючены потонциометры, а на выходе можно подключить реле . И потом последовательно с Сериал кидаюся переменые.
Пример релизации Мультивибратора , частота мигания светодиода задается потенциометром на выв А0.
Разумеется на одной Ардуине можно собрать до 6 независимых мультивибраторов.По числу аналоговых входов.
Программа на двух класс-процессах 1 - мигает светодиодом на выв 13 ; а 2 включает 0 / отключает 1 это мигание выв 2
http://yadi.sk/d/pXeze5_XtkRbP
electronhic Есть такая байка. Жил был царь. Он движением бровей развязывал войну, отправлял армии и так далее. Как он это делал. У него был большой двор. Были наблюдающие за лицом царя 24 часа в сутки. Потом эти наблюдающие сообщали свои наблюдения Большому Совету и уже исходя из возможностей и потребностей этого царства примимали правильное решение. А царь просто хмурил брови и не знал ,что происходит за пределами дворца, хотя и считался в мире Разумным Царем. Так и с вашим меню. Вы хмурите брови, а код программы должен быть поэфективнее работы Большого Совета.
Ну здесь все не так просто. 1) Использование приведеных конструкций. Я называю это класс-процессом. Ну надо же как это называть. Не совмещается с обычным стилем программирования. Так что и основную программу надо писать в виде класс-процесса. 2) программа с меню уже это три класс-процесса: а- основная программа, б- класс-процесс дисплея , в- обработчик команд с клавиатуры, в который входит класс-поток обработки самих клавиш. Так что до меню надо пахать и пахать. И да то меню что сейчас это каменый век. Но пока менять на что-то другое не получится. Ну нет пока рабочего кода.
На 3 . Цикл loop() работает немного не привычном режиме. Он последовательно дает управления всем процессам(представителям классам). А вот уже в представителях классов уже решают, пришло время что-то сделать или подождать.
if (millis() < future) return; // вот где решают , что надо переходить к действию
future = span+millis(); // а здесь готовят новую точку времени для выполнения.
Конечно, что очень не привычно. Но воткнуть в Ардуину месколько независимых процессов того стоит. Да и Ардуины будут развиваться по мощности. И язык Си кростплатформенен. Так что такой вариант структуры программы можно сделать в любой другой среде с языком Си.
ПС: Да и насчет выставления времени в процессах. Если процессы важные, то тайминги можно делать маленькие. А вот если процессу хватит и раз в секунду, то можно и сделать в секунду. Например выводить информацию на экран. Человек - устройство медленное, поэтому процессору много времени обслуживать его не займет. Глядишь и производительность процессора рациональнее распределится.