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. 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:

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

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.

I2S Mikrofon und PIC32MX170F256 als Alternative zu MSGEQ-7

Als günstige Alternative zu einem MSGEQ-7 (Einzelpreis 5,45€) für ein Graphic Equalizer Display (5-Kanal Lichtorgel) ein kleiner Exkurs in die DSP Welt:

Von Knowles gibt es sehr (sehr) kleine Mikrofone, die direkt das Audio Signal als I2S Datenstrom ausgeben (Einzelpreis 2€).

Dieses wird direkt an den I2S Port des PIC32 (Einzelpreis 4€) angeschlossen und mittels DMA im Hintergrund ausgelesen. Nach jeweils 4096 Samples bei 48 kHz wird der DMA Interrupt ausgelöst (etwa 48 mal pro Sekunde) und die Samples des unbeschalteten Kanals weggeworfen und je zwei aufeinanderfolgende Samples des verbleibenden Kanals gemittelt.

Die so übrig bleibenden 1024 Samples (mit einer Abtastfrequenz von nun 24 kHz) werden dann mittels FFT in den Frequenzraum überführt und auf die 5 Bänder aufgeteilt.

Die Anzeige der Balken erfolgt über eine Matrix aus WS2812 LEDs:

bildschirmfoto-2016-09-23-um-21-14-11

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 ));
}

Mailserver mit Postfix, dovecot, spamassassin, opendkim und postgrey unter debian jessy

Der alte Server war dann doch etwas langsam, daher der Umzug auf neue Hardware. Mit dem Umzug galt es auch den bisherigen IMAP Server (cyrus) durch dovecot zu ersetzen. Soweit der Vorsatz, die Umsetzung war dann weitaus schwieriger…

Setup

Neben der Grundfunktionalität (Mails empfangen und senden) sollte der Mailserver wenigstens folgendes können:

  • DKIM zur Authentifizierung
  • SPF
  • Greylisting
  • spamassassin Unterstützung
  • Volltextsuche über IMAP
  • Mehrere virtuelle Domains
  • Weiterleitungen
  • Mehrere Benutzer für IMAP/SMTP
  • TLS Unterstützung

Continue reading

Dimmen von Leuchtstoffröhren über DMX

Normale Leuchtstoffröhren lassen sich ja nicht dimmen. Hierfür gibt es spezielle Vorschaltgeräte, die meistens einen Steuereingang 0-10V haben (z.B. diese hier: http://www.methline.de/methline-p806h14s76-EVG-dimmbar-1-10V-fu.html).  Die Kopplung an den DMX-Bus ist mit einem Arduino und einem Levelshifter (z.B. wie hier beschrieben), einem 10 Volt fähigen DAC (MAX528) oder der fertigen Lösung von dmx4all (DMX 0-10V Interface) schnell erledigt.

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