Forum: Gesperrte Threads Hilfe Triacs explodieren


von Tobi (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

also, wir möchten einen Phasenanschnittsteuerung über eine W4
Sparschaltung Realisieren, die es ermöglichen soll eine DAM im 1+4
Quadranten Sanft Hochlaufen zu lassen bzw. zu Reversieren. Gesteuert
wird das ganze über einen Poti mit 1024 Werten/Bits. Abhängig von den
Stellung des Ptotis wird eine Rampenfunktion für Alpha generiert und 
zwar so,
dass wenn der Poti in der Mittesteht (Potiwert 400-600) der Maschine
steht.

Potiwert 400->0 Linkslauf

Potiwert 400->600 Stillstand

Potiwert 600->1023 Rechtslauf.

Für sich genommen Funktionieren Linkslauf und Rechtslauf auch wunderbar,
das Problem entsteht erst wenn alle Programmteile zusammengefügt werden.
Hier kommt es zu einem Rütteln was auf Fehlzündungen hindeutet, bzw. 
auch schon zur Zerstörung Triacs geführt hat.

Im Stillstand werden alle Zündimpulse ausgeschaltet, zusätzlich alle
Timer und Comparewerte zurückgesetzt und zu guter letz die
Initialisierung wiederholt und auf Nummer sicherzugehen, da eine
Falsches Zünden der Triacs diese ja zerstören würde.
Der µC ist eine Atmega16.
Vielen Dank schonmahl für Anregungen und Tipps.

Quellcode.

/************************************PHASENANSCHNITTSTEUERUNG*********** 
***************************************

Microcontroller: ATMEGA2561
Clock: 16.0000MHz
AVR Hardware: Timer1, Timer3,
externe Hardware: W4-Reversiersparschaltung

//------------------------------------------------------------------
//
//                         PowerModul
//





#include <avr/io.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define  DDRT1  DDRG   //Datenrichtung für das W2 Stellglied
#define  DDRT2  DDRF
#define  DDRT3  DDRA
#define  DDRT4  DDRF



#define  PORTT1     PORTG
#define  PORTT2     PORTF
#define  PORTT3     PORTA
#define  PORTT4     PORTF



#define  T1   PG5  //rechts L1  Ausgangsbits für das W4 Stellglied
#define  T2   PF3  //rechts L3
#define  T3   PA2 //Links L3
#define  T4   PF1 // Links L1  Ausgangsbits für das W4 Stellglied




//********************************************************************** 
**********//POTI

uint16_t ADC_Wert;

//int ADC_Wert_min_R = 600;
//int ADC_Wert_max_R = 1023;



float alpha1=0;
float alpha2=0;

int alpha1_min=12777;
int alpha1_max=18888;

int alpha2_min=32777;
int alpha2_max=38888;


float alpha1_Aus =0;
float alpha2_Aus =0;

int alpha1_min_Aus =18888;
int alpha1_max_Aus =18888;

int alpha2_min_Aus =38888;
int alpha2_max_Aus =38888;


//********************************************************************** 
**********

//*************************************ADC****************************** 
**********

void AdcInit (void)
{
   ADMUX |= (0<<MUX0) | (0<<MUX1) | (1<<MUX2); //ADC4
   ADMUX |= (1<<REFS0); //externe Referenzspannung nutzen 5 V
  ADCSRA |=(1<<ADEN); //ADC überhaupt zu aktivieren.
   ADMUX |= (0<< ADLAR);   // Die 8 bit kommen in das Low-Register
  ADCSRA |=(1<<ADSC); //Messvorgang startet.
   ADCSRA |=(1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);//Vorteiler 128
}

uint16_t ADC_Lesen(void)
{
  uint16_t result = 0;

  ADCSRA |=(1<<ADEN);         //ADC aktivieren.
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
  while (ADCSRA & (1<<ADSC) );    // auf Abschluss der Konvertierung
warten

  ADCSRA &= ~(1<<ADEN);        // ADC wieder deaktivieren
  result = ADCW;
  return result;                  // ADC auslesen und zurückgeben
}

//********************************************************************** 
**********
//                               Funktionen
//********************************************************************** 
**********

// Initialisierung W2 Stellglied
// diese funktionen in main 1x aufrufen

/*****************************PORT-Initialisierung*****************/
void w4Init(void)
{

DDRD=0x00;  //Eingang Nulldurchgang

// Initialisierung Datenrichtung für das W2 Stellglied(als Äusgange
festgelegt)

DDRT1 |= (1<<T1); //DDRTn sind per (#define) definiert worden
DDRT2 |= (1<<T2);
DDRT3 |= (1<<T3);
DDRT4 |= (1<<T4);

PORTT1= 0x00; // PORTG high aktiv
PORTT2= 0x00; // PORTF high aktiv
PORTT3= 0x00; // PORTA high aktiv
PORTT4= 0x00; // PORTF high aktiv


//Ausgänge für LED initialisieren
DDRB |= (1<<PB1);//(1<<PB1) | (1<<PB2) | (1<<PB3);  // Ausprobieren ob
alle Led noch leuchten?????

}

/*****************************Initialisierung
Timer/Counter1*********************************/
void Timer1Init(void) {

//Timer Clock = CPU Clock / 8
   //Mode        = 0 (Normal)

//TCCR1B= 0x02;//TCCR1B |= (0<<CS10) | (1<<CS11)| (0<<CS12);// CPU Takt
/ 8
TCCR1B=0x00;  //stop Timer // Damit Timer bei 0 anfängt
TCCR1A= 0x00;  //normal Mode // Inkrementale Aufzählung

// Interrupts TimerCounter1 aktivieren
TIMSK1 |=(1<<OCIE1C) | (1<<OCIE1B) | (1<<OCIE1A) | (1<<TOIE1); //
TIMSK1=0b00001111;  //compare Register A B C

// Initialisierung Externe Interrupts / Nulldurchgangserkennung
// ND L12 //INT1 Ein = PORTD Pin 1

EIMSK |= (1<<INT1);  // EIMSK |= 0b00000010;  //enable INT1 // 0x01//
Damit wird INT1 aktiviert
EICRA |= (1<<ISC11) | (1<<ISC10); /*EICRA |= 0b00001100//0x0c;
//00000011
                                 rising; 0x04 anyEdge // INT1 reagiert
auf steigende Flanke*/


TCNT1 = 0; // Timer1 auf Null setzen

OCR1C=7222;
TCCR1B= 0x02;  //Vorteiler 8  //start Timer

}
/*****************************Initialisierung
Timer/Counter4*********************************/
void Timer4Init(void) {

TCCR4B=0x00;  //stop Timer // Damit Timer bei 0 anfängt
TCCR4A= 0x00;  //normal Mode // Inkrementale Aufzählung

// Interrupts TimerCounter1 aktivieren
TIMSK4 |= (1<<OCIE4B) | (1<<OCIE4A) | (1<<TOIE4); // TIMSK1=0b00001111;
//compare Register A B

// Initialisierung Externe Interrupts / Nulldurchgangserkennung
// ND L12 //INT1 Ein = PORTD Pin 1

EIMSK |= (1<<INT1);  // EIMSK |= 0b00000010;  //enable INT1 // 0x01//
Damit wird INT1 aktiviert
EICRA |= (1<<ISC11) | (1<<ISC10); /*EICRA |= 0b00001100//0x0c;
//00000011
                                 rising; 0x04 anyEdge // INT1 reagiert
auf steigende Flanke*/

TCNT4 = 0; // Timer1 auf Null setzen

TCCR4B= 0x02;  //Vorteiler 8  //start Timer

}
/*****************************Initialisierung
Timer/Counter3*********************************/
void Timer3Init(void) {

TCCR3B=0x00;  //stop Timer // Damit Timer bei 0 anfängt
TCCR3A= 0x00;  //normal Mode // Inkrementale Aufzählung

// Interrupts TimerCounter1 aktivieren
TIMSK3 |= (1<<OCIE3B) | (1<<OCIE3A) | (1<<TOIE3); // TIMSK1=0b00001111;
//compare Register A B


TCNT3 = 0; // Timer3 auf Null setzen//

TCCR3B= 0x02;  //Vorteiler 8  //start Timer

}
/*****************************Initialisierung
Timer/Counter5*********************************/
void Timer5Init(void) {

TCCR5B=0x00;  //stop Timer // Damit Timer bei 0 anfängt
TCCR5A= 0x00;  //normal Mode // Inkrementale Aufzählung

// Interrupts TimerCounter1 aktivieren
TIMSK5 |= (1<<OCIE5B) | (1<<OCIE5A) | (1<<TOIE5); // TIMSK1=0b00001111;
//compare Register A B

TCNT5 = 0; // Timer1 auf Null setzen

TCCR5B= 0x02;  //Vorteiler 8  //start Timer

}

/******************************EXTERNER Interrupt*****************/

ISR (INT1_vect)   //INT1 hinter RESET höchste Priorität
//Netzsynchronisation
{                    // wird jedesmal aufgerufen wenn der Netznullgang
kommt

 alphawerteInterrupt1();

}//ISR(INT1_vect)



/***************************ZÜNDMUSTER_RECHSTSLAUF ********************/

ISR (TIMER1_COMPA_vect)
{

   zuendmustereinL1();           //positive Halbwelle  //zuendEinL1();

}

ISR (TIMER1_COMPB_vect)
{

  zuendmustereinL1();            //Negative Halbwelle  //zuendEinL1();


}


ISR (TIMER1_COMPC_vect)

{

alphawertetimer1compC();

}//ISR_timer1_compC



ISR (TIMER4_COMPA_vect)
{

   zuendmusterausL1();  //positive Halbwelle   //zuendAusL1();

}

ISR (TIMER4_COMPB_vect)
{

   zuendmusterausL1();  //Negative Halbwelle    //zuendAusL1();

}

ISR (TIMER3_COMPA_vect)
{

   zuendmustereinL3();   //positive Halbwelle   //zuendEinL3();


}

ISR (TIMER3_COMPB_vect)
{

   zuendmustereinL3();   //Negative Halbwelle    //zuendEinL3();


}

ISR (TIMER5_COMPA_vect)
{

   zuendmusterausL3();  //Positive Halbwelle   //zuendAusL3();

}

ISR (TIMER5_COMPB_vect)
{

   zuendmusterausL3();  //Negative Halbwelle    //zuendAusL3();

}



//********************************INITIALISIERUNG*******************
void Init()
{
  w4Init();
  Timer1Init();
  Timer4Init();
  Timer3Init();
  Timer5Init();
  AdcInit();

}

//*****************************HAUPT-PROGRAMM********************/
int main() {



               cli();  //disable Interrupts
               Init();
              sei();  //alles initialisiert

              while(1) {

              ADC_Wert= ADC_Lesen();

                 }



          }

/****************************************************Funktionen********* 
****************************************************/



void zuendungaus(void)
{
   Init();

   PORTT1  &= ~ (1<<T1);  //triac  für rechtslauf auf low setzten
//zuendAusL1();
   PORTT2  &= ~ (1<<T2);  //triac  für rechtslauf auf low setzten
//zuendAusL3();
   PORTT3  &= ~ (1<<T3);  //triac  für Linkslauf auf low setzten
//zuendAusL3();
   PORTT4  &= ~ (1<<T4);  //triac  für Linkslauf auf low setzten
//zuendAusL1();

   TCNT1= 0;
   OCR1A= 0;
   OCR1B= 0;
   TCNT4= 0;
   OCR4A= 0;
   OCR4B= 0;
   //-----------------------------------------------------------------
   TCNT3= 0;
   OCR3A= 0;
   OCR3B= 0;
   TCNT5= 0;
   OCR5A= 0;
   OCR5B= 0;


}//Zuendungaus


void alphawerteInterrupt1(void)
{

if ((ADC_Wert >= 600) && (ADC_Wert <= 1023))
  {

     if ((ADC_Wert >= 1013) && (ADC_Wert <= 1023))
     {

      vollsteuerungL1 ();

     }//if//vollsteuerung//rechtslauf



        if ((ADC_Wert >= 600) && (ADC_Wert < 1013))
     {

     alpha1=(((alpha1_min - alpha1_max)/(1013-600))* (ADC_Wert-600))+
alpha1_max; //rechtslauf();
       alpha2=(((alpha2_min - alpha2_max)/(1013-600))* (ADC_Wert-600))+
alpha2_max;

       TCNT1= 0; // Timer1 wird bei Nulldurchgang auf null gesetzt
     OCR1A=alpha1 ;
       OCR1B=alpha2;
       //-----------------------------------------
    alpha1_Aus=(((alpha1_min_Aus - alpha1_max_Aus)/(1013 - 600))*
(ADC_Wert - 600))+ alpha1_max_Aus;
    alpha2_Aus=(((alpha2_min_Aus - alpha2_max_Aus)/(1013 - 600))*
(ADC_Wert - 600))+ alpha2_max_Aus;


       TCNT4= 0; // Timer4 wird bei Nulldurchgang auf null gesetzt
     OCR4A= alpha1_Aus; //18888;
       OCR4B= alpha2_Aus; //38888;

     }

     }//if//rechtslauf


         if ((ADC_Wert >= 0) && (ADC_Wert <= 400))
         {

        if ((ADC_Wert >=0) && (ADC_Wert <= 10))
            {

             vollsteuerungL1 ();

            }//if//vollsteuerung//linkslauf

              if ((ADC_Wert > 10) && (ADC_Wert <= 400))
             {
              alpha1=(((alpha1_max - alpha1_min)/(400-10))* ADC_Wert)+
alpha1_min;  //linkslauf();
              alpha2=(((alpha2_max - alpha2_min)/(400-10))* ADC_Wert)+
alpha2_min;

             TCNT1= 0; // Timer1 wird bei Nulldurchgang auf null gesetzt
            OCR1A=alpha1 ;
              OCR1B=alpha2;
            //---------------------------------------

        alpha1_Aus=(((alpha1_max_Aus - alpha1_min_Aus)/(400 - 10))*
(ADC_Wert - 10))+ alpha1_min_Aus;
        alpha2_Aus=(((alpha2_max_Aus - alpha2_min_Aus)/(400 - 10))*
(ADC_Wert - 10))+ alpha2_min_Aus;

            TCNT4= 0; // Timer4 wird bei Nulldurchgang auf null gesetzt
            OCR4A= alpha1_Aus; //18888;
              OCR4B= alpha2_Aus; //38888;

              }

          }//if//Linkslauf

            if ((ADC_Wert > 400) && (ADC_Wert < 600))
            {

             zuendungaus();

            }//if//Zuendungaus



}//alphawerteInterrupt1


void alphawertetimer1compC(void)
{

  if ((ADC_Wert >= 600) && (ADC_Wert <= 1023))
  {

   if ((ADC_Wert >= 1013) && (ADC_Wert <= 1023))
   {

    vollsteuerungL3 ();

   }//if//vollsteuerung//rechtslauf

      if ((ADC_Wert >= 600) && (ADC_Wert < 1013))
     {

     alpha1=(((alpha1_min - alpha1_max)/(1013-600))* (ADC_Wert-600))+
alpha1_max; //rechtslauf();
       alpha2=(((alpha2_min - alpha2_max)/(1013-600))* (ADC_Wert-600))+
alpha2_max;



       OCR3A=alpha1;
       OCR3B=alpha2;
        //----------------------------------------------------------
    alpha1_Aus=(((alpha1_min_Aus - alpha1_max_Aus)/(1013 - 600))*
(ADC_Wert - 600))+ alpha1_max_Aus;
    alpha2_Aus=(((alpha2_min_Aus - alpha2_max_Aus)/(1013 - 600))*
(ADC_Wert - 600))+ alpha2_max_Aus;

       OCR5A= alpha1_Aus; //18888;
       OCR5B= alpha2_Aus; //38888;

        }

     }//if//rechtslauf


        if ((ADC_Wert >= 0) && (ADC_Wert <= 400))
        {

         if ((ADC_Wert >=0) && (ADC_Wert <= 10))
               {

                  vollsteuerungL3 ();

               }//if//vollsteuerung//linkslauf

           if ((ADC_Wert > 10) && (ADC_Wert <= 400))
                 {
              alpha1=(((alpha1_max - alpha1_min)/(400-10))* ADC_Wert)+
alpha1_min;  //linkslauf();
              alpha2=(((alpha2_max - alpha2_min)/(400-10))* ADC_Wert)+
alpha2_min;

           TCNT3= 0; // Timer3 wird nach 3,33ms (60°) auf null gesetzt
             OCR3A=alpha1;
             OCR3B=alpha2;
              //------------------------------------------------------------------
          alpha1_Aus=(((alpha1_max_Aus - alpha1_min_Aus)/(400 - 10))*
(ADC_Wert - 10))+ alpha1_min_Aus;
          alpha2_Aus=(((alpha2_max_Aus - alpha2_min_Aus)/(400 - 10))*
(ADC_Wert - 10))+ alpha2_min_Aus;

              TCNT5= 0; // Timer5 wird nach 3,33ms (60°) auf null
gesetzt
             OCR5A= alpha1_Aus; //18888;
             OCR5B= alpha2_Aus; //38888;

          }

        }//if//Linkslauf

              if ((ADC_Wert > 400) && (ADC_Wert < 600))
              {

               zuendungaus();

              }//if//Zuendungaus

}//alphawertetimer1compC



void zuendmustereinL3(void)
{
                           if ((ADC_Wert >= 0) && (ADC_Wert <= 400))
                {
                    PORTT2  &= ~ (1<<T2);
//?????????????????????????????????
                         PORTT3 |= (1<<T3);   //triac für Linkslauf
zünden //zuendEinL3();
                         PORTB  &= ~(1<<PB1);   // Grüne Led geht an
//linkslauf();

                }

                if ((ADC_Wert > 400) && (ADC_Wert < 600))
                {
                  zuendungaus();

                }

                if ((ADC_Wert >= 600) && (ADC_Wert <= 1023))

                {
                                PORTT3  &= ~
(1<<T3);//???????????????????????????????
                   PORTT2 |= (1<<T2);   //triac für rechtslauf zünden
//zuendEinL3();
                         PORTB  &= ~(1<<PB1);   // Grüne Led geht
an//rechtslauf();

                }

}

void zuendmusterausL3(void)
{

                            if ((ADC_Wert >= 0) && (ADC_Wert <= 400))
                {
                 PORTT3  &= ~ (1<<T3);  //triac  für Linkslauf auf low
setzten //zuendAusL3();//linkslauf();

                }

                if ((ADC_Wert > 400) && (ADC_Wert < 600))
                {
                  zuendungaus();

                }

                if ((ADC_Wert >= 600) && (ADC_Wert <= 1023))
                {
                 PORTT2  &= ~ (1<<T2);  //triac  für rechtslauf auf low
setzten //zuendAusL3();//rechtslauf();

                }

}

void zuendmustereinL1(void)
{

                            if ((ADC_Wert >= 0) && (ADC_Wert <= 400))
                {

                PORTT1  &= ~ (1<<T1);//???????????????????????????????
                PORTT4 |= (1<<T4);    //triac für Linkslauf zünden
//zuendEinL1();
                         PORTB  &= ~(1<<PB1);   // Grüne Led geht an
//linkslauf();

                }

                if ((ADC_Wert > 400) && (ADC_Wert < 600))
                {
                  zuendungaus();

                }

                if ((ADC_Wert >= 600) && (ADC_Wert <= 1023))
                {
                    PORTT4  &= ~ (1<<T4);
//????????????????????????????????????????ß
                 PORTT1 |= (1<<T1);    //triac für rechtslauf zünden
//zuendEinL1();
                         PORTB  &= ~(1<<PB1);   // Grüne Led geht an
//rechtslauf();

                }

}

void zuendmusterausL1(void)
{

                            if ((ADC_Wert >= 0) && (ADC_Wert <= 400))
                {

                      PORTT4  &= ~ (1<<T4);  //triac  für Linkslauf auf
low setzten //zuendAusL1();//linkslauf();

                }

                if ((ADC_Wert > 400) && (ADC_Wert < 600))
                {
                  zuendungaus();

                }

                if ((ADC_Wert >= 600) && (ADC_Wert <= 1023))
                {
                 PORTT1  &= ~ (1<<T1);  //triac  für rechtslauf auf low
setzten //zuendAusL1();//rechtslauf();

                }

}

void vollsteuerungL1 (void){

                             TCNT1= 0;
                  OCR1A= 2777;
                  OCR1B= 22777;
                  TCNT4= 0;
                  OCR4A= 0;
                  OCR4B= 0;


               }



void vollsteuerungL3 (void){

                           TCNT3= 0;
                  OCR3A= 2777;
                  OCR3B= 22777;
                  TCNT5= 0;
                  OCR5A= 0;
                  OCR5B= 0;

               }

: Verschoben durch Admin
von Falk B. (falk)


Lesenswert?

@  Tobi (Gast)

>    * W4_schaltung.aps (3,3 KB, 7 Downloads)

>Vielen Dank schonmahl für Anregungen und Tipps.

Lies mal was über Netiquette und Bildformate. Lange Quelltexte 
gehören in den Anhang! .aps kennt kaum jemand.

MFG
Falk

von Floh (Gast)


Lesenswert?

Vor allem, da .aps eine Projektdatei ist.
Da ist kein Quellcode enthalten!

Schaltplan wäre auch nett, nicht jedem sagt w4 Sparschaltung was.

von Fred (Gast)


Lesenswert?

Schau mal da explodiert nix:

Beitrag "Hilfe Triacs explodieren"


Zeig mal ein Bild vom explodierten Triac, Video wäre natürlich noch 
besser.

von Peter D. (peda)


Lesenswert?

Floh schrieb:
> nicht jedem sagt w4 Sparschaltung was.

Google meint dazu:

Sparschaltung an WC-Spülungen W4/W5

Und bei DAM:

http://www.dam-germany.de/

Peter

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Bitte langer Quellcode in den Anhang.

Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.