Sketchbook zu groß

Hallo,

das Sektchbook in meiner arduino-Software ist zu groß.
Wenn ich darüber einen Sketch öffnen möchte, werden nicht alle angezeigt. Die Liste geht über die gesamte Bildschirmhöhe, bzw. darüber hinaus.

Ich habe als erste Hilfe mit dem Windows-Explorer im Sketchordner ein paar Sachen in Ordnern zusammengefasst. Das funktioniert. Ich vermute allerdings, dass es auch eine Möglichkeit in der Software selbst gibt, mit der man das organisiert. Gibt's da was?

BTW: Ich habe im Moment die Version 1.0.5r2 installiert. Ist es ratsam, auf die aktuelle Version 1.6.4 zu wechseln? Oder handele ich mir als Gelegenheitsbastler damit nur mehr Probleme ein?

Hallo,

da hilft nur eine neuere IDE Version >1.6.x. Du mußt dann allerdings Deine Librarys mit rübernehmen oder guckst dann nach neueren Versionen davon. Auf alle Fälle ein Backup machen. Wenn Du rein nur die IDE nimmst, kannste auch erstmal die Portable Version nehmen zum testen.

Ich habe bisher nur die IDE benutzt, um meine kleinen Schnipsel zu programmieren und auf die Arduinos zu laden. Ich habe dafür allerdings auch mal fremde Libraries manuell in irgendwelche Ordner kopiert. Welche das waren und wo die sich nun befinden, weiß ich nicht mehr.

Soweit ich mich erinnern kann, habe ich damals die alte Version (1.0.5r2) als ZIP geladen und nicht installiert. Ich finde unter Windows XP auch keinen Eintrag in Software.
Spricht etwas dagegen, einfach die neuste Version von IDE (1.6.4?) als ZIP zu laden und neben der 1.0.5 zu entpacken, ohne sie zu installieren?
Wenn irgendwann etwas nicht funktioniert, kann ich die notwendigen Änderungen immer noch machen. Ich wüsste nämlich jetzt nicht, welche Dateien ich vom alten Programmverzeichnis ins neue kopieren müsste.

Ein komplettes Backup meiner Festplatte habe ich auf DVD. Es sollte eigentlich nix schiefgehen können. :slight_smile:

Hallo,

wenn die jetzige IDE portable ist, also das entpackte .zip File, dann ist alles Paletti. Lade die neue IDE .zip runter, entpacke “neben” der alten. Und fertig. Die Librarys befinden sich immer in dem entpackten IDE Ordner im Unterordner “libraries”. In der neuen IDE Version haste einen Library Manager. Ob man den nutzen muß weis ich nicht. Ich würde aber erst darin schauen ob die benötigte dabei ist und dann erst zur Not von der alten IDE die fehlende Lib rüberkopieren. Ich weis nicht ob die Lib’s zu jeder Zeit kompatibel sind zu neuen IDE Versionen.

OK, Danke. Das werde ich so ausprobieren.

Kurze Rückmeldung:

IDE1.6.4 funktioniert prinzipiell, aber der Umstieg ist mit einigen Stolpersteinen gespickt und nun klemmt es komplett.

Ich will keine Romane schreiben und versuche es so kurz wie möglich zu machen.

  1. Die IDE1.6.4 hat meinen ProMicro (32U4) nicht erkannt. Dazu musste ich mir neue Treiber besorgen und installieren. Das war gar nicht so einfach, weil ich die im Gerätemanager von WinXP nicht gefunden habe und ich so nicht wusste, wem ich den Treiber verpassen sollte.

  2. Beim ersten Sketchupload hat es meinen ProMicro dann gebricked. Die IDE hat keinen seriellen Port dafür angezeigt und abziehen und anstecken hat ihn auch unter Windows nicht neu eingebunden. Das habe ich dann gelöst, indem ich einfach bei angeschlossenem Arduino einen Sketch hochgeladen habe und im richtigen Moment RST+GND kurz gebrückt habe.

  3. Dann habe ich ein paar Sketche erfolgreich hochgeladen und wollte ein bisschen mit arrays spielen.
    Eindimensionale arrays gingen, aber als ich dann einen zweidimensionalen array angelegt habe, ist der Compiler einfach stehen geblieben. Selbst nach mehreren Minuten kam keine Fehlermeldung.

Hier der Code, bei dem das passiert:

int SensorNum;
int i;
int Sensorwerte[4][4];

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

void loop() {
  delay(1000);
  for (int SensorNum=0; SensorNum<5; SensorNum++){
    for (int i=0; i<5; i++){
      Sensorwerte[i][SensorNum]= i*3;
      if (i<4) {
        Serial.print(Sensorwerte[i]);
        Serial.print("  ");}
      else {
        Serial.println(Sensorwerte[i]);
      };
    };
}
}

Den gleichen Sketch habe ich dann in der alten IDE 1.0.5r2 kompiliert.
Da kommt dann eine ganz lange Latte von Fehlermeldungen, die hiermit anfängt:

array_test_02.ino: In function ‘void loop()’:
array_test_02:15: error: call of overloaded ‘print(int [4])’ is ambiguous

Der obige Sketch enthält natürlich noch Fehler. Das sehe sogar ich als Anfänger :), aber dass der Compiler einfach hängen bleibt, lässt mich darüber nachdenken, ob ich nicht besser mit der alten Version weiterbasteln soll. Das scheint mit anfängertauglicher zu sein.

Das hat nichts der Version zu tun. Der Code ist einfach nicht korrektes C/C++. Egal auf welcher Plattform. Du hast ein zwei-dimensionales Array. Wenn du dann nur array[index] machst, zerfällt das hier zu einem Zeiger auf int, da Array-Variablen Zeiger auf das erste Element sind. Damit kann print() natürlich nichts anfangen. Sowas kann man bei C Strings (d.h. Arrays aus char) machen, aber hier musst du schon beide Dimensionen angeben. Sowie du es auch beim Schreibenden Zugriff machst

Wenn du alle Elemente eines Teil-Arrays ausgeben willst kannst dir dafür eine Funktion schreiben:

void printArrayDimension(int* array, int elements)
{
   for(int i = 0; i < elements; i++)
   {
     Serial.print(array[i]);
     Serial.print(" ");
   }
   Serial.println();
}

Das kann man dann so aufrufen:

printArrayDimension(sensorWerte[i], 4);

Dann werden alle Werte einer Zeile ausgeben.

Außerdem ist der Index falsch. Ein Array mit 4 Elementen geht von 0-3. Index 4 existiert nicht. Also < 4 statt < 5 machen! Besser ist es die Dimensionen als Konstanten anzulegen, statt sie fest in jede Schleife zu schreiben. Dann muss man sie nur an einer Stelle ändern und der Code skaliert damit.

Serenifly:
Das hat nichts der Version zu tun. Der Code ist einfach nicht korrektes C/C++. Egal auf welcher Plattform. Du hast ein zwei-dimensionales Array. Wenn du dann nur array[index] machst, zerfällt das hier zu einem Zeiger auf int, da Array-Variablen Zeiger auf das erste Element sind. Damit kann print() natürlich nichts anfangen. Sowas

Das mit den Zeigern kann ich nicht nachvollziehen.
Dass arrays Zeiger sind, geht noch, aber warum zerfällt das auf einen Zeiger auf int?

BTW: Mit Zeigern bin ich noch nie warm geworden :slight_smile:
Ich meine zwar das Prinzip grundsätzlich verstanden zu haben, aber ich habe das nie umgesetzt bekommen.

kann man bei C Strings (d.h. Arrays aus char) machen, aber hier musst du schon beide Dimensionen angeben. Sowie du es auch beim Schreibenden Zugriff machst

Ist es denn normal, dass der Compiler einfach hängen bleibt und gar keine Ausgabe mehr macht? Bei größeren Quelltexten hätte man kaum eine Chance den Fehler zu finden.
Da der Compiler unter IDE1.0.5 eine Fehlermeldung ausgegeben hat, bin ich davon ausgegangen, dass der Compiler unter 1.6.4 ne Macke hat oder schlechter oder weniger anfängerfreundlich ist.

Wenn du alle Elemente eines Teil-Arrays ausgeben willst kannst dir dafür eine Funktion schreiben:
[…]
Dann werden alle Werte einer Zeile ausgeben.

Das sieht sehr elegant aus und nimmt etwas vorweg, was ich noch ausprobieren wollte.
Was da abgeht, leuchtet mir allerdings nicht ein.
Ich habe mir daraus mal eine lauffähiges Programm erstellt, um damit etwas spielen zu können.

int j,k;
int Sensorwerte[4][3];    //4 Sensoren mit je 3 Werten

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

void loop() {
  delay(1000);
  for (int j=0; j<4; j++){
    for (int k=0; k<3; k++){
      Sensorwerte[j][k]= (k*j);            // Sensorwerte speichern
      };
    printArrayDimension(Sensorwerte[j], 3);
   } ;
   Serial.println("..........");
}

void printArrayDimension(int *array, int elements)
{
   for(int i = 0; i < elements; i++)
   {
     Serial.print(array[i]);
     Serial.print(" ");
   }
   Serial.println();
}

Ich habe mir überlegt, wie die Funktion aussehen müsste, wenn von jedem Sensor der erste Wert ausgegeben werden sollte.
Oder geht das prinzipiell nicht so elegant, weil die Werte im Speicher seriell abgelegt sind?
Ich nehme an, dass die Reihenfolge der Werte wie folgt ist:
Sensorwerte[0][0], Sensorwerte[0][1], Sensorwerte[0][2], Sensorwerte[1][0], Sensorwerte[1][1], …

So ähnlich stelle ich mir das vor, aber es klappt nicht:

void printArray_nWert(int *array, int nWert)
{
   for(int i = 0; i < 4; i++)
   {
     Serial.print(array[i][nWert]);
     Serial.print(" ");
   }
   Serial.println();
}

Außerdem ist der Index falsch. Ein Array mit 4 Elementen geht von 0-3. Index 4 existiert nicht. Also < 4 statt < 5 machen!

Ja, ist klar. Das wusste ich vorher schon, hatte es gestern kurz zuvor noch gelesen, und habe es dann doch falsch eingehackt. Da habe ich den Überblick verloren.

Besser ist es die Dimensionen als Konstanten anzulegen, statt sie fest in jede Schleife zu schreiben. Dann muss man sie nur an einer Stelle ändern und der Code skaliert damit.

Ja, ist auch klar. Das waren nur meine ersten Gehversuche und da sind die Zahlen einfacher, als wenn ich Konstanten einsetze.

Bleiente:
Das mit den Zeigern kann ich nicht nachvollziehen.
Dass arrays Zeiger sind, geht noch, aber warum zerfällt das auf einen Zeiger auf int?

Bei einem zwei-dimensionalen Array ist die Array-Variable ein Zeiger auf ein Array. Genauso wie sie bei einem ein-eindimensionalen Array ein auf den Daten-Typ ist. Und ein Array selbst ist wieder ein Zeiger auf einen Datentyp.

Das bedeutet aber nicht, dass ein zwei-eindimensionales Array automatisch in einen Zeiger auf einen Zeiger zerfällt! Das merkt man wenn man eines als Parameter übergeben möchte. int** geht da nicht

Der Sinn meines Codes war es eine komplette Zeile eines Arrays auszugeben. Was übergeben wird ist eine Zeile (das hat dich wahrscheinlich verwirrt). Was du machst ist von jeder Zeile den Index nWert auszugeben. Dazu musst du aber das komplette Array übergeben. Und das tust du nicht.

Hier mal verschiedene Varianten:

const int ROWS = 5;
const int COLUMNS = 4;

int array[ROWS][COLUMNS] =
{
  { 0, 1, 2, 3 },
  { 4, 5, 6, 7 },
  { 8, 9, 10, 11 },
  { 12, 13, 14, 15 },
  { 16, 17, 18, 19 }
};

//die Funktions-Prototypen ist hier zwingened nötig!!
//Wahrscheinlich erkennt der IDE Parser diese Schreibweise nicht und kann den Prototyp nicht automatisch erzeugen.
//Das Problem gibt es auch bei ein paar anderen Konstrukten
void printArray(int array[][COLUMNS]);
void printRowByIndex(int array[ROWS][COLUMNS], int row);
void printColumn(int array[ROWS][COLUMNS], int column);
void printIndex(int array[ROWS][COLUMNS], int row, int column);

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

  Serial.println("\n----");
  Serial.println("printArray()");
  printArray(array);

  Serial.println("\n----");
  Serial.println("printRow()");
  for (int row = 0; row < ROWS; row++)
    printRow(array[row]);  //Hier wird nur eine Zeile des Array übergeben und diese gedruckt

  Serial.println("\n----");
  Serial.println("printRowByIndex()");
  for (int row = 0; row < ROWS; row++)
    printRowByIndex(array, row);  //Hier wird das komplette Array übergeben. Man übergibt den Index der Zeile die gedruckt werden soll

  Serial.println("\n----");
  Serial.println("printColumn()");
  for (int column = 0; column < ROWS; column++)
    printColumn(array, column);

  Serial.println("\n----");
  Serial.println("printIndex()");
  for (int i = 0; i < ROWS; i++)
  {
    for (int j = 0; j < COLUMNS; j++)
    {
      printIndex(array, i, j);
      Serial.print(" ");
    }
  }
}

void loop()
{
}

void printArray(int array[][COLUMNS])
{
  for (int i = 0; i < ROWS; i++)
  {
    for (int j = 0; j < COLUMNS; j++)
    {
      Serial.print(array[i][j]);
      Serial.print(" ");
    }
  }
  Serial.println();
}

void printRow(int* array)
{
  for (int i = 0; i < ROWS; i++)
  {
    Serial.print(array[i]);
    Serial.print(" ");
  }
  Serial.println();
}

void printRowByIndex(int array[ROWS][COLUMNS], int row)
{
  for (int i = 0; i < ROWS; i++)
  {
    Serial.print(array[row][i]);
    Serial.print(" ");
  }
  Serial.println();
}

void printColumn(int array[ROWS][COLUMNS], int column)
{
  for (int i = 0; i < ROWS; i++)
  {
    Serial.print(array[i][column]);
    Serial.print(" ");
  }
  Serial.println();
}

void printIndex(int array[ROWS][COLUMNS], int row, int column)
{
  Serial.print(array[row][column]);
}

Es auch üblich immer beide Dimensionen an die Funktionen zu übergeben, da die nicht immer global vorhanden sind.

Ob man jetzt array[COL] oder array[ROW][COL] schreibst ist egal

Ansonsten ist das dummerweise wieder so ein Fall wo die IDE es nicht schafft die Funktionsprototypen korrekt zu erzeugen. Also muss man sie explizit hinschreiben wie in C/C++ üblich. Für die einfachen Sachen macht das die Arduino IDE automatisch.

Erstmal vielen Dank für deine Erklärungen. Und noch etwas vorweg: Ich habe bist auf Serial.Begin alles in die Loop gepackt, weil ich sonst nicht weiß, wie ich die Ausgabe auf den seriellen Monitor bekomme. Wenn die Ausgabe nur einmalig passiert, ist der Monitor noch nicht geöffnet.

Dann wollte ich deine Beispiele nachvollziehen und bleibe gleich bei

void printArray(int array[][COLUMNS])

hängen.
Da frage ich mich, wieso wird zwar COLUMNS als Wert übergeben, aber nicht ROWS, wenn man das gesamte Array an die Funktion übergibt?
Es hätte ja sein können, dass man das machen kann, aber nicht muss, also habe ich die Funktion so geändert:

void printArray(int array[ROWS][COLUMNS])

Daraufhin hat der Compiler überraschenderweise gemeldet:
Arduino: 1.6.4 (Windows XP), Platine: "SparkFun Pro Micro 5V/16MHz"

Arrays_Pointer_150520_01:5: error: 'ROWS' was not declared in this scope
Arrays_Pointer_150520_01:5: error: 'COLUMNS' was not declared in this scope
'ROWS' was not declared in this scope

Ich vermute, dass ich ein Buch oder wenigstens ein gutes Tutorial durchackern müsste, um nicht bei jeder Kleinigkeit hängen zu bleiben. Die Fehlermeldung des Compilers kann ich mir nämlich überhaupt nicht erklären, denn ROWS und COLUMNS sind ja in den ersten beiden Zeilen deklariert.

Gibt es ein gutes deutschsprachiges Tutorial, mit dem man in möglichst kurzer Zeit die Grundlagen für C/C++ drauf hat?

Noch etwas zur IDE 1.6.4:
Die ist mir gerade eben zweimal kurz hintereinander abgestürzt. Die hat sich einfach beendet. Gestern ist das einmal passiert. Mit der IDE1.0.5r22 ist das AFAIR nie passiert.

Für mein aktuelles Bastelprojekt werde ich mich wohl zunächst auf meine vorhandenen Programmierkenntnisse beschränken und Arrays außen vor lassen. Das wird den Quelltext zwar aufblähen, und ganz furchtbar unelegant machen, aber dafür werde ich es in absehbarer Zeit umgesetzt bekommen.

Man muss nur eine Dimension übergeben. Du kannst aber auch beide machen. Das ist bei der Initialisierung ähnlich wenn man es direkt mit { } macht statt ein leeres Array anzulegen. Den Rest kann der Compiler selbst herausfinden.

Arrays_Pointer_150520_01:5: error: 'ROWS' was not declared in this scope
Arrays_Pointer_150520_01:5: error: 'COLUMNS' was not declared in this scope
'ROWS' was not declared in this scope

Da hast du den Teil mit den Funktions-Prototypen am Anfang übersehen oder ignoriert! Die musst du hier per Hand anlegen, weil es die IDE nicht kann. Der Parser kommt leider mit bestimmten Sachen nicht zurecht. Dazu habe ich einen drei-zeiligen Kommentar geschrieben.

Wenn du was an der Signatur der Funktion änderst, musst du den entsprechenden Prototypen auch anpassen. Sonst passiert genau was hier gemeckert wird: die Funktion kann nicht gefunden werden

Es gibt auch noch andere Schreibweisen, aber die würden dich noch mehr verwirren und sind auch weniger gerne gesehen. Eine leicht abgewandelte Variante die ganz nett ist ist das:

void func(int m, int n, int arr[][n]);

Dabei übergibt man das Array als 3. Parameter. Dann kann man den Parameter "n" den man vorher übergibt als Array-Dimension verwenden. Das ist sehr schön wenn die Dimensionen nicht global hat (was aber auf dem Arduino sehr oft der Fall ist).
Ist aber nicht grundlegend anders als was ich geschrieben habe.

Wegen deinen IDE Problemen. Versuche vielleicht mal 1.6.0. Damit hast du immer noch viele Verbesserungen, aber nicht das aller neueste.