Note: The source code for the project described in this post can be downloaded here.
This post is a continuation of my “Netduino Enters the Grove” article. Building on the project in that post, I’m going to make the Netduino a more productive member of society by having it display the time, in addition to the temperature.
I’m also going to add to the mix a couple more “twigs” from the Seeed Grove Starter Kit: the 8 x 2 LCD, and the piezo buzzer.
Lastly, I’m going to make use of the Netduino’s serial port to show how to make it communicate with a PC.
Adding the Grove Parallel LCD
The Grove Starter Kit comes with a rather odd LCD: a cramped 8 x 2 board bristling with 24 pins, 6 of them for voltage and 6 for ground.
Since documentation isn’t Seeed’s strong suit, this has led to some head-scratching about the best way to connect the LCD to an Arduino. I wasn’t too optimistic about getting it to work with a Netduino, which is one of the reasons I went with a serial LCD in my earlier post.
However, it turned out to be relatively straightforward to connect, thanks to Szymon Kobalczyk’s excellent MicroLiquidCrystal library.
The LCD connectors that you need to use are the 2 on the right and the 2 on the bottom. The pins are labelled on the back of the LCD’s ”stem” board – clockwise from the upper right connector (and ignoring the voltage and ground pins) they are RW, NC (unused), RS, EN, D4, D5, D6 and D7. These are the pins used in almost any LCD library based on the HD44780 chipset, including one of the constructors of the MicroLiquidCrystal library. (MicroLiquidCrystal supports other types of connections that use fewer digital ports, but for the purpose of testing the Grove LCD’s default configuration I’ll stick to the more traditional GPIO connection for this project).
The 2 key lines of code are:
GpioLcdTransferProvider lcdProvider =
new GpioLcdTransferProvider(rs, rw, enable, d4, d5, d6, d7);
Lcd lcd = new Lcd(lcdProvider);
In my project, I’ve added a wrapper class to MicroLiquidCrystal in order to make to compatible with the 2 other devices I use when testing: a Matrix Orbital serial LCD and a Sparkfun Serial LCD Backpack (as described in my earlier article). So, the code which calls the above methods is in the clsLCD_MLC constructor in the attached source code:
public clsLCD_MLC(Cpu.Pin rs, Cpu.Pin rw, Cpu.Pin enable, Cpu.Pin d4,
Cpu.Pin d5, Cpu.Pin d6, Cpu.Pin d7, byte rows, byte cols)
{
// NOTE - RW pin is needed for Seeed's Grove LCD
lcdProvider = new GpioLcdTransferProvider(rs, rw, enable, d4, d5, d6, d7);
//lcdProvider = new GpioLcdTransferProvider(rs, enable, d4, d5, d6, d7);
lcd = new Lcd(lcdProvider);
SetScreenSize(rows, cols);
lcd.Write("hello, world!");
Thread.Sleep(500); // greet the world and give the LCD time to get its act in order
The call to this code specifies what pins are being used. The configuration shown in the photos uses the following:
lcd = new clsLCD_MLC(Pins.GPIO_PIN_D4, Pins.GPIO_PIN_D13, Pins.GPIO_PIN_D5, Pins.GPIO_PIN_D9, Pins.GPIO_PIN_D10, Pins.GPIO_PIN_D11, Pins.GPIO_PIN_D12, 2, 8);
So, the 4 Grove cables are connected to the Grove shield using (clockwise from the upper right): D13/NC, D4/D5, D9/D10, DD11/D12. Actually, I’m pretty sure that any 4 connectors (or 7 pins) would work just as well. I went with these in order to save the serial port pins and one of the PWM pins for other uses.
The LCD tutorial in the Grove documentation suggests that a 6 pin connection is also possible (minus the RW pin), but I couldn’t get that to work with either the Arduino or Netduino.
By the way, if you are trying your Grove LCD for the first time and nothing appears on the screen, the first thing to check is the contrast control. This is a little metallic potentiometer on the LCD “stem” board – it looks like a brass screw-head. If you don’t see a line of block characters when you first power-up the LCD, then turn the potentiometer counter-clockwise, then try again.
There are a few drawbacks to the Grove LCD compared to other parallel LCDs. The first and most obvious is the size – 8 x 2 characters is OK for the time and temperature, but won’t be enough for future projects. The backlight is “always on”, with no easy way to control that. Presumably, it can be controlled by connecting one (hopefully not all 4!) of the connectors’ voltage pins to a digital PWM pin. However, I haven’t tried this myself yet). The 2 connectors on the bottom, combined with the stiff connector cables, makes mounting the LCD somewhat of a mechanical challenge, as you can see in the photo.
And yet it works. I tested the Netduino Time/Temperature gadget for a couple of days, and the LCD didn’t display any garbled characters or have any other problems.
Adding the Grove Piezo Buzzer
The buzzer connection is quite straightforward. You can connect it to any digital pin if you just want it to buzz, or to a PWM pin if you want to give it a greater musical range. The Netduino has just four PWM pins, 5, 6, 9 and 10. For the purpose of this project, I’m using pin 6.
Since PWM is not supported by the underlying Micro Net Framework, its implementation is left up to the hardware maker. As with Seeed Studios, documentation doesn’t seem to be Secret Labs’ strong suit – they definitely know how to keep a secret. This makes the process of controlling the buzzer a little tricky to figure out. I found the best source to be the full-featured and well-documented code in this post by Ray Mckaig on the Netduino forums.
This is a low-end buzzer, so its musical range runs the gamut from annoying to tortuous. The following code makes 2 types of sounds: an annoying ding-a-ling somewhat like a cordless phone (when the parm is true), or a tortuous beeeeeep that my cat really, really dislikes.
public static void Beep(bool blnUp)
{
blnBeeping = true;
float fltFreq = 10;
int intDuration = 1000;
if (!blnUp)
{
fltFreq = 30;
intDuration = 1000;
}
uint period = (uint)(1000000 / fltFreq);
buzzer.SetPulse(period, period / 2);
Thread.Sleep(intDuration);
buzzer.SetDutyCycle(0);
}
Setting the time through a serial port
One of the most noticeable differences between the .Net Micro Framework and the Arduino is that it is considerably more difficult to have a PC send commands to a NMF device. The Arduino uses the USB connection for this, but the NMF reserves the USB connection for use by the debuggers.(Secret Labs has recently added a firmware feature that allows your program to use the USB port as a serial device, and use one of the Netduino’s serial ports for deploying code and debugging, but I haven’t tried that out yet.)
When using a Netduino serial port for communication with a PC, you’ve got 2 problems: the voltage level sent and received on the Netduino’s pins (3.3V) is much lower than what the PC sends and receives, and the communication protocol used by the Netduino (TTL) is not the same as what the PC uses (RS-232).
Fortunately, there is a relatively inexpensive device that solves both problems: a 3.3V FTDI cable. This is widely available at hobby electronics retailers such as Adafruit and Sparkfun. If you use an Adafruit Boarduino, Solarbotics Ardweeny, Secret Labs’ own Netduino Mini, or some other microcontroller-based device that doesn’t include a USB port, then you probably already have this cable.
With the cable, connection of the Netduino to a PC pretty simple. Only 3 of the cable’s coloured connectors are used: the black cable (ground) should be connected to ground, the orange cable (TX) should be connected to the RX pin of one of the Netduino’s 2 COM RX pins (pin 0 or 2) and the yellow cable (RX) to one of the Netduino’s TX pins (1 or 3).
In the photo of my setup, I’ve inserted a 5 pin male header like this into the breadboard. You’ll need to adjust the pins in the header slightly so that they stick out about the same amount on both sides of the header. Since I’m using COM2 on the Netduino, the white jumper cable goes from the breadboard to pin 2 and the yellow jumper to pin 3.
The code to open the COM port is in the constructor of my “clsUART” class:
public clsUART(string strPort, Int16 intBaud, int intReadBufferLen, bool blnSendResponse)
{
SerialPort UART = new SerialPort(strPort, intBaud, Parity.None, 8, StopBits.One);
UART.Open();
UART.DataReceived += new SerialDataReceivedEventHandler(UART_DataReceived);
Debug.Print(strPort + " Opened at baud " + intBaud);
WriteToUART("Hello World");
And the call to this constructor is:
uart = new clsUART(SerialPorts.COM2, 9600, 50, true); uart.Command += new CommandEventHandler(uart_Command);
A couple of things to note about using the MNF’s SerialPort:
- In order to use the Net MF’s SerialPort class, the Project References must include a reference to Microsoft.SPOT.Hardware.Serial. This isn’t included by Visual Studio in a new Netduino project by default – it has to be added manually
One of the nice things about the FTDI cable is that the chip which handles the RS-232 communications with the PC is embedded in the cable, and therefore it is ready to go as soon as you plug the cable into the PC. You can then use PuTTY (or your serial terminal of choice) to connect to whatever COM port the PC assigns to the cable. If there is nothing at the other end of the cable, other terminal screen will remain empty, but you won’t get any errors either.
The Netduino is not too picky about its own COM port – you can power it on with nothing connected to the COM port pins and it will happily open that COM port without complaint.However, if you “hot plug” the FTDI cable into your Netduino when it is already up and running, you’ll likely find that the connection doesn’t automagically start working – you have to reset the Netduino’s COM port. I added some code to handle this by pressing and holding the red button. This toggles the COM state on or off, sends a message to the LCD, Visual Studio’s Debug window, and the PC serial’s terminal, and makes a buzzer noise (the annoying one when the port goes down, the tortuous one when the port comes back up).
If your PC’s serial terminal displays “Hello world” when the Netduino boots up, or “Hello again world” when you toggle the port open with the red button, then the Netduino is yours to command. It knows the following commands:
Set time: T:hh:mm[:ss] e.g. T:14:35 Set date: D:yyyy-mm-dd e.g. D:2010-12-29 Set temperature format (Celcius or Fahrenheit): F:F|C e.g. F:C Set LCD backlight: L:ON|OFF e.g. L:OFF Set LCD brightness: B:nnn where nnn is 0-255 e.g. B:128
The Netduino will respond to a valid command by sending “OK” to the terminal. Generally the LCD will immediately be updated with whatever setting you changed. However, in the case of the 8 x 2 Grove LCD setting the date and changing the backlight or brightness has no effect.
Should you enter a command that the Netduino doesn’t recognize, it will send a “?” to the terminal and making the annoying sound with the buzzer, so type carefully!
All things considered, this is probably the simplest way to set the time on the Netduino, but also the least convenient. (A clock that has to be set using a serial port – Grandma’s worst nightmare!).
In future posts, I plan to demonstrate a few other methods: an on-screen menu (more convenient, but lots of coding), an Ethernet shield (very convenient for the user – it sets itself – but not so convenient if you don’t happen to have an Ethernet port nearby) and a wireless XBee connection (very very convenient, très cool, and my platform of choice for a lot of projects).
Note: The source code for the project described in this post can be downloaded here. The .zip file contains 2 folders: one (ClockAndTemperature) with my source and one (MicroLiquidCrystal) with the MicroLiquidCrystal library. The latter is a separate project that is loaded by the ClockAndTemperature solution file. The 2 folders should therefore be stored in the same parent folder.



i like it