Hallo zusammen, ich versuche gerade einen DS18B20 Temperatursensor über Arduino anzusprechen. Der Sensor ist an eine digitalen Port angeschlossen, der 4,7k Widerstand ist eingelötet. Der Testsketch liefert mir vertrauenswürdige Temperaturen. Ich nutze die OneWire und DallasTemperature Libaries. Soweit so gut. Nun habe ich aber das Problem, dass ich die gemessene Temperatur im Multiplexingbetrieb über eine LED Matrix ausgeben will. Der Befehl zum Auslesen der Temperatur sensors.getTempCByIndex(0) aber ungefähr 750ms braucht, bis man einen Wert hat. Das stoppt natürlich das Multiplexing, da es ja im gleichen Loop-Statement steht. Als Resultat flackern natürlich die LEDs wie verrückt. Weiß jemand von euch Rat, wie ich das Problem lösen kann? Gruß Cornelius
Multiplexing in einem Timer-Interrupt erledigen.
Kann ich dort auch das Auslesen des Temperatursensors erfolgen lassen und den Wert dann z.B. im Sekundentakt rausschreiben lassen, damit der Multiplexingcode das Ganze übernehmen kann?
Erste frage wie betreibst du den Temperatur sensor? 12Bit Auflösung? Laut Datenblatt braucht er für 12Bit 750ms Conversion time. Da geht die 1-Wire Kommunikation mit wenigen µs bis ms nicht mit ein. In der Zeit könnte man ja vieles machen wenn man nicht, wie ich vermute, in einer delay loop wartet. Also entweder eine vernünftige Library schreiben oder einen scheduler benutzen. Oder ganz simpel seltener messen dann flackert es nicht mehr so.
Cornelius Franz schrieb: > Das stoppt natürlich das Multiplexing, Nein! Das darf nicht passieren. > da es ja im gleichen Loop-Statement steht. Das ist falsch. Cornelius Franz schrieb: > Kann ich dort auch das Auslesen des Temperatursensors erfolgen lassen > und den Wert dann z.B. im Sekundentakt rausschreiben lassen, damit der > Multiplexingcode das Ganze übernehmen kann? Nur wenn Du Deinen Fehler behalten möchtest und weitere dazu ... Im Timerinterrupt wird das Display regelmässig aufgebaut. Die Daten kommen aus dem RAM oder Registern. Im Hauptprogramm wird der Temp.-Sensor abgefragt, dessen Werte dort in das RAM oder die Register geschrieben werden. Gruß Jobst
Ich hatte es erstmal auf die einfache Tour probiert und diesen Code hier in mein Programm eingebaut: #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 13 /*-(Connect to Pin 13 )-*/ OneWire ourWire(ONE_WIRE_BUS); DallasTemperature sensors(&ourWire); void setup() { sensors.begin(); } void loop() { sensors.requestTemperatures(); // Send the command to get temperatures Serial.print(sensors.getTempCByIndex(0)); Serial.println(" Degrees C"); } Das Multiplexing ist so definiert, dass der Wert einer Integervariable als Eingabe in folgender Form genügt, um die Temperatur als große Zahl auf einer 12x11 LED Matrix darzustellen: TempOutside = sensors.getTempCByIndex(0); clearScreenBuffer(); for (int i = 0; i < 7; i++) { matrix[1 + i] |= pgm_read_byte_near(&(ziffern[TempOutside/10][i])) << 12; matrix[1 + i] |= pgm_read_byte_near(&(ziffern[TempOutside%10][i])) << 6; } break; Da der erste Befehl (TempOutside = sensors.getTempCByIndex(0);) so viel Zeit braucht, stoppt natürlich das Mulitplexen bzw. flackert die Matrix wie verrückt. Gruß Cornelius
>stoppt natürlich das Mulitplexen bzw. flackert die Matrix >wie verrückt. Und irgendwann gehen dann LEDs wegen Überstrom kaputt;)
Wieso das? Im normalen Betrieb passiert doch auch nichts...
@ Cornelius Franz (firlefranz) >Wieso das? Im normalen Betrieb passiert doch auch nichts... Lies was zum Thema LED-Matrix und Interrupt. Kurzfassung. Das Multiplexen packt man in einem Timer-Interrupt, der alle ??ms ausgeführt wird. Der unterbricht dann auch mehrfach den Programmablauf in der Hauptschleife, das tut der aber nicht weh. Langsame Sachen wie das Auslesen mancht man in der Hauptschleife, ggf. gesteuert per Flags vom Interrupt. Alles nix neues für die Welt, für dich aber schon. Darum lerne von den Leuten, die das schon erfolgreich getan haben.
Hallo zusammen, ich habe es soweit geschafft das Multiplexing in die Timer1-Schleife zu packen. Es funktioniert auch soweit. In der normalen loop()-Schleife wird zuverlässig der Sensor ausgelesen und der korrekte Wert auf der Matrix dargestellt. Nun sind aber zwei neue Probleme hinzu gekommen. Die Eingabe (drei Kurzhubtaster) wird am Mikrocontroller über die Pins 5, 6 und 7 angesteuert. Packe ich die Funktion, die mir die Modi ändert, indem sie die Befehle der Buttons umsetzt mit in die Timer-Schleife wird die Eingabe nicht weiter verarbeitet. Setze ich die Zeilen in die normale loop()-Schleife funktioniert es zwar, wird aber natürlich wieder vom Temperatursensor ausgebremst. Daher muss ich also immer gut eine Sekunde lang auf den Taster drücken, bis die Eingabe akzeptiert wird. Zudem stürzt dann die Firmware bei einem bestimmten Modus einfach ab. Die LED für die Echtzeituhr blinkt nicht mehr und die ganze Geschichte ist nur durch einen Reset des Atmega aufzulösen. Müsste die Buttongeschichte rein theoretisch auch in der Timer-Schleife funktionieren, oder ist der Weg, den ich hier gewählt habe der einzig Mögliche? Gruß Cornelius
Warum wartest du 750ms in der Hauptschleife, ohne irgendetwas anderes zu tun? Du hast zum Zeitmessen doch den Timer. C-Dummycode:
1 | Interrupt Handler { |
2 | Multiplexe; |
3 | Zähle n um 1 hoch |
4 | }
|
5 | |
6 | |
7 | Main { |
8 | ...
|
9 | while (1) { |
10 | wenn auslesen startet { |
11 | n = 0; |
12 | starte wandlung; |
13 | }
|
14 | behandle taster und modi; |
15 | wenn (n mindestens so groß, dass 750 ms vorbei) { |
16 | lies wert vom Sensor |
17 | }
|
18 | }
|
19 | }
|
Über n muss man sich noch ein paar Gedanken mehr machen (z.B. Überlauf verhindern), aber das Prinzip sollte klar sein. Max
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.