Jeroen Swart

.NET Architect

Download the ALM VM's without a download manager

If you don't know Brian Keller and his ALM VM's, you should really check them out. Each VM contains a completely installed environment for a specific (ALM-related) scenario and comes with a comprehensive set of hands-on-labs and demo's.

This post is not about the VM's themselves. If you want more information about them, go to the overview page and follow the links to the individual VM's.

If you've read the download instructions, you'll know that it tells you to use the 'Free Download Manager' and copy/paste a list of url's to download all the parts. This works nice, but the first thing I do after I'm done downloading, is remove the download manager. It intercepts every download, which I find rather annoying.

To be able to download the VM's without the download manager, I first wrote the simple PowerShell script below. Place it in a ps1 script-file and place the URL's from the VM-page into a urls.txt file in the same folder as the script. You may want to change the target-directory in the script. Then run it. You can restart the script if needed, as it only downloads the files that aren't downloaded yet. In case a file is only partially downloaded, delete it before restarting the script.

$targetDirectory = "D:\Downloads\VS13ALMVM"
mkdir $targetDirectory -ErrorAction SilentlyContinue

$urls = Get-Content (Join-Path $PSScriptRoot "urls.txt")

foreach($url in $urls) {
    $targetPath = Join-Path $targetDirectory ([System.IO.Path]::GetFileName($url))
    $targetPath

    if(!(Test-Path $targetPath)) {
        (new-object net.webclient).DownloadFile($url, $targetPath)
    }
}

This still requires some manual work, creating files and copy/pasting url's. Not a huge problem, but inspired by the way Chocolatey installs, I set out to minimize the manual steps. The result is a set of scripts, one for each VM, in a GitHub repository.

As an example, here is the script for the Visual Studio 2013 Update 3 ALM VM:

# VM details
$vmName = "vs13almvm"
$vmUrl = "http://aka.ms/$vmName"
Write-Host "Downloading ALM VM '$vmName' from '$vmUrl'" -ForegroundColor Yellow

# determine file-location
$targetDirectory = "$env:USERPROFILE\Downloads\$vmName"
Write-Host "Writing files to '$targetDirectory'"
mkdir $targetDirectory -ErrorAction SilentlyContinue | Out-Null

# get the HTML containing the url's for the VM
Write-Host "Downloading web-page containing url's"
$html = (new-object net.webclient).DownloadString($vmUrl)

# get the url's from the page
$match = [regex]::Match($html, '###[^\n]*Do Not Include[^\n]*###(?<urls>.*)###[^\n]*Do Not Include[^\n]*###')
if ($match.Success) {
    # split the url's into an array
    $urls = $match.Groups["urls"].Value -split "<br\s*>"
    Write-Host "Found $($urls.Length) url's on the page"
    
    # process each url
    foreach($url in $urls) {
        $url = $url.Trim()

        # determine the local path
        $targetPath = Join-Path $targetDirectory ([System.IO.Path]::GetFileName($url))

        # download the file, if it doesn't yet exist
        if(!(Test-Path $targetPath)) {
            Write-Host "Downloading '$targetPath'"
            (new-object net.webclient).DownloadFile($url, $targetPath)
        }
    }
}
else {
    Write-Host "Sorry, couldn't find the url's on the web-page" -BackgroundColor Red -ForegroundColor White
}

This script first downloads the web-page containing the url's. Then takes the url's from the page and splits them into an array. Finally, all url's are downloaded into a VM-specific folder in the current user's downloads-folder. I had a bit of trouble getting the url's from the HTML using a PowerShell regular expression, so I decided to use the .NET object. An alternative for getting the url's from the page, is to put them in the script. But since the VM's are sometimes updated and hands-on-labs & demo's are added, I would need to update the list of url's in the scripts. Now I don't :-).

SInce the script is on GitHub, and this is the Chocolatey-inspired bit, you can run the above script by simply running the following command:

iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/CodeblackNL/ALMVMs/master/vs13almvm.ps1"))

This command downloads the script as a string, and then executes that string as a script (iex is short for Invoke-Expression).

Check the GitHub repository for the commands to download the other VM's.

Netduino - Getting Started with LCD

If you want to show more output then blinking LED’s, an LCD module is a good and usually affordable option. They come in different sizes, from 2 numeric-only digits to 40x4 alphanumeric dot-matrix modules. You can also get graphic LCD’s, that range from modules with small resolutions (e.g. 122x32 or 240x128 pixels) to more professional LCD screens (e.g. 5” or 7”),  but I will stick with alphanumeric LCD’s for this post.

Most alphanumeric LCD modules are built around a HD44780 or compatible controller, so they all use the same interface. They are controlled using an 8-bit parallel port, some pins for handshaking (controlling the transfer of data over the parallel port), pins for controlling the contrast and backlight if available and of course pins for power and ground. The parallel port can also be used in 4-bits mode, sending the 8-bit data in two write actions. This saves I/O ports, but takes more time to update the LCD.

There is an excellent library available on codeplex (with a good introduction on the blog of the author) for controlling LCD modules. This library makes showing text on a display as easy as calling a Write method with the desired string. It uses a provider-pattern to allow for different connection scenarios, like direct on GPIO pins, using a shift-register or using an I2C expander. And if you want to use another scenario, you can add your own provider.

I have a 20x2 LCD module that I connected directly to the GPIO pins of my Netduino using the parallel port in 4-bit mode. The connections are made on a breadboard, because this makes it a little easier to put all the wires together. Below is an image of the result. The sample code provided with the library contains a link to a very helpful schematic on the Arduino website. Remember to connect the power on the LCD module to the 5V of the Netduino. 3.3V is not enough and will leave the LCD blank.

 The library contains a simple example of how to use the library. It initializes the LCD, shows the obligatory “Hello world” and then enters a loop that shows the milliseconds since reset. Since I use the GPIO pins directly, I changed the provider in the example. The code I used is shown below.

public class Program
{
    public static void Main()
    {
        // create the transfer provider, use direct GPIO provider
        // Initialize the library with the numbers of the interface pins
        // Use wiring shown here http://arduino.cc/en/uploads/Tutorial/lcd_schem.png
        var lcdProvider = new GpioLcdTransferProvider(Pins.GPIO_PIN_D12,    // RS
                                                        Pins.GPIO_PIN_D11,    // ENABLE
                                                        Pins.GPIO_PIN_D5,     // D4
                                                        Pins.GPIO_PIN_D4,     // D5
                                                        Pins.GPIO_PIN_D3,     // D6
                                                        Pins.GPIO_PIN_D2);    // D7

        // create the LCD interface
        var lcd = new Lcd(lcdProvider);

        // set up the LCD's number of columns and rows: 
        lcd.Begin(20, 2);

        // print a message to the LCD.
        lcd.Write("Hello world!");

        while (true)
        {
            // set the cursor to the first column on the second line
            lcd.SetCursorPosition(0, 1);

            // print the number of milliseconds since reset:
            lcd.Write((Utility.GetMachineTime().Ticks / 10000).ToString());

            Thread.Sleep(100);
        }
    }
}

 

Netduino - Getting Started with steppermotors, shieldless

In my previous post, I explained how I used the Adafruit motorshield to control a steppermotor. Since this shield uses a shift register, it needs a lot of I/O-actions. To control the steppermotor without a shift register, I put together part of the motorshield schematic on a breadboard. What remains is a single L293D with a few supporting parts, as shown in the schematic below.

You can put the schematic together on a small breadboard. Connect D0, D1, D2 and D3 to the corresponding ports on the Netduino. Connect all grounds to the ground on the Netduino, all the VCC to the Netduino 3.3V and the Vin to the Vin of the Netduino. The power of the adapter will be on Vin, powering the motor. The image below shows my result.

I changed the library for the motorshield, used in my previous post, to work with the schematic above. You can download it here. The library only supports steppermotors and it only provides support for single, double and interleave step-types. Pins D0 - D3 are used by default, but you can use any of the digital I/O pins by providing them to the constructor of the Stepper class.

The sample program that comes with the library download does the same as the sample program in my previous post: it initializes a stepper motor with 200 steps per revolution (or 1.8 degrees per step) and then repeats a few forward and reverse 360 degree rotations for each supported step-type. An example of initializing the motor and moving it forward is shown below.

Stepper stepper = new Stepper(StepperPorts.M3_M4, 200);
stepper.Step(200, MotorDirection.Forward, StepType.Single);

But… does it increase the speed of the motor? Well, yes and no. For one motor it does, and for another it doesn’t. The first motor I tested (200 steps per rotation; the one in the image above) runs at 1.36 rotations per second using the shield and at 2.46 rotations per second without the shield, so using the direct control almost doubles the speed. The second motor (a small one with 48 steps per rotation) runs at 5.68 rotations per second with the shield and at 4.04 rotations per second without it, so slowing the motor down by almost 30%.

Of course, the measurements are hardly scientific, and I only tested two motors. I ran each motor for 10 full rotations and recorded the time that took. I did this 10 times for each step-type and calculated the averages.

However, there are some issues with this approach at the moment. Running the step-loop at the highest speed doesn’t move either motor one bit or they just shake somewhat. I had to put in a minimum wait-time of 1 msec after each step to get the motors to rotate. Another problem is the decrease in torque. I need to take a good look at the pulses that come out of the output-pins. Each part of the H-bridge is now controlled one after the other, instead of all at the same time (by setting up all the right output levels first, then providing them to the H-bridge all at once). I want to have a look at this, as soon as I can get my hands on an oscilloscope :-).

It’s not really the result I was hoping for. I’m looking for a speed of about 50 rotations per second. I’m planning to use NEMA 34 motors, which can do that easily. I’m not yet sure what’s causing the issues, but I do know that controlling the pulses directly with the microcontroller will not get me the high speed I’m looking for. One solution could be the use of an L297 chip. This is a steppermotor controller that turns two signals, a clock pulse (e.g. generated with PWM) and a direction signal, into the correct pulses for the H-bridge.

Next: working with LCD.

Netduino - Getting Started with steppermotors

Working with steppermotors is a bit more complex then working with regular DC motors. Apply a voltage to a DC motor and it will rotate. With stepper motors, you need to apply that voltage in a specific pattern.

Instead of using a single coil, as in a DC motor, most steppermotors use two coils. The number of steps is determined by the number of magnetic poles on the rotor. Two common types of steppermotors are unipolar and bipolar steppermotors.

Bipolar & unipolar

A bipolar steppermotor is controlled by reversing the polarity of each coil in the right order. A more detailed description of how a bipolar steppermotor works can be found here.

In a unipolar steppermotor the two coils each have a wire connected to their center. It is controlled by providing power between the center and one of the ends. The center of the coils is always connected to ground. Applying a positive voltage to one or the other end of a coil has the same effect as reversing the voltage on a coil in a bipolar motor. A more detailed description of unipolar steppermotors can be found here.

Wikipedia provides a nice article on steppermotors, which also shows an animation of a steppermotor.

The picture below shows some steppermotors. These are all unipolar. The left and right motors are the same type.

Below are two more pictures of the insides of the steppermotor.

   

Hardware

Since it takes some power to control motors, microcontrollers normally can’t control motors directly. Transistors are up for this job, as I explained before. To be able to provide some extra power, darlington transistors are often used with motors instead of single transistors. A darlington transistor is a set of two transistors that function as one, but can provide a much higher current gain than each transistor by themselves. The image below shows the symbol of a darlington transistor. You can read more information about them on Wikipedia.

Steppermotors are controlled by applying voltage to the ends of each coil (the center taps of a unipolar steppermotor are connected to ground), so you’ll need four (darlington) transistors. Such a set of transistors is called an H-bridge. You can make an H-bridge yourself or you can use an H-bridge chip. There are a lot of H-bridge chips available, like the L293D (handles 600mA), the L298 (handles up to 4A) or the ULN2004 (handles 500mA) to name a few.

Of course, you can also pick one of the motor shields available from stores like Adafruit or Sparkfun. I started with the motorshield from Adafruit. It consists of two L293D’s and can control 2 steppermotors (or 4 DC motors). It uses a serial/parallel shift register (74HC595N) to control the L293D’s with the least amount of I/O pins from the microcontroller. This is a nifty trick, although it makes the software a little bit more complex. It also takes more time to control the L293D’s. Each bit of the shift register (8 in total) must be set on a single data-pin and each data-bit is moved into the shift register using a pulse from a clock-pin; finally the result is made available on the parallel outputs of the register using a latch-pin, resulting in a total of 25 I/O-actions. This does not have to be a bad thing, but it does take more time and therefore limits the maximum speed of the motor.

The image below shows the motorshield, stacked on a Netduino, with a stepper motor connected. Since the USB connection can’t provide the power, I'm using an external power adapter.

Software

Adafruit provides an Arduino library for the motorshield. I found a Micro .NET port of this library on the Netduino forums, but it wasn’t working properly. You can download my version here. The microstep step-type (see below) still isn’t working, my motor just wiggles. I don’t think I’ll need microstepping myself, so I’m not really in a hurry to get it working :-). If you do need it, let me know and I’ll be glad to help. I also haven’t tested the DC motor part of the library.

The library provides four types of step-behavior: single, double, interleave and microstep. The single step-type activates a single coil at a time; this is also referred to as ‘wave drive’. The double step-type activates both coils at the same time; also referred to as ‘full step drive’. Double stepping uses twice the power and provides more torque, although not twice the torque. The interleave step-type combines both the single and the double step-type, activating one coil, then two coils, then one coil again and so on; this is also referred to as ‘half stepping’. Since each activation only makes a half step, this step-type requires twice the amount of steps to make the same rotation as the single or double step-type. The microstep step-type uses PWM (explained here) to have a finer control over the power supplied to the coils. Instead of simply switching a coil on or off, microstepping provides a sine waveform to each coil. This provides smoother rotation, but reduces the accuracy of the steps. As I mentioned, it’s currently not working in the library.

The sample program in the solution initializes a stepper motor with 200 steps per revolution (or 1.8 degrees per step) and then repeats a few forward and reverse 360 degree rotations for each (working) step-type. Below is a short example of how to initialize a motor and move it forward.

Stepper stepper = new Stepper(StepperPorts.M3_M4, 200);
stepper.Step(200, MotorDirection.Forward, StepType.Single);

I feel the shift register is limiting the speed of the steppermotor too much. So next, I will try to control the H-bridge directly, without the shift register.

Next: working with steppermotors, without the shield.

NetDuino - Getting Started with SD

The Netduino Plus has an on-board SD-card slot. It is connected to one of the SPI ports of the microcontroller. Fortunately, you don't need to write code to control the SPI port yourself. The firmware handles this for you, so all you need to do is work with the classes from the System.IO namespace. Do remember that this is the Micro .NET framework and it is not as rich as the full .NET framework, but it does provide enough implementation for working with the SD card.

The root of the file system on the SD card is '\SD'. So, to get all the files in the root directory, you could do the following:

[code:c#;ln:off;alt:on]string[] fileNames = Directory.GetFiles(@"\SD");[/code]

And anything else is just as simple as that. Below is an example that shows all folders and files on the card. You'll need to add a using statement for the System.IO namespace.

[code:c#;ln:off;alt:on]public class Program
{
    public static void Main()
    {
        DirectoryInfo rootDirectory = new DirectoryInfo(@"\SD\");

        RecurseFolders(rootDirectory);
    }

    private static void RecurseFolders(DirectoryInfo directory)
    {
        if (directory.Exists)
        {
            Debug.Print(directory.FullName);

            foreach (FileInfo file in directory.GetFiles())
            {
                Debug.Print(file.FullName);
            }

            foreach (DirectoryInfo subDirectory in directory.GetDirectories())
            {
                RecurseFolders(subDirectory);
            }
        }
    }
}
[/code]

If there is no card in the SD slot, the \'SD' directory will not exist. So check the Exist property before using the rest of the DirectoryInfo object. Using the object (other than the Exist property) if the directory it represents does not exist will throw an expection. If a DirectoryInfo object was already created, for an existing directory, and then the SD card is removed, an exception is thrown when accessing the object. Since removing a card is easy, you should write code that handles that possibility.

Oh, and do remember that the maximum SD card size the Netduino Plus can handle is 2GB. It is clearly mentioned on the Netduino Plus specifications page, but I overlooked it at first myself. When using a larger SD card, it will look as if no card has been inserted at all.

Next: communicate using RS232.

Windows Phone 7 and a Kerio mailserver

At work, we use a Kerio mailserver. To Windows Mobile and Windows Phone devices it looks like an Exchange Server, so you can add your account as an Outlook/Exchange account. Well, in theory. I tried this before, but wasn't able to add the account. I could create a POP3 account, but that left me with e-mail only, not my calendar.

Yesterday I tried again. With a colleague looking at the Kerio logging (thanks Sander!), we found why creating the Outlook/Exchange account on the phone was not working.

When creating the account you need to provide several settings, amongst which is the Domain. I simply assumed this should be the domain of the account (as in domain\username), like when connecting to a real Exchange server. Not so with Kerio. You need to provide the full domain of your e-mail address. So in the case of username@domain.com, the Domain setting should be domain.com.

NetDuino - Getting Started with I2C

I2C is a serial communication protocol, used for communication between IC's. It uses two wires: one for data (SDA) and one for a clock signal (SCL). For more details on this protocol, check this Wikipedia article.

The Netduino has one I2C port which is available on pin A4 (SDA) and A5 (SCL). The I2C protocol works as a bus, so you can connect more than one slave devices to the one I2C port of the Netduino. For the I2C bus to work properly, you need to add two pull-up resistors to pins A4 and A5, regardless of the number of devices connected to the bus.

For experimenting with I2C, I’m using two ‘plugs’ that I got from JeeLabs a while ago. A plug is a small board that is easily plugged into a JeeNode (an Arduino-compatible board). There are several plugs available, like an Analog Plug, a DC Motor Plug or a Gravity Plug. I have an I/O Expander Plug and a RTC Plug, which I will use in the code below. Most plugs only contain a single I2C chip and a few supporting components. So putting one (or more) I2C chips on a breadboard should be pretty easy.

For the examples, I created some classes that represent the I2C plugs: a I2CPlug base-class, an ExpanderPlug class and a RTCPlug class. All three classes are shown below. Add them to your project to be able to use the examples that follow.

public class I2CPlug
{
    private const int DefaultClockRate = 400;
    private const int TransactionTimeout = 1000;

    private I2CDevice.Configuration i2cConfig;
    private I2CDevice i2cDevice;

    public byte Address { get; private set; }

    public I2CPlug(byte address, int clockRateKhz)
    {
        this.Address = address;
        this.i2cConfig = new I2CDevice.Configuration(this.Address, clockRateKhz);
        this.i2cDevice = new I2CDevice(this.i2cConfig);
    }
    public I2CPlug(byte address)
        : this(address, DefaultClockRate)
    {
    }

    private void Write(byte[] writeBuffer)
    {
        // create a write transaction containing the bytes to be written to the device
        I2CDevice.I2CTransaction[] writeTransaction = new I2CDevice.I2CTransaction[]
        {
            I2CDevice.CreateWriteTransaction(writeBuffer)
        };

        // write the data to the device
        int written = this.i2cDevice.Execute(writeTransaction, TransactionTimeout);

        while (written < writeBuffer.Length)
        {
            byte[] newBuffer = new byte[writeBuffer.Length - written];
            Array.Copy(writeBuffer, written, newBuffer, 0, newBuffer.Length);

            writeTransaction = new I2CDevice.I2CTransaction[]
            {
                I2CDevice.CreateWriteTransaction(newBuffer)
            };

            written += this.i2cDevice.Execute(writeTransaction, TransactionTimeout);
        }

        // make sure the data was sent
        if (written != writeBuffer.Length)
        {
            throw new Exception("Could not write to device.");
        }
    }
    private void Read(byte[] readBuffer)
    {
        // create a read transaction
        I2CDevice.I2CTransaction[] readTransaction = new I2CDevice.I2CTransaction[]
        {
            I2CDevice.CreateReadTransaction(readBuffer)
        };

        // read data from the device
        int read = this.i2cDevice.Execute(readTransaction, TransactionTimeout);

        // make sure the data was read
        if (read != readBuffer.Length)
        {
            throw new Exception("Could not read from device.");
        }
    }

    protected void WriteToRegister(byte register, byte value)
    {
        this.Write(new byte[] { register, value });
    }
    protected void WriteToRegister(byte register, byte[] values)
    {
        // create a single buffer, so register and values can be send in a single transaction
        byte[] writeBuffer = new byte[values.Length + 1];
        writeBuffer[0] = register;
        Array.Copy(values, 0, writeBuffer, 1, values.Length);

        this.Write(writeBuffer);
    }
    protected void ReadFromRegister(byte register, byte[] readBuffer)
    {
        this.Write(new byte[] { register });          
        this.Read(readBuffer);
    }
}
public class ExpanderPlug : I2CPlug
{
    private const int ExpanderPlugAddress = 0x20;

    public enum Registers
    {
        IODIR,
        IPOL,
        GPINTEN,
        DEFVAL,
        INTCON,
        IOCON,
        GPPU,
        INTF,
        INTCAP,
        GPIO,
        OLAT
    };

    public ExpanderPlug()
        : base(ExpanderPlugAddress)
    {
    }
    public ExpanderPlug(byte directions)
        : base(ExpanderPlugAddress)
    {
        SetDirections(directions);
    }

    public void SetDirections(byte directions)
    {
        this.WriteToRegister((byte)Registers.IODIR, directions);
    }

    public void Write(byte values)
    {
        this.WriteToRegister((byte)Registers.GPIO, values);
    }

    public byte Read()
    {
        byte[] values = new byte[1] { 0};

        this.ReadFromRegister((byte)Registers.GPIO, values);

        return values[0];
    }
}
public class RtcPlug : I2CPlug
{
    private const int RtcClockPlugAddress = 0x68;

    public RtcPlug()
        : base(RtcClockPlugAddress)
    {
    }

    public void Write(DateTime value)
    {
        byte[] dateBuffer = new byte[]
        {
            ConvertBinaryToBCD(value.Second),
            ConvertBinaryToBCD(value.Minute),
            ConvertBinaryToBCD(value.Hour),
            ConvertBinaryToBCD(0),
            ConvertBinaryToBCD(value.Day),
            ConvertBinaryToBCD(value.Month),
            ConvertBinaryToBCD(value.Year - 2000)
        };

        this.WriteToRegister(0, dateBuffer);
    }
    public DateTime Read()
    {
        byte[] dateBuffer = new byte[7];

        this.ReadFromRegister(0, dateBuffer);

        return new DateTime(ConvertBCDToBinary(dateBuffer[6]) + 2000,
                            ConvertBCDToBinary(dateBuffer[5]),
                            ConvertBCDToBinary(dateBuffer[4]),
                            ConvertBCDToBinary(dateBuffer[2]),
                            ConvertBCDToBinary(dateBuffer[1]),
                            ConvertBCDToBinary(dateBuffer[0]));
    }

    private static byte ConvertBinaryToBCD(int value)
    {
        return (byte)(value + 6 * (value / 10));
    }

    private static int ConvertBCDToBinary(byte value)
    {
        return value - 6 * (value >> 4);
    }
}

As a first example, we’ll toggle all the pins of the expander plug like the blink example.

public class Program
{
    public static void Main()
    {
        // initialize the expander plug, setting all pins as output
        ExpanderPlug expanderPlug = new ExpanderPlug(0x00);

        // do forever...
        while (true)
        {
            expanderPlug.Write(0xff);       // turn all the pins on
            Thread.Sleep(250);              // make the pins stay on for 250 ms
            expanderPlug.Write(0x00);       // turn all the pins off
            Thread.Sleep(250);              // make the pins stay off for 250 ms
        }
    }
}

You can use a LED (with a resistor in series) to test the level of each port as shown below.

Next, we’ll configure all pins as input. You can connect any pin to 3.3V using a resistor and see how the value changes. For the most stable results, connect all the input pins to ground if not connected to 3.3V.

public class Program
{
    public static void Main()
    {
        // initialize the expander plug, setting all pins as input
        ExpanderPlug expanderPlug = new ExpanderPlug(0xff);

        // do forever...
        while (true)
        {
            byte value = expanderPlug.Read();       // get the values of all the pins
            
            Debug.Print("value: " + value.ToString());

            Thread.Sleep(250);
        }
    }
}

For the final example I connected the RTC plug. A date is first written, then continouosly retrieved to show that the clock is running.

public class Program
{
    public static void Main()
    {
        // initialize the RTC plug
        RtcPlug rtcPlug = new RtcPlug();

        // write the current date/time to the clock
        DateTime now = new DateTime(2011, 7, 31, 15, 58, 0);
        rtcPlug.Write(now);

        Debug.Print("now: " + now.ToString());

        // do forever...
        while (true)
        {
            // read the current date/time from the clock
            DateTime value = rtcPlug.Read();

            Debug.Print("value: " + value.ToString());

            Thread.Sleep(250);
        }
    }
}

The Micro .NET Framework does have an internal clock and DateTime.Now does work, but it is reset to '01-01-2009 00:00:00' every time you restart the device. Since the Netduino doesn't have an on-board RTC, it doesn't know the actual date/time. You could use an RTC as shown above and change the current date/time by calling Utility.SetLocalTime once during the initialization of your program. If you really want to get the actual date/time (from an RTC) when calling DateTime.Now, you'll need to update the firmware.

Next: working with steppermotors.

NetDuino - Getting Started with RS232

A common communication protocol is RS232. This is a serial protocol, which uses two wires to transmit data in both directions one bit at a time. A port using this protocol is usually simply called a serial port, because it’s one of the most commonly used protocols for serial communication.

Connecting two devices using RS232 can be as simple as connecting 3 wires between them: transmitted data (TxD), received data (RxD) and ground. It is also possible to connect up to 6 more wires, which handle the handshake part of the RS232 protocol. Handshaking is used to synchronize the communication between the devices: e.g. to let the other device know data was sent or it’s ready to receive data. With 3 wires, and no handshaking, both sides must agree upon the details of the communication: the speed and the number of data-, start- and stop-bits.

What makes using the RS232 protocol difficult in standard digital electronics, is that the protocol uses different voltage levels. Instead of using 0V for a low level or ‘0’ and using the supply voltage (3.3V or 5V) for a high level or ‘1’, the RS232 protocol uses +3V to +15V to signal a ‘0’ and -3V to -15V to signal a ‘1’.

The conversion of RS232 signals and voltage levels is such a common task, that special chips (like the MAX232 or MAX3232) are available to handle this. They even make -12V and +12V out of a 5V or 3.3V power supply. Another option is to use a USB to RS232 converter, like the FT232 chip. This chip presents itself (at its USB side) as a USB serial port to your PC, which is recognized by Windows and a driver is automatically installed. You then have a virtual serial port (usually COM3 or higher) which you can use as if it was a regular RS232 serial port. Whatever you send to this virtual serial port will be present on the RS232 side of the FT232 chip, in logical 0’s and 1’s, and vice versa.

When connecting two microcontroller devices (e.g. two Netduino’s or a Netduino with an Arduino), there is no need to translate the signals. The appropriate ports of each microcontroller can simply be connected directly, or through any type of connector.

Another important thing to know is that the protocol was originally designed for computers and device communication. In this configuration the computer transmits over the TxD line and the device listens to the same line. When connecting two computers, or microcontrollers, to communicate with RS232, both are transmitting over the TxD line and listening on the RxD line. Therefore the lines must be connected across: TxD to RxD and RxD to TxD. When using the ‘real’ RS232 protocol, you can use a special null modem cable, where the TxD and RxD lines are crossed inside. When connecting without such a cable, e.g. between microcontrollers, just remember to connect TxD on one to RxD on the other.

If you want to know more about RS232, check out this Wikipedia article.

The microcontroller on the Netduino has 2 serial ports and both are available through the Netduino headers. Because my laptop has no serial port, I’m using a ‘USB BUB’ board. It’s nothing more than a simple board with a RL232 chip and some supporting components. It’s made by Modern Device, but I ordered mine from JeeLabs, together with some JeeNodes (an Arduino-compatible board).

To setup the hardware part of the example, connect the USB BUB to a PC with a USB cable. It will automatically install the necessary driver and show up as a USB Serial Port in the device manager as shown below.

The ‘LOGIC LVL’ jumper on the USB BUB should be in the 3.3V position, since that’s what the Netduino is working with, but 5V will also work. Connecting the Netduino to the USB BUB takes 3 wires as shown in the picture below. The black wire connects the ground of both boards. The green wire connects the RxD of the Netduino (D0) to the TxD of the USB BUB. The white wire connects the TxD of the Netduino (D1) to the RxD of the USB BUB.

The D0 (RxD) & D1 (TxD) pins of the Netduino headers are connected to the first serial port of the microcontroller, or COM1 for Micro .NET as we will see in code. The second serial port, or COM2, is connected to D2 (RxD) and D3 (TxD) of the Netduino. The first serial port doesn’t provide handshaking. The second serial port does provides handshaking (using CTS & RTS only), but you’re not required to use it.

Below is the code for the Netduino. It sets up a serial port to use COM1 and adds an event handler for when data is received. When data is received, a single byte is read and send back as long as there is data in the buffer to read. You need to add a using statement for the System.IO.Ports namespace. If you want to use COM2 instead, connect the USB BUB to D2 & D3 instead of D0 & D1 and change SerialPorts.COM1 in the code below to SerialPorts.COM2.

public class Program
{
    static SerialPort serial;

    public static void Main()
    {
        // initialize the serial port for COM1 (using D0 & D1)
        serial = new SerialPort(SerialPorts.COM1, 9600, Parity.None, 8, StopBits.One);
        // open the serial-port, so we can send & receive data
        serial.Open();
        // add an event-handler for handling incoming data
        serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived);

        // wait forever...
        Thread.Sleep(Timeout.Infinite);
    }

    static void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // create a single byte array
        byte[] bytes = new byte[1];

        // as long as there is data waiting to be read
        while (serial.BytesToRead > 0)
        {
            // read a single byte
            serial.Read(bytes, 0, bytes.Length);
            // send the same byte back
            serial.Write(bytes, 0, bytes.Length);
        }
    }
}

Next is the code for a simple console application. It uses COM3 which you might need to change depending on what your USB BUB is connected as; check your device manager. The application lets you type a string and sends it out. When data is received, it is shown. As with the Netduino code, you need to add a using statement for the System.IO.Ports namespace.

class Program
{
    static SerialPort serial;

    static void Main(string[] args)
    {
        // provide some usage information
        System.Console.WriteLine("enter some text and hit ENTER.");
        System.Console.WriteLine("enter 'x' and hit ENTER to exit.");
        System.Console.WriteLine();

        // initialize the serial port for COM3 (could be other port, depends on system)
        serial = new SerialPort("COM3", 9600, Parity.None, 8, StopBits.One);
        // open the serial-port, so we can send & receive data
        serial.Open();
        // add an event-handler for handling incoming data
        serial.DataReceived += new SerialDataReceivedEventHandler(serial_DataReceived);

        // this will hold each line entered
        string line = string.Empty;

        // as long as an x is not entered
        while (line.ToLowerInvariant() != "x")
        {
            // read a single line from the console
            line = System.Console.ReadLine();

            // convert the line to bytes
            byte[] utf8Bytes = System.Text.Encoding.UTF8.GetBytes(line);

            // send the bytes over the serial-port
            serial.Write(utf8Bytes, 0, utf8Bytes.Length);
        }
    }

    static void serial_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // wait a little for the buffer to fill
        System.Threading.Thread.Sleep(100);

        // create an array for the incoming bytes
        byte[] bytes = new byte[serial.BytesToRead];
        // read the bytes
        serial.Read(bytes, 0, bytes.Length);
        // convert the bytes into a string
        string line = System.Text.Encoding.UTF8.GetString(bytes);

        // write the received bytes, as a string, to the console
        System.Console.WriteLine("echo: " + line);
        System.Console.WriteLine();
    }
}

Notice how the code for initializing the serial port, sending & receiving data and even for converting of bytes to a string and back, is exactly the same for both platforms! How cool is that.

Next: working with I2C.

NetDuino - Getting Started with SD

The Netduino Plus has an on-board SD-card slot. It is connected to one of the SPI ports of the microcontroller. Fortunately, you don't need to write code to control the SPI port yourself. The firmware handles this for you, so all you need to do is work with the classes from the System.IO namespace. Do remember that this is the Micro .NET framework and it is not as rich as the full .NET framework, but it does provide enough implementation for working with the SD card.

The root of the file system on the SD card is '\SD'. So, to get all the files in the root directory, you could do the following:

string[] fileNames = Directory.GetFiles(@"\SD");

And anything else is just as simple as that. Below is an example that shows all folders and files on the card. You'll need to add a using statement for the System.IO namespace to your code and a reference to the System.IO.dll to your project.

public class Program
{
    public static void Main()
    {
        DirectoryInfo rootDirectory = new DirectoryInfo(@"\SD\");
        RecurseFolders(rootDirectory);
    }

    private static void RecurseFolders(DirectoryInfo directory)
    {
        if (directory.Exists)
        {
            Debug.Print(directory.FullName);

            foreach (FileInfo file in directory.GetFiles())
            {
                Debug.Print(file.FullName);
            }

            foreach (DirectoryInfo subDirectory in directory.GetDirectories())
            {
                RecurseFolders(subDirectory);
            }
        }
    }
}

If there is no card in the SD slot, the \'SD' directory will not exist. So check the Exist property before using the rest of the DirectoryInfo object. Using the object (other than the Exist property) if the directory it represents does not exist will throw an expection. If a DirectoryInfo object was already created, for an existing directory, and then the SD card is removed, an exception is thrown when accessing the object. Since removing a card is easy, you should write code that handles that possibility.

Oh, and do remember that the maximum SD card size the Netduino Plus can handle is 2GB. It is clearly mentioned on the Netduino Plus specifications page, but I overlooked it at first myself. When using a larger SD card, it will look as if no card has been inserted at all.

Next: communicate using RS232.

NetDuino - Getting Started with ADC

The Netduino contains several ports (A0 - A5) that are capable of reading an analog signal and changing it into a digital representation of that signal. These ports can be used for digital I/O as well, but can individually be configured to use an internal ADC (Analog to Digital Converter).

The analog signal at the ADC port can come from different sources. It can come from a sensor, e.g. for measuring light or temperature, or it is simply taken from a variable resistor, that is changed by a user to select some value (e.g. the desired intensity of a dimmed light). The analog signal is a voltage between 0V and 3.3V. The ADC converts this voltage to a number between 0 and 1023, since the Netduino has 10-bits ADC’s. The number 0 represents 0V and 1023 represents Aref. The voltage level at any ADC port can be determined as follows:

float analogValue = (float)digitalValue * (3.3f/ 1023f)

In theory, you should divide by 1024, because there are that many steps. The maximum digital value of 1023 in that case represents a voltage between 3.2967 and 3.3V, but the formula would result in the lower value. In practice it is easier to divide by 1023, so a digital value of 1023 represents the full scale of 3,3V. And with ADC precision-errors and a Vref that's probably not exactly 3.3V, the result is pretty accurate.

The example uses port A0 and continuously reads the digital value and converts it to the actual voltage at the port using the previously mentioned formula. For this example connect a variable resistor to port A0 as shown below.

public class Program
{
    private const int MaximumValue = 1023;
    private const float AnalogReference = 3.3f;

    public static void Main()
    {
        // initialize one of the analog pins
        AnalogInput adcPort = new AnalogInput(Pins.GPIO_PIN_A0);

        // do forever...
        while (true)
        {
            // read a digital value from the ADC
            int digitalValue = adcPort.Read();

            // convert digital value to analog voltage value
            float analogValue = (float)digitalValue / MaximumValue * AnalogReference;

            // show the analog value in the output-window
            Debug.Print(analogValue.ToString());
        }
    }
}

If the default Aref value of 3.3V is not convenient, you can provide your own Aref at the corresponding pin of the Netduino headers. It must however be between 2.6V and 3.3V. To let the Netduino actually use the external Aref, you need to switch port 56 (on the board, but not available on the headers) to low:

OutputPort arefSelect = new OutputPort((Cpu.Pin)56, false);

To use the 3.3V again, switch port 56 to high:

OutputPort arefSelect = new OutputPort((Cpu.Pin)56, true);

Another way to convert the digital value of the ADC port to some meaningful value in code, is by using the SetRange method of the AnalogInput class. It allows you to set the minimum and maximum value returned by the Read method of the AnalogInput class. The conversion of the actual value to the range you have set is then done for you. In the example above we could have added the following line after the declaration of adcPort:

adcPort.SetRange(0, 3300);

The digitalValue can then be used as is, or divided by 100 to get the exact analog value:

float analogValue = (float)digitaValue / 100;

Since Aref can’t be higher than 3.3V, no analog signal higher than 3.3V can be measured by a port directly. Any signal above Aref is read as 1023 and, if considerably higher, may damage the port. To solve this, use a voltage divider using two resistors as shown below. The voltage at the port is Ain x R6 / (R5 + R6). The values of the resistors in the schematic allow for a 5V input to be measured as 3V by the port (5V * 18k / 30k = 3V). You can change the resistor values to accommodate any input voltage, e.g. change R2 to 120k to measure up to 23V. Note however that, when the input value is increased in this way, the accuracy of the value read from the ADC does decrease accordingly. Instead of 1024 steps of roughly 0.003V to reach 3.3V full scale, the ADC will do 1024 steps of roughly 0.022V to reach 23V full scale.

Another trick shown here is the use of a zener diode to protect a port. A zener diode will not allow a higher voltage to pass then the voltage that it was designed for. I won't go into the detailed workings of a zener diode, but effectively it protects the port from any voltage higher than the zener voltage.

Next: using the SD card.