¡Hola!
Estoy desarrollando un sistema Invertec con arduino nano, disparando 6 módulos IGBT, directamente con el puerto del arduino (a través de un controlador apropiado) y obteniendo tres fases.
Para obtener los valores de temporización para disparar los IGBT, utilizo la modulación de espacio vectorial. Significa dividir el ciclo en 6 sectores y, según el sector, usar dos configuraciones de estado para los IGBT "va" y "vb", después de eso, de acuerdo con el grado en que debe ir el fasor, arduino establece el tiempo de cada configuración.
Obtengo la rotación de un motor de jaula de ardilla con el único problema de obtener una fase con menos corriente y menos voltaje.
Para obtener las veces que no estoy usando interrupciones, estoy usando la función micros (), sospecho que podría ser el problema.
Sin embargo, mi cabeza sola no puede ver el problema. por lo tanto, pondré el código aquí para recibir alguna pista sobre lo que podría estar causando este comportamiento. Gracias
int fault_r = A2;
int fault_s = A1;
int fault_t = A0;
int reset_r = A5;
int reset_s = A4;
int reset_t = A3;
int pot = A7;
int Q1 = 2;
int Q2 = 3;
int Q3 = 4;
int Q4 = 5;
int Q5 = 6;
int Q6 = 7;
int interruptor = 9;
int voltaje_nominal = 380;
int frecuencia_nominal = 50;
int Vll = 380;
int v_link = 536;
float k_motor = 1.0;
int frecuencia = 1;
unsigned long microInterval = 2000;
unsigned long t_switching = 4000;
unsigned long currentMicros = micros();
unsigned long previousMicros = 0;
unsigned long t_onda;
unsigned long n_intervalos;
int vectoresXonda;
int v_freq;
long ta;
long tb;
long tc;
long tu;
int va;
int vb;
volatile unsigned long contador = 0;
volatile unsigned long cont_intervalo = 0;
volatile unsigned long offset = 0;
volatile int sector = 1;
int grado_actual;
int gradosXvector;
int antiguo_contador;
int copia_intervalo;
int detenerse = 0;
int vector_contador;
int freno = 0;
uint16_t isinTable8[] = { // sin(x)*1000
0, 17, 34, 52, 69, 87,104,121,139,156,173, // 0 - 10
190,207,224,241,258,275,292,309,325,342, // 11 - 20
358,374,390,406,422,438,453,469,484,500, // 21 - 30
515,529,544,559,573,587,601,615,629,642, // 31 - 40
656,669,681,694,707,719,731,743,754,766, // 41 - 50
777,788,798,809,819,829,838,848,857,866, // 51 - 60
};
int lectura;
int contador_lecturas = 0;
unsigned long acumulador_lecturas;
int acumulador_frecuencia = 0;
int frecuencia_candidata = 0;
int frecuencia_aux = 0;
int encendido = 0;
void setup(void)
{
Serial.begin(115200);
setup_pines();
fallas();
}
void loop(void)
{
encendido = on_off();
if (encendido){
frecuencia = 1;
actualiza_frecuencia();
contador = 1;
vector_contador = 0;
offset = 0;
actualiza_grado();
actualiza_tiempos();
actualiza_vector();
while( encendido ){
if (fallas()){
estado_igbt(0);
break;
}
manejo_vectorial2();
encendido = on_off();
}
}
}
}
int on_off(){
if ( lectura_interruptor() == 0 && encendido == 0 ){
int verifica= 0;
for (int i = 0; i < 10; i++){
if (lectura_interruptor() == 0 ){
verifica++;
}
}
if (verifica >= 9 ){
encendido = 1;
return 1;
}
} else if ( lectura_interruptor() == 1 && encendido == 1 ){
int verifica= 0;
for (int i = 0; i < 10; i++){
if (lectura_interruptor() == 1 ){
verifica++;
}
}
if (verifica >= 9 ){
encendido = 0;
return 0;
}
}
return encendido;
}
int lectura_interruptor(){
return digitalRead(interruptor);
}
void manejo_vectorial2(){
currentMicros = micros();
unsigned long microstep = 0;
if (contador == 1 ){
microstep = tc;
}
else if (contador == 4 || contador == 5 || contador == 8 ) {
microstep = tc;
}
else if ( contador == 2 || contador == 7){
microstep = ta;
}
else if ( contador == 3 || contador == 6){
microstep = tb;
}
if (currentMicros - previousMicros >= microstep) {
contador++;
if (contador >= 9)
{
contador = 1;
vector_contador++;
actualiza_frecuencia();
actualiza_grado();
actualiza_tiempos();
}
control_igbt(); // out to igbts
if (contador == 4) lectura_usuario();
previousMicros = currentMicros;
}
}
void lectura_usuario(){
if (contador_lecturas < 25) {
lectura = analogRead( pot );
acumulador_lecturas += lectura;
contador_lecturas++;
}
else {
lectura = analogRead( pot );
contador_lecturas = 0;
frecuencia_aux = acumulador_lecturas /500;
acumulador_lecturas = 0;
if (frecuencia_aux == frecuencia_candidata ){
acumulador_frecuencia++;
if ( acumulador_frecuencia >= 10 ){
if ( frecuencia != frecuencia_candidata){
if ( frecuencia < frecuencia_candidata) frecuencia++;
if ( frecuencia > frecuencia_candidata) frecuencia--;
if (frecuencia == 0 ) frecuencia =1;
Serial.println(frecuencia);
acumulador_frecuencia = 0;
}
}
}
else {
frecuencia_candidata = frecuencia_aux;
acumulador_frecuencia = 0;
}
}
}
void control_igbt( ){
if ( contador == 2 || contador == 7) estado_igbt(va);
else if ( contador == 3 || contador == 6) estado_igbt(vb);
else if ( contador == 4 || contador == 5) estado_igbt(7);
else if ( contador == 1 || contador == 8) estado_igbt(0);
}
void actualiza_frecuencia(){
t_onda = 1000000/frecuencia;
n_intervalos = t_onda/ t_switching;
vectoresXonda = n_intervalos ;
gradosXvector = 360/vectoresXonda;
v_freq = k_motor*frecuencia;
tu= map(v_freq,1,v_link,10,microInterval-40);
}
void actualiza_grado(){
grado_actual = gradosXvector*vector_contador + offset;
if (grado_actual > 60){
vector_contador = 0;
offset = grado_actual%60;
sector = sector + grado_actual/60;
grado_actual = offset;
if ( sector >= 7 ) sector = 1;
actualiza_vector();
}
}
void actualiza_tiempos(){
ta = map( ( isinTable8[60 - grado_actual] ),0,1000,0,tu);
tb = map( ( isinTable8[60] ),0,1000,0,tu);
tc = ( microInterval -( ta + tb ) );
}
void actualiza_vector(){
switch (sector){
case 1:
va = 1; // 001
vb = 3; // 011
break;
case 2:
va = 2; // 010
vb = 3; // 011
break;
case 3:
va = 2; // 010
vb = 6; // 110
break;
case 4:
va = 4; // 100
vb = 6; // 110
break;
case 5:
va = 4; // 100
vb = 5; // 101
break;
case 6:
va = 1; // 001
vb = 5; // 101
break;
}
}
void estado_igbt( int ig ){
switch ( ig ){
case 7:
PORTD= B00011100; // 111
break;
case 6:
PORTD= B00111000; // 110
break;
case 5:
PORTD= B01010100; // 101
break;
case 4:
PORTD= B01110000; // 100
break;
case 3:
PORTD= B10001100; // 011
break;
case 2:
PORTD= B10101000; // 010
break;
case 1:
PORTD= B11000100; // 001
break;
case 0:
PORTD= B11100000; // 000
break;
}
}
void resetear(){
digitalWrite(reset_r,LOW);
digitalWrite(reset_s,LOW);
digitalWrite(reset_t,LOW);
delay(100);
digitalWrite(reset_r,HIGH);
digitalWrite(reset_s,HIGH);
digitalWrite(reset_t,HIGH);
}
int fallas(){
if (falla()){
if (falla()){
return 1;
}
else return 0;
}
else return 0;
}
int falla(){
if (digitalRead(fault_r) == 0 || digitalRead(fault_s) == 0 || digitalRead(fault_t) == 0) return 1;
else return 0;
}
void setup_pines(){
pinMode(fault_r, INPUT);
pinMode(fault_s, INPUT);
pinMode(fault_t, INPUT);
pinMode(reset_r, OUTPUT);
pinMode(reset_s, OUTPUT);
pinMode(reset_t, OUTPUT);
// reset active in LOW
digitalWrite(reset_r,HIGH);
digitalWrite(reset_s,HIGH);
digitalWrite(reset_t,HIGH);
pinMode(pot , INPUT);
pinMode(interruptor, INPUT_PULLUP);
pinMode(Q1, OUTPUT);
pinMode(Q2, OUTPUT);
pinMode(Q3, OUTPUT);
pinMode(Q4, OUTPUT);
pinMode(Q5, OUTPUT);
pinMode(Q6, OUTPUT);
}