Looking for help with AC fan speed controller/dimmer

I want to make a project By using NODE MCU in Blynk Platform. I want to use 3 touch sensor switch (TTP223) to on and off 3 Lights by them and 4 more touch-sensor switches (TTP223) (or 1 TTP224 which has 4 touch Sensor in a single module) to control AC Fan speed (with zero Cross Detection). To do this I use 3 virtual Pin (V1, V2, V3) and another Virtual Pin (V4) for the Slider button to control fan speed in the Blynk app. It can be control both With the internet (Blynk app) or Without the internet (manually by touch sensor switch) mode. It also has a switching status feedback system in the Blynk app. My problem Is I can not match the slider button (Blynk app’s) with the Physical 4 touch sensor switch (to control the fan speed by 4 steps i.e 0 (off), then 1(low), 2(Medium) and 3 (Full speed)) and the zero-cross detector program in my code. It is better to add a Gauge with the slider button to show the fan speed status in the blynk app. Will you please help me in this regard. my mail address is [email address removed by Moderator, please use PM facility]. Thanks

Wrote the code for above issue (Ac fan dimmer with two touch sensor switch for controlling fan speed physically and with wifi i.e. Blynk App slidder button), but code now work , please help regarding the issue, I think main problem is It is difficult to relate the physical touch sensor switch with blynk app slider , as I am new in coding please some one help me regarding the issue

[Unformatted code removed by moderator]

I have written the code for above issue (Ac fan dimmer with two physical touch sensor switch for controlling fan speed physically and with wifi i.e. Blynk App slider button), but code now work , please help regarding the issue, I think main problem is It is difficult to relate the physical touch sensor switch with blynk app slider , as I am new in coding please some one help me regarding the issue

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

char auth[] = “Your auth token”; // You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon) in the Blynk app or check your email for auth token.

char ssid[] = “Your wifi SSID”; // Your WiFi credentials.
char pass[] = “Your wifi password”; // Set password to “” for open networks.

volatile byte LOAD = 13; // Output to Optocoupler Triac pin controlling the AC load (D7 pin in NodeMCU means GPIO13 pin)//load 4 is AC_pin–required signal as o/p from NodeMCU to MOC3021
// you can choose your pin of choice from any GPIO pin in NodeMCU
volatile int dimming = 128; // Dimming level (0-128) 0 = ON, 100 = OFF
volatile byte ZVC=12 ; // INPUT PIN for the Zero Voltage Cross Signal d6 means GPIO12

int buton1 = 5; // first button at Gpio 5 means D1
int buton2 = 4; // second button at Gpio 4 means D2

int dim2 = 0; // led control
volatile int i=0; // Variable to use as a counter of dimming steps. It is volatile since it is passed between interrupts
int pas = 8; // step for count;
volatile boolean zero_cross=0; // Flag to indicate we have crossed zero

int Slider_Value = 0;

BLYNK_WRITE(V1) // function to assign value to variable Slider_Value whenever slider changes position
{
Slider_Value = param.asInt(); // assigning incoming value from pin V1 to a variable
}

void zero_crosss_int() //function to be fired at the zero crossing to dim the light
{
// Firing angle calculation : 1 full 50Hz wave =1/50=20ms
// Every zerocrossing thus: (50Hz)-> 10ms (1/2 Cycle)
// For 60Hz => 8.33ms (10.000/120)// 10ms=10000us
// (10000us - 10us) / 128 = 75 (Approx) For 60Hz =>65

volatile int dimtime = (75*dimming); // For 60Hz = 65
delayMicroseconds(dimtime); // (off cycle)Wait till firing the TRIAC
digitalWrite(LOAD, HIGH); // Fire the TRIAC
delayMicroseconds(10); // triac On propogation delay
// (for 60Hz use 8.33) Some Triacs need a longer period
digitalWrite(LOAD, LOW); // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC

zero_cross = true;               // set flag for dim_check function that a zero cross has occured
i=0; // stepcounter to 0… as we start a new cycle
digitalWrite(LOAD, LOW);

}
ICACHE_RAM_ATTR void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, pass);

pinMode(buton1, INPUT); // set buton1 pin as input
pinMode(buton2, INPUT); // set buton1 pin as input

pinMode(LOAD, OUTPUT);// Set AC Load pin as output
attachInterrupt(digitalPinToInterrupt(ZVC), zero_crosss_int, RISING); // Choose the zero cross interrupt pin from any GPIO pin of NodeMCU

}

// Turn on the TRIAC at the appropriate time
// We arrive here every 75 (65) uS
// First check if a flag has been set
// Then check if the counter ‘i’ has reached the dimming level
// if so… switch on the TRIAC and reset the counter

void dimming_check() {
if(zero_cross == true) {
if(i>=dimming) {
digitalWrite(LOAD, HIGH); // turn on light
i=0; // reset time step counter
zero_cross=false; // reset zero cross detection flag
}
else {
i++; // increment time step counter
}
}
}

void loop() {
digitalWrite(buton1, HIGH);
digitalWrite(buton2, HIGH);

if (digitalRead(buton1) == LOW)
{
if (dimming<127)
{
dimming = dimming + pas;
if (dimming>127)
{
dimming=128;
}
}
}
if (digitalRead(buton2) == LOW)
{
if (dimming>5)
{
dimming = dimming - pas;
if (dimming<0)
{
dimming=0;
}
}
}
while (digitalRead(buton1) == LOW) { }
delay(10); // waiting little bit…
while (digitalRead(buton2) == LOW) { }
delay(10); // waiting little bit…

dim2 = 255-2*dimming;
if (dim2<0)
{
dim2 = 0;
}

{
Blynk.run();
dimming=map(Slider_Value, 0, 100, 128, 8); // at lower values than 8 , flickering may start at 100% so keeping it 8 for avoiding flickering
delay(10);
//Serial.println(Slider_Value);

}
}

You should start by reading this:

and restructuring your code accordingly.

Pete.

Dear Sir, I was trying but failed. Please help me to read the below issue:

Below code is for AC FAN or Bulb Dimmer with zero cross detection. It runs only Blynk App Slider Button. I want to modify the code for manual control by adding two push buttons (one is for ON the fan , then increasing the fan speed by some steps and another is for decreasing the fan speed by some steps and then Off the fan) along with Blynk app Slider Button for controlling through Wifi. It is better to use Blynk App’s "Step H " button instead of slider button (if it is not possible then use default code’s slider button, no problem ). I am unable to write the function for two push button switches and relate their operation with int dimming (see below code). Can anyone help/guide me to modify the below code as above requirements. Code is written for NodeMcu board and Blynk app runs in android device.

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#define triacPulse 4 //D2
#define ZVC 12 //D6

int Slider_Value;
int dimming;
int x = 0;

char auth[] = "AUTH TOKEN";        // You should get Auth Token in the Blynk App.


char ssid[] = "SSID";         // Your WiFi credentials.
char pass[] = "PASS";    // Set password to "" for open networks.


BLYNK_WRITE(V1)   // function to assign value to variable Slider_Value whenever slider changes position
{
  Slider_Value = param.asInt(); // assigning incoming value from pin V1 to a variable
}


void setup()
{

  pinMode(ZVC, INPUT_PULLUP);
  //digitalWrite(2, INPUT_PULLUP); // pull up
  pinMode(triacPulse, OUTPUT);
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  attachInterrupt(digitalPinToInterrupt(ZVC), acon, FALLING); // attach Interrupt at PIN2
}



void loop()
{
  Blynk.run();
  // When the switch is closed
  dimming = map(Slider_Value, 0, 100, 7200, 200); 

}

void acon()
{
  // Serial.println("REad");

  delayMicroseconds(dimming); // read AD0
  digitalWrite(triacPulse, HIGH);

  delayMicroseconds(50);  //delay 50 uSec on output pulse to turn on triac
  digitalWrite(triacPulse, LOW);

  // Serial.println(digitalRead(triacPulse));
}

Below code is for AC FAN or Bulb Dimmer with zero cross detection. It runs only Blynk App Slider Button. I want to modify the code for manual control by adding two push buttons (one is for ON the fan , then increasing the fan speed by some steps and another is for decreasing the fan speed by some steps and then Off the fan) along with Blynk app Slider Button for controlling through Wifi. It is better to use Blynk App’s "Step H " button instead of slider button (if it is not possible then use default code’s slider button, no problem ). I am unable to write the function for two push button switches and relate their operation with int dimming (see below code). Can anyone help/guide me to modify the below code as above requirements. Code is written for NodeMcu board and Blynk app runs in android device.

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>

#define triacPulse 4 //D2
#define ZVC 12 //D6

int Slider_Value;
int dimming;
int x = 0;

char auth[] = "AUTH TOKEN";        // You should get Auth Token in the Blynk App.


char ssid[] = "SSID";         // Your WiFi credentials.
char pass[] = "PASS";    // Set password to "" for open networks.


BLYNK_WRITE(V1)   // function to assign value to variable Slider_Value whenever slider changes position
{
  Slider_Value = param.asInt(); // assigning incoming value from pin V1 to a variable
}


void setup()
{

  pinMode(ZVC, INPUT_PULLUP);
  //digitalWrite(2, INPUT_PULLUP); // pull up
  pinMode(triacPulse, OUTPUT);
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  attachInterrupt(digitalPinToInterrupt(ZVC), acon, FALLING); // attach Interrupt at PIN2
}



void loop()
{
  Blynk.run();
  // When the switch is closed
  dimming = map(Slider_Value, 0, 100, 7200, 200); 

}

void acon()
{
  // Serial.println("REad");

  delayMicroseconds(dimming); // read AD0
  digitalWrite(triacPulse, HIGH);

  delayMicroseconds(50);  //delay 50 uSec on output pulse to turn on triac
  digitalWrite(triacPulse, LOW);

  // Serial.println(digitalRead(triacPulse));
}

I’ve merged your two topics into one.
Please don’t keep creating new topics about the same project.

Pete.

I assume that you mean widget, in the app?
If so then it’s better to state this.

I’ve already pointed you to the “keep your void loop clean” document. If you’d read it then you’d know that this command belongs elsewhere - probably in the BLYNK_WRITE(V1) callback.

Is your existing code working? If so, what version of the ESP core do you have installed (look in Boards Manager and ESP8266 core by ESP8266 community).

Pete.

This code (not the first shared code, it is just above code) will work only with esp8266 board packages version 2.4.1. , this code runs well , but problem is it runs by Blynk app slider button, It has no manual control. so I need to add two physical button for manual control beside wifi control through Blynk app.

I also read “keep your void loop clean” .Thanks for your suggestion because I did not know that. after reading that I had tried to clean void loop (just above shared code Void loop are cleaned.) Moreover trying to make a functions for the two push buttons but I can’t succeed. I need help just for these reason, how to make functions for the two buttons which also capable to control the dimmer manually like Blynk slider (as run through wifi).

if you see into the above code, you will observed that whenever the slider value is changed then the value stored in V1 Pin and that value changes the dimming Value, and whenever the diming value is changed then delay provided output will change which results variable power at the output.

if I am able to make some button functions which also able to control that dimming value by manual pressing of two buttons which results same as Blynk app’s slider. I just unable to do this and thats why I am seeking your guidance/Help.

If possible just add some needful code with the above shared code (by making button functions, adding button reference and button state as integer, etc what are needful ) so that the dimmer can be controlled by two push buttons manually and by the Blynk slider button through wifi. Thanks.

That’s because your ISR routine isn’t correctly defined.

This…

Should change to this…
ICACHE_RAM_ATTR void acon()

And this function should move up so that it’s before your void setup.
This will prevent the ISR not in IRAM error message with later ESP core versions.

I’d suggest that you look at the “sync physical button” example in the sketch builder for information on how to add a physical button to your sketch and update the corresponding slider/step widget once it’s pressed.

Pete.

Ok, Thank you very much for your information, actually I did not know this, I am trying to learn as per your new suggestions , if need then will inform you, Thanks

Hi, Hope you are well. Last 4 days I have studied a lot of articles and try to learn a lot of issues including your suggestion. Really if you did not advise me, I do not learn the technical issues what I should have know as noob. Thank you very much and really you are our teacher.

After studying a lot I wrote the code and facing some problems which mentioned below as Cases 1,2,and 3:

Case1: Compiler error: ‘class timerOne’ has no member named ‘initialize’
Then studied again and remove #include <TimerOne.h> and use #include <Ticker.h>
Case 2: to do above and compiled again then error shows: ‘Timer1’ was not declared in this scope.

Case 3: modify the void loop part i.e adding Ticker befor Timer1

  Ticker Timer1.attachInterrupt(dim_check, freqStep);  

Then compiler error message appeared as: expected initializer before ‘.’ token

At this moment please see the below code and kindly give some of your valuable time on it to rectify the code. This is a very uncommon project (Basic AC dimmer Project is common but I cannot find anyone who adds push buttons with these desired logic i.e controls the AC dimmer manually (without wifi) along with Blynk app-(with wifi)).

NB: Please also see //------F3 (function 3 ), does the code writing method is ok or not , In this part I am gona synchronise/link with Physical two buttons with Blynk the slider Button.

#define BLYNK_PRINT Serial
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <TimerOne.h>               // ---------------after compiling and error message came, using #include <Ticker.h> instead of #include <TimerOne.h> 

#define triacPulse 13               //as Output to Opto Triac at Gpio 13 means D7
#define ZVC 12                      //as input From Optocoupler to detect zerocrossing signal at Gpio 12 means D6

int Slider_Value;
int x = 0;

volatile int i=0;                   // Variable to use as a counter of dimming steps. It is volatile since it is passed between interrupts
volatile boolean zero_cross=0;      // Flag to indicate we have crossed zero
                
int button1 = 5;                    // first physical button as input at Gpio 5 means D1
int button2 = 4;                    // second physical button as input at Gpio 4 means D2

int dimming = 128;                  // Dimming level (0-128)  0 = on, 128 = 0ff
int pas = 8;                        // step for count;
int freqStep = 75;                  // This is the delay-per-brightness step in microseconds. It allows for 128 steps
                                    // If using 60 Hz grid frequency set this to 65


char auth[] = "AUTH TOKEN";        // You should get Auth Token in the Blynk App.
char ssid[] = "SSID";              // Your WiFi credentials.
char pass[] = "PASS";              // Set password to "" for open networks.
  
BlynkTimer timer;


ICACHE_RAM_ATTR void acon() {           // Serial.println("Read");-------------------------F1

  volatile int dimtime = (75*dimming);  // For 60Hz = 65  
  delayMicroseconds(dimtime);           // read AD0
  digitalWrite(triacPulse, HIGH);
  delayMicroseconds(50);                //delay 50 uSec on output pulse to turn on triac
  digitalWrite(triacPulse, LOW);        // Serial.println(digitalRead(triacPulse));
}

void dim_check() {                      //---------------------------------------------F2
  if(zero_cross == true) {              
    if(i>=dimming) {                     
      digitalWrite(triacPulse, HIGH);  // turn on light or Fan       
      i=0;                             // reset time step counter                         
      zero_cross=false;                // reset zero cross detection flag
    } 
    else {
      i++;                             // increment time step counter               
    }                                
  }    
} 

void checkPhysicalButton() {          //----------------------------------------F3
  digitalWrite(button1, HIGH);
  Blynk.virtualWrite(V2, button1);
  
  digitalWrite(button2, HIGH);
  Blynk.virtualWrite(V2, button2);
  
 if (digitalRead(button1) == LOW)   
   {
  if (dimming<127)  
  {
    dimming = dimming + pas;
    if (dimming>127) 
    {
      dimming=128;
    }
  }
   }
  if (digitalRead(button2) == LOW)   
   {
  if (dimming>5)  
  {
     dimming = dimming - pas;
  if (dimming<0) 
    {
      dimming=0;
    }
   }
   }
    while (digitalRead(button1) == LOW) {  }              
    delay(10);                                    // waiting little bit...  
    while (digitalRead(button2) == LOW) {  }              
    delay(10);                                    // waiting little bit...    
}


BLYNK_CONNECTED() {                               // Request the latest state from the server & Every time we connect to the cloud...-------------F4
  Blynk.syncVirtual(V1);
}

BLYNK_WRITE(V1) {                 // function to assign value to variable Slider_Value whenever slider changes position-------------F5
  Slider_Value = param.asInt(); // assigning incoming value from pin V1 to a variable
}


void setup()
{

  pinMode(ZVC, INPUT_PULLUP);  
  pinMode(triacPulse, OUTPUT);
  
  Serial.begin(9600);
  Blynk.begin(auth, ssid, pass);
  
  attachInterrupt(digitalPinToInterrupt(ZVC), acon, FALLING);       // attach Interrupt at PIN2

  Timer1.initialize(freqStep);                                      // Initialize TimerOne library for the freq we need---To rectify the code lastle add Ticker just before Timer1
  Timer1.attachInterrupt(dim_check, freqStep);                      // Go to dim_check procedure every 75 uS (50Hz)  or 65 uS (60Hz)--To rectify the code lastle add Ticker just before Timer1 and case 3 error message came


  timer.setInterval(100L, checkPhysicalButton);                     // Setup a function to be called every 100 ms

  
}



void loop()
{
  Blynk.run();
  timer.run(); 
  dimming = map(Slider_Value, 0, 100, 7200, 200); 

}

What’s the logic behind adding these TimerOne and Ticker libraries?

Why aren’t you using the BlynkTimer library that is already included in the Blynk library?

Pete.

I thought esp microcontroller itself execute operation by using Timer1 like Atmega 328 and blynkTimer may be used only for app synchronization purpose. Here I used Timer1 for dim check function and for the frequency.

Anyway, Please Suggest me can I use

  timer.initialize(freqStep);      //now use blynk timer                              
  timer.attachInterrupt(dim_check, freqStep);    //now use blynk timer 

  timer.setInterval(100L, checkPhysicalButton);  

Instead of

Timer1.initialize(freqStep);
Timer1.attachInterrupt(dim_check, freqStep)

Sorry, I didn’t understand any of that in relation to this project.

Pete.

Almost one year ago , I made an ac Fan dimmer by using arduino board + two push buttons for speed controlling purpose (Project was successful). In that project I had used below two lines in void setup part. to control the buttons .

  timer1.attachInterrupt(dim_check, freqStep);

Beside that also used void dim_check() function to count button steps and flag for zero cross signal in that code.

after that I also made another Blynk app based AC FAN Dimmer by using slider button (board Node MCU) which only operates by Blynk app i.e it only runs by wifi , It have no manual control (Without wifi).

Now I am trying heart and sole to combine these two code so that made an AC fan dimmer which operates by both wifi (Blynk app) and without wifi (Push buttons)

That’s why I draw your attention again and again . I think if you kindly see the code then you may suggest/guide/teach me What things or what type of rectification I will have to do to execute the objective.

Thanks and regards.

you don’t need to send the state of the buttons to virtual pin periodically. it is enough to send it if it changes

Thanks for your reply. I am finding the hope by your advice. Wil you please tell me details what I have to do or particularly in which portion I have to change to avoid sending the state periodically. If you reply in detail what I have to write the code instead of what I wrote then I can learn from that. Thanks again.

In your code in post#12. your checkPhysicalButton function is called 10 times per second, and you are writing “5” to Blynk virtual pin V2 (because the variable button1 == 5), then you are writing “4” to the same virtual pin (because the variable button2 == 4).

I assume that you are meaning to write the values obtained by reading button1 and button2 to two different virtual pins (not much point in writing both to V2).
However, you aren’t actually capturing the results of the digitalRead(button1) and digitalRead(button2) actions, and even if you were, the Blynk.virtualWrite commands would need to come after reading the digital pins, not before.

I think that what @Juraj was saying is that once you’ve resolved this issue, you only need to write the value of the button1 and button2 pins to the Blynk virtual pins if they’ve changes since last time.

Pete.

it is a slider, not a button, so OP has only one virtual pin