Hi,
here is the class for Gadgeteer Cerbuino Bee, which is taken from http://gadgeteer.codeplex.com/SourceControl/changeset/view/22997#256115 with your modifications and an example in Program.cs in which in addition the code of Justin ( http://www.tinyclr.com/forum/topic?id=8832&page=1 ) to use the SD-Card on Cerbuino Bee and a thread with blinking multicolour led is shown.
[using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using GTI = Gadgeteer.Interfaces;
using System.Threading;
namespace CerbuinoHD44780_Test
{
/// <summary>
/// A Display_HD44780 module for Microsoft .NET Gadgeteer
/// </summary>
public class HD44780 : GTM.Module
{
private GT.Interfaces.DigitalOutput LCD_RS;
private GT.Interfaces.DigitalOutput LCD_E;
private GT.Interfaces.DigitalOutput LCD_D4;
private GT.Interfaces.DigitalOutput LCD_D5;
private GT.Interfaces.DigitalOutput LCD_D6;
private GT.Interfaces.DigitalOutput LCD_D7;
private GT.Interfaces.DigitalOutput BackLight;
const byte DISP_ON = 0xC; //Turn visible LCD on // 1100
const byte CLR_DISP = 0x01; //Clear display
const byte CUR_HOME = 0x02; //Move cursor home and clear screen memory
const byte SET_CURSOR = 0x80; //SET_CURSOR + X : Sets cursor position to X
// 80 + 12 = 0x8C is the 13th
//###################################################################
// Additional commands from Nila "FEZ_Cerb40_LCD
const byte DISP_ON_CURSOR_ON = 0x0E; // 0000 1100 (by Nila)
const byte DISP_ON_CURSOR_OFF = 0x0C; // 0000 1110 (by Nila)
const byte DISP_OB_CURSOR_BLINK = 0X0F; // (by Nila)
const byte FOURBIT_ONELINE = 0X20; // 0010 0000 (by Nila)
const byte FOURBIT_TWOLINE = 0X28; // (by Nila)
const byte BLOCK = 0XFF; // (by Nila)
const byte BLANK = 0XFE; // (by Nila)
//####################################################################
// Note: A constructor summary is auto-generated by the doc builder.
/// <summary></summary>
/// <param name="socketNumber">The socket that this module is plugged in to.</param>
public HD44780(int socketNumber)
{
// This finds the Socket instance from the user-specified socket number.
// This will generate user-friendly error messages if the socket is invalid.
// If there is more than one socket on this module, then instead of "null" for the last parameter,
// put text that identifies the socket to the user (e.g. "S" if there is a socket type S)
GT.Socket socket = GT.Socket.GetSocket(socketNumber, true, this, null);
socket.EnsureTypeIsSupported('Y', this);
LCD_RS = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Four, false, null);
LCD_E = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Three, false, null);
LCD_D4 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Five, false, null);
LCD_D5 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Seven, false, null);
LCD_D6 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Nine, false, null);
LCD_D7 = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Six, false, null);
BackLight = new GT.Interfaces.DigitalOutput(socket, GT.Socket.Pin.Eight, true, null);
Initialize();
TurnBacklightOn();
// ShutBacklightOff();
Thread.Sleep(200);
}
/// <summary>
/// This function will enable the display, clean it, and enter 4-bit mode.
/// </summary>
private void Initialize()
{
LCD_RS.Write(false);
LCD_E.Write(false); // (by Nila)
// 4 bit data communication
Thread.Sleep(50);
LCD_D7.Write(false);
LCD_D6.Write(false);
LCD_D5.Write(true);
LCD_D4.Write(true);
LCD_E.Write(true);
LCD_E.Write(false);
// RS RW E D7 D6 D5 D4 hex 3
// 0 0 x 0 0 1 1
// 1-0
Thread.Sleep(50);
LCD_D7.Write(false);
LCD_D6.Write(false);
LCD_D5.Write(true);
LCD_D4.Write(true);
LCD_E.Write(true);
LCD_E.Write(false);
Thread.Sleep(50);
LCD_D7.Write(false);
LCD_D6.Write(false);
LCD_D5.Write(true);
LCD_D4.Write(true);
LCD_E.Write(true);
LCD_E.Write(false);
Thread.Sleep(50);
LCD_D7.Write(false);
LCD_D6.Write(false); // 0010b (2h)
LCD_D5.Write(true); // 4 bit mode high bits 0010
LCD_D4.Write(false);
LCD_E.Write(true);
LCD_E.Write(false);
SendCmd(FOURBIT_TWOLINE); // 0010 1000 (by Nila)
// SendCmd(DISP_ON_CURSOR_ON);
// SendCmd(DISP_OB_CURSOR_BLINK);
SendCmd(DISP_ON_CURSOR_OFF); // (by Nila)
SendCmd(CLR_DISP); // (by Nila)
// SendCmd(DISP_ON); // 0xC; //Turn visible LCD on // 0000 1100 (original Code)
// SendCmd(CLR_DISP); // 1 0000 0001 (original Code)
}
///<summary>
/// Sends an LCD command.
/// </summary>
private void SendCmd(byte c)
{
LCD_RS.Write(false); //set LCD to data mode
LCD_D7.Write((c & 0x80) != 0);
LCD_D6.Write((c & 0x40) != 0);
LCD_D5.Write((c & 0x20) != 0);
LCD_D4.Write((c & 0x10) != 0);
LCD_E.Write(true); LCD_E.Write(false); //Toggle the Enable Pin
Thread.Sleep(5); // (by Nila)
LCD_D7.Write((c & 0x08) != 0);
LCD_D6.Write((c & 0x04) != 0);
LCD_D5.Write((c & 0x02) != 0);
LCD_D4.Write((c & 0x01) != 0);
LCD_E.Write(true); LCD_E.Write(false); //Toggle the Enable Pin
Thread.Sleep(5); // (by Nila)
//Thread.Sleep(1); // (original Code)
LCD_RS.Write(true); //set LCD to data mode
}
// Additional Code by Nila ################################
public void SendData(byte c)
{
LCD_RS.Write(true); //set LCD to data mode
LCD_D7.Write((c & 0x80) != 0);
LCD_D6.Write((c & 0x40) != 0);
LCD_D5.Write((c & 0x20) != 0);
LCD_D4.Write((c & 0x10) != 0);
LCD_E.Write(true); LCD_E.Write(false); //Toggle the Enable Pin
Thread.Sleep(2);
LCD_D7.Write((c & 0x08) != 0);
LCD_D6.Write((c & 0x04) != 0);
LCD_D5.Write((c & 0x02) != 0);
LCD_D4.Write((c & 0x01) != 0);
LCD_E.Write(true); LCD_E.Write(false); //Toggle the Enable Pin
Thread.Sleep(2);
// LCD_RS.Write(false); //set LCD to data mode
}
// End Additional Code by Nila ################################
/// <summary>
/// Prints the passed in string to the screen at the current cursor position. Note: This function will move the cursor position after.
/// </summary>
/// <param name="str">The string to print.</param>
public void PrintString(string str)
{
Debug.Print("Ausgabe an LCD: " + str);
for (int i = 0; i < str.Length; i++)
Putc((byte)str[i]);
}
/// <summary>
/// Sends an ASCII character to the LCD at the current cursor position. Note: This function will move the cursor position after.
/// </summary>
/// <param name="c">The character to display.</param>
public void Putc(byte c)
{
/*
//##### Sends byte in hex and upper and lower half-byte to Debug.Print ##################
byte[] byteArray = new byte[1];
byteArray[0] = c;
Debug.Print(ByteExtensions.ToHexString(byteArray) + " " + c.ToString());
int CInt = (int)c;
CInt = CInt >> 4; //take upper half of byte
byteArray[0] = (byte)CInt;
Debug.Print(ByteExtensions.ToHexString(byteArray));
byteArray[0] = (byte)(c & 0x0F);
Debug.Print(ByteExtensions.ToHexString(byteArray));
//#############################################################
*/
// LCD_RS.Write(true);
LCD_D7.Write((c & 0x80) != 0); //upper half of byte
LCD_D6.Write((c & 0x40) != 0);
LCD_D5.Write((c & 0x20) != 0);
LCD_D4.Write((c & 0x10) != 0);
LCD_E.Write(true);
LCD_E.Write(false); //Toggle the Enable Pin
LCD_D7.Write((c & 0x08) != 0); //lower half of byte
LCD_D6.Write((c & 0x04) != 0);
LCD_D5.Write((c & 0x02) != 0);
LCD_D4.Write((c & 0x01) != 0);
LCD_E.Write(true);
LCD_E.Write(false); //Toggle the Enable Pin
//Thread.Sleep(5);
Thread.Sleep(1);
}
/// <summary>
/// Clears the screen.
/// </summary>
public void Clear()
{
SendCmd(CLR_DISP);
}
/// <summary>
/// Places the cursor at the top left of the screen.
/// </summary>
public void CursorHome()
{
SendCmd(CUR_HOME);
}
/// <summary>
/// Set the cursor to the passed in position.
/// </summary>
/// <param name="row">Row of the desired cursor position.</param>
/// <param name="col">Column of the desired cursor position.</param>
public virtual void SetCursor(byte row, byte col)
{
byte[] row_offsets = new byte[4] { 0x00, 0x40, 0x14, 0x54 };
SendCmd((byte)(SET_CURSOR | row_offsets[row] | col));
}
/// <summary>
/// Turns the backlight on.
/// </summary>
public void TurnBacklightOn()
{
BackLight.Write(true);
}
/// <summary>
/// Turns the backlight off.
/// </summary>
public void ShutBacklightOff()
{
BackLight.Write(false);
}
}
}/code]
Example:
using System;
using System.Threading;
using System.IO;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using GHI.OSHW.Hardware;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;
namespace CerbuinoHD44780_Test
{
public partial class Program
{
// for LCD Display
int socketNumber = 1;
HD44780 MyHD44780;
// for SD-Card
private GT.Timer _timer;
private string _root;
// for MulticolorLED
Thread LedThread;
// This method is run when the mainboard is powered up or reset.
void ProgramStarted()
{
// Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
Debug.Print("Program Started");
GHI.OSHW.Hardware.StorageDev.MountSD();
if (VolumeInfo.GetVolumes()[0].IsFormatted)
{
_root = VolumeInfo.GetVolumes()[0].RootDirectory;
// Debug.Print("SD is formatted");
// Debug.Print(_root);
}
else
{
Debug.Print("SD is not formatted");
}
// every 10000 ms something is written to SD-Card
_timer = new GT.Timer(10000);
_timer.Tick += new GT.Timer.TickEventHandler(_timer_Tick);
_timer.Start();
MyHD44780 = new HD44780(socketNumber);
MyHD44780.Clear();
Thread.Sleep(50);
MyHD44780.PrintString("Hello TinyCLR");
MyHD44780.TurnBacklightOn();
Thread.Sleep(200);
LedThread = new Thread(BlinkLeds);
LedThread.Start();
// Alternative if HD44780 Module is used
/*
display_HD44780.Clear();
display_HD44780.PrintString("Hallo World");
display_HD44780.TurnBacklightOn();
*/
}
void _timer_Tick(GT.Timer timer)
{
Debug.Print("Timer ticked!");
string fileName = Path.Combine(_root, "file.txt");
Stream stream;
if (File.Exists(fileName))
{
stream = File.OpenWrite(fileName);
stream.Position = stream.Length;
}
else
{
stream = File.Create(fileName);
}
using(var writer = new StreamWriter(stream))
{
writer.WriteLine(Guid.NewGuid().ToString());
}
stream.Dispose();
Debug.Print("Written to file");
}
void BlinkLeds()
{
while (true)
{
multicolorLed.TurnGreen();
Thread.Sleep(1000);
Debug.Print("Blink blue!");
multicolorLed.BlinkRepeatedly(GT.Color.Blue);
Thread.Sleep(5000);
multicolorLed.BlinkRepeatedly(GT.Color.Red);
Thread.Sleep(5000);
}
}
}
}