Jump to content
Intermodellbau 2024: Unser Stand in Halle 3 ist fertig für Besucher - schaut mal 'rein. ×
Schiffsmodell.net

Endabschaltung


lab

Recommended Posts

Nachdem ich inzwischen zwei Tage mit dem Problem verbracht habe und nicht mehr klar denken kann, finde ich vielleicht eine Anregung...

 

Ich möchte einen Motor mit einem L293 Mototreiber in zwei Richtungen steuern (für einen Spindelantrieb eines U-Boot-Tauchtanks) und an beiden Enden per Endabschalter abschalten - aber natürlich in die entgegengesetzte Richtung wieder anfahren lassen.

 

Dazu habe ich die folgende Schaltung mit einem Arduino aufgebaut (interessant ist der obere Teil. Die beiden LEDs rot/gelb simulieren im Moment noch den Motor):

 

attachment.php?attachmentid=15446&stc=1&d=1358085622

 

Mein Problem ist nun, dass der Endlagenschalter zwar den richtigen Motor abschaltet aber das Anfahren in die andere Richtung nicht klappt.

 

Der Code sieht so aus (aufgrund von Beschränkungen des nachrichtentextes kann ich den Code leider nicht direkt einstellen):

https://dl.dropbox.com/u/3363810/denise_software_v4c.txt

 

Das meiste habe ich aus dieser Quelle übernommen:

 

// Reading an RC Receiver - What does this signal look like and how do we read it -

// http://rcarduino.blogspot.co.uk/2012/01/how-to-read-rc-receiver-with.html

//

// The Arduino library only supports two interrupts, the Arduino pinChangeInt Library supports more than 20 -

// http://rcarduino.blogspot.co.uk/2012/03/need-more-interrupts-to-read-more.html

//

// Using pinChangeInt library and Servo library to read three RC Channels and drive 3 RC outputs (mix of Servos and ESCs)

// http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html

//

// RC Channels, L293D Motor Driver - Part 2 Calibration And Code

// http://rcarduino.blogspot.de/2012/05/interfacing-rc-channels-to-l293d-motor.html

//

// rcarduino.blogspot.com

post-6551-1419862357,702_thumb.gif

Link to comment

Nach noch einmal kräftig durchatmen, habe ich das Problem jetzt doch noch selbst gelöst! :lovl:

 

Also erst einmal keine Hilfe mehr erforderlich - für Anregungen von Experten zur Verbesserungen des Programms bin ich natürlich trotzdem dankbar.

 

Gruß, Kai

Link to comment

Hallo Kai,

 

schön das du's selber gefunden hast. Ein paar kleine Tipps möchte ich trotzdem los werden. Gelten nicht speziell für dich, sondern eher als Anregung für die anderen, die mitlesen. (Ich hoffe das tun wenigsten ein paar).

 

- Bei Problemen versucht erstmal das Problem ein zukreisen und das in einem Stück Code zu packen, was nur das Problem betrifft. Das hilft nicht nur den anderen beim Lesen, sondern vor allem einem selber beim denken.

Also den Problemcode so klein wie möglich machen. Und das ganze am besten Schrittweise. Wenn dann plötlich das Problem weg ist, war der letzte Schritt dafür entscheidend. Ist das Problem bei dem übrig gebliebenen Codestück immer noch da, weiter vereinfachen. Bis nicht mehr geht.

 

- Brecht euer Programm in so viele kleine Teilbereich und Funktionen auf, wie möglich. Gebt den Funktionen sprechende Namen (das kostet keinen Platz). Faustregel: Eine Funktion (auch die loop() ist eine Funktion) nicht mehr als 1 Bildschirmseite. Damit man das ganze mit einem Blick überschauen kann.

 

- Benutzt so wenig wie möglich globale Variablen.

- Die kosten Platz im RAM vom Controller und können aber nicht weiter verwendet werden

- Machen den Code schwerer lesbar, weil die Definition weit entfernt ist von der Benutzung.

 

- Lieber eine Funktion als eine globale Variable.

Beispiel analogen Wert einlesen und zurück geben:

nicht so gut

int temp;

void setup()...

void loop() {
...
 doit();
...
 if (temp > 500) {
...
...
}
...

void doit() {
 temp = analogRead(0);
}

 

Macht das gleich aber man kann es besser lesen. (Der Code ist sogar noch kleiner...)

 

void loop() {
...
 if (readAkkuVoltage() > 500) {
...
 }
...  
}

...
int readAkkuVoltage() {
 return analogRead(0);
}

 

-Haltet Code und Variablen zusammen. (Ausnahme sind Konstanten und defines, die man später ändern möchte, die gehören an den Anfang.)

Nicht so gut:

int myRcValue;
...
void setup() {
...
}

void loop() {
...
}

...(Hier noch jede Menge Code)

void getRcValue() {
// die Variable wird nur hier und in der Funktion processRcValue benutzt...
  myRcValue = pulseIn(RC_PIN);
  myRcValue = map (myRcValue, 1000, 2000, 0, 255);
  ...
}

void processRcValue() {
  if (myRcValue > 128) {
  }
}

 

Besser:

...

int myRcValue;

void getRcValue() {
// die Variable wird nur hier und in der Funktion processRcValue benutzt...
  myRcValue = pulseIn(RC_PIN);
  myRcValue = map (myRcValue, 1000, 2000, 0, 255);
  ...
}

void processRcValue() {
  if (myRcValue > 128) {
  }
}

 

Und noch ein Tipp:

Macht euren Code erstmal lauffähig und lesbar/wartbar. Erst wenn alles funktioniert kann man schrittweise an das optimieren gehen. Manchmal muss man sich eben auch entscheiden, lieber lesbarer oder schneller.

Meine persönliche Meinung (wie alles hier): solange der Code tut was er soll, hab ich ihn lieber lesbar als daß ich das letzte Fünkchen Performanz raus kitzele.

Link to comment

Das ganze Programm zu lesen ist mir gerade zu viel, zumal es inzwischen ja funktioniert.

 

Anregung.... du verwendest: if(false == funktion()) Das false ist total unsinnig, weil funktion() ja schon einen boolean zurückliefern muss damit der vergleich überhaupt Sinn macht. Schöner wäre einfach if(!funktion()) do;. Noch schöner für die Lesbarkeit wäre aber die Variable zu ändern die zurückgegeben wird.

im moment hast du: if ( nicht == tag ) licht_an();

lesbarer finde ich: if ( nacht ) licht_an();

Das lässt sich zwar nicht immer realisieren, wenn die variable 2x verwendet wird z.B., aber meistens geht es. Ob in diesem Fall habe ich mir ehrlich gesagt nicht angeschaut.

 

 

Und dann hast du auskommentierten Fehlersuchcode, also

/* serial.print(a);
serial.print(b);*/

Hier möchte ich dir nahelegen einen genaueren Blick auf "#if defined" und "#endif" zu werfen. Damit kannst du den gesamten Fehlersuchcode mit einer einzigen Variablen am Anfang des Quellcodes ein- und ausschalten.

Link to comment

Dafür hab ich mir mal folgendes geschrieben.

#ifdef debug
#define dbgOut(S) \
Serial.print(S); 
#define dbgOutLn(S) \
Serial.println(S); 
#define initDebug() \
 Serial.begin(57600); \
 Serial.flush(); \
 delay(100);
#else
#define dbgOut(S)
#define dbgOutLn(S)
#define initDebug()
#endif

Dann kann ich mit einen einfachen #define debug das ganze einschalten.

Den Serial Initialisierung mach ich dann im Setup() direkt am Anfang mit initDebug. Einfache Ausgaben dann mit dbgOut(...) oder dbgOutLn(..)

Kompliziertere Sachen schachtel ich dann in ein

#ifdef debug
...
#endif

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.