I promised to release the code for the Meek MD1 dimmer once all options are integrated and fully operational, but due to shift in priorities and limited time, I am unable to finish the coding on a short notice.
Therefore I’ll publish the “dirty” code for the time being.
It’s still work in progress and 1 of the major things that I’m currently working on, is the synchronization between the dim-levels and Domoticz. So for instance if the dim-level is on 50% on Domoticz, on the ATmega, this correspondence’s with a value around the 380. So when I manually change this to 260, Domoticz should jump to 25%. With the code below, this is fully operational. But, the manual fine-tuning part, still needs to be coded. For instance, if I manually set the dim-level at a value of 261, Domoticz will set it back to 260. So in the coding I have to build a rounding function so it’ll ignore smaller input changes send by Domoticz.
As you can see in the code, I’m trying to code the ATmega328P as flexible as possible, so you can change setting afterwards as you wish. Also flashing the ATmega328P will be somewhat cumbersome without dedicated equipment.
That’s one of the reasons why I want a full set of options and gimmicks as much as possible in the coding. So if you wish additions or have good ideas, please do inform us and if possible, amend the coding
One of the hardcoding will be something like “disco mode” so the lights will max out and back to minimum in a loop.
Once again, if you have additions or cool idea’s, please share it with us.
Herewith a video of the dimmer in action :
https://www.youtube.com/watch?v=Y9hVDwKcEDw
Coding is borrowed from the following sources :
https://playground.arduino.cc/Main/ACPhaseControl
https://github.com/letscontrolit/ESPEas ... tender.ino
Code: Select all
/*
* ***************************************************************************************************************************\
* Arduino project "ESP Easy" � Copyright www.esp8266.nu
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
* You received a copy of the GNU General Public License along with this program in file 'License.txt'.
*
* IDE download : https://www.arduino.cc/en/Main/Software
* ESP8266 Package : https://github.com/esp8266/Arduino
*
* Source Code : https://sourceforge.net/projects/espeasy/
* Support : http://www.esp8266.nu
* Discussion : http://www.esp8266.nu/forum/
*
* Additional information about licensing can be found at : http://www.gnu.org/licenses
**************************************************************************************************************************/
// This file is to be loaded onto an Arduino Pro Mini so it will act as a simple IO extender to the ESP module.
// Communication between ESP and Arduino is using the I2C bus, so only two wires needed.
// It best to run the Pro Mini on 3V3, although the 16MHz versions do not officially support this voltage level on this frequency.
// That way, you can skip levelconverters on I2C.
// Arduino Mini Pro uses A4 and A5 for I2C bus. ESP I2C can be configured but they are on GPIO-4 and GPIO-5 by default.
#include <Wire.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define DETECT 2 //zero cross detect
#define GATE 3 //TRIAC gate
#define PULSE 4 //trigger pulse width (counts)
int Meek;
int StepDown=1;
int StepUp=1;
int InputDelay=100;
int Domoticz;
int Domoticz1;
int Difference ;
int UpperLimit = 605;
int LowerLimit = 150;
#define I2C_MSG_IN_SIZE 4
#define I2C_MSG_OUT_SIZE 4
#define CMD_DIGITAL_WRITE 1
#define CMD_DIGITAL_READ 2
#define CMD_ANALOG_WRITE 3
#define CMD_ANALOG_READ 4
#define omhoog 8
#define omlaag 12
volatile uint8_t sendBuffer[I2C_MSG_OUT_SIZE];
void setup()
{
Wire.begin(0x7f);
Wire.onReceive(receiveEvent);
Wire.onRequest(requestEvent);
Serial.begin(9600);
pinMode(omhoog, INPUT);
pinMode(omlaag, INPUT);
// set up pins
pinMode(DETECT, INPUT); //zero cross detect
digitalWrite(DETECT, HIGH); //enable pull-up resistor
pinMode(GATE, OUTPUT); //TRIAC gate control
// set up Timer1
//(see ATMEGA 328 data sheet pg 134 for more details)
OCR1A = 100; //initialize the comparator
TIMSK1 = 0x03; //enable comparator A and overflow interrupts
TCCR1A = 0x00; //timer control registers set for
TCCR1B = 0x00; //normal operation, timer disabled
attachInterrupt(0,zeroCrossingInterrupt, RISING);
}
void zeroCrossingInterrupt(){ //zero cross detect
TCCR1B=0x04; //start timer with divide by 256 input
TCNT1 = 0; //reset timer - count from zero
}
ISR(TIMER1_COMPA_vect){ //comparator match
digitalWrite(GATE,HIGH); //set TRIAC gate to high
TCNT1 = 65536-PULSE; //trigger pulse width
}
ISR(TIMER1_OVF_vect){ //timer1 overflow
digitalWrite(GATE,LOW); //turn off TRIAC gate
TCCR1B = 0x00; //disable timer stopd unintended triggers
}
void loop() {
Difference = round(UpperLimit / LowerLimit);
if (Meek>=0 && Meek<=100) {
Domoticz = Meek;
}
if (Meek>=LowerLimit && Meek<=UpperLimit) {
Domoticz1 = map(OCR1A , LowerLimit, UpperLimit, 0 , 100);
}
if (Meek>=1 && Meek<=100) {
OCR1A =map(Meek,1,100, LowerLimit,UpperLimit);
}
if (Meek>=1 && Meek<=100) {
OCR1A =map(Meek,1,100, LowerLimit,UpperLimit);
}
if (Meek>=LowerLimit && Meek<=UpperLimit && Difference > (Domoticz-Domoticz1)) {
Domoticz = Domoticz1;
}
if (Meek>=LowerLimit && Meek<=UpperLimit) {
OCR1A = Meek; }
if (Meek>=1500 && Meek<=1599){
StepDown=(Meek-1500);}
if (Meek>=1500 && Meek<=1599){
StepDown=(Meek-1500);}
if (Meek>=1600 && Meek<=1699){
StepUp=(Meek-1600);}
if (Meek>=1700 && Meek<=1799){
InputDelay=(Meek-1700);}
if (Meek>=1800 && Meek<=1899 && OCR1A>150 && OCR1A<=603 ){
OCR1A=(OCR1A-(Meek-1800));}
if (Meek>=1900 && Meek<=1999 && OCR1A>=150 && OCR1A<603 ){
OCR1A=(OCR1A+(Meek-1900));}
if (Meek==2000 && OCR1A>=150 && OCR1A<=603){
OCR1A=(OCR1A+1);}
if (Meek==2000 && OCR1A==604){
OCR1A=(0);}
if (Meek==2001 && OCR1A==0){
OCR1A=(605);}
if (Meek==2001 && OCR1A<=603 && OCR1A>=150){
OCR1A=(OCR1A-1);}
if (OCR1A>UpperLimit) {
OCR1A=UpperLimit;}
if (OCR1A>0 && OCR1A<=LowerLimit) {
OCR1A=LowerLimit;}
Serial.print("Meek = ");
Serial.print(Meek);
Serial.print("OCR1A = ");
Serial.print(OCR1A);
Serial.print("domoticz =");
Serial.print(Domoticz);
Serial.print("Difference =");
Serial.print(Difference);
Serial.print("Domoticz11111 =");
Serial.print(Domoticz1);
delay(1000);
Serial.print('\n');
int hoog = digitalRead (omhoog);
if (hoog == 1 ){
OCR1A=(OCR1A+1) ;
}
int laag = digitalRead (omlaag);
if (laag == 1 ){
OCR1A=(OCR1A-1);
}
delay(InputDelay);
}
void receiveEvent(int count)
{
if (count == I2C_MSG_IN_SIZE)
{
byte cmd = Wire.read();
byte port = Wire.read();
int value = Wire.read();
value += Wire.read()*256;
switch(cmd)
{
case CMD_DIGITAL_WRITE:
pinMode(port,OUTPUT);
digitalWrite(port,value);
break;
case CMD_DIGITAL_READ:
pinMode(port,INPUT_PULLUP);
clearSendBuffer();
sendBuffer[0] = digitalRead(port);
break;
case CMD_ANALOG_WRITE:
//analogWrite(port,value);
Meek=(value);
break;
case CMD_ANALOG_READ:
clearSendBuffer();
int valueRead = Domoticz;
sendBuffer[0] = valueRead & 0xff;
sendBuffer[1] = valueRead >> 8;
break;
}
}
}
void clearSendBuffer()
{
for(byte x=0; x < sizeof(sendBuffer); x++)
sendBuffer[x]=0;
}
void requestEvent()
{
Wire.write((const uint8_t*)sendBuffer,sizeof(sendBuffer));
}