Archiv der Kategorie: IoT

Measure loudness with a USB micro on a raspberry pi

What: Measuring loudness with a simple USB microphone on a raspberry pi
Why: Create devices which are activated by a certain noise level
How: Use python and some python libraries to analyse the sound stream

Requirements

The following hardware was used for this setup:

The following os was used on the raspberry pi:

The following python version was used (preinstalled with the corresponding raspbian):

  • Python 2.7 (PyAudio was not working for me with Python3 easily)

Setup

Besides plugging the USB microphone in the corresponding USB port (such a surprise), the following things needs to be done.

Install PortAudio

Install the dependencies:

sudo apt-get install libasound-dev

Download the corresponding version (at the time of writing this is 190600_20161030) and uncompress it:

wget http://www.portaudio.com/archives/pa_stable_v190600_20161030.tgz
tar -xvf pa_stable_v190600_20161030.tgz

Build PortAudio from source:

cd portaudio
./configure && make
sudo make install
sudo ldconfig

Install NumPy, PyAudio and SoundAnalyse

pip install numpy
pip install PyAudio
pip install SoundAnalyse

Code

Below is the code I used for measuring. There are some caveats with measuring the loudness:

  • There are by default some warnings when opening the stream
  • When reading the bytes from the stream, there may be an overflow exception which will kill the script. This can be avoided by the parameter exception_on_overflow = False
  • The parameters for pyaud.open may be different depending on the used microphone. The parameters can be determined by iterating over the devices and use: pyaud.get_device_info_by_index(i)
1
2
3
4
5
6
7
8
9
10
11
12
13
import analyse
import numpy
import pyaudio
 
pyaud = pyaudio.PyAudio()
stream = pyaud.open(format = pyaudio.paInt16,channels = 1,rate=44100,input_device_index=2,input=True)
 
while True:
    raws=stream.read(1024, exception_on_overflow = False)
    samples= numpy.fromstring(raws, dtype=numpy.int16)
    loudness = analyse.loudness(samples)
    if loudness > -15:
        print "Really loud"

Flashing christmas poems

What: Using a raspberry pi and some LEDs to send christmas poems in morse code
Why: Controlling LEDs with raspberry
How: Using RPi.GPIO library, some simple LEDs and a python script

Morse code

A basic morse code library for python can be found at github. Essentially, it maps lower case characters (no special ones) to a sequence of morse symbols.
It is a python dictionary with the characters as keys:

s='short'
l='long'
p='pause'

alphabet={}
alphabet['a']=[s, l]
alphabet['b']=[l, s, s, s]

You can use it in any python program:

from morsecode import alphabet

for character in text:
    code=alphabet[character]
    for dur in code:
        if dur=='short':
            # Do something here
            pass
        if dur=='long':
            # Do something here
            pass
        if dur=='short' or dur=='long':
            # Do something here
            pass
        if dur=='pause':
            # Do something here
            pass
    characterbreak()
textbreak()

Translate text to LED signals

Using two LEDs, one can encode the dit (short symbol) and the other one the dah (long symbol) in morse code. You need additional breaks between characters and words. These can be encoded by not flashing any LED.

Putting it together with the morse alphabet and simple logic for processing arbitrary text (note: the script below does not check, if all characters used are present in the alphabet; just use lower case ones and comma and dot):

#!/usr/bin/python
import RPi.GPIO as GPIO
import time
from morsecode import alphabet
import sys

GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.OUT)
GPIO.setup(10, GPIO.OUT)

if len(sys.argv)==1:
    print('you have to provide the text as argument')
    sys.exit(1)
text=sys.argv[1].lower()

dittime=0.25

def dit():
    GPIO.output((4, 10), (GPIO.HIGH, GPIO.LOW))
    time.sleep(dittime)

def dah():
    GPIO.output((4, 10), (GPIO.LOW, GPIO.HIGH))
    time.sleep(3*dittime)

def symbolbreak():
    GPIO.output((4, 10), (GPIO.LOW, GPIO.LOW))
    time.sleep(dittime)

def pause():
    GPIO.output((4, 10), (GPIO.LOW, GPIO.LOW))
    time.sleep(4*dittime)

def characterbreak():
    GPIO.output((4, 10), (GPIO.LOW, GPIO.LOW))
    time.sleep(3*dittime)

def textbreak():
    GPIO.output((4, 10), (GPIO.LOW, GPIO.LOW))
    time.sleep(10*dittime)

while True:
    for character in text:
        code=alphabet[character]
        for dur in code:
            if dur=='short':
                dit()
            if dur=='long':
                dah()
            if dur=='short' or dur=='long':
                symbolbreak()
            if dur=='pause':
                pause()
        characterbreak()
    textbreak()

GPIO.cleanup()

You can start it with (assume you saved the above code in a file called morseflash.py and assigned execution rights):

./morseflash.py "I syng of a mayden that is makeles, \
kyng of alle kynges to here sone che ches. ..."

See it in action:

Docker on Raspbian

What: Getting Docker running without hassle on raspberry3
Why: Using Docker images on raspberry
How: Using arm version of docker and standard apt-functionality

This is an extract from the docker documentation, which worked for me on a raspberry3 with raspbian jessie.

Install requirements

1
2
3
4
5
6
7
sudo apt-get update
sudo apt-get install \
     apt-transport-https \
     ca-certificates \
     curl \
     gnupg2 \
     software-properties-common

Prepare installation

1
2
3
4
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
echo "deb [arch=armhf] https://download.docker.com/linux/debian \
     $(lsb_release -cs) stable" | \
     sudo tee /etc/apt/sources.list.d/docker.list

Install

1
2
sudo apt-get update
sudo apt-get install docker-ce

Test

1
sudo docker run armhf/hello-world

Mosquittos on the couch

What: Put mosquitto messages to the couch
Why: Using mosquitto broker as relay between your IoT devices and a database backend
How: Use mosquitto, curl and some linux magic

Requirements

You need couchdb (assumming it runs locally on port 5984 for this example) and mosquitto (also assuming it runs locally for this example). If you dont have it on your system, have a look at my other blog entry. Additionally, you need curl and the bash.

Set up a simple publisher

Create a simple script test.sh, which will publish messages periodically to the mosquitto broker under the topic test:

counter=0
while true; do
    sleep 3
    mosquitto_pub -t test -m "$counter"
    counter=$(($counter+1))
done

Change the permission for this script in such a way that you can execut it.

Create a test database

curl -X PUT http://localhost:5984/testdb

Connect mosquitto and couch via curl

Mosquitto and couchdb can be connected via a simple shell pipe:

mosquitto_sub -t test | while read line;do curl -H 'Content-Type:application/json' -d "{\"date\":\"$(date +%Y-%m-%dT%H:%M:%SZ)\", \"value\":$line}" http://localhost:5984/testdb;done &

Note: You could think about piping mosquitto directly to couch, if your message is already a json string. Something like this:

mosquitto_sub -t test | while read line;do curl -H 'Content-Type:application/json' -d -http://localhost:5984/testdb;done

This will not work, because curl starts reading the input after it is complete (after the stream from mosquitto is closed). You need the while read line construction like shown above.

Run the test publisher script and verify results

Run the script:

./test.sh

Wait some seconds. Now query the database and you should have some documents there:

curl http://localhost:5984/testdb/_all_docs?include_docs=true

The result should look like:

{"total_rows":8,"offset":0,"rows":[
{"id":"13e93448d1256a98a3fa76f889000414","key":"13e93448d1256a98a3fa76f889000414","value":{"rev":"1-589430e0693f8f209655122fa934c440"},"doc":{"_id":"13e93448d1256a98a3fa76f889000414","_rev":"1-589430e0693f8f209655122fa934c440","date":"2017-06-08T20:47:01Z","value":0}},
{"id":"13e93448d1256a98a3fa76f889000bab","key":"13e93448d1256a98a3fa76f889000bab","value":{"rev":"1-0ebf14c49eab17f786c5f03c7c89acbb"},"doc":{"_id":"13e93448d1256a98a3fa76f889000bab","_rev":"1-0ebf14c49eab17f786c5f03c7c89acbb","date":"2017-06-08T20:47:04Z","value":1}},
{"id":"13e93448d1256a98a3fa76f8890010ee","key":"13e93448d1256a98a3fa76f8890010ee","value":{"rev":"1-8ded0d7b84da764a9fbe3d51bf27db6c"},"doc":{"_id":"13e93448d1256a98a3fa76f8890010ee","_rev":"1-8ded0d7b84da764a9fbe3d51bf27db6c","date":"2017-06-08T20:47:07Z","value":2}},
{"id":"13e93448d1256a98a3fa76f889001e53","key":"13e93448d1256a98a3fa76f889001e53","value":{"rev":"1-d2f32251185308fbca46873999022bfd"},"doc":{"_id":"13e93448d1256a98a3fa76f889001e53","_rev":"1-d2f32251185308fbca46873999022bfd","date":"2017-06-08T20:47:10Z","value":3}},
{"id":"13e93448d1256a98a3fa76f88900238e","key":"13e93448d1256a98a3fa76f88900238e","value":{"rev":"1-307f1ccd43f10642bddf3f8bf5f4646a"},"doc":{"_id":"13e93448d1256a98a3fa76f88900238e","_rev":"1-307f1ccd43f10642bddf3f8bf5f4646a","date":"2017-06-08T20:47:13Z","value":4}},
{"id":"13e93448d1256a98a3fa76f8890032ae","key":"13e93448d1256a98a3fa76f8890032ae","value":{"rev":"1-47d81b8b99058883550ba27088474e70"},"doc":{"_id":"13e93448d1256a98a3fa76f8890032ae","_rev":"1-47d81b8b99058883550ba27088474e70","date":"2017-06-08T20:47:16Z","value":5}},
{"id":"13e93448d1256a98a3fa76f889003c49","key":"13e93448d1256a98a3fa76f889003c49","value":{"rev":"1-33a785b3a53e9b80f4aedc19f0dc5bc8"},"doc":{"_id":"13e93448d1256a98a3fa76f889003c49","_rev":"1-33a785b3a53e9b80f4aedc19f0dc5bc8","date":"2017-06-08T20:47:19Z","value":6}},
{"id":"13e93448d1256a98a3fa76f889004701","key":"13e93448d1256a98a3fa76f889004701","value":{"rev":"1-63238f12e3b566a2329ef60afbd663e2"},"doc":{"_id":"13e93448d1256a98a3fa76f889004701","_rev":"1-63238f12e3b566a2329ef60afbd663e2","date":"2017-06-08T20:47:22Z","value":7}}
]}

Setup ESP8266

What: Setup a ESP8266 by installing fresh NodeMCU firmware
Why: Update firmware and get cheap Esp’s which come without NodeMCU up and running
How: Use NodeMCU-PyFlasher and Docker to flash Esp, build firmware and put it on the Esp

Install docker

If you have no docker installed already, install it. You can use the script below (execute as root, see here).

apt-get install -y --no-install-recommends apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://apt.dockerproject.org/gpg | sudo apt-key add -
add-apt-repository "deb https://apt.dockerproject.org/repo/ debian-$(lsb_release -cs) main"
apt-get update
apt-get -y install docker-engine

Build the firmware

Clone the NodeMCU firmware from github (see here):

git clone https://github.com/nodemcu/nodemcu-firmware.git

Edit the file app/include/user_modules.h. Here you can enable further modules, for example http-module for http requests. For enabling a module, remove the comment markers at the beginning of the line.

Edit the file app/include/user_config.h and enable ssl. As above, this is done by removing the comment markers at the beginning of the line.

Change to the directory and start docker for NodeMCU build (see here):

sudo docker run --rm -ti -v `pwd`:/opt/nodemcu-firmware marcelstoer/nodemcu-build

You should now have two bin-files (for example nodemcu_float_master_20170228-2105.bin) in the bin-folder: One for the integer version and one for the float version.

Flash the firmware to the ESP

Connect the ESP to the USB port of your computer and start the NodeMCU-PyFlasher. Select the correct serial port (you can find it in the device manager, com ports; USB-SERIAL). Select the image file created above. Select the erase flash option and click on Flash NodeMCU.

It should take some time (approx. 1 min). You should see the message „– verify OK (digest matched)“. Now, you have a freshly installed NodeMCU on the Esp. Enjoy!

Setup Raspberry Pi with WLAN and ssh from start

What: Setup Wlan on a fresh raspberry without ethernet cable
Why: Fast and headless setup while still sitting on the couch
How: Use the latest raspbian image, provide wpa_supplicant.conf and ssh file

Download raspbian image

Download the zipped image file from here. I took the raspbian jessie lite.

Unpack it.

Put the image on a SD card

Use a suitable SD card (mine is 8GB) and format it. You can use SDFormatter on Windows for that.

Afterwards, copy the image file to the card. You can use Win32DiskImager for that.

Setup Wlan and ssh

Go to the SD card drive. There should be a file called cmdline.txt.

Create a new file called wpa_supplicant.conf in the same directory like the cmdline.txt and put the following in (Update: The lines changed between Raspbian Jessie and Stretch, see here):

ctrl_interface=/var/run/wpa_supplicant
network={
    ssid="your-network-ssid-name"
    psk="your-network-password"
}

This step is taken from here.

Since december 2016, ssh is by default disabled in raspbian. To enable it, create a new and empty file called ssh in the same directory like the cmdline.txt. See documentation.

Start the raspberry

Put the SD card into the raspberry and start it. The raspberry should now be visible in your network and you should be able to establish a ssh connection via Wlan. For the first raspberry start it may take some time (3 min. in my case) but for further restarts the raspberry was available via ssh within seconds.