Internet’o’meter: En steampunk download hastighedsmåler

Jeg har hygget mig med et lille weekendprojekt: Konverteringen af et antikt tysk voltmeter til et steampunk Internet’o’meter, som viser hvor mange Mb/s jeg suger fra nettet.

Jeg købte instrumentet for en slik for nogle år siden, da jeg synes det er var smukt. Jeg elsker de gamle messinginstrumenter. Det er håndværk i sin reneste form. Se bare indmaden – det er kræs:

Instrumentet var oprindelig designet til at måle 210-250 VDC, og jeg har derfor bypasset seriemodstanden, da jeg ønsker lavest mulig arbejdsspænding. Fuldt viserudslag sker nu ved knap 2V. Perfekt til mit formål.

Den eneste tilslutning til Internet’o’meteret skal være en 230V ledning (i stof, naturligvis, for at holde stilen), så det var nødvendigt med wi-fi. Derfor valgte jeg en Raspberry Pi Zero W som systemhjerne.

 

Problemet med Raspberry Pi er dog, at der ikke er indbygget digital til analog konverter. Derfor tilføjer jeg et 12bit DAC modul fra Adafruit som er baseret på MCP4725. Den forbindes med I2C til Raspberry Pi og der er ganske gode python libraries til rådighed, så det er særdeles nemt at komme i gang.

Koden på raspberry pi’en kan I se her. For en gennemgang af hvordan koden virker, se videoen jeg linker til nede i bunden af denne artikel.


import time
import Adafruit_MCP4725
import socket
import sys


minIP="<RASPBERRY PIs IP ADRESSE>"
minPort="<DEN PORT SOM DER SKAL LYTTES TIL>"
# Create a DAC instance.
dac = Adafruit_MCP4725.MCP4725()

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (minIP, minPort) 
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)

sock.listen(1)

while True:
# print >>sys.stderr, 'waiting for a connection'
connection, client_address = sock.accept()

try:
# print >>sys.stderr, 'connection from', client_address

while True:
data = connection.recv(12)
# print >>sys.stderr, 'received "%s"' % data

if data <> "":
dacVal = 1595+int(round(2.85*float(data)/1000000))
# print dacVal
if dacVal > 1880:
dac.set_voltage(1900, True)
else:
dac.set_voltage(int(dacVal), True)

else:
connection.close()
break
finally:
connection.close()

Dernæst skal den kode som kører på min router skrives. Jeg læser rx og tx bytecounters i regelmæssige intervaller. For hver sample trækker jeg den tidligere værdi fra den nye værdi hvorved jeg får antallet af bytes sendt i det forløbne tidsrum. Jeg ganger med 8 og dividerer med antallet af sekunder, hvorved jeg ender op med bits per sekund.

 


#!/bin/bash

tstart=$(date +%s)
bef_data_r=$(cat/sys/class/net/eth0/statistics/rx_bytes)
bef_data_t=$(cat /sys/class/net/eth0/statistics/tx_bytes)

sleep 2
while true
do
   now=$(date +%s)
   elapsed=$(($now - $tstart))

   data_r=$(cat /sys/class/net/eth0/statistics/rx_bytes)
   data_t=$(cat /sys/class/net/eth0/statistics/tx_bytes)

   now_data_r=$(($data_r - $bef_data_r))           
   now_data_r_bits=$((8*$now_data_r/$elapsed))

   now_data_t=$(($data_t - $bef_data_t))        
   now_data_t_bits=$((8*$now_data_t/$elapsed))

   echo $now_data_r_bits > tmpval 
   nc <RPI_IPADDRESS>:<RPI_PORT> < tmpval

   tstart=$now

   bef_data_r=$(cat /sys/class/net/eth0/statistics/rx_bytes)        
   bef_data_t=$(cat /sys/class/net/eth0/statistics/tx_bytes)

   sleep 2
done

Som I kan se poller jeg værdierne for både up- og downstream. Lige nu viser jeg kun downstream, da det er det mest interessante. Men hvis nu jeg skulle få lidt ekstra tid ved lejlighed, så er koden forberedt! 🙂

 

Jeg har designet en ny skala til instrumentet i InkScape, og printet den på en laserprinter. Det er klart, at man ikke kan sætte en kridhvid skala i et 100+ år gammelt instrument, så skiven skal “patineres”. Det klares med stærk te og en gasbrænder.

Se processen og en demonstration af det færdige resultat i denne video:

 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *

This site uses Akismet to reduce spam. Learn how your comment data is processed.