Sunday, December 14, 2014

My New System Checklist

I recently had need to create a new Raspbian system for a project and decided to record all the things I did after the system image first boots. Frequently, I forget one or two of these, so this will become a checklist that I follow when I create a new system.

There are many guides to creating a system for the Raspberry Pi and this post is not an attempt to create another. I am putting this here for my own reference as much as to share.  To make it helpful to beginners, I have added some explanations.  You may prefer nano over vi as the file editor.

Please feel free to use the comments section to let people know what customization you like to make for your Pi systems.

Load image as usual
raspi-config runs first time
- expand file system
- Internationalization -> set locale -> TZ = US-Eastern
- Internationalization -> Keyboard = English(US)
- advanced -> hostname (RasPi-##-Purpose)
- advanced -> mem split 16 for GPU
- advanced -> enable SPI and I2C and Serial
reboot, and log in as pi (raspberry)

CPU overclocking would also be set up in raspi-config, but I haven't had any need to do this.

All of the following commands require root privilege.  You can either put sudo before each command or enter sudo -i and run a shell as root.

Create a new user for myself, give it sudoer privilege.
adduser ted 
echo "ted ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers

Update the package database and upgrade all installed packages.
apt-get update 
apt-get upgrade

Install some new packages.
apt-get install samba screen git-core libmysqlclient-dev

Configure Samba (Windows file sharing)
vi /etc/samba/smb.conf
uncomment "socket options = TCP_NODELAY"
delete all shares and add:
[opt]
   comment = opt
   writable = yes
   locking = no
   path = /opt
   public = yes

Restart the Samba service
service samba restart  

Edit the SSH server config.  Turning off DNS reverse lookups will speed up the connection process when to log in through SSH.
vi /etc/ssh/sshd_config
add "UseDNS no"

Edit the netwrok configuration and set static IP address and wifi config.  The interface name for the wifi will be used below in the supplicant file.
vi /etc/network/interfaces
iface eth0 inet static
   address 192.168.0.51
   netmask 255.255.255.0
   gateway 192.168.0.1
   
iface home inet static 
   address 192.168.0.53
   netmask 255.255.255.0
   gateway 192.168.0.1

Edit the wifi supplicant file.  The "id_str" setting connects back to the name used above.
vi /etc/wpa_supplicant/wpa_supplicant.conf
network={
        id_str="home"
        ssid="NOTMYSSID"
        psk="NotMyPassword"
        proto=WPA
        key_mgmt=WPA-PSK
        pairwise=TKIP
        auth_alg=OPEN
}

Install Gordon's WiringPi library.  I use this extensively in my C programming.
cd ~
git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
./build
gpio -v
gpio readall

Edit the kernel module configuration to enable SPI, I2C, and 1-Wire.
vi /etc/modprobe.d/raspi-blacklist.conf
uncomment SPI and I2C devices

vi /etc/modules
add this
# SPI devices  
spi-dev  
# I2C devices  
i2c-dev  
# 1-Wire devices  
w1-gpio  
# 1-Wire thermometer devices  
w1-therm  

Finally, reboot the system again.  Then log on as the new user you created and  remove the default user.
userdel pi

If you don't do this last step and your system is accessible from the internet, then it will not be long (sometimes only hours or minutes) before a hacker finds it and does bad things.  My firewall log shows constant attempts to brute force a login via SSH and "pi" is a common user name that is tried.



Tuesday, December 9, 2014

Wifi Router Case Mod

In my previous post I showed how to use the case from an old LinkSys router as a case for a Raspberry Pi.  Today I decided that it needed a little improvement.  Bring on the blinking lights.  Isn't everything better with blinking lights?

I showed in the posts Server Box with Utilization Displays and CPU and I/O Utilization Display - Details how to use LEDs for a utilization display.  This project is a little smaller scale - only six LEDs instead of twenty.



The circuit is very simple.  The positive lead to each LED is connected to a resistor.  All of the resistors are connected to 5V.  The negative lead of each LED is connected to a GPIO pin.  A low signal on the GPIO pin turns the LED on.

This inverts the logic, but that can be handled in software.  This has the benefit of being able to push more current through the LEDs than would be possible if the GPIO line was connected to the positive lead of the LED.


This PCB layout shows a close approximation of how I made the circuit.  I didn't make a printed circuit board, but I have been designing some for work this week, so I did this drawing using PCB Artist.  I definitely plan to create some PCBs for my Pi hobby, once I decide what to make next.


All the wires are connected directly to a ribbon cable. I created a real power plug while I was at it.

The LED circuit is pushed into the front part of the case and through some holes that I drilled.  It is held in place by friction and a little tape.






My latest Raspberry Pi creation is stacked with the modem and router with all their blinking lights.

Now maybe it will not feel inadequate.



Sunday, December 7, 2014

Raspberry Pi Case From Wifi Router


You have most likely seen one of these somewhere before.

This case style is very common.  If you happen to get your hands on one, you can make a great case for the Raspberry Pi.

(Or, you can re-load the router firmware.  See dd-wrt.org for more information.)

I had two in my huge pile of junk, so I though I'd have some fun. This was literally a ten minute project.


The case pops apart easily, if you know the trick.  Grab the blue front part and pull apart from the rear part.  After that, the top and bottom will come apart. A couple of screws later and you have prime case material.



I drilled two holes to mount the Pi and trimmed the rear opening just a little. It needs a better power connector.














One good thing about these cases, they stack very nicely.

Now to search the pile of junk for a hard drive. There is enough room to add one in this case.













Works Great!



Sunday, November 16, 2014

Debouncing GPIO Input

Reading the state of a GPIO pin is very simple.  There are several methods to do this.  But what if you need to detect a very short pulse on a GPIO line or you need to respond very quickly to a state change without using a lot of the CPU to poll the state of the pin? This is exactly what interrupts are designed for.  I will cover how to use interrupts in a future post.  This post will show you how to deal with a common problem that must be addressed before interrupts will work correctly.

When the contacts of a mechanical switch close, they will almost always bounce a little.  This causes multiple spikes up and down on the connected line until the contact is firmly made.  The result is a series of pulses when a single state change was expected. This is, for obvious reasons, called "bouncing" and must be corrected either with hardware or software.

If that wasn't clear enough, maybe a picture will help. Imagine a push-button connected to a GPIO line. When the button is not pressed, a pull-up resistor holds the GPIO at 3.3 volts so that it reads a value of 1.  When the button is pressed, the line is connected to ground and the GPIO will read 0.  But on closer inspection, something else really happens. As this graph shows, the bouncing of the voltage level causes spurious state changes to the GPIO input. If you use an interrupt to increment a counter when the state changes on the GPIO, then a single button press can result in the counter incrementing two, three, or more times when the programmer is expecting only a single increment.

This can be dealt with in software, but that method tends to be unreliable in many instances. It is much better to correct for the bouncing using a simple hardware circuit.  This is called debouncing and one simple solution is shown below.

By connecting a capacitor as shown here, the result is a "smoothing" of the voltage curve. Before the button is pressed, the capacitor is fully charged and the GPIO will read 1. When the button is pressed, the capacitor will start draining through R2 at a rate determined by the size of the C1 and the R2.  The voltage on the GPIO pin will smoothly curve down from 3.3V to 0V and the GPIO will sense a single state change.

The values for C1 and R2 will determine how quickly the state changes.  If they are too small, then there could still be some bouncing.  If they are too large, then the circuit may respond too slowly for the application needed.  This could result in state changes being missed. You may need to experiment to find the proper values for a specific application. The values shown in this circuit are a good place to start.

A digital circuit that is also commonly used for debouncing is called the set/reset latch and can be constructed from two nand gates. To learn more about this option and everything else you might want to know about debouncing, read this paper.   A Guide to Debouncing

Now that you input is properly debounced, you can go on to using it to reliably drive an interrupt.

Wednesday, October 29, 2014

Improved Home Brewing Controller

This post is an update to my Automated Home Brewing post. See that post for more details on the project. After adding some new features haphazardly, I had an ugly conglomeration of old and new parts. It worked, but it wasn't pretty, and I sure didn't want to show it on this blog. So, I decided to build a whole new interface and include the new items:
  • thermocouple interface for flame detection
  • relay control for refrigerator
  • relay control for heater (these two are used for controlling lagering temperature during fermentation)
  • digital input for counting the bubble rate in the airlock during fermentation.
  • battery level monitor, since I usually run this on a small 12V battery
I also kept all the original controls:
  • relay for propane valve
  • relay for igniter
  • 1-wire bus for multiple temperature inputs
  • relay for circulation pump
The item that I struggled with the most was how to make a reliable flame sensor. This is covered in the Flame Sensor Update post. Note - the drawing for the amplifier circuit in that post has the resistor values reversed. Here is the corrected drawing.

The gain formula for a LM358 non-inverting circuit is

               gain = 1 + R2/R1

In this case, R1 = 1K and R2 = 200K, resulting in a gain of 201. This means that a thermocouple output of 5mv will produce an output of just over 1V. Using a gain of 500 would allow for better resolution of the temperature, but 200 is adequate for this purpose. I don't care about the actual temperature. I just need to see if the value is increasing to verify that the flame actually lighted.





I decided to build the interface on a circuit board that would plug directly into the GPIO pins on the Raspberry Pi and mount it with a Pi permanently in a project box. Here is the completed circuit board, in its enclosure, installed on the Raspberry Pi










Here is the project box with the Pi mounted inside. There are holes cut for the USB, network, and HDMI connections. I like this arrangement a lot and will use it again in the future.












Finally, this is the completed system with all the connectors labelled.








The "bubble detector" input was a last minute addition. I haven't actually built the detector yet but the design is straight forward. It will use an infrared LED and detector (sometimes called an IR gate) to see when a section of the airlock changes from water to air. Water is mostly opaque to IR light.

The pulses from the bubble detector will be very short and difficult to accurately count using a simple polling loop. I expect that it will need to be done using GPIO interrupts. I will post the code when I get that working.

Monitoring the "bubble rate" won't really produce any useful numeric data. It is only good for determining when the fermentation has completed. This is important since fermentation can stop early for various reasons and steps must be taken to correct the problem.

Finally, a warning: Working with flammable gas and boiling liquids can be hazardous. I take no responsibility for your use of the advice provided in this post.
BE CAREFUL!  And drink responsibly.



Monday, April 28, 2014

Flame Sensor Update

This is a follow up to the post on Automated Home Brewing.  There were several good ideas in the comments to that post about how to create a flame sensor.  Some require an analog input, which I describe in this post.  I have experimented now with a few methods for detecting a flame and here is what I found.

Plasma Conductance

Cool Fact - flame is a plasma and will conduct current.  I tried using two wires stuck into the flame.  The flame has a fair amount of resistance.  One of the wires was connected to 5V.  The other was connected to a voltmeter.  There were dozens of mV present when the flame was on and zero when it was not.
I think this could be used with an analog input as a flame sensor.

Thermocouple 

Thermocouple
I got a type K thermocouple and tested that directly with a voltmeter.  It only show a couple of mV with a flame on the tip.  I added a simple 100X amplification circuit and connected that to the analog input.  Now I see a range around 300-400mV and see a clear increase when the flame is on it.  One problem I saw is that the sensor has a fair amount of mass, mostly stainless steel.  Once it heats up, it takes a while for it to cool off.  As long as there is a distinct increase when the flame comes on, this could also be used for the flame sensor.
100X Amplification Circuit for Thermocouple

Digital IR Flame Detector

IR Flame Detector

Sensors are available that detect the IR signature of a flame.  Most of these provide analog output only, but I found some that also include a digital output.  This is provided by a built in level compare circuit with an adjustable level.  Because this method is so simple to interface with, this is what I decided to use.  One big problem quickly became apparent - the sensor is triggered by incandescent lights and sunlight.   It worked fine under florescent lights.




I was successful in using this configuration for brewing.  The IR sensor works, but has the false trigger problem.  It works for me but won't work in many environments.  My plan is to rebuild the brewing interface with analog input capability and try one of the other methods.

IR sensor mounted on a small block of wood and placed under the flame.




Friday, April 25, 2014

Interface to the Internet of Things with SkyNet

The Internet of Things (IoT) refers to the many servers that store data uploaded from various devices (things) connected to the Internet, which can range from weather stations, to home appliances, or a farm animal with a biochip transponder.  Even dancing robotic quad choppers.

There are many services that provide IoT support.  After experimenting with some, I settled on the SkyNet.im IoT server.  It provides several simple ways to allow machine to machine communications, including MQTT, REST, and WebSockets.  There are Python and JavaScript libraries to support it.  The API for SkyNet is fairly simple, as is using the REST protocol.  With the curl utility, you can interface to SkyNet from shell commands.

First you need to install the curl program and since I will also be calling this from a C program, I also need the development support.

sudo apt-get install curl libcurl4-gnutls-dev

To create a new device on Skynet, issue the following command (changing the parameters as you see fit)

curl -X POST -d "type=raspberry-pi-example&myvariable=12345" http://skynet.im/devices

SkyNet returns a UUID and a security token.  Save this info.  The device id is used to identify the new device and the security token allows a little security so that only someone with the token can update the data for this device.  If you really need to maintain security for the device, be sure to always update it using HTTPS.  If you use HTTP, then the session is not encrypted and someone could intercept the token and use it themselves.  Also, be aware that anyone can read your data.

To update the data for the device, issue this command.  (All one line.)

curl -X PUT -d "token=PUT-YOUR-TOKEN-HERE&myvariable=5678online=true" http://skynet.im/devices/PUT-YOUR-UUID-HERE

To view the data for a device, issue this command.

curl –X GET http://skynet.im/devices/PUT-YOUR-UUID-HERE

The function listed below provides a simple interface to SkyNet, in C, using libcurl.