für ein Projekt während unserer Ausbildung haben wir uns dafür ein Arduino gekauft, dementsprechend sind wir noch ziemliche Anfänger.
Nun zu meinem Problem.
Unser Projekt ist es das wir die Temperatur und den Wasserfüllstand auslesen wollen von einer Behälter.
Zum auslesen der Sensoren habe ich zwei Funktionen geschrieben und die Werte am Ende auf einem LCD eingeblendet werden.
Jetzt ist es so das in meinem Fall eine Funktion durchläuft die ein Ladebildschirm darstellt bei dem die Werte messen gewerten. Wenn dieser durchglaufen ist werden die Werte im Script aber wirklich erst ausgelesen und auf dem Bildschirm angezeigt werden und in der Zeit ist einige Sekunden nichts auf dem LCD.
Gibt es irgendwie eine Möglichkeit das während die Funktion mit dem Ladebildschirm durchläuft die Werte ausgelesen werden können und man direkt nachdem das fertig ist die Werte bekommt.
ich nehme mal an das Du da was falsch gemacht hast, zeig uns einfach mal Deinen Sketch damit wir das verstehen. Auf der aneren Seite gibts genug Beispiele um die Grundlagen zu lernen.So raten wir hier nur rum.
na da hast Du dir nicht gerade das beste zusammen kopiert.
was sollen die vielen delay in der fuction funcload(). Soll da ein Laufbalken dargestellt werden.? Wenn Du den balke darstellst kannst Du natürlich nichts anderes anzeigen. Dann hast Du da noch mal 5s Wartezeit drin.
Der Messvorgang selbst daurert eine knappe sekunde, mit den delay da drin. Also wann soll der Balken laufen, während der Sekunde Messzeit ? Dann kannst Du die Wartezeit während des Messvorganges nicht mit delay machen.
Die delay müssten grundsätzlich raus. Schau dir das Beispiel blink without delay an und suche hier nach Nachtwächter. Wenn Du das mal begriffen hast ist es ganz einfach.
Entweder mach ich was mit dem Button falsch oder das funktioniert nicht. Da passiert Garnichts wenn ich auf den Knopf drücke und wenn ich starte lädt das die ganze Zeit nur die Temperatur neu.
michael_x:
Mein lcd.begin() braucht zwei Parameter, welche lib verwendest du ?
ein älteres Bsp. Man kann das auslesen noch in eine Funktion packen mit verschiedenen Parameter, je nachdem ob man alle Sensoren auf einmal lesen möchte oder nur einzelne oder was auch immer.
Schau dir auch das Bsp. der Dallas Lib "WaitForConversion2" an.
/*
Arduino Mega 2560
Arduino IDE v1.8.6
*/
#include <OneWire.h>
#include <DallasTemperature.h>
// Data wire is plugged into port 12 on the Arduino
#define ONE_WIRE_BUS 12
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// change of your sensors adress or use "getTempCByIndex" and see below
DeviceAddress sensor1 = { 0x10, 0x40, 0xDD, 0xC3, 0x02, 0x08, 0x00, 0xB4 };
DeviceAddress sensor2 = { 0x10, 0x8A, 0x0B, 0xAC, 0x02, 0x08, 0x00, 0x2C };
DeviceAddress sensor3 = { 0x28, 0xFF, 0x60, 0xAC, 0x6B, 0x14, 0x03, 0xB3 };
int resolution = 9; // DS18S20 only 9bit, other 9...12
unsigned long lastTempRequest;
const unsigned int ConversionDelay = 750; // default 750ms, okay for all DS1820 types
bool AllowDallasTempRequest = true;
float TempSensor1; // Zwischenspeicher zum auslesen
float TempSensor2; // Zwischenspeicher zum auslesen
float TempSensor3; // Zwischenspeicher zum auslesen
void setup(void)
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT); // LED 13 auf Arduino Board
sensors.begin();
// set the resolution (Each Dallas/Maxim device is capable of several different resolutions)
sensors.setResolution(sensor1, resolution);
sensors.setResolution(sensor2, resolution);
sensors.setResolution(sensor3, resolution);
sensors.setWaitForConversion(false); // makes it async
}
void loop(void)
{
// Request a temperature conversion
if ( AllowDallasTempRequest == true )
{
sensors.requestTemperatures();
lastTempRequest = millis();
AllowDallasTempRequest = false;
}
// readout the Dallas sensors
if ( millis() - lastTempRequest >= ConversionDelay ) // waited long enough?
{
TempSensor1 = sensors.getTempC(sensor1); // 1. Dallas Sensor auslesen (Device Adresse)
TempSensor2 = sensors.getTempC(sensor2); // 2. Dallas Sensor auslesen (Device Adresse)
TempSensor3 = sensors.getTempC(sensor3); // 3. Dallas Sensor auslesen (Device Adresse)
AllowDallasTempRequest = true;
Serial.print(F("Temps:")); Serial.print('\t');
Serial.print(TempSensor1); Serial.print('\t');
Serial.print(TempSensor2); Serial.print('\t');
Serial.print(TempSensor3);
Serial.println();
}
// *** does other things *** //
heartbeat(500);
} // End of Loop
// ----------------------------------------------------------------------------------- //
void heartbeat (unsigned int interval) // Kontrolle ob Sketch blockiert
{
static unsigned long last_ms = 0;
static bool state = LOW;
unsigned long ms = millis();
if (ms - last_ms >= interval) {
last_ms = ms;
state = !state;
digitalWrite(LED_BUILTIN, state);
}
}
Wenn ich allerdings nun den Taster drücke, dann hängt es in einer schleife in der es immer zwischen "Neuer Wert" und "Temperatur" hin und her wechselt und die Temperatur ununterbrochen gemessen wird. Nach 1 Minute stoppt es dann, der LCD wird dunkel und es bleibt bei "Temperatur" stehen.
dann hängt es in einer schleife in der es immer zwischen "Neuer Wert" und "Temperatur" hin und her wechselt und die Temperatur ununterbrochen gemessen wird
Ja, das ist so programmiert.
Es wird permanent die Temperatur gemessen. Diese Messung wird künstlich 1 sec langsam gemacht. In dieser Zeit kommt immer wieder funcload dran, was alle 100 ms eine kleine LCD Ausgabe macht.
Gleichzeitig läuft noch die 1 Minute, nach der die LCD-Beleuchtung wieder abgeschaltet wird.
Ich hab nochmal eine Frage zu meinem "Ladebalken" den ich animieren will.
Ich habe jetzt das wie bekomme ich jetzt da eine Wartezeit von 100ms rein ohne delay() zu benutzen.
int funcload() {
int load;
//const unsigned long ms= millis();
lcd.setCursor(0,0);
lcd.print(" Ermittel Werte");
lcd.setCursor(0,1);
do {
a = a+1;
lcd.print(char(255));
//delay(100);
} while ( a <= 16 );
a = 0;
return load;
};
Ich verstehe das Prinzip von BlinkWithoutDelay zwar aber weiß nicht wie ich es umsetzen soll.
delay() durch eine andere blockierende Schleife zu ersetzen kann nicht das Ziel sein.
aber weiß nicht wie ich es umsetzen soll.
Du wirfst die Schleife raus!
So, dass die Funktion SOFORT wieder beendet werden kann.
Stattdessen merkst du dir die die jeweiligen nötigen Statusinformationen irgendwo anders.
Tipp:
Es ist völlig egal, ob die Funktion 10000 mal pro Sekunde aufgerufen wird...
Wichtig ist, dass sie selber weiß, wann sie was tun muss.
Ich verstehe das Prinzip von BlinkWithoutDelay zwar
Nein!
Wenn du es verstanden hättest, könntest du es einbauen.
Also: Weiter machen! (mit verstehen + üben)
Ich verstehe das Prinzip von BlinkWithoutDelay zwar aber weiß nicht wie ich es umsetzen soll
Der Trick ist, sich eine Startzeit zu merken und zu prüfen, wie weit man inzwischen ist.
Im einfachsten Fall macht man gar nichts, wenns noch nicht so weit ist. Aber das kann man anpassen.
Auf jeden Fall beschreiben die hintereinander geschriebenen Zeilen eines Sketches keinen zeitlichen Ablauf.
Manchmal ist es hilfreich, wenn eine Funktion zurückliefert, wie weit sie ist. Auf jeden Fall ist es Unsinn, etwas undefiniertes zurückzuliefern ( dein int load; )
@combie: die Schleife wird hier nur benutzt um eine Anzahl Zeichen auszugeben. Funktioniert hier nur, wenn die globale Variable a direkt vor dem Aufruf von funcload() neu gesetzt wird, und ist daher nicht sehr "elegant", aber eine "blockierende Schleife" ist was Schlimmeres.
@combie: die Schleife wird hier nur benutzt um .......
Genau dort steckt das Problem!
Anforderung:
Ich hab nochmal eine Frage zu meinem "Ladebalken" den ich animieren will.
Antwort:
Du wirfst die Schleife raus!
So, dass die Funktion SOFORT wieder beendet werden kann.
Stattdessen merkst du dir die die jeweiligen nötigen Statusinformationen irgendwo anders.
Also:
Die Schleife muss weg! (dabei bleibe ich)
Alternativ: Oder geschickt umgebaut werden um das Ziel zu erreichen.
Ich würde vermutlich Goto oder Switch benutzen, wenn ich die Schleife beibehalten wollte.
:o Für den Anfang ist es wohl leichter, die Schleife zu eliminieren. :o
Wenn man es falsch macht, kann es ein Problem werden. Aber das gilt ja fast immer
void ladebalken() {
lcd.setCursor(0,1);
do {
a = a+1;
lcd.print(char(255));
} while ( a <= 16 );
a= 0; // kann man eigentlich sogar weglassen
}
Das ist hässlich, aber keine "blockierende Schleife". !
Wenn a global definiert ist, müsste man diesen Schnipsel langsam mit abnehmenden a Werten aufrufen:
int a;
void loop() {
const byte DELAY=100;
static unsigned long lasttime;
if (millis() - lasttime >= DELAY) {
// hier der 100 ms Zyklus
lasttime = millis();
static byte laenge = 0;
a = 15 - laenge; // igitt, warum das ?
if ( a >= 0 ) { ladebalken(); laenge++; }
}
// ... kommt hier nicht blockierend hin
}