Modulacion por espacio vectorial

¡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);
}

Para obtener las veces que no estoy usando interrupciones, estoy usando la función micros (), sospecho que podría ser el problema.

Explicate con mas detalle por favor.

Otra cosa, que Arduino usas?