Pages: [1]   Go Down
Author Topic: Weitere und ernste Probleme mit Fahrtenregler  (Read 505 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Nochmals zur Einführung: Ich möchte gern ein 15 Jahre altes Modellauto auf digitale Fernsteuerung umbauen. Die Funke ist gekauft, die H-Brücke ist gebaut und getestet, alles ist ins Auto eingebaut. Als Fahrtenregler soll ein Attiny45 dienen, den ich entweder über AVR Studio 5.1 oder über einen Arduino Uno programmieren möchte. Da es bei mir nicht anders geht (weil ich definitiv zu dumm bin) muss ich mit Arduino 0.22 arbeiten.
Nun zum Problem: Bei mir verharken sich regelmäßig Arduino Befehle und AVR GCC Software. Zum Beispiel habe ich eine softwaremäßige PWM programmieren müssen, weil ich den Befehl writeAnalog auf dem Attiny nicht zum Laufen kriege. Ich habe alle Pins (bis zur Nummer 25) probehalber in den Befehl analogWrite (PIN, Teil_von_1024) reingeschrieben, es blinkte jeweils nur sinnlos vor sich hin. Also Software für PWM genutzt. Den Timer0 habe ich so eingestellt, dass er eine effektive Frequenz von 40 Hz realisierte, hat auch prima hingehauen, bis ich mittels pulseIn versucht habe den Empfänger der Fernsteuerung auszulesen. Just dann gab es keine Software-PWM mehr, weil es plötzlich Interrupts nicht mehr gibt. (Das der Befehl pulseIn für die Dauer der Messung, also in meinem Fall für max. 2 ms lahmlegt, war mir schon klar, dass es aber gar keine Interrupts mehr gibt?)
Gut habe ich mir gesagt, also auch noch dass in die Software rein. Da es nicht so genau drauf ankommt, habe ich mir gedacht, misst einfach am Anfang jeder Schleife. Wenn du ein paar microsekunden verpasst, dann ist das nicht so schlimm, es wir ja oft genug gemessen.

Daraus ergab sich folgender Code:

Code:
void loop() {

  if ((PINB & 0b00010000) && (run=0)) {

    Start = millis();
    run = 1;
  }
 
  if ((!(PINB & 0b00010000)) && (run = 1)) {
    Impulsdauer = millis() - Start;
    run = 0;

    PORTB = 0b00001111;
    delay(2000);
    PORTB =0b000000000;
    delay(2000);
  }
}

Ich sags nochmal deutlich, dass ist eine Probe!

Was mich an der ganzen Sache fasziniert ist die Tatsache, dass die LED, die an PB0, PB1, PB2 oder PB3 angeschlossen werden kann, dauerhaft leuchtet! Obwohl sie nur 2 sec. lang leuchten sollte. Warum tut sie das?

Normalerweise habe ich das alles mit der bekannten und so beliebten Syntax mit Bitshift und allem Drumherum geschrieben, aber für micht ist das so besser lesbar!

Danke für Eure Antworten!
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3071
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

meinst du vielleicht (run == 0) in deinem if ?

(run=0) setzt run auf 0 und liefert nebenbei immer false zurück.

if ( run=1 ) ist immer true, und verändert run  ...

Schon schlimm, dass solche Sachen in C syntaktisch richtig sind und nicht mal Warnungen produzieren ...
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 160
Posts: 3183
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Schon schlimm, dass solche Sachen in C syntaktisch richtig sind und nicht mal Warnungen produzieren ...

Manche Programmierer, die auch in anderen Sprachen programmieren, wo man mit "=" nicht nur Zuweisungen sondern auch Vergleiche machen kann, haben sich schon angewöhnt, die Parameter beim Vergleich auf Gleichheit mit Konstanten umgedreht hinzuschreiben:

Statt:
if (run==0)
Schreibe:
if (0==run)
Ist es korrekt, frißt es der Compiler so oder so. Aber macht man es falsch, ist es ein Unterschied.

if (0=run) sollte ja bei einem Vergleich auf Gleichheit prüfen. Aber macht man den Fehler so herum, gibt es einen satten Compilerfehler und kann sofort erkennen, dass da etwas nicht stimmt.

Aber im Endeffekt sind das eher typische Anfängerfehler, gelegentlich if (run=0) statt if (run==0) zu schreiben. Das sollte man sich beim Programmieren in C sehr schnell abgewöhnen. Oder beim Vergleich mit Konstanten tatsächlich konsequent die Konstante im Vergleich zuerst hinschreiben.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Herzlichen Dank für diesen Tipp. Das ist absolut richtig.

Wenn Ihr den Code anschaut, dann seht Ihr, dass selbst der fehlerhafte Code kein dauerhaftes Leuchten verursachen sollte! Im zweiten If Statement steht eindeutig: Warte 2000 Millisekunden! Und zwar, nachdem ich die Laterne durch Abschalten der Energieversorgung durch PORTB = 0b00000000 ausgemacht habe! Dieser Programmteil wird immer dann aufgerufen, wenn (!(PINB & 0b00010000)) WAHR ist, also an PB4 kein Signal anliegt. Da ich PB4 über einen Pulldown auf Gnd ziehe, sollte bei jedem Durchlauf die Beleuchtungseinrichtung 2 sec leuchten und dann 2 sec eben nicht leuchten, oder?
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 54
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich habe heute früh von Arduino auf C++ umgeschwenkt. Mit dem AVR Studio 5.1 und dem AVR USB Programmer hat es prima hingehauen. Ich habe zwei Interrupts programmiert, der eine zählt einen Counter hoch und spielt PWM, der andere überwacht PIN4 und gibt Signale bei HIGH und LOW. Mit diesem messe ich die Impulslänge des Fernsteuersignals. Dieses verwurschte ich zu einer Sollgeschwindigkeit. Aus der Sollgeschwindigkeit mache ich dann eine Istgeschwindigkeit, die dem Signal mit leichter Trägheit folgt.

Dieses Geschwindigkeitssignal übergebe ich dann meiner Software PWM. Klappt wunderbar!
Logged

Pages: [1]   Go Up
Jump to: