AC DIMMER doesn't work

Hi,

I am building an automatic system for hydroponic.
My sketch works very well instead for one thing, the AC DIMMER.
When I upload the AC dimmer code alone, it works perfectly fine but when I upload it with the rest of the code, the AC DIMMER seems to work but the LED goes much more slower.
I don’t know if it could be that because of the integration of Blink, that the system goes to slow and the AC DIMMER that need to work fast, probably doesn’t work.

Please Help me.

PD: SKETCHFINALHIDROPONIA is the complete one and the other one (ACDIMMERFINAL) is the sketch for the AC dimmer STANDALONE.

Thank you,

Jonathan

SKETCHFINALHIDROPONIA:

#include <DHT.h>;
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include "max6675.h"
#include <UIPEthernet.h>
#include <BlynkSimpleUIPEthernet.h>

#define DHTPIN 45     //PIN DHT22
#define DHTTYPE DHT22  
          
#define Offset -1.50            
#define samplingInterval 20
#define printInterval 800
#define ArrayLenth  40    

#define MAX_ADC_READING           1023
#define ADC_REF_VOLTAGE           5.0
#define REF_RESISTANCE            5030  // measure this for best results
#define LUX_CALC_SCALAR           12518931
#define LUX_CALC_EXPONENT         -1.405

//Pins
int PINBOMBAAGUA1=2;
int PINBOMBAAGUA2=40; 
int PINSENHUMEDAD = A0;
int PINRELAYLUZ = 34;
int PINSENSORDENIVEL = 5;
int PINSENSORPH= A1;
int firing_pin = 3; 
int zero_cross = A8; 
int thermoDO = 30;
int thermoCS = 25;
int thermoCLK = 32;
int PINBOMBAPERISTALTICA1MAS=14;
int PINBOMBAPERISTALTICA2MENOS=16; 
int PINVENTILADOR1=6;
int PINVENTILADOR2=7;
int PINSENSORLUMINOCIDAD=A2;


//Variables
int BotonMenos; 
int BotonMas; 
int ValeurSensorHumedad = 0;
int pourcentageHumedad = 0;
int valorsensor=0;
int Interruptorcalefaccion;
int Interruptorluz;
float humDHT;  
float tempDHT; 
float PH;
int ldrRawData;
float resistorVoltage;
float ldrVoltage;
float ldrResistance;
float ldrLux;
float luminocidad;
float luminocidadsetpoint;
float phsetpoint;
int humedadsetpoint;
char auth[] = "c9d17da1a5ac40bd962d76366322e149";

#define BLYNK_PRINT Serial

LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7);
DHT dht(DHTPIN, DHTTYPE); 
BlynkTimer timer; 
BLYNK_CONNECTED() {
Blynk.syncAll();
}

//Constantes
int pHArray[ArrayLenth];  
int pHArrayIndex=0; 

MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

//Variables PID 1
int last_CH1_state = 0;
bool zero_cross_detected = false;
int firing_delay = 7400;
int maximum_firing_delay = 7400;
unsigned long previousMillis = 0; 
unsigned long currentMillis = 0;
int temp_read_Delay = 300;//500
int real_temperature = 0;
int setpoint;

//Variable PID 2
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
int PID_value = 0;

//CONSTANTES PID
int kp = 203;   int ki= 2.2;   int kd = 1.04;
int PID_p = 0;    int PID_i = 0;    int PID_d = 0;

//BLYNK
BLYNK_WRITE(V0)//Permite leer el valor del virtual PIN 1 en BLYNK
{
  Interruptorluz = param.asInt(); // Asigna los valores que lee del Virtual PIN 1 a una variable
}
BLYNK_WRITE(V1)//Permite leer el valor del virtual PIN 1 en BLYNK
{
  Interruptorcalefaccion = param.asInt(); // Asigna los valores que lee del Virtual PIN 1 a una variable
}
BLYNK_WRITE(V2)//Permite leer el valor del virtual PIN 2 en BLYNK
{
  setpoint = param.asInt(); // Asigna los valores que lee del Virtual PIN 2 a una variable
}

BLYNK_READ(V3) // Widget in the app READs Virtal Pin V3 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V3
  Blynk.virtualWrite(3, tempDHT);
}

BLYNK_READ(V4) // Widget in the app READs Virtal Pin V4 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V4
  Blynk.virtualWrite(4, humDHT);
}

BLYNK_READ(V9) // Widget in the app READs Virtal Pin V10 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V10
  Blynk.virtualWrite(9, PH);
}

BLYNK_READ(V10) // Widget in the app READs Virtal Pin V10 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V10
  Blynk.virtualWrite(10, luminocidad);
}

BLYNK_WRITE(V11)//Permite leer el valor del virtual PIN 11 en BLYNK
{
  luminocidadsetpoint = param.asInt(); // Asigna los valores que lee del Virtual PIN 11 a una variable
}

BLYNK_READ(V12) // Widget in the app READs Virtal Pin V12 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V12
  Blynk.virtualWrite(12, setpoint);
}

BLYNK_WRITE(V13)//Permite leer el valor del virtual PIN 13 en BLYNK
{
  humedadsetpoint = param.asInt(); // Asigna los valores que lee del Virtual PIN 13 a una variable
}

BLYNK_READ(V15) // Widget in the app READs Virtal Pin V15 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V15
  Blynk.virtualWrite(15, humedadsetpoint);
}

BLYNK_READ(V16) // Widget in the app READs Virtal Pin V16 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V16
  Blynk.virtualWrite(16, luminocidadsetpoint);
}


BLYNK_WRITE(V20)//Permite leer el valor del virtual PIN 21 en BLYNK
{
  phsetpoint = param.asFloat(); // Asigna los valores que lee del Virtual PIN 21 a una variable
}

BLYNK_READ(V21) // Widget in the app READs Virtal Pin V20 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V20
  Blynk.virtualWrite(21, phsetpoint);
}

BLYNK_READ(V22) // Widget in the app READs Virtal Pin V22 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V22
  Blynk.virtualWrite(22, pourcentageHumedad);
}

BLYNK_READ(V23) // Widget in the app READs Virtal Pin V23 with the certain frequency
{
  // This command writes Arduino's uptime in seconds to Virtual Pin V22
  Blynk.virtualWrite(23, real_temperature);
}


WidgetLED led1(V5); //register to virtual pin 5 N.AGUA
WidgetLED led2(V6); //register to virtual pin 6 PUMP
WidgetLED led3(V7); //register to virtual pin 7 PH+
WidgetLED led4(V8); //register to virtual pin 8 PH-
WidgetLED led5(V14); //register to virtual pin 14 TAPA
WidgetLED led6(V17); //register to virtual pin 17 LUZ
WidgetLED led7(V18); //register to virtual pin 18 HOT
WidgetLED led8(V19); //register to virtual pin 19 DRY

void lednivelaguablynk(){
  if (valorsensor==1){
    led1.off();
  }
  else{
    led1.on();
  }
}

void ledpumpstateblynk(){
  if (pourcentageHumedad <= 60 or valorsensor !=1) {   //pourcentageHumedad <= 60 or valorsensor !=1 (Borrar despues de probar nuevo algoritmo (PINBOMBAAGUA1,HIGH,PINBOMBAAGUA2,LOW))
    led2.on();
  }
  else {
    led2.off();
  }
}

void ledhot(){
  if (real_temperature <= 100){
    led7.on();
  }
  else{
    led7.off();
  }
}

void leddry(){
  if (pourcentageHumedad < humedadsetpoint){
    led8.on();
  }
  else{
    led8.off();
  }
}

void ledluz(){
  if(PINRELAYLUZ,HIGH){
    led6.on();
  }
  else{
    led6.off();
  }
}

void ledtapa(){
  if(luminocidad>luminocidadsetpoint and PINRELAYLUZ,LOW){
    led5.on();
  }
  else{
    led5.off();
  }
}

void ledphmenos(){
  if(PINBOMBAPERISTALTICA1MAS, HIGH){
    led4.on();
  }
  else{
    led4.off();
  }
}

void ledphmas(){
  if(PINBOMBAPERISTALTICA2MENOS, HIGH){
    led3.on();
  }
  else{
    led3.off();
  }
}

void setup() {
  
  //PINMODES:
  //pinMode(PINBOTONMAS,INPUT);
  //pinMode(PINBOTONMENOS,INPUT);
  pinMode (firing_pin,OUTPUT); 
  pinMode (zero_cross,INPUT); 
  pinMode(PINRELAYLUZ,OUTPUT); 
  pinMode(PINSENSORDENIVEL,INPUT);
  pinMode (PINBOMBAAGUA1,OUTPUT); 
  pinMode (PINBOMBAAGUA2,OUTPUT); 

  PCICR |= (1 << PCIE2);                                                   
  PCMSK2 |= (1 << PCINT16); 
  
  Time = millis(); 
  dht.begin();
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.begin(16, 2);
  

  //Blynk 
  Serial.begin(9600);
  Blynk.begin(auth);
  Blynk.begin(auth, "blynk-cloud.com", 80);
  timer.setInterval(1000L, lednivelaguablynk);
  timer.setInterval(1000L, ledpumpstateblynk);
  timer.setInterval(1000L, ledhot);
  timer.setInterval(1000L, leddry);
  timer.setInterval(1000L, ledluz);
  timer.setInterval(1000L, ledtapa);
  timer.setInterval(1000L, ledphmenos);
  timer.setInterval(1000L, ledphmas);
}

void loop() {
  Blynk.run();
  timer.run();
  
  currentMillis = millis();        
  if(currentMillis - previousMillis >= temp_read_Delay){
    previousMillis += temp_read_Delay;             
    real_temperature = thermocouple.readCelsius();  

    PID_error = setpoint - real_temperature;       
    
    if(PID_error > 30)                                          
    {PID_i = 0;}
    
    PID_p = kp * PID_error;                       
    PID_i = PID_i + (ki * PID_error);              
    timePrev = Time;                    
    Time = millis();                   
    elapsedTime = (Time - timePrev) / 1000;   
    PID_d = kd*((PID_error - previous_error)/elapsedTime);  
    PID_value = PID_p + PID_i + PID_d;                      
    
    if(PID_value < 0)
    {      PID_value = 0;       }
    if(PID_value > 7400)
    {      PID_value = 7400;    }
    previous_error = PID_error; 
  }
  if (zero_cross_detected)     
    {
      delayMicroseconds(maximum_firing_delay - PID_value); 
      digitalWrite(firing_pin,HIGH);
      delayMicroseconds(100);
      digitalWrite(firing_pin,LOW);
      zero_cross_detected = false;
    } 

   valorsensor=digitalRead(PINSENSORDENIVEL);
  
  digitalWrite(PINVENTILADOR1, LOW);
  digitalWrite(PINVENTILADOR2, HIGH);
  
  valorsensor=digitalRead(PINSENSORDENIVEL);
  if (valorsensor !=1){
      digitalWrite(PINBOMBAAGUA1,HIGH);
      digitalWrite(PINBOMBAAGUA2,LOW);
  }
  else {
    digitalWrite(PINBOMBAAGUA1,HIGH);
    digitalWrite(PINBOMBAAGUA2,HIGH);
  }
 
  if (Interruptorluz==0){
    digitalWrite(PINRELAYLUZ,LOW);
  }

  else{
    digitalWrite(PINRELAYLUZ,HIGH);
  }
  
  humDHT = dht.readHumidity();
  tempDHT= dht.readTemperature();
  
  PH=ReadPH();

  luminocidad=ReadLux();
  
  ValeurSensorHumedad = readhumidity();
  pourcentageHumedad = ConvertEnPorcentaje(ValeurSensorHumedad);
  
  if (pourcentageHumedad > 100){
  pourcentageHumedad = 100;
 }
  if (pourcentageHumedad < 0){
  pourcentageHumedad = 0;
 }

  if (PH>phsetpoint){
    digitalWrite(PINBOMBAPERISTALTICA2MENOS,HIGH);
    delay(100);
    digitalWrite(PINBOMBAPERISTALTICA2MENOS,LOW);
    delay(100);
  }

  if (PH<phsetpoint){
    digitalWrite(PINBOMBAPERISTALTICA1MAS,HIGH);
    delay(100);
    digitalWrite(PINBOMBAPERISTALTICA1MAS,LOW);
    delay(100);
  }

  if (luminocidad<luminocidadsetpoint){
    digitalWrite(PINRELAYLUZ,HIGH);
  }
    else{
    digitalWrite(PINRELAYLUZ,LOW); 
    }

  //BotonMenos = digitalRead(PINBOTONMENOS);
  //BotonMas= digitalRead(PINBOTONMAS);
  
  //if (BotonMenos != 1){
  //setpoint--;
  //}
  //if (BotonMas != 1){
  //setpoint++;
  //}

  delay(100);
  lcd.clear();
  
  lcd.setCursor(0,0);
  lcd.print("H:");
  lcd.setCursor(2,0);
  lcd.print(humDHT);
  lcd.setCursor(7,0);
  lcd.print("%");
  lcd.setCursor(9,0);
  lcd.print("PH:");
  lcd.setCursor(12,0);
  lcd.print(PH);
  lcd.setCursor(0,1);
  lcd.print("SET:");
  lcd.setCursor(4,1);
  lcd.print(setpoint,1);
  lcd.setCursor(6,1);
  lcd.print("C");
  lcd.setCursor(8,1);
  lcd.print("REAL:");
  lcd.setCursor(13,1);
  lcd.print(real_temperature,1);
  lcd.setCursor(15,1);
  lcd.print("C");
}

//Input from optocoupler
ISR(PCINT2_vect){
  if(PINK & B00000001){            
    if(last_CH1_state == 0){      
      zero_cross_detected = true;  
    }
  }
  else if(last_CH1_state == 1){         
    zero_cross_detected = true;   
    last_CH1_state = 0;           
    }
}

int readhumidity(){
  int valorhumedad = 0;
  valorhumedad = analogRead(PINSENHUMEDAD);
  return valorhumedad;
}

int ConvertEnPorcentaje(int value){
 int ValeurPorcentage = 0;
 ValeurPorcentage = map(value, 1023, 350, 0, 100);
 return ValeurPorcentage;
}

int ReadLux(){
  ldrRawData = analogRead(PINSENSORLUMINOCIDAD);
  resistorVoltage = (float)ldrRawData / MAX_ADC_READING * ADC_REF_VOLTAGE;
  ldrVoltage = ADC_REF_VOLTAGE - resistorVoltage;
  ldrResistance = ldrVoltage/resistorVoltage * REF_RESISTANCE;
  ldrLux = LUX_CALC_SCALAR * pow(ldrResistance, LUX_CALC_EXPONENT);
  return ldrLux;
  delay(100);
}

float ReadPH(){
  static unsigned long samplingTime = millis();
  static unsigned long printTime = millis();
  static float pHValue,voltage;
  if(millis()-samplingTime > samplingInterval)
  {
      pHArray[pHArrayIndex++]=analogRead(PINSENSORPH);
      if(pHArrayIndex==ArrayLenth)pHArrayIndex=0;
      voltage = avergearray(pHArray, ArrayLenth)*5.0/1024;
      pHValue = 3.5*voltage+Offset;
      samplingTime=millis();
      return pHValue;
  }
}
double avergearray(int* arr, int number){
  int i;
  int max,min;
  double avg;
  long amount=0;
  if(number<5){   
    for(i=0;i<number;i++){
      amount+=arr[i];
    }
    avg = amount/number;
    return avg;
  }else{
    if(arr[0]<arr[1]){
      min = arr[0];max=arr[1];
    }
    else{
      min=arr[1];max=arr[0];
    }
    for(i=2;i<number;i++){
      if(arr[i]<min){
        amount+=min;       
        min=arr[i];
      }else {
        if(arr[i]>max){
          amount+=max;   
          max=arr[i];
        }else{
          amount+=arr[i]; 
        }
      }//if
    }//for
    avg = (double)amount/(number-2);
  }//if
  return avg;
}```

ACDIMMERFINAL:


```/*    Max6675 Module  ==>   Arduino
 *    CS              ==>     D25
 *    SO              ==>     D30
 *    SCK             ==>     D32
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */

//LCD config
#include "max6675.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7); 

/*    i2c LCD Module  ==>   Arduino
 *    SCL             ==>     D21
 *    SDA             ==>     D20
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */

/*    ACDIMMER .      ==>   Arduino
 *    Zero_cross      ==>     A8
 *    Disparo         ==>     D3
 *    Vcc             ==>     Vcc (5v)
 *    Gnd             ==>     Gnd      */
 

//Inputs and outputs
int firing_pin = 3;
int zero_cross = A8;
int thermoDO = 30;
int thermoCS = 25;
int thermoCLK = 32;

//Start a MAX6675 communication with the selected pins
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);


//Variables
int last_CH1_state = 0;
bool zero_cross_detected = false;
int firing_delay = 7400;

//////////////////////////////////////////////////////
int maximum_firing_delay = 7400;
/*Later in the code you will se that the maximum delay after the zero detection
 * is 7400. Why? Well, we know that the 220V AC voltage has a frequency of around 50-60HZ so
 * the period is between 20ms and 16ms, depending on the country. We control the firing
 * delay each half period so each 10ms or 8 ms. To amke sure we wont pass thsoe 10ms, I've made tests
 * and the 7400us or 7.4ms was a good value. Measure your frequency and chande that value later */
//////////////////////////////////////////////////////

unsigned long previousMillis = 0; 
unsigned long currentMillis = 0;
int temp_read_Delay = 500;
int real_temperature = 0;
int setpoint = 60;

//PID variables
float PID_error = 0;
float previous_error = 0;
float elapsedTime, Time, timePrev;
int PID_value = 0;
//PID constants
int kp = 203;   int ki= 2.2;   int kd = 1.04;
int PID_p = 0;    int PID_i = 0;    int PID_d = 0;

void setup() {
  Serial.begin(9600);
  //Define the pins
  pinMode (firing_pin,OUTPUT); 
  pinMode (zero_cross,INPUT); 
  PCICR |= (1 << PCIE2);    //enable PCMSK0 scan                                                 
  PCMSK2 |= (1 << PCINT16);  //Set pin D8 (zero cross input) trigger an interrupt on state change.
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);
  lcd.begin(16, 2);

}

    indent preformatted text by 4 spaces
void loop() {    
  currentMillis = millis();           //Save the value of time before the loop
   /*  We create this if so we will read the temperature and change values each "temp_read_Delay"
    *  value. Change that value above if you want. The MAX6675 read is slow. Tha will affect the
    *  PID control. I've tried reading the temp each 100ms but it didn't work. With 500ms worked ok.*/
  if(currentMillis - previousMillis >= temp_read_Delay){
    previousMillis += temp_read_Delay;              //Increase the previous time for next loop
    real_temperature = thermocouple.readCelsius();  //get the real temperature in Celsius degrees

    PID_error = setpoint - real_temperature;        //Calculate the pid ERROR
    
    if(PID_error > 30)                              //integral constant will only affect errors below 30ºC             
    {PID_i = 0;}
    
    PID_p = kp * PID_error;                         //Calculate the P value
    PID_i = PID_i + (ki * PID_error);               //Calculate the I value
    timePrev = Time;                    // the previous time is stored before the actual time read
    Time = millis();                    // actual time read
    elapsedTime = (Time - timePrev) / 1000;   
    PID_d = kd*((PID_error - previous_error)/elapsedTime);  //Calculate the D value
    PID_value = PID_p + PID_i + PID_d;                      //Calculate total PID value

    //We define firing delay range between 0 and 7400. Read above why 7400!!!!!!!
    if(PID_value < 0)
    {      PID_value = 0;       }
    if(PID_value > 7400)
    {      PID_value = 7400;    }
    //Printe the values on the LCD
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Set: ");
    lcd.setCursor(5,0);
    lcd.print(setpoint);
    lcd.setCursor(0,1);
    lcd.print("Real temp: ");
    lcd.setCursor(11,1);
    lcd.print(real_temperature);
    previous_error = PID_error; //Remember to store the previous error.
  }

  //If the zero cross interruption was detected we create the 100us firing pulse  
  if (zero_cross_detected)     
    {
      delayMicroseconds(maximum_firing_delay - PID_value); //This delay controls the power
      digitalWrite(firing_pin,HIGH);
      delayMicroseconds(100);
      digitalWrite(firing_pin,LOW);
      zero_cross_detected = false;
    } 
}
//End of void loop
// |
// |
// |
// v
//See the interruption vector




//This is the interruption routine (pind D8(zero cross), D11(increase) and D12(decrease))
//----------------------------------------------
ISR(PCINT2_vect){
  ///////////////////////////////////////Input from optocoupler
  if(PINK & B00000001){            //We make an AND with the state register, We verify if pin D8 is HIGH???
    if(last_CH1_state == 0){       //If the last state was 0, then we have a state change...
      zero_cross_detected = true;  //We have detected a state change! We need both falling and rising edges
    }
  }
  else if(last_CH1_state == 1){    //If pin 8 is LOW and the last state was HIGH then we have a state change      
    zero_cross_detected = true;    //We haev detected a state change!  We need both falling and rising edges.
    last_CH1_state = 0;            //Store the current state into the last state for the next loop
    }```

EDIT YOUR POST TO FORMAT THE CODE CORRECTLY!!

Blynk%20-%20FTFC

Pete.

1 Like

@Jonathan_Prieto This has been suggested to you in the past… so please read this and then adjust your code appropriately… no sense in asking us to fix this mess otherwise.

Things are running slower becasue you are asking too much to be done at the same time in the void loop() Put your needed fast code into fast timed functions that don’t conflict with each other… keep all functions tight and quick.

1 Like