Hi,
Genau so.... oder bleibt er low nur solange IR-signal empfangen wird?
gruß inka
Hi,
Genau so.... oder bleibt er low nur solange IR-signal empfangen wird?
Gruß
Dirk
hi,
nun habe ich mir das leben etwas einfacher gemacht, mit diesem
Code:while(true) { for(j = 0; j < 120; j+=10) { writeChar('\n'); writeInteger(j, DEC); writeChar('\n'); uint8_t i = 0; for(i = 0; i < 199; i++) { temp_IR[i] = read_IR_value(); feld_IR[i] = temp_IR[i]; writeIntegerLength(temp_IR[i],DEC,4); if(i % 12 == 0) writeChar('\n'); else writeString_P(" | "); mSleep(20+j); } } /**************************/ uint8_t key_1 = getMultiIOPressedButtonNumber(); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; /**************************/ }
gewann ich "auf einen rutsch" diese ausgabe:
es hätte sicher mehrere auswahlmöglichkeiten für die größe des "mSleep" gegeben, ich habe mich für die variante 50 entschieden - die gefiel mir in ihrer regelmäßigkeit am besten - jetzt blinkt die kontroll-LED auf der bake mit diesem
deckungsgleich - ca. 4x pro sekunde - zusammen mit der roten LED an der multiIO auf eine entfernung von 4m...Code:while(true) { temp = read_IR_value(); mSleep(50); if (temp == 0) { setMultiIOLED3(1); setMultiIOLED3(0); } /**************************/ uint8_t key_1 = getMultiIOPressedButtonNumber(); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; /**************************/ }![]()
gruß inka
hi,
jetzt habe ich versucht die abfrageschleife mit dem mSleep(50) verzögerung durch eine mit stopwatches zu ersetzen:
die signale der bake werden offensichtlich nicht empfangen, die LED reagiert nicht...Code:while(true) //start endlosschleife startStopwatch1(); // start stopwatches { if(getStopwatch1() > 100) // messe IR empfang wenn 100ms abgelaufen sind { temp = read_IR_value(); //einlesen IR-empfang // mSleep(50); if (temp == 0) //abfrage treffer/empfang { setMultiIOLED3(1); //LED an setMultiIOLED3(0); //LED aus setStopwatch1(0); //stopwatches auf null stellen } } /**************************/ uint8_t key_1 = getMultiIOPressedButtonNumber(); //tastenabfrage key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; /**************************/ } break;
muss ich die dauer der einzelnen funktionen in der whileschleife kennen, oder gibt es eine andere möglichkeit (außer try & error) herauszufinden warum der zeitpunkt der 100ms (aber auch bei 50ms geht es nicht) falsch ist?
gruß inka
Hi,
Kommentare im Codeblock!
Code:while(true) //start endlosschleife startStopwatch1(); // start stopwatches <== Das gehört VOR die while(true) Schleife { if(getStopwatch1() > 100) // messe IR empfang wenn 100ms abgelaufen sind { temp = read_IR_value(); //einlesen IR-empfang // mSleep(50); if (temp == 0) //abfrage treffer/empfang { setMultiIOLED3(1); //LED an setMultiIOLED3(0); //LED aus setStopwatch1(0); //stopwatches auf null stellen <== Gehört ans Ende der if(getStopwatch1() > 100) Klammer, siehe <<<>>> ! } // <<<>>> } /**************************/ uint8_t key_1 = getMultiIOPressedButtonNumber(); //tastenabfrage key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; /**************************/ } break;
Gruß
Dirk
Hi Dirk,
danke für die korrekturen, es funktioniert nun...
Würde für mein verstzändnis der stopwatches bedeuten, dass man diese an einer beliebigen stelle im vorderen bereich des programmes startet (einmal) und dann im ersten durchlauf der while(true) schleife auf null stellt und dann im zweiten durchlauf den Ir-empfang prüft...
zwei dinge haben sich jetzt herausgestellt:
1) die probleme beim empfang der von der bake gesendeten signale gründeten nicht in der zu kleinen leistung der IR-LEDs, sondern in der schlechten koordination des senders mit dem empfänger. Ich habe jetzt die vorwiderstände der IR-dioden wieder auf 47 ohm erhöht, der empfang funktioniert nach wie vor über ca. 4 meter.
Im gegenteil: Ich habe nun beim erkennen der richtung aus der die IR-strahlen kommen probleme mit reflektionen, auch über zwei "ecken"! Der bereich um die 5cm über dem boden ist quasi IR-verseucht...
Da muss ich mir noch etwas einfallen lassen (bündeln des sendestrahls und einengen des empfangskorridors)...
2) hat zwar mit der IR-bake nur am rande zu tun, ein problem ist es aber:
das starten der vier teilprogramme über die 4 multiIO taster.
zwischen diesem
und diesemCode:------------------------------------------ clearLCD(); pressedMultiIOButtonNumber = getMultiIOPressedButtonNumber(); setCursorPosLCD(0, 0); writeStringLCD("1: test_einzelsignal"); setCursorPosLCD(1, 0); writeStringLCD("2: test_feldvariable"); setCursorPosLCD(2, 0); writeStringLCD("3: Suche der bake"); setCursorPosLCD(3, 0); writeStringLCD("4: test_button_4"); mSleep(1500); uint8_t key = getMultiIOPressedButtonNumber(); ----------------------------------------------
liegen jeweils die vier programmteile. Die software reagiert sehr eigenartig auf das drücken der buttons: mal garnicht, mal mit kurzem start mit sofort erfolgtem break, mal richtig. Wie könnte ich da was verbessern? Verzögerungen in der tastenabfrage z.b.?Code:------------------------------------------------- uint8_t key_1 = getMultiIOPressedButtonNumber(); //tastenabfrage key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; ---------------------------------------------
ich habe hier wegen der besseren verständlichkeit meiner frage bzw. meines problems den code einer schablobe für die abfrage der vier tasten eingefügt (obwohl das problem hier kaum auftritt) - hängt das mit der dauer des programms, welches ausgeführt wird zusammen?
btw: die korrekturwerte für die taster sind in der RP6Control_MultiIO.h eingetragen...
Code:#include "RP6ControlLib.h" #include "RP6I2CmasterTWI.h" #include "RP6Control_MultiIOLib.h" #include "RP6Control_I2CMasterLib.h" #include "RP6ControlServoLib.h" #include "standard.h" #define I2C_RP6_BASE_ADR 10 /*********************I2C-fehlermeldungen******************/ /* void I2C_transmissionError(uint8_t errorState) //gibt I2C fehlermeldungen über LCD aus { clearLCD(); writeStringLCD_P("I2C ERROR -->"); setCursorPosLCD(1, 0); // line 2 writeStringLCD_P("TWI STATE: 0x"); writeIntegerLCD(errorState, HEX); } */ /*************** hauptprogramm ***********/ int main(void) { initRP6Control(); multiio_init(); initLCD(); //orientation_init(); setLEDs(0b1111); mSleep(500); setLEDs(0b0000); I2CTWI_initMaster(100); I2CTWI_setTransmissionErrorHandler(I2C_transmissionError); //aktiviert I2C fehlermeldungen showScreenLCD(" RP6Control M32", " schablone", " 4 taster " , " mit ruecksprung "); mSleep(2500); clearLCD(); while(true) { /*****************anzeige gedrückter buttons****************/ // clearLCD(); // accuspannung(); // mSleep(500); clearLCD(); pressedMultiIOButtonNumber = getMultiIOPressedButtonNumber(); // setCursorPosLCD(0, 0); // writeStringLCD("Button: "); // writeIntegerLCD(pressedMultiIOButtonNumber, DEC); setCursorPosLCD(0, 0); writeStringLCD("1 - button_1_test"); setCursorPosLCD(1, 0); writeStringLCD("2 - button_2_test"); setCursorPosLCD(2, 0); writeStringLCD("3 - button_3_test"); setCursorPosLCD(3, 0); writeStringLCD("4 - button_4_test"); mSleep(1500); uint8_t key = getMultiIOPressedButtonNumber(); /********************funktion der buttons*********************/ if(key) { switch(key) { case 1:// setLEDs(0b0001); while(true) { uint8_t key_1 = getMultiIOPressedButtonNumber(); clearLCD(); setCursorPosLCD(0, 0); writeStringLCD("test button 1 "); mSleep(1500); clearLCD(); writeStringLCD("test break all "); mSleep(1500); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; } break; case 2:// setLEDs(0b0010); while(true) { uint8_t key_1 = getMultiIOPressedButtonNumber(); clearLCD(); setCursorPosLCD(0, 0); writeStringLCD("test button 2 "); mSleep(1500); clearLCD(); writeStringLCD("test break all "); mSleep(1500); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; } break; case 3:// setLEDs(0b0100); while(true) { uint8_t key_1 = getMultiIOPressedButtonNumber(); clearLCD(); setCursorPosLCD(0, 0); writeStringLCD("test button 3 "); mSleep(1500); clearLCD(); writeStringLCD("test break all "); mSleep(1500); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; } break; case 4:// setLEDs(0b1000); while(true) { uint8_t key_1 = getMultiIOPressedButtonNumber(); clearLCD(); setCursorPosLCD(0, 0); writeStringLCD("test button 4 "); mSleep(1500); clearLCD(); writeStringLCD("test break all "); mSleep(1500); key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; } break; } } } return 0; }
Geändert von inka (21.01.2014 um 11:32 Uhr)
gruß inka
Hi,
Ja... Das startStopwatchX(); brauchst du nur EINMAL am Programmanfang, d.h. später normalerweise nicht wieder.Würde für mein verstzändnis der stopwatches bedeuten, dass man diese an einer beliebigen stelle im vorderen bereich des programmes startet (einmal) und dann im ersten durchlauf der while(true) schleife auf null stellt und dann im zweiten durchlauf den Ir-empfang prüft...
Die Benutzung geht dann so:
if(getStopwatchX() > 100) // mach was alle 100ms
{
// Was alles zu tun ist ...
setStopwatchX(0); // Stopwatch auf Null stellen
}
Ich würde 2 Sachen ändern:Die software reagiert sehr eigenartig auf das drücken der buttons: mal garnicht, mal mit kurzem start mit sofort erfolgtem break, mal richtig. Wie könnte ich da was verbessern? Verzögerungen in der tastenabfrage z.b.?
1. In der SWITCH-CASE-Struktur sieh dir die while(true) Schleifen an: Alle Pausen (mSleep) dort und im Bereich "anzeige gedrückter buttons" müssen raus,- d.h.: Die Haupt-while(true)-Schleife muss ohne Unterbrechungen/Pausen ablaufen. Wenn man Texte länger lesen soll, müßte man das auch mit einer weiteren Stopwatch machen.
2. Die Zeile uint8_t key_1 = getMultiIOPressedButtonNumber(); brauchst du nicht. Es reicht: uint8_t key_1; (Grund: Weiter unten wird die Taste ja wieder eingelesen: key_1 = getMultiIOPressedButtonNumber(); )
Gruß
Dirk
Hi Dirk,
macht das programm wirklich ALLE 100ms etwas oder immer dann wenns mal größer als 100ms ist? Also 101/102/105 - wanns gerade abgefragt wird? Ich glaube, wenn die funktionen im ablauf länger/komplizierter werden klappt es mit der abfrage nicht mehr so genau?
ich habe nun den zweiten abschnitt meinesdurch die stopwatches ergänzt, es läuft im prinzip, aber eben nur im prinzip. Mit dem mSleep(50) war die ausgabe so:Code:case 2: setLEDs(0b0010); writeString_P("\n\n messung feldvariable\n\n"); writeChar('\n'); initRP6Control(); initLCD(); startStopwatch2();//neu while(true) { uint8_t i = 0; for(i = 0; i < 199; i++) { temp_IR[i] = read_IR_value(); feld_IR[i] = temp_IR[i]; if(getStopwatch2() > 50)//neu { writeIntegerLength(temp_IR[i],DEC,4); if(i % 12 == 0) { writeChar('\n'); setStopwatch2(0);//neu } else { writeString_P(" | "); setStopwatch2(0);//neu } // mSleep(50);//entfallen } } /**************************/ uint8_t key_1; key_1 = getMultiIOPressedButtonNumber(); if(key_1 != 0) break; /**************************/ } break;
Code:0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004
mit stopwatches ist sie so:
der code raegiert nun williger auf den druck auf die buttons, kann ich die ausgabe regelmäßiger machen?Code:0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004 | 0004
gruß inka
Genau SO ist es, so steht es ja auch im Code, nämlich >100. Versuche ruhig mal "=100", dann wird es noch schlimmer werden!
Was in einem harten Zeitraster abgearbeitet bzw. getestet werden soll, muss
- entweder schnell pollend, also häufiger als die Zeitzähleinheit angegangen werden
- oder besser noch: als (hochpriorer) Interrupt implementiert werden.
Hi inka,
Ja, genau. Es kann ja immer nur etwas alle 100ms gemacht werden, wenn die Hauptschleife, in der die if(getStopwatchX() > 100 steht, nicht regelmäßig wieder bei der Abfrage ankommt. Hat also die Hauptschleife so viel zu tun, dass sie z.B. für einen kompletten Durchlauf 200ms braucht, dann kann die o.g. Stopwatch-Abfrage natürlich auch nur alle 200ms laufen.macht das programm wirklich ALLE 100ms etwas oder immer dann wenns mal größer als 100ms ist? Also 101/102/105 - wanns gerade abgefragt wird?
Ist die Hauptschleife schnell (das sollte sie!), dann kommt das mit den 100ms ganz gut hin. Der Ablauf ist dann in der if(getStopwatchX() Schleife:
- Stopwatch > 100 ?
- Alles, was gemacht werden muss
- Stopwatch = 0
Das bedeutet auch, dass wenn "Alles, was gemacht werden muss" etwas länger dauert, diese Zeit zum Intervall noch addiert werden muss.
Wenn du wissen willst, mit welchem Stopwatchwert du in die Abfrage gehst, dann gib den Wert der Stopwatch doch am Anfang der if(getStopwatchX() Schleife aus. Dann kannst du sehen, wie die Intervalle aussehen: writeInteger(getStopwatchX(), DEC);
Was kann man machen:
- Hauptschleife optimieren (Sleeps raus, keine UART/WiFi/LCD-Ausgaben, kein Warten auf Bedingungen ...)
- Auch in den if(getStopwatchX() Schleifen keine Verzögerungen, wenn sie NUR ZUM MESSEN dienen. Daneben kann es natürlich auch noch solche Schleifen zur Textausgabe geben,- die braucht man aber meist selten (alle 0,5 oder 1 s).
Die Ausgabe wird "unregelmäßig", weil du in der for(i = 0; i < 199; i++) Schleife die Ausgabe mit einer Stopwatch machst. Dann passiert es manchmal, dass die for-Schleife schneller ist als die 50ms der Stopwatch, dann ist die Stopwatch noch <= 50 und eine Ausgabe wird übersprungen.der code raegiert nun williger auf den druck auf die buttons, kann ich die ausgabe regelmäßiger machen?
Du must die ganze Ausgabe in die Stopwatch-Abfrage bringen und darin nicht eine for-Schleife nehmen, sondern eine Schleife mit einem globalen Zähler.
Gruß
Dirk
Lesezeichen