Ви не увійшли.
Есть скетч.
Он управляет светом.
1-й режим - ходовые огни
2-й и 3-й - стробоскопы.
В машине при включении ксенона идет помеха, которая как то попадает в сериал порт и дает ложное собрание.
Ни кондеры ни резисторы ни дроселя - не помогают
Выход один - назначить действие на удержание, но у меня это не получается и все, помогите:
int led1 = 6;
int led2 = 7;
int led3 = 8;
int led4 = 9;
int lighton = 4;
int val=1, stope=1;
long previousMillis = 0;
int buttonState = 0;
long interval = 300;
void setup() {
Serial.begin(9600);
delay(2);
pinMode(2, INPUT);
digitalWrite(2, HIGH);
pinMode (led1, OUTPUT);
pinMode (led2, OUTPUT);
pinMode (led3, OUTPUT);
pinMode (led4, OUTPUT);
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
pinMode (lighton, INPUT); // Вход для выключателя DRL от фар
digitalWrite(lighton, HIGH);
attachInterrupt(0, buttonPin, FALLING);
while(!Serial);
}
void one()
{
while(stope==1)
{
if (digitalRead(lighton) == LOW)
{
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
}
if (digitalRead(lighton) == HIGH) //Если подается +12 с зажигания - ДХО горят
{
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
}
if(Serial.available() > 0) stope = Serial.parseInt();
}
}
void two()
{
while(stope==1)
{
digitalWrite(led1, HIGH);
digitalWrite(led2, LOW);
digitalWrite(led3, HIGH);
digitalWrite(led4, LOW);
delay(300);
digitalWrite(led1, LOW);
digitalWrite(led2, HIGH);
digitalWrite(led3, LOW);
digitalWrite(led4, HIGH);
delay(300);
if(Serial.available() > 0) stope = Serial.parseInt();
}
}
void three()
{
while(stope==1)
{
digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(40);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(40);
digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(40);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(40);
digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(40);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(40);
digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(40);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(40);
digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(40);
digitalWrite(led1, LOW);
digitalWrite(led3, LOW);
delay(40);
digitalWrite(led1, HIGH);
digitalWrite(led3, HIGH);
delay(40);
digitalWrite(led2, HIGH);
digitalWrite(led4, HIGH);
delay(40);
digitalWrite(led2, LOW);
digitalWrite(led4, LOW);
delay(40);
digitalWrite(led2, HIGH);
digitalWrite(led4, HIGH);
delay(40);
digitalWrite(led2, LOW);
digitalWrite(led4, LOW);
delay(40);
digitalWrite(led2, HIGH);
digitalWrite(led4, HIGH);
delay(40);
digitalWrite(led2, LOW);
digitalWrite(led4, LOW);
delay(40);
digitalWrite(led2, HIGH);
digitalWrite(led4, HIGH);
delay(40);
digitalWrite(led2, LOW);
digitalWrite(led4, LOW);
delay(40);
digitalWrite(led2, HIGH);
digitalWrite(led4, HIGH);
delay(40);
digitalWrite(led2, LOW);
digitalWrite(led4, LOW);
delay(40);
digitalWrite(led2, HIGH);
digitalWrite(led4, HIGH);
delay(40);
if(Serial.available() > 0) stope = Serial.parseInt();
}
}
void loop()
{
if(Serial.available() > 0) val = Serial.parseInt();
switch(val)
{
case 1:stope=1; one();break;
case 2:stope=1; two();break;
case 3:stope=1; three();break;
}
}
void buttonPin()
{
static unsigned long millis_prev;
if(millis()-1000 > millis_prev)
{
stope=1;
delay(50);
val++;
delay(50);
stope=0;
Serial.println(val);
if(val==4)val=1;
}
millis_prev = millis();
}
Неактивний
Экранировать пробовал, от части помогло, но не полностью...
Я уже не знаю что пробовать.
Изначально это был проект "по приколу". Вещь - которая не сильно нужна.
Но теперь уже принципиально доделать...
По сути это остался единственный баг...
Мне кажется, что помогло бы переключение режима по удержанию на кнопку...
Остання редакція radio-active (2018-03-06 10:45:04)
Неактивний
а не пробовали почитать про дребезг контактов и по нормальному обрабатывать данные с кнопки, прицепить какую нибудь библиотеку.
Пробовал, причем тут дребезг контактов??? Кнопка отрабатывает четко. Если кнопку не нажимать (даже отключить) и включить фары - идет сработка.
Библиотеку onebutton пробовал, не вышло что то...
Неактивний
)) Тогда причём кнопка? Найдите источник помехи и устраните. Мудрёно? )
Да, мудрЁно... 4 блока розжига и есть помеха....
Просто подскажите как сделать длинное нажатие, что бы на короткое нажатие не было реакции.
При включении фар идет короткая помеха, которая как то попадает в Serial. И программа расценивает эту помеху за нажатие.
А вот если программа будет ждать длинное нажатие, то на эту помеху не должна сработать....
Неактивний
Ну хоть это, ито не получается интегрировать:
#include "OneButton.h"
OneButton button(2, true);
void setup() {
button.attachLongPressStart(buttonPin);
pinMode(13, OUTPUT);
}
void loop() {
button.tick();
delay(10);
}
void buttonPin() {
digitalWrite(13, HIGH);
}
Неактивний
нажал - запомнил время 1
отпустил - запомнил время 2
получил разницу время 2 и время 1
если меньше заданного значения - игнорировать
Да, но я не могу внедрить из за:
attachInterrupt(0, buttonPin, FALLING);
оно мне все портит....
Так скетч отдельно работает:
int T = 0;
void setup()
{
pinMode(13, OUTPUT);
pinMode(2, INPUT);
}
void loop()
{
if(digitalRead(2)==LOW)//если кнопка нажата ...
{
T++;// прибавляем к переменной 1 при каждой смене цикла.
delay(500);//небольшая защита от "дребезга" контактов кнопки
}
else
{
T=0;
}
if(T>=3)
{
digitalWrite(13,!digitalRead(13));//инвертируем состояние пина
T=0;
}
}
А как вставляю в основной код - работает не корректно...
Неактивний
Подозреваю, что человек просто не шарит. Бывает же такое?)
Ну так вы шарящий - подскажите! "Люблю" таких умников на форумах, которые сами нехрена не разбираются, но умничают больше других.
Неактивний
я бы сделал следущее,
для начало избавился бы от делэй и от прерывания. использовал бы таймер - библиотеку SimpleTimer.h .
долгое нажатие сделал бы тоже через таймер. т.е. нажал кнопку - запустился таймер напр. (на 3 сек.) по окончании таймера выполняется функция где идет проверка не нажата ли кнопка.
Неактивний
завести счетчик, он накручивается пока нажата кнопка, при достижении выполняется код. после выполнения кода обнуляется счетчик.
Ну а если правильно то лучше взять готовый велосипед и изваять типа:
if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
longPressActive = true;
LED1State = !LED1State;
digitalWrite(LED1, LED1State);
}
longPressTime - переменная где задаш скок надо удерживать чтоб сие чудо сработало
никаких делаев и переполнения переменных. все ок и все сработает
по аппаратному: самый кайфовый метод на сегодня (для меня лично, в условиях жостких помех от ЧПУ) является PC817 последовательно резистор на 3.3 кОм и последовательно светодиод, именно светодиод- индикация которая подскажет что опто работает и не сгорела, так для перестраховки. Это входной контур а выходной естественно с подтяжкой на GND через 10кОм резистор и напрямую к 5V. Когда опто замыкает- на входе в ардуино(или любого другого МК) 5V.
Работает нормально, при чем в очень большом диапазоне от 9v- 26VDC.
Ссори за баламут но еще не обжился, только зарегистрировался
Неактивний
Есть скетч.
Он управляет светом...
вобчем смысл такой: обнаружил факт нажатия (защитившись от дребезга deBouncerом) и через delay(500) проверяешь val = digitalRead(кнопка)... Если val = удерживаемой кнопке, то запускаем цикл обработки удержания
И про самодельный тимер:
unsigned long volatile now;
typedef struct {
unsigned long Start; // Переменная хранения начального значения счетчика миллисекунд
unsigned long Period; // Переменная хранения периода таймера
bool Enable;
} myStructT;
//---------------------------------------------------------------------------------------------------
myStructT OpenTimer; // привязать коня
...
OpenTimer.Enable = false; // только привязать коня = 2,5 мин
OpenTimer.Period = 150000;
...
где-то в лупе:
now = millis();
...
OpenTimer.Start = now;
OpenTimer.Enable = true;
ну и соответственно
bool Timer( myStructT T )
{
if( millis() > (T.Start + T.Period) )
return true;
else
return false;
}
И про самодельный тимер: ...
Только UFO007 забыл про тот факт, что значение переменной системного времени чиклическое, с периодом 49,7102696181 суток. И вот это не всегда будет соответствовать действительности:
if (millis() > (T.Start + T.Period)) ...
У Вас бывает период больше чем в ~50 cуток? Нет никакой проблемы переполнения.
Причём тут период? Если писать как в #19, то проблема возникает с любым периодом, хоть в 1 мс.
Неактивний