HC-SR04 Sensor fehlt da was?

selfmade:
Wie muss ich mir das Abspeichern der Sketche auf dem Arduino vorstellen.
Haben da mehrere Sketche Platz?

Nein. Beim "Upload" wird immer der vorhandene Sketch gelöscht und der neue Sketch hochgeladen.

selfmade:
wieviel MG passen da drauf?

Was soll MG bedeuten? Megabytes?
Ein Arduino UNO hat 32 KB Flash-Speicher, also 0,032 MB. Oder in Gigabytes ca. 0,000032 GB.

selfmade:
wenn ich einen Sketch nicht mehr brauche wie bring ich den wieder runter oder lösche diesen?

Der alte wird automatisch gelöscht, bevor der neue hochgeladen wird.

sorry hatte mich verschrieben
ja natürlich MB
habe gerade auf der arduino seite gesehen das der mega 256kb hat. für einen code sind zwar 32kb schon einiges was wahrscheinlich bei den meisten reicht.

Wenn auf dem Flash-Speicher kann also nur 1 Programm laufen... wow.
das bedeutet das alles was ich an das Arduino anschliessen in ein Programm packen muss. mmmhhh.

Gibt es da Lösungsansätze zur Programmierung?
Beispiel: in einer Schleife muss/will ich nur alle 10 Minuten was auslesen und eine Aktion ausführen. ZB. beim Temp-Sensor
in der anderen Schleife möchte ich 1 mal pro Std was ausführen z.B. PH messen usw usw.

irgendwie geht das aber bestimmt oder?

aber bestimmt

Eine Stunde sind 3600000L millis().
Schau dir das Tutorial BlinkWithoutDelay als Basis an.
Wenn du nicht rauskriegst, was das mit deiner Frage zu tun hat, melde dich wieder :wink:

32kB reicht für viele Programme aus. RAM ist eher ein Problem als Flash. Vor allem auf dem UNO. Flash wird erst problematisch wenn du zig Bibliotheken hast und vor allem bei TFTs mit mehreren Fonts.
Und selbst auf dem Mega kann es unter Umständen problematisch werden Programme größer als 64k oder 128k zu schreiben, da da im Hintergrund einige Tricks ablaufen, weil Zeiger auf einem 8 Bit Prozessor nur 16 Bit haben.

Um dein Programm zu strukturieren musst du die Aufgaben teilen und in getrennte Funktionen packen. Diese kann man dann in loop() aufrufen, bzw. Funktionen können wieder andere Funktionen aufrufen. Das ist aber im Prinzip auch nicht anders wie man Programme auf dem PC schreibt.

selfmade:
Gibt es da Lösungsansätze zur Programmierung?

Kooperatives Multitasking mit der loop-Funktion als Scheduler.

selfmade:
Beispiel: in einer Schleife muss/will ich nur alle 10 Minuten was auslesen und eine Aktion ausführen. ZB. beim Temp-Sensor
in der anderen Schleife möchte ich 1 mal pro Std was ausführen z.B. PH messen usw usw.

irgendwie geht das aber bestimmt oder?

Die Arduino-Software startet automatisch einen Timer, der Dir einen mit der Funktion "millis()" auslesbaren Millisekundentakt bereitstellt. Davon abgeleitet kannst Du Dir natürlich auch eigene Funktionen basteln, die nur alle 10 Minuten laufen. Alle 10 Minuten wäre also 10 * 60 Sekunden * 1000 Millisekunden = 600000. Also mußt Du immer, wenn millis() um 600000 weitergezählt hat, einmal Deine Funktion laufen lassen.

ok,
Danke für die Hinweise.
Da hab ich noch einiges an Arbeit vor.

Gibt es hier irgendwo ein umfangreiches Beispielprogramm was eben mit vielen Unterfunktionen etc. arbeitet was auch etwas dokumentiert ist.
Wenn ich den Aufbau und die Logik dahinter sehe komme ich schneller voran

Hallo!
Schau dir mal in Ruhe die LCDMenü Lib von Jomelo an.
http://forum.arduino.cc/index.php?topic=73816.0
Da kannst die Sketche in Funktionen packen, die du einfach aus dem Hauptmenü starten kannst...
Stabil und leicht zu adaptieren...perfekt...habe mit einem 2004 I2C LCD, einem Joystick und einem Megashield mit
RTC und SD die "perfekte" Basis für neue Projekte....

mfg Martin

Nichts gegen Jomelos Menu Library,
aber wenn dich das erstmal abschreckt, mach dir nichts draus.

"Beispiel" und "umfangreich" sind halt üblicherweise Gegensätze.

Aber hinter

jurs:
Kooperatives Multitasking mit der loop-Funktion als Scheduler.

steckt im Prinzip nur

// Kommentar ...

// Version ...

// Pinbelegung
const int FehlerLED=13;
..
void setup()
{
     pinMode (FehlerLED, OUTPUT);
     Serial.begin(115200);
     setup1();
     setup2();
      //  ...
}

void loop()
{
     ZustaendeNeuErfassen(); // das E von jurs/Serenifly's   Eva ;)
     Funktion1();
     Funktion2();
     FunktionXYZ();
     // ...
}

"kooperativ" deswegen, weil die Einzelfunktionen mitspielen müssen. Sie dürfen also nicht lange irgendwo hängen, sondern müssen in der Hoffnung auf baldigen Neuaufruf schnell zum Aufrufer zurückkehren.

Wenn man dann Funktionen, die nichts miteinander zu tun haben, in unterschiedliche Dateien legt, und globale Variablen -- soweit sinnvoll -- vermeidet, kann man evtl. den Überblick behalten :wink:

Wobei die Hardwarebelegung ( Beispiel FehlerLED ) hier gut aufgehoben ist...

Aber das ist alles Geschmackssache

selfmade:
Gibt es hier irgendwo ein umfangreiches Beispielprogramm was eben mit vielen Unterfunktionen etc. arbeitet was auch etwas dokumentiert ist.
Wenn ich den Aufbau und die Logik dahinter sehe komme ich schneller voran

Hier mal ein kurzes Beispielprogramm, das einmal pro Minute die Temperatur "mißt" (die Messung wird nur durch eine Zufallsfunktion simuliert) und alle 10 Minuten den PH-Wert.

Das Programm zeigt, wie ich an so etwas herangehe:

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

float temperatur;
#define TEMPINTERVALL 60*1000L // 60 Sekunden
float phWert;
#define PHINTERVALL 10*60*1000L // 10 Minuten

void eingabeTemperatur()
{
  static unsigned long letzteMessung=-TEMPINTERVALL;
  unsigned long now=millis();
  if (now-letzteMessung>TEMPINTERVALL)  // 1 Minute
  {
    temperatur=20+random(50)/10.0; // Test only: Zufallswert "messen"
    letzteMessung=now;
    Serial.println("Debug-Meldung: Temperatur gemessen");
  }
}

void eingabePH()
{
  static unsigned long letzteMessung=-PHINTERVALL;
  unsigned long now=millis();
  if (now-letzteMessung>PHINTERVALL)  // 60 Minuten
  {
    phWert=7+random(10)/10.0; // Test only: Zufallswert "messen"
    letzteMessung=now;
    Serial.println("Debug-Meldung: PH-Wert gemessen");
  }
}


void verarbeitung()
{
  // nichts
}

void ausgabe()
{ // einmal pro Sekunde den Wert in der Anzeige aktualisieren
  static unsigned long letzteAnzeige=0;
  unsigned long now=millis();
  if (now-letzteAnzeige>1000) // 1 Sekunde
  {
    Serial.print("Temp: ");Serial.print(temperatur);Serial.print('\t');
    Serial.print("PH: ");Serial.print(phWert);Serial.println();
    letzteAnzeige=now;
  }
}

void loop() {
  eingabeTemperatur();
  eingabePH();
  verarbeitung();
  ausgabe();
}

Jedes Programm wird in verschiedene "Tasks" (= Funktionen) aufgeteilt, die in der loop-Funktion reihum immer wieder abgearbeitet werden. Eine sinnvolle Aufteilung der Tasks erfolgt nach dem "EVA-Prinzip":

  • Eingabe
  • Verarbeitung
  • Ausgabe
    Die EVA-Trennung ist deshalb so sinnvoll, weil sie die spätere Wartbarkeit und Erweiterung des Programms sehr vereinfacht. So könnte man Eingaben von Tastaturbedienung auf Drehgeber umstellen. Oder auf Infrarot-Fernbedienung. Oder die Ausgabe erstmal für Serial programmieren und später ein LCD-Textdisplay umschreiben. Oder auf die Ausgabe per Netzwerk auf einem Webbrowser, der die Daten abruft.

Nur "Debug-Ausgaben" auf Serial, um sich während der Programmentwicklung zwischendurch mal etwas auf Serial ausgeben zu lassen, um den Stand von Variablen zu prüfen, sind außen vor, und können überall im Code eingestreut werden.

Der Trick dabei, dass scheinbar "alles gleichzeitig" abläuft, liegt darin:
a) Aufrufe der "delay" Funktion mit langen delay-Zeiten bei interaktiven Programmen stets vermeiden!
b) Jede Task-Funktion so programmieren, dass sie in kürzester Zeit abgearbeitet ist

So können dann die Schritte Eingabe-Verarbeitung-Ausgabe viele tausend mal pro Sekunde ablaufen und im Programm "passiert" tatsächlich eigentlich nur dann etwas, wenn die Zeit reif dafür ist, z.B. einmal pro Sekunde, einmal pro Minute oder einmal alle 10 Minuten.

im Programm "passiert" tatsächlich eigentlich nur dann etwas, wenn die Zeit reif dafür ist, z.B. einmal pro Sekunde, einmal pro Minute oder einmal alle 10 Minuten.

Sehr klare und schöne Erklärung, finde ich! Fehlt nur " ... oder wenn ein Ereignis eintritt, auf das reagiert werden soll: sei es ein Signal von aussen ( Taster, Alarm-Kontakt Änderung ), ein Serielles Eingabe-Kommando oder gar die Anfrage eines (Ethernet) Client "

Da loop sehr schnell ist, braucht man für solch spontane Ereignisse meist keine Interrupt-Behandlung.