Header image  
Electricidad, Electrónica, automatización industrial, láser, vacío  
line decor
    INICIO  || Traductor de idiomas ||
line decor
 
 
 
 

 
 

Fuente de intensidad usando un Arduino

Diseño de una fuente de intensidad usando partes recicladas y un simple arduino para hacerla automática y reprogramable a las necesidades de cada aplicación.

valorpwm = valorpwm + 1; // Si detecta intensidad menor a la ajustada, incrementa un paso el PWM.
// Si detecta intensidad mayor, entonces resta 1

Imagen
En la imágen del osciloscopio, lo verde es los pulsos PWM, y lo amarillo la intensidad, se ve una rampa de cerca de 10mS cuando se pone en marcha, y como se va a usar en una CNC, interesa que la rampa sea más pronunciada para que no se note diferente potencia en el inicio del corte.

También se aprecia que la regulación va y viene , no consigue estabilizar, en parte por que la resolución del PWM del arduino es de 8 bits (255 pasos), y solo estaba trabajando con un máximo de 120 pasos, para los 25 amperios que puede dar la fuente..
Detalle de las fluctuaciones por la regulación normal: (Amarilo intensidad)

Imagen

Entonces modificando el código y con una regulación proporcional a la diferencia del valor medido con el ajustado y multiplicado por un factor de 0.2 para este caso:

valorpwm = valorpwm + (ajustei - intensidad) * p;
// Si detecta intensidad menor a la ajustada, entonces incrementa la diferencia multiplicado por un valor "P" que es el parámetro proporcional (0.2 para el ejemplo).


Imagen

Se puede ver que la rampa es mucho mejor con cerca de 1ms de rampa. Y además ya no hay las fluctuaciones de funcionamiento en continuo. Aunque se ha pasado un poco al arrancar, ha subido un poco más para luego estabilizarse.

Ajustando mejor el parámetro proporcional a 0.1, y con menos tiempo por división para ver mejor la rampa:

Imagen


El programa tal y como funciona: (Se puede mejorar, es una primera versión que funciona para lo que necesito)


// Fuente de intensidad regulable y reciclada de una placa base de PC, por Alfon 22-02-2012
#include <LiquidCrystal.h>
  LiquidCrystal lcd(10, 9, 7, 6, 5, 4);

const int apvoltios = 0;
const int apintensidad = 1;
const int apajuste = 2;
const int apinput = 3;
const int oppwm = 11;
const int opmarcha = 12;

int voltios = 0, ajustei = 0, voltiosentrada = 0;       
int valorpwm = 0;       
int i, j;
float decimales, intensidad = 0;
int decimal;
long time = 0;
int limitesaturacion = 120;   // Limite saturación bobinas
float ajusteii;


// Opciones PID:
float p = 0.12;   // Proporcional , a 0.4 o más se dispara, a 0.1 ideal, a menos rampa lenta.
float clectura = 0.0 ;

void setup() {
  lcd.begin(8, 1);
  pinMode(oppwm, OUTPUT);
  pinMode(opmarcha, INPUT);
  analogWrite(oppwm, valorpwm);   // Desactiva PWM al enchufar, si surgen problemas entonces invertir la salida simple con un transistor npn
  setPwmFrequency(11, 1);    // Ajusta la frecuencia del PWM , llamada a la función
  lcd.setCursor(0,0);
}

void loop() {

if(digitalRead(opmarcha) == HIGH){
    intensidad = analogRead(apintensidad);
    voltios = analogRead(apvoltios);
    ajustei = map(analogRead(apajuste), 0, 1024, 0, 250);
    if((intensidad <= ajustei - 0.2 || intensidad >= ajustei + 0.2 ) && millis() > time + 500){   // Para no relentizar con la muestra en pantalla, y cada 0,5 segundos
      lcd.setCursor(0,0);
      lcd.print( "ON ");
      lcd.print((intensidad/10) - clectura);
      lcd.setCursor(7,0);
      lcd.print( "A");
      /* ajusteii = (ajustei - 6)/10;
      lcd.setCursor(14,0);
      lcd.print((ajustei - 6)/10);
      */
      time = millis();
    }
   
        if(intensidad <= ajustei  ){
               
                if(voltios < 1000){
                    valorpwm = valorpwm + (ajustei - intensidad) * p;
                    if(valorpwm > limitesaturacion){ valorpwm=limitesaturacion;}
                    analogWrite(oppwm, valorpwm);       
                }else{
                    // Error, valor de voltios superior a 4,7 aprox
                    digitalWrite(oppwm, LOW);
                    valorpwm = 0;
                   
                    lcd.setCursor(0,0);
                    lcd.clear();
                    lcd.print( "ER.S.C   ");
                    delay(100);
         
                  }
        }else{
            valorpwm = valorpwm - (intensidad - ajustei) * p;
            if(valorpwm < 0){ valorpwm = 0; }
            analogWrite(oppwm, valorpwm);
        }
      }else{
        valorpwm = 0;
        analogWrite(oppwm, valorpwm);
        ajustei = map(analogRead(apajuste), 0, 1024, 0, 250);
        lcd.setCursor(0,0);
        lcd.clear();
        lcd.print( "Off ");
        lcd.setCursor(4,0);
        lcd.print((ajustei/10));
        lcd.setCursor(7,0);
        lcd.print( "A");
        delay(100);
      }
 
}

/**
* Divides a given PWM pin frequency by a divisor.
*
* The resulting frequency is equal to the base frequency divided by
* the given divisor:
*   - Base frequencies:
*      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
*      o The base frequency for pins 5 and 6 is 62500 Hz.
*   - Divisors:
*      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
*        256, and 1024.
*      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
*        128, 256, and 1024.
*
* PWM frequencies are tied together in pairs of pins. If one in a
* pair is changed, the other is also changed to match:
*   - Pins 5 and 6 are paired on timer0
*   - Pins 9 and 10 are paired on timer1
*   - Pins 3 and 11 are paired on timer2
*
* Note that this function will have side effects on anything else
* that uses timers:
*   - Changes on pins 3, 5, 6, or 11 may cause the delay() and
*     millis() functions to stop working. Other timing-related
*     functions may also be affected.
*   - Changes on pins 9 or 10 will cause the Servo library to function
*     incorrectly.
*
* Thanks to macegr of the Arduino forums for his documentation of the
* PWM frequency divisors. His post can be viewed at:
*   http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/0#4
*/
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}


La parte final del código es una función para modificar la frecuencia del PWM de los arduino.

Volver al index