• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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
А зачем предлагать какое-то решение, если это решение не правильное и не подходит? Вопрос то был достаточно конкретный, почему так работает детектор.
 
Сверху Снизу