Archiv der Kategorie: Neues

Datenknoten mit Arduino

Leider sind die Abstände, in denen ich einwenig 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 Gefielden 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 inetwa 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 Developmentboards zu benutzen. Ich habe die günstigste Variante für einen Testaufbau gewählt -> den Chinanachbau vom ArduinoUno (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 muß, 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 nach dem Einschalten des Controllers auslesen und seriell in den Controller schieben. Der daraus resultierende Wert steht dann in einer Variable als Busadresse zu Verfügung.

Jeder dieser Slaves mit seiner individellen 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-Tastereingang 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 MasterProgrammes 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 LEDmuster an die Sensorslaves 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 ArduinoUno auf seinen Microcontroller reduziert. Darüber werde ich in einem der nächsten Posts berichten…

 

 

 

Temperatursensor für IV-11 DCF melody

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 parallel geschaltet werden. Der Sender wird, wie auch der Empfänger, in ein kleines PVC-Gehäuse eingebaut. Hier sind ausser einem 3mm Bohrloch und ggf. etwas Silikon für die Abdichtung der Solarzelle (für den Betrieb aussen am Fenstersims) keine weiteren Werkzeuge von Nöten.

Sender mit Solarzelle

Um den Empfänger mit der Uhr zu verbinden, sind am Mainboared 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 Funkempä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:

Frohe Weihnachten 2017

Frohe Weihnachten an die Besucher des Blogs!

Das dritte Jahr „Technik- und Retroblog“ ist jetzt um und ich habe es geschafft, mindestens einen Beitrag im Monat zu erstellen. Es gibt auch noch reichlich Material aus alten Zeiten, worüber ich hier wieder posten möchte. Die Zugriffsstatistik auf die Blogseite zeigt mir auch, dass sich auch einige Besucher hierher verirren…

Ich bin auch immer wieder auf der Suche nach kleinen, kuriosen Geräten und Spielzeugen aus den 70er, 80er Jahren. Doch Vieles ist nicht mehr zu bekommen und komplett verschwunden. Es wird leider immer schwieriger Dinge aus seiner Jugendzeit zu finden. Aber wir werden sehen, was das neue Jahr bringen wird 🙂

In diesem Sinn:

Fröhliche Weihnachten und schöne Feiertage!

 

LCR-Meter über Matlab auslesen

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 acht mal zu wiederholen. Gespeichert wird auf eine 3,5 Zoll Floppy Disc – das einzige verfügbare Medium. Man könnte den 4297A optiona 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 Progammable Instruments) mit dem Messgerät kommuniziert. Das soll heissen: 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-Script 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 Script 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 Transmissionline 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 „gematchten“ System am Ende der Leitung in Wärmeenergie umgewandelt, sondern zurück in das System reflektiert.

die Leitung ist kurzgeschlossen

Das folgende ganz einfache Matlabscript ermöglicht das Auslesen der Messgeräteparameter. Das Script dient als Beispiel, wie man schnell zu den Messdaten kommt. Im Programmingmanual des Herstellers vom LCR-Meter sind alle SCPI Commandos 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');

NES Classic Mini : Aus mit Wucherpreisen

Das Unternehmen Nintendo hat im Jahr 2016 die Spielekonsole Nintendo Classic Mini aufgelegt und in den Verkauf gebracht. Sie ist ein Revival der 8-Bit Ur-Spielekonsole Nintendo Entertainment System aus dem Jahr 1983 (Veröffentlichung in Japan) bzw. 1986 (Veröffentlichung in Europa). Die Ur-NES Konsole hat sich ca. 61 Millionen mal verkauft und wurde 1992 von der SNES (Super Nintendo Entertainment System) einer 16Bit Konsole abgelöst. Die Beliebtheit der Nintendokonsolen ist scheinbar so groß, dass die Neuauflage mit einem Verkaufspreis von ca. 60 Euro kurz nach der Veröffentlichung ausverkauft war. Hier witterten Geschäftemacher den großen Deal und boten die Geräte über Amazon, ebay und co zu teilweise horrenden Preisen an. Auch jetzt, knapp ein Jahr später sind sie noch nicht unter 100 Euro zu bekommen. Und Nintendo produziert auch keine weitere Einheiten. Stattdessen hat das selbe Spiel mit dem Revival der SNES Serie in einer Miniaturausgabe begonnen. 

Der NESPI in seiner Verpackung

Es gibt aber auch andere Möglichkeiten, um mit viel weniger Geld in den Besitz einer miniaturisierten Version dieser Konsole zu gelangen. Um ein paar Euro bekommt man ein Gehäuse namens NESPI CASE, das der NES CLASSIC MINI entspricht, jedoch mit einem großen Unterschied: Den Rechner kann man in Form eines Raspberry PI selber einbauen. Damit eröffnen sich unzählige Möglichkeiten mit Emulatorsoftware eigene Konsolen softwaremäße nachzubauen.  Das NESPI-Case besitzt einen integrierten 4 Port – USB Hub sowie einen LAN Ethernet Connector, der die Anschlüsse des Raspberry PI nach aussen führt. Hierbei sind zwei USB Ports so angeordnet, dass sie als Controller-Anschlüsse dienen. Die weiteren zwei USB Ports sowie der Ethernetanschluss liegen unter der Geräteklappe, wo einst die Spielemodule eingesteckt wurden. Das Gerät ist mit einem Einschalter mit Power LED  sowie einem Reset-Taster ausgestattet.

NESPI Case ausgepackt
Bedienelemente und Anschlüsse

Das Gehäuse wird mit bereits vormontierten Adapterplatinen geliefert. Auch die Schrauben für die Montage des Raspberry Pi, sowie für die Gehäuseschalen sind im Lieferumfang enthalten. Ein kleiner beiliegender Kreuzschraubendreher, sowie ein Zettel mit einer Montageanleitung machen die Sache noch einfacher.

Raspberry PI im NESPI-Gehäuse

Die Lan und USB- Ports des RaspberryPi werden über die, an den Adapterplatinen befindlichen Kabel samt Steckern nach aussen geführt. Sind die Steckverbindungen hergestellt, so kann die RapsberryPI-Platine im Gehäuse verschraubt werden. Optional kann auch noch ein 5VDC Lüfter mit den Abmessungen 30x30x10mm im Gehäusedeckel per Rastnasen befestigt werden. Für die Stromversorgung des Lüfters steht auf der Platine ein zweipoliger Pinheader zur Verfügung. Ist alles eingebaut und angeschlossen, dann kann das Gehäuseoberteil angeschraubt werden.

Raspberry Pi eingebaut

Nun kann die Software eingerichtet werden. Ich bevorzuge hierbei die Images von retropie bzw. recalbox. Nähere Indormatinen dazu findet man auf den entsprechenden Webseiten. Sind die gewünschten Emulatoren eingerichtet, so muss man nur mehr die Spieledateien, die sogenannten „Roms“, also binäre Kopien der Spielemodule der einstigen Originalhardware in einer .bin oder .rom oder .iso Datei etc. auf die SD-Karte oder einen USB-Stick kopieren und in die „EmulationStation“ einbinden. Und schon kanns losgehen. Auch die USB-Controller im NES – Look sind um ganz wenige Euro aus China zu bekommen…

NESPIE mit NES-Nachbau „ChinaController“

 

Ein alter NES „Klassiker“

 

VFD-Uhr mit Datum, Wochentag und Sound

Einen neuen Bausatz zum Thema Vakuum Floureszenz Display habe ich von Günter (gr-pojects) erhalten. Vielen Dank!

Es ist eine Uhr mit Vakuum-Floureszenz-Anzeigeröhren der Typen IV-11 für die Stunden, Minuten und Sekundenanzeige und einer IV-18 Röhre für die Datumsanzeige, sowie IV-3 zur Darstellung des Wochentages. Die Uhr besteht aus einem Mainboard mit Spannungsversorgung, CPU, MP3-Modul sowie den Treiberbausteinen für die Röhren. Die Uhrzeit wird über einen extern angeschlossenen DCF-77 Empfänger eingestellt und synchronisiert. Später wird das Board noch mit einer Realtimeclock-Schaltung erweitert.  Die Energieversorgung für die gesamte Schaltung kommt von einem kleinen Steckernetzteil mit 12V/1.2A. Die gesamte Stromaufnahme beträgt ca. 450mA. Als besonderes Feature besitzt die Uhr ein kleines MP3-Soundmodul mit MicroSD-Kartenslot. Dieses erhält vom Microcontroller über die serielle Schnittstelle zu jeder viertel-Stunde ein entsprechendes Commando, ein MP3 File abzuspielen. So wird die viertel Stunde mit einem „Gongschlag“, die halbe Stunde mit zwei und die dreiviertel Stunde mit drei „Gongschlägen“ signalisiert. Zur vollen Stunde wird die entsprechende Uhrzeit angesagt.

Die gesamte Schaltung ist in ein Alu-Acryl Gehäuse eingebaut. Alle Formteile sind gefräst und werden  verschraubt. Ein Video vom Aufbau und der Funktion ist unten zu sehen:

ABS Steuergerät und der Wackelkontakt

In den modernen Kraftfahrzeugen ist ja massenweise Elektronik verbaut, die über unterschiedliche Bussysteme miteinander kommuniziert. Zahlreiche Steuergeräte verarbeiten Sensordaten und führen damit Regel- und Steueraufgaben durch und senden diese an Aktoren und Geber. Doch leider ist viel Elektronik, vorallem die hochintegrierte, auch fehleranfällig. Die rauhen Umgebungsbedinungen, die in einem Fahrzeug herrschen, insbesonders im Motorraum, lassen diese Komponenten schneller altern. So treten immer wieder Ausfälle von Komponenten auf. Manchmal sind es nur Kleinigkeiten, wie Kontaktfehler durch zum Beispiel kalte Löstellen. Diese Fehler lassen sich oft auch einfach reparieren, ohne gleich ein neues Teil kaufen zu müssen. Oder zumindest provisorisch reparieren, um das Fahrzeug im betriebsfähigen Zustand zu halten, bis ein Neuteil verfügbar ist.

Dieses Mal habe ich ein Auge auf ein Steuergerät eines BMW geworfen, das für die Bremsdruckunterbrechung im Radblockier-Fall zuständig ist – also ein ABS – Steuergerät. Die ABS-Kontrolleuchten im Tachomodul signalisierten durch ein Dauerleuchten, dass hier ein Defekt vorliegt. Die Radsensoren und Verbindungsleitungen zum Steuergerät kamen als Fehlerursache nicht in Betracht – es konnte dann nur das Steuergerät sein. Vom Hydraulikblock getrennt landet es auf meinem Tisch.

Bosch ABS-Steuergerät 34.52-6750345

Die Elektronik verbirgt sich unter einer verschweissten Kunststoffabdeckung. (im Bild direkt vor dem Stecker zu sehen). Diese lässt sich nur mit gröberer Gewalt öffnen. Ich wählte hier eine kleine Trennscheibe für den Drehmel, mit dem ich die Klebestellen an drei Kanten vorsichtig auftrennen konnte.

Schnitt entlang der Klebeschweissstelle

Im Bild kann man die Schnittstelle erkennen. Die hintere Seite unter dem Stecker ist für die Trennscheibe nicht zugänglich. Das ist aber auch nicht notwendig, da der Deckel so zum Stecker hin hochgebogen werden kann und nicht vollständig entfernt werden muss.

Deckel ist hochgeklappt

Nun kann der Deckel hochgeklappt werden. Darunter kommt die Elektronik zum Vorschein. Hier ist nun höchste Vorsicht geboten. Die Trägerplatine (vermutlich Rogers-Material) ist lediglich mit Silikongel geschützt. Und darunter befinden sich nicht nur einige SMD-Komponenten, sondern auch direkt die DIEs (also die Siliziumhalbleiter – so wie sie vom Waver geschnitten werden, bevor sie in einem Gehäuse vergossen und gesichtert werden) Diese wiederum sind auf die Platine geklebt und mit Bonddrähten zu dieser verbunden. Die Drähte haben teilweise einen Durchmesser von 25µm und man kann sich vorstellen, die sind auch ziemlich empfindlich. Geschützt sind sie lediglich durch das Silikongel, das immer extrem dauerelastisch ist. Diese Konstruktion macht den extremen mechanischen Materialstress, der durch die thermischen Gegebenheiten im Motorraum und Vibrationen besteht, vermutlich am besten mit…

Betrachtet man die Platine genauer, so ist zu erkennen, dass auch die Verbindungsleitungen zur Aussenwelt (Stecker und Elektromagnete) mit unterschiedlich dicken Bonddrähten ausgeführt sind. Und hier ist in den meisten Fällen auch der Fehler zu suchen. Manche Bondstellen brechen.

Die ersten fünf dicken Leitungen von links sehen unter dem Mikroskop wie folgt aus:

Bruchstellen an den Bondstellen

Wenn man ganz genau hinsieht kann man die Bruchstellen erkennen. Mit einer Pinzette lassen sich die defekten Leitungen einfach herunterziehen.

defekte Bonddrähte sind entfernt

Sind die defekten Bonddrähte entfernt, dann muss das Silikongel vorsichtig zur Seite geschoben werden. (Ideal wäre an dieser Stelle, das gesamte Gel zu entfernen – das würde eine professionelle Reparatur unter dem Wirebonder ermöglichen) Da ich die Möglichkeit zur Gelentfernung leider nicht habe, muss hier gelötet werden. Aber auch hier ist doch ein wenig Geschick von Nöten.

Neue Verbindungsleitungen

Es sieht zwar nicht perfekt aus, aber die Lötverbindungen halten und haben Kontakt. Ich habe hier lackierten Kuperdraht mit 100µm Durchmesser genommen, da die Silberbonddrahtbestände in dieser riesigen Dimension nicht vorrätig sind…

Jetzt kann das fehlende Silikongel ersetzt werden. Ein vorsichtiges Verstreichen des umliegenden ist bedingt ebenfalls möglich. Der Deckel kann nun mit Kleber wieder verschlossen und versiegelt werden. Hier bietet sich der KFZ-Scheibenkleber an.

Wenn alles geklappt hat und keine weiteren Bonddrähte (auch auf dem Board selbst) beschädigt sind, dann sollte das Steuergerät wieder arbeiten.  Hier ein kurzes Video zur Reparatur:

 

 

 

Raspberry PI – OS tuning

Der Raspberry PI wird mittlerweile ja in vielen Anwendungen im Dauerbetrieb eingesetzt und hat dort unterschiedlichste Aufgaben zu erfüllen. Manchmal ist er ein Webserver, eine Wettersensorstation, ein NAS, oder eine Steuerung. Was auch immer. Doch meist hat ein Raspberryboard nur eine dieser Aufgaben zu erfüllen. Die Betriebssysteme bieten jedoch wesentlich mehr Funktionen und Features an, die nicht unbedingt für alle Anwendungen benötigt werden, aber trotzdem mitlaufen und Prozesszeit benötigen, oder die SD-Karte mit unnötigen Schreibzyklen belasten. Das lässt sich aber ändern.

Mein Kollege Mario Wehr hat eine Sammlung an Optimierungen zusammengestellt, die ich hier mit seiner Genehmigung veröffentlichen darf.

Xserver/Windomanager disablen
cmd: raspi-config Menp -> Boot Optins -> Desltop/CLI -> Console only with Login

GPU Shared MEM auf 16MB
cmd: raspi-config Menü -> Advanced Config -> Memory Split ->16MB

Interfaces Disable
cmd: raspi-config Menü -> Interfaced -> Alle Interfaces disablen

Entfernen nicht benötigter Kernelmodule
Bringt: Mehr Speicher für Userspace.
Schnellerer Boot.

Kernel module werden unter:
/etc/modprobe.d/{files}
ge-Blacklistet.

IPV6 disable

File: ipv6.conf
alias net-pf-10 off
alias ipv6 off

File: raspi-blacklist.conf
blacklist ipv6

Sound disable

File: raspi-blacklist.conf

blacklist snd_bcm2835
blacklist snd_soc_bcm2708_i2s
blacklist snd_soc_core
blacklist snd_compress
blacklist snd_pcm
blacklist snd_page_alloc
blacklist snd_seq
blacklist snd_seq_device
blacklist snd_timer
blacklist snd

Bluetooth disable

File: raspi-blacklist.conf
blacklist btbcm
blacklist hci_uart

File: /boot/config
dtoverlay=pi3-disable-bt

cmd: systemctl disable hciuart

UIO disable

File: raspi-blacklist.conf
blacklist uio_pdrv_genirq
blacklist uio

Verschieben von /Temp /Log ins Ram
Bringt: Die SD hält um einiges länger Schnellerer Boot

File: /etc/fstab
tmpfs /tmp tmpfs defaults,size=8M 0 0
tmpfs /var/tmp tmpfs defaults,size=8M 0 0
tmpfs /var/log tmpfs defaults,size=8M 0 0

Log anpassen
Bis auf Kernel/Daemon können alle Logs abgeschalten werden.
File: /etc/rsyslog
#cron.* /var/log/cron.log
daemon.* -/var/log/daemon.log
kern.* -/var/log/kern.log
#lpr.* -/var/log/lpr.log
#mail.* -/var/log/mail.log
#user.* -/var/log/user.log
#mail.info -/var/log/mail.info
#mail.warn -/var/log/mail.warn
#mail.err /var/log/mail.err

Log-Rotating
Da der tmpfs Space klein ist -> logrotate auf 1 bzw daliy
File: /etc/logrotate -> /etc/logrotate.d/{files}

Social Media – muss wohl sein …

Jeder spricht heute von Social Media und dank Smartphone und mobilem Internet kann auch jeder daran teilnehmen. In Wikipedia ist unter „Social Media“ folgende Definition zu finden:

Social Media (auch soziale Medien) sind digitale Medien und Technologien, die es Nutzern ermöglichen, sich untereinander auszutauschen und mediale Inhalte einzeln oder in Gemeinschaft zu erstellen. Der Begriff „Social Media“ wird aber auch für die Beschreibung einer neuen Erwartungshaltung an die Kommunikation genutzt und zur Abgrenzung von dem Begriff soziale Medien im Singular verwendet, da es sich um mehr handelt als um einzelne Medienkanäle.

Soziale Interaktionen in sozialen Medien gewinnen zunehmend an Bedeutung und wandeln mediale Monologe(one to many).

Zudem sollen sie die unbehinderte Verbreitung von Wissen und Informationen unterstützen und den Benutzer von einem Konsumenten zu einem Produzenten entwickeln. Demnach besteht weniger oder kein Gefälle zwischen Sender und Rezipienten (Sender-Empfänger-Modell). Als Kommunikationsmittel werden dabei Text, Bild, Audio oder Video verwendet. Das gemeinsame Erstellen, Bearbeiten und Verteilen von Inhalt, unterstützt von interaktiven Anwendungen, betont auch der Begriff Web 2.0.

quelle: wikipedia

Na dann… wird´s ja Zeit, da auch mit zu machen 🙂 Googles youtube und google+ verwende ich ohnehin, um videos zu den Blogbeiträgen zu verlinken. Und mit der Platform Instagram lässt sich ein kurzes Intro zum Blog verlinken. Das sollte dann mit den gewohnten Buttons zu realisieren sein …

Hameg Oszilloskop HM1508

Ein besonderes Dankeschön möchte ich in diesem Beitrag an die Firma Rohde und Schwarz Österreich GmbH für die kostenlose Überlassung eines Hameg Mixed Signal CombiScope HM1508 aussprechen. Vielen Dank für diese Spende.

Das Hameg HM1508 ist ein Vier-Kanal Oszilloskop mit zwei analogen Kanälen und zwei Logic-Eingängen. Die Samplerate beträgt 1GS/s bei einer Speichertiefe von 106 Punkten pro Kanal. Die analoge Bandbreite beträgt 150MHz. Das Gerät ist noch mit einer klassischen Monochrom-Anzeigeröhre ausgestattet und bietet etliche Funktionen der modernen Speicheroszilloskope.

So sind beispielsweise Messungen am Signal im Amplituden- und Zeitbereich per Cursor und auch automatisch möglich.

Die Datenpunkte werden per Interpolation (sinx/x, pulse, bzw. linear) verbunden. Die Dataaquisition kann in den Modi: single, average, envelope, roll und refresh erfolgen. Die vertikale Darstellung ist in den Bereichen von 1mV bis 20V pro Division einstellbar. Weiters bietet das Hameg einige Math-Funktionen sowie die Moglichkeit, die erfassten Daten zu speichern und exportieren.

Eine USB-Schnittstelle, sowie eine RS232 DB9 Buchse dienen als Schnittstelle zur Aussenwelt.

Ebenso im Lieferumfang enthalten: Die Signalprobes (eine pro Channel)

Die Abmessungen betragen: 285 x 125 x 380 mm 
Gewicht: 5,6kg
Leistungsaufnahme: 35W bei 240VAC und 50Hz