диммер, и датчики со2
parent
0f060421f8
commit
a8b206c3a1
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,253 @@
|
||||||
|
//20.02.2019
|
||||||
|
//by Reptiloid software
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
#include "AC_Dimmer.h"
|
||||||
|
|
||||||
|
#define DIMM_MAX 5
|
||||||
|
#define AC_FREQ 50
|
||||||
|
#define MAX_HEAT_DIV 10
|
||||||
|
|
||||||
|
//======================================
|
||||||
|
|
||||||
|
#define ZERO_VAL 19850
|
||||||
|
#define K 77
|
||||||
|
|
||||||
|
#define SSR 0
|
||||||
|
#define DIMM 1
|
||||||
|
#define HEAT 2
|
||||||
|
|
||||||
|
//=======================================
|
||||||
|
|
||||||
|
struct dimmer
|
||||||
|
{
|
||||||
|
unsigned char flag;
|
||||||
|
unsigned char val;
|
||||||
|
unsigned char pin;
|
||||||
|
unsigned char SSR_state;
|
||||||
|
unsigned char heat_val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sort
|
||||||
|
{
|
||||||
|
unsigned char val;
|
||||||
|
unsigned char pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================
|
||||||
|
|
||||||
|
volatile unsigned char cnt;
|
||||||
|
volatile unsigned char dims;
|
||||||
|
volatile unsigned char lim;
|
||||||
|
volatile unsigned char not_z;
|
||||||
|
volatile unsigned char heat_cnt = 0;
|
||||||
|
|
||||||
|
dimmer dimmer[DIMM_MAX];
|
||||||
|
sort sort_vals[DIMM_MAX];
|
||||||
|
sort sort[DIMM_MAX*2];
|
||||||
|
|
||||||
|
//===============================================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Dimmer_init_begin()
|
||||||
|
{
|
||||||
|
TCCR1A=0;
|
||||||
|
TCCR1B=2;
|
||||||
|
TIMSK1=1;
|
||||||
|
|
||||||
|
EICRA=3;
|
||||||
|
EIMSK=1;
|
||||||
|
EIFR=1;
|
||||||
|
|
||||||
|
for(unsigned char i=0; i<DIMM_MAX; i++)
|
||||||
|
{
|
||||||
|
dimmer[i].pin = 0xff;
|
||||||
|
dimmer[i].val = 0;
|
||||||
|
dimmer[i].flag = SSR;
|
||||||
|
dimmer[i].SSR_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned char i=0; i<DIMM_MAX*2; i++)
|
||||||
|
{
|
||||||
|
sort[i].pin = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dimmer_pin_assign(unsigned char dim_num, unsigned char dim_pin)
|
||||||
|
{
|
||||||
|
dimmer[dim_num].pin = dim_pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dimmer_init_end()
|
||||||
|
{
|
||||||
|
unsigned char j=0;
|
||||||
|
|
||||||
|
for(unsigned char i=0; i<DIMM_MAX; i++)
|
||||||
|
{
|
||||||
|
if(dimmer[i].pin != 0xff)
|
||||||
|
{
|
||||||
|
sort_vals[j].pin = dimmer[i].pin;
|
||||||
|
j++;
|
||||||
|
pinMode(dimmer[i].pin, OUTPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dims = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void tim_form()
|
||||||
|
{
|
||||||
|
unsigned char j;
|
||||||
|
|
||||||
|
not_z = 0;
|
||||||
|
for(j = 0; (sort_vals[j].val == 0 && j < dims); j++) not_z++;
|
||||||
|
|
||||||
|
lim = dims - not_z;
|
||||||
|
sort[lim*2-1] = sort_vals[dims-1];
|
||||||
|
|
||||||
|
for(j=0; j<lim-1; j++)
|
||||||
|
{
|
||||||
|
sort[lim*2-2-j].val = sort_vals[dims-1-j].val - sort_vals[dims-j-2].val;
|
||||||
|
sort[lim*2-2-j].pin = sort_vals[dims-j-2].pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
sort[lim-1].val = 255 - sort_vals[dims-1].val + sort_vals[not_z].val;
|
||||||
|
sort[lim-1].pin = sort_vals[dims-1].pin;
|
||||||
|
|
||||||
|
for(j = 0; j<lim-1; j++)
|
||||||
|
{
|
||||||
|
sort[j] = sort[j+lim];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SSR_switch(unsigned char dim_num, unsigned char state)
|
||||||
|
{
|
||||||
|
Dimm_value(dim_num, 0);
|
||||||
|
|
||||||
|
dimmer[dim_num].flag = SSR;
|
||||||
|
dimmer[dim_num].SSR_state = state;
|
||||||
|
|
||||||
|
if(state == 0) digitalWrite(dimmer[dim_num].pin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Dimm_value(unsigned char dim_num, unsigned char power)
|
||||||
|
{
|
||||||
|
if(power > 240) power = 240;
|
||||||
|
|
||||||
|
dimmer[dim_num].flag = DIMM;
|
||||||
|
dimmer[dim_num].val = power;
|
||||||
|
unsigned char j;
|
||||||
|
|
||||||
|
for(unsigned char i = 0; i<dims; i++)
|
||||||
|
if(sort_vals[i].pin == dimmer[dim_num].pin)
|
||||||
|
{
|
||||||
|
if(power > sort_vals[i+1].val && i<dims-1)
|
||||||
|
{
|
||||||
|
for(j = 1; ((power > sort_vals[i+j].val) && (i+j<dims)); j++)
|
||||||
|
{
|
||||||
|
sort_vals[i+j-1] = sort_vals[i+j];
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_vals[i+j-1].val = power;
|
||||||
|
sort_vals[i+j-1].pin = dimmer[dim_num].pin;
|
||||||
|
}
|
||||||
|
else if(power < sort_vals[i-1].val && i>0)
|
||||||
|
{
|
||||||
|
for(j = 1; ((power < sort_vals[i-j].val) && (i-j>=0)); j++)
|
||||||
|
{
|
||||||
|
sort_vals[i-j+1] = sort_vals[i-j];
|
||||||
|
}
|
||||||
|
|
||||||
|
sort_vals[i-j+1].val = power;
|
||||||
|
sort_vals[i-j+1].pin = dimmer[dim_num].pin;
|
||||||
|
}
|
||||||
|
else sort_vals[i].val = power;
|
||||||
|
|
||||||
|
i = dims;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Heater(unsigned char dim_num, unsigned char heat_power)
|
||||||
|
{
|
||||||
|
Dimm_value(dim_num, 0);
|
||||||
|
|
||||||
|
dimmer[dim_num].flag = HEAT;
|
||||||
|
dimmer[dim_num].heat_val = heat_power;
|
||||||
|
|
||||||
|
if(heat_power == 0) digitalWrite(dimmer[dim_num].pin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
|
||||||
|
ISR(INT0_vect)
|
||||||
|
{
|
||||||
|
if(sort_vals[dims-1].val != 0 && dims > 0)
|
||||||
|
{
|
||||||
|
tim_form();
|
||||||
|
cnt=lim*2-1;
|
||||||
|
TCNT1 = 0xffff - (ZERO_VAL - K*sort[cnt].val);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned char i = 0; i<DIMM_MAX; i++)
|
||||||
|
{
|
||||||
|
if(dimmer[i].flag != DIMM)
|
||||||
|
{
|
||||||
|
if(dimmer[i].flag == HEAT)
|
||||||
|
{
|
||||||
|
if(dimmer[i].heat_val > heat_cnt) digitalWrite(dimmer[i].pin, 1);
|
||||||
|
else digitalWrite(dimmer[i].pin, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(dimmer[i].SSR_state > 0) digitalWrite(dimmer[i].pin, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(heat_cnt < MAX_HEAT_DIV-1) heat_cnt++;
|
||||||
|
else heat_cnt = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ISR(TIMER1_OVF_vect)
|
||||||
|
{
|
||||||
|
if(sort_vals[dims-1].val != 0 && dims > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
digitalWrite(sort[cnt].pin, 1);
|
||||||
|
delayMicroseconds(30);
|
||||||
|
digitalWrite(sort[cnt].pin, 0);
|
||||||
|
|
||||||
|
while(sort[cnt-1].val == 0)
|
||||||
|
{
|
||||||
|
cnt--;
|
||||||
|
digitalWrite(sort[cnt].pin, 1);
|
||||||
|
delayMicroseconds(30);
|
||||||
|
digitalWrite(sort[cnt].pin, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
cnt--;
|
||||||
|
TCNT1 = 0xffff - K*sort[cnt].val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
//20.02.2019
|
||||||
|
//by Reptiloid software
|
||||||
|
|
||||||
|
/*
|
||||||
|
Îãðàíè÷åíèÿ:
|
||||||
|
- Äëÿ êîíòðîëÿ ôàçû èñïîëüçîâàòü òîëüêî D2
|
||||||
|
- Íå èñïîëüçîâàòü ïèíû D9 è D10 äëÿ ØÈÌ (Analog.Write())
|
||||||
|
òîëüêî öèôðîâîé âûõîä/âõîä digitalWrite()
|
||||||
|
*/
|
||||||
|
|
||||||
|
//====================================================
|
||||||
|
|
||||||
|
#ifndef AC_Dimmer_h
|
||||||
|
#define AC_Dimmer_h
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
//=================================================
|
||||||
|
|
||||||
|
|
||||||
|
void Dimmer_init_begin();
|
||||||
|
void Dimmer_pin_assign(unsigned char dim_num, unsigned char dim_pin);
|
||||||
|
void Dimmer_init_end();
|
||||||
|
void Dimm_value(unsigned char dim_num, unsigned char power);
|
||||||
|
void SSR_switch(unsigned char dim_num, unsigned char state);
|
||||||
|
void Heater(unsigned char dim_num, unsigned char heat_power);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,110 @@
|
||||||
|
//20.02.2019
|
||||||
|
//by Reptiloid software
|
||||||
|
|
||||||
|
/*
|
||||||
|
Ограничения:
|
||||||
|
- Для контроля фазы использовать только D2 (прерывание INT0)
|
||||||
|
(порт M2 диммера подключать к порту D2 АРДУИНО)!!!
|
||||||
|
- Не использовать пины D9 и D10 для ШИМ Analog.Write()!!!
|
||||||
|
только цифровой выход/вход digitalWrite() и digitalRead()
|
||||||
|
|
||||||
|
Функционал:
|
||||||
|
- Данная библиотека позволяет регулировать нагрузку(и),
|
||||||
|
подключенную в промышленную сеть 220В с помощью АУРДУИНО
|
||||||
|
различными встроенными функциями описанными ниже
|
||||||
|
|
||||||
|
Как работать:
|
||||||
|
1) Чтобы начать работу нужно подключить библиотеку AC_Dimmer.h
|
||||||
|
2) Обозначить и раздать номера диммерам (нумерация от 0!!!), используемым в проекте:
|
||||||
|
#define <"имя димера"> <"порядковый номер">
|
||||||
|
|
||||||
|
Например:
|
||||||
|
#include <AC_Dimmer.h>
|
||||||
|
|
||||||
|
#define Dimmer_1 0
|
||||||
|
#define Dimmer_2 1
|
||||||
|
#define Dimmer_3 2
|
||||||
|
|
||||||
|
3) Инициализировать димер(ы) в void setup().
|
||||||
|
- Инициализацию выполнять строго между функций Dimmer_init_begin() и Dimmer_init_end();
|
||||||
|
- Инициализировать с помощью функции Dimmer_pin_assign():
|
||||||
|
Dimmer_pin_assign(<"имя димера">, <"порт(пин) ардуино димера">);
|
||||||
|
|
||||||
|
Например:
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Dimmer_init_begin();
|
||||||
|
|
||||||
|
Dimmer_pin_assign(Dimmer_1, 3);
|
||||||
|
Dimmer_pin_assign(Dimmer_2, A3);
|
||||||
|
Dimmer_pin_assign(Dimmer_3, A2);
|
||||||
|
|
||||||
|
Dimmer_init_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
3) В void loop() использовать нужную функцию:
|
||||||
|
|
||||||
|
- Dimm_value(<"имя димера">, <"значение мощности от 0 до 255">)
|
||||||
|
- Heater(<"имя димера">, <"значение мощности от 0 до 10">)
|
||||||
|
- SSR_switch(<"имя димера">, <значения 1 или 0 (HIGH/LOW)>)
|
||||||
|
|
||||||
|
Например: void loop()
|
||||||
|
{
|
||||||
|
Dimm_value(Dimmer_3, 64); // 25% мощность на диммере№3
|
||||||
|
Heater(Dimmer_2, 3); //30% мощности на диммере№2 (при условии что там ТЕН или другая низкоинерциооная нагрузка)
|
||||||
|
Dimm_value(Dimmer_1, 128); //50% мощности на диммере№1
|
||||||
|
|
||||||
|
delay(1000); //установленные высше параметры удерживаются 1сек
|
||||||
|
|
||||||
|
SSR_switch(Dimmer_3, LOW); // отключим все диммеры на 1сек
|
||||||
|
SSR_switch(Dimmer_2, LOW);
|
||||||
|
SSR_switch(Dimmer_1, LOW);
|
||||||
|
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
Код даного примера предполагает плавное поочередное зажигание и
|
||||||
|
и тушение трех ламп накаливания, подключенных к ардуино каждая через независимый диммер
|
||||||
|
|
||||||
|
Демонстрацию работы библиотеки на тестовом стенде и схему можно посмотреть здесь:
|
||||||
|
https://www.youtube.com/watch?v=9fhkJQIRmEA
|
||||||
|
|
||||||
|
Так же можно использовать для теста одиночного диммера
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <AC_Dimmer.h>
|
||||||
|
#include <math.h> //если Вы хотите использовать данную библитеку в своем в проекте,
|
||||||
|
//математическая библиотека <math.h> не обязательна к включению
|
||||||
|
|
||||||
|
#define Dimmer_1 0
|
||||||
|
#define Dimmer_2 1
|
||||||
|
#define Dimmer_3 2
|
||||||
|
|
||||||
|
unsigned char i = 0;
|
||||||
|
unsigned char range = 70; // Диапазон регулировки
|
||||||
|
// (255 - максимальное значение)
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Dimmer_init_begin();
|
||||||
|
|
||||||
|
Dimmer_pin_assign(Dimmer_1, 3);
|
||||||
|
Dimmer_pin_assign(Dimmer_2, A3);
|
||||||
|
Dimmer_pin_assign(Dimmer_3, A2);
|
||||||
|
|
||||||
|
Dimmer_init_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
|
||||||
|
Dimm_value(Dimmer_1, range*fabs(sin(i*2*3.14/255)));
|
||||||
|
Dimm_value(Dimmer_2, range*fabs(sin((i+(255/3))*2*3.14/255)));
|
||||||
|
Dimm_value(Dimmer_3, range*fabs(sin((i+(255*2/3))*2*3.14/255)));
|
||||||
|
|
||||||
|
delay(25);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
//30.03.2019
|
||||||
|
//by Reptiloid software
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Данный скетч реализует ручную независимую регулировку мощности для каждого диммера
|
||||||
|
с помощью соответствующего потенциометра на аналоговых пинах
|
||||||
|
(рекомендуемы номинал 1-100К)
|
||||||
|
|
||||||
|
Так же можно использовать для теста одиночного диммера
|
||||||
|
|
||||||
|
Подробное описание работы и синтаксиса библиотеки можете
|
||||||
|
посмотреть в примере AC_DIMMER_FADE
|
||||||
|
|
||||||
|
Демонстрацию работы библиотеки на тестовом стенде и схему можно посмотреть здесь:
|
||||||
|
https://www.youtube.com/watch?v=9fhkJQIRmEA
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <AC_Dimmer.h>
|
||||||
|
|
||||||
|
#define Dimmer_1 0
|
||||||
|
#define Dimmer_2 1
|
||||||
|
#define Dimmer_3 2
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Dimmer_init_begin();
|
||||||
|
|
||||||
|
Dimmer_pin_assign(Dimmer_1, 3);
|
||||||
|
Dimmer_pin_assign(Dimmer_2, A3);
|
||||||
|
Dimmer_pin_assign(Dimmer_3, A2);
|
||||||
|
|
||||||
|
Dimmer_init_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
int adc_read;
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
adc_read = analogRead(A4)/4;
|
||||||
|
Dimm_value(Dimmer_1, adc_read); // потенциометры на пинах А4, А5, А6
|
||||||
|
adc_read = analogRead(A5)/4;
|
||||||
|
Dimm_value(Dimmer_2, adc_read); // для ручной регулировки мощности
|
||||||
|
adc_read = analogRead(A6)/4;
|
||||||
|
Dimm_value(Dimmer_3, adc_read); // на каждый диммер
|
||||||
|
|
||||||
|
delay(50);
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
Данный скетч позволяет запустить димер в режиме FADE для платы ESP8266
|
||||||
|
- 2сек диммер плавно увеличивает мощность
|
||||||
|
- 2сек диммер плавно уменьшает мощность
|
||||||
|
|
||||||
|
Для того чтобы успешно прошить даный скетч Вам нужно:
|
||||||
|
- скачать дистрибутив для работу с ESP8266 в Arduino IDE
|
||||||
|
- скачать библиоеки Ticker.h
|
||||||
|
- подключить димер на соответствующие пины или назначить свои
|
||||||
|
|
||||||
|
При работе с ESP8266 подключать библиотеку AC_Dimmer и использовать ее функции не нужно
|
||||||
|
Достаточно прошить лишь данный пример
|
||||||
|
Для управления можностью используется переменная val (смотрите ниже)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <Ticker.h>
|
||||||
|
|
||||||
|
Ticker blinker;
|
||||||
|
|
||||||
|
const byte interruptPin = D7; // пин диммера М2
|
||||||
|
const byte dimPin = D5; // пин диммера М1
|
||||||
|
int val = 0; // переменная, которая определяет мощность от 0 до 10000
|
||||||
|
|
||||||
|
int power = 0;
|
||||||
|
int rise = 0;
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR handleInterrupt();
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR onTimerISR() // обработчик прерывания таймера
|
||||||
|
{
|
||||||
|
digitalWrite(dimPin, HIGH);
|
||||||
|
delayMicroseconds(40);
|
||||||
|
digitalWrite(dimPin, LOW);
|
||||||
|
|
||||||
|
timer1_write(50000);//10мс
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleInterrupt() // обработчик прерывания по фронту (от пина детекции фазы димера)
|
||||||
|
{
|
||||||
|
power = 49000 - 4.785*val;
|
||||||
|
timer1_write(power);
|
||||||
|
|
||||||
|
if(val < 10000 && rise == 1) val = val + 100; // плавное наростание
|
||||||
|
else rise = 0;
|
||||||
|
|
||||||
|
if(val > 0 && rise == 0) val = val - 100; // плавное угасание
|
||||||
|
else rise = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
|
||||||
|
pinMode(interruptPin, INPUT_PULLUP);
|
||||||
|
pinMode(dimPin, OUTPUT);
|
||||||
|
|
||||||
|
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, RISING);
|
||||||
|
|
||||||
|
timer1_attachInterrupt(onTimerISR);
|
||||||
|
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
|
||||||
|
|
||||||
|
// здесь можно писать свой код (setup())
|
||||||
|
//
|
||||||
|
// здесь можно писать свой код (setup())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
// здесь можно писать свой код
|
||||||
|
//
|
||||||
|
// здесь можно писать свой код
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Даный скетч позволяет управлять сетевым диммером DMR-02 через WiFi
|
||||||
|
с помощью ESP8266 и смартфона с любой точки планеты, где есть доступ в интернет
|
||||||
|
|
||||||
|
Скетч позволит управлять нагрузкой (лампой) с помощью ползунка на Вашем смартфоне по WiFi
|
||||||
|
|
||||||
|
Код работает в неблокирующем режиме (можно добавлять свой код)
|
||||||
|
|
||||||
|
Управление со смартфона будет происходить с помощью программы Blynk (Play market/APP store)
|
||||||
|
Перед началом работы рекомендуется разобраться с функионалом данного софта
|
||||||
|
|
||||||
|
пример работы (ВИДЕО)
|
||||||
|
https://www.youtube.com/watch?v=Z_Vvgx4QuSY
|
||||||
|
|
||||||
|
Для того чтобы успешно прошить даный скетч Вам нужно:
|
||||||
|
- скачать дистрибутив для работу с ESP8266 в Arduino IDE
|
||||||
|
- скачать библиоеки Blynk и Ticker.h
|
||||||
|
- скачать приложение Blynk на смартфон
|
||||||
|
- создать проект в приложении Blynk для управления димером
|
||||||
|
- получить на почту Ваш ЛИЧНЫЙ токен с приложения Blynk и вписать его ниже
|
||||||
|
- вписать имя и пароль WiFi для подключения ESP8266 (смотрите ниже)
|
||||||
|
- подключить димер на соответствующие пины или назначить свои
|
||||||
|
|
||||||
|
При работе с ESP8266 подключать библиотеку AC_Dimmer и использовать ее функции не нужно
|
||||||
|
Достаточно прошить лишь данный пример
|
||||||
|
Для управления можностью используется переменная val (смотрите ниже)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <Ticker.h>
|
||||||
|
#include <BlynkSimpleEsp8266.h>
|
||||||
|
|
||||||
|
Ticker blinker;
|
||||||
|
|
||||||
|
const byte interruptPin = D7; // пин диммера М2
|
||||||
|
const byte dimPin = D5; // пин диммера М1
|
||||||
|
|
||||||
|
int power = 0;
|
||||||
|
int val = 0; // переменная задающая мощность от 0 до 10000
|
||||||
|
|
||||||
|
char auth[] = "7wE5GzzU2zs83pOZKSbMxfEu_G53y4V6"; // Ваш ЛИЧНЫЙ токен от приложения Blynk
|
||||||
|
char ssid[] = "AndroidAP"; // имя WiFi
|
||||||
|
char pass[] = "23412123"; // пароль WiFi
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR handleInterrupt();
|
||||||
|
|
||||||
|
void ICACHE_RAM_ATTR onTimerISR() // обработчик прерывания таймера
|
||||||
|
{
|
||||||
|
digitalWrite(dimPin, HIGH);
|
||||||
|
delayMicroseconds(40);
|
||||||
|
digitalWrite(dimPin, LOW);
|
||||||
|
|
||||||
|
timer1_write(50000);//10мс
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleInterrupt() // обработчик прерывания по фронту (от пина детекции фазы димера)
|
||||||
|
{
|
||||||
|
power = 49000 - 4.75*val;
|
||||||
|
timer1_write(power);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
Blynk.begin(auth, ssid, pass);
|
||||||
|
|
||||||
|
pinMode(interruptPin, INPUT_PULLUP);
|
||||||
|
pinMode(dimPin, OUTPUT);
|
||||||
|
|
||||||
|
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, RISING);
|
||||||
|
|
||||||
|
timer1_attachInterrupt(onTimerISR);
|
||||||
|
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
|
||||||
|
|
||||||
|
// здесь можно писать свой код (setup())
|
||||||
|
//
|
||||||
|
// здесь можно писать свой код (setup())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
Blynk.run(); // функция поллинга данных по WiFi
|
||||||
|
|
||||||
|
// здесь можно писать свой код
|
||||||
|
//
|
||||||
|
// здесь можно писать свой код
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BLYNK_WRITE(V0) // функция считывания данных по WiFi
|
||||||
|
{
|
||||||
|
val = param.asInt();
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include <AC_Dimmer.h> KEYWORD1
|
||||||
|
Dimmer_pin_assign KEYWORD1
|
||||||
|
Dimmer_init_end KEYWORD1
|
||||||
|
Dimmer_init_begin KEYWORD1
|
||||||
|
Heater KEYWORD2
|
||||||
|
Dimm_value KEYWORD2
|
||||||
|
SSR_switch KEYWORD2
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,28 @@
|
||||||
|
# AC_dimmer-dmr-0.2.1
|
||||||
|
|
||||||
|
Последняя версия библиотеки на сетевой диммер dmr-0.2.x
|
||||||
|
|
||||||
|
Пример работы (Demo-video): https://www.youtube.com/watch?v=9fhkJQIRmEA
|
||||||
|
|
||||||
|
Пример работы c ESP8266 (управление диммером через Wifi с помощью смартфона) (Demo-video): https://www.youtube.com/watch?v=Z_Vvgx4QuSY
|
||||||
|
|
||||||
|
- Работа в трех режимах:
|
||||||
|
- режим трердотелого реле (вкл/выкл с учетом фазы)
|
||||||
|
- фазовая регулировка (классический режим)
|
||||||
|
- полуволновый режим (для повышеных мощностей для мощных нагревателей)
|
||||||
|
|
||||||
|
- позволяет параллельную работу нескольких димеров на одной плате Ардуино
|
||||||
|
|
||||||
|
- Добавлен пример работы с ESP8266 по Wifi
|
||||||
|
|
||||||
|
Библиотека Ардуино: [AC_Dimmer.zip](https://github.com/serhiy23412/AC_dimmer-dmr-0.2.1/blob/master/AC_Dimmer.zip)
|
||||||
|
|
||||||
|
Простой пример на Raspberry Pi (by Andy): [Raspberry Pi example.txt](https://github.com/serhiy23412/AC_dimmer-dmr-0.2.1/blob/master/Raspberry_Pi_example.txt)
|
||||||
|
|
||||||
|
Более детальная информация: [AC_Dimmer_Docum.docx](https://github.com/serhiy23412/AC_dimmer-dmr-0.2.1/blob/master/AC_Dimmer_Docum.docx)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
import time
|
||||||
|
import math
|
||||||
|
|
||||||
|
PHASE_DFREQ = 100
|
||||||
|
DRIVER_MIN = 0.3
|
||||||
|
DRIVER_MAX = 0.95
|
||||||
|
|
||||||
|
power = DRIVER_MIN
|
||||||
|
|
||||||
|
def phase_callback(channel):
|
||||||
|
global power
|
||||||
|
if power < DRIVER_MIN:
|
||||||
|
power = DRIVER_MIN
|
||||||
|
if power > DRIVER_MAX:
|
||||||
|
power = DRIVER_MAX
|
||||||
|
|
||||||
|
time.sleep(math.acos(2.0 * power - 1.0) / (math.pi * PHASE_DFREQ))
|
||||||
|
GPIO.output(23, GPIO.HIGH)
|
||||||
|
time.sleep(0.00003)
|
||||||
|
GPIO.output(23, GPIO.LOW)
|
||||||
|
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
|
||||||
|
GPIO.setup(23, GPIO.OUT) # dimmer control
|
||||||
|
GPIO.setup(24, GPIO.IN) # phase control
|
||||||
|
|
||||||
|
GPIO.add_event_detect(24, GPIO.BOTH, callback=phase_callback, bouncetime=9)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(power)
|
||||||
|
time.sleep(15)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
power += 0.05
|
||||||
|
print(power)
|
||||||
|
time.sleep(10)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
pass
|
||||||
|
|
||||||
|
finally:
|
||||||
|
GPIO.remove_event_detect(24)
|
||||||
|
GPIO.cleanup()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -42,9 +42,11 @@
|
||||||
MHZ19 myMHZ19;
|
MHZ19 myMHZ19;
|
||||||
SoftwareSerial mySerial(RX_PIN, TX_PIN);
|
SoftwareSerial mySerial(RX_PIN, TX_PIN);
|
||||||
|
|
||||||
unsigned int VersionSW = 17;
|
unsigned int VersionSW = 20;
|
||||||
|
|
||||||
//17 - локальный брокер
|
//17 - локальный брокер
|
||||||
|
//19 - какие то траблы в офисе
|
||||||
|
//20 - Ручное удаление
|
||||||
|
|
||||||
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||||||
|
|
||||||
|
@ -63,7 +65,7 @@ WiFiUDP ntpUDP;
|
||||||
NTPClient timeClient(ntpUDP, "192.168.89.210", 0, 20000); //Собственно сервер времени смещение и частоат запроса, но он вручную
|
NTPClient timeClient(ntpUDP, "192.168.89.210", 0, 20000); //Собственно сервер времени смещение и частоат запроса, но он вручную
|
||||||
const PROGMEM char *willmess = "{\"conn\":\"err\"}";
|
const PROGMEM char *willmess = "{\"conn\":\"err\"}";
|
||||||
const char *mqttHostName = "metrics"; //Хостнейм брокера metrics.local cctv.automation.art //192.168.89.210
|
const char *mqttHostName = "metrics"; //Хостнейм брокера metrics.local cctv.automation.art //192.168.89.210
|
||||||
unsigned int mqttPort = 1883; //Порт брокера 1883 8889
|
unsigned int mqttPort = 1883; //Порт брокера 1883 8889
|
||||||
|
|
||||||
String getMacAddress();
|
String getMacAddress();
|
||||||
String macc = getMacAddress();
|
String macc = getMacAddress();
|
||||||
|
@ -72,9 +74,9 @@ String willTopicTemp = "aastudio/sens/" + macc + "/status";
|
||||||
const PROGMEM char *mqttLogin = "AA_Lab", *mqttPass = "automation.art$";
|
const PROGMEM char *mqttLogin = "AA_Lab", *mqttPass = "automation.art$";
|
||||||
|
|
||||||
const char *mqttIPHost; //тут хранится IP хоста по хостнейму
|
const char *mqttIPHost; //тут хранится IP хоста по хостнейму
|
||||||
unsigned long timingUpdate, timingReqSensor, timingSendMqtt; //Таймеры для millis()
|
unsigned long timingUpdate=0, timingReqSensor=0, timingSendMqtt=0; //Таймеры для millis()
|
||||||
int PROGMEM nextM5Update = 450000; //каждые 7.5 минут запрос обновления с сервера //опрос датчиков раз в 10 секунд
|
int PROGMEM nextM5Update = 450000, nextMqttSend = 60000; //каждые 7.5 минут запрос обновления с сервера
|
||||||
int PROGMEM nextMqttSend = 10000; //Отправка
|
//Отправка
|
||||||
bool typeSensor = false, GlobalOled = false;
|
bool typeSensor = false, GlobalOled = false;
|
||||||
bool mqttSendFlag = false;
|
bool mqttSendFlag = false;
|
||||||
bool safetyStateNow = false, safetyStateOld = false;
|
bool safetyStateNow = false, safetyStateOld = false;
|
||||||
|
@ -115,7 +117,7 @@ void setup()
|
||||||
{
|
{
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
Serial.setDebugOutput(true);
|
Serial.setDebugOutput(true);
|
||||||
|
M5.begin(true, false, true);
|
||||||
Wire.begin(32, 26);
|
Wire.begin(32, 26);
|
||||||
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
|
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C))
|
||||||
{ // Address 0x3D for 128x64
|
{ // Address 0x3D for 128x64
|
||||||
|
@ -165,7 +167,7 @@ void setup()
|
||||||
myMHZ19.autoCalibration(false);
|
myMHZ19.autoCalibration(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
M5.begin(true, false, true);
|
|
||||||
|
|
||||||
delay(50);
|
delay(50);
|
||||||
pinMode(TRIGGER_PIN, INPUT);
|
pinMode(TRIGGER_PIN, INPUT);
|
||||||
|
@ -246,6 +248,8 @@ int setMqttServer(const char *mqttHostNameF, unsigned int mqttPortF)
|
||||||
IPAddress ipaddr;
|
IPAddress ipaddr;
|
||||||
OTApreferences.begin("ota-config");
|
OTApreferences.begin("ota-config");
|
||||||
|
|
||||||
|
OTApreferences.putString("mqttip", "0");
|
||||||
|
delay(1000);
|
||||||
String keyIpMqtt = OTApreferences.getString("mqttip", "0");
|
String keyIpMqtt = OTApreferences.getString("mqttip", "0");
|
||||||
Serial.print("keyIpMqtt: ");
|
Serial.print("keyIpMqtt: ");
|
||||||
Serial.println(keyIpMqtt);
|
Serial.println(keyIpMqtt);
|
||||||
|
@ -340,7 +344,7 @@ void checkButton()
|
||||||
|
|
||||||
OTApreferences.begin("ota-config");
|
OTApreferences.begin("ota-config");
|
||||||
OTApreferences.putString("mqttip", "0");
|
OTApreferences.putString("mqttip", "0");
|
||||||
OTApreferences.end();
|
OTApreferences.end();
|
||||||
|
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
@ -358,7 +362,8 @@ void OTAUpdate()
|
||||||
{
|
{
|
||||||
|
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
String serverPath = "http://meteosence.s-host.net/airqa/airquality.php?meteopas=84sdi5239dfkg4&mac=" + macc + "&meteodata=gethash";
|
String serverPath = "http://meteosence.s-host.net/airqa/airquality.php?meteopas=
|
||||||
|
&mac=" + macc + "&meteodata=gethash";
|
||||||
|
|
||||||
http.begin(serverPath.c_str());
|
http.begin(serverPath.c_str());
|
||||||
int httpResponseCode = http.GET();
|
int httpResponseCode = http.GET();
|
||||||
|
@ -565,7 +570,7 @@ int SendMqttReq(bool sendVal = true, bool sendStatus = true, byte statusConn = 1
|
||||||
doc["bsid"] = WiFi.BSSIDstr();
|
doc["bsid"] = WiFi.BSSIDstr();
|
||||||
doc["ts"] = timeNow;
|
doc["ts"] = timeNow;
|
||||||
doc["exp"] = timeNow + 600;
|
doc["exp"] = timeNow + 600;
|
||||||
doc["sv"] = VersionSW;
|
doc["sv"] = VersionSW;
|
||||||
|
|
||||||
JsonData = "";
|
JsonData = "";
|
||||||
serializeJson(doc, JsonData);
|
serializeJson(doc, JsonData);
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue