HYT939 und NTC an Matlab über Arduino

Loading

DSC_2311In den letzten Blogeinträgen habe ich mit dem Arduino einen NTC-Widerstand  über einen Spannungsteiler an den Analogeingang des Arduino-UNO angeschlossen und ihn als eigenständiges Programmchen am Arduino als Temperatursensor laufen lassen. Die aktuellen Messwerte wurden auf einem LC-Display angezeigt. Dann habe ich die selbe Hardware über die Matlab Software und das „Arduino for Matlab“-Package betrieben und mittels Matlabcode direkt den Temperaturverlauf geloggt. Im vorhergehenden Blog war dann ein kombinierter Temperatur und Luftfeuchtigkeitssensor (Type HYT939) an der Reihe, der über den I²C Bus am Arduino seine Daten lieferte und wieder am LCD ausgegeben hat.

In diesem Bericht kommt nun wieder Matlab ins Spiel. Hier habe ich versucht, beide Sensoren, den NTC am Analogeingang und den HYT am I²C Bus, gleichzeitig auszulesen. Das sollte über einen mehrere Minuten andauernden Zeitraum passieren, wobei die Messwerte gleich mitgeloggt werden, um sie danach in einem Vergleichsdiagramm zu plotten. Der Hardwareaufbau ist wieder ganz einfach. Der NTC ist in Serie mit einem 2k2 Widerstand geschaltet. Die Enden des Spannungsteilers gehen an die +5V Versorgung und GND und der Teilerpunkt wird an den A0 – Eingang des Arduino Uno angeschlossen. Der HYT bekommt ebenfalls seine 5V vom Arduino selbst und an A4 und A5 ist der I²C anzuschließen (genaue Pinbelegung s. vorgehenden Bericht). Jetzt fehlt noch das Matlab-Script. Es ist hier einzusehen:

 

 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beispielscript um mit ArduinoUno einen Temperaturverlauf aufzuzeichnen
% Sensoren an A0 (Spannungsteiler mit NTC) und HYT939 an I2C
% 03/2016 by I.Bihlo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
a = arduino('com4','Uno','libraries','I2C')
analogpin=0; %Anschlusspin analog des UNO
analog=0; %Variable für den Analogwert festlegen
nn=600; %anzahl der messpunkte
addr='0x28'; %addresse für digitalsensor
bus=i2cdev(a, addr) %i2c object erzeugen
%ein paar konstanten für die weiteren berechnungen
r=2200; %Spannungsteilerwiderstand
rt=0; %das wird der errechnete widerstand des NTC
urt=0; %das wird der errechnete Spannungsabfall am NTC
% konstanten für berechnung der Temperatur aus NTC Widerstand
% B25=3977K
a1=3.354016E-03;
b1=3.2569850E-04;
c1=2.61013E-06;
d1=6.38309e-08;
rref=2200;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Lesen des I2C Bus
% Lesen eines Temperaturabhängigen Widerstandes am Analog Eingang A0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for x=1:nn
%%%% Analog 
analog(x)=readVoltage(a, analogpin); %Liest den AnalogIn von A0 und gibt in Volt aus
urt(x)=5-analog(x); %spannungsabfall am NTC 
rt(x)=(r/analog(x))*urt(x); %widerstand des NTC
pause(0.5);
%%%%Digital
data = read(bus, 4); %4 byte von i2c auslsesen
pause(0.5);
%Rohdaten aus Puffer lesen und zusammenbauen
humrawh=dec2bin(data(1),8); %byte 1 auf 8bit festlegen in binär wandeln
humrawl=dec2bin(data(2),8); %byte 2 auf 8bit festlegen in binär wandeln
humrawall=strcat(humrawh,humrawl); % beide bins concentenaten
humraw=bin2dec(humrawall); % die ganze kette wieder in dec wandeln
%tempraw=uint16(data(3))*256+uint16(data(4));
temprawh=dec2bin(data(4),8);
temprawl=dec2bin(data(3),8);
temprawall=strcat(temprawl,temprawh);
temprawall=temprawall(1:14); %% die letzten beiden bits abschneiden
tempraw=bin2dec(temprawall);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Humidity berechnen lt. Datenblatt
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
hum(x)=double(100/(16384-1))*double(humraw);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Temperatur berechnen lt. Datenblatt
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
temp(x)=double(165/(16384-1))*double(tempraw)-40.0;
%berechung der analogtemperatur
rvsrref(x)=rt(x)/rref; 
tempa(x)=1/(a1+(b1*log(rvsrref(x)))+(c1*(log(rvsrref(x)^2)))+(d1*(log(rvsrref(x)^3))));
tempc(x)=tempa(x)-273.15 %Kelin in Celsius umrechnen
pause(1);
end
clear a;
time=1:nn;
%plotten der daten
figure(1);
subplot(2,1,1);
plot(time,tempc,'m');
grid on; hold on;
%plot(time,analog,'b');
%plot(time,rt/1000,'r');
%plot(time,urt,'g'); 
plot(time,temp,'g');
legend('Temperatur NTC[°C]','Temperatur HYT939 [°C]');
%legend('Analogspannung des ADC','Widerstand des NTC in kOhm','Spannung am NTC','Temperatur [°C]');
subplot(2,1,2);
plot(time,hum,'m');
grid on; hold on;
legend('Rel Luftfeuchtigkeit HYT939 [%RH]');
%ende

Nachdem der Code nun nach einigen Anpassungen läuft, habe ich beide Sensoren (wie am Titelbild zu sehen) nebeneinander angeordnet und vor Beginn der Messung mit Kältespray (Kälte75 von KontaktChemie) heruntergekühlt. Dann startete das Script und begann aufzuzeichnen. Im Ergebnis sollte der Verlauf der Erwärmung auf die Raumtemperatur zu sehen sein. Da die Kälte am Metallgehäuse des HYT sofort eine Schicht aus gefrorenem Kondensat bildet die langsam taut, erwartete ich mir einen Luftfeuchtigkeitswert im Bereich der Sättigung. (was dann auch deutlich im Plot zu sehen ist).

HYTvsNTC

Feuchtesensor am Arduino

Loading

DSC_2268In den letzten Blog-Einträgen habe ich mit Hilfe des Arduino Uno – Experimentierboards auf unterschiedliche Weise einen NTC-Widerstand zur Messung der Temperatur eingesetzt. Aus einem anderen Projekt habe ich auch noch einen Feuchte/Temperatursensor der Firma IST (Innovative Sensor Technologie) zur Verfügung, der mit einem Raspberry und in Python ausgelesen wurde. Es handelt sich um den digitalen Sensor HYT939, der über den I²C Bus ausgelesen wird. Er zeichnet sich laut Datenblatt mit folgenden Merkmalen aus:

  • DSC_2269chemisch sehr resistent
  • sehr weiter Temperatur- und Feuchtigkeitsmessbereich (-40°C .. +125°C, 0% ..100% RH)
  • mechanisch robuste Bauform
  • kalibriert und temperaturkompensiert
  • sehr geringer Drift
  • einsetzbar bis zu einem Umgebungsdruck von 16bar
  • Versorgungsspannung von 2.7 bis 5.5V
  • Auflösung von +/- 0.02% RH und 0.015°C
  • Genauigkeit von +/- 1.8% RH bei +23°C und +/-0.2K

Also wollte ich diesen Sensor auch mit dem Arduino betreiben und vielleicht in weiterer Folge auch den NTC parallel auslesen und die Ergebnisse vergleichen. Aber zurerst einmal wird der HYT an den Arduino angeschlossen.

hytpinDas Bild zeigt das Pinout des HYT in der Ansicht von unten. Die Belegung der Pins lautet:

  • 1…SCL
  • 2…VCC
  • 3…GND
  • 4…SDA

Somit lässt sich der Sensorchip ganz einfach an den Arduino anschließen, wobei die Pins SDA auf den Arduino Pin A4 und SCL auf den Pin A5 gelegt sind. Die Ausgabe der ausgelesenen Werte soll wieder wie beim NTC auf dem LC-Display stattfinden. Nachstehend ist der Code gelistet:

 

/*
   HYT939 bei Arduino UNO an:
   SDA pin A4
   SCL pin A5
   HYT939 bei MEGA2560 an:
   SDA pin 20
   SCL pin 21
   LCDisplay
   Pinzuordnungen allgemein für LCD
   RS to digital 12
   EN to digital 11
   D4 to digital 5
   D5 to digital 4
   D6 to digital 3
   D7 to digital 2
   R/W to ground
   VSS to ground
 */
 //I2C Addresse festlegen
 #define ADDR 0x28
 
 //Variablen und Datentypen festlegen
 double temp;
 double hum;
 unsigned int tempraw;
 unsigned int humraw;
 int x;
 unsigned char buffer[4];
 
 //Libraries laden
 #include <Wire.h>
 #include <LiquidCrystal.h>
 
 // interfacepins initialisieren
 LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 
 &nbsp; void setup()
 &nbsp; {
 &nbsp; //I2C und LCD Interface initialisieren,
 &nbsp; Wire.begin();
 &nbsp; lcd.begin(20, 4);
 &nbsp;&nbsp;
 &nbsp; Serial.begin(9600);
 &nbsp; lcd.println("HYT939-Sensor");
 &nbsp; }
 
 void loop()
 &nbsp; {
 &nbsp; //I2C auselesen
 &nbsp; Wire.beginTransmission(ADDR);&nbsp;
 &nbsp; Wire.endTransmission();
 &nbsp; delay(200);
 
 &nbsp; //4 Bytes auslesen
 &nbsp; Wire.requestFrom(ADDR, 4,true);
 &nbsp; x=0;
 &nbsp; while(Wire.available())&nbsp;
 &nbsp; { char c = Wire.read(); buffer[x]=c; x++; }
 
 //Rohdaten aus Puffer lesen
 tempraw=buffer[2]*256+buffer[3];
 humraw=buffer[0]*256+buffer[1];
 
 //Daten laut Datenblatt maskieren
 tempraw&=0xfffc;
 humraw&=0x3fff;
 tempraw=tempraw/4;
 
 //Rohdaten in Ausgabeformat umrechnen
 temp=(double)tempraw/99.2909; &nbsp;//skalieren laut datasheet
 temp=temp-40.0;
 hum=(double)humraw/163.83;
 
 //Daten auf LCD schreiben
 &nbsp; lcd.setCursor(0, 2); &nbsp;
 &nbsp; lcd.print("Temperatur =");
 &nbsp; lcd.setCursor(11, 2);
 &nbsp; lcd.print(temp);
 &nbsp;&nbsp;
 &nbsp; lcd.setCursor(0, 3); &nbsp;
 &nbsp; lcd.print("Humidity =");
 &nbsp; lcd.setCursor(14, 3);
 &nbsp; lcd.print(hum);
 //lcd.setCursor(0, 2);
 //lcd.print('Buffer0 =');
 //lcd.setCursor(11, 2);
 //lcd.print(buffer[2]);
 //lcd.setCursor(0, 3);
 //lcd.print('Buffer1 =');
 //lcd.setCursor(11, 3);
 //lcd.print(buffer[3]);
 }

 

Ortsradioaktivität mit Homematic

Loading

sfws.lfrz.atMein Interesse an Strahlungsmessung im Allgemeinen und das Interesse am Eigenbau von Messgeräten lässt mich oft, vor allem bei langweiligem Fernsehprogramm, im Web recherchieren. Auf der Suche nach dem Begriff Geigerzähler findet man ja unheimlich viele Ergebnisse. Nach einer Unterhaltung mit einem Kollegen, wie es zu Zeiten von Tschernobyl hier mit der Strahlungsbelastung aussah, suchte ich auch nach einer Karte mit der aktuellen Strahlungsverteilung in Österreich und wurde auch fündig. Es gibt ein ganzes Netzwerk an Messgeräten in ganz Österreich verteilt, das stündlich die Radioaktivität misst und aufzeichnet. Über diese Website kann man sich anhand einer Karte mit unterschiedlich (entsprechend der Intensität der Strahlung) eingefärbten Punkten informieren. Klickt man einen Messpunkt an, so erhält man die Detailwerte der Messungen angegeben in nSievert/h dargestellt als Diagramm oder auch in Tabellenform. Die Website nennt sich: https://sfws.lfrz.at.

Toll dachte ich beim Betrachten der Messdaten. Noch toller wäre es, selber so eine Messstation aufzubauen und in mein bestehendes Homematic-System mit aufzunehmen. Oder für´s erste könnte man ja versuchen, die Daten der Website in die Homematic zu integrieren. … und dann beispielsweise bei Überschreitung eines Messwertes eine Nachricht oder einen Alarm zu generieren.

Also habe ich mir die Website genauer angesehen und die java- und php-scripten analysiert, die hier aufgerufen werden. Schlussendlich lässt sich über die Seite https://sfws.lfrz.at/json.php ein gutes Interface erreichen, dass mit den entsprechenden Kommandos bedienen kann. Für meinen Fall hole ich mit https://sfws.lfrz.at/json.php?command=getstationdata&stationcode=AT0408&a=&b= die Messdaten für eine nahe Messstation ab.

Der webresponse sieht dann in etwa so aus:

{"v":[{"d":1457276400,"v":90.1,"c":32768}, {"d":1457272800,"v":88.9,"c":32771}, {"d":1457269200,"v":85.8,"c":32781}, {"d":1457265600,"v":83.1,"c":32790}, {"d":1457262000,"v":83.7,"c":32788}, {"d":1457258400,"v":86.6,"c":32778}, {"d":1457254800,"v":88.2,"c":32773}, {"d":1457251200,"v":83.1,"c":32790}, {"d":1457247600,"v":84.2,"c":32786}, {"d":1457244000,"v":85.1,"c":32783}, {"d":1457240400,"v":89.7,"c":32768}, {"d":1457236800,"v":99.1,"c":38656}, {"d":1457233200,"v":101,"c":39680}, {"d":1457229600,"v":90.8,"c":33280}, {"d":1457226000,"v":92,"c":34048}, {"d":1457222400,"v":112,"c":46848}, {"d":1457218800,"v":115,"c":48896}, {"d":1457215200,"v":109,"c":45056}, {"d":1457211600,"v":104,"c":41728}, {"d":1457208000,"v":91.5,"c":33536}, {"d":1457204400,"v":89.7,"c":32768}, {"d":1457200800,"v":84.9,"c":32784}, {"d":1457197200,"v":84.4,"c":32785}, {"d":1457193600,"v":83.5,"c":32788}], "a":"1457190947","b":"1457277347"}

Also perfekte Rohdaten um damit was anfangen zu können 🙂 Im Datensatz ist der Zeitstempel (im Unix-Zeitcode Format), der Messwert in nS/h, sowie ein RGB Farbcode für die Darstellung der Farbe in der Webkarte angegeben. Also beginnen wir, die Messdaten über die Homematic CCU2 Zentrale abzurufen und nach der Datenaufbereitung in Systemvariablen zu speichern.

Als erstes legen wir zwei neue Systemvariablen an:Systemvariable_StrahlungswertDie erste Variable soll „Strahlungswert“ heissen und vom Datentyp „Zahl“ sein. Als Maßeinheit gebe ich nS/h (nanoSivert pro Stunde) an.

Systemvariable_MesszeitpunktDie zweite Variable benennen wir „Messzeitpunkt“ mit dem Datentyp „Zeichenkette“. Wenn alles mit OK bestätigt ist, dann legen wir unter Programme und Verknüpfungen ein neues Programm an:

neuesProgrammDas Programm habe ich „strahlungswerte über web“ genannt und als Trigger ein periodisches Zeitevent definiert. Das Programm soll alle 60 Minuten ausgeführt werden um die Daten vom Web abzuholen und in die Systemvariablen zu schreiben.

Zeiteinstellung

Nachdem der Auslöser definiert ist, muss eine Aktivität bestimmt werden. Wir wählen hier keinen Aktor, sondern die Option „Skript“:

neuesProgrammDanach klicken wir auf die Script-Zeile und öffnen den Scripteditor:

scripteingebenDie nachfolgenden Zeilen sind am besten per copy und paste in den Scripteditor einzufügen und per OK zu bestätigen.

 

!script zum importieren der webdaten von der landeswarnzentrale radioaktivität
!by ingmar b.03/2016
string stderr;
string stdout;
string answer;
!Website angeben - die Antwort kommt als string
&nbsp;&nbsp;&nbsp; string url="https://sfws.lfrz.at/json.php?command=getstationdata&stationcode=AT0408&a=&b=";

!mit wget den Inhalt der Antwort in stdout schreiben&nbsp;&nbsp; &nbsp;
!wget commando bei CCU2
!system.Exec("wget -q -O - "#url, &stdout, &stderr);

!Änderung: Ein Blogleser hat mich daraug aufmerksam gemacht, dass der Aufruf von gwet bei der ccu3 nicht wie oben angegeben funktioniert. Darum bei ccu3 Geräten wie folgt:
!wget commande bei CCU3
system.Exec("wget -q -O - '" # url # "'", &stdout, &stderr);
!stdout in die variable answer schreiben
answer = stdout;
!stringlänge des Inhalts von answer ermitteln
integer length = answer.Length(); 
!foreach(summand, summanden.Split(","))
!answer=answer.Split("},{"));
var rad;
var zeitst;
var radiation;
var zeitstempel;
!Antwort Radiation&nbsp; in index 1,4,7,10,13...70
!Antwort Zeitcode in index 0,3,6,9,12...69
rad=(answer.StrValueByIndex(",", 1)); 
zeitst=(answer.StrValueByIndex(",",0));
!WriteLine(rad); nur zum debuggen
!WriteLine(zeitst); nur zum debuggen
radiation=rad.Substr(4,4);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !String an pos4 substituiern und 4 Stellen ausgeben
zeitstempel=zeitst.Substr(11,10);&nbsp;&nbsp; !String an pos11 substituiern und 10 Stellen ausgeben
zeitst=zeitstempel.ToInteger();
zeitst=zeitst.ToTime();
rad=radiation.ToFloat();
dom.GetObject("Messzeitpunkt").State(zeitst); !Systemvariable muss definiert sein
dom.GetObject("Strahlungswert").State(rad); !Auch die Systemvariable 'Strahlungswert' vorher anlegen

 

Zum Schluss noch per Fehlerprüfung nachsehen ob der code ein Problem hat und dann OK und mit OK speichern. Hat alles geklappt sollte man jetzt die Systemvariablen ansehen können und es sollten auch gültige Werte zu sehen sein:

Systemvariablen

NTC am Arduino

Loading

ArduTemp(2)Nach dem kleinen Projektchen „Arduino mit Matlab“ möchte ich der Vollständigkeit halber den selben Aufbau auch noch ohne Matlab laufen lassen. Dabei soll der Code mit der mitgelieferten Arduino Entwicklungsumgebung „Arduino Software 1.6.7“ erstellt und in den Atmega 328 geladen werden. Damit man in dieser Stand-Alone-Variante auch was sehen kann, soll ein altes vierzeiliges LC-Display angeschlossen werden. Idealerweise gibt es hier eine schöne library namens LiquidCrystal.h, mit der das LCD im 4Bit Betrieb ganz einfach angesteuert werden kann.

Also schnell die benötigten Pins des LCD (übrigens ein JM204A) aus dem Datenblatt herausgesucht und mit Flachbandkabel und Pinheadern versorgt und an den Arduino angeschlossen. (die Belegung des Arduino habe ich im Script angegeben)

 

ArduTemp(1)Der NTC-Spannungsteiler bleibt, wie er ist. Und schon kann’s losgehen. Da wir die vier schönen Zeilen mit 20 Zeichen pro Zeile am LCD zur Verfügung haben, kann auch viel Information angezeigt werden. Ich habe mich entschieden, den Integer Wert des 10Bit ADC anzuzeigen (0-1023), den errechneten Widerstandswert des NTC´s und natürlich die daraus errechnete Temperatur.

Und das hier ist der simple Code 😉 …

 

/* ingmarsretro 2016
* Pinzuordnungen fürs LCDisplay
&nbsp;* RS to digital 12
&nbsp;* EN to digital 11
&nbsp;* D4 to digital 5
&nbsp;* D5 to digital 4
&nbsp;* D6 to digital 3
&nbsp;* D7 to digital 2
&nbsp;* R/W to ground
&nbsp;* VSS to ground
*/

// include libraries
#include <LiquidCrystal.h>
#include <math.h>
int analogpin = 0;
int analogvalue = 0;
double a1=3.354016E-03;
double b1=3.2569850E-04;
double c1=2.61013E-06;
double d1=6.38309e-08;
double urt=0;
double rt=0;
double rvsrref=0;
double temp=0;
double tempc=0;
double r=2200;
double rref=2200;
double analog=0;

// interfacepins initialisieren
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
&nbsp; // setup LCD spalten und reihen
&nbsp; lcd.begin(20, 4);
&nbsp; lcd.print("Testprogramm NTC");
&nbsp; Serial.begin(9600);
}

void loop() {
&nbsp; analogvalue=analogRead(analogpin);
&nbsp; analog=(0.004882812*analogvalue);
&nbsp; urt=5-analog;
&nbsp; rt=((r/analog)*urt);

&nbsp; rvsrref=rt/rref;
&nbsp; temp=(1/(a1+(b1*log(rvsrref))+(c1*(log(rvsrref*rvsrref)))+(d1*(log(rvsrref*rvsrref*rvsrref)))));
&nbsp; tempc=temp-273.15;
&nbsp;
&nbsp; //&nbsp; column 0, line 1
&nbsp; // (note: line 1 is the second row, since counting begins with 0):
&nbsp; lcd.setCursor(0,1);lcd.print("ADC-Wert =");
&nbsp; lcd.setCursor(11,1);
&nbsp; lcd.print(analogvalue);
&nbsp;
&nbsp; lcd.setCursor(0, 2); &nbsp;
&nbsp; lcd.print("Widerstd =");
&nbsp; lcd.setCursor(11, 2);
&nbsp; lcd.print(rt);

&nbsp; lcd.setCursor(0, 3); &nbsp;
&nbsp; lcd.print("Temp Cels=");
&nbsp; lcd.setCursor(11, 3);
&nbsp; lcd.print(tempc);

 

Vorsicht bei Elektroartikeln aus Fernost

Loading

DSC_2196Neulich ist mir bei einem Kaltgeräte Anschlusskabel aufgefallen, dass sich der Kabelmantel im Bereich der Zugentlastung gelöst hat. Die Drähte kamen zum Vorschein. Ansich ist das jetzt nichts Besonderes, wenn hier nicht, abgesehen von den ungewöhnlichen Farben, auch der ungewöhnlich kleine Durchmesser der Drähte in Auge stechen würde.

DSC_2199
links: Kabel ohne CE Kennzeichnung rechts: Standardkabel
DSC_2198
Stecker ohne jegliche Prüfzeichen.

Normalerweise ist so ein Mantelkabel mit 16A/250V und einem CE Zeichen am Stecker gekennzeichnet. Der Querschnitt der Litzendrähte beträgt 1.5mm2.  Bei dem Kabel hier am Foto war aber eine Angabe von 10A/250V aufgedruckt und KEIN CE Zeichen vorhanden. Die Litzen haben einen Querschnitt von unter 0.5mm² !! Wer so ein Kabel verwendet und beispielsweise ein Heizgerät damit betreibt, der darf sich dann nicht wundern, wenn mal schnell ein kleiner Brand ausbricht… Leider kann ich nicht mehr nachvollziehen mit welchem Gerät ich dieses Kabel mitgeliefert bekommen habe. Aber es entspricht nicht den gültigen Normen und stellt eine Gefahr im Betrieb dar. Auf jeden Fall: Finger weg von solchen Produkten!

Arduino mit Matlab … Der Sensor

Loading

Nachdem ich im letzten Teil die Installation der Arduino-Matlab Packages zum Laufen bekommen habe, kann es nun weitergehen. Ziel dieses kleinen Beispiels ist es ja, an einen Arduino Uno einen NTC-Widerstand anzuschließen. Dieser soll als analoger Temperatursensor dienen (was er ja ist 😀 ) und über einen der A/D – Eingänge des Arduino eingelesen werden. Matlab soll dann schlussendlich die eingelesenen A/D- Werte  in Temperaturwerte umrechnen. Das Ganze soll über eine gewisse Zeit laufen, wobei alle paar n-Sekunden ein Wert eingelesen wird. Am Ende soll ein wunderschöner Temperaturplot mit Temperatur über Zeit erstellt werden.

Doch zuerst zum Sensor. Ich verwende hier einen NTC-Widerstand von dem Hersteller VISHAY mit einem R25 von 2200 Ohm (s.Datenblatt). Das bedeutet, er hat bei 25°C einen ohmschen Widerstand von 2.2kOhm. Je wärmer es nun wird, umso kleiner wird der Widerstand und umgekehrt. Der analoge Eingang des Arduino hat eine Auflösung von 10Bit. Das bedeutet, er kann den Spannungshub am Eingang (eingestellt durch die ADC Referenz) in 210 , also 1024 Teile auflösen (zerlegen). Der Standard beim Arduino ist 0V bis 5V. Also 0V am Eingang bedeutet einen ADC-Wert von 0 und 5V bedeutet einen ADC-Wert von 1024. Die Auflösung, also die kleinste auflösbare Spannungsänderung  ist daher:
formelarduino01 (2)Gibt der ADC beispielsweise einen Wert von 558 aus, so entspricht dies einer Spannung am Eingang von 558*0.00488V = 2.72304V. Doch wie soll der NTC jetzt an den Eingang angeschlossen werden? Ganz einfach. Man nehme einen Spannungsteiler und dimensioniere ihn so, dass der Strom durch die beiden Widerstände nie so groß werden kann, dass er zum einen die Versorgung des Arduino gefährdet und zum anderen auch nie so groß werden kann, dass er den NTC selbst erwärmt. In der Skizze ist nun dargestellt wie der Spannungsteiler aufgebaut und angeschlossen ist. Jetzt gilt es noch herauszufinden, wie aus der Spannung am ADC der gemessene Widerstandswert berechnet werden kann. Hier hilft die Spannungsteilerregel:
formel2
In diesem Beispiel hier besteht der Spannungsteiler aus dem NTC (2k2 @ 25°C) und einem 2k2 Festwiderstand. Wenn der NTC null Ohm haben sollte (nur rein theoretisch), so fließt ein maximaler Strom von 0.002A durch die Widerstände (5V/2200Ohm). Wir lesen jetzt in Matlab den Spannungsabfall am NTC ein und können uns über den Spannungsteiler den Widerstandswert berechnen. Jetzt fehlt nur noch die Formel zur Berechnung der Temperatur. Und die ist, samt den notwendigen Konstanten A1, B1, C1 und D1, im Datenblatt angegeben:formel3Das Ergebnis dieser Berechnung ist die Temperatur in Kelvin. Um die Temperatur aber in °Celsius angezeigt zu bekommen, rechnet man: °C = °K-273,15. Mit all diesen Informationen kann man jetzt ein Matlab-Script schreiben, das dann in etwa so aussieht:
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Beispielscript um mit ArduinoUno einen Temperaturverlauf aufzuzeichnen
% 02/2016 by I.Bihlo
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
&nbsp;
%a = arduino('com5','Uno');
&nbsp; a = arduino('com5','Uno','TraceOn', true)
&nbsp; analogpin=0;
&nbsp; analog=0;
&nbsp;
&nbsp; %ein paar konstanten für die weiteren berechnungen
&nbsp; %
&nbsp; r=2200;&nbsp; %Spannungsteilerwiderstand
&nbsp; rt=0; %das wird der errechnete widerstand des NTC
&nbsp; urt=0; %das wird der errechnete Spannungsabfall am NTC
&nbsp;
&nbsp; % konstanten für berechnung der Temperatur aus NTC Widerstand
&nbsp; % B25=3977K
&nbsp; a1=3.354016E-03;
&nbsp; b1=3.2569850E-04;
&nbsp; c1=2.61013E-06;
&nbsp; d1=6.38309e-08;
&nbsp; rref=2200;
&nbsp;
&nbsp;
&nbsp;
&nbsp; %Lesen eines Temperaturabhängigen Widerstandes am Analog Eingang A0
&nbsp; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
&nbsp;
&nbsp; for x=1:50
&nbsp; analog(x)=readVoltage(a, analogpin) %Liest den AnalogIn von A0 und gibt in Volt aus
&nbsp; urt(x)=5-analog(x); %spannungsabfall am NTC
&nbsp; rt(x)=(r/analog(x))*urt(x); %widerstand des NTC
&nbsp;
&nbsp; %berechung der temperatur
&nbsp; rvsrref(x)=rt(x)/rref;
&nbsp; temp(x)=1/(a1+(b1*log(rvsrref(x)))+(c1*(log(rvsrref(x)^2)))+(d1*(log(rvsrref(x)^3))));
&nbsp; tempc(x)=temp(x)-273.15 %Kelin in Celsius umrechnen
&nbsp; pause(2);
&nbsp;
&nbsp; end
&nbsp;
&nbsp; clear a;
&nbsp;
&nbsp; %plot den mist
&nbsp; figure(1);
&nbsp; time=1:50;
&nbsp; plot(time,analog,'b');
&nbsp; grid on; hold on;
&nbsp; plot(time,rt/1000,'r');
&nbsp; plot(time,urt,'g');
&nbsp; plot(time,tempc,'m');
&nbsp; legend('Analogspannung des ADC','Widerstand des NTC in kOhm','Spannung am NTC','Temperatur [°C]'); 
&nbsp; %ende

 

 
temperaturgraph
So sieht der Graph mit dem Temperaturlog danach aus…

Ärger mit HDMI Upscaler

Loading

DSC_2164Dieses Teil hier habe ich mir über ebay bestellt. Es ist dies ein Video – „Upscaler“, also ein Teil, das den alten analogen Videostandard (Composite CVBS) digitalisiert und in den HD-Standard 720p bzw. 1080p hochrechnet und über eine HDMI Buchse ausgibt. Gedacht ist es, um den Output eines alten VHS-Recorders, einer alten Spielekonsole oder des guten alten Commodore C64 auf den Fernseher, oder eher auf einen Computermonitor zu bekommen, der einen digitalen Eingang (DVI) hat. So also der Plan. Also im Netz gesucht und unter vielen Angeboten ein Gerät gefunden, das neben den Chinch Buchsen für CVBS-Video und Audio L,R auch noch einen HDMI Eingang besitzt. Cool – dachte ich. Mit drei Tasten soll man Auflösung, 50/60Hz (Pal/NTSC-TV Norm) und eben den Eingang umschalten können.

 

DSC_2165Also bestellt, bezahlt und auch geliefert bekommen. Und gleich einen ersten Test, wie denn die Bildqualität am PC-Monitor so sei, begonnen. Also das Gerät (in einer Mattschwarzen Metallbox – optisch gut verarbeitet) angeschlossen, das mitgelieferte 5V Steckernetzteil eingestöpselt und in freudiger Erwartung auf den Bildschirm gestarrt. Da stand aber außer „kein Signal“ nur mehr … eben „kein Signal“.

Also erstmal überprüft, ob Saft da ist. Ja – die rote Led am Gerät leuchtete. Dann die Kabelverbindungen überprüft, andere Kabel bzw. Adapter verwendet – nichts. Danach versucht, vom Raspi über HDMI an die Box, dann weiter über HDMI an den TV … nichts. Dann alle möglichen Tasten und Kombinationen gedrückt … wieder nichts. Als Endkontrolle dann den Raspi direkt mit dem TV über HDMI verbunden – und bumm – Bild ist da. Also muß was mit dem Converter nicht stimmen. Kein Problem dachte ich, reklamieren und zurücksenden. Genau das habe ich nach Absprache mit dem Lieferanten auch gemacht. Dann passierte erstmal nicht. Keine Rückerstattung, kein neues Gerät. Die Zeit verging … knapp sechs Wochen später kam dann der Paketdienst – aber er brachte keinen neuen Converter, sondern mein Paket wieder zurück. Mit dem Postvermerk „wurde nicht abgeholt“. Also wieder den Lieferanten kontaktiert… er habe nichts erhalten, auch keinen Abholschein, bekam ich zu hören. Ich solle das Paket einfach noch einmal versenden. Die Kosten für den Rückversand trage er aber nicht. (wieder nicht). Das war jetzt genug. Das Hin- und Her senden übersteigt ja schon fast den Warenwert. Da von diesem Händler kein kulantes Verhalten zurückkam, kam von mir eine negative ebay-Bewertung und ich verzichtete auf den ganzen Rechtsanspruch und Käuferschutz. Dafür nahm ich das Gerät unter die Lupe.

DSC_2166Auf den ersten Blick sieht das Innenleben recht ordentlich aus. Wenn man aber genauer hinsieht, dann erkennt man eine Verarbeitung nach „Fernostqualität“. Der MST6M181VS-LF-Z1 Videoprozessor Chip beispielsweise, wurde bei der Bestückung scheinbar nicht exakt positioniert und leicht verdreht festgelötet. Auch war zwischen den Pads und den Anschlussbeinchen des IC´s ein Spalt zu erkennen. Und hier ist auch das Problem. Als ich testweise mit den Fingern Chip und PCB zusammendrückte, startete der Upscaler und zeigte am  TV ein kleines Infofenster mit Auflösung und Scanfrequenz. Das bedeutet, dass es hier Verbindungsprobleme gibt. Also startete ich den Versuch, mit der Reworkanlage und ein wenig Kolophonium, den Chip nachzulöten. Das gelang auch, und der Scaler startet jetzt immer zuverlässig.

DSC_2163
IC ist schlecht positioniert
DSC_2158
Nachlöten mit Heißluft

Aber leider hielt das nur kurze Zeit, er startet zwar immer noch, zeigt aber nur mehr wirre Pixel und bunte Flächen an. Vermutlich hat der Reworkprozess den Chip zu sehr gestresst und ihm ein vorzeitiges Ende bereitet. Also noch einmal mit der Heißluft nachgelötet (kann ja sein dass immer noch eine Lötstelle nicht passt), aber das Ergebnis war dasselbe.

 

Arduino mit Matlab … Startschwierigkeiten

Loading

arduino01 (4)Heute möchte ich ein Thema vorstellen, mit dem ich mich kurz im Rahmen einer Recherche beschäftigt habe. Viele (Techniker) kennen vielleicht die Software Matlab von der Firma Matworks. Das ist ein extrem umfangreiches Softwarepaket, das bei uns in der Lehre eingesetzt wird, um Studierende in allen möglichen technischen Bereichen zu unterrichten. Sei es Signalverarbeitung, Regelungstechnik, Bildverarbeitung, etc. – Matlab ist das Tool, um all das professionell umzusetzen. Auch wenn es um Messdatenerfassung geht, muß man nicht unbedingt auf Tools zurückgreifen, mit denen ein Projekt oder Programm „gezeichnet“ wird. Das ist zwar toll für den Einstieg, kann (und wird) in späterer Folge aber aufgrund des riesen Overheads und der benötigten PC Resourcen viel zu umständlich, wenn man schnell einmal über eine externe Hardware irgendwelche physikalischen Größen aufzeichnen und verarbeiten will.

In diesem kleinen Projektchen möchte ich nun zeigen, wie einfach man mit Hilfe eines Arduino Uno Boards zusammen mit Matlab eine Temperaturmessung realisieren kann. Der Sensor soll hier ein ganz einfacher NTC Widerstand sein. Das bedeutet, der ohmsche Widerstand des Bauteils ändert sich mit der Temperatur, in dessen Umgebung sich das Bauteil befindet. Die Änderung passiert hier folgendermaßen: wenn die Temperatur steigt, so wird der ohmsche Widerstand kleiner. (Negativer Temperatur Koeffizient) (Coefficient engl. -> NTC). Einziger kleiner Haken – die Änderung passiert nicht linear wie zum Beispiel beim PT100. Das bedeutet der Verlauf  des Widerstands bei Änderung der Temperatur ist keine Gerade mit irgendeiner Steigung, sondern eine e-Funktion. Das wiederum bedeutet, dass, will man aus den gemessenen Widerstandwerten in eine Temperatur zurückrechnen, die Funktionsgleichung zum NTC gefunden werden muss. Glücklicherweise findet man diese aber fix und fertig in den Herstellerdatenblättern 😉 aber dazu später.

Man hat nun einen temperaturabhängigen Widerstand, ein Arduino Uno – Board und einen PC auf dem Matlab läuft. Wie geht´s nun weiter? Nehmen wir als Beispiel an, dass Matlab 2014b installiert ist. Nun gibt es in Matlab unter dem Tab „Home“ eine Rubrik, die sich „Add-Ons“ nennt. Klick man auf  diese, so klappt ein Menue auf, in dem man den Eintrag „Get Hardware Support Packages“ findet. Den klickt man an und es öffnet sich ein Fenster namens „Support Package Installer“.

Unter „Install from Internet“ und „Next>“ kommt man zu einem Auswahlmenue der verfügbaren Packages. Hier sucht man sich „Arduino“ aus und setzt im rechten Bereich des Fensters einen Haken – und zwar bei dem Paket „Aquire inputs and send outputs on Arduino Uno…“. Danach wieder auf „Next>“ klicken und die Installation vollenden.

Ist alles erledigt so kann man den Arduino am USB-Port anstecken. Windows sollte einen Treiber zuordnen. (Unter Systemsteuerung – Gerätemanger – Anschlüsse > sollte ein Arduino Uno (COMx) zu finden sein). Ist das der Fall, dann sollte es klappen 🙂

Jetzt kann in der Matlab Console folgender Befehl eingegeben werden:

arduino()

Folgende Antwort kommt nun zurück:

 arduino with properties:

Port: 'COM5'
Board: 'Uno'
AvailableAnalogPins: [0, 1, 2, 3, 4, 5]
AvailableDigitalPins: [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Libraries: {'I2C', 'SPI', 'Servo'}

Der COM-Port unterscheidet sich natürlich und wird meist auf den nächsten freien COM gemappt. Hat das aber geklappt, so ist der erste Teil schon gewonnen. Matlab kommuniziert mit dem Arduinoboard. Es kann aber auch vorkommen, dass Fehlermeldungen auftauchen. Wie bei mir der Fall:

Cannot detect Arduino hardware. Make sure original Arduino hardware is properly plugged in. If
using unofficial(clone) hardware, specify port and board type. For more information, see the
arduino function reference page.

Das war die erste Meldung nach der Installation: Dafür gibt’s aber auch Abhilfe. Man gibt folgendes ein:

a = arduino('com5','Uno')

Wenn auch dann eine Fehlermeldung kommt, so wie natürlich bei mir, dann kann man mit folgendem commando auf Fehlersuche gehen:

 a = arduino('com5','Uno','TraceOn', true)

Jetzt kam bei mir die Meldung : Updating server code on Arduino Uno (COM5). Please wait.  Und danach gleich ein Errorfenster mit einem „avr-gcc.exe
Die Anwendung konnte nicht korrekt gestartet werden (0xc00000142)“ Fehler. Danach habe ich lange in diversen Foren gesucht, Tracelogs verglichen und nach den Fehlermeldungen gegoogelt. Hier gab es Tips von: die make.exe in den Tiefen des SupportPackages Ordner ist nicht kompatibel mit 64bit Systemen, mit Windows8.1 und Windows10 gibt es Zugriffsrechteprobleme und und und. Leider war aber nie ein Lösungsvorschlag dabei der bei mir funktionierte. Also habe ich auf einem zweiten Rechner eine jungfräuliche Installation von Matlab und dem Arduino Matlab Package durchgeführt. Und siehe da – es funktionierte. Aber wie jetzt nach dem Fehler suchen, oder ihn beheben. Also habe ich auf dem funktionierenden Rechner einen Tracelog durchgeführt, indem ich beim Aufrufen der Arduinofunktion einen Port angegeben habe, auf dem ein anderes NICHT Arudino Gerät angeschlossen ist. Und siehe da, der Errortracelog war seeehr lange und ausführlich. Man konnte ansehen was die Funktion alles aufruft. Und irgendwo ganz unten im Log las ich was von avrdude… Da kam mir die Idee. Auf meinem PC sind einige Entwicklungsumgebungen installiert. Unter anderem auch AVR-Studio und der WinAVR20100110 Compiler. Und genau der war das Problem. Den WinAVR gelöscht und schon klappte es.

Also steht dem weiteren Aufbau zur Realisierung des Projektchens nichts mehr im Weg. Aber darüber scheibe ich beim nächsten Mal in Teil 2…

 

Drehpendeluhr mit Sperrschwingerantrieb

Loading

sperrschwinger_drehpendelEin ein Euro-Schnäppchen aus eBay steht dieses Mal auf dem Tisch. Da es ja laut Kalender noch Winter ist, eine perfekt passende Freizeitaufgabe für diese Jahreszeit. Auf dieses Teil habe ich nur wegen der Glashaube mitgeboten, da ich  die eigentlich als Ersatz für eine andere Uhr benötige. Aber als ich dann bei einem Euro den Zuschlag erhielt und das Ding geliefert wurde, stellte sich heraus, dass es gar nicht so schlecht aussieht und vor allem zum Großteil aus Messing besteht. Einzige Ausnahme ist das Uhrwerk selber.

Es ist das Uhrwerk einer Haller – Drehpendeluhr mit Batterieantrieb. Allerdings noch kein Quarzwerk, bei dem das Drehpendel nur zur Zierde mitläuft, sondern ein sogenannter Sperrschwingerantrieb. Hier stellt das Pendel zusammen mit einer Spulenkonstruktion und einem Kondensator , die zeitbestimmende Konstante dar. Ein Sperrschwinger ist eine elektrische Oszillatorschaltung, die mit Hilfe einer gekoppelten Doppelspule und einem elektronischen Schalter (Transistor, oder früher Elektronenröhre) die elektrische Energie in einen Schwingungsvorgang umwandelt. Dabei dient ein Kondensator in Serie zu einer Wicklung als Zeitkonstantengeber. Die Spule als Steuerspule für den Transistor, und die Koppelspule als Arbeitsspule für einen drehbar gelagerten Permanentmagneten.

sperrschwinger_schaltung
Funktionsschema des Sperrschwingers

Das funktioniert folgendermaßen: Beim Einschalten wird der Kondensator geladen. Da er in Serie zur Spule liegt, fließt durch ihn und die Spule der Ladestrom. Dieser steuert zum einen den Transistor aus, der wiederum die Koppelspule mit Energie versorgt. Diese Energie hat ein Magnetfeld zur Folge, das wiederum den Permanentmagneten abstößt. Dieser dreht sich nun von der Spule weg.

Nach diesem ersten Impuls ist nun aber auch der Kondensator aufgeladen und es fließt kein Strom mehr. Der Transistor sperrt und die Koppelspule hat nichts zu tun.

Da sich aber der drehbare Magnet, der auf unserer Drehpendelachse befestigt ist, noch dreht, kommt er nun irgendwann wieder an der Spule vorbei. Dort induziert er einen negativen Impuls, der der Ladung des Kondensators entgegenwirkt. Der ist also wieder entladen. Jetzt will er sich natürlich gleich wieder aufladen und lässt einen Strom durch ihn selbst und die Spule fließen. Das wiederum steuert den Transistor aus, der wiederum lässt Strom durch die Koppelspule fließen… die wiederum baut ein Magnetfeld auf … das Magnetfeld drückt den Permanentmagneten der Pendelachse wieder weg … usw., usw.

Jetzt muss man nur noch die sich drehende mechanische Energie der Pendelachse zum Antreiben einer Uhrenhemmung verwenden. Und voila, man hat eine Uhr.

sperrschwinger1Die Uhr kam beinahe in einem Stück bei mir an. Einzig im Uhrwerk war kein Rädchen mehr an seinem Platz – hier hatte der Vorbesitzer wohl erfolglos versucht einen Fehler zu beheben. Also habe ich zuerst einmal die paar Plastikzahnrädchen wieder an ihren Platz gesteckt und alles sauber zusammengebaut. Das auf einem Permanentmagneten gelagerte Pendel drehte sich auch nahezu widerstandfrei. Also eine Batterie hinein und … nichts. Keine Bewegung, absolut keine Reaktion. Also wieder alles demontiert und die Platine mit den Koppelspulen unter die Lupe genommen. Und siehe da – eine Unterbrechung der grünen Spule – hier war der Draht gerissen.

sperrschwinger2Glücklicherweise ist das an einer sehr gut zugänglichen Stelle, sodass eine Reparatur einfach war. Nachdem nun beide Spulen wieder in Ordnung waren, ging’s an den erneuten Zusammenbau. Gleich nach dem Einlegen der Batterie war sofort zu bemerken, wie sich nun der Permanentmagnet des Schwingers wieder von der Spule abstößt.

 

 

 

In dem folgenden Filmchen ist das Arbeitsprinzip der Mechanik dargestellt:

Das hier sind alle Teile der Mechanik, aus der die Uhr aufgebaut ist. Also ein sehr einfaches Werksperrschwinger_drehpendel_teileDas hier ist die Mechanik mit der Hemmung (alles in Plastik) ohne die Antriebseinheit:

sperrschwinger_mechanik

 

 

Stylophone – Pocket Synthesizer

Loading

stylo(7)Ein interessantes Gerät ist das sogenannte „Stylophone„. Es ist ein einfaches elektronisches Musikinstrument das ursprünglich von der Firma Dubreq hergestellt wurde. Es handelt sich dabei um ein Miniaturkeyboard, dessen „Tasten“ mit einem „Stift oder Stylus“ berührt werden. Der Stift hat eine elektrisch leitfähige Spitze und ist mit einem Draht zum Gerät verbunden. Die Tasten sind eigentlich keine Tasten, sondern nur elektrisch leitfähige Flächen einer Platine. Berührt man mit dem Stift jetzt eine der Tastenflächen, so wird ein Stromkreis geschlossen, der einen elektronischen Tongenerator aktiviert. Jede der Tastenflächen stellt für den Tongenerator einen anderen elektrischen Widerstand dar, der damit auch die Tonfrequenz des Generators verändert.

Es ist also ein einfacher Synthesizer. Das Klangbild kann durch Zuschalten eines Multivibrators und verschiedenen Filtern verändert werden. Auch die Oktaven lassen sich umschalten. Das erste Stylophone oder Elektrophon wurde im Jahr 1967 entwickelt und in den Siebzigerjahren von einigen Bands eingesetzt. Bei dem hier vorgestellten Gerät handelt es sich um eine Nachbau-Neuauflage, die mit modernerer Elektronik ausgestattet ist.

stylo(1)Die kleine Platine beherbergt die Schaltung für den Tongenerator und einen Audioverstärker für die Tonausgabe über den Lautsprecher. Auf der großen Platine sind die Tastenfelder angebracht. Es gibt noch zwei Umschalter für die Klangbilder, zwei 3.5mm Klinkenbuchsen um ein externes Audiosignal einzumischen und das Gesamtsignal auszugeben, sowie ein Potentiometer zum Stimmen.

 

stylo(2)

Hier ist die Platine mit einer einfachen Multivibratorschaltung (Oszillator) und dem NF-Verstärker zu sehen. Das Stylophone erzeugt einen monophonen, also einen Kanal, Audioausgang.

stylo(5)

Gespielt wird das Stylophone mit dem Stylus, dem Stift, der den elektrischen Kontakt zu den Tastenflächen herstellt.

stylo(9)

Im folgenden Video“16 Classic Hits On Stylophone“ wird gezeigt, was man mit dem Stylophone machen kann, wenn man es kann. (c)YouTube user: maromaro1337