Klausuraufgabe verstehen die 2.

Hallo zusammen,

Ich bin es mal wieder mit einer weitern Aufgabe, die ich nicht so ganz verstehe.
Dieses mal geht es um Arrays.
Zunächst einmal der Code:

byte x[100];
byte y[100];

void setup() 
{
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  Serial.begin(115200);
}

void loop() 
{
  digital_to_array(5, 3, x);
  digital_to_array(6, 3, y);
  int n = analyse_x_y();
  Serial.println(n);
}

Nun besteht die Aufgabe darin, dass die Funktion "digital_to_array" das Einlesen eines Arrays übernehmen soll. Als 1. Parameter soll der analoge Pin, als 2. Parameter das Intervall zum Befüllen des Arrays in Millisekunden und als 3. Parameter der Array übergeben werden.
Des weiteren soll eine Funktion "analyse_x_y" die beiden globalen Arrays x und y auswerten. Diese Funktion soll die Summe aller Werte aus x und y zurückgeben.
Ich habe schon Erfahrungen mit Arrays aber die Aufgabenstellung verwirrt mich so sehr, dass ich keine Ahnung habe wie ich daran gehen soll.

Ich bedanke mich schon mal, für jede(n) Hilfe/Denkanstoß den ich von euch bekomme.

Ich verstehe an der Aufgabe auch so einiges nicht.

Aber, wo klemmts denn bei dir?

Um ehrlich zu sein, weiß ich nicht einmal wie ich hier anfangen soll.
Also wie ich die Funktionen aufschreiben soll als Code...

byte x[100];
byte y[100];
...
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
...
  digital_to_array(5, 3, x);
  digital_to_array(6, 3, y);

Angesichts der Array-Definition als byte, der pinModes und des Funktionsnamens würde ich mal davon ausgehen, dass es sich hier nicht um analoge Eingabe handelt.

Für mich einfachst mögliche Interpretation der Aufgabe:
Es werden Nullen und Einsen in einem Abstand von (hier) 3ms in den Arrays gesammelt und am Ende die Einser gezählt.

Die eigentliche Aufgabe dann vielleicht:

  • Funktionen anwenden
  • Funktionsprototypen (oder Methoden-Signaturen ;)) korrekt aufschreiben
  • Funktionen so implementieren, dass das Wissen um die “Globalität” der Arrays in digital_to_array() nicht erforderlich ist, aber in analyse_x_y() wohl zu verwenden ist
  • Auf den Trick kommen, wie die Größe der übergebenen Arrays in digital_to_array() zu bestimmen ist

Diese Interpretation beruht im Wesentlichen auf einem Blick in die Glaskugel (Sonne scheint, da kann man das schon mal riskieren).

Gruß Walter

rammdon:
Um ehrlich zu sein, weiß ich nicht einmal wie ich hier anfangen soll.
Also wie ich die Funktionen aufschreiben soll als Code...

Nunja....

Funktionen schreiben, solltest du schon mal gemacht haben, um diese Aufgabe zu lösen!

Also lesen: "C++ function"
Und üben!

Auch ein langer Weg beginnt mit einem Schritt.

Nun besteht die Aufgabe darin, dass die Funktion “digital_to_array” das Einlesen eines Arrays übernehmen soll. Als 1. Parameter soll der analoge Pin, als 2. Parameter das Intervall zum Befüllen des Arrays in Millisekunden und als 3. Parameter der Array übergeben werden.

void digital_to_array (Einlesepin, Intervall, Datenarray)
{
for (int i = 0; i<100; i++)
{
Datenarray[i] = digitalRead(Einlesepin);
delay(Intervall);
}}

Jetzt bin ich nicht sicher ob die Übergabe des Arrays so richtig ist. Aber das wird mir sicher jemand korrigieren.

Grüße Uwe

Im Zusammenhang mit der "Aufgabe", bin ich auf ein lustiges Problem gestoßen!
Getestet mit einem UNO.

Eigentlich ist der int Wertebereich ja sehr beschränkt.
So dass 255 * 200 = 51000 nicht darstellbar ist.
Erstaunlicher Weise zeigt es mir im diesem Beispiel 4294952760 als Summe an.

Das passt nicht in int.
Und ich sehe nicht was da falsch läuft.

!Hilfä!

Übringens, mit

volatile int result = 0;
Zeigt es das richtige Ergebnis an -14536

byte x[100];
byte y[100];

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

void loop()
{

  // alle Zellen vorbesetzen
  for(byte &data:x) data = 0xFF;
  for(byte &data:y) data = 0xFF;

  // summe über alle Zellen
  int result = 0; 
  for(byte data:x) result += data;
  for(byte data:y) result += data;

  // summe zeigen
  Serial.println(result);
}

(deleted)

combie:
Das passt nicht in int.
Und ich sehe nicht was da falsch läuft.

Hallo,

genau weiß ich es auch nicht, es hängt jedoch mit der for Kurzform zusammen. In Langform stimmts.

Danke vielmals für die ganzen Antworten! Das hat mir sehr geholfen. :slight_smile:

Doc_Arduino:
Hallo,

genau weiß ich es auch nicht, es hängt jedoch mit der for Kurzform zusammen. In Langform stimmts.

Naja…

Noch weiter zusammen gestrichen gibts auch mit der Langform die gleichen Probleme.
Aber zumindest mit einer Warnung garniert.

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

  
  int result = 0; 
  for(int i = 0; i<200;i++) result += 0xff;

  // summe zeigen
  Serial.println(result);
}

void loop()
{
}
E:\Programme\arduino\portable\sketchbook\sketch_jul12d003\sketch_jul12d003.ino: In function 'setup':
E:\Programme\arduino\portable\sketchbook\sketch_jul12d003\sketch_jul12d003.ino:8:36: warning: iteration 128 invokes undefined behavior [-Waggressive-loop-optimizations]
    8 |   for(int i = 0; i<200;i++) result += 0xff;
      |                             ~~~~~~~^~~~~~~
E:\Programme\arduino\portable\sketchbook\sketch_jul12d003\sketch_jul12d003.ino:8:19: note: within this loop
    8 |   for(int i = 0; i<200;i++) result += 0xff;
      |                  ~^~~~
C

Schätze mal, dass die aggressive-loop-optimization auch in der Kurzform zuschlägt, nur dann stumm versagt.

Hallo,

das ist count abhängig, ab count 129 macht es Mist. Sobald der Wertebereich von int überläuft geht irgendwas schief.

byte x[200];

void setup()
{
  Serial.begin(115200);
  Serial.println("\nStart");

  for(byte i=125; i<135; i++)
  {
    summieren(i);
  }
  
}

void loop()
{

}

void summieren (const byte count)
{
// alle Zellen vorbesetzen
  for(byte &data:x) data = 0xFF;
  
  // summe über alle Zellen
  int result = 0;
  for(byte i=0; i<count; i++)
  {
    result += x[i];
  }
 
  // summe zeigen
  Serial.print(count); Serial.print('\t');
  Serial.println(result);
}

.
125 31875
126 32130
127 32385
128 32640
129 4294934655
130 4294934910
131 4294935165
132 4294935420
133 4294935675
134 4294935930

Dass die Berechnung beim Überlauf versagt, ist eine Sache.
Dass sie (manchmal) stumm versagt, ist böse.

Und das am meisten überraschende, ist für mich, dass selbst Serial.print() dann aus dem Ruder läuft.

rammdon:
Danke vielmals für die ganzen Antworten! Das hat mir sehr geholfen. :slight_smile:

Danke für die Rückmeldung!

Da ich ein neugieriger Mensch bin:
Magst Du Deine Lösung auch zeigen?
Gibt es eine Musterlösung zum Vergleich, aus der wir evtl. ersehen können, was der Aufgabensteller sich eigentlich gedacht haben könnte?

Gruß Walter

Hallo,

der Seriellen mag ich keine Schuld geben. Die gibt doch nur das aus was ihr übergeben wird.
Es schlummert scheinbar ein Problem im gcc 8.4.0 und 9.3.0.
Mit gcc 7.3.0 und 10.1.0 stimmt der Überlauf.
Ob -std=gnu++17 oder -std=gnu++20 spielt keine Rolle.

byte x[200];

void setup()
{
  Serial.begin(115200);
  Serial.println("\nStart");

  for(byte i=128; i<130; i++)
  {
    summieren(i);
  }
  
}

void loop()
{
}

void summieren (const byte count)
{
// alle Zellen vorbesetzen
  for(byte &data:x) data = 0xFF;
  
  // summe über alle Zellen
  int result = 0;
  for(byte i=0; i<count; i++)
  {
    result = result + x[i];
    Serial.print(count); Serial.print('\t');
    Serial.print(x[i]); Serial.print('\t');
    Serial.println(result);
  }
 
  // summe zeigen
  Serial.print(count); Serial.print('\t');
  Serial.println(result);
}

wno158:
Danke für die Rückmeldung!

Da ich ein neugieriger Mensch bin:
Magst Du Deine Lösung auch zeigen?
Gibt es eine Musterlösung zum Vergleich, aus der wir evtl. ersehen können, was der Aufgabensteller sich eigentlich gedacht haben könnte?

Gruß Walter

Nachdem ich die ersten Antworten bekommen habe, habe ich ganz schnell meinen Ansatz aus dem Fenster geschmissen.... und ich glaube da ist er auch besser aufgehoben :smiley:
Es gibt leider keine Musterlösung.

Hallo,

mit dem folgenden Code hängt sich alles bei count 129 auf. Er bleibt endlos mit “129” in einer Dauerschleife hängen. Egal welchen gcc ich verwende. Das ist Hexerei. :grin:

Übrigens war in #11 meine Interpretation der Daten falsch. Er läuft auch nicht bis count 128 korrekt über. Wenn der gesamte Code Mist macht, dann bleibt er schon vorher immer im positiven Bereich obwohl er ins Negative müßte.

void setup()
{
  Serial.begin(115200);
  Serial.println("\nStart");

  for(byte i=128; i<131; i++)
  {
    summieren(i);
  }
  
}

void loop()
{
}

void summieren (const byte count)
{
  // aufsummieren
  int result = 0;
  for(byte i=0; i<count; i++)
  {
    result += 0xFF;
    Serial.print(count); Serial.print('\t');
    Serial.println(result);
  }
 
  // Summe zeigen
  Serial.print(count); Serial.print('\t');
  Serial.println(result);
}

Vermutung: 129 * 255 = 32895 > 32767

Gruß Tommy

combie:
Eigentlich ist der int Wertebereich ja sehr beschränkt.
So dass 255 * 200 = 51000 nicht darstellbar ist.
Erstaunlicher Weise zeigt es mir im diesem Beispiel 4294952760 als Summe an.

Übringens, mit

volatile int result = 0;
Zeigt es das richtige Ergebnis an -14536
Und ich sehe nicht was da falsch läuft.

result als word/uint16_t -> 51000

Und das am meisten überraschende, ist für mich, dass selbst Serial.print() dann aus dem Ruder läuft.

Für mich auch, aber ich hab einen Lösungsansatz:

long x=4294952760;

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

void loop() {

Ausgabe:

21:22:08.659 -> -14536

Das sieht nach Schieberegistern und zwei uint16_t vor der Ausgabe aus, nachdem automatisch ein (unsigned) long aus dem int wurde.

rammdon:
...habe ich ganz schnell meinen Ansatz aus dem Fenster geschmissen.

Das nun wieder finde ich schade - aber für mich kein Problem.

Warum ich das schade finde?
Weil die Antworten, die hier so erscheinen, aus kumuliert etlichen Jahrzehnten Beschäftigung mit dem Thema basieren. Dahinter steckt vielleicht auch eine bestimmte Art und Weise des Herangehens an ein Problem und eine Denkweise.

Wenn Du meinst, dass diese Art für die Klausuraufgaben eine Hilfreiche wäre, müssten wir Deinen (Denk-) Ansatz schon kennen, um Dich ggf. in eine andere / diese Richtung "stubsen" zu können. Ich nehme mal an, dass der eine oder andere das auch so sieht - Hilfe zur Selbsthilfe eben.