Embedded to machine learning

Setting up a Raspberry Pi sensor environment and teaching myself and the machine with it

kuva

Reading temperatures with Raspberry Pi is a good exercise in electronics for more programmer types. There are many instructions on how to use a DS18B20 1-Wire temperature sensor with Raspberry Pi, but in this post I’ll have some Ansible magic and prettier photos.

Setting up Raspberry Pi devices with Ansible was explained in the previous blog post.

I experimented with this setup the first time following Adafruit’s Raspberry Pi Lesson 11. DS18B20 Temperature Sensing.

Required hardware and software

  1. Raspberry Pi
  2. Ansible and clone of raspberry-ansible repository configured with correct IP addresses and SSH keys
  3. DS18B20 digital temperature sensor (datasheet, Finnish electronics vendor)
  4. 4,7 kΩ or 10 kΩ resistor (Finnish electronics vendor: 4,7 kΩ, 10 kΩ)
  5. Breadboard (Wikipedia, Finnish electronics vendor)
  6. Jumper cables from Raspberry Pi to breadboard: male-female (Finnish electronics vendor)
  7. Jumper cables from and to breadboard: male-male (Finnish electronics vendor)

required parts

Raspberry Pi GPIO

GPIO stands for General Purpose Input/Output. These are ports that you can control with software reading and writing bits to and from external devices. GPIO pins are located in Raspberry’s top left corner in the image above (close to the number 1).

The pinout (i.e. which pin does what) is described in the document GPIO: Raspberry Pi models A and B. Pinout diagram is shown below, with a close-up photo of the pins. Labels P1 and L13 are used for reference to make sure that the pinout isn’t upside down.

GPIO photo

GPIO schema

where 5V and 3V3 stand for +5V and +3,3V DC, GND stands for ground and all yellow boxes with numbers in them are GPIO data pins. The numbering isn’t in any logical order, but the numbers are used for identifying those ports in the software.

A good reference with more detailed explanations for these pins is the Raspberry pinout site.

Making the connections

First of all, Raspberry Pi has to be powered off when making the GPIO connections!

circuit diagram

Circuit diagram is shown in the image above. DS18B20 uses 1-Wire data transfer protocol, and Raspberry Pi driver for 1-Wire uses GPIO port 4, so the sensor’s middle pin has to be connected there.

4,7 or 10 kΩ resistor is used as a pull-up resistor to keep the data line signal level in a valid range.

The part inside the dashed box will be done in breadboard, and connections from breadboard to Raspberry Pi will be done with the longer jumper cables (number 6 in the required hardware list).

Breadboard connections

The breadboard is connected internally so that each of the 5-pin slots are connected to each other (horizontally in the above image) and two connected lines run on each side of the boards (vertically, marked with red and blue in the board).

I added the relevant “hidden” connections to the image above:

  • Ground (GND) comes from Raspberry with the black wire to vertically connected blue line, and is connected from there with a blue jumper wire to the top pin of DS18B20 sensor.
  • Data (DQ) is the yellow wire that is connected to a 4,7 kΩ resistor and the middle pin of DS18B20 sensor.
  • +3,3 V (VDD) is the orange wire that is first connected to the vertical red line, and from there with orange jumper cables to both the other end of the resistor, and to the bottom pin of DS18B20 sensor.

Breadboard and Raspberry GPIO connections

This photo above shows also the connections from breadboard to Raspberry.

Enabling 1-Wire support

The ansible script repository raspberry-ansible has a role and playbook for setting up 1-Wire on the Raspberry Pi device.

It can be run with the following command (assuming you have SSH keys set as explained in the previous blog post):

$ ansible-playbook -i hosts onewire.yml

It will set the Raspberry Pi device tree as w1-gpio, restart the device, load kernel modules w1-gpio and w1-therm, and add them to be loaded on reboot.

Reading temperatures

Finally it’s time to read some sensor data. w1-gpio and w1-therm drivers create filehandles for each DS18B20 sensor in the following path:

pi@raspberry1:~ $ ls /sys/bus/w1/devices/
28-0000075f24dc  w1_bus_master1

All directories starting with 28- are DS18B20 sensors ending with a unique hardware id.

For each of those, you can read the temperature from the file w1_slave:

pi@raspberry1:~ $ cat /sys/bus/w1/devices/28-0000075f24dc/w1_slave
99 01 4b 46 7f ff 07 10 79 : crc=79 YES
99 01 4b 46 7f ff 07 10 79 t=25562

where the number t=25562 is the temperature including three decimal points, i.e. in this case 25,562 °C.

Multiple sensors

As a bonus, adding multiple sensors to the same 1-Wire bus is really easy. Just plug in another DS18B20 with pins connected the same way as the first one and everything just works!

pi@raspberry1:~ $ ls /sys/bus/w1/devices/
28-0000075f24dc  28-0000075f5202  w1_bus_master1
pi@raspberry1:~ $ cat /sys/bus/w1/devices/28-0000075f24dc/w1_slave
9d 01 4b 46 7f ff 03 10 57 : crc=57 YES
9d 01 4b 46 7f ff 03 10 57 t=25812
pi@raspberry1:~ $ cat /sys/bus/w1/devices/28-0000075f5202/w1_slave
a1 01 4b 46 7f ff 0f 10 d9 : crc=d9 YES
a1 01 4b 46 7f ff 0f 10 d9 t=26062

Here we can see that even though the sensors are 2 mm apart, the temperatures are somewhat different. DS18B20 accuracy is ±0,5 °C, so the readings 25,812 °C and 26,062 °C are well within tolerance.

kuva

After installing an image to an SD card, and booting up a Raspberry Pi device with the new operating system, it’s time for the repetitive task of adding users, installing software and configuring it. For one device this might be ok, but what if you have to configure two or ten with the same parameters? And what if you want to change to bigger SD cards with newer operating system image in your tinkering environment?

Ansible to the rescue. It is a tool for configuring and managing computers that runs over an SSH connection and doesn’t require any client software to be installed on the managed computers. It also has a repository for user-made configuration scripts, or roles, called Ansible Galaxy.

Required hardware and software

I have used the Raspbian Jessie lite image on Raspberry Pi 2 model B, but all models and both versions of the Raspbian image should work.

Repository file structure

./bootstrap.yml
./hosts
./keys/
./roles/firewall/
./roles/raspbian_bootstrap/
  • bootstrap.yml is an Ansible playbook that contains instructions about which roles are run on which hosts, and with which variables.
  • hosts has a list of hosts where the configurations are run into.
  • keys is a directory for SSH keys for passwordless access to the Raspberries.
  • roles/firewall contains tasks for setting up firewall.
  • roles/raspbian_bootstrap has lots of tasks for setting up user, hostname, apt, etc. This is a fork of debian_boostrap by Emilien Mantel with minor modifications to suit Raspbian.

Configuring device(s)

The devices are listed in hosts file with the following simple syntax:

raspberry1 ansible_host=192.168.100.37

where first word is the desired hostname for the device (used as an ansible alias and changed to be the device’s hostname). Connection will be made to the IP address given in ansible_host always.

Multiple devices can be listed with each on their own line.

Configuring SSH keys

SSH keys can be generated with for example Atlassian’s instructions. This will give you a private and a public key (id_rsa and id_rsa.pub respectively).

Public key has to be copied to the Raspberry, and these Ansible scripts will do it as long as the file location is correct in bootstrap.yml. Private key is used when connecting to the device: after public key is set up correctly to the device, password authentication is no longer needed and the keys are used instead.

I have used keys generated specifically for this task and put them in this repository’s keys directory, but they can be in your home directory as well. In this case, these configuration parameters in bootstrap.yml have to be changed:

ansible_ssh_private_key_file: "keys/id_rsa"
dbs_ssh_pubkey: "{{ lookup('file', 'keys/id_rsa.pub') }}"

Running the playbook

The playbook is run with the following command:

ansible-playbook -i hosts bootstrap.yml --ask-pass

On the first run to a fresh Raspbian install with no SSH keys configured, it will ask for pi-user password (raspberry by default). Then it will ask to what this password will be changed into:

$ ansible-playbook -i hosts bootstrap.yml --ask-pass
SSH password:
Enter new password for user pi:

PLAY [all] *********************************************************************
...

Testing the changes

After all, there aren’t that many visible changes as these roles will do just basic housekeeping that probably would have been left undone unless it was automated.

Anyways, now you should be able to log in with the SSH key and see the changed hostname for example:

$ ssh pi@192.168.100.37 -i keys/id_rsa
...
pi@raspberry1:~ $

Or you can check for NTP status:

$ ntpq -p
 remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+dsl-kpobrasgw1- .PPS.            1 u  233  256  377   42.722   -2.835   1.288
*ntp2.tdc.fi     .PPS.            1 u   64  256  367   15.933    0.240   1.363
-ns2.posiona.net 192.36.133.17    2 u  190  256  377   15.099    0.149   0.637
+87-92-47-29.bb. 192.36.144.23    2 u  259  256  377   13.248   -0.295   0.683

More interesting configurations in the next post!