Dimmer con cruce por 0 con Arduino

Buenas, tengo un problema con mi proyecto, estoy controlando un motor universal en AC de 600W a travez de un dimmer con cruce por cero conectado a un Arduino UNO que lo maneja por PWM (La regulacion en el arduino esta echa por un potenciometro de 10K). Mi problema sucede a bajas revoluciones, es decir baja frecuencia, el motor chispea mucho y va a los tirones, una vez que sube las RPM este problema desaparece, me recomendaron hacerle un filtro, ¿esto podra se? y en caso de que sea ¿como tendria que calcular y hacer este filtro?
Cualquier informacion me resultaria util


image
Aca les dejo el codigo, el cual modifique para que el motor arranque a un %30 de su capacidad y no chispee tanto, pero la idea en caso de solucionarlo es usarlo de 0 a 100:

#include <RBDdimmer.h>//

//#define USE_SERIAL  SerialUSB //Serial for boards whith USB serial port
#define USE_SERIAL  Serial
#define outputPin  6

 
#define zerocross  2 // for boards with CHANGEBLE input pins

//dimmerLamp dimmer(outputPin, zerocross); //initialase port for dimmer for ESP8266, ESP32, Arduino due boards
dimmerLamp dimmer(outputPin); //initialase port for dimmer for MEGA, Leonardo, UNO, Arduino M0, Arduino Zero

int outVal = 0;

void setup() {
  USE_SERIAL.begin(9600);
  dimmer.begin(NORMAL_MODE, ON); //dimmer initialisation: name.begin(MODE, STATE) 
  
}

void loop() 
{
  
  int potValue = analogRead(0);
    if (potValue <= 102) // Si  el valor analógico es igual o menor a 102 (aproximadamente 10% de 1023)
  {
    dimmer.setPower(0); // Apaga el motor estableciendo la potencia del dimmer a 0
  }
  else
  {
    
  outVal = map(potValue, 102, 1024, 30, 80); // analogRead(analog_pin), min_analog, max_analog, 100%, 0%);
  USE_SERIAL.println(outVal); 
  dimmer.setPower(outVal); // name.setPower(0%-100%)
  delay(100);
  
  }

  
}

No, la frecuencia de red es fija, 50 ó 60 Hz según sea en tu país.
Lo que manejas con el dimmer es la tensión al "recortar" la onda senoidal.

Te paso la traducción (según Google) de parte de este tutorial
"... El uso de un optocoupler proporciona una señal precisa de cruce cero, pero no es extremadamente estrecha. El ancho del pulso de este circuito (a 50Hz) es típicamente alrededor de 600us (0,6ms) que suena lo suficientemente rápido. El problema es que a 50Hz cada medio ciclo toma solo 10ms (8,33ms a 60Hz), por lo que el ancho del pulso es superior al 5% del período total. Es por eso que la mayoría de los atenuadores solo pueden reclamar un rango del 10%-90% - el pulso de cruce cero dura demasiado tiempo para permitir un mayor rango. La solución es evitar regular hasta el mínimo o hasta el máximo..."

1 Like

Gracias con la informacion, me exprese mal, con baja frecuencia queria hacer referencia al ancho de pulso del PWM.

Controlar un motor con un dimmer siempre es una mala idea. Lámparas son una cosa y lámparas de filamento que ya estan prohibidas en casi todo el mundo o no se fabrican mas.
Como son resistivas el control funciona bien.
Pero en un motor hay otros problemas.
Lo mejor es que te compres un variador de velocidad y controles el motor usando la entrada que disponga, 0-10, 4-20 o 0-20mA, entrada de frecuencia, o MODBUS.
Nunca intentes esto con un motor a menos que sea como hobby.

1 Like

Totalmente de acuerdo, es solo para un proyecto de la facultad, solo de hobby. Pero el único error que tengo de momento es el tema de los tirones en bajas rpm, si soluciono dicho inconveniente ya podre ejemplificar el funcionamiento del dimmer con el motor (objetivo del proyecto). Gracias por el comentario, y si me podés agregar alguna posible solución también te agradecería, Gracias!

Te sugiero que busques una lampara de filamento y veas como se comporta.
Si se comporta bien (cosa que desacarto) el problema es la Fuerza contra electromotriz presenteen todo motor. Accionas sobre un elemento inductivo.
Si me das para elegir te diria que no uses un TRIAC y en su reemplazo usa un puente de diodos con un IGBT.

aca la prueba

Hi,
No se si te interesa pero yo desarolle un control ac para mi amplificador para evitar la corriente de "inrush" que usa un triac . Ya que la onda senoidal de medio ciclo es de 8.3 ms yo disparo el triac menos de 8.3 y el tiempo del disparo voy disminuyendo hasta llegar a los 4.15 que serian 45 grados de la onda sinoidal y en este momento mantengo el triac energizado todo el tiempo. Para que tenga una idea adjunto una foto animada de como yo lo hago.Esta foto fue hecha por uno de los mienbros del diyaudio para demostrar como funciona el control de los pulsos. Si esta interesado te puedo pasar el diagrama electrico y el sketch que uso para controlar el triac. Si estasinteresado te puedo pasar el circuito y el sketch. Para ver como los pulsos son hechos click en la foto y veras como el control trabaja.

LEADING

1 Like

Hola, sisi me interesa, me parece una muy buena opcion, muy ingenioso, si puedes pasarme las cosas estaria agradecido, gracias!

Hi,
Adjunto el circuito electronic y el sketch que uso para controlar el triac. Yo uso otro relay para bypass el traic ya que quiero eliminar los ruidos del traic una vez que el traic esta continuamente energizado. Yo uso el control para prender/apagar un amplificadr de sonido y puede introducir ruidos.


```cpp
/* This program will ramp the AC on power ON /OFF
  by firing the traic at zero crossing. This will
  minimized the inrush currrent to aminimum by
  firing the traic at zero crossing on power
  ON/OFF Warning the timimg it is set for 60 cycles.
  This program it is compiling for Arduino UNO board*/
//************************************************************************************
#include <Wire.h>             // Needed for legacy versions of Arduino.
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 20, 4); // Set the LCD I2C address0x27
#include <Arduino.h>
int triac_rly_byp = 5 ;       //pin output triac relay bypass output pin
int ac_zero_x     = 3;        //pin input  variable zero crossing 
int pwr_switch    = 7;        //pin input  variable
int triac_ssr     = 6;        //pin output  SSR gate trigger output pin
int led_ind       = 12;       //pin output power on indicator
int ac_sine_angle;            //variable
unsigned long angle_delay;
int tmp_var = 0;
int on_off_flag = 0;
int start_cycle_dly = 0;
//************************************************************************************
void setup() {

  // put your setup code here, to run once
  Serial.begin(9600);      // open the serial port at 9600 bps
  lcd.begin()  ;
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);  //set curso character position=0  line=0
  lcd.print(" AC Power Control");
  lcd.setCursor(0, 1);  //set curso character position=0  line=0
  lcd.print("System Initializing");
  delay(2000);
  lcd.clear();
  //**********************************************************************
  pinMode(pwr_switch, INPUT_PULLUP);
  pinMode(triac_ssr, OUTPUT);
  digitalWrite(triac_ssr, LOW);
  pinMode(triac_rly_byp, OUTPUT);
  digitalWrite(triac_rly_byp, LOW);
  pinMode(ac_zero_x , INPUT_PULLUP);
  pinMode(led_ind, OUTPUT);
  digitalWrite(led_ind, LOW);
  lcd.setCursor(0, 2);  //set curso character position=0  line=0
  lcd.print("  System  Running  ");
  delay(2000);
  lcd.clear();
}
//**************************************************************************************
void loop() {

  //use for scoping purposes only
  //power_off();              //Uncomment to  scope timiming signal
  //power_on();               //Uncomment to  scope timiming signal
  //test_triac_pulse();       //Uncomment to  scope timiming signal

  //***************************************************************************************
  // put your main code here, to run repeatedly:
  read_switch();

  delay (1000);
}
//***************************************************************************************
void read_switch() {

  byte tmp_var = digitalRead(pwr_switch);
  //******************************************
  if (tmp_var == 0) {
    lcd.clear()  ;
    lcd.setCursor(0, 0);
    lcd.print("Amplifier Power OFF ");
  }
  //******************************************
  if (tmp_var  == on_off_flag ) {
    return;
  }
  // Power ON action
  else if  ( tmp_var == 1 ) {
    power_on();
  }
  // Power Off action
  else if (tmp_var == 0 ) {
    power_off();
  }
}
//*************************** Zero crossing pulse ***************************************
void trigger_triac_pls() {

  unsigned long start_time = 0;
  //********************* wait for the zero crossing pulse
  while (tmp_var == 0 ) {
    tmp_var = digitalRead(ac_zero_x);
  }
  while (tmp_var == 1 ) {
    tmp_var = digitalRead(ac_zero_x);
  }
  //********************** syncronize the angle to trigger on the traic
  start_time = micros();
  while ((micros() - start_time) <=  start_cycle_dly  + ac_sine_angle ) {
    //Do nothing Wait for the right time to trigger the triac
  }
  digitalWrite(triac_ssr, HIGH);   //Trigger the triac ON pulse
  delayMicroseconds(100);          // Delay pulse  ON width 100 microseconds
  digitalWrite(triac_ssr, LOW);    //Turned the triac off
}
//************************** power OFF **************************************************
void power_off() {

  lcd.clear() ;
  lcd.setCursor(0, 0);
  lcd.print("Turning Power Off");
  digitalWrite(triac_rly_byp, LOW); //turn off triac bypass relay
  delay(500);
  start_cycle_dly = 4000; // Start position to trigger the triac 3600  miliseconds delay after the Zero crossing
  //*******************************
  for (ac_sine_angle = 000 ; ac_sine_angle <= 3600 ; ac_sine_angle = ac_sine_angle + 20 ) {
    /* This loop is used to delay the ramp slope by triggering the traic 6 time
       at the same angle. This will slow down the ramp */
    //*******************************
    for (int rpt_angle = 1 ; rpt_angle <= 6 ; rpt_angle++) {
      trigger_triac_pls();
    }
  }
  on_off_flag = 0;
  digitalWrite(led_ind, LOW);  //Turn off power led light indicator
 lcd.clear() ;
  lcd.setCursor(0, 0);
  lcd.print("Amplifier Power Off");
}
//'*************************** power ON ***************************************************
void power_on() {
  
  lcd.clear() ;
  lcd.setCursor(0, 0);
  lcd.print("Turning Power  ON");
  start_cycle_dly = 4000; //start triggering the triac 3600 + 3600 miliseconds delay after the Zero crossing
  //**************************************
  for (ac_sine_angle = 3600; ac_sine_angle > 100; ac_sine_angle = ac_sine_angle - 20 ) {
    /* This loop is used to delay the ramp slope by triggering the traic 6 time
      at the same angle. This will slow down the ramp */
    for (int rpt_angle = 1 ; rpt_angle <= 6 ; rpt_angle++) {
      trigger_triac_pls();
    }
  }

  digitalWrite(triac_ssr, HIGH);      //turn solid state relay permantly ON
  delay(500);
  digitalWrite(triac_rly_byp, HIGH) ; //turn on triacr bypass relay
  digitalWrite(led_ind, HIGH);        //Turn ON power led light indicator
  on_off_flag = 1;                    //Set flag to indicated the triac it is ON
  lcd.clear() ;
  lcd.setCursor(0, 0);
  lcd.print("Amplifier Power ON");
}
//*******************************************************************************************
void test_triac_pulse() {

  do {
    //do nothing
    tmp_var = digitalRead(ac_zero_x);
  } while (tmp_var == 0  );
  do {
    //do nothing
    tmp_var = digitalRead(ac_zero_x);
  } while (tmp_var == 1  );
  digitalWrite(triac_ssr, HIGH);   // sets the pin on
  delayMicroseconds(50);          // pulses width 50 microseconds
  digitalWrite(triac_ssr, LOW);    // sets the pin off
}
//**********************************************************************************************


This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.