• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Диммер на ESP-01

Melandr

Member
Добрый день!
Делаю диммер на ESP-01 с подключением к Cayenne. Проблем с поключением к Cayenne нет, вижу информацию с микроконтроллера. Но почему-то не срабатывает прерывание по переходу через 0, и соответственно нет управления нагрузкой. Ниже схема и код. Есть сомнения в правильности указания номеров пинов ESP-01
схема.png
Код:
//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial    // Comment this out to disable prints and save space
#include <CayenneMQTTESP8266.h>                                     // Include library file for MQTT
//#include <SimpleTimer.h>

#define TRIAC_PIN     2         //GPIO2
#define ZC_PIN        1         //GPIO1 - TXD
#define BUTTON_PIN    3         //GPIO3 - RXD

void ICACHE_RAM_ATTR zero_crosss_int();

char ssid[] = "ASUS";                                               // Your WIFI Name   
char wifiPassword[] = "xxx";                                    // Your WIFI password
char username[] = "xxxx";           // Your MQTT cayenne username
char Password[] = "xxxx";       // Your MQTT cayenne Password
char clientID[] = "xxxx";           // Your MQTT cayenne clientID

//SimpleTimer timer;

int DIMMING_VALUES = 0;
int DIMMING_TIME = 0;
int BUTTON = 0;

volatile unsigned long countZeroCross = 0;
unsigned long lastMillis = 0;
/*
// This function sends Arduino's up time every second to Virtual Pin 5.
void sendUptime()
{
  // Send values using the virtualWrite function. Cayenne currently accepts int and float values.
  // Please don't send more that 10 values per second.
  Cayenne.virtualWrite(V5, millis() / 1000);
}*/

//=====================Basic Setup ============================

void setup(){ 
   Serial.begin(115200);                                              // Setup Debug uart port if you want ?
   pinMode(TRIAC_PIN, OUTPUT);                                         // Set AC Load pin as output
   digitalWrite(TRIAC_PIN, LOW);
   pinMode(BUTTON_PIN, INPUT_PULLUP);
   pinMode(ZC_PIN, INPUT_PULLUP);
  
   attachInterrupt(digitalPinToInterrupt(ZC_PIN), zero_crosss_int, RISING);                     // Choose the zero cross interrupt egde selection
   Cayenne.begin(username, Password, clientID, ssid, wifiPassword); // Setup cayenne server for MQTT protocol

   // Настройте функцию, которая будет вызываться каждую секунду
//  timer.setInterval(1000L, sendUptime);
}

void loop()
  {
      Cayenne.loop();
 //     timer.run(); // Инициализация SimpleTimer
      if(millis() - lastMillis > 1000){
        lastMillis = millis();
      }
      BUTTON = digitalRead(BUTTON_PIN);
  }

void ICACHE_RAM_ATTR zero_crosss_int()                   //function to be fired at the zero crossing to dim the light
{
  DIMMING_TIME = (75 * DIMMING_VALUES);  // For 60Hz =>65
  delayMicroseconds(DIMMING_TIME);       // Wait till firing the TRIAC
  digitalWrite(TRIAC_PIN, HIGH);            // Fire the TRIAC
  delayMicroseconds(10);                 // triac On propogation delay
                                         // (for 60Hz use 8.33) Some Triacs need a longer period
  digitalWrite(TRIAC_PIN, LOW);             // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
  countZeroCross += countZeroCross;
}

CAYENNE_OUT_DEFAULT()
{
  // Write data to Cayenne here. This example just sends the current uptime in milliseconds on virtual channel 0.
  Cayenne.virtualWrite(V0, millis());
  Serial.println(millis());
  Cayenne.virtualWrite(V5, BUTTON);
  Serial.println(BUTTON);
  Cayenne.virtualWrite(V6, countZeroCross);   
  Serial.println(countZeroCross);
  // Some examples of other functions you can use to send data.
  //Cayenne.celsiusWrite(1, 22.0);
  //Cayenne.luxWrite(2, 700);
  //Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
}

CAYENNE_IN(1)
{
  int Dimm_Val=getValue.asInt();
  DIMMING_VALUES = (120-Dimm_Val);
  Serial.println(DIMMING_VALUES);
}

CAYENNE_IN(2)
{
  digitalWrite(TRIAC_PIN, !getValue.asInt());  // to get the value from the website 
}
//==================================================================
Заранее спасибо за помощь!
 

CodeNameHawk

Moderator
Команда форума
Если не работает обычно делают отладку.
Покажите как вы пытаетесь отладить.
Один из методов это оставить только код, который относиться к проблеме, выбросив все остальное.
 

nikolz

Well-known member
для начала выведите на терминал значение сигнала перехода через ноль путем чтения пина в цикле.
 

nikolz

Well-known member
вот вариант простейшего алгоритма диммера :
-----------------------------------
int Dimmer, Shift;
void setup()
{
Shift=100; //установить задержку включения относительно нуля
//... вставить настройку порта ввода сигнала нуля на ввод и порта вывода сигнала на управление
...
// настроить прерывание от пина ввода нуля на высокий уровень detect - Функция колбека прерывания
...
}
void loop()
{
... // сброс сигнала управления в Low
if ((Dimmer--)==0) установить сигнал управления в High;
}
//********************обработчики прерываний*******************************
void detect() { Dimmer=Shift; }
 

Melandr

Member
Доброй ночи!
Ниже осциллограмма на выводе отслеживания перехода через "0"
SDS00001.jpg
Видно, что в момент перехода через "0" напряжение падает до 3 В. И соответственно, этого мало, чтобы сработало прерывание микроконтроллера. Выше в теме схема, это вывод ZERO. Что необходимо изменить в детекторе перехода через "0", чтобы правильно срабатывало прерывание.
С программой думаю проблем быть не должно, проблема чисто аппаратная.
Также на вывод 220V подключен выключатель, информация о состоянии этого выключателя идет в Cayenne.
 

nikolz

Well-known member
У вас ZERO подключено к пину, который используется как выход UART.
Его надо ПРОГРАММНО включить на вход - это раз.
Кроме того, АППАРАТНО можно увеличить резистор R15 - это два.
возможно взять другой оптрон - это три.
 

nikolz

Well-known member
у вас MOC изображен с детектором нуля.
надо так изобразить
1605413263625.png
 

nikolz

Well-known member
еще у вас сопротивления R2+R3=60 кОм
что обеспечит максимальный ток 310/60=5 ма
а минимальный ток для 4N35 =10 ма
можно либо резисторы R2,R3 уменьшить - это четыре.
либо попробовать через базу (6) приоткрыть транзистор -это пять.
-------------------
для начала покажите картинку при отключенном ZERO от пина ESP.
 

nikolz

Well-known member
и еще...
нет смысла делать обнаружитель нуля двухполупериодный.
проще и лучше сделать на один период. и проблем не будет и деталей меньше и результат лучше.
 

nikolz

Well-known member
так как у Вас микропроцессор, то он может определить оба фронта импульса.
Поэтому детектор нуля можно аппаратно упростить и сделать OK2 по входу так же как OK1,
а программно если надо обнаруживать и отрицательный фронт.
Но, реально, я ранее нарисовал вам алгоритм, достаточно определить лишь один фронт импульса.
 

nikolz

Well-known member
еще у вас на схеме лишние резисторы
R9 - закоротить
R10 -можно убрать
все резисторы обвязки ESP лучше поставить номиналом 4.7к
 

nikolz

Well-known member
чем больше R15, тем меньше надо ток для открытия оптрона OK2.
это для примера PC817 его лучше поставить в OK2
1605421540768.png
 

CodeNameHawk

Moderator
Команда форума
Видно, что в момент перехода через "0" напряжение падает до 3 В. И соответственно, этого мало, чтобы сработало прерывание микроконтроллера.
void setup(){ Serial.begin(115200); // Setup Debug uart port if you want ? pinMode(TRIAC_PIN, OUTPUT); // Set AC Load pin as output digitalWrite(TRIAC_PIN, LOW); pinMode(BUTTON_PIN, INPUT_PULLUP);

pinMode(ZC_PIN, INPUT_PULLUP);
Не используйте Serial, если подключились к ноге Тх.
 

Melandr

Member
Его надо ПРОГРАММНО включить на вход - это раз.
pinMode(ZC_PIN, INPUT_PULLUP);
Это в коде выше в теме.
для начала покажите картинку при отключенном ZERO от пина ESP.
Это картинка была без установленной платы ESP-01
Определитель нуля - это линия ZC. А линия 220V служит для отслеживания наличия 220В при включении выключателя обычного, который включает свет. Выключатель может быть выключен, а вентилятором вытяжки нужно управлять, поэтому там и стоит отдельный оптрон.
 

nikolz

Well-known member
pinMode(ZC_PIN, INPUT_PULLUP);
Это в коде выше в теме.

Это картинка была без установленной платы ESP-01
Определитель нуля - это линия ZC. А линия 220V служит для отслеживания наличия 220В при включении выключателя обычного, который включает свет. Выключатель может быть выключен, а вентилятором вытяжки нужно управлять, поэтому там и стоит отдельный оптрон.
Тогда покажите картинку ZERO для резистора R15=10 кОм.
-----------
У Вас блок питания от 220 вольт работает, чтобы показать что есть 220 вольт Вы еще OK1 поставили,
который от 3.3 вольт запитали.
Может быть не надо так хитро делать, а просто вывести с блока питания 3.3 вольта?
 

Melandr

Member
Подключали такую штуку?
Если нет , разбирайтесь зачем там питание отдельно, выключателя не хватает
 

Melandr

Member
Есть 2 выключателя, включающие свет в санузле и ванной.
Необходимо включать два вентилятора по таймер с задержкой выключения по этим выключателям и регулировать скорость бонусом.Устройство должно быть постоянно под питанием
 

nikolz

Well-known member
Есть 2 выключателя, включающие свет в санузле и ванной.
Необходимо включать два вентилятора по таймер с задержкой выключения по этим выключателям и регулировать скорость бонусом.Устройство должно быть постоянно под питанием
оно мне нужно?
проблема же у Вас, а не у меня.
Я лишь сказал как оптимизировать Вашу схему.
 

Melandr

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