Blog moved to http://www.andrevdm.com/

Tuesday 15 December 2015

CentralConfig

Untitled Document.md

CentralConfig - Multi-machine configuration manager

CentralConfig is available on NuGet, source at https://github.com/andrevdm/CentralConfig

Overview

CentralConfig is a replacement for the built in .net ConfigurationManager. It makes managing multi-machine configurations simple while, from a usability point of view, looking very similar to ConfigurationManager.

Features

  • All config must be able to be stored in version control
  • A way to have config centralised. I.e. you should not have to update the same setting on multiple machines.
  • Support for multiple environments (dev, build, test, prod etc)
  • A sane and simple way of having default values. You should not have to specify the same settings for each machine if a default will work.
  • Override a setting for a particular machine. e.g. one machine in an environment must have a slightly different config.
  • Simple and light weight
  • Support for simple values as well as more complex object types
  • A full replacement for ConfigManager

What about the .net config transformer

The .net transformer does a reasonable job but did not quite do everything I required. The examples below should show some of the differences

Using CentralConfig

Install “CentralConfig” from nuget Unless you have created a custom persistor use the mongo settings persistor Set the central config mongo settings Setup DI

app.settings for the mong persistor

   <appSettings>
     <add key="MongoDB.Server" value="mongodb://localhost:27017" />
     <add key="CentralConfig.MongoDatabase" value="TestConfig" />
   </appSettings>

DI setup

   ObjectFactory.Configure( x =>
   {
       x.For<IEnvironment>().Use<SystemEnvironment>();
       x.For<IConfigPersistor>().Use<MongoDbConfigPersistor>();
   } );

Configure settings in Mongo

   {
       "key" : "TestSetting",
       "machine" : null,
       "value" : "some value"
   }

Use the setting from code

   //ConfigManager.AppSettings["TestSetting"]
   Console.WriteLine( "test: {0}", ConfigManager.AppSettings["TestSetting"] );

Different Persistors

I’ve always used the mongo persistor but you can easily create new persistors as required. To do so implement the IPersistor interface

    public interface IConfigPersistor
    {
        string ReadAppSetting( string key, string machine, long version );
        string ReadAppSetting( string key, string machine );
        string ReadAppSetting( string key, long version );
        string ReadAppSetting( string key );

        TResult GetSection<TResult>( string sectionName, string machine, long version );
        TResult GetSection<TResult>( string sectionName, string machine );
        TResult GetSection<TResult>( string sectionName, long version );
        TResult GetSection<TResult>( string sectionName );
    }

Order of matching

When you request a value, CentralConfig will try find the most specific value it can. So it will first look for the setting match both the key and the current machine name, if that does not match then it looks for a value matching on key only

   {
       "key" : "TestSetting",
       "machine" : null,
       "value" : "some value"
   },
   {
       "key" : "TestSetting",
       "machine" : "MYPC",
       "value" : "another value"
   }

Given the mongo settings above when you request “TestSetting” you will get “another value” if your machine name is MYPC or “some value otherwise”

Monday 12 January 2015

Capturing multiple channels of digital data on a two channel digital oscilloscope

In my last post I showed how I parsed the CSV data to do some basic logic analysis. The problem is that I have a two channel scope and need to capture three channels for SPI (i.e. clock + MOSI + MISO).

As it turns out this can be done without too much fuss by using a digital to analogue (DAC) "resistor ladder". The two options I looked at were the R-2R ladder and the simpler binary weighted ladder. For two levels the binary weighted DAC is the simplest, it just needs two resistors (one double the other one's resistance).

Here is the circuit diagram

So one input goes through the 1k resistor and the other through a 2k resistor and you measure the output. With an DAC with only two levels there is tolerance for some noise on the digital lines.

I'm working at ~3 volts, so the levels I'm going to see are
Voltage D0 D1
0v 0 0
1V 0 1
2V 1 0
3V 1 1


You can clearly see the three levels on the scope when measuring Vout



I kept the clock separate on channel 2 so that I could trigger on it. Here is the clock + data



With only two channels going through the DAC you could reconstruct the two digital data channels by eye. That is not much fun though. So I modified my F# script from the previous post to split the data into two values and then do the logical analysis and print out two channels of data. This proved very useful when using a SPI device that returns data (e.g. SD card). Here is the full F# script also available as a gist.

Logic level parsing Rigol oscilloscope CSV data with F#

I was recently debugging a SPI communication but had no logic analyser. Fortunately my oscilloscope (rigol DS1052e) can export a capture as CSV (I assume that most digital oscilloscopes can export to CSV too).
Parsing the CSV is trivial, getting a logic level from it is also fairly easy. I realise that this is terribly quick & dirty but it worked 100% for what I needed. Here is the high level process
  1. Ignore timings - SPI is clocked so actual timing is irrelevant for this analysis
  2. Parse X and Y channels
  3. Convert clock channel voltage into logic level 1 or 0
  4. Discard all rows apart from rows where the clock goes high
  5. Convert data channel to logic level
  6. Group into bytes
  7. Display hex value

As I said, very simple but it worked well and I was able to see exactly what was going on. Obviously this only works for synchronous (clocked) protocols like SPI/I2C but that is all I needed.

Here is the full F# script (also see the gist)

Monday 5 January 2015

Accurate clock with any frequency oscillator (e.g. embedded PIC projects)

When I created an electric timer using a PIC one of the things I needed was an accurate clock. The PIC I was using did not have a built in real-time clock (RTC) and I did not want to use an external one. After some searching I found two popular suggestions to create an accurate clock
  1. Use a 32.768kHz crystal which divides down perfectly to give you seconds etc
  2. Use any frequency oscillator and manually set the value of the timer register on each interrupt. I.e. to skip some number of cycles
I did not like either of these solutions
  1. 32.768kHz is ridiculously slow compared to the 20-40MHz the PICs can run at
  2. Manually setting the timer register takes some number of clock cycles and this will affect the timing. Working out how many clock cycles exactly sounds like an error prone and rather boring task
Fortunately I found this article "A very versatile Zero Cumulative Error timing system with PIC source code" @ http://www.romanblack.com/one_sec.htm. It shows a really simple way to get an accurate clock, i.e. no accumulating error,using any oscillator frequency. Take a look at the article. It has PIC source code and a nice explanation.
Its a brilliantly simple solution. Here is my attempt to explain it. Perhaps having two different explanations helps.
Imagine you have an oscillator that ticks every 3 units but a clock event that needs to happen every 5 units of time. The key to understanding this is that even though 3 does not go into 5 you can get close without accumulating error.
Consider the first 5 oscillator ticks
  • 3 - less that first time period (5), do nothing
  • 6 - greater that first time period (5), do clock
  • 9 - less that second time period (10), do nothing
  • 12 - greater that second time period (10), do clock
  • 15 - equal to third time period (15), do clock
So at each oscillator tick there is some discrepancy but it does not accumulate. In the example above the clock is 100% accurate every fifteenth oscillation.
With a micro running at many megahertz you can adjust the timer prescale to make this periodic discrepancy as small or large as you like.
In my timer I was happy to be out by a few seconds at any time. Of course you could of course use a smaller prescale value and keep it down to milliseconds if you really need to

Using F# on a Raspberry Pi

This is how I got F# working on a Raspberry Pi. The demo shows how to communicate with a Nokia 5110 LCD (PCD8544). While simple it does show how to use the wiringPi library, GPIO and SPI.

Installing mono

Installing mono on the latest Raspbian is easy. Just run the following Command
   sudo apt-get install mono-complete
That should get everything you need.

Using F#

While there are several tutorials on installing F# on the internet, I've chosen to rather compile the F# code on my main machine and copy the compiled assemblies across. I did this for two reasons
  1. I prefer to work on my main computer, its just faster.
  2. I'm having issues getting the F# compiler to work 100% on the pi, but given point one I've not tried very hard to sort it out.

GPIO from F#

There are several options for accessing the Raspberry PI GPIO ports. I decided to use WiringPi as it seems to be one of the most popular libraries at the moment. There are a few .NET wrappers for WiringPi but I decided to write my own DllImports because its so easy and I can better control how I want the access to work. To get WiringPi working I followed the instructions from http://wiringpi.com/download-and-install/ Once it is installed you will need to create the shared libraries. To do this run
  1. cc -shared wiringPiI2C.o -o libwiringPiI2C.so
  2. cc -shared wiringPiSPI.o -o libwiringPiSPI.so
I'll show you how to use these files shortly.

Nokia 5110 / PCD8544

The Nokia 5110 LCDs are 84x48 pixel LCD screens that are easy to use. There are hundreds of tutorials around so I wont duplicate that effort here. If you want to understand how it works make sure you also look at the datasheet. Wiring will be as follows NB I prefer the GPIO pin numbering over the wiring pi numbering. Remember this when looking at GPIO pin numbers below
LCD Pi
Reset gpio 24 (pin 18)
CE CE0/gpio 8 (pin 10)
DC gpio 23 (pin 16)
DIn MOSI/gpio 10 (pin 19)
CLK SCLK/gpio 11 (pin 23)
Vcc + 3.3v (pin 1)
Light gpio 18 (pin 12)
Gnd ground (pin 6)

Using WiringPi from F#

Using WiringPi from F# is easy enough. Make sure that the two .so (shared libraries) created above are in the same directory as the compiled .exe. Then you can create DllImport statements for the functions that you want to export. As an example here is how to import the "pinMode" function Rather than just using the raw imports, I chose to create a type safe F# wrapper for the imported functions. For example when setting the pin mode I'd like to have an type for the I/O mode so that it can be type checked rather than using an int. Also I want a simple way to specify the pin I'm using that works with the pin number, GPIO number or wiring pi standard numbering. Here is the full code that does all of that A few things to note
  • The DllImport is in a private module.
  • I've created F# wrappers for the imports that use strongly typed parameters
  • I've only defined a few of the pins, enough for this demo

SPI

(See spi.fs)
For the PSI imports I defined a few F# wrapper methods that make working with SPI easier. Remember that SPI is full-duplex so however many bytes you write you will get the same number of bytes returned. However quite often you don't care about the return values, e.g. with the LCD code. So I've created a function that does a write and a read (spiWR) and one that "only writes" (spiW) i.e. ignores the result.

The LCD code

For the LCD I wanted to have the following * Communication using hardware SPI using the wrappers defined above * Reasonably efficient, e.g. send multi-byte commands/data in a singe DC/SPI "session" * A simple interface that hides all of this detail Since you may want to wire the LCD different for different projects the pins used must be configurable. To allow for this there is a lcdConfig record that must be passed to each LCD function containing the required settings. This also documents in code how the LCD should be wired. When you start using the LCD you need to created an instance of this record and call lcdInit. lcdInit will initialise the SPI hardware and send all the required LCD initialisation commands. Remember that to communicate with the LCD you first need to set DC high for data or low for a command. For example lcdGoto lcdGoto, sends two commands (DC is low for both). The first command 0x40+row sets the row. The second 0x80+col sets the column Here is the full code

Using the wrappers

Once all the wrappers are defined the code to interface with the LCD is simple. This demo displays the date and time and updates it every second for ~1 minute,

Compiling the code and copying to the pi

To build and copy the code to the pi I use the following bash script, which assumes the pi is on IP 192.168.0.73
#!/bin/sh
fsharpc --out:lcdDemo.exe --target:exe --debug+ --debug:full --tailcalls+ --optimize font.fs wipiInit.fs gpio.fs spi.fs lcd.fs lcdDemo.fs && scp -r lcdDemo* pi@192.168.0.73:~/prog/fs/wiringPi_5110_Basic/
Make sure you pi a running SSHd. Configuring SSH to allow login using your private key is also a good idea as it means you don't need to type your password each time you build the code. The sample also contains a Visual Studio solution should you be using Visual Studio or MonoDevelop etc. Make sure you copy FSharp.Core.dll and the two .so shared wiringPi libraries discussed above across to the pi in the same directory as the compiled .exe before your first run.

Thats it

Overall getting F# working was pretty simple. The performance is great, startup time is fantastic (the JVM was terrible :( ). I hope this helps get you started. Overall I'm really impressed with how well it all works The full code for this demo can be found here: https://github.com/andrevdm/PiPcd8544Demo