Offline
Newbie
Karma: 0
Posts: 6
|
 |
« on: November 19, 2012, 02:02:25 pm » |
Hallo Leute Ich muss In einem Interrupt grosse Delay Zeiten generieren, brauche ca. 1. Stunde und delay zeiten von 1-5 Sekunden zur überwachung einer Brennstoffzelle. Die Zeiten müssen nicht genau sein . delay Funktioniert ja leider nich. Ich habe hier eine Anleitung gefunden aber leider noch nicht begriffen http://arduino.cc/forum/index.php?topic=29867.0;wap2kann mir jemand helfen ?
|
|
|
|
|
Logged
|
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3310
|
 |
« Reply #1 on: November 19, 2012, 02:19:02 pm » |
Brauchst Du denn wirklich einen Interrupt? Ist der Impuls so kurz, dass Du ihn nicht im normalen loop() erfassen kannst?
Wenn es mit Interrupt gehen soll, dann kann Du das wie im von Dir geposteten Link machen, also im Interrupt ein Flag setzen (Achtung: volatile-Deklaration nicht vergessen) und dieses im loop() wieder abfragen (und natürlich zurücksetzen). Wenn Du Verzögerungen möchtest, würde ich als Flag gleich den Wert von millis() auslesen und setzen, dann kannst Du von dem Wert aus Vergleiche machen. Poste den Code, den Du hast, dann können wir Dir zeigen, wo das eingebaut werden muss.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #2 on: November 19, 2012, 03:16:10 pm » |
Hey Danke viemal für deine Antwort ! Den Standby Modus möchte ich komplett in einem Interrupt Programmieren. Ich schreibe Dir hier einen Teil meines codes. Im Void Standby sollte ich ein Delay haben vor dem Befehl digitalWrite(CellPlus, LOW); (Beispiel) Ich muss wohl den Befehl irq_flag im void loop Programmieren ?! Danke ! int Taster=7; //Taster int Zschloss=2; // Zündschloss Auto int Modus=9; //Fahrmodus /Zyklus oder Full Power int Led=13; //Kontroll LED int CellGND= 12; // Autput Cell GND int CellPlus= 11; // Autput Cell + int CellCharge=10; // Output Umschalt-Relais 1=Messen 0=Laden int Messen = A0; // Input Pin für Messzyklus 1,5V=300 3V=600 volatile int Messwert = 0; // variable zum speichern von Input Analog 0 volatile byte irq_flag = 0; // globale variable, "volatile", da in irq verwendet (ist ein muss) int Modus_Wert = 0; //variable zum speichern von Zyklus oder Full Power long letzteMillis = 0; // initialisiere Variable fuer den Zeitpunkt der letzten LED-Aktualisierung long intervall = 20000; // Intervall, in dem die LED blinkt (Millisekunden), nur Beispiel
void setup() { Serial.begin(9600); pinMode(Led,OUTPUT); //Kontroll LED Digital Output 13 pinMode(CellGND, OUTPUT); // CellGND Digital Output 12 pinMode(CellPlus, OUTPUT);// CellPlus Digital Output 11 pinMode(CellCharge, OUTPUT);//Umschalt-Relais 1=Messen 0=Laden pinMode(Zschloss,INPUT); // Zündschloss Digital Input 8 pinMode(Taster,INPUT); // Taster Digital Input 7 pinMode(Modus,INPUT); // Fahrmodus 1=Full Power 2=Zyklus int letzter_Tasterzustand = LOW; int led_state = LOW;
attachInterrupt(0, Standby, LOW); }
void loop() { //Fahrmodus
digitalWrite(CellCharge, LOW); delay(10); digitalWrite(CellGND,LOW); delay(10); digitalWrite(CellPlus,LOW); Modus_Wert = digitalRead (Modus);
while (Modus_Wert==HIGH) { //if (digitalRead(Zschloss)==LOW) //{ //break; //} digitalWrite(CellGND,HIGH); delay(1000); digitalWrite(CellPlus,HIGH);
if (digitalRead(Modus)==LOW) { break; }
} digitalWrite(CellPlus,LOW); delay(1000); digitalWrite(CellGND,LOW); delay(10); digitalWrite(CellCharge,LOW); delay(10);
}
void Standby()//STANDBY LOOP { digitalWrite(CellCharge, LOW); irq_flag = 1000; if(irq_flag == 10000) { /* sende den ping */ irq_flag = 0; // ruecksetzen des flags } digitalWrite(CellPlus, LOW); }
|
|
|
|
« Last Edit: November 19, 2012, 04:21:47 pm by uwefed »
|
Logged
|
|
|
|
|
Forum Moderator
BZ (I)
Offline
Brattain Member
Karma: 162
Posts: 15752
+39 349 2158303
|
 |
« Reply #3 on: November 19, 2012, 04:28:03 pm » |
Ich hab den Kode nicht verstanden. Beschreib mal genau was Arduino machen soll. Grüße Uwe
|
|
|
|
|
Logged
|
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3310
|
 |
« Reply #4 on: November 19, 2012, 08:13:43 pm » |
attachInterrupt(0, Standby, LOW); Du bist Dir schon im Klaren, was das macht? Der Interrupt-Handler "Standby" wird so lange immer wieder ausgeführt, wie Pin 2 LOW ist. In dieser Zeit wird kein anderer Code ausgeführt. Ist das wirklich das, was Du willst? Ich gehe mit uwefed einig, dass Du erklären solltest, was der Arduino genau machen soll und welche Bedeutung die Ein- bzw. Ausgänge haben.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #5 on: November 20, 2012, 05:41:08 am » |
Beschreib bitte genau was du machen willst. Hier passen ein paar Begriffe nicht zusammen. Interrupt -> für Prozesse die Zeitkritisch bearbeitet werden müssen (Reaktion auf Ereignis) Standby -> Bereitschaftsbetrieb (Ein gerät das darauf wartet, dass es wider Arbeiten soll) meinst du vielleicht Sleep Mode zu Energie sparen? Wenn ein bestimmter Programmteil für eine bestimmte zeit nicht ausgeführt werden soll dann verwende einfach mills() im loop. Wenn du Strom sparen willst schau dir das an: http://www.mikrocontroller.net/articles/Sleep_Modehttp://arduino.cc/playground/Learning/ArduinoSleepCodeDu kannst ihn z.B. durch eine RTC mit einem Interrupt wecken.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #6 on: November 20, 2012, 06:50:10 am » |
OK ich muss wohl den Code noch weiter erklären. Ich möchte Im Interrupt eine Standby Zeit (die fest definiert ist!) von ca. 1.Stunde in dieser Zeit soll der Arduino gar nichts machen !! Nachher wird ( im Interrupt) ein Mess und ev. Ladezyklus ausgeführt. Den habe ich aus dem Code rausgenommen. Die Standby Void soll aber jederzeit unterbrochen werden können mit Pin 2- Void loop // Fahrmodus.
Der Begriff Standby ist vielleicht etwas verwirrlich gewesen ?
Arduino soll einfach nach abstellen vom Zündschloss Pin 2 ca 1 Stunde gar nichts machen im Void Standby nachher kommt da schon noch ein Programm Code den ich rausgelöscht hab.
Das ist mein Erstes Arduino Proyekt kann sein das es (für einige ) keinen Sinn macht so lange wartezeiten in einen Interrupt zu Programmieren ?!
Danke euch allen für Eure Antworten
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #7 on: November 20, 2012, 07:52:44 am » |
Erklär bitte warum das in einen Interrupt soll? Das macht keinen Sinn. Ein Interrupt ist dazu da das regulär laufende Progrmm für eine kurze Aktion zu unterbrechen z.B. um auf Tastendrücke oder Impulse reagieren zu können. Wenn du deinen "Standby" im Interrupt machst ist dieser auch nicht unterbrechbar. Dein "Standby" gehört also in den loop. Warum nimmst du den Mess- und Ladezyklus raus? Entscheide dich ob du was machen willst oder nicht. So könnte das Ganze aussehen:
attachInterrupt(0, Fahrmodus, CHANGE );
loop() { while (fahrmodus == false && Zeit < 1h ) {-> Mach deinen Mess- und Ladezyklus} while (fahrmodus == true ) {-> Mach das was du zum fahren brauchst} }
Fahrmodus(){ if (PIN2 == LOW) {Fahrmodus = false} if (PIN2 == HIGH) {Fahrmodus = true}
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #8 on: November 20, 2012, 12:21:23 pm » |
Wie gesagt das ist mein erstes Arduino Projekt. Ich dachte mir eben das es so einfacher ist die 2 Programmteile zu schreiben, da der Fahrmodus und der Standbymodus unabhängig voneinander laufen und ich immer durch Pin 2 den Modus wechseln wollte. Dass die Delay Funktion nicht geht im Interrupt wusste ich anfangs eben noch nicht.
Mein Code ist auch noch lange nicht fertig. Ich blieb eben bei diesm Delay problem stehen... Wie ich aber jetzt sehe ist es wohl nicht möglich im Interrupt eine "Verweilzeit" zu Programmieren die dann jederzeit durch PIN 2 unterbrochen werden kann ???
Danke nochmals
|
|
|
|
|
Logged
|
|
|
|
|
Switzerland
Offline
Faraday Member
Karma: 69
Posts: 3310
|
 |
« Reply #9 on: November 20, 2012, 12:34:54 pm » |
Wie ich aber jetzt sehe ist es wohl nicht möglich im Interrupt eine "Verweilzeit" zu Programmieren die dann jederzeit durch PIN 2 unterbrochen werden kann ??? Nein, das ist so nicht möglich, jedenfalls nicht sinnvoll. Was Du hier brauchst, wird in Programmiererkreisen State Machine genannt. Du hast also verschiedene Zustände und in jedem Zustand existiert dann ein Code-Teil, der definiert, wie sich der Prozessor hier zu verhalten hat. Ein Interrupt-Handler wäre aber ein denkbar schlechter Ansatz, eine solche State Machine zu implementieren. In Pseudo-Code sähe das dann etwa so aus: byte status = 0; uint32_t start_time = 0;
void setup() { }
void loop() { if (status == 0) { // führe Dinge aus if (button_pushed) { status = 1; // wechsle in den nächsten Zustand } } else if (status == 1) { start_time = millis(); // hier können andere Dinge ausgeführt werden if (millis() - starttime > 3600000L) { // eine Stunde vorüber status = 0; } } }
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Faraday Member
Karma: 16
Posts: 3196
20 LEDs are enough
|
 |
« Reply #10 on: November 20, 2012, 02:32:57 pm » |
Wie kommt Ihr auf das Brett, daß Interrupts nichts für lange Delays sind? Interrupts sind sehr sinnvoll für lange Delays. Vor allem dann wenn man Strom sparen muß. Allerdings ist der Arduino nicht wirklich brauchbar wenn man Strom sparen muß/will.
D.h. Timer einstellen, laufen lassen und dann den Prozessor schlafen legen und nur mit Interrupt aufwachen. Leider kann man mit dem Arduino ohne Tricks keine 1h Delays hinbekommen. Also entweder zusätzlich eine RTC oder per Interrupt immer wieder aufwachen lassen, per Programm weiterzählen und dann wieder schlafen legen.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 6
|
 |
« Reply #11 on: November 20, 2012, 03:49:28 pm » |
Hey Leute Merci nochmals !
Dieses Forum ist ja super !
Weil ich in meinem Code immer wieder Delays von 1-3 Sekunden habe, dachte ich es sei einfacher den "Modus" meiner Brennstoffzelle mit einem Interrupt zu Programmieren, da der Code ja bei einem Interrupt immer sofort unterbrochen wird.
Danke Psyon für den State Machine Code ! Jetzt muss ich wohl einfach alle Delays in meinem Code durch eine Zählschleife in Milisekunden Programmieren sonst bleibt das Programm ja immer beim Delay hängen und schaltet nicht sofort um wenn ich den Modus (Status) verändere?? Ebenfalls wenn ich das richtig sehe muss in jeder schleife eine Abbruchbedibgung einbauen ?
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
BZ (I)
Offline
Brattain Member
Karma: 162
Posts: 15752
+39 349 2158303
|
 |
« Reply #12 on: November 20, 2012, 04:41:58 pm » |
Ebenfalls wenn ich das richtig sehe muss in jeder schleife eine Abbruchbedibgung einbauen ? Kontrollen mit millis() ob die Zeit schon vorbei ist geht davon aus, daß die Kontrolle sehr oft gemacht wird (loop()_funktion läuft permanent durch weil nichts gemacht wird. Erklärung für "ganze" Männer: Du schaust alle Minute auf die Uhr, ob die Kartoffeln gekocht sind und stehst erst vom Sofa auf, wenn die Zeit um ist, damit Du das Fußballsiel verfolgen kannst.  Die Kontrolle für die MODUS-Änderung braucht nur einmal in der Schleife sein. Grüße Uwe
|
|
|
|
« Last Edit: November 20, 2012, 04:50:06 pm by uwefed »
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 82
|
 |
« Reply #13 on: November 20, 2012, 05:39:43 pm » |
Vor allem dann wenn man Strom sparen muß. Allerdings ist der Arduino nicht wirklich brauchbar wenn man Strom sparen muß/will.
Das ist aber nicht das was der TO machen will. Ebenfalls wenn ich das richtig sehe muss in jeder schleife eine Abbruchbedibgung einbauen ?
Ja. Ohne Abbruchbedingung bleibt man sonst ewig in der Schleife -> Endlosschleife. Der loop ist z.B eine Endlosschleife. Der fängt immer wieder von vorn an. Wenn der loop z.B. nur einmal ausgeführt werden soll setzt man am Ende ein while(true) da bleibt der Controller dann drin hängen bis man Reset drückt.
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Faraday Member
Karma: 16
Posts: 3196
20 LEDs are enough
|
 |
« Reply #14 on: November 21, 2012, 02:21:54 pm » |
Also ich würde in so einem Fall alles in setup() packen und gar nichts in loop(). Am Ende von loop() mit einer for(;  ; Schleife zu stoppen finde ich schräg.
|
|
|
|
|
Logged
|
|
|
|
|
|