1

I am working on an AC Dimmer project using ESP32 and Attiny85.

Note : I know ATtiny85 is overkill for this project, And it can be done without Attiny85, I have already done this using ESP32 alone. But I have some PCB laying around designed in such a manner. So thought of doing this.

Here ESP32 communicates to Attiny over i2c. ESP - Master Attiny - Slave enter image description here Here Zero Cross Detector(ZCD) circuit is connected to PB1. and T1 to Triac Circuit

Depending on the commands over i2c from ESP to each Attiny, It controls the brightness.

The Problem

I am able to set the brightness using i2c (like LOW, MED, HIGH, OFF). But only once. For example, if I set it to HIGH state initially it will get stuck in that state, Even if any other command is given, Similar for all others. Basically, it will only work once.

I think the interrupt is causing the problem, once interrupt is attached the i2c isn't responding

Here are codes
Slave https://pastebin.com/sqsMYLa0

#include "PinChangeInterrupt.h"
#include "TinyWireS.h"
 
#define I2C_SLAVE_ADDR 2
int AC_LOAD = 3;
int ZCD_Pin = 1;
int dimming = 128; 
int Speed[3] = {90, 50, 20};
int speedValue;
bool fan;
void setup() {
 pinMode(AC_LOAD, OUTPUT); 
 TinyWireS.begin(I2C_SLAVE_ADDR);
 TinyWireS.onReceive(receiveEvent);
 pinMode(ZCD_Pin, INPUT_PULLUP);
}
 
 
void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
 int dimtime = (75 * dimming); // For 60Hz =>65
 delayMicroseconds(dimtime); // Wait till firing the TRIAC
 digitalWrite(AC_LOAD, HIGH); // Fire the TRIAC
 delayMicroseconds(100); // triac On propogation delay // (for 60Hz use 8.33) Some Triacs need a longer period
 digitalWrite(AC_LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}
 
void receiveEvent(uint8_t howMany)
{
 byte byteRcvd = 0;
 if (TinyWireS.available()) {
 byteRcvd = TinyWireS.receive(); // get the byte from master
 
 if (byteRcvd == '0') {
 fan = false;
 detachPinChangeInterrupt(digitalPinToPCINT(ZCD_Pin));
 digitalWrite(AC_LOAD, LOW);
 }
 if (byteRcvd == '1') {
 fan = true;
 speedValue = Speed[0];
 attachPCINT(digitalPinToPCINT(ZCD_Pin), zero_crosss_int, RISING);
 }
 if (byteRcvd == '2') {
 fan = true;
 speedValue = Speed[1]; 
 attachPCINT(digitalPinToPCINT(ZCD_Pin), zero_crosss_int, RISING);
 }
 if (byteRcvd == '3') {
 fan = true;
 speedValue = Speed[2];
 attachPCINT(digitalPinToPCINT(ZCD_Pin), zero_crosss_int, RISING);
 }
 dimming = speedValue;
 }
}
 
void loop() {
 delay(100);
}

Master https://pastebin.com/E5U74LEx

#include <Wire.h>
//#define I2C_SLAVE_1_ADDR 1
#define I2C_SLAVE_2_ADDR 2
 
void setup() {
 Wire.begin(); // join i2c bus (address optional for master)
 Serial.begin(9600);
 Serial.print("Ready");
}
 
char x = 0;
 
void loop() {
 if (Serial.available() > 0) {
 
 x = Serial.read();
 
 if (x == '0') {
 Wire.beginTransmission(2); 
 Wire.write('0'); 
 Wire.endTransmission(); 
 Serial.print("Send 0");
 }
 if (x == '1') {
 Wire.beginTransmission(2); 
 Wire.write('1'); 
 Wire.endTransmission(); 
 Serial.print("Send 1");
 }
 if (x == '2') {
 Wire.beginTransmission(2); 
 Wire.write('2'); 
 Wire.endTransmission(); 
 Serial.print("Send 2");
 }
 if (x == '3') {
 Wire.beginTransmission(2); 
 Wire.write('3'); 
 Wire.endTransmission(); 
 Serial.print("Send 3");
 }
 }
}

For testing, I have used Serial monitor for sending commands. Later It will be done using MQTT

asked Jul 1, 2021 at 18:20
3
  • 2
    That's a pretty long delay in the ISR; have you tried setting a state and handling the rest in loop? Commented Jul 1, 2021 at 22:44
  • @DaveNewton Yes, but the output is flickering. here is the code pastebin.com/FnTkE8hZ Commented Jul 2, 2021 at 4:01
  • arduino.stackexchange.com/questions/63631/… Commented Jul 2, 2021 at 5:01

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.