определение наличия напряжения в сети 220

bwn
Offline
Зарегистрирован: 25.08.2014

masterar пишет:

Для новичков прикладываю схему и формулу для расчета резистора для диода оптопары (на схеме R1, R2 вот здесь у меня была ошибка, все остальное подключал правильно). 

(U - UF) / IF = R

Напряжение подаваемое на светодиод минус макс. прямое напряжение светодиода и всё это делим на ток светодиода.

 
 
 

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

bwn
Offline
Зарегистрирован: 25.08.2014

CARLOS пишет:

MaksMS пишет:

Что за изврат ? зачем прерывания ? Это лишнее

Берем любую зарядку от телефона и через резистор+ стабилизатор на 5в подаем на цифровой вход ардуины..

Ардуина в цикле уже проверяет наличие единички на входе и действует..

Обязателен ли резистор (ом?) и стабилитрон?? В БП зарядки вроде они и так стоят....

На ваше усмотрение, дополнительная защита от китайцев. Во многих китай-зарядках стабилизатора нет в принципе. 

boban_
Offline
Зарегистрирован: 09.10.2013

Если ардуина на 3.3В то схема такая:

БП (5В) -> зарядное для LiOn акк-ра -> диод Шоттки -> LiOn акк -> ардуина

До диода Шоттки можно брать напряжение.

VampeerCo
Offline
Зарегистрирован: 07.02.2017
nickol
Offline
Зарегистрирован: 10.08.2018

Здравствуйте!

Решаю задачу - по датчику напряжения через прерывание вызывать обработчик при отключении AC220V, что-то вроде:

void AC_off_handler() {
  // handler idea - hold the AC on and off time,set TRIGGER_PIN HIGH and disable TRIGGER_PIN state change,
  AC_off_flag = true;
  AC_change_time = CurrentMillis;
  digitalWrite(TRIGGER_PIN, HIGH);   
}

Вопрос - как в прерывании запретить изменение состояния TRIGGER_PIN в основном цикле? То есть можно остановить сам основной цикл while (AC_off_flag)

Но вдруг есть более изящный способ? В идеале игнорирование обращений digitialWrite while (AC_off_flag)?

Спасибо!

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

Изящный способ конечно есть. Это условный оператор if.

nickol
Offline
Зарегистрирован: 10.08.2018

Это как раз не изящный способ, но, конечно, рабочий, спасибо! Приходится перед каждым вызовом digitalWrite ставить проверку проверку AC off flag. К примеру (ниже) уже 2 раза в строках 13, 15.

void trigger_1 (uint8_t pusk_pin, uint32_t pusk_seconds, uint32_t duration) {  // if time from RTC is within "pusk_seconds + longevity" pusk_pin is LOW. If trigger 2 has been started less than 30 secons ago - wait
  uint32_t time_from_RTC = time_sec(); // seconds from the start of the day
  if ((((pusk_seconds + duration) <= DAY_SECONDS) // cycle ends before midnight
    &&(time_from_RTC >= pusk_seconds)
    &&(time_from_RTC < (pusk_seconds + duration)))
    
    ||(((pusk_seconds + duration) > DAY_SECONDS) // cycle ends after midnight
    &&((time_from_RTC >= pusk_seconds)
    || (time_from_RTC < (pusk_seconds + duration - DAY_SECONDS))))) {
      if (digitalRead(pusk_pin)) {
        if (digitalRead(TRIGGER2_PIN)) {
          start_1_millis = CurrentMillis; // hold last trigger start time
          if (!AC_off_flag) digitalWrite(pusk_pin, LOW);
        }
        else if ((CurrentMillis - start_2_millis) >= THRESHOLD * 1000 / DEBUG_TIME_MULTIPLIER) if (!AC_off_flag) digitalWrite(pusk_pin, LOW);
      }
    }
    else if (!digitalRead(pusk_pin)) digitalWrite(pusk_pin, HIGH);
}

 

DetSimen
DetSimen аватар
Онлайн
Зарегистрирован: 25.01.2017

я бы делал проще. 

#include "Arduino.h"
#include "Alarm220.h"

using PAlarmFunc = void(*)(int);



volatile bool     Tick220 = false;    // было ли прерывание от 220
volatile uint32_t LastTick220 = 0;	  // когда было последний рас

PAlarmFunc OnAlarm = NULL;				// функция, вызываемая при пропадании 220


void Alarm220(int);  // prototype


void setup() {
	OnAlarm = Alarm220;
}

void loop() {
	if (Tick220) {			// если было прерывание от 220
		Tick220 = false;    // то сбрасываем его флаг 
		return;				// и уходим, аптамуш всё в порядке
	}

	// если нет, то 
	// смотрим сколько времени не было прерывания 

	uint32_t now = millis();

	// если времени прошло меньше 25 мс, то тоже пока всё в порядке, выходим

	if ((now - LastTick220) < 25) return;

	// иначе тревога, 25 мс прерывания не было, значить 220 Вольт пропало

	if (OnAlarm) OnAlarm(кодошибки);

	abort();

}



ISR какой то там вектор{  // прерывание
	Tick220 = true;
	LastTick220 = millis();
}


void Alarm220(int alarmnum) {
	// включай все что нужно при пропадании напряжения
}

 

b707
Онлайн
Зарегистрирован: 26.05.2017

nickol - у вас общая логика условия кривая. поэтому и "некрасиво". Насколько я понял, вы при каждом проходе через луп проверяете, находится ли время в заданном интервале - и если да - включаете нагрузку. Зачем так делать?

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

Вот и в светче надо сделать точно так же. Когда настает время pusk_seconds - включаем нагрузку, от этого момента отсчитываем duration и выключаем. И тогда эти зубодробительные условия станут значительно проще , а проверку на переход через полночь можно будет убрать вовсе.

nickol
Offline
Зарегистрирован: 10.08.2018

Спасибо, идея понятна! На досуге попробую реализовать.