Dresden
Offline
Newbie
Karma: 0
Posts: 8
sledge hammer computing
|
 |
« on: June 02, 2011, 03:52:18 am » |
Hallo allerseits, vor wenigen Tagen bin ich im Netz zufällig über Arduino gestolpert - oute mich nun als Anfänger  -und wollte mein erstes Projekt meiner Gartendusche widmen: Ein in der Sonne liegender Schlauch soll bei genügend Temperaturunterschied eine in einem Fass liegende Lenzpumpe ansprechen. Siehe meine Mausgrafik dazu im Anhang  Ich kopierte also die DS1820-Bibliothek und ~Beispiele in das Arduino-Tool. Ich fand aber nur Beispiele einer Temperaturanzeige, keines über eine Steuerung damit. Ich nahm also dann das Temperatur-Tester-Skript und probierte einige Zeit, die Werte - den Temperaturfühler und Temperatur - in eine Varible zu verpacken. Dann kam ich dann zu dieser Lösung, welche zu funktionieren scheint: #include <OneWire.h> #include <DallasTemperature.h>
// Data wire is plugged into port 2 on the Arduino #define ONE_WIRE_BUS 3 #define TEMPERATURE_PRECISION 9
int DEVICE = 0; float WERTX = 0; float WERTY = 0; float WERTDEV0 = 0; float WERTDEV1 = 0;
// 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);
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address
void setup(void) { // start serial port Serial.begin(9600); Serial.println("Dallas Temperature IC Control Library Demo"); pinMode(13, OUTPUT); // Start up the library sensors.begin(); // Grab a count of devices on the wire numberOfDevices = sensors.getDeviceCount(); // locate devices on the bus Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(numberOfDevices, DEC); Serial.println(" devices."); //DEVICE=(numberOfDevices, DEC); // report parasite power requirements Serial.print("Parasite power is: "); if (sensors.isParasitePowerMode()) Serial.println("ON"); else Serial.println("OFF"); // Loop through each device, print out address for(int i=0;i<numberOfDevices; i++) { // Search the wire for address if(sensors.getAddress(tempDeviceAddress, i)) { Serial.print("Found device "); Serial.print(i, DEC); Serial.print(" with address: "); printAddress(tempDeviceAddress); Serial.println();
Serial.print("Setting resolution to "); Serial.println(TEMPERATURE_PRECISION,DEC); // set the resolution to 9 bit (Each Dallas/Maxim device is capable of several different resolutions) sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION); Serial.print("Resolution actually set to: "); Serial.print(sensors.getResolution(tempDeviceAddress), DEC); Serial.println(); }else{ Serial.print("Found ghost device at "); Serial.print(i, DEC); Serial.print(" but could not detect address. Check power and cabling"); } } }
// function to print the temperature for a device void printTemperature(DeviceAddress deviceAddress) { // method 1 - slower //Serial.print("Temp C: "); //Serial.print(sensors.getTempC(deviceAddress)); //Serial.print(" Temp F: "); //Serial.print(sensors.getTempF(deviceAddress)); // Makes a second call to getTempC and then converts to Fahrenheit
// method 2 - faster float tempC = sensors.getTempC(deviceAddress); Serial.print("Temp C: "); Serial.print(tempC); delay(5000); // 5 Sekunden Pause
//beide Variablen uebertragen die Temperatur, WERTY nur zu Testzwecken, wird nicht weiter ausgewertet WERTX=(tempC); WERTY=(sensors.getTempC(deviceAddress));
//Serial.print(" Temp F: "); //Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit }
void loop(void) { // call sensors.requestTemperatures() to issue a global temperature // request to all devices on the bus Serial.print("Requesting temperatures..."); sensors.requestTemperatures(); // Send the command to get temperatures Serial.println("DONE"); // Loop through each device, print out temperature data for(int i=0;i<numberOfDevices; i++) { // Search the wire for address if(sensors.getAddress(tempDeviceAddress, i)) { // Output the device ID Serial.print("Temperature for device: "); Serial.println(i,DEC);
DEVICE=(i);
// It responds almost immediately. Let's print out the data printTemperature(tempDeviceAddress); // Use a simple function to print out the data Serial.print("\n"); Serial.print("\n"); switch (DEVICE) { case 0: //definiere Inhalt Device 0 WERTDEV0=(WERTX); case 1: // definiere Inhalt Device 1 WERTDEV1=(WERTX); } //geht nur richtig, wenn DEVICE gleich 1 ist, sonst haben 0 und 1 gleiche Werte... if (DEVICE == 1) { Serial.print("Temp.0: "); Serial.print(WERTDEV0); Serial.print("\n"); Serial.print("Temp.1: "); Serial.print(WERTDEV1); Serial.print("\n"); Serial.print("\n"); if (WERTDEV0 > WERTDEV1) { digitalWrite(13, HIGH); } else { digitalWrite(13, LOW); } } } //else ghost device! Check your power requirements and cabling } }
// function to print a device address void printAddress(DeviceAddress deviceAddress) { for (uint8_t i = 0; i < 8; i++) { if (deviceAddress[i] < 16) Serial.print("0"); Serial.print(deviceAddress[i], HEX); } }
Wenn nun Temperaturfühler Device 0 einen höheren Wert als Device 1 besitzt, so wird Pin13 angesteuert. Allerdings werden die Variablen von Device 0 und Device 1 nur dann richtig gesetzt, wenn Device 1 ausgegeben wird. Das verstehe ich nicht, habe es aber mit einer if-Anweisung abgefangen  Gibt es für diesen Zweck mit den DS1820 schon eine Lösung, welche evtl. etwas eleganter ist? Beste Grüße Jörn
|
|
|
|
« Last Edit: June 02, 2011, 05:24:13 am by joe-eis »
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 231
|
 |
« Reply #1 on: June 02, 2011, 06:41:46 am » |
Hallo Jörn, ich habe mir eine Heizungssteuerung gebaut incl. Solaranlage und Kachelofen, wobei der Kachelofen einen Wasserkreislauf besitzt und sowohl Warmwasser als auch Heizung beliefert. Das ist ja im Prinzip nichts anderes als das was du machst. Es geht sicherlich viel einfacher, hier mal ein Beispiel, welches alle 8 Sekunden 6 Dallas 18B20 einliest: delay halt ich für ziemlich ungünstig, warum das Programm anhalten? void SensorLesen(){ jetzt = millis(); if(jetzt - vorher > 8000){ //Sensoren werden nur alle 8 sec gelesen sensors.requestTemperatures(); Temperatur[0] = sensors.getTempC(Sensor0); Temperatur[1] = sensors.getTempC(Sensor1); Temperatur[2] = sensors.getTempC(Sensor2); Temperatur[3] = sensors.getTempC(Sensor3); Temperatur[4] = sensors.getTempC(Sensor4); Temperatur[5] = sensors.getTempC(Sensor5); vorher=millis(); } } Falls du Fragen hast melde dich. Gruß Bernward
|
|
|
|
|
Logged
|
|
|
|
|
Dresden
Offline
Newbie
Karma: 0
Posts: 8
sledge hammer computing
|
 |
« Reply #2 on: June 02, 2011, 07:37:05 am » |
Hallo Bernward, danke Dir für die rasche Antwort. Die Lösung von Dir ist das, was ich suche... Das sind meine Anfängerfehler und ~Probleme, ich beschäftige mich erst seit ein paar Stunden mit dem Arduino und habe mit den Befehlssatz und der Syntax etwas zu kämpfen  Ich wusste nicht, dass ich mit delay des Programm anhalte, ich habe es irgendwo aufgeschnappt und eingebastelt... Wo ich richtig am grübeln war, ist den Temperaturfühler zu definieren und ihm einen Wert zuzuweisen. Das hast Du ja mit deiner Funktion sensors.requestTemperatures(); ja sauber hinbekommen.  Wie hast Du die Varible oder Adresse(?) Sensor(N) bei sensors.getTempC(...) definert? Viele Grüße Jörn
|
|
|
|
« Last Edit: June 02, 2011, 07:40:17 am by joe-eis »
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 231
|
 |
« Reply #3 on: June 02, 2011, 08:14:23 am » |
Hallo Jörn, als erstes die Deklaration hier nur das wichtigste: #include <OneWire.h> #include <LiquidCrystal.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 22 // alle Temperaturfühler an PIN 22 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); float Temperatur[6]; int sensoranzahl, unsigned long vorher, jetzt; // Sensoren 0-5 feste Vorgabe der Seriennummern der Temperatursensoren DeviceAddress Sensor0 = {0x28, 0xBB, 0x7B, 0xDA, 0x02, 0x00, 0x00, 0xA9}; DeviceAddress Sensor1 = {0x28, 0xA3, 0x82, 0xDA, 0x02, 0x00, 0x00, 0x06}; DeviceAddress Sensor2 = {0x28, 0x0C, 0x9E, 0xDA, 0x02, 0x00, 0x00, 0x23}; DeviceAddress Sensor3 = {0x28, 0x06, 0xCB, 0xDE, 0x02, 0x00, 0x00, 0xA5}; DeviceAddress Sensor4 = {0x28, 0x13, 0x81, 0xDA, 0x02, 0x00, 0x00, 0x4F}; DeviceAddress Sensor5 = {0x28, 0x47, 0xFA, 0x8D, 0x02, 0x00, 0x00, 0xFE}; bei der festen Vorgabe kannst du die Sensoren nachher stecken wie du willst, mit Sensor0 wird immer der erste angesprochen, egal wo er in der Reihe angeschlossen ist. Im void setup kannst du bei Bedarf einmalig die Anzahl der Sensoren ermitteln: sensors.begin(); sensoranzahl=sensors.getDeviceCount(), DEC;
Der Rest wird in SensorLesen gemacht. Und jetzt noch ein Beispiel für die Pumpe, hier am Beispiel der Solarpumpe: das mit dem start[], beginn[] ende[] und Laufzeit[] kannst du weglassen, hier berechne ich die Laufzeiten der einzelnen Pumpen und gebe diese im LCD-Display aus. void SolarPumpe(){ // Pumpe (Solaranlage) stellt sich ein, wenn Wasser um Solardiff wärmer ist als im Speicher und gleichzeitig wärmer als Solarminwert ist // Pumpe (Solaranlage) stellt sich aus wenn Temperatur in Solaranlage <= Temperatur+3 im Speicher ist flag=1; if (Temperatur[4] > Temperatur[2] + Solardiff && Temperatur[4] > Solarminwert){ flag=0; if (!start[3]){ beginn[3] = int(millis()/1000); start[3] = true; } } if (Temperatur[4] <= Temperatur[2] + 3){ flag=2; if (start[3]){ ende[3] = int(millis()/1000); start[3] = false; Laufzeit[3] = Laufzeit[3] + int(ende[3] - beginn[3]); } } if (flag == 0) digitalWrite(Relais03, HIGH); if (flag == 2) digitalWrite(Relais03, LOW); }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 231
|
 |
« Reply #4 on: June 02, 2011, 08:28:33 am » |
noch ein Tip, ich würde allen Variablen "erklärende Namen" geben, wenn du mal richtig lange Programme mit vielen Variablen hast ist es absolut von Vorteil, wenn der Name schon aussagt, worum es geht. Und schließlich sind wir hier in einem deutschsprachigen Forum, warum dürfen Variablen dann nicht auch deutsche Namen haben. Gruß Bernward
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
BZ (I)
Online
Brattain Member
Karma: 161
Posts: 15712
+39 349 2158303
|
 |
« Reply #5 on: June 02, 2011, 01:18:27 pm » |
Hallo joe-eis Ich weiß, daß ich wieder mal den Bösen spiele  Versuch zuerst mal ein Buch über Arduino zu lesen oder das offizielle Tutorial http://arduino.cc/en/Tutorial/HomePage durchzuarbeiten um etwas Gefühl für den Arduino zu bekommen. Viele Grüße Uwe
|
|
|
|
« Last Edit: June 03, 2011, 04:16:03 pm by uwefed »
|
Logged
|
|
|
|
|
Dresden
Offline
Newbie
Karma: 0
Posts: 8
sledge hammer computing
|
 |
« Reply #6 on: June 03, 2011, 03:50:50 pm » |
Hallo Bernward, ich danke für die ausführlichen Beiträge und Tipps, nun habe ich eine gute Vorlage für mein Projekt  Hallo Uwe, für den Einstieg hatte ich ich etwas Lektüre von freeduino.de, das ist ausreichend für einfache Standartsituationen und leichtverständlich, wenn man etwas Shell kann. Danke Dir aber für den Link, ich werde bestimmt auf dies oder jenes Beispiel zurückgreifen. Heute lagen mein Display von tuxgraphics.org im Postkasten  Die Ansprech-Methodik der Dallas/Maxim 1-Wire Bausteine (DS1820, DS2413,...) wird aber hier nicht erläutert  Viele Grüße Jörn
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
BZ (I)
Online
Brattain Member
Karma: 161
Posts: 15712
+39 349 2158303
|
 |
« Reply #7 on: June 03, 2011, 04:18:22 pm » |
Such einfach mit eine Suchmaschiene "Arduino" und "1820" Dann findest Du zB das hier: http://www.arduino.cc/playground/Learning/OneWireViele Grüße Uwe
|
|
|
|
|
Logged
|
|
|
|
|
Dresden
Offline
Newbie
Karma: 0
Posts: 8
sledge hammer computing
|
 |
« Reply #8 on: June 03, 2011, 04:24:55 pm » |
Verdammt, Du hast recht. Der 3. Treffer ist es  Viele Grüße Jörn
|
|
|
|
|
Logged
|
|
|
|
|
Forum Moderator
BZ (I)
Online
Brattain Member
Karma: 161
Posts: 15712
+39 349 2158303
|
 |
« Reply #9 on: June 03, 2011, 04:28:13 pm » |
Auf dem Playground sind jede Menge Beispiele und Erklährungen der verschiedensten Hardware. Schau Dich dort auch mal um. Viele Grüße Uwe
|
|
|
|
|
Logged
|
|
|
|
|
Dresden
Offline
Newbie
Karma: 0
Posts: 8
sledge hammer computing
|
 |
« Reply #10 on: June 09, 2011, 05:02:51 am » |
Hallo, ich habe nun fertig  und möchte mich für die Tipps bedanken. Es ist nun ein Sketch entstanden, welche ich auch verstehe und deren Genauigkeit der Temperaturerkennung höher (?) ist: Bernward, Du wirst Teile deines Codes wiedererkennen  #include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h>
// Data wire is plugged into port 8 on the Arduino #define ONE_WIRE_BUS 8 #define TEMPERATURE_PRECISION 9
// initialize the library with the numbers of the interface pins LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// 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);
float Temperatur[2]; float TempDiffAn = 4; float TempDiffAus = 1; float TempStart = 20; float TempEnde = 40; int Zustand = 0; unsigned long vorher, jetzt;
// Sensoren 0-1 feste Vorgabe der Seriennummern der Temperatursensoren DeviceAddress Sensor0 = {0x28, 0x10, 0x26, 0xBB, 0x02, 0x00, 0x00, 0x6B}; DeviceAddress Sensor1 = {0x28, 0x30, 0x3F, 0xEC, 0x02, 0x00, 0x00, 0x0C};
void setup() { Serial.begin(9600); // Serielle Schnittstelle initiieren sensors.begin(); // Start up the sensor library pinMode(13, OUTPUT); // // set up the LCD's number of columns and rows: lcd.begin(16, 2); }
// liest aller 10 Sekunden Dallas 18B20 ein void loop(){ jetzt = millis(); if(jetzt - vorher > 10000){ //Sensoren werden nur alle 10 sec gelesen sensors.requestTemperatures(); Temperatur[0] = sensors.getTempC(Sensor0); Temperatur[1] = sensors.getTempC(Sensor1); vorher=millis(); // Die Variablen-Inhalte Serial.print("\n"); Serial.print("Variablen-Wert fuer Device 1 is: "); Serial.print(Temperatur[0]); Serial.print("\n"); Serial.print("Variablen-Wert fuer Device 2 is: "); Serial.print(Temperatur[1]); Serial.print("\n"); // Temperatur 1 = Solarschlange, Temperatur 2 = Duschfass // Pumpe soll anspringen, wenn Temperatur 1 um 4 Grad oder mehr höher als Temperatur 2 ist // Pumpe soll ausgehen, wenn Temperatur 2 um 1 Grad oder mehr kälter als Temperatur 2 ist // Pumpe soll nicht angehen, wenn Temperatur 1 kälter als 20°C ist // Pumpe soll nur angehen, wenn Temperatur 2 kälter als 40°C ist if (Temperatur[0] > Temperatur[1] + TempDiffAn && Temperatur[0] > TempStart && Temperatur[1] < TempEnde) { digitalWrite(13, HIGH); // set the LED on Zustand = 1; } if (Temperatur[0] < Temperatur[1] + TempDiffAus) { digitalWrite(13, LOW); // set the LED off Zustand = 0; } } lcd.setCursor(0, 0); lcd.print("Solar: "); lcd.print(Temperatur[0]); lcd.print(" C"); lcd.setCursor(0, 1); lcd.print("Fass: "); lcd.print(Temperatur[1]); lcd.print(" C");
// belege das 16. Zeichen der 2. Zeile, bei Pumpe=1 soll dort ein P erscheinen: lcd.setCursor(15, 1); if (Zustand == 1) { lcd.print("P"); } else { lcd.print("."); } }
Grüße Jörn Übrigens, der Stromverbrauch liegt (bei Vin = 6V) so bei 57 mA, wobei ca. 10 mA auf die LCD-Beleuchtung entfallen.
|
|
|
|
« Last Edit: June 10, 2011, 03:17:42 am by joe-eis »
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 231
|
 |
« Reply #11 on: June 09, 2011, 12:43:22 pm » |
Hallo Jörn, freut mich wenn ich helfen konnte, man muß ja nicht alles selber erfinden, wenn es das schon gibt. Allerdings hab ich meine 6 Dallas 18B20 anders verschaltet als du in Bild 1. Ich habe bei allen Pin 1 und 3 miteinander verbunden und auf Masse gelegt. Und die +5V bei allen an Pin2 und den Arduino. Gruß Bernward
|
|
|
|
|
Logged
|
|
|
|
|
Dresden
Offline
Newbie
Karma: 0
Posts: 8
sledge hammer computing
|
 |
« Reply #12 on: June 10, 2011, 03:12:34 am » |
Hallo Bernward, Ich habe bei allen Pin 1 und 3 miteinander verbunden und auf Masse gelegt. Das Prinzip habe ich so aus dem Buch "Arduino Praxiseinstieg von Thomas Brühlmann" übernommen. Mit +5V an Pin 3 wird der Master auf dem Bus definiert, der bzw. die anderen Bus-Mitglieder werden mit Masse auf diesem Pin als Slave definiert. In wie weit das in der Praxis notwendig ist ..?? Interessant ist jedenfalls die höhere Genauigkeit gegenüber des Sketches meines ersten Beitrages. Es war erst eine Auflösung von 0,5 Volt, wobei die beiden Sensoren schon beim Programmstart um diesen Betrag abwichen. Nun ist die Ausgabe nach dem Komma zweistellig, beim Start zeigen beide Temperaturen den gleichen Betrag an und die Temperatursprünge liegen nun bei 0,06 °C. Schön wäre auch eine Forum-Abteilung mit kompletten, nachbaufähigen Projektvorstellungen  Viele Grüße Jörn
|
|
|
|
« Last Edit: June 10, 2011, 03:19:14 am by joe-eis »
|
Logged
|
|
|
|
|
Germany
Online
Edison Member
Karma: 33
Posts: 1789
Arduino rocks
|
 |
« Reply #13 on: June 10, 2011, 03:49:05 am » |
Die Beschaltung des DS1820 hat nach meinem Kenntnisstand nichts mit Master oder Slave zu tun, hier geht es schlichtweg um die Spannungsversorgung des Sensors. Die kann nämlich auf zwei Weisen erfolgen: extern (und somit 3 Leitungen zum Sensor) oder aber "parasite powered" (und damit über zwei Anschlussleitungen). Näheres dazu findet man im Datenblatt des Sensors.
|
|
|
|
« Last Edit: June 10, 2011, 04:27:55 am by sth77 »
|
Logged
|
|
|
|
|
|
|
|