Archiv der Kategorie: Elektronikbastler

Beiträge über Bastelprojekte zum Thema Elektronik
zum Beispiel: Ein Radio mit Arduino, Geigerzähler…

Konfigurierbare Steckernetzteile

Loading

Dieser kurze Beitrag soll nur als Hilfe dienen, um gegebenenfalls schnell nachsehen zu können. Im Laufe der Zeit sammeln sich bei vermutlich jedem von uns unzählige Steckernetzteile und Adapter an. Einige sind Festspannungsnetzteile, andere wiederum sind im Bereich der Ausgangsspannungen einstellbar. Einstellen lassen sich die Ausgangsspannungen dieser Netzteile mit Schiebe- oder Drehschaltern oder auch mit kleinen Steckern (Jumpern) in denen Widerstände verbaut sind.

Auf den Jumpern ist auch immer die Spannung aufgedruckt, die damit eingestellt wird. Es gibt jedoch einen kleinen Haken an der Sache. Wenn man mehrere unterschiedliche Netzteile (unterschiedlich im Bereich der Leistung und auch im Ausgangsspannungsbereich) hat, dann hat man schnell ein Sammelsurium unterschiedlicher Widerstandsjumper. Das Problem ist jetzt, dass die Jumper alle gleich aussehen und auch mit gleichen Spannungswerten bedruckt sind. Sortiert man die nicht ordentlich zu den jeweiligen Netzteilen, dann ist das Malheur schnell passiert. Ein Beispiel: Ein Netzteil der Type SPS24-24W hat einen Jumper mit Aufdruck 9V. Der Jumper hat einen Widerstand von ca. 9kOhm. Ein anderes Netzteil der Type SPS12-23W hat ebenfalls einen Jumper mit Aufdruck 9V – allerdings einen Widerstand von nur 1.5kOhm. Und so ist es schnell passiert, dass man (oder ich) den Jumper vom falschen Netzteil einsteckt. In meinem Beispiel habe ich den 9V Jumper mit 1.5kOhm in das SPS24-24W Netzteil gesteckt. Bevor ich noch mit den Messstrippen an der Kabelbuchse war, gab es einen dumpfen Knall, eine allzu bekannte Rauchschwade und den dazugehörigen Geruch eines geplatzten Kondensators (Elkos).

Was war passiert? Der Wert des falschen Jumperwiderstandes war kleiner als der kleinste Wert des korrekten Jumpers (24V = 2.42kOhm). Also war die Ausgangsspannung deutlich höher als 24V und somit auch deutlich höher als die Spannungsfestigkeit des Sieb Elkos am Ausgang (der hatte bei 220µF eine Spannungsfestigkeit von 25V).

Um das zukünftig zu vermeiden, habe ich die Widerstandswerte passend zu den Netzteilmodellen der Reihe SPS herausgemessen.


Modell SPS12-12W-A
(von dem Modell habe ich leider kein Exemplar zur Verfügung – falls jemand eines zur Hand hat, würde ich mich freuen die Widerstandwerte hier in die Liste aufnehmen zu können)

Spannungen:
3V ………….  0.00k
4.5V………..  0.00k
5V…………… 0.00k
6V…………..  0.00k
7.5V……….  0.00k
9V …………  0.00k
12V………..  0.00k

Modell SPS12-24W-B
Spannungen:
3V …………. 373.0k
4.5V………..  6.01k
5V…………… 4.51k
6V…………..  3.08k
7.5V……….  2.04k
9V …………  1.54k
12V………..  1.02k

Modell SPS24-24W-A
Spannungen:
9V ………….  9.09k
12V…………  5.75k
13.5V……..  4.97k
15V…………  4.29k
18V…………  3.39k
20V ………..  2.98k
24V………..   2.42k

Modell SPS24-48W-B
Spannungen:
9V ………….  17.38k
12V…………  8.27k
13.5V……..  6.78k
15V…………  5.48k
18V…………  4.20k
20V ………..  3.60k
24V………..   2.78k

edit 10.52021: Bilder vom der Platine des  Netzteils SPS24-24W-A hinzugefügt:

VW-Audi Handyadapter USB Buchse Umbau

Loading

Universelle Ladeschale

Für viele VW und Audi Modelle gibt es als Zubehör eine universelle Handyladeschale für Mittelarmlehne. Diese Ladeschale ermöglicht es, die Antenne des Handys über eine in der Ladeschale integrierte Patch-Antenne zu koppeln und mit der Fahrzeugantenne zu verbinden. Dazu genügt es, das Telefon oder Smartphone einfach in die Schale zu legen und die Antenne ist gekoppelt. Diese „Schale“ besitzt unter einer Klappe auch einen USB Anschluss. Wenn man hier einfach ein beliebiges USB-Handyladekabel anschließt (z.B. USB auf USB-C) dann wird nichts passieren. Das Handy wird nicht geladen. Dafür kann man entsprechende Kabel als Zubehör erwerben.

Man kann diese „Ladeschale“ aber auch öffnen und sehen was in dem Gehäuse steckt und sich selber eine Lösung basteln. Dann sollte es möglich sein, jedes USB Kabel anzustecken und nicht wieder eines erwerben zu müssen. Zumal ja schon jeder etliche Kabel zu Hause hat. Also raus mit den Schrauben (sind übrigens Torx) und ‚runter mit dem Deckel.

Antennenplatine

Unter dem oberen Gehäusedeckel kommt eine schwarz lackierte Platine zum Vorschein. Diese stellt die Antennenstruktur dar und ist mit an den Enden verschmolzenen Kunststoff Bolzen befestigt.

Antennenplatine entfernt

Ist die Antennenplatine gelöst, so kann man sie vorsichtig herunterheben. Das Koaxialkabel ist an der Platine festgelötet. Man sollte also nicht zu fest daran ziehen.

Jetzt können die Schrauben des darunter liegenden Boards entfernt werden. Die Platine ist jetzt frei. Auf Ihr befindet sich unter anderen auch die DC-DC Converter Schaltung für die Stromversorgung der USB-Buchse.

Wenn man die Schaltung genauer untersucht so gibt es keine direkte Verbindung zum Minuskontakt der USB-Buchse. Die Masse des DC-Converters liegt am Shield der USB-Buchse an. Der Pluskontakt stimmt.

Eine kleine Modifikation schafft Abhilfe. Im Bild unten sind die Änderungen eingekreist.

An der rot markierten Stelle befindet sich ein SMD Kondensator. Diesen habe ich ausgelötet und damit er nicht verloren geht und ich ggf. wieder Rückbauen kann, an einer Seite an dem darunter befindlichen Kondensator festgelötet. (er befindet sich jetzt funktionslos an der grün markierten Position. An dessen ursprüngliche Stelle (rote Markierung) habe ich ein kleines Stück Draht gelötet. Dieser stellt eine niederohmige Verbindung zwischen dem Minus-Pin der USB Buchse und dem Schirm dar. Somit wird der USB Port auch ohne spezielles Kabel mit Energie versorgt.

 

IR-Thermokamera an Raspberry PI

Loading

Lepton Camera Module

Ein vielleicht interessantes kleines Projekt ist, ein Lepton Kameramodul mit einem Raspberry zu betreiben.  In meinem Fall verwende ich ein Lepton Modul mit 80×60 Pixeln bei einer Pixelgröße von 17µm und einer spektralen Empfindlichkeit im langwelligen Infrarot Bereich von 8µm bis 14µm. Die Framerate beträgt maximal 8,6 Hz. Das Kameramodul wird in ein Breakout-Board gesteckt und dieses mit dem Raspberry PI verbunden. Die Infos dazu gibt‘s weiter unten. Es gibt auch im Entwicklerbereich der Website flir.lepton.com eine Anleitung wie das Breakoutboard mit dem Raspi betrieben wird.

Camera Module mit Breakout Board V1.4

Benötigt wird ein Raspberry PI (in diesem Beispiel habe ich einen Raspberry PI4 verwendet), ein Lepton Thermal Kamera Breakout Board V1.4 und ein wenig Drahtwerk für die Verbindungsleitungen. Die genaue Teileliste (um auch alles Aufbauen und in Betrieb nehmen zu können) ist unten angeführt:

  • Raspberry PI (Modell 2,3 oder 4)
  • Micro SD-Karte (ab 8GB)
  • USB-Steckernetzteil mit Micro USB (oder USB-C) Kabel (je nach Raspberry PI Modell)
  • LAN-Kabel und Zugang zu einem Switch oder Router mit bestehender Internetverbindung
  • Idealerweise einen Rechner mit (SD-Karten-Slot) um das Image für den Raspberry vorzubereiten
  • Ein Monitor für den Raspberry PI mit HDMI oder MINI-HDMI-Kabel
  • USB-Tastatur, Maus
  • Lepton Thermal Kamera Breakout Board

Ist alles vorhanden, dann ist die Verdrahtung des Kamera Moduls mit dem PI herzustellen. Am einfachsten verwendet man die Jumper-Kabel (Female-Female) die in der Modulbastelwelt sehr beliebt sind. Ein Lötkolben ist für viele Demo- und Testaufbauten nicht mehr notwendig… Die folgende Skizze zeigt die herzustellende Verdrahtung:

Klicken zum Vergrössern

Das Pinning ist hier nochmals angeführt:

  • Raspi GPIO PIN01 (3V3)     –>    Lepton Pin VIN
  • Raspi GPIO PIN03 (SDA)    –>     Lepton Pin SDA
  • Raspi GPIO PIN05 (SCL)      –>    Lepton Pin SCL
  • Raspi GPIO PIN06 (GND)   –>     Lepton Pin GND
  • Raspi GPIO PIN19(MOSI)  –>     Lepton Pin MOSI
  • Raspi GPIO PIN21(MISO)  –>     Lepton Pin MISO
  • Raspi GPIO PIN23(CLK)      –>     Lepton Pin CLK
  • Raspi GPIO PIN24(CEO)     –>     Lepton Pin CS

Als Betriebssystem für den Raspberry Pi habe ich Raspbian installiert. Das geht entweder über den Download des RASPBIAN Images von der Webseite https://www.raspberrypi.org/downloads/raspbian oder auch über den NOOBS Installer. Mit dem Tool „etcher“ oder „win32diskimager“ kann die Image Datei auf die SD-Karte geschrieben werden. Wer mit NOOBS arbeitet braucht nur die zip-Datei auf die FAT32 formatierte SD-Karte zu entpacken. Ist das erledigt, dann einfach die SD-Karte in den Raspberry stecken, Monitor, Keyboard und Maus an den PI anstecken und zum Schluss die Stromversorgung aktivieren. Wenn NOOBS auf der Karte ist, dann wird nach dem Start eine Auswahl an zu installierenden Betriebssystemen angezeigt. Hier am besten auch RASPIAN auswählen und die Installation starten. Ist das abgeschlossen, dann ist je nach gewähltem Image entweder nur eine Konsole oder eben ein Desktop zu sehen. Im letzten Fall ist dann ein Terminal zu öffnen, damit in der Konsole weitergearbeitet werden kann.

Mit sudo raspi-config ist nach dem login in die Konsole das Raspberry PI Config – Tool zu öffnen. Darin sind folgende Services zu aktivieren:

  • SPI (unter Advanced Options)
  • SSH (unter Advanced Options)
  • I2C (unter Advanced Options)
  • Enable Camera (im Hauptmenu des raspi-config tools)

Danach ist der Raspberry zu rebooten. Nach dem erneuten Start und login (als User pi mit default Passwort raspberry) muss das Paket openCV installiert werden. Mit sudo apt-get install python-opencv ist das erledigt.

Auf GitHub habe ich eine Python Library von brandoncurtis und kekiefer für das Lepton Board gefunden. Die Library nennt sich pylepton und ist auf https://github.com/groupgets/pylepton zu finden.

Mit git clone https://github.com/kekiefer/pylepton.git legen wir das Repository  an und wechseln danach in das Verzeichnis cd pylepton. Jetzt kann das Setup Skript ausgeführt werden: sudo python setup.py install.

Mit dem folgenden kleinen Codebeispiel wird die Lepton Kamera ausgelesen, das 80×60 Pixel große Bild auf 800% skaliert und angezeigt.

 

 import numpy as np  
 import cv2  
 from pylepton import Lepton  
 with Lepton() as lepi:  
  a,_ = lepi.capture()  
 cv2.normalize(a, a, 0, 65535, cv2.NORM_MINMAX) # extend contrast  
 np.right_shift(a, 8, a) #daten in 8bit anpassen 
 cv2.imwrite("thermobild.jpg", np.uint8(a)) #bild schreiben 
 img=cv2.imread('thermobild.jpg')  
 cv2.imshow('Thermobild', img)  
 print('Originalabmessungen: ',img.shape)  
 scale_percent = 800  
 width = int(img.shape[1] * scale_percent / 100)  
 height = int(img.shape[0] * scale_percent / 100)  
 dim = (width, height)  
 resized = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)  
 print('Achtfach vergroessert: ',resized.shape)  
 cv2.imshow("Thermobild 8x", resized)  
 cv2.waitKey(0)  
 cv2.destroyAllWindows()  
 exit()  

Das Ergebnis sieht dann zum Beispiel so aus:


 

 

Diodenkennlinie mit Sourcemeter und Matlab aufnehmen

Loading

Dieses Mal gibt es hier keinen Bericht über die Restauration oder die Vorstellung eines alten Gerätes. Im Rahmen meiner beruflichen Tätigkeit muss ich immer wieder Messaufbauten realisieren und diese nach Möglichkeit automatisieren, um die Messzeiten zu minimieren. Auch die Datenauswertung und das Postprocessing möchte ich immer gerne automatisieren. Dafür gibt es sehr viele unterschiedliche Lösungsansätze. Der Grundansatz ist aber immer gleich. Ein, oder mehrere Messgeräte sind über eine Schnittstelle mit einem Rechner oder Controller verbunden. Auf dem Rechner oder Controller läuft eine Software, die das Messgerät steuert und die gemessenen Daten an den Rechner zurücksendet. Auf dem Rechner werden die Daten dann gespeichert, den Anforderungen entsprechend aufbereitet und ausgegeben.

Die Schnittstellen zwischen Rechner und Messtechnik können je nach Ausstattung des Messgerätes dabei RS232, GPIP, IEEE1394, USB oder LAN sein. Bei vielen Geräten wird der einfache SCPI-Befehlssatz im ASCII Code zum Befehle senden und empfangen über das entsprechende Protokoll der gewählten Schnittstelle verwendet. Die Software am Rechner oder Controller muss in der Lage sein die Hardware anzusprechen und schon kann eine Datenkommunikation hergestellt werden. Als Software oder Skriptsprache kann hier beispielsweise NI-LabVIEW, Matlab, C-Code, C++ Code, C#, Python, etc. verwendet werden. Und die Rechner- oder Controllerhardware kann ein Windows, Mac, oder LinuxPC sein, aber auch ein einfacher Arduino, RaspberryPi, oder ein programmierter Mikro-Controller, der eine der benötigten Schnittstelleninterfaces besitzt.

Bei meiner Arbeit wird das gerne mit Matworks Matlab gemacht (bzw. ich mache es gerne mit Matlab, weil ich Programme und Skripten lieber tippe als sie zu zeichnen 😀 ), einer skriptorientierten Software. Im konkreten Beispiel habe ich ein SOURCEMETER des Herstellers Keithley, das Keithley2400 über die RS232 Schnittstelle an einem WIN10 PC mit Matlab 2017b angesteuert. Das Sourcemeter hat die Aufgabe eine Diodenkennlinie aufzunehmen. Das Sourcemeter ist imstande einen Strom zu sourcen, also eine steuerbare Stromquelle zu sein und gleichzeitig den gesourcten Strom und die an den Klemmen anliegende Spannung zu messen. Umgekehrt wiederum kann es auch als steuerbare Spannungsquelle eingesetzt werden, die Spannung an den Klemmen und den Strom durch den DUT (Device Under Test) messen.  Und das geht in allen vier Quadranten, also Stromquelle oder -Senke, oder Spannungsquelle oder -Senke sein.

Genau das benötigte ich in diesem supereinfachen Beispiel um die Kennlinie eines PN-Überganges aufzunehmen und zwar vom Diffusionsbereich bis in den Durchlassbereich und natürlich auch wenn der PN-Übergang unter Photonenbeschuss steht 🙂

Die folgenden beiden Matlab-Skripten ermöglichen diese einfache Kennlinienaufnahme. Der Messaufbau selbst besteht lediglich aus einer, an die Klemmen des K2400 angeschlossenen Diode (in diesem Fall eine Photozelle). Dabei stellt das erste Skript eine gesteuerte Stromquelle dar und im zweiten Skript wird die Spannungsquelle durchgesteuert und jeweils die Daten aufgezeichnet und zum Schluss als Plot dargestellt.

 Matlab Code stromgetrieben:

% IV Logger PN Kennlinie
% 2.05.2019 ingmarsretro
% der supereasysimple-code
% drive current and measure voltage
% with sourcemter über RS232 

 serialObject = serial('COM4','BaudRate',19200, 'DataBits',8);   

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Sourcemeter 2400 setup                             %
    % serial config: 8N1, 19200, termchar CR+LF          %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
    fopen(serialObject)
    s.InputBufferSize = 6000;
    fprintf(serialObject,'*RST');
    
    mincurr = -15E-3;  % maximaler negativer strom (load an der Zelle) 
    maxcurr = 10E-4;   % maximaler positiver strom 
    step = 1E-5;       % schrittweite
    

    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % Messgeraet einstellen  %
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % SOURCING ->  CURRENT
    %
    %fprintf(serialObject,':INIT:CONT OFF;:ABOR');
    fprintf(serialObject,':FORM:DATA ASCII');
    fprintf(serialObject,':SOUR:FUNC CURR');
    fprintf(serialObject,':SOUR:CURR:MODE FIX');
    fprintf(serialObject,':SOUR:CURR:RANG 10E-2'); % -> 000.000mA
    fprintf(serialObject,':SOUR:CURR:LEV 0.0'); % -> Starteinstellung 0 A
    
    % MEASUREMENT -> Spannung 
    fprintf(serialObject,':SENS:FUNC "VOLT:DC"');
    fprintf(serialObject,':SENS:VOLT:PROT 8');     % -> compliance 8V
    fprintf(serialObject,':SENS:VOLT:RANG 10E-1'); % -> 0.00000 V
    fprintf(serialObject,':TRIG:COUN 1');
    
    %fprintf(serialObject,':CONF:VOLT:DC');
    
    fprintf(serialObject,':OUTP ON');

        %% Messen und Daten abholen
    count = 1; 
    v(1)=0; i(1)=0;  %init der arrays 
   
       for curr = mincurr:step:maxcurr
           
          strom=num2str(curr);
          command = strcat(':SOUR:CURR:LEV ',{' '},strom);
          fprintf(serialObject,char(command));
         

          fprintf(serialObject,':READ?');
          data=fscanf(serialObject);  % gesamten buffer des device einlesen
          c = strsplit(data,',');          % gelesenen string nach ',' in zellen zerlegen
          i(count) = str2num(cell2mat(c(2)));                 % stromzelle 
          v(count) = str2num(cell2mat(c(1)));                 % spannungszelle
        

        count = count +1;
       end
   
    
    figure(1);
    plot(v,i);
    grid on; hold on;
    xlabel('voltage [V]'); ylabel('current [A]')
    title('IV - Kennlinie ');
    
    %% instrument in local mode schalten
    fprintf(serialObject,':OUTP OFF');
    fprintf(serialObject,'SYSTEM:LOCAL');
    fclose(serialObject);

 

Matlab Code spannungsgetrieben:

% IV Logger PN Kennlinie
% 3.05.2019 ingmarsretro
% der supereasysimple-code
% drive current and measure voltage
% wit sourcemter über RS232 

 serialObject = serial('COM4','BaudRate',19200, 'DataBits',8);   

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    % Sourcemeter 2400 setup                             %
    % serial config: 8N1, 19200, termchar CR+LF          %
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
    fopen(serialObject)
    s.InputBufferSize = 6000;
    fprintf(serialObject,'*RST');
    
    minvolt = -1;      % maximale negative spannung  
    maxvolt = 0.5;       % maximale positive spannung
    
    %mincurr = -20E-3;  % maximaler negativer strom (load an der Zelle) 
    %maxcurr = 10E-4;   % maximaler positiver strom 
    
    step = 1E-2;       % schrittweite
    
    % 
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % Messgeraet einstellen  %
    %%%%%%%%%%%%%%%%%%%%%%%%%%
    % SOURCING ->  VOLTAGE
    %
    %fprintf(serialObject,':INIT:CONT OFF;:ABOR');
    fprintf(serialObject,':FORM:DATA ASCII');
    fprintf(serialObject,':SOUR:FUNC VOLT');
    fprintf(serialObject,':SOUR:VOLT:MODE FIX');
    fprintf(serialObject,':SOUR:VOLT:RANG 10E-0');    % -> 00.0000 V
    fprintf(serialObject,':SOUR:VOLT:LEV 0.0');       % -> Starteinstellung 0 V
    
    % MEASUREMENT -> CURRENT 
    fprintf(serialObject,':SENS:FUNC "CURR:DC"');
    fprintf(serialObject,':SENS:CURR:PROT 40E-3');     % -> compliance 10.0000 mA
    fprintf(serialObject,':SENS:CURR:RANG 10E-2');     % -> 0.00000 mA  (muss kleiner als complience sein)
    fprintf(serialObject,':TRIG:COUN 1');
    
    %fprintf(serialObject,':CONF:VOLT:DC');
    
    fprintf(serialObject,':OUTP ON');


        %% Messen und Daten abholen
    count = 1; 
    v(1)=0; i(1)=0;  %init der arrays 
   
       for volt = minvolt:step:maxvolt
           
          spannung=num2str(volt);
          command = strcat(':SOUR:VOLT:LEV ',{' '},spannung);
          fprintf(serialObject,char(command));
           


          fprintf(serialObject,':READ?');
          data=fscanf(serialObject);  % gesamten buffer des device einlesen
          c = strsplit(data,',');          % gelesenen string nach ',' in zellen zerlegen
          i(count) = str2num(cell2mat(c(2)));                 % stromzelle 
          v(count) = str2num(cell2mat(c(1)));                 % spannungszelle
        
        

        count = count +1;
       end
   
    
    figure(1);
    plot(v,i);
    grid on; hold on;
    xlabel('voltage [V]'); ylabel('current [A]')
    title('IV - Kennlinie ');
    
    %% instrument in local mode schalten
    fprintf(serialObject,':OUTP OFF');
    fprintf(serialObject,'SYSTEM:LOCAL');
    fclose(serialObject);

 

Das Ergebnis der beiden Skripten ist der folgende Kennlinienverlauf:

Homematic CCU – Tuning

Loading

Die CCUs der Homematic kommunizieren mit ihren drahtlos angebundenen Sensoren und Aktoren über das 868MHz ISM Band. Hier sind die Sendeleistung und die Senderate klar definiert. So kommt es durchaus häufiger vor, dass bei vielen Geräten, die unterschiedlich weit von der Zentrale entfernt sind, auch Kommunikationsfehler auftreten. Einige diese Fehler sind dabei auf die Feldstärke an der CCU- Antenne zurückzuführen. Die Wellenlänge in Luft beträgt bei 868MHz in etwa 0,345m. Die Antenne in der CCU und in den Aktoren ist auf Lambda/4 ausgelegt. Das sind ca. 8,6cm, die als Unipol im Gehäuse liegen. Diese Antenne ist einfach und funktionell. Allerdings kann der Antennengewinn und somit die Reichweite der Homematic durch einbauen einer anderen Antenne einfach gesteigert werden.

CCU2 mit externe 868MHz Antenne

Es gibt zu diesem Thema im Netz schon einige Lösungen und Umbauten. Hier beschreibe ich meinen Umbau auf eine externe Antenne. Die Antenne soll extern befestigt werden. Eine SMA-Buchse ermöglicht das Anschließen unterschiedlicher Antennen. In diesem Beispiel habe ich mich für eine 868 MHz Helix Antenne mit Knickgelenk entschieden. Die SMA Buchse ist eine fertig konfektionierte MH113 50Ohm Buchse mit 1,13mm Koaxialleitung und MHF1 Stecker.

SMA Buchse mit Koaxialkabel

Der MHF1 Stecker wird nicht benötigt und kann von der Koaxialleitung „abgeschnitten“ werden. Bei diesem, nun offenen, Kabelende muss der Innenleiter und Schirm zum Anlöten vorbereitet werden.

Offenes Ende des Koaxialkabels

Jetzt ist die CCU2 an der Reihe. Der Deckel ist schnell entfernt und die Platine freigelegt. Unten links im Bild ist das RF-Modul der Homematic mit dem Antennendraht zu erkennen. Zuerst wird die originale Antenne entfernt und ein wenig vom Lötstoplack der Masseplane entfernt. An dieser Stelle wird dann der Schirm des Koaxialkabels festgelötet.

Geöffnete CCU2

Das vorbereitete Stückchen Koaxialkabel mit dem SMA Stecker wird nun am RF-Modul angelötet. Hierbei kommt der Innenleiter an das RF-Pad mit dem vorher die Antenne verbunden war und das Schirmgeflecht an die freigekratzte Masseplane.

RF Modul mit entfernter Antenne
Koaxkabel am RF – Modul festgelötet

Die elektrische Verbindung ist somit hergestellt. Eine kleine Unstimmigkeit gibt es hier allerdings noch, bzw. habe ich mich hier noch nicht schlau gemacht: Die originale Antenne war ein einfacher Draht. Das würde bedeuten, es gibt eine Impedanz Anpassung am Ende des RF-Modul LNAs und des High-Z Drahtes. Die Koaxialleitung mit dem SMA Stecker hat allerding ebenfalls eine charakteristische Impedanz von 50 Ohm. Das würde bedeuten, es gäbe (oder gibt) hier eine Fehlanpassung. Das wiederum würde wieder Reflexionen an der Leitung und somit wiederum Leistungseinbußen hervorrufen. Im Gesamtsystem wird aber trotz vermutlicher Fehlanpassung eine Reichweitensteigerung erreicht. (Die wiederum könnte man aber mit einer korrekten Netzanpassung nochmals steigern… dazu müsste man sich das RF-Modul genauer ansehen) 

Montageloch im CCU2 – Deckel

Jetzt muss nur noch ein geeignetes Loch für den SMA – Stecker in den Gehäusedeckel gebohrt werden. Dann kann man den SMA Stecker festschrauben. Nach dem Zusammenbau der CCU ist nun nur mehr die Antenne aufzuschrauben und der Umbau ist erledigt.

868 MHZ Helixantenne mit 50Ohm SMA Stecker

Einen Funktionstest, bzw. einen Nachweis der Steigerung der Empfangs- Sendeleistung kann man überprüfen, indem man die RSSI-Pegel der angelernten Sensoren und Aktoren vor und nach dem Umbau vergleicht. Hier hilft „devconfig“, ein kleines Tool in der Homematic Software, das mittels SSH freigeschaltet werden kann:

 
echo CP_DEVCONFIG=1 >> /etc/config/tweaks

 

Kleines Bastelprojekt zur Sommerzeit

Loading

Solarmodul
Als Mini – Bastelprojekt zur Sommerzeit bezeichne ich folgende Bastelei. Ein kleines monokristallines Solarmodul mit der Bezeichnung „SM 6“ von einem bekannten, großen Elektronikdistributor der mit „C“ beginnt und mit „d“ endet, spielt in dem Projekt die Hauptrolle. Das Modul hat eine Nennleistung von 6Wp bei einem maximalen Strom von 320mA. Die Nennspannung liegt bei 17,3V. Die Leerlaufspannung beträgt 20,8V. Die Siliziumzellen sind in einer EVA (Ethylen-Vinyl-Acetat) Kunststoffplatte eingebettet und UV- und feuchtigkeitsbeständig. Das ganze Modul ist ca. 25cm x 25 cm groß. Es ist also ideal geeignet, um die Energie zum Betreiben von USB-Geräten bereitzustellen. Hierbei habe ich zum Beispiel an WIFI-IP-Cams gedacht. Auch das Laden von Smartphones oder Tablets sollte damit möglich sein.
Um das nun auch durchführen zu können, muss aus der Nennspannung der Photovoltaikzelle die Betriebsspannung des USB-Standards (5V) erzeugt werden. Das könnte man jetzt ganz einfach mit einem 7805er Regler machen und die Differenz dabei in Wärme umwandeln. Doch das ist die, so ziemlich ineffizienteste Möglichkeit, die Energie des Panels in ein Handy zu bekommen.
Zum einen ist der Innenwiderstand des Panels von der Lichtintensität abhängig, was einen großen Einfluss auf den Wirkungsgrad bei nicht angepassten Lastwiderständen hat. Zum anderen ist ein Längsregler ein Energievernichter, da die Differenz zwischen Eingangsspannung und geregelter Ausgangsspannung bei Stromfluß in Verlustleistung, also Wärme umgewandelt wird. Hier ist man mit einem Schaltwandler (Buck-Converter) besser bedient.
 
In einem einfachen Laboraufbau kann das Verhalten des Panels untersucht werden. Dazu wird die Leerlaufspannung des Panels bei unterschiedlicher Beleuchtungsstärke gemessen. Anschließend wird das Panel mit unterschiedlichen Widerstandswerten belastet und der Strom durch die Last, sowie die Spannung am Panel gemessen. Die Messwerte werden aufgezeichnet und der Ri (Innenwiderstand der Quelle) berechnet. Der nachfolgende Stromlaufplan zeigt den Messaufbau:
Messaufbau – Schaltung
Als Amperemeter dient ein Agilent- und als Voltmeter ein Keithley 2701 Tischmultimeter. Diese Messgeräte können beide über SCPI-Befehle gesteuert werden. Als Schnittstelle ist jeweils ein LAN-Port vorhanden. Das macht es einfach, über einen PC und ein geeignetes Skript, einen automatisierten Messablauf zu realisieren. Und da Matlab eine sehr bequeme Möglichkeit bietet, zu skripten, wird es auch gleich verwendet. Um in einem Labor messen zu können und in etwa dieselben Umgebungsbedingungen zu haben, wird anstelle der Sonne eine Tischlampe mit Halogenglühbirne verwendet. Die Helligkeit der Lampe wird einfach durch die Versorgung mit einem Labornetzgerät von 0-13V eingestellt. Natürlich kann auch das Labornetzgerät per Matlab gesteuert werden.
Messaufbau mit Lampe als „Sonne“

Die Lampe ist in einem Abstand von 25cm mittig über dem Panel platziert. Um ein Gefühl zu bekommen, welche Beleuchtungsstärke mit der Lampe erreicht wird, wird mit einem Luxmeter eine Referenzmessung gemacht. Das heißt, die Lampe fährt die Leistungsrampe von 0-13V durch und das Luxmeter misst die Beleuchtungsstärke im Abstand von 25cm unter der Lampe. Das Ganze wird in 0.5V Schritten aufgelöst. Daraus ergibt sich eine Kurve, die so aussieht:

Spannung an der Lampe ergibt Beleuchtungsstärke

Jetzt kann die Messung beginnen. Als Lastwiderstand werden manuell Widerstände an das Panel geschaltet und Strom und Spannung bei jeder Helligkeitsstufe gemessen. Es sind elf Lastwiderstandswerte die von 4.7 Ohm bis 220 Ohm reichen nacheinander angeschlossen. Eine Leerlaufmessung wird dann natürlich ohne Lastwiderstand gemacht. Folgender Graph zeigt den errechneten Innenwiderstand bei zwei Lasten des Panels über den Helligkeitsverlauf der Lampe in Lux und im weiteren Graph über die Spannung an der Lampe (für die bessere Skalierung). Den Innenwiderstand einer Quelle errechnet man aus der Leerlaufspannung der Quelle abzüglich der Spannung unter Last, dividiert durch den Strom. Mit der Differenz der Leerlauf und Lastspannung erhält man also den Spannungsabfall am Innenwiderstand. Da im Lastfall auch der Strom bekannt ist, braucht man nur mehr das Ohm´sche Gesetz anzuwenden, um den Widerstandswert zu erhalten…

Innenwiderstand vs. Beleuchtungsstärke
Innenwiderstand vs. Spannung an der Lampe

Da jetzt einige Klarheiten über das Verhalten der PV-Zelle beseitigt wurden, kann ich noch kurz über den Aufbau des Spannungswandlers berichten. Wie schon zuvor angekündigt, ist ein Schaltwandler der effizientere Weg, die Energie an den Verbraucher anzupassen. Hier kommt ein LM2596S zum Einsatz. Der LM 2596 ist ein „Simple Switcher Power Converter, der mit 150kHz schaltet und eine Last mit 3A versorgen kann.) Hier eine Übersicht der Funktionen:

  • 3.3-V, 5-V, 12-V, and Adjustable Output Versions
  • Adjustable Version Output Voltage Range: 1.2-V to 37-V ± 4% Maximum
    Over Line and Load Conditions
  • Available in TO-220 and TO-263 Packages
  • 3-A Output Load Current
  • Input Voltage Range Up to 40 V
  • Excellent Line and Load Regulation Specifications
  • 150-kHz Fixed-Frequency Internal Oscillator
  • TTL Shutdown Capability
  • Low Power Standby Mode, IQ, Typically 80μA
  • Uses Readily Available Standard Inductors
  • Thermal Shutdown and Current-Limit Protection

(Quelle: Datenblatt des Herstellers TEXAS Instrument)

Mit diesem Schaltwandler und noch ein paar wenigen anderen Komponenten lässt sich schnell eine Schaltung zusammenzimmern und mit dem Layout Tool „Eagle“ in eine Platine verwandeln. Diese Schaltung ist aber so einfach aufgebaut, dass sie lediglich mit den Vorzügen des LM2596 möglichst effizient arbeitet, aber kein Powertracking durchführt. Das heißt, die Last, die die Schaltung für die Solarzelle darstellt wird nicht an den Innenwiderstand der Solarzelle angepasst.

 

Schaltbild des DC-DC Converters

Aus dieser Schaltung wurde dann ein einfaches Layout erstellt, eine Platine geätzt und diese bestückt. Eine USB-Buchse am Ausgang ermöglicht das direkte Ansschließen von USB-Geräten. Um das Ganze auch ein wenig vernünftig aussehen zu lassen habe ich der Platine noch ein kleines Kunststoffgehäuse gespendet…

Messaufbau
Schaltbare Lastwiderstände
Layout am Computer
Folie zum Erstellen der Printplatte
Geätzte PCB
Bestückte PCB
Fertige Schaltung

Datenknoten mit Arduino

Loading

Leider sind die Abstände, in denen ich ein wenig Zeit finde, einen neuen Beitrag für den Blog zu schreiben, nicht kürzer geworden. Aber einen Beitrag pro Monat zu posten, halte ich ein… 🙂

Dieses Mal ist es kein Retro Bastelprojekt aus den heimischen Gefilden oder eine Restauration eines alten Gerätes, sondern wieder etwas zum Thema Arduino. Die Idee – es soll ein Sensor gebaut werden, der wie immer, eine physikalische Größe in ein elektrisches Signal umwandelt. Das ist jetzt nichts Besonderes und um welche Art von Sensor es sich handeln wird, werde ich vorerst noch nicht beschreiben. Aber es soll nicht ein Sensorboard geben, sondern viele. Und diese Sensorboard kurz „Sensoren“ sollen in einer zweidimensionalen Matrix miteinander vernetzt werden. Man kann sich das in etwa vorstellen wie ein Schachbrett, wobei jedes der Schachbrettfelder einen Sensor darstellt. Dieses Netzwerk an Sensoren – also Sensorknoten – soll dann über eine Übergabestelle mit einem Rechner verbunden sein und die Sensordaten des jeweiligen Feldes ausgeben. Es soll dann auch möglich sein, einzelne Felder aus dem Netzwerk zu entfernen ohne dass das verbleibende Netzwerk seine Funktion verliert.

Das ganze System soll möglichst einfach und günstig aufgebaut werden. Und so ist schnell ein Systemkonzept entstanden, in dem die Knoten über den I²C Bus kommunizieren und ihre Daten zu einem Master senden. Das folgende Diagramm soll das verdeutlichen.

Dieses Konzept, so dachte ich mir, lässt sich am einfachsten mit einem Atmega Microcontroller realisieren. Der hat genügend IO´s, einen I²C Bus und UART onboard, ebenso auch analoge Eingänge und benötigt wenig Bauteilperipherie, um ihn in einem eigenen Layout zum Leben zu erwecken. Und es gibt nichts schnelleres, so einen Testaufbau eines solchen Knotennetzwerks zu realisieren, als die gut bekannten Arduino Development Boards zu benutzen. Ich habe die günstigste Variante für einen Testaufbau gewählt -> den Chinanachbau vom Arduino Uno (Joy-IT UNO) mit dem Atmga328 im gesockelten DIL Gehäuse.

Joy-It Uno Boards

Im Bild sind zehn Stück dieser Microcontrollerboards zu sehen. Von denen soll einer als Bus-Master und neun Stück als Slaves eingesetzt werden. Jeder dieser Slaves hat natürlich eine eindeutige Bus-Adresse, die im System nur einmal vorkommt. Im Testaufbau wird diese Busadresse über den Programmcode fest vergeben, da ohnehin jeder Arduino einmal mit dem Rechner verbunden werden muss, um den Programm-Upload durchzuführen. Das soll natürlich später anders aussehen. Denn der Arduino wird auf den Atmega328 Chip, seinen Quarz und die paar Widerstände reduziert auf dem Sensorboard mit gelayoutet. Programmiert soll der Chip dann über die ISP Pins werden. Da bei vielen Boards natürlich nicht jedes Mal der Programmcode individuell angepasst wird und alle das gleiche Flashfile erhalten sollen, will ich die Sensoradresse mit einem 7Bit Dipschalter einstellen. Ein 4021 Cmos Static Shift Register soll die Bits nach dem Einschalten des Controllers auslesen und seriell in den Controller schieben. Der daraus resultierende Wert steht dann in einer Variablen als Busadresse zu Verfügung.

Jeder dieser Slaves mit seiner individuellen Busadresse wird nun vom Masterknoten der Reihe nach abgefragt, welchen Zustand er hat und ob er einen Ausgang schalten soll, oder nicht. Das bedeutet, der Knoten hat lediglich einen DO (Digitalen Ausgang) mit dem er beispielsweise eine LED aus- und einschalten kann und einen oder mehrere DI (Digitalen Eingang) der einen Zustand, zum Beispiel eines einfachen Schalters abfragt. Diese Funktionen werden in 2 Bits eines Bytes gespeichert. Ein weiteres Byte dient zur Übertragung der Busadresse. Es werden also zwei Bytes über den Bus geschickt. Das untenstehende Bild zeigt den Testaufbau mit den „UNO-Boards“

Alle Arduinos sind mit I²C Datenbus und Spannungsversorgung verbunden

Der Ablauf läuft wie folgt:

MASTER:
Der Masterknoten sendet nach der Reihe an alle Slave-Adressen eine Anfrage und einen Schaltbefehl (der kommt für alle Knoten von einem TEST-Taster Eingang am Master) für den LED-Ausgang des Knotens und sieht ob eine Antwort zurückkommt oder nicht. Wenn keine Antwort kommt, ist der Knoten nicht im Netz oder defekt. Kommt eine Antwort, so besteht diese aus der Adresse des Knotens und seinem Statusbyte. Diese Informationen werden über ein RS232 Terminal an den, am Master angeschlossenen Rechner übertragen. So kann dort beispielsweise über eine Visualisierung mittels (NI LabVIEW, oder Matlab o.ä.) der Schaltzustand jedes einzelnen Knotens am Bildschirm angezeigt werden. Mit einer Anpassung des Master Programmes ist es auch möglich, die LED-Ausgänge der Slaves über den Rechner zu schalten.

SLAVE:
Wenn der Masterknoten vom Slave Daten anfordert, so sendet der Slave zwei Bytes zurück. Wobei Byte0 wieder die Slave ID (also Busadresse ist) und Byte1 die Daten. Byte1 besteht eigentlich aus nur zwei Bit, die wie folgt kodiert sind (in dezimaler Darstellung):
 0 = LED aus | Sensor nicht ausgelöst
 1 = LED ein | Sensor nicht ausgelöst
 2 = LED aus | Sensor ausgelöst
 3 = LED ein | Sensor ausgelöst

Der Programmcode als Beispiel:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// I2C Slave Code
// 16.05.2018 
// ver 1.3
#include <Wire.h>
#define ADDRESS 2     // adresse des slave knotens
#define PAYLOAD_SIZE 2 // anzahl der bytes  die vom masterknoten zu erwarten sind
int LED=12;            // indicator led an pin D12
int SENSOR = 8;        // sensor input an pin D8
bool actionState=0;      // sensor zustand
int busstatus;  // statusvariable 
                       // 0 = LED aus | sensor nicht belegt
                       // 1 = LED ein | sensor nicht belegt
                       // 2 = LED aus | sensor belegt
                       // 3 = LED ein | sensor belegt
 
bool sensled=0;          // sensor LED
byte nodePayload[PAYLOAD_SIZE];

void setup()
{
  pinMode(LED, OUTPUT);         //sensorLED
  pinMode(SENSOR, INPUT);       //Sensor 
  Wire.begin(ADDRESS);          // Activate I2C network
  Wire.onReceive(receiveEvent);
  Wire.onRequest(requestEvent); // auf master anforderung warten
                      //  // debug interface
                      //  Serial.begin(9600); 
}

// *********************************mainloop****************************************************
void loop()
{ 
  delay(5);
  
   if(sensled){digitalWrite(LED, HIGH);}
         else{digitalWrite(LED, LOW);}

  actionState = digitalRead(SENSOR);  //Sensoreingang abfragen        
   if((actionState==1)&&(sensled==1)) {busstatus=3;}
   else if ((actionState==0)&&(sensled==1)) {busstatus=1;}
   else if ((actionState==1)&&(sensled==0)) {busstatus=2;}
   else if ((actionState==0)&&(sensled==0)) {busstatus=0;}

                      //  Serial.println("######################");
                      //  Serial.print("busstatus neu setzen ");
                      //  Serial.println(busstatus);
                      //  Serial.print("sensled LED            ");
                      //  Serial.println(sensled);
                      //  Serial.print("actionState           ");
                      //  Serial.println(actionState);
                      //  Serial.println("######################");
  nodePayload[0] = ADDRESS;                  // Adresse in byte0 zurücksenden.  
  nodePayload[1] = busstatus;                //byte 1 ist die statusinfo der LED
}



// *********************************************************************************************
void requestEvent()
{ Wire.write(nodePayload,PAYLOAD_SIZE);  
  Serial.println("bytes status schreiben");
  Serial.println(nodePayload[0]);
  Serial.println(nodePayload[1]);
  delay(5);
}

// *********************************************************************************************
void receiveEvent(int bytes)  //einen wert vom I2C lesen
      
{
  
  busstatus = Wire.read(); //If the value received was true turn the led on, otherwise turn it off  
                              //  Serial.println("status empfangen");
                              //  Serial.println(busstatus);
  if((busstatus==1)||(busstatus==3)){sensled = 1;}
                                else{sensled = 0;}
                                              
}

 

Die Busadresse ist in diesem Slave-Code noch individuell einzugeben. In der nächsten Version ist dann der vorherbeschriebene „Serializer“ der parallelen Dip-Schaltervariante implementiert. Das folgende Codebeispiel ist von Masterknoten, der die Slaves ausliest und mittel Prüftaster ein LED Muster an die Sensor Slaves sendet:

 

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// I2C masterknoten 
// 16.05.2018 
// ver 1.2
// changes abfrage wenn kein knoten am bus dann 255 ausgeben
#include <Wire.h>

#define busbytes 2          // wievele byte vom I2C knoten zu erwarten sind
#define maxKNOTEN  10       // anzahl der zu scannenden slaves
#define startKNOTEN 2       // startadresse der slaves
#define DELAY 5             // einfach ein delay ....

int i; int j=0;
int buttonPin = 12;
int testbut = 0; int anim = 0;
int buttonState = 0;
int DATEN[busbytes];
int adresse; int busstatus;  
byte sensorbelegt; byte ledsensoron;

                       // 0 = LED aus | Sensor nicht belegt
                       // 1 = LED ein | Sensor nicht belegt
                       // 2 = LED aus | Sensor belegt
                       // 3 = LED ein | Sensor belegt

int leddat1[] = {1,1,1,1,0,1,1,1,1}; // -
int leddat2[] = {0,0,0,0,1,0,0,0,0}; // |

void setup()
{
  Serial.begin(9600);  
  Serial.println("MASTER-KNOTEN");
  Serial.print("Maximum Slaveknoten: ");
  Serial.println(maxKNOTEN);
  Serial.print("Datengroesse in byte: ");
  Serial.println(busbytes);
  Serial.println("***********************");
  
  Wire.begin();                 // Activate I2C link
  pinMode(buttonPin, INPUT);    // test-tastereingang festlegen
}


//#####################################################################################################
void loop()
    
{
  for (int Knotenadresse = startKNOTEN;         //alle knoten scannen
           Knotenadresse <= maxKNOTEN; 
           Knotenadresse++) 

        
    //################################################################################################       
    { 
     // testbut = 0;  
     anim = 0;   
    Wire.requestFrom(Knotenadresse, busbytes);        // daten vom jeweiligen knoten anfordern
                                                 
           DATEN[0]=255; DATEN[1]=255;   // wenn kein knoten dann auf 255 setzen    
          if(Wire.available() == busbytes) {                                    // wenn knoten und daten dann
            for (i = 0; i < busbytes; i++) DATEN[i] = Wire.read();          // daten holen (zuerst busID, dann daten)
           // for (j = 0; j < busbytes; j++) Serial.println(DATEN[j]);        // daten an rs232 ausgeben   
          }            

//            Serial.println(Knotenadresse);
//            Serial.println(DATEN[0]);
//            Serial.println(DATEN[1]);
//            Serial.println(" ");
           
            adresse=DATEN[0]; 
            busstatus=DATEN[1];
           
            if(busstatus == 0)       {sensorbelegt=false;  ledsensoron=false;}
            else if (busstatus == 1) {sensorbelegt=false;  ledsensoron=true;}
            else if (busstatus == 2) {sensorbelegt=true;  ledsensoron=false;}
            else if (busstatus == 3) {sensorbelegt=true;  ledsensoron=true;}
      
         //################################################################################################
         //Testbutton Status lesen und variable testbut entsprechend setzen
       
          buttonState = digitalRead(buttonPin);               //tastereingang einlesen
          if(buttonState == HIGH){                            //wenn taster aktiv dann variable anim setzen
          anim = 1;
          //delay(5); 
          }
            
//            //debug debuginfo tasterstatus auf rs232 ausgeben
//            Serial.println("#######################");
//            Serial.print("Knoten Adresse    :");
//            Serial.println(adresse);
//            Serial.print("Busstatus         :");
//            Serial.println(busstatus);
//            
//            Serial.println("----------------");
//            Serial.print("Fliese belegt    :");
//            Serial.println(sensorbelegt);
//            Serial.print("LED Fliese       :");
//            Serial.println(ledsensoron);
//            Serial.print("#######################");
//            Serial.println(" ");
      
          //################################################################################################
          //Testbutton Status an jeweiligen knoten senden
      
          Wire.beginTransmission(Knotenadresse);           // transmit to device actual in for loop
          //anim schreiben
                    
           if (anim==0) {testbut=leddat1[j]; j++;}
                   else {testbut=leddat2[j]; j++;}
           if (j>8){j=0;}
          
          Wire.write(testbut);                             // senden des tasterstatus
          Wire.endTransmission();                          // ende gelände mit uerbertragung
       
          delay(DELAY);
          

    }
   
}

 

Mit dieser Anordnung ist es jetzt möglich alle Arduinos und deren Eingang auszulesen bzw. die LED über den Bus zu steuern. Im nächsten Schritt wird ein „Sensor“ gebaut, eine Platine gelayoutet und der Arduino Uno auf seinen Microcontroller reduziert. Darüber werde ich in einem der nächsten Posts berichten…

 

 

 

Temperatursensor für IV-11 DCF melody

Loading

Ein Funktionsupdate für die IV-11 DCF melody Uhr ist von gr-projects erhältlich. Es handelt sich dabei um einen Funktemperatursender. Das Besondere daran ist, dass der im ISM-Band 433MHz arbeitende Sender mit einer Photovoltaikzelle (Solarzelle) ausgestattet ist. Je nach Ausführung kann im Sender ein kleiner Akku oder eine CR2032 Knopfzelle verbaut werden. Die Batterie wird so bei Sonneneinstrahlung von der Solarzelle gestützt bzw. in der Akkuversion wird dieser tagsüber geladen und hält den Sender dann über die dunkle Zeit weiter in Betrieb.

Der Zusammenbau ist einfach. Der Bausatz besteht aus einem Sender und einem Empfänger. Die Platinen von Sender und Empfänger sind mit wenigen Bauteilen schnell bestückt. Hier ist aber doch etwas Aufmerksamkeit gefragt und man sollte die Dokumentation sorgfältig lesen, denn aufgrund der geringeren Stückzahl der Bausätze werden die Platinen ohne Bauteilaufdruck und Lötstoplack gefertigt.

Sendermodul

Die Funkmodule selbst sind vollständig vorbestückt (SMD) und müssen nur mehr in die entsprechenden Platinen eingelötet werden. Dem Temperaturfühler (NTC) kann zu Abgleichzwecken optional ein Trimmpotentiometer parallelgeschaltet werden. Der Sender wird, wie auch der Empfänger, in ein kleines PVC-Gehäuse eingebaut. Hier sind außer einem 3mm Bohrloch und ggf. etwas Silikon für die Abdichtung der Solarzelle (für den Betrieb außen am Fenstersims) keine weiteren Werkzeuge von Nöten.

Sender mit Solarzelle

Um den Empfänger mit der Uhr zu verbinden, sind am Mainboard der Uhr ein paar kleine Änderungen durchzuführen. Zum einen wird der Microcontroller getauscht – logisch – denn es gibt ja ein neues Programm, das in der Datumszeile dann auch die Temperatur anzeigt. Ein Widerstand wird entfernt, einer kommt hinzu und ein Jumper kann gegen eine Brücke getauscht werden. Die Verbindung zwischen dem Mainboard der Uhr und dem Funkempfänger wird mit einem Stück Kabel hergestellt. Drei Leitungen sind erforderlich (GND, +5V und das Datensignal vom Empfängercontroller zum Uhrencontroller). Das war´s dann auch schon. Die Uhr kann in Betrieb gehen. Nach einigen Sekunden wird die empfangene Temperatur in der Röhre angezeigt.

Empfängerplatine im Gehäuse

 

Ein Video über den Aufbau der Schaltung gibt es hier:

Langzeitmessungen mit Keithley und Matlab

Loading

Keithley2000 Tischmultimeter

Ein alter Begleiter im Bereich Messgeräte ist das Tischmultimeter von Keithley. In unseren Labors werden vorwiegend die Typen der 2000er Serie eingesetzt. Es gibt sie in unterschiedlichen Ausstattungsvarianten betreffend der Schnittstellen zur Außenwelt. Hier ist GBIP-Bus natürlich ein Standard, ebenso wie RS232. Die neueren Geräte besitzen mittlerweile ein LAN Interface mit dem eine Kommunikation über das Internet Protokoll möglich ist. Über jede dieser Schnittstellen kann über „Standard Commands for Programmable Instruments“ (SCPI) mit dem Gerät kommuniziert werden. In diesem Beispiel werde ich das Keithley 2000 über Matlab ansteuern und zyklisch über einen längeren Zeitraum Messwerte auslesen, diese in Matlab speichern und schlussendlich in einem Plot ausgeben – quasi einen simplen Datalogger konfigurieren. Der Zweck dieses Aufbaus ist es, den Spannungsverlauf (bzw. auch Strom) eines Akkus bzw. Batterie eines Low-Energie Device zu erfassen.

Rückseite des Keithley 2000

GPIB Interface (IEEE488)

RS232 Schnittstelle

In diesem Beispiel werde ich die serielle Datenübertragung per klassischer RS232 Schnittstelle verwenden, da diese für meine Anwendung vollkommen ausreicht. Zudem kann ich mir die Installation der Treiberpakete für das GPIP-USB Interface ersparen. 🙂 Da viele der aktuellen Rechner und Laptops auch keine RS232 Ports mehr haben, muss ein USB-RS232 Adapter (beispielsweise FTDI232 etc.) her.

USB-RS232 Adapter am Keithley2000

Ist die Verbindung zwischen dem Multimeter und dem Rechner hergestellt, kann, wie in diesem Beispiel, über ein Matlabskript kommuniziert werden. Dem Keithley muss nur mehr mitgeteilt werden, dass es über die serielle Schnittstelle „sprechen“ soll. Die folgenden Code-Schnipsel zeigen, wie man einfach über SCPI Daten auslesen kann:


serialObject = instrfind('Type', 'serial', 'Port', 'COM26', 'Tag', '');
%serialPort = 'COM23';
%serialObject = serial(serialPort,'BaudRate',9600, 'DataBits',8);

if isempty(serialObject)
serialObject = serial('COM26','BaudRate',57600, 'DataBits',8);
else
fclose(serialObject);
serialObject = serialObject(1)
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Sourcemeter 2000 setup
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fopen(serialObject)
% fprintf(serialObject,':*RST')

time = now;
voltage = 0;
%%
figureinstanz = figure('NumberTitle','off',...
'Name','Spannungslogg',...
'Color',[0 0 0],'Visible','off');
plotinstanz = plot(voltage,time,'Color','red');

%% Messzeit und evtl Messintervall
stoptime = 10; %60 seconds
timeInterval = 1; % brauch' ma jetzt nicht

% Messgeraet einstellen
fprintf(serialObject,':SOUR:FUNC:MODE CURR'); % current source selection.
fprintf(serialObject,':SOUR:CURR:MODE FIXED'); % changes voltage mode to fixed
fprintf(serialObject,':SOUR:CURR:LEV 0'); % sets current to 0

fprintf(serialObject,':SENS:FUNC &quot;VOLT&quot;');
fprintf(serialObject,':SENS:VOLT:PROT 4');
%fprintf(serialObject,':SENS:CURR:RANG:AUTO ON');
fprintf(serialObject,':SENS:VOLT:RANG 10');
fprintf(serialObject,':FORM:ELEM VOLT');

% %fprintf(serialObject,':TRAC:COUN 1');
% %fprintf(serialObject,':TRAC:FEED:CONT NEV');
%
%
% fprintf(serialObject,':TRAC:CLE');
%
% fprintf(serialObject,':TRAC:POIN 10');
% fprintf(serialObject,'TRAC:FEED:SENS');
% fprintf(serialObject,'TRAC:FEED:CONT NECT');
% fprintf(serialObject,'TRIG:COUN 10');
% fprintf(serialObject,':OUTP ON');
%
% fprintf(serialObject,':INIT');
% fprintf(serialObject,':TRACE:DATA?');

%% Daten abholen
count = 1; voltage(1)=4
tic;
time=toc;
% while time&lt;=stoptime
while voltage&gt;=1.5
% fprintf(serialObject,':INIT');
% fprintf(serialObject,':TRAC:FEED SENS');
% fprintf(serialObject,':TRAC:DATA?');
%
fprintf(serialObject,':READ?');
voltage(count) = fscanf(serialObject,'%f');
time(count) = toc;
set(plotinstanz,'YData',voltage,'XData',time);
set(figureinstanz,'Visible','on');
pause(timeInterval);
count = count +1;
end

figure(1);
plot(time,voltage);
grid on; hold on;
xlabel('Zeit [s]'); ylabel('Batteriespannung [V]')
title('Spannungsverlauf Batterie 3V Lithium (2032 mit Modul) im default mode');

% fprintf(serialObject,':OUTP OFF');
%% Put the instrument in local mode
fprintf(serialObject,'SYSTEM:LOCAL');
fclose(serialObject);

Wie so ein Datalog dann aussieht, ist in der folgenden Grafik dargestellt. Hier ist der Spannungsverlauf einer nahezu entladenen Batterie bis zum Abschalten des Verbrauchers über die Zeit aufgezeichnet worden.

LCR-Meter über Matlab auslesen

Loading

LCR-Meter 4297A Agilent

In diesem Post möchte ich mich einmal etwas anderem widmen. Es geht nicht um Retrotechnik, sondern um eine Kleinigkeit, die mir das Arbeiten im Büro erleichtert. Eines der vielen Messgeräte mit denen ich zu tun habe, ist ein Agilent LCR-Meter. Mit dem LCR-Meter 4297A kann man bekannterweise ja die Induktivität, die Kapazität, etc. von elektrischen Bauteilen und generell von Strukturen, die dem Bereich der Elektronik/Elektrotechnik zugeordnet sind, messen. Grob gesagt, der 4297A misst eigentlich nur Strom / Spannung, die Phasenlage  zwischen den beiden und die Energierichtung. Und das bei einer bestimmten Frequenz. Mathematisch werden dann aus diesen Paramatern alle Größen wie L,C,R,X,Y,Q,PHI,… errechnet und ausgegeben. Die Frequenz hier hierbei vom 1MHz bis 3GHz (in 100kHz Schritten) einstellbar. Idealerweise kann das Messgerät nicht nur in einem Frequenzpunkt messen, sondern auch in vielen. Mit „vielen“ ist hier gemeint, dass das Messgerät Frequenztabellen mit 32 Einträgen erzeugen kann. Von diesen Tabellen existieren acht Stück. So ist es möglich, den Verlauf einer gemessenen Größe in Form einer Kurve darzustellen. Allerdings ist das ziemlich umständlich. Die Inhalte der Tabellen müssen händisch (als „csv“ Dateien) Tabelle für Tabelle exportiert und gespeichert werden. Das bedeutet, jede Tabelle muss einzeln angewählt werden. Danach ist der Dialog „Export List View“ zu selektieren – dann ein Speicherpfad und Dateiname anzugeben. Erst jetzt werden die ersten 32 Datensätze exportiert. Dieser Vorgang ist insgesamt achtmal zu wiederholen. Gespeichert wird auf eine 3,5 Zoll Floppy Disc – das einzige verfügbare Medium. Man könnte den 4297A optional auch in ein LAN hängen und eine Dateifreigabe einrichten. Der händische Export bleibt aber nicht erspart. Auf einem „normalen“ Rechner können die  .csv Files jetzt geöffnet werden. Die müssen dann im postprocessing händisch zusammengefügt werden. Erst jetzt kann aus den Daten ein Diagramm gebastelt werden. Hier bietet sich als Tool Matlab von Matworks an, das in unseren Laboren im Rahmen der Ausbildung häufig eingesetzt wird.

NI GPIB – USB Controller

Um diesen umständlichen Prozess wesentlich zu vereinfachen, habe ich ein kleines Skript erstellt, das über die SCPI – Befehle (Standard Commands for Programmable Instruments) mit dem Messgerät kommuniziert. Das soll heißen: Das Messgerät ist über einen GPIB-USB Controller mit einem PC verbunden. Auf dem PC befindet eine Matworks Matlab Installation samt den benötigten Toolboxen. Das Matlab-Skript soll nun einfach die Tabellen der Reihe nach durchschalten und die Inhalte der einzelnen Parameter auslesen und einem Array speichern. Der Inhalt der Arrays wir dann direkt in einem Plot dargestellt. Diese Methode bedient sich aber nur der Inhalte der Tabellen. Es wäre natürlich auch möglich, über das Skript in einer Schleife jede gewünschte Frequenz direkt einzustellen, die Messwerte auszulesen, die nächste Frequenz anzuwählen usw.  Das würde max. 29990 Punkte über den gesamten Frequenzbereich ergeben. Die acht Tabellen á 32 Punkte erlauben hingegen nur 256 Punkte. Das ist fürs erste aber ausreichend und auch viel schneller.

Transmission Line 50 Ohm mit Abschlusswiderstand

die Leitung ist terminiert

In dem Beispiel ist der Impedanzverlauf (Z-Verlauf) einer 50 Ohm Transmission Line dargestellt. Das Ende der Leitung ist dabei mit einem 50Ohm Widerstand abgeschlossen. Der Frequenzbereich ist 1MHz bis 3 GHz. Anders sieht es aus, wenn die Leitung offen oder kurz geschlossen ist. Die elektromagnetische Welle wird dann nicht, wie bei dem „matched“ (angepassten) System am Ende der Leitung in Wärmeenergie umgewandelt, sondern zurück in das System reflektiert.

die Leitung ist kurzgeschlossen

Das folgende ganz einfache Matlabskript ermöglicht das Auslesen der Messgeräteparameter. Das Skript dient als Beispiel, wie man schnell zu den Messdaten kommt. Im Programmingmanual des Herstellers vom LCR-Meter sind alle SCPI Kommandos und reichlich Beispiele angeführt, mit denen man mit dem Messgerät kommunizieren kann.


%auslesen der agilent LCR Keule 4287A
%gekodet von ingmar bihlo Ende November 2017

%anschluss über gpib ni adapter
%LCR gpip adresse: 5
%%
%vorarbeiten an LCR Keule
%
% Es müssen 8 Tabellen mit je 32 Punkten definiert sein
% (power und average ist egal, wird nicht ausgelesen)
% die CALibration muss gemacht worden sein
% unter "measurement parameters" muessen vier parameter definiert sein
% zb. Z, qhi, R, L, etc... diese sind dann in den variablen param1 bis 4
% enthalten

%%

% gpib interface oeffnen und identifier lesen
g = gpib('ni', 0, 5);
g.InputBufferSize = 100000; % Set the buffer size
fopen(g);
fprintf(g, '*IDN?')
idn = fscanf(g);
fclose(g);

num1all=0; % initialisieren der variablen für den summenvector
num2all=0;
num3all=0;
num4all=0;
freq=0;

fopen(g);
%read list parameters (frequency points)
fprintf(g, ':SOUR:LIST?');
fpoint=fscanf(g);
listchar=strsplit(fpoint,',');
list=[cellfun(@str2num, listchar(:,1:end))]
clear listchat; clear fpoint;

%analyze list content
points=freq(1);

for i=1:8
%Tables selecten
fprintf(g, strcat(':SOUR:LIST:TABL 0',num2str(i)));
pause(1); %pause 1s zum umschalten der tabelle

%parameter1 abholen
fprintf(g, ':DATA:FDAT1?'); %parameter 1 anfragen
par1=fscanf(g); %parameter 1 holen

string1=strsplit(par1,','); %parameter 1 string nach komma zerlegen
%num1=[cellfun(@str2num, string1(:,1:end))] %parameter 1 strings in dec konvertieren
num1=[cellfun(@str2num, string1(:,1:end))];
num1all=[num1all,num1]; %parameter1 aktuell mit parameter1 aus vorherigem durchlauf concentenaten

fprintf(g, ':DATA:FDAT2?');
par2=fscanf(g);
string2=strsplit(par2,',');
num2=[cellfun(@str2num, string2(:,1:end))]
num2all=[num2all,num2];

fprintf(g, ':DATA:FDAT3?');
par3=fscanf(g);
string3=strsplit(par3,',');
num3=[cellfun(@str2num, string3(:,1:end))]
num3all=[num3all,num3];

fprintf(g, ':DATA:FDAT4?');
par4=fscanf(g);
string4=strsplit(par4,',');
num4=[cellfun(@str2num, string4(:,1:end))]
num4all=[num4all,num4];

%read list parameters (frequency points)
fprintf(g, ':SOUR:LIST?');
fpoint=fscanf(g);
listchar=strsplit(fpoint,',');
listraw=[cellfun(@str2num, listchar(:,1:end))];
list=listraw(:,2:end); %von pos2 das feld schreiben (an pos ist die anzahl der zeilen)

for c=1:3:96
freq=[freq,list(c)]; %von jedem 3. wert aus list ein neues array bilden
end

clear listchat; clear fpoint;

pause (1);
end

%%

%ausgabevariablen festlegen
frequency=freq(:,2:end);
param1=num1all(:,2:end);
param2=num2all(:,2:end);
param3=num3all(:,2:end);
param4=num4all(:,2:end);

%%
% Cell array richtig uma drahn
x1=param1(1:32);
y1=param1(33:256);
param1 = [y1 x1];

x2=param2(1:32);
y2=param2(33:256);
param2 = [y2 x2];

x3=param3(1:32);
y3=param3(33:256);
param3 = [y3 x3];

x4=param4(1:32);
y4=param4(33:256);
param4 = [y4 x4];
%%
%uerberflüssige variablen loeschen
clear c; clear i; clear list; %clear freq;
clear par1;clear par2;clear par3;clear par4;
clear string1;clear string2;clear string3;clear string4;
clear num1all;clear num2all;clear num3all;clear num4all;

fclose(g);

%plotten der ergebnisse
figure(1);
plot(frequency,param1);
grid on; hold on;
xlabel('Frequency [Hz]'); ylabel('Measurement Parameter1 |Z| [Ohm]');
title('Agilent LCR Keule');

figure(2);
plot(frequency,param2);
grid on; hold on;
xlabel('Frequency'); ylabel('Measurement Parameter2');
title('Agilent LCR Keule');

figure(3);
plot(frequency,param3);
grid on; hold on;
xlabel('Frequency'); ylabel('Measurement Parameter3');
title('Agilent LCR Keule');

figure(4);
plot(frequency,param4);
grid on; hold on;
xlabel('Frequency'); ylabel('Measurement Parameter4');
title('Agilent LCR Keule');