Raspberry Pi Meetup

Last week I was at the 3rd meetup of Raspberry Pi Belgium. I presented my endeavour to monitor utility meters with a Raspberry Pi and Mono, the successes and the failures.

My talk was based on a couple of previous blogposts:

But also an article I have yet to write where I use a DHT22 sensor to monitor humidity and temperature, like every step in this journey it had its challenges.

The other presentation was done by Jan Tielens. He showed us around the IoT hub in Azure.

Slides are available here.

Tracking water usage with Rasbian, Mono and Azure

Although I had this up and running back in March, it took me a while to find some time to write everything down. Here it goes.

Part 1: how does stuff work?

With my .NET application running on the Pi. I now had to see how I could monitor my water usage. Typical water meters in Belgium, or at least where I live, look quite dull but they have everything what’s needed to make them smart.

One way to get automatic readouts is to contact the supplier and let them add a logger but it’s not cheap. Their website is not really helpful but it looks like it will cost more than €100 and then there is a yearly or monthly fee. Not a valid option.

However if you do some research you’ll find info on how these meters work and chances are your meter is outputting a magnetic pulse. In the video below you will see a very nice explanation of it at around 0:35.

With my newfound knowledge I installed the application “Magnetic Detector!” on my iPhone and headed down in the basement while the tap was running and sure enough a sine wave appeared.

sine wave

While doing further research I learned that detecting magnetism can be done with a reed switch or a Hall effect sensor. I chose the first one since the Hall effect sensor would need power all the time and eventually I want to replace the Pi with a tiny board. Basically the reed switch is just like a manually operated switch except it will close whenever a magnet is nearby.

Part 2: Wiring it up

I bought a reed switch for €3 and set everything up. I first tested with a regular magnet to see if everything worked and then placed my setup near my water meter.

schema

The reed switch can be inserted into a cavity of the water meter, apparently it’s really built to accept these kinds of devices.

meter

Part 3: Storing the readouts

With the hard part behind me, I created a free Azure web app and connected it to a free SQL database. Note that you can only create a free SQL database from within an Azure web app, if you go directly to SQL databases you will not find that option.

free database

Since it’s a .NET app I also installed the package Newtonsoft.Json to transfer my pulse counts to the Azure web app. I spent several hours trying to get it working though as I, once again, was faced with a mysterious error.

System.TypeInitializationException: The type initializer for 'Newtonsoft.Json.JsonWriter' threw an exception. ---> System.BadImageFormatException: Could not resolve field token 0x04000493
File name: 'Newtonsoft.Json'
  at Newtonsoft.Json.JsonWriter.BuildStateArray () <0x76860c90 + 0x0009f> in <filename unknown>:0

Don’t know why, but I eventually went looking at the dependencies of Newtonsoft.Json and then explicitly updated my mono installation with the necessary bits from the Debian package list. Everything started working and uploading the pulse was just plain C#.

public void Upload(Tick tick)
{
    using (HttpClient client = new HttpClient())
    {
        client.PostAsync(_apiEndpoint, new StringContent(JsonConvert.SerializeObject(tick), Encoding.UTF8, "application/json")).Wait();
    }
}

My database started filling up and after only one day I could calculate that my showers were consuming 70 liters and the dishwasher 30 liters. Time to cut back on the time spent in the shower!

ticksdb

In order to keep the program running in the background I’m using a program called screen, you can find more info on that in this excellent post.

Part 4: Next steps
I had the Pi running in April, but had some issues with the Wifi. Some days I received no pulses at all and I had to reboot to gain access. Since then, well actually yesterday, I’ve changed to code to keep track of the pulse counts that failed to be uploaded and transfer them at a later time. Next up will be to create a dashboard to view the pulses or add further sensors to monitor gas and electricity.

Getting up and running with Mono and Raspberry Pi 3

Last week I got my hands on a Raspberry Pi and this weekend I finally found some time to sit down and get my first project with a Pi going. Naturally I ran into several issues and with today being Pi day, I thought I’d share my notes.

Last year I started a project with a bunch of colleagues where we try to monitor our gas, water and electricity meter. I’ve presented what we achieved so far at Cloudbrew last year. The aim is to build an IoT solution with a mobile application, cloud backend and lots of devices (Arduino’s and Pi’s for now). I didn’t want to wait on us finishing this to gather readouts from our utility meters so I thought I’d grab a Pi or two and get started. Since we already had figured out how to get the readouts I thought an hour or two would be all I need to put the solution on a Pi.

First thing I did was to download Raspbian Jessie Lite and follow the steps from the official site. Jessie is a headless operating system, since I won’t be connecting a monitor. I’m not choosing Windows 10 IoT for now because the onboard Wifi, a main selling point of the new Pi, is not supported at the time of this writing.

After connecting an ethernet cable and a power supply I used PuTTY to open an SSH session to connect to the Pi. So far so good.

The next task was to get the Wifi going. This turned out to be rather easy. Open “/etc/wpa_supplicant/wpa_supplicant.conf” in your editor and add the SSID and password of the network you want to connect to. Like most of the time, someone else had written down the instructions.

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

blog_pi_wifi_commands

I unplugged the ethernet cable and connected via Wifi. I then updated the Pi with “sudo apt-get update” and “sudo apt-get upgrade” so I was running the latest bits.

sudo apt-get update
sudo apt-get upgrade

Next up, programming. I briefly looked at the options I had. I could program in C, Python, C++, and many others. But time was limited this weekend. I live and breath .NET so I changed the list to .NET Core or Mono. I chose Mono because I had experimented with it years ago and .NET Core has not yet reached a stable point. Toying around with alpha and beta releases was not on my todo list for today.

The default package repository has a very old version of Mono, so you need to follow the instructions on the Mono site. Add the signing key and package repository to your system then run “sudo apt-get install mono-runtime”.

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list
sudo apt-get update
sudo apt-get install mono-runtime

I created a Hello World console application on my Windows 10 laptop and used PSFTP to copy the exe to the Pi. It just worked.

pasted_image_at_2016_03_12_12_57_pm

Then the search was on to find a library to interface with the GPIO pins on the Pi. After looking around I found Raspberry Sharp IO . It had the API I wanted. You can use the event model to track changes in the GPIO pins, just what I needed.

var pin2Sensor = ConnectorPin.P1Pin11.Input();
 
GpioConnection connection = new GpioConnection(pin2Sensor);
connection.PinStatusChanged += (sender, statusArgs) 
                    => Console.WriteLine("Pin changed", statusArgs.Configuration.Name);

Deploying this to the Pi however resulted in catastrophic failure. Some weird error message:

pi@raspberrypi:~/ticktack $ sudo mono TickTackConsole.exe
Missing method .ctor in assembly /home/pi/ticktack/Raspberry.IO.GeneralPurpose.dll, type System.Runtime.CompilerServices.ExtensionAttribute
Can't find custom attr constructor image: /home/pi/ticktack/Raspberry.IO.GeneralPurpose.dll mtoken: 0x0a000014
* Assertion at class.c:5597, condition `!mono_loader_get_last_error ()' not met
 
Stacktrace:
 
 
Native stacktrace:
 
 
Debug info from gdb:
 
[New LWP 1965]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
0x76e67ee8 in __libc_waitpid (Cannot access memory at address 0x1
pid=1966, stat_loc=0x7e904960, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:40
40      ../sysdeps/unix/sysv/linux/waitpid.c: No such file or directory.
  Id   Target Id         Frame
  2    Thread 0x769f3430 (LWP 1965) "mono" 0x76e65a40 in do_futex_wait (isem=isem@entry=0x3181a4) at ../nptl/sysdeps/unix/sysv/linux/sem_wait.c:48
* 1    Thread 0x76f5e000 (LWP 1961) "mono" 0x76e67ee8 in __libc_waitpid (Cannot access memory at address 0x1
pid=1966, stat_loc=0x7e904960, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:40
 
Thread 2 (Thread 0x769f3430 (LWP 1965)):
#0  0x76e65a40 in do_futex_wait (isem=isem@entry=0x3181a4) at ../nptl/sysdeps/unix/sysv/linux/sem_wait.c:48
#1  0x76e65af4 in __new_sem_wait (sem=0x3181a4) at ../nptl/sysdeps/unix/sysv/linux/sem_wait.c:69
#2  0x00219f98 in mono_sem_wait ()
#3  0x0019091c in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
 
Thread 1 (Thread 0x76f5e000 (LWP 1961)):
Cannot access memory at address 0x1
#0  0x76e67ee8 in __libc_waitpid (pid=1966, stat_loc=0x7e904960, options=0) at ../sysdeps/unix/sysv/linux/waitpid.c:40
#1  0x000c0ba4 in ?? ()
Cannot access memory at address 0x1
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
 
=================================================================
Got a SIGABRT while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
=================================================================

Fast forward 4 hours. It turns out installing mono runtime doesn’t quite get you all the bits you need. You need to run the following command:

sudo apt-get install  libmono-system-core4.0-cil

After that the application started again. The button I had connected to the pins activated my code. Yay! With that my time for the weekend was all used up but I’m now ready to be create my actual application.

pasted_image_at_2016_03_12_05_18_pm

To be continued. #MarchIsForMakers