Attiny 85 Voltage controlled AC Dimmer

I tried this AC dimmer with attiny 85. But the problem is i am not able to get it work. The bulb just turns on and off randomly. I am not getting what to fed to the pin (3 physical pin on attiny 85) it is mentioned 0-5v in.. But i am not understanding how to achieve. I am trying to provide signal for the attiny 85 with nodemcu.
But the hardware part is completely working fine, as i tested it with nodemcu. But now i need the zero crossing and all other stuff happening in the attiny and the nodemcu must only provide signal to the attiny.

I need help with - what signal needs to be fed to attiny in order to get it working from nodemcu ?

I am not getting what to fed to the pin (3 physical pin on attiny 85) it is mentioned 0-5v in..

Feed pin3 a voltage 0-5 from a potentiometer to set the dimming.

// use analog input to set the dimmer
int instelwaarde = analogRead(INSTELPIN);
OCR1A = map(instelwaarde, 0, 1023, 65, 2);

cattledog:
Feed pin3 a voltage 0-5 from a potentiometer to set the dimming.

// use analog input to set the dimmer

int instelwaarde = analogRead(INSTELPIN);
OCR1A = map(instelwaarde, 0, 1023, 65, 2);

YES !! I tried that !! It completely turns on the bulb near the 3.3v and turns of the bulb at 0v. and if i try to very carefully fine tune the pot, there is flickering occurring. I am not understanding where i am going wrong. :sob:

OCR1A = map(instelwaarde, 0, 1023, 65, 2);

Forget about the pot for now, and just input some different values for OCR1A between 2 and 65. Or perhaps sweep through them with a for loop and some delay. Do you still see the flickering?

sorry i have no idea on that. I am a newbie actually. But am familiar with arduino codes but this is new to me. I have never used a attiny before. But i will try your suggestion and let you know what was the result.
But i feel this will not solve the issue, Because the nodemcu will pulse or give PWM signal at a voltage of 0.1 to 1.0 volt. But as per the post we need 5v max . So i highly doubt will i be able to get this working.

But i will try to change values of the pre scaler and see if something works out....

Because the nodemcu will pulse or give PWM signal at a voltage of 0.1 to 1.0 volt

I don't understand. analogWrite() on the node mcu should be a 1 kHz pwm output of 0 and 3.3v. Put the pwm output through a simple low pass RC filter to get an analog voltage. Feed that to the Attiny.

Arduino function for NodeMCU PWM
analogWrite(pin, dutycycle): Enables software PWM on the specified pin. duty cycle is in the range from 0 to PWMRANGE, i.e. 1023 by default.

analogWrite(pin, 0): Disables PWM on specified pin.

analogWriteRange(new_range): This function is used to change PWM range (duty cycle).

analogWriteFreq(new_frequency): PWM frequency is 1kHz by default. Call this function to change it with new frequency.PWM frequency is in the range 1 – 1000Khz.

cattledog:
I don't understand. analogWrite() on the node mcu should be a 1 kHz pwm output of 0 and 3.3v. Put the pwm output through a simple low pass RC filter to get an analog voltage. Feed that to the Attiny.

Yes but i measured it and i am getting only 1v

Also see this link below
https://esp8266.github.io/Arduino/versions/2.0.0/doc/reference.html

it also says about what you have mentioned about the writerange and frequency , and there the ADC voltage is 0-1v .

I am getting confused as the time goes by searching for the solution. And am thinking am i the only person trying this circuit and code ! Because no one as raised a query regarding this. And how did they get it right ??

And can you please help me understand this !! PLease ! I am a Newbie..
OCR1A = map(instelwaarde, 0, 1023, 65, 2);

and also the RC filter you mentioned above. So that i can build and try ...
Its a request.

Yes but i measured it and i am getting only 1v

How did you do this? Scope? You can’t measure pwm output accurately with a multimeter.

it also says about what you have mentioned about the writerange and frequency , and there the ADC voltage is 0-1v .

You are confusing output with analogWrite() and input with analogRead()

And can you please help me understand this !! PLease ! I am a Newbie…
OCR1A = map(instelwaarde, 0, 1023, 65, 2);

In this linked code the value of OCR1A sets the delay from zero cross interrupt to the triac trigger for dimming. The value of OCR1A is being adjusted with a mapped analogVoltage reading.

// Voltage controlled dimmer with ATtiny85
//
// This arduino sketch includes a zero 
// crossing detect function and an opto-isolated triac.
// 
// AC Phase control is accomplished using the internal 
// hardware timer1 in the ATtiny85
//
// Timing Sequence
// * timer is set up but disabled
// * zero crossing detected
// * timer starts counting from zero
// * comparator set to "delay to on" value
// * counter reaches comparator value
// * comparator ISR turns on triac gate
// * counter set to overflow - pulse width
// * counter reaches overflow
// * overflow ISR turns off triac gate
// * triac stops conducting at next zero cross

// The hardware timer runs at 8MHz. 
// A half period of a 50Hz AC signal takes 10 ms is 80000 counts.
// Prescaler set to 1024 gives 78 counts per half period


#include <avr/io.h>
#include <avr/interrupt.h>

#define DETECT 2      //zero cross detect, interrupt 0, is physical pin 7
#define GATE 3        //triac gate is physical pin 2
#define PULSE 2       //trigger pulse width (counts)
#define INSTELPIN 2   // =A2 (digital pin4) is physical pin 3 

void setup(){
  // 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 
  TCCR1 = 0;     // stop timer 
  OCR1A = 50;    //initialize the comparator
  TIMSK = _BV(OCIE1A) | _BV(TOIE1);  //interrupt on Compare Match A | enable timer overflow interrupt
  sei();  // enable interrupts
  // set up zero crossing interrupt
  attachInterrupt(0,zeroCrossingInterrupt, FALLING);    
}  

//Interrupt Service Routines
void zeroCrossingInterrupt(){   
  TCNT1 = 0;   //reset timer - count from zero
  TCCR1 = B00001011;        // prescaler on 1024, see table 12.5 of the tiny85 datasheet
}

ISR(TIMER1_COMPA_vect){    //comparator match
  digitalWrite(GATE,HIGH); //set triac gate to high
  TCNT1 = 255-PULSE;       //trigger pulse width, when TCNT1=255 timer1 overflows
} 
 
ISR(TIMER1_OVF_vect){       //timer1 overflow
  digitalWrite(GATE,LOW);   //turn off triac gate
  TCCR1 = 0;                //disable timer stop unintended triggers
}

void loop(){     // use analog input to set the dimmer
int instelwaarde = analogRead(INSTELPIN);
OCR1A = map(instelwaarde, 0, 1023, 65, 2); 
}

Change loop() to the code to sweep the through the range of OCR1A to test the dimming output and validate the output circuit.

void loop() {
  const int interval = 1000;
  static unsigned long lastMillis;
  static byte timerDelay = 2;
  static byte timerDelayChange = 1;

  if (millis() - lastMillis >= interval)
  {
    lastMillis = millis();
    if (timerDelay == 2)
      timerDelayChange = 1;
    else if (timerDelay == 65)
      timerDelayChange = -1;

    timerDelay += timerDelayChange;
    OCR1A = timerDelay;
    //Serial.println(OCR1A);
  }
}

and also the RC filter you mentioned above. So that i can build and try …
Its a request.

Please Google “low pass filter Arduino pwm”.
You will not be able to get 5v from the 3.3v Node mcu without additional hardware to amplify the output.
Alernativly, you might try an mcp4725 module DAC

You will not be able to get 5v from the 3.3v Node mcu

I think that you could achieve the full range of dimming (OCR1A range 2 - 65) with the lower voltage by changing the mapping of the voltage input to reflect the maximum value you will see on the attiny analogRead().

int instelwaarde = analogRead(INSTELPIN);
//OCR1A = map(instelwaarde, 0, 1023, 65, 2);
OCR1A = map(instelwaarde, 0, 675, 65, 2);

cattledog:
I think that you could achieve the full range of dimming (OCR1A range 2 - 65) with the lower voltage by changing the mapping of the voltage input to reflect the maximum value you will see on the attiny analogRead().

int instelwaarde = analogRead(INSTELPIN);

//OCR1A = map(instelwaarde, 0, 1023, 65, 2);
OCR1A = map(instelwaarde, 0, 675, 65, 2);

IN mapped analog value i changed the value 65 to 70. And the random flickering is kind of reduced. Is there any formula or thumb rule to set the mapping ?? And i have to try the Low rc filter. as i dont have the required value of resistor and capacitor. And i will change the loop to what you have said and see whether the hardware is in hand shake with the attiny.
But later part controlling with nodemcu is hard and tricky i guess. Do you feel that adding an RC filter to the output pin of the nodemcu and connecting the RC output to Attiny will give what i want ?BTW i am using a LED dimmer code for nodemcu and it dims the LED connected to it. Will the same PWM be able to control the attiny along with RC filter ???
And thank you so much for the quick replies. :slightly_smiling_face:

Do you feel that adding an RC filter to the output pin of the nodemcu and connecting the RC output to Attiny will give what i want ?

Yes.

BTW i am using a LED dimmer code for nodemcu and it dims the LED connected to it. Will the same PWM be able to control the attiny along with RC filter

I would think that the pwm values used for the led control could be converted to a voltage and scaled correctly for the AC control on the attiny, although there are probably non linearity issues in the responses of the different lights.

I'm not very familiar with the attiny, but you might be able to deal with the situation digitally and read the duty cycle of the pwm coming from the node mcu and adjust the phase chopping accordingly. But you are pretty far down the current path, and implementing the RC filter is a first step.

Is there any formula or thumb rule to set the mapping ??

// The hardware timer runs at 8MHz.
// A half period of a 50Hz AC signal takes 10 ms is 80000 counts.
// Prescaler set to 1024 gives 78 counts per half period

You can't go above 78 and turn off in the half cycle following the zero cross interrupt. There are possibly other timing reasons to stay below this maximum number. I guess the bulb is pretty dim at 65, so the original code didn't take it any higher.

Bro !!

But i tried With potentiometer of stable output of 0-5v. But even then that did not work. I am not getting what is it asking for as input !! Stable voltage or pwm or another kind of input.

And i need to try the prescaler or map the input and give it a try...

I am not getting what is it asking for as input !! Stable voltage

int instelwaarde = analogRead(INSTELPIN);

The code you posted is looking for a stable voltage which is read with analogRead().

Try changing this line

//#define INSTELPIN 2   // =A2 (digital pin4) is physical pin 3 
#define INSTELPIN A2

Sure i will try this and let you know the result. Thank you for the support.