Arduino im Modellbau

Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#61 Re: Arduino im Modellbau

Beitrag von Husi »

the-fallen hat geschrieben:Schon mal in einer anderen Sprache programmiert ...
Äh ja, schon hin und wieder. Allerdings war das mein erster Versuch mit C.

Wer kann mir bei meinem Array Problem helfen? Via Google habe ich nicht die Lösung gefunden, die ich suche...
Hier ein kleines Testprogram um mit Serial, Strings und Arrays etwas zu spielen.
Wie_die_Dimension_eines_Text_Arrays_bestimmen.png
Wie_die_Dimension_eines_Text_Arrays_bestimmen.png (190.2 KiB) 1044 mal betrachtet
Wie in dem Bild zu sehen, möchte ich Dimension des Arrays "vom System" ermitteln lassen und nicht via Zahl oder VAR vorgeben.
Ich dachte da an so ein UBound(MyArray) wie in VB... :oops:

Noch schöner wäre es, wenn ich auch noch wüßte, wie am einen String z.B. "Beispieltext Nr: 1;Beispieltext Nr: 2;Beispieltext Nr: 3;Beispieltext Nr: 4;Beispieltext Nr: 5;Beispieltext Nr: 6"
auf Grund des Zeichens ";" in ein Array (der Dimension 0 To 5) aufspalten lässt.

Code: Alles auswählen

String BeispielStringArray[]={"Beispieltext Nr: 1", "Beispieltext Nr: 2", "Beispieltext Nr: 3", 
                              "Beispieltext Nr: 4", "Beispieltext Nr: 5", "Beispieltext Nr: 6"};

void setup() {
  Serial.begin(9600);
}

void TextZeileAusgeben(String Text) {
  for (int n=0; n<Text.length(); n++) {  
    Serial.print(Text.charAt(n));  // nur den Buchstaben an der Pos. "n" ausgeben
    delay(100);                    // nach jedem Buchstaben eine kurze Pause
  }
  Serial.println();
}

void TextArrayAusgeben(String TextArray[]) {
  for (int i=0; i<6; i++) {
    TextZeileAusgeben(TextArray[i]);    
    delay(200);        // nach der fertigen Zeile etwas warten    
  }
  Serial.println();    // nach fertigem Text- bzw. Array-Block einen Absatz ausgeben
}

void loop() {
  TextArrayAusgeben(BeispielStringArray);  
}
Vielen Dank
Mirko
Bild Bild Bild Bild
Benutzeravatar
Crizz
Beiträge: 27061
Registriert: 12.04.2007 17:44:22
Wohnort: Haiger
Kontaktdaten:

#62 Re: Arduino im Modellbau

Beitrag von Crizz »

@Tracer : wenn du ein ungültiges Objekt ansteuern willst, erhälst du einen Compilerfehler wenn du das Sketch prüfen läßt, Du kannst also auf dem Weg prüfen lassen, ob die verwendete Anweisung Sstemkompatibel ist, aber nicht die Funktion des Sketches selber prüfen.

Oder ganz salopp : du verwendest eine Anweisung um einen Ausgang zwischen 1 / 0 zu togglen. Der Compiler sagt dir nur, ob die verwendete Anweisung auf dem ausgewählten Board / CPU unterstützt wird und meckert ggf. - er gibt dir aber keine Simulationsmöglichkeit die die reale Hardwareseitige Ansteuerung des Controllers ersetzt.

Sprich : kein SPICE integriert.
_________________________________________________________________________________
"Leben ist das, was passiert, während du etwas ganz anderes planst" ... ( John Lennon )

! REVOLECTRIX-Distributor ! -> Ladeequipment / Akkus : -> HaDi-RC.de

Alle Projektberichte für den VTH-Verlag als PDF zum Download unter http://www.CrizzD.de !
Benutzeravatar
tracer
Operator
Operator
Beiträge: 63774
Registriert: 18.08.2004 18:50:03
Wohnort: Kollmar
Kontaktdaten:

#63 Re: Arduino im Modellbau

Beitrag von tracer »

Mirko, bei den Array bin ich noch nicht, ich habe nur mal etwas mit Deinem Code gespielt, Redundanzen entfernt, und es auf Englisch gemacht.

IMHO immer eine good practice, wenn Du das erste mal in einem internationalem Forum postest, und da nicht-englische Namen oder Kommentare sind, wird es meistens ignoriert.

Compilen tut der Sketch, ob er auch macht was er soll :scratch:
Kannst ja mal ausprobieren, wenn Du Lust hast.

Code: Alles auswählen

const int LED_PIN = 13;

#define SPEED 250;
const word DIT = SPEED;
const word DAH = 3 * SPEED;

// delay between 2 symbols are 3 dit (1 Dah)
// char space space 1 Dah
// word space 7 Dit



void setup() {
  pinMode(LED_PIN, OUTPUT);      // initialize digital pin 13 as an output.
}



void switchLED(boolean state, int delta = 0)
{
  digitalWrite(LED_PIN, state);
  delay(delta);
}



void Dit()
{
   switchLED(HIGH, DIT);
   switchLED(LOW);
}


void Dah()
{
   switchLED(HIGH, DAH);
   switchLED(LOW);
}
   

void S_blink() {
  Dit();
  Dit();
  Dit();
  
  // end of symbol, move to funtion later
  Dah();
  
}



void O_blink() {
  Dah();
  Dah();
  Dah();
  
  // end of symbol, move to funtion later
  Dah();
  
}


void SOS_blink()
{
  S_blink();
  O_blink();
  S_blink();
}



// the loop function runs over and over again forever
void loop() {
  SOS_blink();
  delay(1000);          // Warten zwischen den SOS Blink-Code
}
Benutzeravatar
tracer
Operator
Operator
Beiträge: 63774
Registriert: 18.08.2004 18:50:03
Wohnort: Kollmar
Kontaktdaten:

#64 Re: Arduino im Modellbau

Beitrag von tracer »

Husi hat geschrieben:Ich dachte da an so ein UBound(MyArray) wie in VB...
sizeof() müsste gehen.
Benutzeravatar
the-fallen
Beiträge: 1976
Registriert: 07.03.2011 14:20:47
Wohnort: zwischen Augsburg und Landsberg a.L.

#65 Re: Arduino im Modellbau

Beitrag von the-fallen »

Richtig.
So ein Simulator müsste ja nicht nur das Arduino simulieren, sondern auch noch die Hardware die man anschließt.

Eine LED ist da ja noch einfach...Sensoren, Displays, Aktoren, Ethernet, SD-Karten, WLAN, alle anderen Kommunikationsschnittstellen ... man kann ja eigentlich ALLES was es gibt von jedem Hersteller und jeder Baureihe anschließen.
So etwas zu simulieren wäre glaube ich einfach unmöglich...
  • Prôtos FBL -stretched- a un motor 5+4D 1.13mm 14P de torro [V-Stabi]|[V-Gov] | [YGE90LV] | [UweG-Taumelscheibe] | [ZyclicMod]
  • SuziJanis 700 UltraLight 3570g Abfluggewicht
  • Besessen: T-Rex 250SE, T-Rex 450L, T-Rex600EFL, TDR, Blade mSRX
  • nur Gebaut und eingeflogen: Blade700, Goblin500, TRex150 RKH, Blade 130X RKH, Vibe90
  • Heizkoffersteuerung "HeatBox"

[" 99 little bugs in the code | 99 little bugs in the code | Take one down, patch it around | 117 little bugs in the code "] - Alex Shchepetilnikov
Benutzeravatar
the-fallen
Beiträge: 1976
Registriert: 07.03.2011 14:20:47
Wohnort: zwischen Augsburg und Landsberg a.L.

#66 Re: Arduino im Modellbau

Beitrag von the-fallen »

@Mirco:

Was du vorhast ist nicht einfach. In C ist die Dimension eines Arrays nicht bekannt.
C kümmert sich nicht um deine Speicheraufteilung oder darum, wo der Inhalt einer Variable aufhört und die nächste anfängt.
Das musst du durch gutes Programmieren selber tun, darum sind Programme die in C geschrieben wurden auch immer sehr anfällig für Overflows aller Art.
Bietet auf der anderen Seite auch gewisse Freiheiten die man sonst nicht hat :D


Du kannst es aber so machen:

Code: Alles auswählen

  
  String test[] = {"test1", "Beispiel Nr 7", "Achtungneunzig","Flanders",  "Arduino"};
  Serial.println(sizeof(test));
  Serial.println(sizeof(String));
  uint16_t size = sizeof(test)/sizeof(String);
  Serial.println(size);
Ausgabe:

Code: Alles auswählen

80
16
5

Was wird gemacht?
Wir ermitteln die Größe des Arrays im Speicher (80Byte) und dividieren es durch die Größe eines String-"Objektes" (16 Byte).
Ergebnis: es passen 5 solcher Objekte in die 80 Byte, also stehen wohl 5 Strings in dem Array.

Das funktioniert hier so schön, weil der eigentliche Text (der ja unterschiedlich lang sein kann) irgendwo im speicher steht, das Array aber nur String-"Objekte" speichert. Jedes dieser String-"Objekte" weiß, wo sein Text im Speicher steht.


Es gibt natürlich noch andere Speichermöglichkeiten als Arrays, z.B. (verkettete) Listen. Da für deinen Zweck ein Array okay ist wäre der Rest zu kompliziert.

Noch schöner wäre es, wenn ich auch noch wüßte, wie am einen String z.B. "Beispieltext Nr: 1;Beispieltext Nr: 2;Beispieltext Nr: 3;Beispieltext Nr: 4;Beispieltext Nr: 5;Beispieltext Nr: 6"
auf Grund des Zeichens ";" in ein Array (der Dimension 0 To 5) aufspalten lässt.
Wenn es String bleibt, könntest du mit indexOf() arbeiten und somit die Position des nächsten ";" ermitteln. Würdest du ein char[] nutzen müsstest du Zeichen für Zeichen angucken bis du dein Trennzeichen (";") gefunden hast.
  • Prôtos FBL -stretched- a un motor 5+4D 1.13mm 14P de torro [V-Stabi]|[V-Gov] | [YGE90LV] | [UweG-Taumelscheibe] | [ZyclicMod]
  • SuziJanis 700 UltraLight 3570g Abfluggewicht
  • Besessen: T-Rex 250SE, T-Rex 450L, T-Rex600EFL, TDR, Blade mSRX
  • nur Gebaut und eingeflogen: Blade700, Goblin500, TRex150 RKH, Blade 130X RKH, Vibe90
  • Heizkoffersteuerung "HeatBox"

[" 99 little bugs in the code | 99 little bugs in the code | Take one down, patch it around | 117 little bugs in the code "] - Alex Shchepetilnikov
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#67 Re: Arduino im Modellbau

Beitrag von Husi »

the-fallen hat geschrieben:

Code: Alles auswählen

 uint16_t size = sizeof(test)/sizeof(String);
Serial.println(size);
Was wird gemacht?
Wir ermitteln die Größe des Arrays im Speicher (80Byte) und dividieren es durch die Größe eines String-"Objektes" (16 Byte).
Ergebnis: es passen 5 solcher Objekte in die 80 Byte, also stehen wohl 5 Strings in dem Array.
Danke, so etwas ähnliches habe ich im Netz auch gefunden, wollte es aber nicht glauben, das es so umständlich sein soll. Da bin ich von anderen Sprachen wohl etwas verwöhnt. :oops:
the-fallen hat geschrieben:Wenn es String bleibt, könntest du mit indexOf() arbeiten und somit die Position des nächsten ";" ermitteln. Würdest du ein char[] nutzen müsstest du Zeichen für Zeichen angucken bis du dein Trennzeichen (";") gefunden hast.
Na toll, dann darf ich mir also die Function split halt auch selbst schreiben. Auch hier habe ich etwas mehr erwartet... :roll:

Viele Grüße
Mirko
Bild Bild Bild Bild
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#68 Re: Arduino im Modellbau

Beitrag von Husi »

tracer hat geschrieben:IMHO immer eine good practice, wenn Du das erste mal in einem internationalem Forum postest, und da nicht-englische Namen oder Kommentare sind, wird es meistens ignoriert.
Ist RHF ein internationales Forum?
Ich schreibe meinen Quellcode lieber in deutsch und das auch noch mit schön langen sprechenden Variablen- bzw. Funktions-Namen. So kann ich den Quelltext auch nach 2 Jahren Pause immer noch so flüssig wie einen Roman lesen. Das könnte ich bei deinem Quellcode nicht. Der Compiler schmeißt alles unnötige und zu lange eh raus, darum brauche ich mich also gar nicht zu kümmern.
Von mir aus, darf es jeder so machen, wie er es möchte.
tracer hat geschrieben:

Code: Alles auswählen

void loop() {
  SOS_blink();
  delay(1000);          // Warten zwischen den SOS Blink-Code
}
In deiner Variante ist auch noch ein deutscher Randnotiz. :D
Außerdem hättes du jetzt nicht mehr die Möglichkeit (die ich mir immer gerne offen lasse) z.b. so etwas zu machen.

Code: Alles auswählen

void loop() {
  SOS_blinken(LED_13);
  delay(1000);            // Warten zwischen den SOS Blink-Code
  SOS_blinken(LED_20);
  delay(1000);            // Warten zwischen den SOS Blink-Code
  S_blinken(LED_21);  // S blinken
}
Viele Grüße
Mirko
Bild Bild Bild Bild
Benutzeravatar
tracer
Operator
Operator
Beiträge: 63774
Registriert: 18.08.2004 18:50:03
Wohnort: Kollmar
Kontaktdaten:

#69 Re: Arduino im Modellbau

Beitrag von tracer »

Husi hat geschrieben:In deiner Variante ist auch noch ein deutscher Randnotiz.
Die war noch aus Deinem Code übrig. :-)
Benutzeravatar
acanthurus
Beiträge: 3348
Registriert: 21.10.2008 08:39:59
Wohnort: Kreis Ludwigsburg

#70 Re: Arduino im Modellbau

Beitrag von acanthurus »

Das erinnert mich an Zeiten, als man mit Turbo-Pascal Variabeldeklarationen wie

var ItDoesntDoAnythingItsJustaDummy: integer;

und Konstrukten wie

const Weihnachten:=FALSE;
repeat until Weihnachten;

Den Informatik-Pauker an den Rand des Nervenzusammenbruchs gebracht hat ;)

Bei der Hardware würde ich diese Schaltung empfehlen: https://xkcd.com/730/
I told my mom when I grow up I want to be an Engineer, she told me I can't do both!
Benutzeravatar
the-fallen
Beiträge: 1976
Registriert: 07.03.2011 14:20:47
Wohnort: zwischen Augsburg und Landsberg a.L.

#71 Re: Arduino im Modellbau

Beitrag von the-fallen »

Naja es ist eben C und für einen Microprozessor mit begrenzten Ressourcen.
Zeichenketten sollten da wirklich nur für die Interaktion mit einem Benutzer verwendet werden, und String wirklich nur wenn man das braucht und ein char[] nicht reicht.
Vieles muss man sich sicher einmal selber schreiben aber kann den Code ja immer wieder verwenden oder man macht sich eine eigene Bibliothek (später dann).

Programmieren auf einem Mikroprozessor heißt auch zu lernen, minimalen und guten Code zu schreiben.
Aber das kommt mit der Übung von alleine.
  • Prôtos FBL -stretched- a un motor 5+4D 1.13mm 14P de torro [V-Stabi]|[V-Gov] | [YGE90LV] | [UweG-Taumelscheibe] | [ZyclicMod]
  • SuziJanis 700 UltraLight 3570g Abfluggewicht
  • Besessen: T-Rex 250SE, T-Rex 450L, T-Rex600EFL, TDR, Blade mSRX
  • nur Gebaut und eingeflogen: Blade700, Goblin500, TRex150 RKH, Blade 130X RKH, Vibe90
  • Heizkoffersteuerung "HeatBox"

[" 99 little bugs in the code | 99 little bugs in the code | Take one down, patch it around | 117 little bugs in the code "] - Alex Shchepetilnikov
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#72 Re: Arduino im Modellbau

Beitrag von Husi »

Moin moin,

der nächste Schritt ist gemacht... Und bei euch? Hat außer mir, noch jemand den Arduino und das Buch ausgepackt?

ich wollt versuchen ein Servo anzusteuern und (vorerst nur) mit einem Poti stellen.
Dabei dachte ich mir jedoch, das ich gerne noch "Warnschwellen" hätte, die vor erreichen des Wegbegrenzers via LED eine optische Warnung vor Erreichen der unteren, sowie der oberen Servo- Abschaltung / Endbegrenzung anzeigen.

So sieht es auf meinem Steckbrett aus:
Schaltung komplett
Schaltung komplett
P3311553_klein.jpg (74.44 KiB) 910 mal betrachtet
Der neue Servostecker ist echt praktisch :-)
Der neue Servostecker ist echt praktisch :-)
P3311552_klein.jpg (66.26 KiB) 912 mal betrachtet
Hier der Quell-Code:

Code: Alles auswählen

// Husi Versuch 03 -> 10K Ohm Poti einlesen und Werte via Serial und Servo ausgeben.
#include <Servo.h>

const int PIN_LED       = 13;  // Kontroll-Leuchte, ob gerade am Poti gedreht wird
const int PIN_LED_ROT   = 10;  // Warn-Leuchte vor bald Ende (oben)
const int PIN_LED_WEISS = 11;  // Warn-Leuchte vor bald Ende (unten)
const int PIN_POTI      = A0;  // Analoger Input PIN

const int EPSILON  =  10;      // Rauschunterdrückung Vorgabe
int Poti_Wert_alt  = -99;      // VAR alter Wert
int Poti_Wert_neu  =   0;      // VAR neuer Wert
int Wert_Delta;                // Rauschunterdrückung Hilfswert (aktueller Unterschied)
int Wert_Proz;                 // Prozentwert des (Poti-) Signals
String Text_Ausgabe;           // String für User Interface (Serial) 

Servo Servo_01;                // Servo Objekt erzeugen

void setup() {
  pinMode(PIN_LED,       OUTPUT);
  pinMode(PIN_LED_ROT,   OUTPUT);
  pinMode(PIN_LED_WEISS, OUTPUT);
  Serial.begin(9600);
  digitalWrite(PIN_LED, LOW);
  Servo_01.attach(3);          // Servo am PIN Nr. 3 eingesteckt
}

void TextWerteBlock_Ausgeben(int neu, int alt, int delta) {
  Text_Ausgabe= "Wert neu= " + String(neu) + " (" + String(Wert_Proz) + "%)";
  Serial.println(Text_Ausgabe);
  Text_Ausgabe= "Wert alt= " + String(alt);
  Serial.println(Text_Ausgabe);
  Text_Ausgabe= "Wert Delta= " + String(delta);
  Serial.println(Text_Ausgabe);
  Serial.println();
}

void Servo_01_bewegen(int Wert) {
  if ((45 < Wert) && (Wert <  96)) {
    Servo_01.write(Wert);   // Servo nur in den Grenzen bewegen => sonst Anschlag!
  }
  if (Wert < 50) {
    digitalWrite(PIN_LED_WEISS, HIGH);  // unterhalb Warnschwelle, LED an.
  } else {
    digitalWrite(PIN_LED_WEISS, LOW);
    if (Wert > 80) {
      digitalWrite(PIN_LED_ROT, HIGH);  // oberhalb Warnschwelle, LED an
    } else {
      digitalWrite(PIN_LED_ROT, LOW);
    }
  }
}

void loop() {
  Poti_Wert_neu = analogRead(PIN_POTI);  // Einlesen des Poti Wertes:
  Wert_Delta= abs(Poti_Wert_alt - Poti_Wert_neu);
  if (Wert_Delta >  EPSILON) {
    digitalWrite(PIN_LED, HIGH);  // LED auf dem UNO solange leuchten lassen, wie "Traffic" ist.
    Wert_Proz = map(Poti_Wert_neu, 0, 1023, 0, 100);   // Umrechnen von (0 <-> 1023) auf %
    Servo_01_bewegen(Wert_Proz);
    TextWerteBlock_Ausgeben(Poti_Wert_neu, Poti_Wert_alt, Wert_Delta);
    Poti_Wert_alt = Poti_Wert_neu;
    delay(50);
    digitalWrite(PIN_LED, LOW);   // LED auf dem UNO wieder aus
  }
}
Viele Grüße
Mirko
Bild Bild Bild Bild
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#73 Re: Arduino im Modellbau

Beitrag von Husi »

the-fallen hat geschrieben:Zeichenketten sollten da wirklich nur für die Interaktion mit einem Benutzer verwendet werden, und String wirklich nur wenn man das braucht und ein char[] nicht reicht.
Kannst du bitte erklären, warum? Wie berechnet sich der benötigte Speicherplatz für eine String Variable? Ist es ein fester Wert, oder ein Byte pro Zeichenlänge?
Bei einem char[5] gehe ich von 5 Byte aus, evtl. noch eines für die Array-Verwaltung? Ist das bei einem String anders?
the-fallen hat geschrieben:Programmieren auf einem Mikroprozessor heißt auch zu lernen, minimalen und guten Code zu schreiben.
Kannst du bitte mal ein Beispiel für einen "schlechten" und das gleiche Beispiel mit einem "guten" Code schreiben? Ich lerne gerne dazu.


Stimmt eigentlich meine Annahme, das die Länge der Variablennamen beim kompilieren egalisiert werden, weil es direkt in Speicheradressen umgesetzt wird?

Viele Grüße
Mirko
Bild Bild Bild Bild
Benutzeravatar
the-fallen
Beiträge: 1976
Registriert: 07.03.2011 14:20:47
Wohnort: zwischen Augsburg und Landsberg a.L.

#74 Re: Arduino im Modellbau

Beitrag von the-fallen »

Kannst du bitte erklären, warum? Wie berechnet sich der benötigte Speicherplatz für eine String Variable? Ist es ein fester Wert, oder ein Byte pro Zeichenlänge?
Bei einem char[5] gehe ich von 5 Byte aus, evtl. noch eines für die Array-Verwaltung? Ist das bei einem String anders?
char ist ein sogenannter "einfacher Datentyp" und wird im Speicher als Byte (je Zeichen bei unseren Arduinos) abgelegt.
Ein char-Array (char[]) ist dann eine Kette von chars hintereinander im Speicher mit einer Startadresse.

String ist ein sogenannter "komplexer Datentyp". Er kann viel mehr mit seinem eigenen Inhalt tun (z.B. manipulieren) und bringt gleich Methoden dafür mit. Das kann hilfreich sein, wenn man es braucht. Jedoch wird für die Verwendung von String ein ganzer Satz mehr Code geladen.

Beispiel:

Code: Alles auswählen

void setup() {
  // put your setup code here, to run once:
  char wort[] = "Test";
  Serial.println(s);
}

void loop() {
  // put your main code here, to run repeatedly: 
}
Ergebnis:
Binäre Sketchgröße: 10.496 Bytes (von einem Maximum von 262.144 Bytes)
Estimated memory use: 2.564 bytes (of a 65.536 byte maximum)

Code: Alles auswählen

void setup() {
  // put your setup code here, to run once:
  String wort = "Test";
  Serial.println(s);
}

void loop() {
  // put your main code here, to run repeatedly: 
}
Ergebnis:
Binäre Sketchgröße: 14.452 Bytes (von einem Maximum von 262.144 Bytes)
Estimated memory use: 3.908 bytes (of a 65.536 byte maximum)


Das ganze Relativiert sich natürlich, je öfter ich String benutze, da der zusätzliche Code ja insgesamt nur ein mal dazugeladen und immer wieder verwendet wird. Zehn mal verwendet wird der Code also nicht auch zehn mal größer. Er wäre aber insgesamt dennoch größer als wenn ich zehn mal char[] verwende.
Kann man ja einfach mal ausprobieren.


Kannst du bitte mal ein Beispiel für einen "schlechten" und das gleiche Beispiel mit einem "guten" Code schreiben? Ich lerne gerne dazu.
Das ist natürlich ohne konkrete Aufgabenstellung nicht so leicht zu zeigen. (Habe schon drüber nachgedacht mir ein paar leichte aufgaben einfallen zu lassen und man schaut mal, wie jeder das löst so dass man von einander lernen kann).

Ein prominentes Beispiel wäre aber z.B. das Deklarieren einer Variable innerhalb einer Schleife (anstatt außerhalb und diese nur in der Schleife zu verwenden). In der Regel behebt ein guter Kompiler so etwas aber. Ist also eher ein "fiktives" Beispiel an dem man das aber gut erkennt.

Ein anderes Beispiel ist der Unterschied zwischen "call by value" und "call by reference" - also den Aufruf einer Methode und die Art und Weise, wie ich größere (komplexere) Variablen übergebe. Angenommen ich habe eine Variable mit 100 Byte Inhalt und ich rufe eine Funktion auf die diesen Inhalt modifiziert. Ich kann natürlich diese 100Byte übergeben, in der Funktion verändern und zurückgeben, wo der modifizierte Inhalt wieder in die originalvariable zurück geschrieben wird.

Beispiel:

Code: Alles auswählen

a = macheWas(a);
In diesem Fall wird eine Kopie des Inhaltes in der Funktion macheWas() bearbeitet und zurückgegeben. Ich verschwende also mal eben noch mal 100Byte.

Ich kann aber auch der Funktion einfach nur sagen, WO die Variable im Speicher liegt.
Beispiel:

Code: Alles auswählen

macheWas(&a);
Hier übergebe ich nur die Adresse der Variable im Speicher. Das ist bei den AVR-Prozessoren gerade mal 2Byte.

Weitere Möglichkeit ist natürlich, dass die Variable a global bekannt ist und die Funktion macheWas einfach drauf zugreift (wenn das gegeben ist).

Außerdem - auch wenn das nicht direkt mit dem Code zu tun hat - ist eine gute Dokumentation etwas, das den guten Code erst richtig perfekt macht. Auch wenn es Mühe kostet.

Stimmt eigentlich meine Annahme, das die Länge der Variablennamen beim kompilieren egalisiert werden, weil es direkt in Speicheradressen umgesetzt wird?
Ja. Der Variablenname ist für dich. Intern sind das alles nur Speicheradressen (sogenannte "Pointer"). Für den Kompiler kannst du auch alles stumpf durchbuchstabieren.
Ein guter Stil ist es aber "sprechende" Variablennamen zu verwenden. Also ein Name, der schon irgendwie aussagt, wofür die Variable ist.

Schlecht: int a;
Gut: int tasterZaehler;


Du wirst dir sowas selber danken wenn du zwei Monate später deinen Code anguckst und versuchst, nach zu vollziehen was da passiert. Oder wenn du den Code jemanden zeigen willst.





Ich finde aber den Code aus deinen Beispielen wirklich vorbildlich (jetzt klinge ich ja wie so ein verkorkster Oberlehrer :D ).
Ich muss mich oft selber zwingen das so gut lesbar und dokumentiert zu machen. Ist also eine gute Sache die man so beibehalten sollte und zu der ich mich auch immer wieder zwingen muss.
  • Prôtos FBL -stretched- a un motor 5+4D 1.13mm 14P de torro [V-Stabi]|[V-Gov] | [YGE90LV] | [UweG-Taumelscheibe] | [ZyclicMod]
  • SuziJanis 700 UltraLight 3570g Abfluggewicht
  • Besessen: T-Rex 250SE, T-Rex 450L, T-Rex600EFL, TDR, Blade mSRX
  • nur Gebaut und eingeflogen: Blade700, Goblin500, TRex150 RKH, Blade 130X RKH, Vibe90
  • Heizkoffersteuerung "HeatBox"

[" 99 little bugs in the code | 99 little bugs in the code | Take one down, patch it around | 117 little bugs in the code "] - Alex Shchepetilnikov
Benutzeravatar
Husi
Beiträge: 2808
Registriert: 19.03.2007 20:06:17
Wohnort: Darmstadt
Kontaktdaten:

#75 Re: Arduino im Modellbau

Beitrag von Husi »

the-fallen hat geschrieben:String ist ein sogenannter "komplexer Datentyp". Er kann viel mehr mit seinem eigenen Inhalt tun (z.B. manipulieren) und bringt gleich Methoden dafür mit. Das kann hilfreich sein, wenn man es braucht. Jedoch wird für die Verwendung von String ein ganzer Satz mehr Code geladen.
Oh, das wußte ich bisher noch nicht. Ich dachte, es würden nur die Methoden geladen, die expliziet aufgerufen werden.
the-fallen hat geschrieben:char wort[] = "Test";
Na das finde ich ja auch interessant. Ich hätte mich so eine Zuweisung nicht getraut, weil das Array zuerst hätte dimensionieren wollen. Das fällt mir aber schwer, wenn ich Zahlen (dessen Länge ich nicht kenne -> ein-, zwei-, oder dreitstellig) in einen String konvertiere.
the-fallen hat geschrieben:Ein anderes Beispiel ist der Unterschied zwischen "call by value" und "call by reference"
OK, ich ging davon aus, das die Default-Einstellung immer "call by reference" ist. In anderen Programmiersprachen ist das so und ich muß bewußt eine Variablenübergabe via "Function xy(ByVal WertKopie As Integer)" machen.
the-fallen hat geschrieben:macheWas(&a);
Wie sieht in diesem Fall die Definition des Funktion-Kopfes aus? Ganz normal?
the-fallen hat geschrieben:(jetzt klinge ich ja wie so ein verkorkster Oberlehrer :D ).
Nein, ich habe doch gefragt und bin über die Antworten sehr dankbar.

Viele Grüße
Mirko
Bild Bild Bild Bild
Antworten

Zurück zu „Arduino Tipps & Hilfe“