Помогите с ШИМ сриптом

sirius82
Offline
Зарегистрирован: 29.10.2014

Ардуинка с датчиком + 2 светодиода (для теста, после теста будет 8 шт.).

Логика: Есть кратковременный сигнал от датчика, запускаем плавное зажигание светодиодов, при достижении последнего ждем и далее уже плавно гасим. Если при гашении датчик опять сработал, то плавно обратно возвращаем яркость светодиодов с того, на котором остановились, когда появился повторный сигнал с датчика.

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

Первые варианты программного когда были операторах IF (все работало как я хотел, но иногда зависал процесс, на датчик ничего не реагировало)... потом я перешел на switch, код упростился, но осталось добить последний глюк, который я не могу выявить.
 

int calibrationTime = 2; 
int pirPin = A0; //вывод подключения сенсора
int Ledstart = 5; //пин первого светодиода
int timedelay=0; //задержка между огнями
int lnumber=6; //пин последнего светодиода
int i,j; //переменные 
int wait = 3000; //ожидание по свечению после датчика 

int PinStart; // с этого пина стартуем 
int FadeStart; // с этой яркости стартуем

int FadeStop; // здесь запомним величину яркости
int PinStop; // здесь запомним светодиод на котором остановилось гашение
int programsNumber; 
/////////////////////////////
//SETUP
void setup(){

Serial.begin(9600);
pinMode(pirPin, INPUT);
digitalWrite(pirPin, LOW);

for (i=Ledstart;i<=lnumber;i++) //определяем какие порты будут у нас рабочими, к примеру для 8 светодиодов: 0-7 
{
pinMode(i,OUTPUT); 
}
//дадим датчику время на калибровку
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);

programsNumber = 0;
PinStart = Ledstart;
Ledstart;
}
////////////////////////////
//LOOP
void loop(){
//... начало старта по движению
if(digitalRead(pirPin) == HIGH && digitalRead(Ledstart) == 0 ){ //..если датчик сработал и первый светодиод не горит
Serial.println("START");
PinStart = Ledstart; // указываем первый пин светодиода при первом старте
programsNumber = 1; // запуск первого case логики
j=0;
FadeStart = 0; // стартуем с нуля по яркости

}
switch (programsNumber) 
{
case 1: //... полное нарастание при старте
{ 
for(int FadeStart = FadeStart; FadeStart <= 255; FadeStart ++) { // тут только один светодиод, который зажигается с уровня яркости котоырй зафиксировали после того, как сработал датчик при гашении. До этого, он просто идет первым при плавном зажигании, при первом срабатывании датчика
analogWrite(PinStart, FadeStart); 
delay(6);
}

for (int i=PinStart+1;i<=lnumber;i++) { // зажигание остальных светодиоды после гашения с 0 уровня яркости
for(int fadeValue = 0 ; fadeValue <= 255; fadeValue ++) { 
analogWrite(i, fadeValue); 
delay(6);
}

delay(timedelay);//подождали перед следующим светодиодом
}


delay(wait); // пауза на свечение

for (int i=lnumber;i>=Ledstart;i--) { //.. переход на затухание после полного зажигания света 
for(int fadePirPin = 255; fadePirPin >= 0; fadePirPin -=1) { //the led visualizes the sensors output pin state
analogWrite(i, fadePirPin); 
delay(15); 

if(digitalRead(pirPin) == HIGH ){ //... если при гашении срабатывает датчик останавливаем гашение и запоминаем на каком светодиоде остановилось и на каком уровне гашения 
Serial.println("stop");
delay(10);
j=2;
break;
} 
FadeStop = fadePirPin; // тут фиксируем уровень яркости при гашении и срабатывании break на датчик
PinStop = i; // тут запомниаем светодиод при brake на датчик
Serial.println(PinStop);
Serial.println(fadePirPin);
}

}
programsNumber=0+j; // переходим на case 2  если сработал датчик  при гашении
}
break;


case 2: //...дозажигает светодиод
{ 
Serial.println("start grow ");
PinStart = PinStop;
FadeStart = FadeStop;
j=0;
programsNumber=1; // идем на case 1 и дозажигаем погасшие светодиоды
}
break; 
}

} 

 

я не знаю где проблема, есть вероятность, что это тут: 

for (int i=PinStart+1;i<=lnumber;i++) {

И то, что светодиод который идет после одиночного за счет того, что +1 - становится больше чем пин последнего светодиода (inumber)

Из-за чего рушится вся локига и светодиоды с первого выключаются и заново увеличивают яркость. МОгу ошибаться конечно. В общем нужна помощь.

 

Radjah
Offline
Зарегистрирован: 06.08.2014

Больше глобальных переменных для бога глобальных переменных!

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Radjah пишет:

Больше глобальных переменных для бога глобальных переменных!

У вас комплекс насчет глобальных переменных в элементарных скетчах?

Radjah
Offline
Зарегистрирован: 06.08.2014

Б - Бережливость.

An25
Offline
Зарегистрирован: 19.09.2014

Блин-блинский! Двумя темами ниже я приводил готовое решение этой проблемы на случай 5-и датчиков и 5-и ламп. Ну искать что-ли совсем лень!!!???

http://arduino.ru/forum/programmirovanie/upravlenie-svetom-s-pomoshchyu-arduiny-i-datchika-dvizheniya

Если хочется найти ошибку именно в вашем скетче, то увы, я не возьмусь.