Category Archives: hardware

GPS / PPS basierter NTP-Server auf Raspberry Pi

Im Netz gibt es mittlerweile viele Anleitung zu NTP über GPS (siehe https://www.eecis.udel.edu/~mills/ntp/html/drivers/driver20.html oder http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html). Aber entweder werden spezielle Receiver verwendet, oder PPS funktioniert nicht. Daher hier die Anleitung für Dummies:

Vorbereitung Empfänger:

Als Empfänger kommt der billigste u-blox7 Empfänger zum Einsatz (z.B. hier: https://www.amazon.de/dp/B015E2XSSO/), der über USB als serielles Gerät die NMEA Daten liefert. Doch wir wollen auch das PPS-Signal! -> Lötkolben

Die LED wird mit dem PPS-Signal des Empfängers betrieben und hat einen Pegel von etwa 2,8V und kann damit direkt an den Raspberry angeschlossen werden (GPIO-18 in unserem Fall).

Raspberry Pi

Kerneleinstellungen:

Laden der folgenden Module (eintragen in /etc/modules):

i2c-dev
pps-gpio

Aktivieren des PPS-GPIO Moduls auf Pin 18 (Eintragen als letzte Zeile in /boot/config.txt):

dtoverlay=pps-gpio,gpiopin=18

Das pps-gpio Modul stellt sicher, dass das PPS Signal ausgewertet werden kann. Zusätzlich wird noch das Paket pps-tools benötigt, das mittels

apt-get install pps-tools

installiert werden kann. Die Änderung wird nach einem Reboot aktiv. Und kann mittels:

pi@raspberrypi:~ $ sudo ppstest /dev/pps0
trying PPS source "/dev/pps0"
found PPS source "/dev/pps0"
ok, found 1 source(s), now start fetching data...
source 0 - assert 1493324550.000003956, sequence: 456311 - clear 0.000000000, sequence: 0
source 0 - assert 1493324551.000001890, sequence: 456312 - clear 0.000000000, sequence: 0
source 0 - assert 1493324552.000001441, sequence: 456313 - clear 0.000000000, sequence: 0

geprüft werden.

NTP Konfiguration

In /etc/ntp.conf folgendes eintragen:

driftfile /var/lib/ntp/ntp.drift
statsdir /var/log/ntpstats/
statistics loopstats peerstats clockstats

filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable

server 0.debian.pool.ntp.org iburst
server 1.debian.pool.ntp.org iburst
server 2.debian.pool.ntp.org iburst
server 3.debian.pool.ntp.org iburst

server 127.127.20.0 minpoll 2 maxpoll 4 prefer # GPSd
fudge 127.127.20.0 flag1 1 refid NMEA

restrict -4 default kod notrap nomodify nopeer noquery
restrict -6 default kod notrap nomodify nopeer noquery
restrict 127.0.0.1
restrict ::1

Jetzt fehlt “nur” noch die Verbindung des GPS Treibers (127.127.20.0) zu unserem GPS Empfänger. Der Treiber 20 verwendet hardcodiert die Dateien /dev/gpsX und /dev/gpsppsX für die NMEA und PPS Informationen. Ein einfacher Symlink reicht leider nicht, da dieser beim Reboot wieder gelöscht wird. Stattdessen via /etc/udev/rules.d/09.pps.rules automatisch eintragen lassen (siehe Comment from Pete Stephenson on http://www.satsignal.eu/ntp/RaspberryPi-notes.html):

KERNEL=="ttyACM0", SYMLINK+="gps0"
KERNEL=="pps0", OWNER="root", GROUP="tty", MODE="0660", SYMLINK+="gpspps0"

Neustart des ntp-Servers mittels /etc/init.d/ntp restart. Damit die beiden Symlinks auch nach einem Reboot aktiv bleiben, die Anlage der symlinks in die /etc/rc.local eintragen:

ln -s /dev/pps0 /dev/gpspps0
ln -s /dev/ttyACM0 /dev/gps0

Abfrage des Timeservers mittels: ntpq -c peers -c rv :

 remote          refid        st t when poll reach    delay   offset jitter
==============================================================================
oGPS_NMEA(0)     .NMEA.        0 l    -    8   377    0.000   -0.003  0.002
-ntp0.technl.net 80.114.85.144 2 u   47   64   377   48.622   -9.328  2.313
+mail.veland.de  89.238.79.186 3 u   47   64   377   38.701    2.456  3.736
+v6.blazing.de   213.172.96.14 2 u   52   64   377   28.919   -0.301  2.960
+217.79.179.106  212.51.144.44 2 u   57   64   377   31.623   -0.386  2.552
associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync,
version="ntpd 4.2.8p10@1.3728-o Sun Apr 16 12:01:26 UTC 2017 (1)",
processor="armv7l", system="Linux/4.4.50-v7+", leap=00, stratum=1,
precision=-19, rootdelay=0.000, rootdisp=1.000, refid=NMEA,
reftime=dcaccfd1.533a3357 Thu, Apr 27 2017 20:15:13.325,
clock=dcaccfd1.9db99523 Thu, Apr 27 2017 20:15:13.616, peer=36778, tc=3,
mintc=3, offset=-0.003099, frequency=-13.013, sys_jitter=0.002371,
clk_jitter=0.002, clk_wander=0.001

Der jitter kann evtl. noch verbessert werden durch die Angabe von nohz=off (http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html#nohz) und fixe Frequenzen für arm_freq_min und arm_freq_max, aber das muss ich selbst erst noch beobachten.

RS485 Interface an einem PIC16F1708

Neues Projekt mit RS-485 Interface: 29 Module mit je 37 LEDs, die über einen Raspberry Pi gesteuert werden sollen.

Problem: der PIC16F1708 ist nicht in der Lage festzustellen, ob noch eine Übertragung via EUSART Modul aktiv ist (Quote: “The TSR register is not mapped in data memory, so it is not available to the user.”). Die Transmitter-Enable Leitung (DE) kann also nicht mit dem letzten gesendeten Bit wieder deaktiviert werden.

Lösung: Beim Senden von jedem Zeichen die DE Leitung auf High setzen (und so den 75176 in Sendemodus bringen), den TMR0 (re-)starten und im Interrupt-Handler von TMR0 dann die DE Leitung wieder auf Low setzen:

void TMR0_CallBack(void) {
  IO_DE_SetLow();
}

void RS485_Put(uint8_t c) {
  IO_DE_SetHigh();
  TMR0_Reload();
  EUSART_Write(c);
}

void RS485_Print(const unsigned char* message) {
  char c; 
  while (c = *message++) {
    RS485_Put(c);
  } 
}

char to_hex(uint8_t v) {
  v = v & 0xf;
  if (v<10) {
    return '0'+v;
  }
  return 'A'-10+v;
}

void RS485_PrintHex8(uint8_t val) {
  RS485_Put(to_hex(val>>4));
  RS485_Put(to_hex(val));
}

void RS485_PrintHex16(uint16_t val) {
  RS485_Put(to_hex(val>>12));
  RS485_Put(to_hex(val>>8));
  RS485_Put(to_hex(val>>4));
  RS485_Put(to_hex(val));
}

void RS485_PrintDecimal(uint16_t val) {
  RS485_Put('0'+ ((val/10000) % 10 ));
  RS485_Put('0'+ ((val/1000) % 10 ));
  RS485_Put('0'+ ((val/100) % 10 ));
  RS485_Put('0'+ ((val/10) % 10 ));
  RS485_Put('0'+ ((val/1) % 10 ));
}

Touch-Slider mit AT42QT2120

Der AT42QT2120 von Atmel bietet eine sehr einfache Möglichkeit einen linearen Schieberegler über ein Touchpad zu realisieren:

Bildschirmfoto 2015-03-07 um 14.35.03

Dabei ist nur das Layout für die vier Felder des Touchsensors zu beachten:

Bildschirmfoto 2015-03-07 um 14.37.35

Die Felder dürfen dabei recht groß werden (Länge eines Felds bis 20cm ohne nennenswerte Einschränkungen nutzbar).

S0-Messwerterfassung von Stromzählern

Neuere Stromzähler sind zum Teil mit einem Optokoppler ausgestattet, der für jede verbrauchte Wattstunde einen Impuls liefert (1000 Impulse = 1 kWh). Der Anschluss an einen Arduino gestaltet sich dem entsprechend einfach: D+ Ausgang des Zählers auf 5V legen und den D- Ausgang an einen digitalen Eingang des Arduino anschließen, dieser muss noch mit einem 4k7 Widerstand gegen Masse gezogen werden um ein klares Signal zu erhalten.


Continue reading

INA219 Leistungssensor

Für die einfache Überwachung von Stromverbrauchern (Gleichstrom) eignet sich der INA219 hervorragend. Über I2C liefert dieser bis zu 15-Bit genaue Werte über die aktuelle Spannung, den Strom und die daraus berechnete Leistung.

Als externe Komponente ist neben dem obligatorischen Abblockkondensator nur noch der Shunt notwendig. Bis zu 16 Sensoren lassen sich gemeinsam an einem I2C-Bus betreiben: Zwei Adresseingänge, die an Vcc, Gnd, SDA oder SCL gelegt werden legen die Adresse des im kompakten SO-8 Gehäuse daherkommenden Chips fest:

Messwertaufnehmer für 4 Verbraucher mit jeweils bis zu 30A bei 12V, die über M6-Schrauben direkt an den Shunts befestigt werden

Als Shunt kommt die WSMS5515-Serie von Vishay Dale mit 500μΩ zum Einsatz, die bei 30A Last einen Spannungsabfall von 15mV liefern. Durch die Auflösung des INA219 kann diese Kombination Ströme von 1mA messen und die Leistung auf 20mW genau bei einem Maximum von 524W bestimmen.

Vom Prototyp zur Kleinserie

In den letzten Monaten wurde der Prototyp eines Universalladegeräts für Mobiltelefone mit Statusanzeige (nicht angeschlossen, lädt, geladen, Überlast) in einer Kleinserie für “The Electric Hotel” vervielfältigt:

Hier eine kleine Liste der Dinge, die bei der Serienfertigung zu beachten sind:

  • Ausreichend Rand um den Nutzen für den Bestückungsautomaten
  • Passermarken oder gegenüberliegende Bohrungen auf jeder Platine im Nutzen
  • Koordinaten aller Bausteine immer auf die Mitte des Gehäuses beziehen
  • Klare Kennzeichnung der Einheiten (mm, cm, inch, mil)
  • Gerberfiles des Nutzens, Drillfile, Stückliste und Koordinaten der Bauteile für den Bestücker bereitstellen
  • Eindeutige Beschriftung aller beigestellten Bauteile, bei kleinen Bauteilen (0805 und kleiner) durchaus 10% mehr bereitstellen, da der Automat auf dem Weg die Bauteile verlieren kann
  • Falls Bauteile nicht bestückt werden sollen, diese trotzdem in die Stückliste als “nicht zu bestücken” aufnehmen

Continue reading

Platinenherstellung

Hier eine Anleitung, wie man mit ein wenig Chemie in kurzer Zeit hochwertige Platinen herstellen kann.

Layout erstellen

Das Layout wird mit EAGLE erstellt und gegen die eigenen Design-Regeln geprüft (Ausgehend von den pcb-pool Regeln: Minimale Leiterbreite 6 mil, minmaler Abstand 6 mil, Bohrungen mindestens 0,5mm):

Continue reading

Neues Midi-Pult (Update 4)

Nachdem aus dem 120 RGB-LED Projekt ein wunderbares Leitsystem für die Nachrichtenmeisterei bei der Museumsnacht 2010 geworden ist (Video folgt noch), steht nun ein neues Projekt vor der Tür: Ein edles Midi-Pult mit 32 Fadern, 64 Drehencodern und den darin integrierten Tastern.

Zum Aufbau: das Pult ist in zwei Teile, jeweils 19-Zoll/5HE, aufgeteilt. Beide Hälften verfügen über eigenständige A/D-Wandler (MCP3208) für die 100mm Fader und Digital-Inputs (74HC165) für die Encoder und Taster. Diese geben Ihre Daten auf einen zentralen Bus, der von dem Microcontroller auf MIDI umgesetzt wird.

Bei der Wahl des Prozessors standen die üblichen Verdächtigen zur Auswahl (PIC, Atmel und MSP), es ist aber – trotz der anhaltenden Lieferengpässe bei Atmel – ein Atmega328 geworden. Nachdem die Software recht schnell auf dem Arduino lauffähig war, ging es an die Code-Optimierung. Sobald ein wenig mehr IO-Leistung gebraucht wird (für die Encoder werden insgesamt 256 Bit über den Bus geschoben), sollte auf digitalRead und digitalWrite verzichtet werden. Die Umstellung von digitalRead(10) auf ((PINB & 0x04) >>2) brachte Faktor 40, so dass nun auch schnelle Drehungen ohne Verlust von Schritten erfasst werden. Das war dann auch der Abschied von Arduino.App und der Beginn der Umstellung auf Eclipse-CDT, das auch unter MacOS eine gute Unterstützung der kompletten AVR-Suite bietet.

Da das Pult länger halten und angenehm zu bedienen sein sollte, kommen die edlen ALPS-Produkte zum Einsatz, die in Stückzahlen auch bezahlbar sind. Die Encoder stammen aus der Automotive Serie, sind staubdicht und auf 500.000 Zyklen ausgelegt.

Momentan sind die Platinen in der Produktion bei pcb-pool, die Frontplatte wird von Schaeffer-AG hergestellt.  Sobald es an den Zusammenbau geht, folgen weitere Bilder.

Update 1:

Mittlerweile gibt es die ersten Bilder von pcb-pool:

Jetzt bleibt nur zu hoffen, dass die Stencils für die richtige Seite angefertigt werden.

Schaeffer hat die Frontplatten bereits gefräst, da der Versand für den 01.10. geplant ist, müssten diese also zusammen mit den Platinen am Samstag in der Post sein.

Update 2:

Es wurde dann doch Montag, aber sowohl die Platinen als auch die Frontplatten waren heute in der Post. Da die Encoder erst am 18.10. geliefert werden, konnten die Frontplatten schon teilweise bestückt werden:

Morgen geht es, sofern die Zeit es zulässt an die Bestückung der Platinen:

Update 3:

Die SMD-Bestückung der kleinen Platinen ist erledigt, nur für die Wandlerplatinen reichte die Lötpaste dann doch nicht mehr. Am Wochenende wird das Gehäuse gesägt und der Aufbau getestet.

Update 4:

Das Gehäuse war dann recht schnell gesägt, die Bestückung erledigt, alle Stecker (68 Stück für die Flachbandkabel im Inneren) verpresst. Der erste Test verlieft fast gut, aber drei Lessons Learned gab es dann doch noch bei dem Projekt:

  • Niemals mit 100 nF X7R Abblockkondensatoren geizen
  • Einen A/D Wandler immer nur mit einer Taktfrequenz betreiben, die tatsächlich kleiner ist als die maximal zulässige (der Atmel war dann doch schneller als erwartet)
  • Traue niemals einem Datenstrom, der seriell übertragen wurde (es kann tatsächlich mal ein Byte fehlen)

Aber nun ist das Pult fertig und konnte erfolgreich am MOTU-828MK2 MIDI-Port betrieben werden, alle 160 Midi-Signale werden einwandfrei übermittelt, in dem zugehörigen Live-Set konnten allerdings auf Grund der Ableton-Einschränkung nur jeweils 128 gleichzeitig getestet werden.

Zum Abschluss noch ein paar Bilder vom fertigen Gerät:


MAX6966 10-Port Led Treiber

Auf der Suche nach einer Alternative zu der PIC Ansteuerung der RGB-LEDs fand ich bei Maxim den MAX6966, der einen schöne Lösung für die niedrigen Helligkeitsstufen bietet. Für alle Kanäle lässt  sich mit einem gesonderten 3-Bit Register die Konstantstromquelle in 8 Stufen zwischen 1.25 mA und 20 mA einstellen. Wenn ein Kanal einer RGB-Led hell leuchtet spielt die Auflösung der anderen beiden Kanäle ja keine große Rolle mehr.

Für den Hobbybastler ohne Lötstoppmaske leider nicht gut zu verarbeiten: Entweder im 16-poligen TQFN (0,5 mm Pinabstand) oder QSOP Gehäuse (0,635 mm Pinabstand). Zudem sind zwei Stromversorgungen einzuplanen: Einmal die 3,3 Volt Logiklevel und eine zweite für die LEDs (sollte mindestens 1 Volt über der Vorwärtsspannung liegen). Bei meinen bevorzugten Cree CLV1A-FKB LEDs also mindestens 4,2 Volt.

Da die Ausgänge aber auch parallel geschaltet werden können, sind auch 50 mA LEDs (wie z.B. OVSTRGBBCR8 v0n Optek) direkt ansteuerbar.