Pages: [1] 2   Go Down
Author Topic: Programm läuft von alleine los - LED glimmt - geht es schneller ?  (Read 1727 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

* Jens_Analogwerte_lesen.ino (2.21 KB - downloaded 32 times.)

* Plan.png (92.08 KB, 1193x679 - viewed 41 times.)
* LOG.txt (34.59 KB - downloaded 26 times.)
« Last Edit: April 21, 2013, 07:01:31 am by DrThunderhell » Logged

Switzerland
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Logged

Austria
Offline Offline
Full Member
***
Karma: 2
Posts: 107
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Du hast break; in den einzelnen case-Abfragen vergessen. Bei dir werden alle "cases" schon beim ersten Programmdurchlauf abgearbeitet.

Code:
switch (Zustand)
  {
  case 0:  //waiting for start
    digitalWrite(FGL1, LOW);
    if (WertTaster == HIGH)
    {
      Starttime=millis();
      Zustand = 1;
    }
    break;
  case 1:  //Startdelay
    if ((millis()-Starttime)>=Startdelay)
    {
      digitalWrite(FGL1, HIGH);
      Zustand = 2;
    } 
    break;
...

Ein freier/unbeschalteter Analogeingang wir immer irgendetwas anzeigen, weil das Potential nicht definiert ist, d.h. Es wird zwischen 0 und 5V liegen.

Die Variable Starttime muss unsigned long sein, wie t3d_et schon erwähnt hat.

Grüße,
J3RE
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok Danke, hat prima funktioniert.

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?
Logged

Offline Offline
God Member
*****
Karma: 12
Posts: 578
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Baudrate der seriellen Ausgabe auf Maximum bringt noch was.
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Was ist denn maximal möglich ?

es wird doch vorgeschlagen mit 9600 zu arbeiten, kann da nichts kaputt gehen?
Logged

Wien
Offline Offline
Edison Member
*
Karma: 27
Posts: 1845
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

nein, mit der baudrate kannst Du nichts kaputtmachen, da wird kein strom zu hoch oder so...

es kann nur passieren, daß bei zu langem kabel oder schlechtem kabel die kommunikation nicht mehr zuverlässig ist.

gruß stefan
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
God Member
*****
Karma: 10
Posts: 721
42
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: April 21, 2013, 08:04:20 am by Marcus W » Logged


Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hm ok, klingt eindeutig.
Aber ist es nicht trotzdem irgendwie möglich das Programm schneller zu machen oder noch abzuspecken?

Ich hab auch was von nem prescaler gelesen, habs aber nicht ganz geschnallt, was macht dieser?

Wärs möglich die Werte permanent über nen Timer interrupt auszulesen? Das Programm kann ja "langsamer" laufen
Logged

Offline Offline
Edison Member
*
Karma: 38
Posts: 1152
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Code:
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
Code:
float VoltageA0 = WertA0*(5.0/1023.0);
könntest du ändern in
Code:
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
Code:
Timestamp0 = micros()
dann, vor Beginn der Ausgabe
Code:
Timestamp1 = micros()
und in der Ausgabe dann
Code:
Serial.print(Timestamp1 - Timestamp0)
.

Gunther
« Last Edit: April 21, 2013, 10:41:16 am by guntherb » Logged

Grüße
Gunther

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.

Gruß Jens
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2983
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

@Gunther:
Quote
das spart eine floating point multiplikation.
Mein (und dein) avr-gcc Compiler ist so schlau, dass er das selber merkt:

Code:
void setup() {
float VoltageA0 = analogRead(A0)*(5.0/1023.0);
//float VoltageA0 = analogRead(A0) / 204.6;
Serial.begin(115200);
Serial.print(VoltageA0);
}
void loop() {}
Ü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")




 
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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).
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2983
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Wenn es eh kein Mensch direkt lesen soll:

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
« Last Edit: April 21, 2013, 05:11:20 pm by michael_x » Logged

Pages: [1] 2   Go Up
Jump to: