Forum: Mikrocontroller und Digitale Elektronik Benötigte Leistung berechnen von einem veränderlichen Rechtecksignal


von Hasanovic (Gast)


Angehängte Dateien:

Lesenswert?

Hallo !

Habe einen ADuC841 µC mit dem ich einen Transistor konstant auf 34 grad 
halten will. Und durch gewollte Einflüsse (kälter/wärmer) verändert sich 
die Temperatur des Transistors. Meine Aufgabe besteht darin die 
Temperatur konstant auf 34 grad zu halten und die Leistung dafür zu 
berechnen.
Unser einziges Problem ist noch die Berechnung der Leistung.

Das Rechecksignal ändert sich durch die Einflüsse je nach Kälte und 
Wärme. Ist der Transistor kälter so muss geheizt => mehr leistung nöitg

Es sollte eine Momentan- und Gesamtleistung ausgegeben werden.

Mein erster Versuch funktioniert nicht.
Und zwar wurde immer die letzte positive Flanke gemerkt und bei der 
nächsten positiven Flanke berechnet.

Hier mal der Code:

if(ADC_Wert <= limit) // Im Limit steht der "Spannungswert für 34 grad" 
in HEX
{

P20 = 0x00; // nicht heizen
letztes_null = 1; // letzte positive flanke
}
else
{
P20 = 0xFF; // heizen


if (letztes_null == 1)
{
Prozentwert =((durchgaenge_eins * 10) / durchgaenge) * 100;
durchgaenge_gesamt += durchgaenge;
durchgaenge_eins_gesamt += durchgaenge_eins;
Prozentwert_gesamt = ((durchgaenge_eins_gesamt* 10) / 
durchgaenge_gesamt)*100 ;
durchgaenge_gesamt = 0;
durchgaenge_eins_gesamt =0;

letztes_null = 0;
durchgaenge_eins = 0;
durchgaenge = 0;
}

durchgaenge_eins++;


}durchgaenge++;


Es sollen die Durchgänge gemerkt werden und somit die Leistung berechnet 
werden. Doch meine Idee funktioniert nicht.

Ich hoffe jemand kann mir helfen.

Code auch als textdokument bereitgestellt zur besseren Übersicht

LG

von Matthias L. (Gast)


Lesenswert?

Bevor du hier Code dastellst, den keiner nachvollziehen kann, weil 
keiner eine Schaltung hat,

solltest du lieber zuerst erklären, wie du erkennst/misst, dass der 
Transistor zu kalt/warm ist?

Weiterhin ist unklar, wie du den Transistor heizen willst! Oder soll nur 
in einer Variablen die erforderliche (momentane) Heizleistung ermittelt 
werden, also zB in Watt. ?

Oder soll der Transistor gleich geheizt werden?

Was macht das Rechttecksignal? Wo kommt es her? Wer erzeugt es? Was tut 
es?

Offensichtlihc nutzt du den ADC. Für was? Was kommt da rein? Wie sind 
diese ADC-Wert skaliert??

von Karl H. (kbuchegg)


Lesenswert?

Hasanovic schrieb:

> Das Rechecksignal ändert sich durch die Einflüsse je nach Kälte und
> Wärme.

Klingt für mich stark nach PWM?

> Ist der Transistor kälter so muss geheizt => mehr leistung nöitg

Das bedeutet für das Rechtecksignal dann was?

von Hasanovic (Gast)


Lesenswert?

Durch eine konstantstromquelle fließt ein fixer Strom über den 
Transistor, hierbei entsteht eine Temperatur abhänige Ube. Diese wird 
mittels ADC eingelesen und mit dem Fixen-Wert (bei 34 Grad C) 
verglichen.

z.B.

Kühlt der Transistor auf 32 grad ab. Der µC erkennt dies durch die Ube 
und schaltet den port ein => transistor heizt.
Durch das Ständige heizen und abkühlen entsteht das Rechtecksignal, aus 
dem ich die Leistung errechnen will.

Bei einer kalten Umgebung wird der Transistor sich also öfter auf 34 
Grad erhitzen müssen, bzw er braucht mehr Leistung um die 34 Grad zu 
halten. Die folge ist das die Heizphasen größer sind als die 
Abkühlphasen.
Beim Rechtecksignal wird also bei öfterem Heizen, der positive Puls(1) 
länger werden als die Pause(0).

Durch dieses Puls/Pause Verhältnis muss ich die Leistung errechnen. Da 
die Periodendauer der Puls/Pause sich immer verändert, fällt es mir 
schwer, dies zu realisieren.

Ja, Leistungserrechnung in Watt bzw mW. Spannung 5V , Strom 200mA -> bei 
100 % 1 Watt in einer Periode.

ja, der Transistor wird sofort geheizt wenn das Programm erkennt das die 
Temperatur unter 34 Grad fällt.

zb. ADC Werte werden in Hex eingelesen zb 350 h. Der vergleichs Wert ist 
36e. D.h der Transistor ist zu heiß und er kühlt ab.

mfg

von Karl H. (kbuchegg)


Lesenswert?

Hasanovic schrieb:

> ja, der Transistor wird sofort geheizt wenn das Programm erkennt das die
> Temperatur unter 34 Grad fällt.

Und diese Erkennung erfolgt in regelmässigen Zeitintervallen?`

Wenn ja:

Du hast 2 Variablen:
  eine für die Gesamtzahl der ADC Messungen
  und eine für die Anzahl der Messungen, bei denen der ADC zu niedrig
  war und daher die Heizung eingeschaltet werden muss.

Die Gesamtzahl wird bei jeder ADC Messung um 1 erhöht, die andere nur 
dann, wenn die Heizung aufgrund des ADC Wertes auch eingeschaltet werden 
muss.

Das Verhältnis der beiden Zahlen sagt dir dann mit wievielen % die 
Heizung eingeschaltet war und da du die Leistungsaufnahme bei 100% 
kennst, kannst du auch die Aufnahme für diese x % ausrechnen

Das ganz ist dann natürlich Zeitdiskret, aber solange die Messung nur 
oft genug sollte der Wert ziemlich gut sein.

Nach 1 Sekunde oder so (abhängig davon, wie oft du den ADC abfragst), 
wertest du die Zähler aus und setzt beide wieder auf 0 - der nächste 
Messzyklus hat begonnen.


Edit:
Also im Prinzip das was du sowieso schon machst.
Nur darfst du das natürlich nicht davon abhängig machen (ja wovon hast 
du das eigentlich in deinem Code abhängig gemacht?), sondern du musst es 
immer machen
1
  durchgaenge++;
2
  if(ADC_Wert <= limit) // Im Limit steht der "Spannungswert für 34 grad" in HEX
3
  {
4
    P20 = 0x00; // nicht heizen
5
  }
6
  else
7
  {
8
    P20 = 0xFF; // heizen
9
    durchgaenge_eins++;
10
  }
11
12
  if( durchgaenge == 100 )    // zb nach jeweils 100 ADC Messungen
13
  {
14
    Prozentwert = ((durchgaenge_eins * 10) / durchgaenge) * 100;
15
16
    durchgaenge = 0;
17
    durchgaenge_eins = 0;
18
  }

von Andreas (Gast)


Lesenswert?

Karl heinz Buchegger schrieb:

Edit:
Also im Prinzip das was du sowieso schon machst.
Nur darfst du das natürlich nicht davon abhängig machen (ja wovon hast
du das eigentlich in deinem Code abhängig gemacht?), sondern du musst es
immer machen

Wie meinst du das, ich darf das natürlich nicht abhängig machen, wovon 
abhängig?


Ja der adc wird so ca alle 200ms gestartet. Dann wird ausgewertet und 
das Berechnugnsbrogramm wird dann gestartet und hier wird dan aus und 
eingeschlaten, dies macht er so 500 mal, das lang genug 
eingeschlaten/bzw ausgeschlaten wird.

if( durchgaenge == 100 )    // zb nach jeweils 100 ADC Messungen
  {
    Prozentwert = ((durchgaenge_eins * 10) / durchgaenge) * 100;

    durchgaenge = 0;
    durchgaenge_eins = 0;
  }

Diese Methode macht im Prinzip ja das gleiche nur über eine längeren 
Bereich, so wie ich das jetzt verstehe.

Hierbei war das problem, das diese Werte sich eher auf die Momentane 
Leistung beziehen. Darum hab ich versucht mittels :

durchgaenge_gesamt += durchgaenge;
durchgaenge_eins_gesamt += durchgaenge_eins;

Proz_gesamt = ((durchgaenge_eins_gesamt* 10) / durchgaenge_gesamt)*100 ;

Einen Mittelwert der Gesamten Leistung zu errechnen, aber da machte nach 
einer gewissen Zeit, ca 2 sec, wahrscheinlich der Speicherplatz nicht 
mit, da sich das Programm dan von selbst neugestartet hat.

-----------

Eine andere Überlegung war jz bei: der schleife 2 Timer zu starten

if(ADC_Wert <= limit)
  {
    P20 = 0x00; // nicht heizen
    TR2 =0:     // Timer2 off

  }
  else
  {
    TR1 =0;       //Timer1 off so das ein wert drin steht
    Wert = (TH1 * 0xFF) | TL1     //In wert steht dann der wert des 
Timers
    P20 = 0xFF; // heizen
    TR1 =1;     // Timer1 on
    TR2 =1;     // Timer2 on
  }

Der Timer 1 läuft von der Positiven Flanke bis zur nächten positiven 
Flanke. Der Timer 2 jedoch nur von der positiven Flanke bis zum Ende 
dieser Flanke. Die Differenz ist dan der % wert der leistung.

mfg

von Karl H. (kbuchegg)


Lesenswert?

Andreas schrieb:

> Also im Prinzip das was du sowieso schon machst.
> Nur darfst du das natürlich nicht davon abhängig machen (ja wovon hast
> du das eigentlich in deinem Code abhängig gemacht?), sondern du musst es
> immer machen
>
> Wie meinst du das, ich darf das natürlich nicht abhängig machen, wovon
> abhängig?

Ich war zu faul, da jetzt grossartig zu analysieren was es mit dem 
letztes_null auf sich hat und was das für den Code bedeutet.


> Diese Methode macht im Prinzip ja das gleiche nur über eine längeren
> Bereich, so wie ich das jetzt verstehe.

Im Grunde ja.
Ob länger oder kürzer kann ich nicht sagen. Ich hab im Originalcode 
nicht mehr nachverfolgt, wie sich die Sache mit letztes_null verhält.


> Proz_gesamt = ((durchgaenge_eins_gesamt* 10) / durchgaenge_gesamt)*100 ;
>
> Einen Mittelwert der Gesamten Leistung zu errechnen, aber da machte nach
> einer gewissen Zeit, ca 2 sec, wahrscheinlich der Speicherplatz nicht
> mit,

Das ist quatsch.
Du brauchst ja deswegen auch nicht mehr Speicher. Aber irgendwann ist es 
natürlich so, dass die Zahlen zu groß werden und überlaufen (BTW: du 
hast keine Datentypen angegeben). Wenn dann zufällig durchgaenge_gesamt 
durch den Überlauf auf 0 geht oder durchgaenge_gesamt kleiner als 
durchgaenge_eins_gesamt wird, dann kann alles mögliche passieren.

> da sich das Programm dan von selbst neugestartet hat.

Ist unwahrscheinlich. Ein Rechenproblem (durch Überläufe) führt nicht zu 
einem Neustart. Da ist dann noch ein anderes Problem vorhanden.

Du könntest natürlich auch ganz einfach über die letzten 10 (allgemeiner 
x) Prozentwerte einen Mittelwert bilden. Denk dir was aus. Aber achte 
darauf, dass dir keine Summierungen überlaufen.

> Der Timer 1 läuft von der Positiven Flanke bis zur nächten positiven
> Flanke. Der Timer 2 jedoch nur von der positiven Flanke bis zum Ende
> dieser Flanke. Die Differenz ist dan der % wert der leistung.

Ich hab da jetzt nicht weiter darüber nachgedacht. Aber das kommt mir 
ziemlich kompliziert vor.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.