Setting the Netduino's DateTime Automatically

Whenever the Netduino boots up or is restarted, you'll find that the date and time reverts to the default values.  Since the release of the Netduino Plus, ethernet access has been built in and provides a welcome solution to this issue.

The Network Time Protocol (NTP) provides an easy way to sync a device (such as your Windows computer) with a network time server.  By invoking an NTP server at start-up, the Netduino will automatically set its DateTime.

The following code was provided on a blog by Michael Schwarz and slightly modified to accept an additional (time zone) parameter:

using System;
using System.Net;
using System.Net.Sockets;

public static class Ntp
    public static bool UpdateTimeFromNtpServer(string server, int timeZoneOffset)
            var currentTime = GetNtpTime(server, timeZoneOffset);

            return true;
            return false;

    /// <summary>
    /// Get DateTime from NTP Server
    /// Based on:
    /// </summary>
    /// <param name="timeServer">Time Server (NTP) address</param>
    /// <param name="timeZoneOffset">Difference in hours from UTC</param>
    /// <returns>Local NTP Time</returns>
    private static DateTime GetNtpTime(String timeServer, int timeZoneOffset)
        // Find endpoint for TimeServer
        var ep = new IPEndPoint(Dns.GetHostEntry(timeServer).AddressList[0], 123);

        // Make send/receive buffer
        var ntpData = new byte[48];

        // Connect to TimeServer
        using (var s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
            // Set 10s send/receive timeout and connect
            s.SendTimeout = s.ReceiveTimeout = 10000; // 10,000 ms

            // Set protocol version
            ntpData[0] = 0x1B;

            // Send Request

            // Receive Time

            // Close the socket

        const byte offsetTransmitTime = 40;

        ulong intpart = 0;
        ulong fractpart = 0;

        for (var i = 0; i <= 3; i++)
            intpart = (intpart << 8) | ntpData[offsetTransmitTime + i];

        for (var i = 4; i <= 7; i++)
            fractpart = (fractpart << 8) | ntpData[offsetTransmitTime + i];

        ulong milliseconds = (intpart * 1000 + (fractpart * 1000) / 0x100000000L);

        var timeSpan = TimeSpan.FromTicks((long)milliseconds * TimeSpan.TicksPerMillisecond);
        var dateTime = new DateTime(1900, 1, 1);
        dateTime += timeSpan;

        var offsetAmount = new TimeSpan(timeZoneOffset, 0, 0);
        var networkDateTime = (dateTime + offsetAmount);

        return networkDateTime;

Here's a short list of some NTP servers:

  • (actually it's a collection of servers behind a single address)
Pass one of these server names as a string and call during your project's Main() method:
private static bool SetTime()
    var result = Ntp.UpdateTimeFromNtpServer("", -4);  // Eastern Daylight Time
    Debug.Print(result ? "Time successfully updated" : "Time not updated");

    return result;
It's unfortunate that the Netduino doesn't support Microsoft.SPOT.ExtendedTimeZone.SetTimeZone() to allow a time zone to be specified (thus eliminating the need for that extra "timeZoneOffset" parameter I added to two of the methods) or even the Microsoft.SPOT.Time.TimeService.UpdateNow() method, which would make all of the code above obsolete. However, it's understandable some libraries needed to be stripped due to memory size limitations. I'm still a huge fan of the Netduino; it still offers a lot of functionality on a very small and cheap device.

Additional References:

.NET Micro Framework, the Netduino, MP3s and File Reading

Microcontrollers have truly advanced to the point where it's possible to control them through high-level programming languages.  After surviving my assembly class in college (using a MIPS processor simulator), I swore off bit-shifting and jump statements altogether and never looked back.

Had it not been for the .NET Micro Framework, I don't think I'd even consider trying to get a tiny device to do anything a bigger computer could do; the learning curve was just too high.  Sure, the Arduino prototyping platform paved the way toward where we are now, but I liked the fact that I could write code in a familiar IDE with a familiar language (C#) and get a tiny device to do my bidding-- at least blink-- in a matter of minutes.

Sure, there are still new concepts for object-oriented developers to tackle, like interrupt ports and the need to pick up hardware like resistors, breadboards, and "shields" (devices that can be plugged into the top of the device), but it can bring familiar object-oriented concepts and even multithreading to an entirely new platform. It was actually fun to pick up a soldering iron again, something I haven't done in at least 15 years.

I decided to try the Netduino Plus, a very affordable device with a tiny amount of memory and a growing number of shields that are supported.  Here's my extremely minor contribution to this effort in the post, "compatible shields and accessories."

I've piled on two shields, one for SD card reading / writing and one for playing MP3s.  Provided you're only interested in playing a song encoded at about 30kbps, it's a blast.

Here's the code for Program.cs, which plays each MP3 file on an SD card in succession on a Netduino (predates the Netduino Plus with onboard SD card):

using System;
using Microsoft.SPOT;
using SecretLabs.NETMF.Hardware.Netduino;
using SecretLabs.NETMF.IO;
using System.IO;

namespace NetduinoMp3 {
    public class Program
        private static readonly int FileBufferSize = Vs1053.BufferSize * 10;

        public static void Main()
            StorageDevice.MountSD("SD1", SPI_Devices.SPI1, Pins.GPIO_PIN_D10);

            string[] directories = Directory.GetDirectories(@"\");
            Debug.Print("directory count: " + directories.Length);

            for (var i = 0; i < directories.Length; i++) {
                Debug.Print("directory: " + directories[i]);

            var files = Directory.GetFiles(@"\SD1");
            Debug.Print("file count: " + files.Length);


            for (var i = 0; i < files.Length; i++) {
                Debug.Print("filename: " + files[i]);
                var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read, FileShare.None, _



And the class "Vs1053.cs", used to control the MP3 shield:

using System;
using System.IO;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
using System.Threading;

namespace NetduinoMp3 {
    public static class Vs1053 {
        // GPIO ports:
        static private OutputPort _reset;
        static private InterruptPort _dreq;

        const Cpu.Pin PinBsync = Pins.GPIO_PIN_D2;
        const Cpu.Pin PinDreq = Pins.GPIO_PIN_D3;
        const Cpu.Pin PinReset = Pins.GPIO_PIN_D6;  // NOTE: This doesn't map to an actual pin
        const Cpu.Pin PinCs = Pins.GPIO_PIN_D9;

        // Define SPI Configuration for VS1053 MP3 decoder:
        static private readonly SPI.Configuration DataConfig = new SPI.Configuration(PinBsync, false, _ 
                0, 0, false, true, 3000, SPI.SPI_module.SPI1);
        static private readonly SPI.Configuration CmdConfig = new SPI.Configuration(PinCs, false, _ 
                0, 0, false, true, 3000, SPI.SPI_module.SPI1);
        static private SPI _spi;

        // Registers:
        const int RegisterSciMode = 0x00;
        const int RegisterSciVol = 0x0B;
        const int RegisterSciClockf = 0x03;

        public static readonly int BufferSize = 96;
        private const ushort SciMode = 0x880;  // SM_SDINEW (default) + SM_EARSPEAKER_HI

        static private bool _isInitialized;
        static private readonly byte[] ReadBuffer = new byte[BufferSize];
        static private readonly byte[] CmdBuffer = new byte[4];

        static private readonly AutoResetEvent AutoResetEvent = new AutoResetEvent(false);

        public static void Initialize() {
            if (_isInitialized)

            _spi = new SPI(CmdConfig);
            _reset = new OutputPort(PinReset, true);
            _dreq = new InterruptPort(PinDreq, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            _dreq.OnInterrupt += _dreq_OnInterrupt;

            _isInitialized = true;


            CommandWrite(RegisterSciMode, SciMode | (1 << 2));
            CommandWrite(RegisterSciClockf, 7 << 13);
            CommandWrite(RegisterSciVol, 0x2424);

            _spi.Config = DataConfig;

        private static void _dreq_OnInterrupt(uint port, uint state, DateTime time) {
            if (state == 0)

        private static void Reset() {

        static private void CommandWrite(byte address, ushort data) {
            CmdBuffer[0] = 0x02;
            CmdBuffer[1] = address;
            CmdBuffer[2] = (byte)(data >> 8);
            CmdBuffer[3] = (byte)data;


        static private ushort CommandRead(byte address) {
            CmdBuffer[0] = 0x03;
            CmdBuffer[1] = address;
            CmdBuffer[2] = 0;
            CmdBuffer[3] = 0;

            _spi.WriteRead(CmdBuffer, CmdBuffer, 2);

            ushort command = CmdBuffer[0];
            command <<= 8;
            command += CmdBuffer[1];

            return command;

        public static void SetVolumePercent(int volume) {
            if (volume < 0 || volume > 100)
                throw new ArgumentOutOfRangeException("volume");

            SetVolumePercent(volume, volume);

        public static void SetVolumePercent(int leftChannel, int rightChannel) {
            if (leftChannel < 0 || leftChannel > 100)
                throw new ArgumentOutOfRangeException("leftChannel");
            if (rightChannel < 0 || rightChannel > 100)
                throw new ArgumentOutOfRangeException("rightChannel");

            // TODO: Invert decibel value, divide by percent, call SetVolume(ushort leftChannel, ushort rightChannel)

        public static void SetVolume(ushort bothChannels) {
            CommandWrite(RegisterSciVol, bothChannels);  // TODO: This doesn't work outside the Initialize() method

        public static void SetVolume(ushort leftChannel, ushort rightChannel)
            SetVolume((ushort) (leftChannel*256 + rightChannel)); // TODO: Verify no loss of fidelity

        public static void SendData(FileStream fileStream)
            var size = fileStream.Length - fileStream.Length % BufferSize;
            for (var i = 0; i < size; i += BufferSize) {
                fileStream.Read(ReadBuffer, 0, BufferSize);


        public static void Shutdown() {
            if (!_isInitialized) return;



            _isInitialized = false;

I think there's a lot to be desired, but it's hopefully at least a good starting point for somebody and at least extends on my initial post to the Netduino forum that simply stated that the MP3 shield "worked."

Additional References: