Фоторезистор и светодиод

Chester
Offline
Зарегистрирован: 14.12.2019

Всем доброго времени суток. Нужна помощь. Задача такая: нужно чтобы при закрывании фоторезистора или выключении света светодиод включался на несколько секунд (5-10) и потом выключался. У меня только пока получилось сделать чтобы светодиод включался при закрывании и выключался при свете. 

int ledPin = 7;
int photoPin = A0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(photoPin, INPUT);

}

void loop() {
  if (analogRead (photoPin) >830)
  digitalWrite (ledPin, HIGH);
  if (analogRead (A0) <600)
  digitalWrite (ledPin, LOW);

}

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Chester пишет:

Задача такая: нужно чтобы при закрывании фоторезистора или выключении света светодиод включался на несколько секунд (5-10) и потом выключался. 

1. А что потом, после того, как выключился? Если, например, свет снова появится? Ничего не делать?

2. А что делать, если во время этих "нескольких секунд" свет снова появится? Тоже ничего? Плевать?

Chester
Offline
Зарегистрирован: 14.12.2019

1. После того как выключился, чтобы можно было повторить (закрыть фоторезистор, чтобы светодиод погас на несколько секунд). 

2. Если во время нескольких секунд свет появится, то светодиод должен погаснуть.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Тогда Делайте его зажигание, после этого при помощи millis ждите, что произойдёт раньше - появится свет или истечёт время. Как только что-то из этого произойдёт - гасите и переходи в изначальное состояние.

Попробуйте это написать. Всё необходимое есть здесь и здесь.

Попробуйте и покажите, что получилось.

Chester
Offline
Зарегистрирован: 14.12.2019

Спасибо) В общем получилось. Но отсчет времени идёт от того момента, когда я убираю палец с фоторезистора. Можно ли как то сделать чтобы время отсчитывалось от тогр момента когда я закрою фоторезистор? И ещё интервал времени до отключения бывает меняется (становится меньше), не знаете с чем это может быть связано?

Вот что получилось:

int ledPin = 7;
int photoPin = A0;
int ledState = LOW;
long previousMillis = 0; 
long interval = 10000;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(photoPin, INPUT);

}

void loop() {
  if (analogRead (photoPin) >600)
  digitalWrite (ledPin, HIGH);
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
  previousMillis = currentMillis; 
  if (ledState == HIGH)
      ledState = LOW;
  digitalWrite(ledPin, ledState);
  }


}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Написано не так, как нужно - с тем и связано.

В стр. №18 что происходит?

b707
Offline
Зарегистрирован: 26.05.2017

Chester пишет:

Спасибо) В общем получилось. Но отсчет времени идёт от того момента, когда я убираю палец с фоторезистора.

посмотрите внимательнее в свой код - у вас отсчет момента вообще не связан с показаниями фоторезистора. Ни с "убиранием пальца", ни с закрыванием - вообще никак.

Chester
Offline
Зарегистрирован: 14.12.2019

Что нужно исправить чтобы интервал времени до отключения не менялся?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Для начала - включать отсчёт времени тогда, когда включаете светодиод. А то сейчас у Вас просто блинк получился.

Гриша
Offline
Зарегистрирован: 27.04.2014

Chester пишет:

Что нужно исправить чтобы интервал времени до отключения не менялся?

нужен таймер, счетчик и признак (флаг). Все это должно выполняться по алгоритму, для этого есть операторы for и if. 

флаг можно ставить из сбрасывать - все зависит от вашей фантазии. 

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

АПД. и считайте свой фоторезистор пока простой кнопкой.

Chester
Offline
Зарегистрирован: 14.12.2019

Можно поподробнее: как сделать чтобы время отсчитывалось после включения светодиода? И что не так со временем, почему меняется?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

А если Вы судите беготню, как Вы делаете. чтобы секундомер включился одновременно свистком? Нажимаете на нём кнопку когда свистите. Ну так и здесь, начинайте отсчёт millis, когда включаете светодиод.

Гриша
Offline
Зарегистрирован: 27.04.2014

Chester пишет:

Можно поподробнее: как сделать чтобы время отсчитывалось после включения светодиода? И что не так со временем, почему меняется?

общий принцип: что-то произошло - запомнили когда это случилось... прибавили некоторое время - что-то сделали и т.д.

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

Chester
Offline
Зарегистрирован: 14.12.2019

Опять я. Всё ещё не выходит. Правда теперь время не меняется, но это наверно из за того что я использовал delay. В остальном пока всё по-прежнему: отсчёт так же начинается с момента убирания пальца, хотя я пробовал поменять.

int ledPin = 7;
int photoPin = A0;
int ledState = LOW;
long interval = 5000;
long previousMillis = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(photoPin, INPUT);

}

void loop() {
  if (analogRead (photoPin) >1000)
  digitalWrite (ledPin, HIGH);
  if (analogRead (photoPin) >1000 && digitalRead(7) == HIGH)
  delay (interval);
  if(millis() - previousMillis >= interval) {
  digitalWrite(ledPin, ledState);
  }
  }

 

Гриша
Offline
Зарегистрирован: 27.04.2014

Chester пишет:

Опять я. Всё ещё не выходит. Правда теперь время не меняется, но это наверно из за того что я использовал delay. В остальном пока всё по-прежнему: отсчёт так же начинается с момента убирания пальца, хотя я пробовал поменять.

int ledPin = 7;
int photoPin = A0;
int ledState = LOW;
long interval = 5000;
long previousMillis = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(photoPin, INPUT);

}

void loop() {
  if (analogRead (photoPin) >1000)
  digitalWrite (ledPin, HIGH);
  if (analogRead (photoPin) >1000 && digitalRead(7) == HIGH)
  delay (interval);
  if(millis() - previousMillis >= interval) {
  digitalWrite(ledPin, ledState);
  }
  }

За то видно, что делаете сами...

начните с разбора этого кода, потом в самом начале LOOP напишите флаг 

if (analogRead (photoPin) >1000) {PhotoLevel = 1;}

else  { PhotoLevel = 0; }

//  не забудьте объявить эту переменную. пусть PhotoLevel - будет флагом.

Chester
Offline
Зарегистрирован: 14.12.2019

Снова здравствуйте. Мне подсказали сделать немного по-другому. Всё работает, но время так же не постоянно. Светодиод отключается то через 5 секунд, то через 3 или 4. Не могу понять с чем это связано.

int ledPin = 7;
int photoPin = A0;
long previousMillis = 0;
long interval = 5000;
unsigned long currentMillis;
int start = 0;
int led = 1;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(photoPin, INPUT);
}

void loop() {
if (analogRead (photoPin) > 800 && led == 1) {
start = 1;
digitalWrite (ledPin, HIGH);
}

if (start == 1)   currentMillis = millis();
if (currentMillis - previousMillis >= interval  ) {
digitalWrite (ledPin, LOW);
previousMillis = currentMillis;
start = 0; 
led = 0;
}
if (analogRead (photoPin) < 800) led = 1;
}

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Chester пишет:
Мне подсказали

А Вы не пробовали свою голову включать? Попробуйте, Вам понравится.

Могу попробовать довести Вас до победного конца, при условии, что Вы будете делать, что скажут.

У Вас проблема с тем, что Вы не знаете что именно Вы собираетесь делать, а пытаетесь программировать. Нельзя запрограммировать "не понимаю что".

Для начала распишите Ваш алгоритм словами по русски. Не используйте средства языка программирования. Просто словами пишите, что собираетесь делать. К языку программирования перейдём только тогда, когда Вы словами сумеете объяснить себе, что Вы делаете.

Chester
Offline
Зарегистрирован: 14.12.2019

Ну давайте попробуем. Есть фоторезистор, есть светодиод. Светодиод не горит на свету. Становится темно и светодиод загорается на несколько секунд, а потом гаснет в темноте. Дальше включается свет, светодиод не горит. Потом опять свет выключается и всё по новой.

sadman41
Offline
Зарегистрирован: 19.10.2016

В применении к фоторезистору: что такое "темно" и что такое "светло" (это два разных состояния)?
В применении к выходу МК и светодиоду: что такое "горит" и "гаснет"?

Т.е. теперь попытайтесь объяснить правила игры микропроцессору, который не оперирует абстрактными понятиями.

SLKH
Offline
Зарегистрирован: 17.08.2015

Chester пишет:

Ну давайте попробуем. Есть фоторезистор, есть светодиод. Светодиод не горит на свету. Становится темно и светодиод загорается на несколько секунд, а потом гаснет в темноте. Дальше включается свет, светодиод не горит. Потом опять свет выключается и всё по новой.

не так. не экономьте строки.

==============

если светло

   светодиод не горит

конецесли

==============

если стало темно

   включили светодиод

   запомнили время

конецесли

==============

и т.д.

 

Ершол нужно учить на школьной информатике...

Chester
Offline
Зарегистрирован: 14.12.2019

Темно - освещение меньше 800 ((photoPin) < 800), светло - освещение  больше 800 ((photoPin) < 800). Светодиод горит - (ledPin, HIGH), светодиод гаснет - (ledPin, LOW).

b707
Offline
Зарегистрирован: 26.05.2017

Chester - уже который вариант кода - а все одна и та же проблема, вы не запоминаете момент времени, когда включили светодиод.

Скажите, что непонятного в этом совете - начинать отсчет интервала по включению светодиода? а если все понятно - почему вы этого не делаете?

Chester
Offline
Зарегистрирован: 14.12.2019

Я не совсем понимаю каким образом начинать отсчет интервала по включению светодиода. То есть если темно и включен светодиод, то начинаем отсчёт. Вот так:

if (analogRead (photoPin) >800 && ledPin == HIGH)
delay (5000)

?

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, как вы начинаете отсчёт, если вам сказали: принимать таблетки через полчаса после еды?

Наверное, посмотрите на часы, запомните текущее время и будете периодически проверять - не пора ли?

b707
Offline
Зарегистрирован: 26.05.2017

Chester пишет:

Я не совсем понимаю каким образом начинать отсчет интервала по включению светодиода. То есть если темно и включен светодиод, то начинаем отсчёт. Вот так:

if (analogRead (photoPin) >800 && ledPin == HIGH)
delay (5000)

?

а причем тут delay() ? - у вас же интервалы на миллис

Chester, скажите, тот код. который Вы постите как "свой" - вы в нем ничерта не понимаете. что ли? Вот например у вас есть такая строчка

if (currentMillis - previousMillis >= interval  ) {

 

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

Гриша
Offline
Зарегистрирован: 27.04.2014

Chester пишет:

Я не совсем понимаю каким образом начинать отсчет интервала по включению светодиода. То есть если темно и включен светодиод, то начинаем отсчёт. Вот так:

if (analogRead (photoPin) >800 && ledPin == HIGH)
delay (5000)

?

нет, не так. Условие правильное (если не придираться), но теперь нужно посмотреть на часы и запомнить время, а потом в другом условии проверять не прошло ли оно... и перейти по ссылки из поста 14 и разобрать тестовый код до последнего символа

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Chester пишет:

Ну давайте попробуем. Есть фоторезистор, есть светодиод. Светодиод не горит на свету. Становится темно и светодиод загорается на несколько секунд, а потом гаснет в темноте. Дальше включается свет, светодиод не горит. Потом опять свет выключается и всё по новой.

Проба неудачная. Вот в #19 ближе к делу, но надо ещё конкретнее.

Chester
Offline
Зарегистрирован: 14.12.2019

Я бы хотел сказать спасибо всем огромное за помощь. Мне это нужно было для универа, но я так и не успел сдать т.к. препод не пришёл. Мне всё-таки помогли доделать код, всё работает. Выложу тут, вдруг кому поможет.

int ledPin = 7;
int photoPin = A0;
long previousMillis = 0;
long interval = 5000;
unsigned long currentMillis;
long prevMillis;
int start = 0;
int led = 1;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(photoPin, INPUT);
}

void loop() {
  // Serial.println(analogRead (photoPin));
  if (analogRead (photoPin) > 800 && led == 1) {
    start = 1;
    previousMillis = millis();
    prevMillis = previousMillis;
    led = 0;
    digitalWrite (ledPin, HIGH);
    Serial.print("start "); Serial.println(millis());
  }

  if (start == 1)    currentMillis = millis();
  if (currentMillis - previousMillis >= interval  ) {
    previousMillis = millis();
    Serial.print("stop "); Serial.print(millis()); Serial.print(" "); Serial.println(previousMillis - prevMillis);
    digitalWrite (ledPin, LOW);
    start = 0;
    led = 0;
  }
  if (analogRead (photoPin) < 800) led = 1;
}