код - можно ли проще?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Первый раз в жизни писал код, так что жду подзатыльники) Вообщем перелопатил инет уже голова дымит, но вроде почти что хотел, я создал! Вот мучает один вопрос; А можно ли проще как то его написать, короче?

#define fadePin1 10 //пин управления MOSFET транзистором
#define fadePin2 9 //пин управления MOSFET транзистором
#define fadePin3 6 //пин управления MOSFET транзистором

int calibrationTime = 30; //Время калибровки датчика (10-60 сек. по даташиту)
int pirPin = 2;  //пин подключения управляющего сигнала PIR датчика
int light;       //переменная для хранения состояния света (вкл/выкл)
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);  //настариваем 2 пин как вход для сигналов с датчика
  pinMode(fadePin1, OUTPUT);//пины на выход, для управления транзисторами
  pinMode(fadePin2, OUTPUT);
  pinMode(fadePin3, OUTPUT);
  light = 0;     //устанаваливаем переменную для первого включения света
  
  Serial.print("Calibrating"); //дадим датчику время на калибровку
  for(int i = 0; i < calibrationTime; i++)
   {
    Serial.print(".");
    delay(1000);
  }
  Serial.println(" done");
  Serial.println("SENSOR ACTIVE");
  delay(50);

}

void loop(){
 
   if(digitalRead(pirPin) == HIGH )  //если сигнал с датчика высокого уровня(т.е. есть движение)
   {
     if(light == 0)   //и если свет не был включен
     {
       for(int i=0; i<=255; i++)  //то плавно включаем свет
       {
       analogWrite(fadePin1, i); 
       delay(10);   //каждые 10мс увелияение на 1
       }
       if(fadePin1 < 200) 
       for(int i=0; i<=255; i++)
       {analogWrite(fadePin2, i); 
       delay(10);
       }
       if(fadePin2 < 200)
       for(int i=0; i<=255; i++)
       {analogWrite(fadePin3, i); 
       delay(10);
       }
      delay(5000); // пауза после полного открытия всех транзисторов 
       light = 1; // передаем значение переменной, что свет включен
     }
   } 
   else  //иначе
   {
     if(light == 1) //если свет включен
     {
       for(int i=255; i>=0; i--)//плавно гасим его
       {
       analogWrite(fadePin1, i);
       delay(10);
       }
       light = 0;
       if(light == 0)
       for(int i=255; i>=0; i--)
       {
       analogWrite(fadePin2, i); 
       delay(10);
       }
       light = 0;
       if(light == 0)
       for(int i=255; i>=0; i--)
       {
       analogWrite(fadePin3, i); 
       delay(10);
       } 
       light = 0; // передаем значение переменной, что свет выключен
     }
   }}

Интересно мне это, хочу научится, хотя бы немного)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Вайвай, сам себе подзатыльник! А поздороваться то забыл! Всем драсте!!!

vde69
Offline
Зарегистрирован: 10.01.2016

для начало надо избавится от всех delay, например так http://arduino.ru/forum/programmirovanie/klass-titanovyi-velosiped-stopwatch

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Условия в строках 39 и 44 абсурдные. fadePin1 объявлен через define как 10, он всегда будет меньше 200, тоже самое с fadePin2...

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

SOCHINEC пишет:
А можно ли проще как то его написать, короче?

Так надо короче, или читабельнее? ;)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Надо логичнее!) я если честно сам не особо понял что я написал, писал просто по логике, по своей логике, что в голове!) Но думаю что все это может быть, проще, короче и читабельнее!)) Это половина кода, который я пытаюсь написать, вот и хочу понять что и как! Так как дальше я думаю будет еще сложнее! Я Ж ГОВОРЮ, ДО ЭТОГО ВООБЩЕ НЕ ЗНАЛ ЧТО ТАКОЕ ВООБЩЕ ВОЗМОЖНО, что то самому собрать, написать, и будет работать)))  Но хочу научится! ;)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Тогда как он работает, почему светодиоды, загораются по очереди, как я и хотел, что на что ссылается? Поясните если не трудно! Это вопрос к уважаемому Andy! 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну так и учитесь! Для начала исправьте то, что вы накопипастили из сети, хотя бы поусраняйте html обрамление. Иначе компилятор ЭТО даже не станет смотреть. Далее, исправьте те ошибки, на которые вам УЖЕ указали, а потом .. выкладывайте продолжим ваше обучение.

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

ну например строки 30-77: почти одно и то же 6 раз. Можно оптимизировать.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Tomasina пишет:

ну например строки 30-77: почти одно и то же 6 раз. Можно оптимизировать.

так вот и я это понимаю, но не понимаю как сделать правильно!) Пока не понимаю...)

ну ни чего, голова, есть, а она нам дана не только чтоб в нее есть!))

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Не учу тех, кто врёт:

In function 'void setup()':
Blink:16: error: expected primary-expression before '<' token
   Serial.print("Calibrating"); <span style="font-family:Verdana, Geneva, Arial, sans-serif;font-size:12px;line-height:1.5em;">//дадим датчику время на калибровку</span>
                                ^
Blink:16: error: 'span' was not declared in this scope
   Serial.print("Calibrating"); <span style="font-family:Verdana, Geneva, Arial, sans-serif;font-size:12px;line-height:1.5em;">//дадим датчику время на калибровку</span>
                                 ^
Blink:16: error: expected ';' before 'style'
   Serial.print("Calibrating"); <span style="font-family:Verdana, Geneva, Arial, sans-serif;font-size:12px;line-height:1.5em;">//дадим датчику время на калибровку</span>
                                      ^
Blink:17: error: 'i' was not declared in this scope
   for(int i = 0; i < calibrationTime; i++)
                  ^
Blink:17: error: expected ';' before ')' token
   for(int i = 0; i < calibrationTime; i++)
                                          ^
exit status 1
expected primary-expression before '<' token

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

а последние 2 почему? Ведь тип для i указан.

Upd: если тег span убрать, то все остальное компилируется.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Andy пишет:

Условия в строках 39 и 44 абсурдные. fadePin1 объявлен через define как 10, он всегда будет меньше 200, тоже самое с fadePin2...

С этим разобрался!) fadePin1 я присвоил им уже и так 6.9 и 10 в самом начале, вот оно чё!)

#define fadePin1 10 //пин управления MOSFET транзистором
#define fadePin2 9 //пин управления MOSFET транзистором
#define fadePin3 6 //пин управления MOSFET транзистором

int calibrationTime = 30; //Время калибровки датчика (10-60 сек. по даташиту)
int pirPin = 2;  //пин подключения управляющего сигнала PIR датчика
int light;       //переменная для хранения состояния света (вкл/выкл)
void setup(){
  Serial.begin(9600);
  pinMode(pirPin, INPUT);  //настариваем 2 пин как вход для сигналов с датчика
  pinMode(fadePin1, OUTPUT);// 3 пин на выход, для управления транзисотором
  pinMode(fadePin2, OUTPUT);
  pinMode(fadePin3, OUTPUT);
  light = 0;     //устанаваливаем переменную для первого включения света
  //дадим датчику время на калибровку
  Serial.print("Calibrating");
  for(int i = 0; i < calibrationTime; i++)
   {
    Serial.print(".");
    delay(1000);
  }
  Serial.println(" done");
  Serial.println("SENSOR ACTIVE");
  delay(50);

}

void loop(){
 
   if(digitalRead(pirPin) == HIGH )  //если сигнал с датчика высокого уровня(т.е. есть движение)
   {
     if(light == 0)   //и если свет не был включен
     {
      for(int i=0; i<=255; i++)  //то плавно включаем свет
       {
       analogWrite(fadePin1, i); 
       delay(10);   //каждые 10мс увелияение на 1
       }
      for(int i=0; i<=255; i++)
       {analogWrite(fadePin2, i); 
       delay(10);
       }
      for(int i=0; i<=255; i++)
       {analogWrite(fadePin3, i); 
       delay(10);
       }
      delay(5000); 
       light = 1; //и передаем значение переменной, что свет включен
     }
   } 
   else  //иначе
   {
     if(light == 1) //если свет включен
     {
      for(int i=255; i>=0; i--)//плавно гасим его
       {
       analogWrite(fadePin1, i);
       delay(10);
       }
      for(int i=255; i>=0; i--)
       {
       analogWrite(fadePin2, i); 
       delay(10);
       }
      for(int i=255; i>=0; i--)
       {
       analogWrite(fadePin3, i); 
       delay(10);
       } 
       light = 0; //и передаем значение переменной, что свет выключен
     }
   }}

 

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

SOCHINEC пишет:
так вот и я это понимаю, но не понимаю как сделать правильно!) Пока не понимаю...)

в строках 32-77 у тебя фактически один и тот же код, меняются только знаки и переменные, поэтому все повторяющееся удобнее вынести в отдельную функцию. Перед loop() пишем:

// Функция плавного зажигания/гашения
// Входные параметры: <номер пина>, <режим (HIGH или LOW)>
void fadeLED(byte pin, boolean state)
{
  for(int i = 255*(1-state); state ? i<=255 : i>=0; state ? i++ : i--)
  {
    //analogWrite(pin, i);
    Serial.println(i);
    delay(10);
  }
}

И тогда где нужно плавное включение на пине 10, то пишем:

fadeLED(10, HIGH);

Где нужно плавное выключение на пине 10, то пишем:

fadeLED(10, LOW);

Тогда цикл loop() становится очень лаконичным и читабельным:



void loop()
{ 
  if(digitalRead(pirPin))  //если есть движение
  {
    if(!light)   //и если свет не был включен
    {
      fadeLED(fadePin1, HIGH);
      fadeLED(fadePin2, HIGH);
      fadeLED(fadePin3, HIGH);
    }
    delay(5000); // пауза после полного открытия всех транзисторов 
    light = 1; // передаем значение переменной, что свет включен
  } 
  else  //иначе
  {
    if(light)   //и если свет включен
    {
      fadeLED(fadePin1, LOW);
      fadeLED(fadePin2, LOW);
      fadeLED(fadePin3, LOW);
    }
    light = 0; // передаем значение переменной, что свет выключен
  }
}

P.S. Объявление цикла for не слишком изящное, красивее сделать чисто на математике, но мне сегодня лень думать...

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

ну незнаю, достаю код сразу из компилятора! Я и не говорю, что я ничего не брал из инета, вот тут взял исходный код! https://www.youtube.com/watch?v=xDjChZ-zFlw

vde69
Offline
Зарегистрирован: 10.01.2016

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Последние 2 - наведенные. Был проброшен кусок текста до первой ; поэтому начало цикла for обработано не было.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

vde69 пишет:

я на 699 дне)))

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Заменить на функции

for(int i=0; i<=255; i++)
        {
          analogWrite(fadePin3, i); 
          delay(10);
        }

и это

      for(int i=255; i>=0; i--)//плавно гасим его
      {
        analogWrite(fadePin1, i);
        delay(10);
      }

например так

//в функцию передаем пин светодиода
void fadeUP(byte pin){//зажигаем
  for(int i=0; i<=255; i++)
  {
    analogWrite(pin, i); 
    delay(10);
  }
}

void fadeDN(byte pin){//гасим
  for(int i=255; i>=0; i--)
  {
    analogWrite(pin, i); 
    delay(10);
  }
}

Можно объединить их в одну

Вызывать например fadeUP(fadePin3); //как пример

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну вы просто откопировали исходный код на 3 лампы неподумавши. Вам точно надо чтобы лампы загорались и гасли строго по очереди или надо плавное И одновременное зажигание-гашение ламп? Давайте для начала уточним ТЗ.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Tomasina пишет:

SOCHINEC пишет:
так вот и я это понимаю, но не понимаю как сделать правильно!) Пока не понимаю...)

в строках 32-77 у тебя фактически один и тот же код, меняются только знаки и переменные, поэтому все повторяющееся удобнее вынести в отдельную функцию. Перед loop() пишем:

// Функция плавного зажигания/гашения
// Входные параметры: <номер пина>, <режим (HIGH или LOW)>
void fadeLED(byte pin, boolean state)
{
  for(int i = 255*(1-state); state ? i<=255 : i>=0; state ? i++ : i--)
  {
    //analogWrite(pin, i);
    Serial.println(i);
    delay(10);
  }
}

И тогда где нужно плавное включение на пине 10, то пишем:

fadeLED(10, HIGH);

Где нужно плавное выключение на пине 10, то пишем:

fadeLED(10, LOW);

Тогда цикл loop() становится очень лаконичным и читабельным:



void loop()
{ 
  if(digitalRead(pirPin))  //если есть движение
  {
    if(!light)   //и если свет не был включен
    {
      fadeLED(fadePin1, HIGH);
      fadeLED(fadePin2, HIGH);
      fadeLED(fadePin3, HIGH);
    }
    delay(5000); // пауза после полного открытия всех транзисторов 
    light = 1; // передаем значение переменной, что свет включен
  } 
  else  //иначе
  {
    if(light)   //и если свет включен
    {
      fadeLED(fadePin1, LOW);
      fadeLED(fadePin2, LOW);
      fadeLED(fadePin3, LOW);
    }
    light = 0; // передаем значение переменной, что свет выключен
  }
}

P.S. Объявление цикла for не слишком изящное, красивее сделать чисто на математике, но мне сегодня лень думать...

в 5 строчке 1 кода мы получается уже присвоили i значение, я правильно понял?

vde69
Offline
Зарегистрирован: 10.01.2016

для начал простыми русским словами распишите алгоритм, например:

// если прошло 5 секунд от .... - надо подать напряжение 1в на ножку .... и запомнить это время

//через каждые 0.5 сек увеличивать напряжение на 1в

// опросить состояние кнопок, если кнопка 1111 нажата - все выключем

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

Ну вы просто откопировали исходный код на 3 лампы неподумавши. Вам точно надо чтобы лампы загорались и гасли строго по очереди или надо плавное И одновременное зажигание-гашение ламп? Давайте для начала уточним ТЗ.

их будет ШИМ: 3, 5, 6, 9, 10, и 11 они должны загораться по очереди, с одного конца в другой и гореть какое-то задонное время или (пока есть сигналы с датчиков), от одного датчика. И загораться в другую сторону от другого! На словах просто)

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

Определить переменные соответственно их размеру

Вместо

int calibrationTime = 30; //Время калибровки датчика (10-60 сек. по даташиту)
int pirPin = 2;  //пин подключения управляющего сигнала PIR датчика
int light;       //переменная для хранения состояния света (вкл/выкл)

Написать

byte calibrationTime = 30; //Время калибровки датчика (10-60 сек. по даташиту)
#define pirPin 2 //пин подключения управляющего сигнала PIR датчика
boolean light;       //переменная для хранения состояния света (вкл/выкл)

Вместо

      for(int=0; i<=255; i++)  //то плавно включаем свет
      {
        analogWrite(fadePin1, i);
        delay(10);   //каждые 10мс увелияение на 1
      }

Писать

      for(byte i=0; i<255; i++)  //то плавно включаем свет
      {
        analogWrite(fadePin1, i);
        delay(10);   //каждые 10мс увелияение на 1
      }

 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Замечательно. Если последовательно, то ваш подход и его улучшения, выложенные уже тут - верны.

Остается разобраться с датчиком или датчиками. так и не понял с ваших "простых слов". :)

1. Сколько всего датчиков?

2. Разные датчики на включение И выключение сработали (кнопки нажаты) ОДНОВРЕМЕННО .. что делать?

3. Ни один датчик не сработал - что делать?

4. В процессе включения, но до его завершения, сработал датчик на выключение - что делать? Аналогично наоборот. Или пока процесс "идет" датчики игнорируются программой?

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

Замечательно. Если последовательно, то ваш подход и его улучшения, выложенные уже тут - верны.

Остается разобраться с датчиком или датчиками. так и не понял с ваших "простых слов". :)

1. Сколько всего датчиков?

2. Разные датчики на включение И выключение сработали (кнопки нажаты) ОДНОВРЕМЕННО .. что делать?

3. Ни один датчик не сработал - что делать?

4. В процессе включения, но до его завершения, сработал датчик на выключение - что делать? Аналогично наоборот. Или пока процесс "идет" датчики игнорируются программой?

1) датчиков 3. два датчика движения и датчик освещенности. один датчик движения в начале пути, другой в конце!

2) одновременно.. зажигать от краев к центру

3) ждать какое-то время, и все потушить в том же порядке, как включалось! 1датчик - с лево на право, 2датчик - с право на лево,                   1+2датчики - от центра к краям! как то так я это вижу! но пока иду по малому пути)      

4) выключение, только после паузы! а вот если движение есть еще, после начала процесса, то надо паузу начинать считать сначала!

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

yul-i-an пишет:

Определить переменные соответственно их размеру

 

Вместо

      for(int=0; i<=255; i++)  //то плавно включаем свет
    

Писать

      for(byte i=0; i<255; i++)  //то плавно включаем свет
     

а что тут изменилось? кроме int и byte 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Э-э-э.. подождите. У вас же вроде как лампы "плавно зажигаются" в первом посту .. какое "движение в начале и конце"? :)

Там "изменилось" - размер памяти под счетчик цикла: int - это 2 байта, а byte  - он один, и к тому же беззнаковый, что привело к изменению проверки в цикле с >= на строго > и это - важно. Читать про диапазоны значений.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Для начала хотя бы лампы от одного датчика! Если все сразу, боюсь не выйдет!)))

разобраться в написании кода, что куда, зачем и почему! 

вот сейчас пытаюсь понять что написано здесь )))

for(int i = 255*(1-state); state ? i<=255 : i>=0; state ? i++ : i--)

если честно, темный лес))) пытаюсь разложить по слогам, а еще лучше по буквам)))

это для Вас это все как 2*2, а я силен в своей работе!) В которую если кто то из Вас начнет вникать, будет так же)))

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

SOCHINEC пишет:
вот сейчас пытаюсь понять что написано здесь...

Если второй входящий параметр HIGH, т.е. 1, то цикл развернется так:

for(int i = 0; i<=255; i++)

Если LOW, то развернется так:

for(int i = 255; i>=0; i--)

Конкретно тут вникать можно позже, сейчас же взять и использовать "как есть", ибо на всю остальную логику не влияет.

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

SOCHINEC пишет:
вот сейчас пытаюсь понять что написано здесь )))

Рассмотри другой вариант

void fadeLED(byte pin, boolean state)
{
  for(int i = 0; i<=255; delay(10), i++) analogWrite(pin, state?i:255-i);
}

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Tomasina я то все собрал, работает! Спасибо! Но надо еще МНЕ понять, почему работатет то)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Да нет там никакого "темного леса", хотя и наверчено зазря.

for(int i = 255*(1-state); (state ? i<=255 : i>=0); (state ? i++ : i--) )

Дважды применен тернарный оператор "функция if()", пишется так: (условие? вычисление_ДА : вычисление_НЕТ). Возвращает или то или иное. Так - понятней? :)

А теперь, давайте вернемся к вашим баранам, пардон лампам и датчикам .. или алгоритму:

Цитата:

1) датчиков 3. два датчика движения и датчик освещенности. один датчик движения в начале пути, другой в конце!

2) одновременно.. зажигать от краев к центру

3) ждать какое-то время, и все потушить в том же порядке, как включалось! 1датчик - с лево на право, 2датчик - с право на лево,                   1+2датчики - от центра к краям! как то так я это вижу! но пока иду по малому пути)      

4) выключение, только после паузы! а вот если движение есть еще, после начала процесса, то надо паузу начинать считать сначала!

Как понял:

Есть некий путь - "коридор" в котором стоит 3,5,6,9,10,11 .. 6 ламп. В концах коридора стоят PIR-датчики присутствия/движения и где-то посередние есть ещё датчик освещенности. Нормально - все выключено. Задача: при недостатке освещения от центрального датчика И при появлении движения плавно включать лампы от соответствующего края до конца коридора - "провести" движение.

Так?

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Дважды применен тернарный оператор "функция if()", пишется так: (условие? вычисление_ДА : вычисление_НЕТ). Возвращает или то или иное. Так - понятней? :) - вот так понятнее, впринцыпе уже и сам разобрал!) Но все равно, ОГРОМНОЕ СПАСИБО!

(Как понял:

Есть некий путь - "коридор" в котором стоит 3,5,6,9,10,11 .. 6 ламп. В концах коридора стоят PIR-датчики присутствия/движения и где-то посередние есть ещё датчик освещенности. Нормально - все выключено. Задача: при недостатке освещения от центрального датчика И при появлении движения плавно включать лампы от соответствующего края до конца коридора - "провести" движение.)

Так?

Да, почти так, только это дорога на улице))!

Tomasina
Tomasina аватар
Offline
Зарегистрирован: 09.03.2013

Andy пишет:
Рассмотри другой вариант

  for(int i = 0; i<=255; delay(10), i++) analogWrite(pin, state?i:255-i);

это даже более изящно и наглядно, нежели мой вариант.

Спасибо, я тоже учусь! :)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Вобщем-то "все равно где" .. хоть тюремный коридор в доме для мышек. :)

Попробуйте выделить из этого описания нечто "первичное" и уже от него строить алгоритм работы. Я вот виже "при недостатке освещения" .. то есть пока датчик освещения показывает "светло" - то нечего включать и проверять на движение. Но, обратите внимание, что как только у вас лампы включатся .. ему точно станет "светло". :) Соответственно, "главное" .. что-то иное. Что? :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

Да нет там никакого "темного леса"

Ну тут для Вас нет темного леса, а для меня он еще и дремуч)))! Давайте рассмотрим Ваш темный лес! ;) не полузуясь гуглом, 

SCOTCH-BRITE что это и с чем его едят? :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

Вобщем-то "все равно где" .. хоть тюремный коридор в доме для мышек. :)

Попробуйте выделить из этого описания нечто "первичное" и уже от него строить алгоритм работы. Я вот виже "при недостатке освещения" .. то есть пока датчик освещения показывает "светло" - то нечего включать и проверять на движение. Но, обратите внимание, что как только у вас лампы включатся .. ему точно станет "светло". :) Соответственно, "главное" .. что-то иное. Что? :)

светло ему не станет, он не будет подсвечен лампами!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

И тем не менее, оно - не главное. Главное это состояния вашей системы. В каких состояниях она может находится?

Logik
Offline
Зарегистрирован: 05.08.2014

vde69 пишет:

8-/

А я получается на 14611+60=1471. Два месяца как собрал типа такого http://samogonka.net/products/pryamotochny-j-kondensator/

Тока в картинках ошибко! Омолаживающее зелье только после конденсатора получается!

ПС. Просто прифигел... будущее настораживает.

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

И тем не менее, оно - не главное. Главное это состояния вашей системы. В каких состояниях она может находится?

светло - OFF, темно и есть движение плавно - ON(если движение продолжается хотя бы с одного датчика то держим - ON), нет движения (пауза, а вдруг движение) плавно - OFF! других состояний вроде не вижу!)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Давайте вместе. :)

"Есть некий путь - "коридор" в котором стоит 3,5,6,9,10,11 .. 6 ламп. В концах коридора стоят PIR-датчики присутствия/движения и где-то посередние есть ещё датчик освещенности. Нормально - все выключено. Задача: при недостатке освещения от центрального датчика И при появлении движения плавно включать лампы от соответствующего края до конца коридора - "провести" движение."

1. Старт системы: Нормально - всё выключено.

2. Датчик освещения фиксирует "светло" и блокирует работу всего остального. Ничего не проверяем, ничего не делаем.

3. Освещения мало: Датчики движения молчат - продолжаем опрос датчиков движения пока не п.2.

4. Сработал датчик освещения. Фиксируем начало состояния: "включение ламп по очереди с этого края" (п.5)

5. Включае лампы по очереди с активного края И фиксируем время для перехода в состояние п.6 "Последовательное выключение ламп с этого края"

6. По истечению задержки из п.5: Последовательно выключаем лампы с этого же края.

Примечания:

** В процессе обработки состояний п.4.,п.5 и п.6. ОДНОВРЕМЕННО с ними продолжаем опрос датчиков движения из п.3 (а вдруг сработает второй датчик?)

** Повторное срабатывание того же самого датчика блокируется до начала п.6. И если он активен до п.6., последний пропускается, а задержка исчисляется заново. То есть лампы не гасим до истечения новой задержки.

** Срабатывание одного датчика движения должно блокировать активность другого в небольшом интервале времени по истечению задержки между п.5 и п.6 - "выход" вошедшего движущегося объекта из коридора. Он оттуда ожидаемо выходит за типовой интервал времени.

Так? :) (Фактически имеем типовой конечный автомат, с ДРАКОН-схемой "силуэт")

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Ну и ещё, в догонку.

Сигнал от датчика движения переводит вашу систему (КА - конечный автомат) в направленный, линейно исполняемый алгоритм по включению ламп и ожиданию задержки. То есть таких состояний - 2 по количеству датчиков (отсюда-туда и обратно). Каждое из состояний может исполняться ОДНОВРЕМЕННО - заход в коридор с двух концов. И завершаться они должны также по сигналам со "второго" датчика - НЕЗАВИСИМО друг от друга.

Соответственно, для фиксации таких состояний вам потребуется 2 переменных - "флага": "движение слева направо начато" и "движение справа-налево начато". Это же флаги можно использовать и для п.6: "начато выключение ламп слева-направо" .. простым кодированием значения: 0 - нет активной фазы, 1 - фаза включения (п.5), 2 - выключаем (п.6).

Блоки алгоритма по включению-выключению ламп, получается должны исполняться "по частям", поскольку может потребоваться включать лампы с обоих концов одновременно (но не обязательно одинаково! С одной стороны может уже гореть 2 лампы, а с другой движение только началось!). У вас 6 ламп, соответственно можно завести ещё 2 переменных, содержащих номер включаемой/выключаемой лампы с каждой стороны. Режим включать или выключать - определяется предыдущим абзацем. Тут нам вполне достаточно текущего номера лампы.

Ну вот теперь можно уточнить алгоритм смены состояний вашего КА. :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

1. Старт системы: Нормально - всё выключено.

2. Датчик освещения фиксирует "светло" и блокирует работу всего остального. Ничего не проверяем, ничего не делаем.

3. Освещения мало: Датчики движения молчат - продолжаем опрос датчиков движения пока не п.2.

4. Сработал датчик движения. Фиксируем начало состояния: (опрашиваем 2 датчик) "включение ламп по очереди с этого края" (п.5) 

5. Включае лампы по очереди с активного края (опрашиваем 2 датчик) И фиксируем время для перехода в состояние  п.6 "Последовательное выключение ламп с этого края"

6. По истечению задержки из п.5: (опрашиваем оба датчика, если движения нет, если движение есть хотя бы не одном датчике п.6 начинаем заного) Последовательно выключаем лампы с этого же края.

7. если в процессе выключения, есть движение, останавливаем выключение  , и снова начиная со значения на котором остановили процесс выключения включаем с того края, с которого движение!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Уточненный алгоритм:

Старт системы: настроить входы-выходы и все выключить нафиг.

Повторять все время:

1. Если светло, то выход. Ничего не делаем.

2. Если первый датчик не блокирован И сработал, то: текущая лампа = 0; включить режим "от первого ко второму, включение ламп"; Перейти к п.3;

3. Если второй датчик не блокирован И сработал, то: текущая лампа = 0; включить режим "от второго к первому, включение ламп"; Перейти к п.4;

4. Если включен режим "от первого ко второму", то:

4.1. Включить текущую лампу; Увеличить номер лампы; Если номер последний, то: текущая лампа = 0; изменить режим на "выключение ламп от первой ко второй"; установить задержку режима.

5., 5.1. Аналогично п.4 но для второго режима

6. Если включен режим "выключение" И время задержки кончилось, то:

6.1. выключаем текущую лампу; номер лампы++; Если номер последний, то: изменяем режим в 0 (нет действий) и включаем задержку блокировки второго датчика.

.. второе направление - аналогично.

Ну вот, в силу аналогичности действий, напрашивается организовать данные в массив "направлений" (пока из 2-х) и завернуть алгоритм в цикл по направлениям.

Дальше как, справитесь сами? :)

Как видите, до самой программы дело ещё даже не дошло...

 

 

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

И завершаться они должны также по сигналам со "второго" датчика - НЕЗАВИСИМО друг от друга.

 

Ну тут не соглашусь! Прохожу 1 датчик, загорелось, прошел половину, и вдруг меня заметил 2 датчик, все потухло, а дойти не успел!)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 Вы меня совсем заморочили уже))) это конечно хорошо, но рано! Мне бы хотя бы пока так!

1. датчик движения 1 сработал - зажигаем слева на право!

2. ждем 10 сек. просто HIGH!

3. выключаем слева на право!

4. датчик движения 2 сработал - зажигаем с право на лево!

5. ждем 10 сек. просто HIGH!

6. выключаем с право на лево!

и ПОКА это все!

первые 3 пункта вроде освоил, но не до конца!)

Надо же вникнуть, понять! а когда так много условий, начинаю путаться)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Вот. Для этого второй датчик и блокируем, чтобы он на выходящего не сработал. :)

SOCHINEC
Offline
Зарегистрирован: 01.05.2016

Arhat109-2 пишет:

Вот. Для этого второй датчик и блокируем, чтобы он на выходящего не сработал. :)

так он должен сработать, и начать отсчет паузы заного!

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

?!? Вам не терпится покодить и посмотреть результат? А может сначала доведем сам алгоритм "до ума", а потом начнем его программировать? В словах мне кажется проще такое сделать чем потом сидеть и править программу. Нет? :)

Вам тоже настоятельно рекомендую для начала разыскать тут drakon.su книжку Паронджанова "Занимательная информатика" и прочитать её. Мой рыбенок освоил ейё за пару дней. Очень доходчивый язык и веселые задачки. Давайте все-таки сначала алгоритм, а потом код программы.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Тогда ваша пауза будет работать дважды: по входу в коридор от первого И по выходу из него от второго датчика.