RSS

Posts Tagged ‘Netduino’

74HC595 Shift Registers

Monday, May 30th, 2011

The 7400 family of chips have for many years provided a set chips which implement common logic functions. The 74HC595 is a member of this family and provides an eight bit serial-in, parallel-out shift register. This register also provides a pin which can be used to cascade these chips providing a longer sequence of bits if required. In this post we will look at this chip and implement a C# class which can be used to set / reset individual bits in a series of cascaded shift registers. This is very much a software engineers view on how to access a shift register.

74HC595

Those of you who are familiar with the principles and operations of a shift register can skip the next section and move on the the implementation.

Shift Register Overview

A shift register in its simplest form is a series of bits. Data is shifted into the register using serial communication on bit at a time. Each time a bit is pushed into the shift register it moves all those to the right of it one place to the right with the bit at the end being discarded. For example, consider the following four bit register:

b3b2b1b0
1000

Adding a new bit with the value 0 results in the following:

b3b2b1b0Discarded
01000

The 74HC595 has an additional pin which allows the output of the discarded bit. By feeding this discarded bit into another 75HC595 you can build up a chain of cascaded chips to make a larger shift register.

Hardware

A simple LED driver is used to illustrate the hardware and software principles used. The hardware will use two 74HC595’s (although it is possible to use more) to drive a bank of LEDs (one per output for each chip). The bill of materials becomes:

ItemQuantityNotes
74HC5952
LEDs16One for each output pin on the 74HC595’s.
47 Ohm Resistor1
Netduino Plus1
WireLots of itYou really will need lot of it.

The LEDs are really there just to give an instant visual interpretation of the output from the shift registers and to prove the software is working. The way they are wired up and the resistor used to limit the current means that the more LEDs are powered, the dimmer they will be. The wiring looks something like this:

Shift Register Cascade

Shift Register Cascade

Looking at the diagram, the wiring seems confusing. The green wires show the wiring of the LEDs to the outputs of the shift registers. The outputs of the shift register should be wired to the LEDs from right to left in the order QA through QH. This is probably the most confusing part of the diagram due to the number of connections but these all follow the simple principle of wiring the output from the chip to the LED and then through to ground.

If we throw away the green connections then we have a few key connections:

  1. SI on the left most shift register (pin 14) should be connected to MOSI on the Netduino.
  2. SCK on the left most shift register (pin 11) should be connected to SPCK on the Netduino
  3. /G on the left shift register (pin 13) should be connected to the latch pin on the Netduino
  4. RCK on the left shift register (pin 12) should be connected to ground

When cascading the registers the following connections should be made for the registers to the right of the first register:

  1. Serial Out (pin 9) of the left chip to SI (pin 14) of the right chip
  2. SCK of both chips (pin 11) should be connected
  3. /G on both chips (pin 13) should be connected

The data is fed into the shift registers from the left with bit 0 appearing on the far right. The clock and the enable is fed into both chips at the same time. The serial data is fed into the chip on the far left and is cascaded on to the chip to it’s immediate right. Further chips can be added to the right and cascaded in the same manner. In this way, bit 0 will always be at the far right of the shift registers.

Software

The software used the SPI interface on the Netduino to communicate with the shift registers. An important note in the documentation is that the chip has a two stage process for transferring the data from the input to the output. Each bit is transferred into the shift register on the rising edge of the clock pulse. This is then transferred on to the output on the following rising edge. This is fine for all but the last bit as it will need a rising edge in order to be transferred to the output. Standard SPI has the idle clock set to low. As such this could lead to the final bit not being transferred to the output. In order to overcome this the SPI interface was set to the idle clock being high. The final transition from an active clock to an idle clock will then trigger the transfer of the final bit from the input to the output.

From a software engineers point of view a shift register is nothing more than an array of boolean values and this is the approach that was taken. The software holds an array of boolean values (multiples of 8 bits as the shift registers targeted are 8 bit registers). The software holds an array of values which the programmer can then choose to output to the registers.

The variable declarations become:

/// <summary>
/// Array containing the bits to be output to the shift register.
/// </summary>
private bool[] _bits;

/// <summary>
/// Number of chips required to implement this ShiftRegister.
/// </summary>
private int _numberOfChips;

/// <summary>
/// SPI interface used to communicate with the shift registers.
/// </summary>
private SPI _spi;
The variable holding the number of chips is used to help the runtime performance by not having to recalculate the number of chips on each transfer to the hardware.

The constructor for the class instantiates the array holding the number of bits in the shift register and the SPI interface:

public ShiftRegister(int bits, Cpu.Pin latchPin = Cpu.Pin.GPIO_Pin8, SPI.SPI_module spiModule = SPI.SPI_module.SPI1, uint speedKHz = 10)
{
    if ((bits > 0) && ((bits % 8 ) == 0))
    {
        _bits = new bool[bits];
        _numberOfChips = bits / 8;
        for (int index = 0; index < bits; index++)
        {
            _bits[index] = false;
        }

        SPI.Configuration config;

        config = new SPI.Configuration(SPI_mod: spiModule, ChipSelect_Port: latchPin, ChipSelect_ActiveState: false, ChipSelect_SetupTime: 0, ChipSelect_HoldTime: 0,  Clock_IdleState: true, Clock_Edge: false, Clock_RateKHz: speedKHz);

        _spi = new SPI(config);
    }
    else
    {
        throw new ArgumentOutOfRangeException("ShiftRegister: Size must be greater than zero and a multiple of 8 bits");
    }
}

A little bit operator overloading on the indexer allows the programmer to address the individual bit in the shift register:

/// <summary>
/// Overload the index operator to allow the user to get/set a particular 
/// bit in the shift register.
/// </summary>
/// <param name="bit">Bit number to get/set.</param>
/// <returns>Value in the specified bit.</returns>
public bool this[int bit]
{
    get
    {
        if ((bit >= 0) && (bit < _bits.Length))
        {
            return (_bits[bit]);
        }
        throw new IndexOutOfRangeException("ShiftRegister: Bit index out of range.");
    }
    set
    {
        if ((bit >= 0) && (bit < _bits.Length))
        {
            _bits[bit] = value;
        }
        else
        {
            throw new IndexOutOfRangeException("ShiftRegister: Bit index out of range.");
        }
    }
}

The final piece of the jigsaw is to allow the programmer to send the data to the shift register:

/// <summary>
/// Send the data to the SPI interface.
/// </summary>
public void LatchData()
{
    byte[] data = new byte[_numberOfChips];

    for (int chip = 0; chip < _numberOfChips; chip++)
    {
        data[chip] = 0;
        byte bitValue = 1;
        int offset = chip * 8;
        for (int bit = 0; bit < 8; bit++)
        {
            if (_bits[offset + bit])
            {
                data[chip] |= bitValue;
            }
            bitValue <<= 1;
        }
    }
    _spi.Write(data);
}

This method is really the work horse as it converts the bits into an array of bytes which are transferred to the shift registers.

Testing it Out

Testing should be easy, lets walk through all of the bits for a 16 bit register made by having two shift register connected together:

public static void Main()
{
    ShiftRegister shiftRegister = new ShiftRegister(16, Pins.GPIO_PIN_D9);
    while (true)
    {
        for (int index = 0; index < 16; index++)
        {
            shiftRegister[index] = true;
            shiftRegister.LatchData();
            Thread.Sleep(100);
            shiftRegister[index] = false;
        }
    }
}

This example uses two registers (16 bits) and uses pin D9 as the enable pin for the register. The code sets, displays and then resets each bit starting at bit 0 through to bit 15.

The full code for the shift register class can be found here (ShiftRegister.zip).

Windows Application Communicating with Netduino Over USB

Saturday, May 28th, 2011

Whilst the Netduino Plus has the advantage of being able to communicate with a PC by networking, the Netduino and the Netduino Mini do not have this capability built in. The simplest way of communicating with these two devices is probably by a serial connection. Both of these devices differ in the capabilities, one has two TTL COM ports whilst the other (the Netduino Mini) has a RS232 COM port and a TTL COM port.

This article discusses the connection using the TTL COM port to a PC using a USB connection. This is applicable to the Netduino, the Netduino Plus and the Netduino Mini.

USB Connection

Before we can start to write any software we need to make the physical connection. There are a few options available, a breakout board which converts the USB connection into a serial connection or a cable which has the conversion hardware built in. I went for the later option as this seemed simpler. The cable I purchased was the FTDI 5V VCC 3.3V IO cable. Plugging this cable into the PC installed new drivers (on Windows 7) and created a new COM port for me.

Connecting the cable was simple, The ground on the cable connected to the ground on the Netduino. The Tx and Rx connections needed to be crossed. So Rx on the cable went to the Netduino digital pin 1 and Tx on the cable connected to Netduino digital pin 0.

Software

This solution requires two projects, a Windows Forms application and a Netduino application.

Windows Form Application

This application will simply send commands in the form of lines of text down the serial port to the Netduino. Each command will terminate with a r character. This application is simple and mimics sending a command to turn an LED on or off.The application looks like this:

Windows Serial Interface

Windows Serial Interface

Clicking the LED On button sends the string LED=1 down the serial line to the listening device. Similarly, clicking on LED Off button sends the command LED=0 to the device.

The code to achieve this is trivial and there are only three parts, the first is to create the connection (see MainForm_Load) and the second and third parts send the command to the device (see btnLEDOn_Click and btnLEDOff_Click).

/// <summary>
/// Initialise the application.
/// </summary>
private void MainForm_Load(object sender, EventArgs e)
{
	com6 = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
	com6.Open();
}

/// <summary>
/// Send a command to the device listening on the com port.
/// </summary>
private void btnLEDOn_Click(object sender, EventArgs e)
{
	com6.Write("LED=1\r");
}

/// <summary>
/// Send a command to turn the LED off.
/// </summary>
private void btnLEDOff_Click(object sender, EventArgs e)
{
	com6.Write("LED=0\r");
}

Netduino Application

The Netduino application is a little more complex as it has to listen to the serial port and assemble a buffer containing the commands being received. The achieve this I abstracted the serial port processing into a separate class. This class took care of listening to the serial port and building up a beffer. The class then provided a way of reading a line of text from the buffer and presenting this to the caller as a single entity. The main code for this is contained in the class CommPort and can be found in the SerialComms.cs file in the attached project.

The main program loop becomes a simple affair and looks like this:

public static void Main()
{
    CommPort port = new CommPort(SerialPorts.COM1, BaudRate.Baudrate9600, Parity.None, 8, StopBits.One);
    while (true)
    {
        string text = port.ReadLine();
        if (text.Length != 0)
        {
            Debug.Print("Command: " + text);
        }
        Thread.Sleep(1000);
    }
}

To run the code I compiled the Windows Form application and then navigated (using Windows explorer) to the directory containing the executable. Double clicking on this started the application and opened the COM port. Next I deployed the Netduino application to the Netduino and with the debugger attched I clicked on the LED On button in the Windows application. A short time later the text Command: LED=1 appeared in the debug window.

The code for this project can be found here (WinFormSerialExample.zip).

Netduino and Bluetooth (RN-42)

Sunday, April 24th, 2011

After many a hour playing (and swearing) I think I have now managed to get the Netduino talking to a Bluetooth module in command mode. There were many teething problems along the way but I think the source code which is attached along with the notes should allow the reconfiguration/control of the Bluetooth module from the Netduino.

Objective

There were two objectives for this project, namely

  1. Allow a PC to send data to the Netduino over a Bluetooth device
  2. Provide a mechanism for the Netduino to reconfigure a Bluetooth device

This is a mainly software project as the connections are straightforward.

The Hardware

The Bluetooth module chosen was a Roving Networks RN-42. This device can be found on a breakout board on several hardware sites (Proto-Pic or Sparkfun) and provides a simple COM connection to the Netduino.

Wiring up the module was simple, only six connections to worry about 🙂

  1. CTS and RTS – connect these together.
  2. Vcc – connect to 3.3V
  3. GND – connect to ground (make sure this is connected to the ground on the Netduino as well)
  4. TX – connect to RX on the Netduino (I was using COM1 so connect to RX on the Netduino – Digital pin 1)
  5. RX – connect to TX on the Netduino (I was using COM1 so connect to TX on the Netduino – Digital pin 0)

There were a few teething problems along the way. The major issue was that at the time I was not able to get access to the correct documentation for the module. A little persistence and I finally had it.

So the first task was to get the module talking to my PC. Powering on the module and then getting my PC to search for Bluetooth device was simple. The PC found the device and paired without much fuss. I opened PuTTY and set the COM port parameters and I was talking to the module.

This is where it started to get interesting (i.e. frustrating) as I had missed a crucial part of the documentation. In order to enter command mode you must enter the command string within 60 seconds of the module being powered up. Once I had this figured it was a doddle. PuTTY allowed me to enter commands and displayed the responses.

So at this point I knew I had a working Bluetooth module and it could connect to the the PC in both data and command mode.

Software

The next problem was to bring the module under the control of the Netduino. This required the a few design decisions. The module can return both single and multi-line responses to commands.

The simplest problem was the single line response. The system simply looped until a line of data was returned.

For the multi-line response it was necessary to allow the system some processing time. The approach taken was to allow the user to specify a wait time. This would allow the Bluetooth module to fill the buffer with response to the command. This puts the Netduino to sleep far a while. Again, this was considered acceptable as the system would be configuring the Bluetooth module – i.e. a startup overhead rather than a run-time overhead.

Usage

The library is pretty simply to use with the constructor taking the parameters needed to create a new instance of the class and connect it to the Bluetooth module and the few remaining public methods allowing the user to talk to the module.

Constructor

The public constructor takes five parameters which essentially allow the class to configure the serial port used to communicate with the module.

public RovingNetworks(string port, BaudRate baudRate, Parity parity, int dataBits, StopBits stopBits)

EnterCommandMode

This method switches the module into command mode. It must be called within 60 seconds (if using default configuration) of the module being turned on.

ExitCommandMode

This method returns the module to data mode.

This methods has two variants. The first is used for simple commands and returns a single string which is the one line response from the module. The second is for more verbose commands where more than one line is returned from the module.

For the majority of commands only one line of test is returned and so the simple one line method can be used. This will loop until a response has been received by the system. This response is then returned to the user.

public string SendCommand(string command)
{
    string result;

    ClearBuffer();
    _bluetoothModule.Write(Encoding.UTF8.GetBytes(command), 0, command.Length);
    result = ReadLine();
    while (result == "")
    {
        result = ReadLine();
    }
    return (result);
}

The second method assumes a multi-line response from the command. In order to collect these responses together the system pauses a while. It is important that this pause is long enough for the module to process the command and generate the response but not too long as this will block the thread for the specified timeout period.

public ArrayList SendCommand(string command, int timeout)
{
    ArrayList result;
    string line;

    ClearBuffer();
    result = new ArrayList();
    _bluetoothModule.Write(Encoding.UTF8.GetBytes(command), 0, command.Length);
    Thread.Sleep(timeout);
    line = ReadLine();
    while (line != "")
    {
        result.Add(line);
        line = ReadLine();
    }
    return (result);
}

Example

The following small program shows the execution of a single command which returns some configuration information for the module.

RovingNetworks rn42;

rn42 = new RovingNetworks(Serial.COM1, BaudRate.Baudrate115200, Parity.None, 8, StopBits.One);
if (rn42.EnterCommandMode())
{
    Debug.Print("Success");
    ArrayList result = rn42.SendCommand("Drn", 500);
    foreach (string str in result)
    {
        Debug.Print(str);
    }
    Thread.Sleep(Timeout.Infinite);
}
else
{
    Debug.Print("Oh dear...");
}

The code is available RN 42 Bluetooth Source Code There’s not a lot of it and it’s reasonably well commented so we’ll call it a day.

Edit (25th April 2011): Implemented IDispose and updated the source code.

4 Digit, 7 Segment Display – Part 2 – Ouput an Unsigned Short

Tuesday, March 15th, 2011

Update 18 March 2011: This is where this series of posts finishes for the minute as I appear to have fried the MAX7219 (or something else is wrong with the setup) as I can send commands to it but the output does not make any sense. I’ll have to return to this series when I have a new chip.

This is the second in a series of posts discussing the MAX7219 LED driver chip being used to drive a four digit, seven segment LED display. The series is made up of the following posts:

  1. Part 1 – Output a Byte
    Output a series of bytes from the Netduino Plus using the SPI protocol
  2. Part 2 – Output an Unsigned Short (This Post)
    Similar to the first post but this time we will write a series of short integers using SPI. This will also start to implement the code which will write the data to the MAX7219 chip.
  3. Part 3 – Displaying Numbers
    Using the MAX7219 class to display a number on the display
  4. Part 4 – Displaying Sensor Data
    Hooking up a sensor to the Netduino and displaying the reading from the sensor.

Objective

The objective of this post is to start to flesh out the code (which will be presented in the final post) to start to send commands in the form of 16 bit unsigned shorts to the MAX7219.

All of the hardware remains as before and only the software changes. As before, the logic analyser is used to verify the results.

Software

The software required a minor update to convert the output to an array of ushorts and put the register in the msb and the data in the lsb.

Results

The main program does little more that send two commands to the logic analyser, namely a command to enter normal operation followed by a command to restrict the number of digits to four.

The results can be seen here:

This image shows the command to restrict the display to four digits being sent over the SPI bus.

The next step is to complete the wiring and to start to send display data to the MAX7219.

4 Digit, 7 Segment Display – Part 1 – Ouput a Byte

Tuesday, March 15th, 2011

Update 18 March 2011: This is where this series of posts finishes for the minute as I appear to have fried the MAX7219 (or something else is wrong with the setup) as I can send commands to it but the output does not make any sense. I’ll have to return to this series when I have a new chip 🙁

This series of posts will discuss using the MAX7219 LED driver chip to drive a four digit, seven segment LED display. The series is made up of the following posts:

  1. Part 1 – Output a Byte (This Post)
    Output a series of bytes from the Netduino Plus using the SPI protocol
  2. Part 2 – Output an Unsigned Short
    Similar to the first post but this time we will write a series of short integers using SPI. This will also start to implement the class which will write the data to the MAX7219 chip.
  3. Part 3 – Displaying Numbers
    Using the MAX7219 class to display a number on the display
  4. Part 4 – Displaying Sensor Data
    Hooking up a sensor to the Netduino and displaying the reading from the sensor.

Background Reading

The following posts provide some background information as these are similar projects:

Objective

The objective of these post is to connect the Netduino Plus to the breadboard and get a 5V logic signal representing a series of bytes. In order to do this it is necessary to convert the output from the Netduino Plus from 3.3V to 5V. I propose to experiment and use a 7408 quad 2 input AND gate to convert the 3.3V signal up to 5V. So for this post we will need the following components:

  1. Netduino Plus
  2. 1 x 74HCT08N quad 2 input AND gate
  3. Breadboard with 5V power supplied to the power rails
  4. Wire to connect the components

Theory

Part of this exercise is to see if we can convert a 3.3V signal into a 5V signal. This is necessary as the MAX7219 uses 5V inputs. The quad input AND gate was chosen to do this for no other reason than I had a few spare in the component box. The data sheet for this chip states that the minimum voltage for a high input is 3.15V when the chip is supplied with 4.5V. A quick experiment shows that a 3.3V input signal to this chip does indeed result in a high output.

So by connecting one of the inputs to the AND gate to 5V and the second to the signal source, then the output from the gate should reflect the input but translated from 3.3V to 5V.

One point to note is that the chip will take a little while for the signal on the inputs to be reflected on the output pins. This application will be running at a low frequency (10KHz) and so the chip should be able to keep up.

Software

The software is a simple starter program which cycles through the bytes from 0 to 255 and output’s these bytes on the SPI bus. The Saleae logic analyser is used to verify that the data is being output correctly. A small test program should demonstrate that the data is being transmitted on the bus correctly:

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoPlus;

namespace NetduinoPlusTestApplication
{
    public class Program
    {
        public static void Main()
        {
            SPI.Configuration config;
            SPI spi;
            byte[] b;

            config = new SPI.Configuration(Pins.GPIO_PIN_D10, false, 0, 0, false, false, 10, SPI.SPI_module.SPI1);
            spi = new SPI(config);
            b = new byte[1];

            while (true)
            {
                for (byte v = 0; v <= 255; v++)
                {
                    b[0] = v;
                    spi.Write(b);
                    Thread.Sleep(20);
                }
            }
        }
    }
}

Hardware

The following table shows how the Netduino Plus is connected to the 74HCT08N

74HCT08NConnection
2, 5, 10, 13, 14+5V
7Ground
12Netduino Plus digital pin 10 (used for CS)
1Netduino Plus digital pin 11 (MOSI)
4Netduino Plus digital pin 13 (Clock)

The ground on the Netduino Plus should also be connected to the ground on the breadboard.

Results

After completing the wiring the logic analyser was hooked up and the following trace appeared:

Scrolling through the trace show each of the ASCII characters being interpreted correctly.

So the next step it to start to build the class which will talk to the MAX7219.

NE555 Calculator and Data Logger

Saturday, March 5th, 2011

A while ago I wrote about my renewed relationship with the NE555 when I produced a simple astable circuit. The experience of trying to work out the values lead me to think about writing a calculator application. This lead me to wonder how I could validate the results given that I do not have an oscilloscope – simple add a data logger to the Netduino and use that. The following shows how I did it and provides some information about how the code works.

Objective

Write application which provides the functionality:

  1. Given a set of components and/or the frequency of the circuit calculate the missing value for the components or frequency
  2. Present the results to the user
  3. Capture data on the Netduino on one of the analog pins
  4. Transfer the data from the Netduino and plot the results

This will require two applications, one to interact with the user and perform the calculations and data plotting and one application to capture the data on the Netduino.

Netduino Application

This application is an extension to the Silverlight application which I documented here. This has the core functionality required to allow the Netduino Plus to communicate with a Silverlight application. A few slight changes were required, namely:

  1. Make the web server understand the commands which would be issued by the Silverlight application
  2. Implement a data logger.

For the first of the changes we simply need to add some additional variables to store the configuration and modify the ProcessCommand method. The system uses the Command.html special file (as before) to receive commands/requests from the user. The valid actions implemented are as follows:

ActionParametersDescription
tTest the connection. This simply returns a Hello string to the calling application.
gGet the preconfigured file and send this back to the caller.
cSampleRate and FileNameConfigure the Netduino data logger. The system will configure the Netduino to log data every SampleRate milliseconds and store the results in the specified file.

The last part of the change to the web server is to provide a mechanism to communicate the change to the data logging component. This done using an event as the data logger and the web server are executing in different threads.

The next change required is to implement the data logging functionality. The data logging runs in the main thread. The on board switch was used to trigger data collection rather than having the Netduino log data permanently. The on board LED was also used to indicate if the board is collecting data. A Timer was used to trigger the collection of data from the analog pin. This meant that the board can capture at most 1000 samples per second.

private static void onBoardButton_OnInterrupt(uint data1, uint data2, DateTime time)
{
    if (data2 == 0)
    {
        if (_logging)
        {
            _timer = null;
            _onBoardLED.Write(false);
            _logging = false;
        }
        else
        {
            using (TextWriter tw = new StreamWriter(@"SD" + _fileName, false))
            {
                tw.WriteLine("Ticks,Data");
                tw.Close();
            }
            _startTime = Utility.GetMachineTime().Ticks;
            _timer = new Timer(new TimerCallback(CollectData), null, 0, _sampleRate);
            _onBoardLED.Write(true);
            _logging = true;
        }
    }
}

This code is tied to the on board switches interrupt. It starts and stops the logging depending upon the current state. A logging start request opens the specified file and puts the header into the file. This effectively deletes and results already stored in the file. The timer is created and tied to the CollectData callback. This callback simply reads the pin and writes the number of ticks since the start of the logging session along with the reading from the pin.

private static void CollectData(object o)
{
    string data;

    data = Utility.GetMachineTime().Ticks - _startTime + "," + _analogInput.Read();
    using (TextWriter tw = new StreamWriter(@"SD" + _fileName, true))
    {
        tw.WriteLine(data);
        tw.Close();
    }
}

Silverlight Application

This is where the project began to take on a life of it’s own. The code discussed here consumed the majority of the time spent on the project. The code is fairly well commented and so the main features will be discussed here.

The project uses MVVM to implement a calculator for the NE555. This results in little code in the code behind for the main page. What code there is simply creates a new instance of the View Model class and calls methods in the class when buttons on the interface are clicked. The remaining communication is achieved using data binding in Silverlight.

The calculator can be used to calculate one of the following (given the remaining three values):

  • R1
  • R2
  • C1
  • F

The system takes three of the specified values and calculates the remaining. The values for the components can come from three sources, a standard component, a user specified value or a range of values.

If single component values are used (either standard components or user values) then a single result set is generated. If a range of values are selected for one or more of the components then the system will generate a table of values with one line for each of the requested values.

So much for discussing the application, it is probably just as easy to try the application which can be found here.

The first tab (Parameters on the application collects the parameters for the calculations and allows the user to request that the results are calculated.

NE555 Calculator

NE555 Calculator

The next tab (Results) presents the results of the calculation.

The final tab (Netduino) allows the application to communicate with a Netduino Plus.

NE555DataLogger

Although the Silverlight application is hosted on my web site, you can still use this to communicate with your Netduino Plus if it is connected to your network.

Results

The resulting application is more or less complete. There are a few things which could be done to make it more robust or more useful, namely:

  1. Add data validation to the properties in the NE555Calculator class.
  2. Make the data logger work with multiple files.
  3. Allow the configuration of the pin used to collect data.
  4. Use the date and time to record when the sample was taken
  5. Collect multiple samples at the same time
  6. Allow the user to enter the reference voltage and scale the data items plotted accordingly
  7. Convert the ticks into milliseconds

These are left as an exercise for the reader.

Source Files

The source files for this project can be found here:

SimpleWebServer.zip

Astable NE555 Silverlight Calculator

As usual, these sources are provided as is and without warranty. They are used at your own risk.

Setting This Up

The Silverlight application can be run from a web site or from Visual Studio. The web server needs a little more than just running the project on the Netduino. You will also have to place the clientaccess.xml policy file on the SD card as Silverlight requests this file in order to determine if it allowed to talk to the web server.

Analog Input

Saturday, February 12th, 2011

The aim of this experiment was to test the analog input.  The simplest way I could think of to do this is to hook up a potentiometer to one of the analog pins and then display the values using the debugger.

First task is to wire up the board.  The final wiring looked like this:

I say final wiring as my initial version looked a little different.  The first version did not have the 3.3V output connected to Aref and as a result I found myself getting very odd results from the analog input pin.

The code to read data from the Netduino looks like the following:

public static void Main()
{
    AnalogInput analog;

    analog = new AnalogInput(Pins.GPIO_PIN_A1);
    analog.SetRange(0, 1023);
    while (true)
    {
        Debug.Print(analog.Read().ToString());
        Thread.Sleep(1000);
    }
}

Running the application and turning the potentiometer results in a range of values from 0 to 1023.

RGB LED and PWM

Saturday, February 12th, 2011

Lots of abbreviations in this post but the aim is simple. Going back to working with LEDs, the idea is to control a RGB LED using the Netduino. The LED I have purchased is a common cathode LED the details of which can be found here.

The LED can be used either as a status display (using each of the three colours for a different status) or the three colours can be mixed to provide mixed colour output. This entry describes how to use the Netduino to provide a mixed colour output using PWM.

Wiring Up The Circuit

The LED is a common cathode LED with three anodes, one for each colour (Red, Green and Blue). This will require three pins on the Netduino in order to control the changing colours. Each of the three pins will require a current limiting resistor in order to ensure that we don’t try to draw too much current from the Netduino and burn out the pins. A quick application of Ohms law to ensure that we do not try and draw more than 8mA gave the following nearest equivalent resistors:

ColourVoltageResistor
Red2V220 ohms
Green3.2V20 ohms (2 x 10 ohms)
Blue3.2V20 ohms (2 x 10 ohms)

The next step is to hook up the LED to the Netduino. This is done using three of the four PWM pins on the board. By using PWM we can vary the power supplied to each of the three pins on the LED. This will allow control of the amount of each colour generated which in turn will determine the colour of the LED. The image below shows the circuit set up on breadboard:

Software

The software uses PWM to control the power supplied to the LED. I found two articles which helped in understanding how this works, the first on Wikipedia and the second by Philip on the Netduino forums. The basic principle is that by varying the amount of time a pin is powered we can change the average power supplied by the pin. The following code show how this can be achieved using three of the Netduino’s PWM pins:

public static void Main()
{
    PWM red;
    PWM green;
    PWM blue;

    red = new PWM(Pins.GPIO_PIN_D6);
    blue = new PWM(Pins.GPIO_PIN_D5);
    green = new PWM(Pins.GPIO_PIN_D9);

    while (true)
    {
        for (uint redDuration = 0; redDuration < 4000; redDuration += 1000)
        {
            red.SetPulse(10000, redDuration);
            for (uint greenDuration = 0; greenDuration < 4000; greenDuration += 1000)
            {
                green.SetPulse(10000, greenDuration);
                for (uint blueDuration = 0; blueDuration < 4000; blueDuration += 1000)
                {
                    blue.SetPulse(10000, blueDuration);
                    Thread.Sleep(200);
                }
            }
        }
    }
}

The program simply cycles through a series of values for each of the selected pins and changes the amount of time each pin is active. The result is a LED which constantly changes colour.

Silverlight on the Netduino

Tuesday, February 1st, 2011

Having been working with the Netduino Plus for a few week I wanted to look at the possibility of using the network to communicate with the board. Having browsed the forums on the Netduino home page I found a few discussions about using this board as a web server including using a WiFly board to hook up to a wireless network. The SDK also comes with several examples of network programming with the micro framework.

Objective

Allow the PC to send and receive data to the Netduino Plus over a wired network.

Main Program

The Netduino Plus board does not have the same resources available to the programmer you would normally find in a PC environment. This leaves the programmer with little to work with. The HTTP server supplied as a sample with the micro framework occupies a substantial amount of memory on the board.

One of the simpler examples provided with the framework implements a very simple server. A little bit of redesign and coding converted this into a very basic web server. The server is capable of serving a few file types (HTML, JPG, CSS, Javascript and XAP) to the client.

The main program is a simple affair. It contains a few definitions to support the file locations for the web files along with a small amount of code to offer “I am alive” feedback to the user.

For the “I am alive” feedback I have chosen to use the on board LED and button. The LED will flash twice when the user presses the on board button. A small power saving I know.

The final job of the main program is to instantiate the web server. This will start the server listening on the specified port.

private static OutputPort _onBoardLED;
private static InterruptPort _onBoardButton;

public static void Main()
{
    _onBoardLED = new OutputPort(Pins.ONBOARD_LED, false);
    _onBoardButton = new InterruptPort(Pins.ONBOARD_SW1, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeBoth);
    _onBoardButton.OnInterrupt += new NativeEventHandler(onBoardButton_OnInterrupt);

    _webServer = new WebServer(WEB_ROOT, WebServer.HTTP_PORT);

    Thread.Sleep(Timeout.Infinite);
}

///
/// Flash the on board LED to let the user know we are still alive.
///
private static void onBoardButton_OnInterrupt(uint data1, uint data2, DateTime time)
{
    if (data2 == 0)
    {
        _onBoardLED.Write(true);
        Thread.Sleep(250);
        _onBoardLED.Write(false);
        Thread.Sleep(250);
        _onBoardLED.Write(true);
        Thread.Sleep(250);
        _onBoardLED.Write(false);
    }
}

The code for this can be found in SimpleWebServer.zip.

The files served provides a static web site to the client (a trip back to the 1990s).

Web Server

The web server class contains the methods to create a non blocking web server which will listen to the network on the specified socket and process the requests.

The constructor for the class sets up the local variables and creates a new thread to listen for requests:

public WebServer(string webFilesLocation, int portNumber)
{
    _webRoot = webFilesLocation;
    _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    _socket.Bind(new IPEndPoint(IPAddress.Any, portNumber));
    _socket.Listen(int.MaxValue);
    new Thread(Listen).Start();
}

The Listen method does the main work of listening to the socket, getting the request and converting it to a string which can be processed and finally closing the socket.

private void Listen()
{
    while (true)
    {
        using (Socket client = _socket.Accept())
        {
            int requestSize;
            byte[] buffer;
            int amountRead;
            string request;

            requestSize = client.Available;
            buffer = new byte[RECEIVE_BUFFER_SIZE];
            Debug.Print("Request received from " + client.RemoteEndPoint.ToString() + " at " + DateTime.Now.ToString("dd MMM yyyy HH:mm:ss"));
            amountRead = client.Receive(buffer, RECEIVE_BUFFER_SIZE, SocketFlags.None);
            request = new string(Encoding.UTF8.GetChars(buffer));
            Debug.Print(request);
            ProcessRequest(client, request);
            buffer = null;
            request = null;
            client.Close();
        }
    }
}

The method which processes the request is a simple method which is designed to check the first list of the request and verify that the web server can understand the protocol of the request. This server can only process HTTP 1.1 get requests. The first line of such a request should come through as something like the following:

GET filename.html HTTP/1.1

The ProcessRequest method looks something like the the following:

private void ProcessRequest(Socket client, string request)
{
    string[] firstLine;

    firstLine = request.Substring(0, request.IndexOf('n')).Split(' ');
    if (firstLine[0].ToLower() != "get")
    {
        Send(client, HTTP_501_NOT_IMPLEMENTED);
    }
    else
    {
        if (firstLine[2].ToLower() != "http/1.1r")
        {
            Send(client, HTTP_505_HTTP_VERSION_NOT_SUPPORTED);
        }
        else
        {
            SendFile(client, firstLine[1]);
        }
    }
}

The constants in upper case contain response strings indicating that the web server has encountered an error.

The key work for sending the files and processing commands can be found in the SendFile method. The first thing this method does is to check on the file name to see if it is the “special command” file. If it is then the query string is passed to the command processor. All other requests are processed as request for files which should exist on the server. The system works out if it understands the file type and if it does then the file is sent to the client.

One design decision taken was to restrict the output to the client to 256 byte chunks. This decision was made in order to conserve memory.

Commands

The eventual aim is to connect sensors etc. to the Netduino and then read the data from them over the network. In order to test the theory a “dummy” sensor was added to the command processor. This simply returned the number of milliseconds from the current time divided by 100.

TimeSpan time;

tme = Utility.GetMachineTime();
Send(client, "Time " + time.Hours + ":" + time.Minutes + ":" + time.Seconds);

By using the command.html file and the QueryString we can test the system by making a simple request from the web browser. For instance:

http://192.168.10.100/Command.html?GetTemperature

could be interpreted as a request to read the temperature from a sensor attached to the board.

Silverlight Client

The next step was to look at dynamic content. The board is not powerful enough to support conventional technologies such as PHP or ASP. Silverlight offers the ability to move the dynamic content creation away from the web server and onto the client desk top. To demonstrate this, a simple Silverlight application was created to be served by the web server (hence the support for XAP files). The initial version simply said hello to the user.

So far, so good. The web server was serving HTML and Silverlight files to the client.

The next step was to flesh out the Silverlight client to hold sensor data and display this to the user. This part of the application is implemented in MVVM. For this I needed a class to hold a sensor reading and a class (TemperatureReading)to hold a collection of sensor readings (TemperatureViewModel).

public class TemperatureReading
{
    ///
    /// Date and time the reading was recorded.
    ///
    public DateTime When { get; set; }

    ///
    /// Temperature.
    ///
    public double Temperature { get; set; }

    ///
    /// Constructor
    ///
    /// <param name="when" />When was the reding taken
    /// <param name="temperature" />Reading taken
    public TemperatureReading(DateTime when, double temperature)
    {
        When = when;
        Temperature = temperature;
    }
}

The ViewModel holding the temperature readings is as follows:

public class TemperatureViewModel : INotifyPropertyChanged
{
    #region Properties

    ///
    /// Collection of temperature readings.
    ///
    private ObservableCollection _readings;
    public ObservableCollection Readings
    {
        get { return (_readings); }
        set
        {
            _readings = value;
            RaisePropertyChanged("Readings", "NumberOfReadings");
        }
    }

    ///
    /// Number of readings in the collection of temperature readings.
    ///
    public int NumberOfReadings
    {
        get { return (_readings.Count); }
    }

    #endregion

    #region Constructor(s)

    ///
    /// Default constructor
    ///
    public TemperatureViewModel()
    {
        Readings = new ObservableCollection();
    }

    #endregion

    #region INotifyPropertyChanged Members

    ///
    /// Event used to notify any subscribers that the data in this class has changed.
    ///
    public event PropertyChangedEventHandler PropertyChanged;

    ///
    /// Let any subscribers know that some data has changed.
    ///
    /// <param name="properties" />Array of name of the properties which have changed.
    private void RaisePropertyChanged(params string[] properties)
    {
        if ((properties != null) && (PropertyChanged != null))
        {
            foreach (string property in properties)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }
    }

    #endregion

    #region Methods

    ///
    /// Add a new reading to the collection.
    ///
    /// <param name="reading" />Reading to be added.
    public void Add(TemperatureReading reading)
    {
        Readings.Add(reading);
        RaisePropertyChanged("Readings", "NumberOfReadings");
    }

    #endregion
}

Now we have somewhere to store the data we need to display the interface and then add a way of getting the data into the application.

The MainPage.xaml displays the data in a DataGrid and a chart. There is also a button for starting and stopping the collection of data. The DataGrid and the Chart are both bound to an instance of the TemperatureViewModel class.

The data for the class is collected periodically by using a web request from an instance of the WebClient class. This is then parsed and added to the collection of readings and the interface updated automatically through the magic of the RaiseProipertyChanged method of the TemperatureViewModel class.

The source can be found here: SilverlightOnNetduino.zip.

Building the Server

The web server code was modified to provide simulated readings from a temperature sensor. This is simply the current number of milliseconds divided by 100. The data is stored in a DataGrid and a presented to the user:

Adding the Silverlight Toolkit charting control to the application allowed the data to be plotted:

The next step is to tie this up to a real sensor and serve data to the users desktop.

Don’t Panic Mr Mainwaring

Wednesday, January 26th, 2011

This evening saw a bit of a Dads Army moment. The Netduino would not talk to me or my laptop. There I sat with a brilliant idea for a new project and the little devil just looked at me. Had I killed the hardware with static?

Quick search of the Netduino forums found the solution:

  1. Start MFDeploy
  2. Hold down the push button on the Netduino and plug it into the computer
  3. Click on the Erase button in MFDeploy

A quick basic onboard LED program written, compiled and YES – deployed.

Phew… Now what was that brilliant idea again? Drat, so worried I forgot it.

And if you are interested, the original article can be found here.