Kann mir jemand mal helfen und bitte über meinen Quellcode schauen,
ich bin total neu in der Materie und kenn mich noch kaum aus. Hab einen Arduino Mega 2560.
Manchmal Funktioniert es manchmal nicht. Aber nach einem reset/oder upload läuft es immer von alleine los.
Die Funktion des Programms sollte sein:
Nach betätigen eines Tasters und einer Wartezeit werden 4 Schritte durchlaufen die jeweils den Ausgang für eine bestimmt Zeit ein- oder Ausschalten.
Währenddessen sollen 3 Analogeingänge und ein Digitaler eingelesen werden und der Taster nicht betätigt werden können.
Probleme:
nach Aufspielen des Programms läuft es los ohne das ich auf den Taster drücke.
manchmal kann ich mit dem Taster starten, manchmal nicht.
wenn der Zyklus einmal durchlaufen ist glimmt die LED noch und schaltet nicht komplett ab. (Habs auch mit der Internen an PIN13 versucht, selbes Phänomen)
Zusatz Fragen:
warum hab ich eine steigende Analoge Spannung von 1-2V obwohl ich noch keine Spannung angelegt habe? oder ist genau das der Grund?
Die Programmlaufzeit ist laut dem Logfile ca 30ms, geht das nicht schneller?
Als Anlage hab ich mein Programm, den Aufbau und das Logfile hinzugefügt.
Wär schön wenn sich jemand findet der mir helfen könnte.
gruß Jens
Läuft das Programm denn ansonsten normal ab? Wäre zur Sicherheit noch interessant, auch mal den "Zustand" zu loggen und natürlich den Ausgang an dem die LED angeschlossen ist.
Dass du an den analogen Eingängen Blödsinn misst, wenn nichts angeschlossen ist, ist normal.
Ein vorprogrammiertes Problem wirst du früher oder später mit der Zeitsteuerung haben. Integer gehen nur bis 32'768, dann überlaufen sie, das sind in ms also ca. 30 Sekunden. Mit unsigned long hast du ein bisschen mehr Luft.
Die breaks hab ich total vergessen^^ aber nachdem sie gesetzt wurden hat auch das glimmen der led aufgehört und es läuft auch nicht mehr von selber an.
Das mit den Int, unsigned Long wusst ich nicht.
was mich noch interessieren würde:
die Zykluszeit der Messungen sind laut logfile immer noch ca 40ms, kann man das Programm noch irgendwie schneller machen? was schluckt soviel Zeit?
ok, hab sie jetzt mal auf 115200 gesetzt, da gehts schon anders ab.
Zykluszeit 4ms.
Der Serialmonitor in dem Arduino Programm lässt sich nicht höher einstellen.
Geht noch mehr? wenn ja wie?
Sehr geil wär es wenn eine kontinuierliche Zykluszeit von 100ns oder so machbar wäre.
100ns sind 10-7 Sekunden oder 0,0000001 Sekunden. Der Takt deines Arduinos ist maximal 16Mhz also 106 Hertz oder 16.000.000 Zyklen pro sekunde... also 62.5ns pro Zyklus. In den 100ns Bereich wirst du fast unmöglich vordringen, da das Programm auch noch Laufzeit benötigt.
welchen Teil genau willst du denn schneller haben?
Man kann Programmteile, die nur seltener gebraucht werden in Zeitscheiben auslagern, dann bleibt die eigentliche loop() schlanker und schneller.
if (millis()> Zeitscheibe_1sek ) // Zeitscheibe wird alle 1000ms aufgerufen
{ Zeitscheibe_1sek = millis()+1000;
// mach was, was nur jede Sekunde erledigt werden muß
} // end Zeitscheibe_1sek
Allerdings wird die Ausführung der Loop bei der Zeitscheibe jedesmal kurz unterbrochen.
die Zeile float VoltageA0 = WertA0*(5.0/1023.0); könntest du ändern in float VoltageA0 = WertA0 / 204.6
das spart eine floating point multiplikation.
Um zu sehen, wie schnell dein Code wirklich ist, ohne Serial.print, kannst du an Anfang der loop() einen befehl setzen Timestamp0 = micros() dann, vor Beginn der Ausgabe Timestamp1 = micros() und in der Ausgabe dann Serial.print(Timestamp1 - Timestamp0).
Merci gunther für den Tip, hab ich gleich mal gemacht.
Wenn ich nur die Loopschleife messe hab ich 8-16 µs.
Kommt aber die Serielle Ausgabe hinzu sind es 2000-4000µs je Zyklus.
d.h. die Ausgabe bremst aus.
Ist es denn nicht möglich mit einem serial.print Befehl mehrere Variablen zu schicken. Evtl als Array oder so?
Oder kann ich die Baudrate noch mehr erhöhen als 115200? Wie kann ich es dann lesen, der Serial Monitor kann ja nur bis 115200.
Übersetzen für einen Uno liefert:
Binäre Sketchgröße: 3.932 Bytes (von einem Maximum von 32.256 Bytes)
Wenn ich den Kommentar in die obere Zeile setze, kommt der gleiche Sketch von 3.932 Bytes raus.
Aber ganz auf float verzichten bringt was...
Es gibt andere Terminal-Programme, die evtl. auf mehr als 115200 eingestellt werden können.
Ein 16MHz Arduino sollte auch noch 230400, 250000 oder noch mehr können, schau dir mal diesen Thread an.
Aber, als Mensch mitlesen geht etwa bis 9600, darüber brauchst du auf der PC-Seite sowieso ein Empfangsprogramm, dass die vielen Daten weiterverarbeitet (wie z.B. das erwähnte "Oszilloskop")
Mitlesen brauch ich es ja nicht, meine Messung startet und wird einfach mitgeloggt.
Das Ergebniss lass ich mir nacher irgendwo Grafisch darstellen zum Auswerten.
Aber es wär halt schöner, wenn es noch nen ticken schneller gienge als derzeit ~3ms/Zyklus. kontinuierlich (Beziehungsweise für einen variablen Messbereich zwischen 1 und 30 Sekunden).
Eine Zahl im Bereich 0 .. 256255 kann man mit 4 Buchstaben, z.B. "255," oder binär als 1 Zeichen übertragen.
Dadurch kriegst du statt 3 ms z.B. 1 ms hin.
Mit anderen Daten bringt Binär statt Text nicht ganz so große, aber auch deutliche Verbesserungen.
Edit: 0...256 wären 257 verschiedene Werte, also einer zuviel. Sorry
michael_x:
Eine Zahl im Bereich 0 .. 256 kann man mit 4 Buchstaben oder binär als 1 Zeichen übertragen.
Da hast du was verwechselt oder!? 0-256 0-255 entspricht ja einem Byte, also 8 Bit, dafür kann man char oder uint8_t (unsigned Integer mit 8 statt 16 Bit) verwenden.
DrThunderhell:
Ist es denn nicht möglich mit einem serial.print Befehl mehrere Variablen zu schicken. Evtl als Array oder so?
du kannst natürlich eine char-Array füllen und das dann auf einmal ausgeben.
Vor allem würde ich die ganzen Texte "VoltageA0" usw. nur einmal an Anfang ausgeben, als Tabellenüberschrift, und später nur noch die Zahlen.
wenn du dann anstelle der leerzeichen ein char(9) (tab) ausgiebst, dann lässt sich das leichter einlesen, später.
Ein Modul für SD Karten steht mir hier nicht zur verfügung.
Das mit dem Array hört sich gut an, funktioniert aber leider nicht so richtig.
+= als operator kennt er nicht, außerdem hab ich ja verschiedene Variablentypen.
so war es vorher:
Serial.print(millis()-Starttime);
Serial.print("ms ");
Serial.print(analogRead(A0)*0.0048875855327468);
Serial.print("V ");
Serial.print(analogRead(A1)*0.0048875855327468);
Serial.print("V ");
Serial.print(analogRead(A2)*0.0048875855327468);
Serial.print("V ");
kann man denn den Typ konvertieren oder so, das alles Char oder String ist?
Oh, das habe ich übersehen, das ich hier ja strings verkettet habe!
ich habe es gerade mal nachgemessen: um 3 Floatwerte auf SD zu schreiben, brauche ich 18ms. ist also auch nicht schneller.
Allerdings soll es Optimierungen geben um die SD-Lib schneller zu machen.
(ein SD-Card reader kostet 2€ beim Chinesen
Zum konvertieren: hier fällt mir nur "sprintf" ein, ich weiß allerdings nicht, wie schnell das ist.
und noch was: wenn du die daten sowieso später am PC weiterverarbeiten willst, dann schreibe doch nur die gemessenen AD-Werte als integer.
Umrechnen kann der PC besser...
wenn ich die Voltage nicht als Float übernehme (gleich ausgerechnet in richtige Volt) sondern nur den eingelesenen Int Wert
unsigned int Zeit=(millis()-Starttime);
int Voltage1= (analogRead(A0));
int Voltage2= (analogRead(A1));
int Voltage3= (analogRead(A2));
int Eingang= (digitalRead(Taster));
int LED=(digitalRead(Ausgang));