Archiv für Arduino

Temperatur mit dem Arduino erfassen und auf dem Computer ausgeben Vol. 2

Posted in Arduino, Elektronik, Maxim/Dallas, Processing with tags , , , , , , , on 3. August 2009 by crackburg

Der Chip…:

Diesmal kommt anders als im vorherigen Beispiel ein Maxim/Dallas DS18b20 (Datenblatt) zum Einsatz. Vorteil gegenüber dem vorher verwendeten DS1620 ist zum einen, dass dieser Chip nur einen anstatt drei Portpins belegt. Zum anderen kann man mit der OneWire-Technologie von Dallas viel grössere Kabellängen realisieren, was ja für einen externen Sensor an sich wünschenswert ist. Das TO92-Gehäuse macht die Freude fast rund. Lässt es sich doch wunderbar mit Schrumpfschlauch abdichten und verwenden.

Und nun zu den Nachteilen. Da hätten wir als erstes die Auslesegeschwindigkeit. Jedes mal wenn man den Chip ausliest, dauert es ca. eine Sekunde bis er einen Wert zurückliefert. Nachdem ich vorher in meinem Hauptprojekt alle delays entfernt habe, ist so eine Zwangspause natürlich erstmal ärgerlich. Aber da ich ja nicht mit permanent wild schwankenden Temperaturen zu kämpfen habe, werde ich einfach die Temperatur nicht so häufig auslesen.

Mein zweiter Kritikpunkt ist die Codegrösse die entsteht wenn man den DS18b20 mit der Library von Miles Burton verwendet. War vorher mein kompletter Code samt Libs in etwa 6KB gross, so nimmt die Temperaturanfrage und DallasTemperature lib schon diese grösse ein. Was heisst das sich durch verwendung des Ds18b20 mein kompilierter Code auf die doppelte Grösse aufgebläht hat. Das habe ich aber auch pragmatisch gelöst und den Atmega88 durch einen Atmega168 ersetzt.

Die Schaltung…:

Pin 1 am DS18b20 geht auf Masse (GND). Pin 2 geht auf einen Digitaleingang am Arduino (bei mir D5). Ausserdem geht von Pin 2 ein 4,7 Kiloohm Pullup-Widerstand auf +5V (VCC). Pin 3 geht auf +5V(VCC). Beim Betrieb im parasitären Modus, zieht sich der DS18b20 seine Versorgungsspannung über die Datenleitung. Aber in Zeiten von Ebola und Schweinegrippe, muss man ja nicht auch noch die Bauteile zu parasitärem Verhalten ermutern.

Arduino Code:

/*
DallasTemperature.CPP –  Dallas Temperature Control Library 1.0.0 Author: Miles Burton, miles@mnetcs.com
Code basiert auf dem Beispiel von Miles Burton, miles@mnetcs.com
*/

#include <DallasTemperature.h>

DallasTemperature tempSensor;

void setup(void) {
// inputs/outputs initialsieren
// seriellen port starten
Serial.begin(9600);
tempSensor.begin(5); // Die Datenleitung geht in den digitalen Pin 5 am Arduino
}

void loop(void) {

// Bei der Library anfragen ob das Geraet gueltig ist
switch(tempSensor.isValid())
{
case 1:
Serial.println(„Invalid CRC“);
tempSensor.reset(); // Versuch den Chip erneut zu erkennen
return;
case 2:
Serial.println(„Not a valid device“);
tempSensor.reset(); // Versuch den Chip erneut zu erkennen
return;
}

// getTemperature liefert einen float-Wert zurueck. Dies ist immer eine positive Zahl.

Serial.print(„Temp: „);
//Temperatur abfragen und auf der seriellen ausgebendas abfragen der Temperatur braucht ca. 1sek. deswegen der „delay“ an dieser Stelle
Serial.print(tempSensor.getTemperature());
Serial.print(„C“);
Serial.println();
}

Processing Code:

import processing.serial.*;

Serial myPort;  // Die serielle Schnittstelle
PFont fontA;
String tempBuffer = null;
int lf = 10;    // Linefeed in ASCII

String Temperatur = „keine Daten“;

void setup() {

size(200, 200);
background(210);
// Alle verfügbaren seriellen Ports auflisten:
println(Serial.list());

/*Auswahl der seriellen Schnittstelle. die erste ist 0, die zweite ist 1 usw.*/
myPort = new Serial(this, Serial.list()[1], 9600);
/* Die Schrift laden. Schriften muessen im Datenverzeichnis des Sketches vorliegen.
um eine Schrift zu erstellen, verwende den Menuepunkt /Tools/create Font.
fontA = loadFont(„ArialRoundedMTBold-48.vlw“);*/

// Schrift und deren groesse definieren (in Pixeln)
textFont(fontA, 20);
}

void draw() {

while (myPort.available() > 0) { //Warten bis Daten auf der seriellen vorhanden sind
redraw();
String inBuffer = myPort.readStringUntil(lf); //So lange den inhalt der seriellen Schittstelle in den inBuffer lesen bis ein Linefeed kommt

if (inBuffer != null && inBuffer.startsWith(„Temp:“)) //wenn der inBuffer nicht leer ist und mit Temp: beginnt
{
Temperatur = inBuffer; // schreibe den Inhalt von inBuffer nach Temperatur
}

if (inBuffer != null && tempBuffer != inBuffer) {
background(210);
fill(51);
text (Temperatur, 1 , 20);
String tempBuffer = inBuffer;

}
}
}

Advertisements

Relaistreiber 0.2

Posted in Arduino, Elektronik with tags , , , , , , on 1. August 2009 by crackburg

Wie bei der vorherigen Version versprochen, habe ich den Relaistreiber überarbeitet. Der schaltende Portpin wird jetzt durch einen Optokoppler vor allem bösen was aus der Relaisspule sickern könnte geschützt. Als Optokoppler soll ein  CNY17 zum Einsatz kommen.

Temperatur mit dem Arduino erfassen und auf dem Computer ausgeben

Posted in Arduino, Maxim/Dallas, Processing with tags , , , , on 9. Juli 2009 by crackburg

Ich moechte mit dem Freeduino und einen DS1620 die Temperatur messen und diese dann auf dem Computer ausgeben. Die Ausgabe der Temperatur erfolgt ueber Seria.println auf der seriellen Schnittstelle.  Im Video sieht man dann erst die Ausgabe in Minicom und dann in Processing.

Der DS1620 wird ueber die Library von John P. Mulligan angesprochen.

ds1620 004

Processing Code:

// basiert auf dem Beispiel von Tom Igoe

import processing.serial.*;

Serial myPort;  //Die Serielle Schnittstelle
PFont fontA;
String tempBuffer = null;
int lf = 10;    // Linefeed in ASCII

void setup() {

size(200, 200);
background(210);
//Gib eine Liste der seriellen Interfaces aus
println(Serial.list());

// Serielle Schnittstelle festlegen
myPort = new Serial(this, Serial.list()[0], 9600);
// Die Schrift.  Der Font muss im Data Verzeichnis vom Sketch liegen
// Um einen Font zu erstellen, verwende  Tools > Create Font
fontA = loadFont(„ArialRoundedMTBold-48.vlw“);

// Textgroesse definieren (in pixeln)
textFont(fontA, 20);
}

void draw() {

while (myPort.available() > 0) {
redraw();
String inBuffer = myPort.readStringUntil(lf);

if (inBuffer != null && tempBuffer != inBuffer) {
background(210);
println(inBuffer);
fill(51);
text („Temp:“, 1, 20);
fill(51);
text (inBuffer, 1, 40);
fill(51);
text („°C“, 35, 40);
String tempBuffer = inBuffer;

}
}
}

Arduino Code:

*/

#include „DS1620.h“

// Pins fuer die 3-wire-serial definieren
int dq = 5;
int clk = 4;
int rst = 3;

// Aufruf des DS1620 Konstruktors
DS1620 d = DS1620(dq, clk, rst);

void setup()
{
// Beginne serielle Kommunikation mit 9600 Baud
Serial.begin(9600);

// Schreibe TH und TL ins EEPROM des DS1620

d.write_th(30);
d.write_tl(15);

// Schreibe configuration/status register
// Dezimal 10 = Binary 00001010
// Aktiviert CPU-Mode und deaktiviert 1-Shot Mode.
// das Datenblatt erzaehlt mehr
d.write_config(10);
d.start_conv();

}

void loop()
{
//  Temperatur auslesen und aud der seriellen Schnittstelle ausgeben
Serial.println(d.read_temp());

// eine Sekunde Pause vor dem naechsten Lesezyklus
delay(1000);
}

Der Giessduino

Posted in Arduino, Elektronik, Maxim/Dallas with tags , , , , , on 25. Juni 2009 by crackburg

Wer kennt es nicht… das laestige giessen der Pflanzen auf der Balkon. Gerade in warmen Phasen wird man oft erst durch das erbaermliche aeussere der Balkonpflanzen auf seine eigene Vergesslichkeit aufmerksam gemacht. Diesem Umstand moechte ich nun mit Hilfe der Arduino-Bewegung entgegentreten. Jetzt wird vielleicht die Frage aufkommen, warum dafuer ein Mikrokontroller und nicht eine herkoemmliche Zeitschaltuhr?! Stecker in die Zeitschaltuhr stecken ist doch voll langweilig und gewoehnlich. Ausserdem habe ich seit Ostern einen Freeduino welcher geradezu nach einer Aufgabe schreit. Und mit dieser „einfachen“ Aufgabestellung konnte ich mein quasi nicht vorhandenes Wissen ueber Mikrokontroller, Elektronik und C-Programmierung riesig eerweitern. Eine tolle Plattform. Nun gibt es zur Zeit einen Wettbewerb, bei dem man einen Arduino nebst Workshopbausatz gewinnen kann. Dafuer kann ich meinen Giessduino bzw. was davon schon exisitiert auch mal praesentieren.

Was dem Mikrocontroller als erstes beigebracht werden muss, ist das lesen der Uhr (Schnuersenkel binden waere aetzender). Hierfuer verwende ich einen Timekeeper der Firma Dallas Maxim, den DS1302 in DIP Bauform.

ds1302

Um den Timekeeper mit dem Arduino sprechen zu lassen, verwende ich die Library von Matt Sparks.

Angeschlossen habe ich den Timekeeper an den Arduino I/O-Ports 5,6 und sieben, wie in Matts Beispiel.ds1302_freeduino

Nun noch den Beispielcode mit der Arduino IDE einspielen:

/*

Example sketch for interfacing with the DS1302 timekeeping chip.

Copyright (c) 2009, Matt Sparks

All rights reserved.

http://quadpoint.org/projects/arduino-ds1302

*/

#include <stdio.h>

#include <string.h>

#include <DS1302.h>

/* Set the appropriate digital I/O pin connections */

uint8_t CE_PIN = 5;

uint8_t IO_PIN = 6;

uint8_t SCLK_PIN = 7;

/* Create buffers */

char buf[50];

char day[10];

/* Create a DS1302 object */

DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);

void print_time()

{

/* Get the current time and date from the chip */

Time t = rtc.time();

/* Name the day of the week */

memset(day, 0, sizeof(day)); /* clear day buffer */

switch (t.day) {

case 1:

strcpy(day, "Sunday");

break;

case 2:

strcpy(day, "Monday");

break;

case 3:

strcpy(day, "Tuesday");

break;

case 4:

strcpy(day, "Wednesday");

break;

case 5:

strcpy(day, "Thursday");

break;

case 6:

strcpy(day, "Friday");

break;

case 7:

strcpy(day, "Saturday");

break;

}

/* Format the time and date and insert into the temporary buffer */

snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",

day,

t.yr, t.mon, t.date,

t.hr, t.min, t.sec);

/* Print the formatted string to serial so we can see the time */

Serial.println(buf);

}

void setup()

{

Serial.begin(9600);

/* Initialize a new chip by turning off write protection and clearing the

clock halt flag. These methods needn't always be called. See the DS1302

datasheet for details. */

rtc.write_protect(false);

rtc.halt(false);

/* Make a new time object to set the date and time */

/* Tuesday, May 19, 2009 at 21:16:37. */

Time t(2009, 5, 19, 21, 16, 37, 3);

/* Set the time and date on the chip */

rtc.time(t);

}

/* Loop and print the time every second */

void loop()

{

print_time();

delay(1000);

}

Nun kann der Arduino die Zeit lesen und gibt diese einmal pro sekunde ueber die serielle Schnittstelle aus. Gesetz dem Fall das im Beispielcode auch die richtige Zeit eingetragen ist, sollte diese sogar stimmen :D. Problematisch ist das er nun bei jedem Stromausfall die statisch eingetragene Zeit verwendet. Hier muss eine Veraenderung her, die ein setzen der Zeit nur auf wunsch durchfuehrt.

Jetzt kann das Ding also Uhr lesen und damit umgehen. Wie geht es nun weiter. Nun muss er zur richtigen Uhrzeit eine Wasserpumpe schalten. Da bietet sich doch ein Relais an. Als Relaisschaltung habe ich erstmal ein Beispiel aus dem Arduino Playground verwendet. Diese Schaltung funktioniert super, ist aber doch nicht perfekt. Das Stichwort hier lautet galvanische Trennung. Durch die Transistorschaltung wie im Beispiel, sind die beiden Stromkreise nicht voneinander getrennt, was in der Theorie zu arg stinkenden Bauteilen oder gar zu einen gemuetlichen Grillabend auf frischer Hausglut fuehren kann. Von diesem Standpunkt aus betrachtet, wird diese  Schaltung in absehbarer Zeit durch eine auf Optokoppler basierte ersetzt.

relays

Ich habe den Code nun um die if/then Anweisung ergaenzt, die zu drei Zeiten am Tag das Relais auf High setzt. Auch due dafuer benoetigten Variabelen habe ich mit eingefuegt. Ausserdem habe ich den Teil der die Uhr stellt auskommentiert, um nicht nach jedem Stromausfall wieder in alten Zeiten schwelgen zu muessen. Schicker waere natuerlich eine Funktion die nur auf wunsch die Zeit mit einem einzugebenden Wert befuellt, das kommt aber spaeter. Erstmal wird er auch so die Blumen giessen.

#include <stdio.h>

#include <string.h>

#include <DS1302.h>

/* Set the appropriate digital I/O pin connections */

uint8_t CE_PIN = 5;

uint8_t IO_PIN = 6;

uint8_t SCLK_PIN = 7;

int wasser = 8;

byte minute = 15;

byte stunde1 = 10;

byte stunde2 = 13;

byte stunde3 = 19;

/* Create buffers */

char buf[50];

char day[10];

/* Create a DS1302 object */

DS1302 rtc(CE_PIN, IO_PIN, SCLK_PIN);

void print_time()

{

/* Get the current time and date from the chip */

Time t = rtc.time();

/* Name the day of the week */

memset(day, 0, sizeof(day)); /* clear day buffer */

switch (t.day) {

case 1:

strcpy(day, „Sunday“);

break;

case 2:

strcpy(day, „Monday“);

break;

case 3:

strcpy(day, „Tuesday“);

break;

case 4:

strcpy(day, „Wednesday“);

break;

case 5:

strcpy(day, „Thursday“);

break;

case 6:

strcpy(day, „Friday“);

break;

case 7:

strcpy(day, „Saturday“);

break;

}

/* Format the time and date and insert into the temporary buffer */

snprintf(buf, sizeof(buf), „%s %04d-%02d-%02d %02d:%02d:%02d“,

day,

t.yr, t.mon, t.date,

t.hr, t.min, t.sec);

/* Print the formatted string to serial so we can see the time */

Serial.println(buf);

/* hier wird geguckt wie spaet es ist. wenn die Zeit reif ist, geht der Port fuer das Relais auf HIGH */

if (t.sec > 30 && t.min == minute && (t.hr == stunde1 || t.hr == stunde2 || t.hr == stunde3)

{

digitalWrite(wasser, HIGH);

}

else

{

digitalWrite(wasser, LOW);

}

}

void setup()

{

pinMode(wasser, OUTPUT);

Serial.begin(9600);

/* Initialize a new chip by turning off write protection and clearing the

clock halt flag. These methods needn’t always be called. See the DS1302

datasheet for details. */

// rtc.write_protect(false);

// rtc.halt(false);

/* Make a new time object to set the date and time */

/* Tuesday, May 19, 2009 at 21:16:37. */

// Time t(2009, 5, 19, 21, 16, 37, 3);

/* Set the time and date on the chip */

// rtc.time(t);

}

/* Loop and print the time every second */

void loop()

{

print_time();

delay(1000);

}

Hier nun ein Bild der Schaltung auf einem Breadboard. Das Relais klickerklackert (auch wenn es ein 6V Relais ist. Ich habe eines fuer 5V, das passt aber nicht ins Breadboard)  zur richtigen Zeit und auch die Uhr weiss nach Tagen noch wie spaet es ist. Leider ist diese Bauform nicht so wirklich balkontauglich. Also geht es wohl ans loeten.

Leider habe ich zur Zeit nur einen DS1302 und muss das loeten vertagen bis die anderen geliefert worden sind.

arduino 008

Nun wird es also ernst. Die vorher entwickelte (eher zusammengegoogelte aber entwickeln klingt echt mal serioeser) Schaltung muss nun auf eine Platine gebracht werden. Da ich meinen schicken Freeduino nicht die Sommersaison ueber auf dem Balkon parken moechte und fuer einen zweiten die Kohle echt nicht ueber ist, entschied ich mich dafuer mir den Giessduino selbst zu bauen.

Auf dem Breadboard exisitert das ganze schon. Es ist ein ATmega8 mit Arduino Bootloader und ein paar Bauteilen. Nun muss ich mir nur noch Gedanken machen, wie ich das auf eine Platine bekomme.

arduino 010

Geschaltet wird dann dies hier. werde das noch in Aktion dokumentieren.

3189

Die Vision ist nun das der Controller auch noch Licht schaltet. Dann kann ich ihn im Winter auf der Fensterbank verwenden.  Auch soll er die Temperatur messen und auch mit diesen Daten arbeiten. Das ist aber eher was fuer draussen denn fuer drinnen.

Alles ist moeglich…. Licht steuern, Temperatur messen, pH Wert bestimmen, düngen mit Hilfe von Schlauchpumpen usw. usw.

Ich bin von mir selbst erstaunt, wie schnell ich doch von „hey willst du auch so ein Ding haben? Nagut, fuer nen Zwanni kann man nichts verkehrt machen und wegschmeissen kann ich es immernoch“ zu einem ambitionierten Elektroniklehrlingsgehilfenassistent geworden bin. Ein Super Eval-Board das man auspackt und nach ein paar Minuten Erfolgserlebnisse verzeichnet. Es regt zum Nachdenken an und laesst einen schnell auf gute Ideen fuer Basteleien kommen.

ATmega328 und USB2seriell adapter Bestellt

Posted in Arduino with tags , on 25. Juni 2009 by crackburg

Ich habe heute drei ATmega328 und ein FTDI Adapter bei Watterott bestellt. Zwei von den 328 wandern in meine Freeduinos. Das Breakout Board brauche ich fuer den Prototypen des Pflanzduinos.