Forum: Mikrocontroller und Digitale Elektronik Subtrahieren funktioniert nicht wie es soll.


von Phil E. (mieper)


Angehängte Dateien:

Lesenswert?

Hallo Community!

Ich versuche derzeit zum üben einen Spannungsregler mit einem Atmega8 zu 
bauen.
Das ganze funktioniert auch ziemlich super. Selbstverständlicherweise 
reagiert das ganze nicht so schnell wie ein Spannungsregler den es 
fertig zu kaufen gibt. Es geht aber um den Lerneffekt.

Vorgeschichte:

Ich lese am ADC0(Versorgungsspannung) und ADC1(Sollspannung) die 
verschiedenen Spannungen ein. Dabei kommen Werte von 0 bis 1023.
Daraus berechne ich den Faktor, und multipliziere diesen mit 255. Dann 
gebe ich dem PWM Register OCR2 diesen Wert.
1
int main(void){
2
  int variable = 0;
3
  int variablex = 0;  
4
  int x1=0, x2=0;
5
}
1
while(1){
2
    x1 = MESSWERT(0);
3
    x2 = MESSWERT(1);
4
              
5
    variable = (x2 / x1) * 255;
6
    if (variable < 0){variable = 0;}
7
    if (variable > 255){variable = 255;}
8
    variablex = variable;
9
        
10
    OCR2 = variablex
11
}

Mein Problem ist jetzt folgendes:

Leider regelt der PWM (oder 'variablex') nur in viertel Schritten. Also 
63, 127, 191 und 255.
Ich kann mir aber nicht erklären weshalb das so ist.
'variablex' steht noch im Code weil ich das ganze mal mit Float probiert 
hatte. Hat leider ebenso wenig funktioniert.


Habt ihr eine Idee?


Grüße
Phil



Edit: Zum debuggen habe ich ein Display angeschlossen und lasse mir die 
beiden Spannungen anzeigen sowie die Variable 'variablex'. (Siehe Bild) 
Da kann ich ablesen das variablex nur 4 verschiedene Werte anzeigt (63, 
127, 191 und 255).

von Peter II (Gast)


Lesenswert?

> variable = (x2 / x1) * 255;
> if (variable < 0){variable = 0;}
> if (variable > 255){variable = 255;}


(x2 / x1) wird als int gerechnet. Damit kann dort nur eine ganzzahliger 
wert >= 0 rauskommen.  Das ganze mal 255 ist immer 0, 255, 512 usw.

und wenn du jetzt

> if (variable > 255){variable = 255;}

machst, dann kommt dort zwangsläufig immer 255 oder 0 raus.

von J.-u. G. (juwe)


Lesenswert?

1. Ich sehe in Deinem Code keine Subtraktion.
2. Der gezeigte Code ist nicht der, den Du auf Deinem µC laufen hast. 
Die while-Schleife ist ausserhalb der main-Funktion.
3. Lasse Dir auf dem LCD nciht die Spannungen anzeigen, sondern direkt 
die Variablen x1 und x2.

von Phil E. (mieper)


Lesenswert?

J.-u. G. schrieb:
> 1. Ich sehe in Deinem Code keine Subtraktion.

Divison, Tut mir leid.

J.-u. G. schrieb:
> 2. Der gezeigte Code ist nicht der, den Du auf Deinem µC laufen hast.
> Die while-Schleife ist ausserhalb der main-Funktion.

Ist ein Code ausschnitt in welchem die beiden Schleifen getrennt gezeigt 
sind.

J.-u. G. schrieb:
> 3. Lasse Dir auf dem LCD nciht die Spannungen anzeigen, sondern direkt
> die Variablen x1 und x2.

Dann mach ich das mal.

von Phil E. (mieper)


Angehängte Dateien:

Lesenswert?

Ich hab mich jetzt komplett festgefahren.


http://www.youtube.com/watch?v=CxaaXux4PX4
http://www.youtube.com/watch?v=ASZX5g6Zlvk
Wer gute Augen hat kann auch was erkennen. :)

von Peter II (Gast)


Lesenswert?

auch das dürfte nicht gehen
1
 float variable = 0; //standart pwm
2
 int x1=0, x2=0;
3
4
 x1 = MESSWERT(0);
5
 x2 = MESSWERT(1);
6
              
7
 variable = (x2 / x1);

x2 / x1 wird kein float ergeben! Statt Video sollte du eventuell die 
Grundlagen von C und den Datentypen dir mal anschauen.

Auch wenn es mit float möglich ist, solltest du wenn möglich darauf 
verzichten.

von J.-u. G. (juwe)


Lesenswert?

Phil E. schrieb:
> Youtube-Video "Lcd2"

Ja, da siehts Du doch genau das von Peter beschriebene Verhalten. 
Solange x2 kleiner ist als x1, ergibt die Division (x2/x1) gleich Null. 
Wenn x2 gleich oder größer als x1 wird, dann wird der Quotient zu 1. Und 
damit "variablex2" zu 255.

von Dietrich L. (dietrichl)


Lesenswert?

@Phil:
Statt mit float zu arbeiten wäre Festkomma-Arithmetik besser:
http://www.mikrocontroller.net/articles/Festkommaarithmetik

Aber bei Deinem ersten Programm sollte
Phil E. schrieb:
> variable = (x2 / x1) * 255;

zumindest so sein:
1
variable = (x2 * 255) / x1;

Gruß Dietrich

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

x2 * 255 kann aber überlaufen, oder nicht?  Besser wäre dann x2 * 255L.

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.