Kategorien
Arduino

Arduino – MCP42010 mehrere digitale Potentiometer kaskadiert steuern

Arduino – MCP42010 – Beispiel Ansteuerung mehrerer digitaler Potentiometer

Nach dem Beispiel Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett und der grafischen Variante Node Red – Arduino – digitales Potentiometer MCP42010 steuern habe ich die Ansteuerung von 2 digitalen Potentiometern MCP42010 kaskadiert getestet.

Schaltung

 

Ansteuerung der beiden MCP42010

Die Ansteuerung des primären MCP42010 ist ausführlich in Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett beschrieben.
Schreiben in Potentiometer 1 -> B00010001 und in Potentiometer 2 -> B00010010
Als zweites Byte wird der Wert übertragen, den das ausgewählte Potentiometer annehmen soll.

Um den zweiten MCP42010 zu erreichen müssen 4 Bytes, statt bisher 2 gesendet werden. Beim dritten MCP42010 wären es dann 6, beim vierten 8 und so weiter.
Um ein Potentiometer des 2. MCP42010 direkt anzusteuern ohne die Inhalte des ersten Chips zu verändern, werden zwei weitere Bytes mit dem Wert 0 gesendet.
Siehe auch Bild links aus dem Datenblatt.

Schreiben in Potentiometer 3 -> B00010001 WERT B00000000 B00000000
Schreiben in Potentiometer 4 -> B00010010 WERT B00000000 B00000000

Das ganze ist von rechts nach links zu lesen.
Es werden 4 Bytes geschrieben oder besser hinein geschoben. Die ersten beiden Bytes (von links) werden von den folgenden beiden Bytes in den zweiten MCP42010 geschoben.
Im ersten MCP42010 kommen zwei mal Null an, also keine Änderungen an den Werten im 1. Chip.

Anbei ein Minimal Beispiel, wie in das Potentiometer 1 (Pot0) des zweiten MCP42010 der Wert 127 geladen wird.

Kategorien
Node Red

Arduino – Node Red – MCP42010 – Steuerung des digitalen Potentiometers

Arduino – Node Red – MCP42010 – Beispiel Steuerung des digitalen Potentiometers

Im Beitrag Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett habe ich dargestellt wie der MCP42010 über den seriellen Monitor der Arduino IDE gesteuert werden kann.
Jetzt will ich dieses etwas komfortabler zu tun.
Die Bedienung sollte aus dem Browser heraus erfolgen, optisch sehr ansprechend aussehen und auch mit dem Smartphone möglich sein.

Warum mit Node Red?

Node Red ist in der Standard Installation der Raspberry Pi enthalten, kostenlos und intuitiv bedienbar.
Durch die Möglichkeit den Programm Flow per drag and drop zusammen zu stellen, kommt man sehr schnell zu einem guten Ergebnis.
Für Prototypen und auch IOT Anwendungen eine echt tolle Sache.
Wo Licht ist, ist auch Schatten: Es verbraucht recht viel Ressourcen.
Dennoch kommt die Raspberry Pi 2 spielend damit zurecht und die Pi 3 logischerweise noch viel besser.

benötigte Funktionen des Flows

Der Flow soll die Eingaben, die ich im Experiment Arduino – steuern und Test Digital Potentiometer MCP42010 auf Steckbrett per Hand gemacht habe übernehmen.
Der Flow soll die Rückgabe – Werte in einem Gauge Chart darstellen.

Eingabe:
1:Wert von 0-255 -> setzt Potentiometer1 auf den Wert und gibt die Spannung an A0 zurück
2:Wert von 0-255 -> setzt Potentiometer2 auf den Wert und gibt die Spannung an A1 zurück

Der Flow

  • einfach den folgenden Flow kopieren und unter Menü (rechts oben) -> Import – Clipboard einfügen
[{"id":"ebf0e947.110038","type":"ui_slider","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Slider","topic":"","group":"Pot1","order":1,"min":0,"max":"255","x":225.5,"y":125,"wires":[["25bd2695.9acaf2"]]},{"id":"b755b484.2bd75","type":"ui_text","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Wert","group":"Pot1","order":1,"format":"{{msg.payload}}","x":636.5,"y":102,"wires":[]},{"id":"ed9f01b2.dfae38","type":"ui_gauge","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Spannung in V an A0","group":"Pot1","order":1,"format":"{{value}}","min":0,"max":"5","x":681.5,"y":322,"wires":[]},{"id":"25bd2695.9acaf2","type":"function","z":"8ec3bd3.cce4dc","name":"Value to Command","func":"var msg1 = { payload:\"1:\" + msg.payload +\"\\n\"};\nreturn [msg, msg1];","outputs":"2","noerr":0,"x":440.5,"y":125,"wires":[["b755b484.2bd75"],["134514.6c0042ed"]]},{"id":"134514.6c0042ed","type":"serial out","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"d535ccdc.123838","x":658.5,"y":148,"wires":[]},{"id":"13db30d1.da3c67","type":"serial in","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"43aa993f.185738","x":186.5,"y":345,"wires":[["f39416bc.0495"]]},{"id":"f39416bc.0495","type":"function","z":"8ec3bd3.cce4dc","name":"Response to value","func":"//find A0 or A1\nvar value;\nif (msg.payload.indexOf(\"A0\") != -1) {\n    value = msg.payload.split(\"A0: \");\n    value = value[1].replace(\" Volt\", \"\");\n    msg.payload = value;\n    return [msg, null];\n} else {\n    value = msg.payload.split(\"A1: \");\n    value = value[1].replace(\" Volt\", \"\");\n    msg.payload = value;\n    return [null , msg];\n}","outputs":"2","noerr":0,"x":431.5,"y":345,"wires":[["ed9f01b2.dfae38"],["ddbfff6.2bdb3"]]},{"id":"8a48ef7d.33ba9","type":"ui_slider","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Slider","topic":"","group":"Pot2","order":1,"min":0,"max":"255","x":224,"y":227,"wires":[["127d632d.c0419d"]]},{"id":"5a58be54.e6b8d8","type":"ui_text","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Wert","group":"Pot2","order":1,"format":"{{msg.payload}}","x":635,"y":204,"wires":[]},{"id":"127d632d.c0419d","type":"function","z":"8ec3bd3.cce4dc","name":"Value to Command","func":"var msg1 = { payload:\"2:\" + msg.payload +\"\\n\"};\nreturn [msg, msg1];","outputs":"2","noerr":0,"x":439,"y":227,"wires":[["5a58be54.e6b8d8"],["ee1b0407.9fbca"]]},{"id":"ee1b0407.9fbca","type":"serial out","z":"8ec3bd3.cce4dc","name":"/dev/ttyUSB0","serial":"43aa993f.185738","x":657,"y":250,"wires":[]},{"id":"ddbfff6.2bdb3","type":"ui_gauge","z":"8ec3bd3.cce4dc","tab":"147200e2.b8e19f","name":"Spannung in V an A1","group":"Pot2","order":1,"format":"{{value}}","min":0,"max":"5","x":681,"y":370,"wires":[]},{"id":"147200e2.b8e19f","type":"ui_tab","z":"","name":"Test MCP42010","icon":"dashboard","order":"1"},{"id":"d535ccdc.123838","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false},{"id":"43aa993f.185738","type":"serial-port","z":"","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"\\n","bin":"false","out":"char","addchar":false}]

Video Ansteuerung MCP42010 mit Node Red

Kategorien
Arduino

Arduino MCP42010 – Steuerung und Test des Digital Potentiometers

Arduino MCP42010 – auf einem Steckbrett austesten

Es gibt viele Anleitungen digitale Potentiometer mit einer Arduino anzusteuern.
Meine Suche im Internet nach dem MCP42010 in Verbindung mit Arduino war sehr vielversprechend, führte aber erst nach einigen Versuchen zum Erfolg.
Viele Seiten und Foreneinträge diskutieren das Thema, beschreiben aber keine funktionierende Lösung.

Die Idee ist die beiden digitalen 10 Kiloohm Potentiometer an den Enden zwischen 5 Volt und Masse zu schalten und die Mitte des Potis auf jeweils einen analogen Eingang zu legen.
Je nach dem was jetzt für ein Widerstand (angesteuert) wird, wird die Spannung an den analogen Eingängen steigen oder fallen. Und das lässt sich auswerten.

Ich beschreibe, wie ich vorgegangen bin.

Zum Einsatz kam ein Arduino Nano Nachbau, der schon für etwas über 3,50 Euro zu haben ist und ein digitales Potentiometer MCP42010 (Datenblatt), was ich für ca. 2 Euro bei www.reichelt.de bestellt habe. Ich habe den Aufbau auch mit einer Arduino Uno getestet mit den selben IO Pins. Erfolgreich :-)

Wie in der folgenden Fritzing Grafik und dem Eagle Schaltplan zu erkennen, habe ich folgendermaßen verdrahtet.
Pin Belegung MCP42010MCP42010:
Pin 1 -> D10 Arduino, Pin2 -> D13 Arduino, Pin3 -> D11 Arduino, Pin4 -> Masse, Pin5 -> Masse, Pin6 -> A1 -> Arduino, Pin7 -> +5V, Pin8 -> + 5V, Pin9 -> A0 Arduino, Pin10 -> Masse, Pin11 -> +5V, Pin12 -> 5V, Pin13 – frei, Pin14 -> 5V

Arduino: Außer den Anschlüssen unter MCP42010 nur noch 5 Volt und Masse, um die Arduino mit Strom zu versorgen.

Ansteuerung des MCP42010

Auszug Datenblatt MCP42010Wie im Datenblatt auf Seite 18 zu sehen, muss CS (PIN 10) für die Dauer der Übertragung auf Low gesetzt werden.
Für die Übertragung werden 2 Bytes gesendet.
Als erstes ein Steuerbyte, in dem die Operation (Schreiben) und der Pot (das gewünschte der beiden Potentiometer) angegeben wird.
Schreiben in Potentiometer 1 -> B00010001 und in Potentiometer 2 -> B00010010
Als zweites Byte wird der Wert übertragen, den das ausgewählte Potentiometer annehmen soll.
Anbei ein Minimal Beispiel, wie in das Potentiometer 1 (Pot0) der Wert 127, also ca. Mittelstellung geladen wird.

//minimal Example to set the Pot0 of a MCP42010 to the value 127 
#include 
void setup() {
  // take the CS pin low to select the chip:
  digitalWrite(10,LOW);
  //  send in the address and value via SPI:
  SPI.transfer(B00010001);
  // write out the value 127
  SPI.transfer(127);
  // take the CS pin high to de-select the chip:
  digitalWrite(10,HIGH);
}
 
void loop() {
 
}

Das Programm zur ‚komfortablen‘ Ansteuerung der 2 Potentiometer des MCP42010

Die Bedienung ist sehr einfach gehalten, wie auch schon im Video oben zu sehen war. Ich übergebe Werte an das digitale Potentiometer und werte die resultierende Spannung an den analogen Eingängen A0 und A1 aus.
Für die Dateneingabe und -Ausgabe nutze ich den Seriellen Monitor der Arduino IDE.

Eingabe:
1:Wert von 0-255 -> setzt Potentiometer1 auf den Wert und gibt die Spannung an A0 zurück
2:Wert von 0-255 -> setzt Potentiometer2 auf den Wert und gibt die Spannung an A1 zurück
s -> gibt Werte beide Potentiometer und die Spannungen an A0 und A1 zurück

// inslude the SPI library:
#include 
 
// set pin 10 as the slave select for the digital pot:
const int slave_Select_Pin  = 10;
const int analogInPin0      = A0; 
const int analogInPin1      = A1; 
String    inputString       = "";         // a string to hold incoming data
boolean   stringComplete    = false;      // whether the string is complete
int       level1            = 0;
int       level2            = 0;
 
void setup() {
     inputString.reserve(100);
     // set the slaveSelectPin as an output:
     pinMode (slave_Select_Pin, OUTPUT);
     Serial.begin(9600);
 
     // initialize SPI:
     SPI.begin();
     MSP42010PotWrite(slave_Select_Pin, B00010001, level1);
     MSP42010PotWrite(slave_Select_Pin, B00010010, level2);
}
 
void loop() {
  if (stringComplete) {
    //check ob R1:
    if (inputString.substring(0, 2) == "1:") {
      level1 = inputString.substring(2).toInt();
      MSP42010PotWrite(slave_Select_Pin, B00010001, level1);     
      printValues(level1, analogInPin0);
    }
    //check ob R2:
    if (inputString.substring(0, 2) == "2:") {
      level2 = inputString.substring(2).toInt();
      MSP42010PotWrite(slave_Select_Pin, B00010010, level2); //Datasheet Page 18
      printValues(level2, analogInPin1);
    }
    //check ob s
    if (inputString.substring(0, 1) == "s") {
      printValues(level1, analogInPin0);
      printValues(level2, analogInPin1);
    }
    // clear the string:
    inputString = "";
    stringComplete = false;
  }
}
 
void MSP42010PotWrite(int slaveSelectPin, byte address, int value) {
     // take the SS pin low to select the chip:
     digitalWrite(slaveSelectPin,LOW);
     //  send in the address and value via SPI:
     SPI.transfer(address);
     SPI.transfer(value);
     // take the SS pin high to de-select the chip:
     digitalWrite(slaveSelectPin,HIGH);
}
void printValues(int level, int aPin) {
      delay(5);
      int pot = 0;
      if (aPin == 15) {
        pot = 1;
      }
      Serial.print("level Pot");
      Serial.print(pot);
      Serial.print(": ");
      Serial.print(level);
      Serial.print(" Spannung an A");
      Serial.print(pot);
      Serial.print(": ");
      double sl = analogRead(aPin);
      sl = sl * 5 / 1024; 
      Serial.print(sl);
      Serial.println(" Volt");  
}
/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  while (Serial.available()) {
    // get the new byte:
    char inChar = (char)Serial.read();
    // add it to the inputString:
    // if the incoming character is a newline, set a flag
    // so the main loop can do something about it:
    if (inChar == '\n') {
      stringComplete = true;
    } else {
      inputString += inChar;
    }
  }
}
Kategorien
Programmierung

Geany dark Editor in Ubuntu dunkel machen

Geany dark Editor dunkel machen

Allgemeines

Meine Anwendungen laufen unter Ubuntu (Stand 1/2017 Version 14.10) mit dem Fenstermanager Unity und dem Ubuntu Standard GTK+ Thema Ambiance.

Es ist möglich in Unity unterschiedliche Styles auszuwählen, aber über alle Anwendungen hinweg sind die dunklen Themen nicht so ansprechend.
Speziell bei den Internet Browsern finde ich dunkle Themen nicht passend.

Es ist aber möglich einzelne Anwendungen mit ausgewählten ‚Farb‘ – Themen zu starten.
Um geany wie unten im Bild dargestellt aussehen zu lassen, bin ich folgendermaßen vorgegangen.

Schrit für Schritt

  • geany installieren, falls noch nicht vorhanden -> sudo apt-get install geany

editor intern

  • sollten in geany noch keine Color Themes vorhanden sein, diese hier downloaden: https://github.com/geany/geany-themes/
  • den Ordner colorschemes in den Ordner ~/.config/geany/ kopieren
  • jetzt können in geany unter Ansicht -> Editor -> Farbschemata – Color Themes ausgewählt werden
    Ich verwende ‚Himbeere‘.geany dark -farbauswahl

Außenbereich

Wie in http://www.henrykoch.de/de/eclipse-programmierumgebung-dunkel-machen beschrieben, baue ich auf einem existierenden dunklen GTK+ Thema auf und habe dieses für mich modifiziert.
Folgende Infos habe ich als Datei .gtkrc_dark unter ~/.config/geany/GTK/ gespeichert:

gtk-color-scheme = "base_color:#252525\nfg_color:#f0f0f0\ntooltip_fg_color:#252525\nselected_bg_color:#FFD587\nselected_fg_color:#252525\ntext_color:#dadada\nbg_color:#4d4d4d\ntooltip_bg_color:#FFA500\nlink_color:#494949"
style "gtkcompact" {
	font_name="Sans 11"
	GtkButton::default_border={0,0,0,0}
	GtkButton::default_outside_border={0,0,0,0}
	GtkButtonBox::child_min_width=0
	GtkButtonBox::child_min_heigth=0
	GtkButtonBox::child_internal_pad_x=0
	GtkButtonBox::child_internal_pad_y=0
	GtkMenu::vertical-padding=1
	GtkMenuBar::internal_padding=0
	GtkMenuItem::horizontal_padding=4
	GtkToolbar::internal-padding=0
	GtkToolbar::space-size=0
	GtkOptionMenu::indicator_size=0
	GtkOptionMenu::indicator_spacing=0
	GtkPaned::handle_size=4
	GtkRange::trough_border=0
	GtkRange::stepper_spacing=0
	GtkScale::value_spacing=0
	GtkScrolledWindow::scrollbar_spacing=0
	GtkExpander::expander_size=10
	GtkExpander::expander_spacing=0
	GtkTreeView::vertical-separator=0
	GtkTreeView::horizontal-separator=0
	GtkTreeView::expander-size=8
	GtkTreeView::fixed-height-mode=TRUE
	GtkWidget::focus_padding=0
 
	####################
	# Color Definitions
	####################
 
	bg[NORMAL]= @bg_color
	bg[PRELIGHT]  = shade (1.02, @bg_color)
	bg[SELECTED]  = @selected_bg_color
	bg[INSENSITIVE]   = shade (0.95, @bg_color)
	bg[ACTIVE]= shade (0.9, @bg_color)
	fg[NORMAL]= @fg_color
	fg[PRELIGHT]  = @fg_color
	fg[SELECTED]  = @selected_fg_color
	fg[INSENSITIVE]   = darker (@bg_color)
	fg[ACTIVE]= @fg_color
	text[NORMAL]  = @text_color
	text[PRELIGHT]= @text_color
	text[SELECTED]= @selected_fg_color
	text[INSENSITIVE] = shade (0.8, @bg_color)
	text[ACTIVE]  = darker (@text_color)
	base[NORMAL]  = @base_color
	base[PRELIGHT]= shade (0.98, @bg_color)
	base[SELECTED]= @selected_bg_color
	base[INSENSITIVE] = shade (0.97, @bg_color)
	base[ACTIVE]  = shade (0.94, @bg_color)
 
}
 
class "GtkWidget" style "gtkcompact"
style "gtkcompactextra" {
	xthickness=0
	ythickness=0
}
 
class "GtkButton" style "gtkcompactextra"
class "GtkToolbar" style "gtkcompactextra"
class "GtkPaned" style "gtkcompactextra"

Zum starten benötige ich noch ein Bash Script:

#!/bin/sh
export GTK2_RC_FILES="/home/.../.gtkrc_dark"
geany $1
env --unset=GTK2_RC_FILES

Zusätzlich habe ich mir noch ein kleines dunkles geany Logo gebaut und auch unter /home/…/ gespeichert. (die 3 files als zip file geanydarkfiles.zip)

Die letzte Aktion muss mit Root Rechten ausgeführt werden: sudo gedit /usr/share/applications/geany.desktop

folgende beiden Einträge anpassen:

Exec=/home/.../geany.sh %F
Icon=/home/.../geany.xpm

Jetzt lässt sich Geany immer in dunkel aufrufen, ohne es aus einer Konsole starten zu müssen damit es finster wird. geany dark _aufruf

geany dark Editor dunkel - dark

Drehzahl Steuern mit Arduino PWM – Papbst ebm G1G133-DE19-15* Lüfter

Drehzahl Steuern mit Arduino

Zum Glück hatte ich noch etwas ‚Leistungselektronik‘ von meinen Experimenten mit einer Lichtmaschine im Werkzeugkasten.
Mit dem enthaltenen MOSFET Transistor ist es definitiv kein Problem 24V / 2A zu schalten.
Pulsweitenmodulation mit Arduino ist ’normalerweise‘ mit einem Befehl umgesetzt.

Video vom Testlauf

Code Arduino Sketch

Ein Befehl und Arduino gibt ein PWM Signal aus.
Um den Lüfter in seinem Lauf zu bremsen eignete sich die Standard PWM Frequenz von 62500 HZ nicht.
Das führte bei mir dazu, dass der Motor je nach Pulsweite entweder An oder Aus war.
Ich denke mal das liegt am Lüfter-Motor selbst, der ja in sich mit einer Menge an Steuer Elektronik ausgestattet ist.
Mit dem Befehl TCCR1B = TCCR1B & 0b11111000 | 0x03; setze ich die PWM Frequenz auf knapp 500 HZ herunter. Siehe: http://forum.arduino.cc/index.php?topic=16612#msg121031

int Luefter = 10;          // the PWM pin the Luefter is attached to
int sensorValue = 250;
int oldsensorValue = 0;
volatile unsigned long count;
 
 
// the setup routine runs once when you press reset:
void setup() {
    //PWM Frequenz runter regeln
    //http://forum.arduino.cc/index.php?topic=16612#msg121031
    TCCR1B = TCCR1B & 0b11111000 | 0x03; //PWM Frequenz Pin10 - 488.28125 Hz Standard 31250 / 64
 
    Serial.begin(9600);
 
    // declare pin 'Luefter' to be an output:
    pinMode(Luefter, OUTPUT);
 
    setPwmFrequency(Luefter,32);
    analogWrite(Luefter, sensorValue);
}
// the loop routine runs over and over again forever:
void loop() {
 
 
  sensorValue = analogRead(A0)/4;
  if ( sensorValue > oldsensorValue + 1 || sensorValue < oldsensorValue - 1 ) {
    //print out the value you read:
    Serial.print("PWM------");
    Serial.println(sensorValue);
    analogWrite(Luefter, sensorValue);
 
    oldsensorValue = sensorValue;
  }
  count=0;
  delay(2000);
  Serial.print("gemessen-u/min--");
  Serial.println(count*15);
  delay(1);
}

Unruhiger Lauf

Wie im Video zu erkennen, läuft der Motor bei geringen Drehzahlen (bis 300 U/min) und bei höheren Drehzahlen (ab 1500) ganz normal.
Im Bereich dazwischen läuft der Motor nicht sauber.  Auf der folgenden Seite teste ich die Spannung mit einem Elko zu stabilisieren.
Die viele Technik im Motor selbst macht dieser relativ simplen Lösung der Ansteuerung mit einem PWM Signal einen Strich durch die Rechnung.

Kategorien
Raspberry Pi

USB over IP, Netz, WLAN verlängern – über Raspberry Pi Arduino zu nutzen

USB over IP – erster Anlaufpunkt:

Aktionen auf der Server Seite – Raspberry Pi

USB über IP soll auf der Raspberry Pi ab Kernel Linux-3.17 ohne weitere Installation verfügbar sein.

Check, welchen Kernel ich habe:

17:45:46|pi@raspberrypi:~|$ uname -r
4.1.13+

Kernelversion ist höher :-)
Test:

17:49:05|pi@raspberrypi:~|$ usbip
-bash: usbip: Kommando nicht gefunden.

Satz mit x :-(

Weiter mit den Tipps aus dem Forum https://www.raspberrypi.org/forums/viewtopic.php?p=121691

usbip installieren

17:49:25|pi@raspberrypi:~|$ sudo apt-get install usbip

Kernelmodul laden

17:54:16|pi@raspberrypi:~|$ sudo modprobe usbip-host

usbip daemon starten

08:52:50|pi@raspberrypi:~|$ sudo usbipd -D

USB Geräte auflisten (ohne Arduino)

18:01:48|pi@raspberrypi:~|$ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.

USB Geräte auflisten (mit Arduino)

18:02:30|pi@raspberrypi:~|$ lsusb
Bus 001 Device 002: ID 0424:9512 Standard Microsystems Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. 
Bus 001 Device 005: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

In meinem Fall ist die ID des USB Gerätes 1a86:7523
Das selbe nochmal mit dem Programm usbip

18:05:21|pi@raspberrypi:~|$ sudo usbip list -l
Local USB devices
=================
 - busid 1-1 (0424:9512)
         1-1:1.0 -> hub
 
 - busid 1-1.1 (0424:ec00)
         1-1.1:1.0 -> smsc95xx
 
 - busid 1-1.2 (1a86:7523)
         1-1.2:1.0 -> ch341

Binden des USB Gerätes

09:22:48|pi@raspberrypi:~/deb_pakete|$ sudo usbip bind -b 1-1.2
bind device on busid 1-1.2: complete

Aktionen auf der Client Seite – in meinem Falle Laptop mit Ubuntu

download und install der passenden usbip Version

10:04:25|henry@t410:~/deb_pakete|$ wget http://ftp.de.debian.org/debian/pool/main/l/linux-tools/usbip_1.1.1+3.2.17-1_amd64.deb
--2016-02-13 10:05:51--  http://ftp.de.debian.org/debian/pool/main/l/linux-tools/usbip_1.1.1+3.2.17-1_amd64.deb
Auflösen des Hostnamen »ftp.de.debian.org (ftp.de.debian.org)«... 141.76.2.4
Verbindungsaufbau zu ftp.de.debian.org (ftp.de.debian.org)|141.76.2.4|:80... verbunden.
HTTP-Anforderung gesendet, warte auf Antwort... 200 OK
Länge: 52602 (51K) [application/x-debian-package]
In »»usbip_1.1.1+3.2.17-1_amd64.deb«« speichern.
 
100%[=====================================>] 52.602      --.-K/s   in 0,08s   
 
2016-02-13 10:05:51 (628 KB/s) - »»usbip_1.1.1+3.2.17-1_amd64.deb«« gespeichert [52602/52602]
 
10:05:51|henry@t410:~/deb_pakete|$ sudo dpkg -i usbip_1.1.1+3.2.17-1_amd64.deb Vormals nicht ausgewähltes Paket usbip wird gewählt.
(Lese Datenbank ... 588070 Dateien und Verzeichnisse sind derzeit installiert.)
Vorbereitung zum Entpacken von usbip_1.1.1+3.2.17-1_amd64.deb ...
Entpacken von usbip (1.1.1+3.2.17-1) ...
usbip (1.1.1+3.2.17-1) wird eingerichtet ...
Trigger für man-db (2.6.7.1-1ubuntu1) werden verarbeitet ...

Kernelmodul laden

10:06:22|henry@t410:~/deb_pakete|$ sudo modprobe vhci-hcd
10:08:30|henry@t410:~/deb_pakete|$ lsmod | grep vhci
vhci_hcd               33435  0 
usbip_core             27617  1 vhci_hcd

Auflisten der USB Devices, welche auf der PI zur Verfügung gestellt wurden

10:11:10|henry@t410:~/deb_pakete|$ sudo usbip list -r 192.xxx.xxx.xxx
Exportable USB devices
======================
 - 192.xxx.xxx.xxx
      1-1.2: QinHeng Electronics : HL-340 USB-Serial adapter (1a86:7523)
           : /sys/devices/platform/bcm2708_usb/usb1/1-1/1-1.2
           : Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
           :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/01/02)

Hinzufügen des USB Devices

10:24:20|henry@t410:~/deb_pakete|$ sudo usbip attach -h 192.xxx.xxx.xxx -b 1-1.2
10:24:45|henry@t410:~/deb_pakete|$ lsusb
Bus 003 Device 002: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter

Check mit Arduino Programmieroberfläche

Arduiono Remote programmiert über IP

Aktionen auf der Server Seite – Raspberry Pi

Nach Benutzung auf der Server Seite – Das USB Gerät wieder freigeben

09:22:54|pi@raspberrypi:~/deb_pakete|$ sudo usbip unbind -b 1-1.2
unbind device on busid 1-1.2: complete

Papst ebm G1G133-DE19-15* Lüfter Drehzahl Messen / Steuern mit Arduino und Raspberry Pi

Auf Ebay werden ab 13 Euro gebrauchte Lüfter mit Gleichstrommotoren angeboten, welche mit bis zu Luftstrom: 225 m³/h bei maximal 45 Watt sehr gute Leistungswerte aufweisen.
Für mich war wichtig, dass ich die Drehzahl des Lüfters geregelt bekomme, da ich nicht immer volle Leistung benötige.

In den Bewertungen des Produkts unten in der Auktion, wurde angekündigt, dass sich die Drehzahl des Motors über PWM steuern lässt.
Auch dieses Datenblatt eines fast baugleichen Lüfters lässt auf Seite 4 die Vermutung zu, dass sich die Drehzahl über ein PWM Signal steuern lässt. Das hat in meinem Falle nicht funktioniert.

Nach vielen Versuchen ein PWM Signal anzulegen und einen Drehzahlimpuls abzuholen, habe ich mich dazu entschlossen den Lüfter auseinander zu nehmen.

Im Inneren ist kein normaler Gleichstrommotor, dass ist mehr ein Mikrocontroller – gesteuertes High-Tech Produkt. Ich bin mir sicher, dass die Beschaltung eine Drehzahlsteuerung zulassen würde und wenn dafür der Code des Mikrocontrollers etwas angepasst werden müsste.

Weiter gehts auf den folgenden Seiten:

Dashboard – IOT – Sensordaten – von meiner Raspberry Pi

Dashboard IOT Realtime Sensordaten, gesendet von Raspberry Pi’s

Der letzte update erfolgte: loading …

Kategorien
Python

Raspberry Pi – Python – (HC-SR04) Ultraschall Abstandsmessung – fehlerhafte Ergebnisse durch Statistik in den Griff bekommen – Teil1

Ausgangszustand:

Nach folgender Anleitung Entfernung messen mit Ultraschallsensor HC-SR04 habe ich relativ schnell einen HC-SR04 Ultraschall Entfernungs Sensor zum laufen gebracht und in meinem Brunnen installiert.
Der Brunnen ist nur ca. 4,5 Meter tief und wird zusätzlich über eine Drainage (Entwässerung Einfahrt, Hof) gespeist, was bedeutet, dass der Wasserspiegel bei Regen kurzfristig ansteigt.

Die Pumpe ist im Brunnen angebracht und sollte möglichst trocken bleiben.
Eine Anzeige wie hoch das Wasser steht ist dementsprechend sinnvoll.
Der Abstand zum Wasserspiegel beträgt je nach Wetterlage bis zu 3,5 Meter.
Es zeigte sich relativ schnell, dass die Messergebnisse stark schwanken.
Da der Sensor ca. 10 Meter von der Raspberry Pi angebracht ist, habe ich einen Digital Level Converter zwischen geschaltet, um diesen sauber mit 5 Volt ansteuern zu können.
An der Schwankung der Messergebnisse änderte das nichts.

Mir ist aufgefallen, dass die Messwerte genauer sind, sobald der Brunnendeckel offen ist, wodurch

  • die Luftfeuchtigkeit sinkt
  • die Reflexion des Schalls sich verändern könnte

Suche im Internet

Ein Blick auf die Messergebnisse

Einzelwert1 = 117.4 cm
Einzelwert2 = 186.5 cm
Einzelwert3 = 118.0 cm
Einzelwert4 = 120.9 cm
Einzelwert5 = 121.3 cm
Einzelwert6 = 189.0 cm
Einzelwert7 = 118.1 cm
Einzelwert8 = 122.9 cm
Einzelwert9 = 188.1 cm

Die Grün dargestellten Werte zeigen den tatsächlichen Abstand, welchen ich auch mit dem Zollstock gemessen habe.
Zwei Drittel der Messwerte sind unbrauchbar.
Der Durchschitt über diese Werte liegt bei 142,47 cm, was immer noch über 40 cm am Ziel vorbei ist. Selten kommt es auch vor, dass es extreme Sprünge in Richtung 2 oder 2,5 Meter gibt.
Ich habe mich entschieden, jeweils 11 Werte hintereinander zu messen, diese nach Größe zu ordnen und den zweitgrößten Wert in eine Datenbank zu übernehmen.
Dies erfolgt alle 10 Minuten.
Jede volle Stunde hat eine extra Zeile in der Tabelle mit dem kleinsten gemessenen Wert und den größten gemessenen Wert innerhalb einer Stunde.

import time
import numpy as np
 
def LeseWasserstandBrunnen():
    #Liefert den zweitgroessten Wert einer Messreihe aus 11 Werten zurück
    abstand = []
    for i in range(0, 11):
        abstand.append(distanz()) #Die Funktion distanz() 
                                  #liefert einen Messwert vom HC-SR04 
        time.sleep(0.1)
 
    abstand = np.sort(abstand)
 
    return "%.2f" % float(abstand[len(abstand) -2])

Die folgenden Grafiken zeigen Oben die Übernahme der Messwerte ohne Gewichtung und Unten Messwerte, bei denen ich den zweitgrößten Werte einer Serie angenommen habe.
Blau = minimal; Grün = maximal;

Dartellung_Messwerte_1
Dartellung_Messwerte_2

Beim betrachten des unteren Diagramms fällt auf, dass die Minimalwerte pro Stunde fast durchgehend genau sind.
Da ich die weiß, dass die Ausreiser nach oben und unten Messfehler sind, kann ich das Ergebnis der Tagesdarstellung auch recht gut bewerten.

Jetzt will ich diese Stundenwerte zu einem einzigen Tageswert konsolidieren, um so einen Zeitabschnitt von einem Monat darstellen zu können.
Da sollten dann auch Schwankungen des Wasserstands gut erkennbar sein.
Die ‚Blauen‘, also die Minimalen Stundenwerte erscheinen geeignet, aber ein Durchschnitt der Werte dann doch eher nicht.

Nach ein wenig suchen habe ich bei Youtube folgendes Video gefunden:

Der Zentralwert scheint für meine Ausreiser in den Minimalwerten der richtige Ansatz zu sein.

Kategorien
Python

Python – Löschen der ältesten Files in einem Verzeichnis, nur die neuesten (x) bleiben zurück

Durch das experimentieren mit der Pi Kamera und einem PIR Bewegungsmelder an der Raspberry Pi wurden schnell viele Bilder auf die SD Karte geschrieben.

Um etwas Kontrolle rein zu bringen, ist das folgende Python Script eine gute Basis.
Es gibt die Möglichkeit ein Verzeichnis und die maximale Anzahl Dateien darin anzugeben.
Übersteigt die Anzahl Dateien den definierten Wert, werden ältere Dateien gelöscht.

In meinem Fall halte ich immer maximal 1000 Bilder im Ordner.

Beispielcode:

#!/usr/bin/python
 
import os
 
path = "/home/pi/pictures/"
max_Files = 1000
 
def sorted_ls(path):
    mtime = lambda f: os.stat(os.path.join(path, f)).st_mtime
    return list(sorted(os.listdir(path), key=mtime))
 
del_list = sorted_ls(path)[0:(len(sorted_ls(path))-max_Files)]
 
for dfile in del_list:
    os.remove(path + dfile)