January 23rd, 2015 | Tags: ,

An Arduino Library for the MCP3424 12,14,16,18bit ADC from Microchip.

The MCP3424 is a low-cost 18Bit Sigma-Delta ADC with I2C Interface.

This library implements the following features:

  • channel setting by address or pin selection
  • continuous and one_shot modes
  • selectable sample rates 12,14,16 and 18 bit
  • selectable PGA gains: x1, x2, x4, x8
  • conversion errors: overflow, underflow, i2c, progress, timeout
  • general call requests
  • highest valid gain selection
  • selectable blocking/non-blocking modes

MCP3424 on Github

January 21st, 2015 | Tags: , , , ,

The Problem

Some ignorant portals and many spammers sending multi part MIME encoded messages
marked as text/plain but inside of the part is actually text/html. This results
in pain in the ass raw oneliner html message in the mail reader.


The exercise here is to locate the text part in the Email and convert the html part into text.


The easy solution is to convert all body parts of the MIME Email to text:

# ~/.procmailrc
:0 fbw
* ^From:.*ignorant@domain.tld
|/usr/bin/lynx -dump -stdin -force_html

However this is not very clever, because it converts also the html part we want to keep.

More clever is to extract the email, locate the html part and convert it to text.

# ~/.procmailrc
:0 fw
* ^From:.*ignorant@domain.tld

The following Perl sciprt uses MIME::Parse to split the Email, locates the text/plain part and filters the html with lynx into readable text:


use strict;
use MIME::Parser;
use IPC::Open2;
use FileHandle;

$ENV{"PATH"} = '/usr/bin';

my $parser = new MIME::Parser;


my $entity=$parser->parse(*STDIN);

print $entity->head->as_string,"\n";

my $boundary = '--' . $entity->head->multipart_boundary;

my @parts = $entity->parts;

for my $part (@parts)  {
  if($part->parts) {
    push @parts,$part->parts; # for nested multi parts

  if ($part->head->mime_type =~ m,text/plain,) {
      my $textmsg;
      my ($chld_rd, $chld_wr) = (FileHandle->new, FileHandle->new);
      my $pid = open2($chld_rd, $chld_wr,
                       qw{/usr/bin/lynx -dump -force_html -stdin});
      print $chld_wr $part->bodyhandle->as_string;
      close $chld_wr;
      { local $/ = undef;
        $textmsg = <$chld_rd>;
        close $chld_rd;
      print $boundary,"\n";
      print $part->head->as_string,"\n";
      print $textmsg;

    } else {
      print $boundary,"\n";
      print $part->as_string,"\n";
print $boundary,"--\n";
July 6th, 2014 | Tags: , ,

Playing around with Arduino finally implemented the printf. The
floating point library can be only enabled by modifying the IDE Utilizar float con sprintf() y derivados en Arduino.

/* simple implementation of printf for SoftwareSerial */

#include <SoftwareSerial.h>
#include <inttypes.h>

class mySerial : public SoftwareSerial {

    mySerial(uint8_t receivePin, uint8_t transmitPin, bool inverse_logic = false) :
      SoftwareSerial(receivePin, transmitPin,inverse_logic) {}

    virtual size_t write(uint8_t byte) {
      return SoftwareSerial::write(byte);

    int printf(char* fmt, ...) {
      char buff[256];
      va_list args;
      va_start(args, fmt);
      int return_status = vsnprintf(buff, sizeof(buff), fmt, args);
      uint8_t *s = (uint8_t *)&buff;
      while (*s) write(*s++);
      return return_status;


mySerial m(PD0,PD1);

/* to enable support for floating point functionality,
   use following linker switches
   -Wl,-u,-lprintf_flt vfprintf

void setup() {
  m.print("Hello from Arduino!\n");
  m.printf("%s %.3f %x %d %4o\n", "Hello", 3.14159, 0x80, 333, 128);
  m.printf("%16s %08x %e\n", "Hello", 0x1234, 1e-10);

  printf("%.3f %en", 3.14159, 3.14159);


void loop() {

I started a long awaiting project, to build a Geiger-Müller radiation counter. The Geiger tube is a SBT-11 russian tube for alpha, beta and gamma radiation. The tube is quite sensitive and of a relatively small size. The picture at the right hand side shows the SBT-11 tube and the high voltage power supply in a plastic CCFL case. The power supply works with 3.3V. A small CCFL transformer boosts the 3.3V to about 390V. The switching regulartor IC is a MC34063.

The datasheet says the tube has 0.6 pulses/sec of own background. 0.6 pulses/s are about 36 Pulses/min. To get the prove I started to count the pulses.

The Measurement

The common method to measure pulses is a round robin array to save the pulses and the sum of pulses yelds the CPM.
The code below shows an Arduino example:

ISR(each_second) {
   int pulses_per_second = count - last_count;
   register unsigned int cpm_pos = it_cpm++ % 60;
   cpm[cpm_pos] = pulses_per_second;

   int sum_cpm = 0;
   for(int i=0;i < 60;i++)
      sum_cpm = sum_cpm + cpm[i];
   Serial.println(sum_cpm, DEC);

The Result

The diagram on the left hand side shows the histogram of about 20 hours measurement. The own background of the tube has an intervall of 0 to about 86 pulses per minute. It shows (as expected) a discrete normal distribution with a mean of 36-38 pulses per minute or 0.6-0.63 pulses per second. So what does it say? This may concern everybody who needs to measure low radiation or background radiation. Usually it is not needed to substract the 0.6 pulses from result, because it is more expressive to give an confidence interval as an result.

ARMstrap eagle PCB


ARMstrap Eagle is an very nice OpenSource development board with a ARM Cortex-M4 STM32F4[012]7 CPU running at 168 MHz. The main feature of this board is the Black Magic Probe embedded debug interface. Beside of this it is interesting for me to learn how other features like the true Random Generator, AES encryption, RTC and so on work.


Since the ARMstrap Eagle documentation is not very chatty about on how to get everything done on Linux, here are additional important notes:

Build Environment

A popular repository is GNU Tools for ARM Embedded Processors.

  • Extract the files to your desired directory i.e. /opt or ${eclipse_home}.
  • Modify your PATH environment variable:
     echo 'export PATH=/opt/gcc-arm-none-eabi-4_8-2014q1/bin:"$PATH"' >> ~/.bashrc

UDEV Settings

ARMstrap eagle uses the Vendor-ID from OpenMoko:

~$ lsusb
Bus 004 Device 018: ID 1d50:6018 OpenMoko, Inc.
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

Here are my settings:

# /etc/udev/rules.d/55-armstrap.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1d50", ATTRS{idProduct}=="6018", RUN+="/sbin/modprobe cdc-acm", GROUP="plugdev", MODE="0660", SYMLINK+="eagle%n"

After you create the 55-armstrap.rules, you need to reload your rules

 udevadm control --reload

The udev devices will finally appear as:

# ls -l /dev/eagle*
lrwxrwxrwx 1 root root  7 May 16 19:03 /dev/eagle1 -> ttyACM1
lrwxrwxrwx 1 root root  7 May 16 19:03 /dev/eagle2 -> ttyACM2
lrwxrwxrwx 1 root root 15 May 16 19:03 /dev/eagle4 -> bus/usb/004/019


# for n in /dev/eagle*; do ls -l /dev/$(readlink $n); done
crw-rw-r-- 1 root plugdev 189, 1 May 16 19:03 /dev/ttyACM1
crw-rw-r-- 1 root plugdev 189, 2 May 16 19:03 /dev/ttyACM2
crw-rw-r--+ 1 root plugdev 189, 402 May 16 19:03 /dev/bus/usb/004/019

You may also take a look at the README of the Black Magic Debugger.

Eclipse Settings

The new GCC 4.8 needs to have some different settings in Project->Properties->C/C++-Build->Settings

Cross GCC Assembler->General

 -mcpu=cortex-m4 -mthumb -mno-warn-deprecated -mfloat-abi=hard

Cross G++ Linker->Miscellaneous

 -mcpu=cortex-m4 -mthumb -mno-warn-deprecated -mfloat-abi=hard

Cross GCC Compiler->Miscellaneous

 -c -fmessage-length=0 -march=armv7e-m -mcpu=cortex-m4 -fno-common -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -MD -ffunction-sections -fno-builtin 

Cross GCC Compiler->Debugging

 -g3 -ggdb

An important step -ggdb. Without it you wont see any source int the debugger.

GDB Hardware Debugging

Rename the first line to:

target extended-remote /dev/eagle1

Serial Console

I belive /dev/eagle2 is the serial console. I need to check this.

Flashing/Uploading the Code

The debugging configuration flashes already and starts debugging.
To have only only flashing without debugging I created a small script

# /path/gdbupload.cmd
set print pretty
set auto-load safe-path /
target extended-remote /dev/eagle1
mon swdp_scan
attach 1

In eclipse select Project->Properties and got to:


select Configuration->Release
In Post-build steps->Command insert

arm-none-eabi-gdb -batch -x /opt/armstrap/gdbupload.cmd ${ProjName}.elf

The output for relase build

includes/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_adc.o includes/STM32F4xx_StdPeriph_Driver/src/misc.o
arm-none-eabi-gdb -batch -x /opt/armstrap/gdbupload.cmd blinky.elf
Target voltage: 4.9V
Available Targets:
No. Att Driver
 1      STM32F4xx
0x08000366 in loop ()
Loading section .isr_vector, size 0x188 lma 0x8000000
Loading section .text, size 0x3a0 lma 0x8000188
Start address 0x8000288, load size 1320
Transfer rate: 3 KB/sec, 660 bytes/write.
Detaching from program: /opt/armstrap/workspace/blinky/Debug/blinky.elf, Remote target

19:29:02 Build Finished (took 513ms)

April 27th, 2014 | Tags:

Today I’ve been able to properly convert a tiff file to pdf and
then back to tiffg3. The commands are:

$ convert -page A4 -density 600 -quality 100 -compress Zip file.tiff file.pdf

It is important to set the pagesize here, otherwise GhostScript wont resize it properly.

        -dFIXEDMEDIA -sDEVICE=tiffg3 \
        -r204x196 -sDithering=gsmono -dPDFFitPage
        -sOutputFile=file-g3.tiff file.pdf

Important here also the -dPDFFitPage

January 9th, 2014 | Tags: , , , , ,

The router’s default IP is To easily access the router, I first added an alias with the IP of the router’s subnet:

# ifconfig eth0:0

# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface     *        U     0      0        0 eth0     *        U     0      0        0 eth0

# ping
PING wrt ( 56(84) bytes of data.
64 bytes from wrt ( icmp_seq=1 ttl=64 time=0.345 ms
64 bytes from wrt ( icmp_seq=2 ttl=64 time=0.933 ms
# nc -z -v 80
wrt [] 80 (http) open

Now it’s eays to connect the router’s web interface and change it’s IP as needed.

If you have chinese firmware, then use this menu entry to upload new firmware:

More information you’ll find on the OpenWRT pages: Flashing

Office phones have to be online at office hours, otherwise a voicemail should be enabled. They should also be aware of holidays.

The dialplan

; extensions.conf
exten => 1234567,n,GotoIfTime(09:00-18:00,mon-fri,*,*?hcheck:vm)
exten => 1234567,n,GotoIfTime(09:00-14:00,sat,*,*?hcheck:vm)
exten => 1234567,n(hcheck),AGI(isholiday.pl)
exten => 1234567,n,GotoIf($[${ISHOLIDAY} = "YES"]?vm)
exten => 1234567,n(open),NoOp
exten => 1234567,n(vm),VoiceMail(1234567,sub)

A little perl-script checks for german holidays. The AGI figures out the holiday days for each year, so no updates are needed except a new day was added or removed. The AGI:

# holiday check for asterisk
# /var/lib/asterisk/agi-bin/isholiday.pl

use strict;
my ($isholiday, $today,$ymd);

END { printf "SET VARIABLE ISHOLIDAY %s\n\n", ($isholiday)?"YES":"NO"; }

while(<STDIN>) {
     last unless length($_);

use Date::Holidays::DE qw(holidays);

my $feiertage_ref = holidays(
    WHERE    => [ 'common', 'ni'], # ni = Niedersachsen
    FORMAT   => "%F",
    YEAR     => 1900 + (localtime())[5],
    ADD      => [ 'heil', 'wei1', 'wei2',
                  'osts', 'ostm', 'pfis',
                  'pfim', '3okt', 'silv',
                  'mari' ]);

my (@ymd) = (localtime)[5,4,3];
$today = sprintf "%s-%s-%s", 1900+$ymd[0], 1+$ymd[1], $ymd[2];

for my $d (@$feiertage_ref) {
    if ($d eq $today) {
        $isholiday = 1;
December 15th, 2012 | Tags: , , , , ,

There is often a need to debug scripts which are started by daemons, so you have no input/output available. The following snippet easily redirects stdout and stderr to a file:


exec >> /tmp/script_debug.log 2>&1
set -x 

echo Start: $(date)

: buggy code

echo Stop: $(date)

and here the output:

$ cat /tmp/script_debug.log
++ date
+ echo Start: Sat Dec 15 08:37:45 CET 2012
Start: Sat Dec 15 08:37:45 CET 2012
+ your-buggy-cmd
foo: line 8: your-buggy-cmd: command not found
++ date
+ echo Stop: Sat Dec 15 08:37:45 CET 2012
Stop: Sat Dec 15 08:37:45 CET 2012
November 12th, 2011 | Tags: ,

The first part of Parallel Bash dealt with creation of parallel processes, so now it’s time for a real parallel tool.

The Apache benchmark tool ab has the disadvantage of sending only one URL for requests. To emulate a real server load we need some tools which can download several different files (.jpg, .js, .php, .css, ..) where each of them causes different CPU loads and network througphut, as well as different sizes of tranfered data. This can easily be done with httrack or wget.

And here is how:

The parallel routine pwork runs a site-mirror and collects the elapsed time in a log file


pwork () {
    TMPDIR=$(mktemp -d /tmp/htbench_instance_XXXXX)
    TMPFILE=$(mktemp /tmp/htbench_log_XXXX)
    ( cd $TMPDIR
      #  append elapsed time to HTLOG
      /usr/bin/time -f "%e" -o $TMPFILE
      httrack -c8 --mirror --depth=2 -Q -q $1
      if lockfile -1 -r12 $HTLOCK; then
          cat $TMPFILE >> $HTLOG
      rm -f $HTLOCK $TMPFILE
    rm -rf "$TMPDIR"

Limit the benchmark to n loops:

while [ $COUNT != 0 ]
do      J=$(jobs -p)
        echo "jobs left: "$COUNT
        N=$(echo $J|wc -w)
        if [ -z "$N" -o "$N" -lt $PARALLEL ]; then
            pwork "$URI" &
            (( COUNT-- ))
        sleep .2

Show final results:

show_results () {

    MINRUN=$(sort -n $HTLOG|head -1|cut -d' ' -f1)
    MAXRUN=$(sort -n $HTLOG|tail -1|cut -d' ' -f1)
    AVGRUN=$(perl -e '$sum=$count=0;
                         while (<>) {
                             chomp;$sum+=$_;$count++; }
                          printf "%.2fn", $sum/$count;' $HTLOG)
    rm $HTLOG

    echo "Benchmark Results"
    echo "================="
    echo "longest runtime:  "$MAXRUN
    echo "shortest runtime: "$MINRUN
    echo "average runtime:  "$AVGRUN

reaper () {
        echo "waiting to finish $RUNNING" >&2
        exit 0

trap reaper 0 1 2 3 11 15

Use with care!

Download latest version: