LCDPlus


The following program can be used to test all of the available functionality of the LCD Plus shield including: LCD display; variable backlight control using Pulse Width Modulation (PWM); reading a DS18B20 temperature sensor using the One Wire (OW) protocol; reading a light sensitive resistor using Analog to Digital Conversion (ADC); reading and writing to a DS1307 Real Time Clock (RTC) using the I2C protocol; reading from the 5 button keypad using ADC; writing date, time and temperature readings to the onboard SD card slot.

The imported files used (for example, LCDDogm, DS1307 etc) are all part of the Firewing compiler install, so all you need to do is build the LCD Plus test program shown below and you should be good to go. Use the keypad "up and down" buttons to change brightness and "left and right" to change display contrast. Pressing button "S5" will display the current value obtained from the light sensor. The program will record date, time and temperature to a comma delimited file every minute, assuming an microSD card is plugged in. If using an SD card, enure it is correctly formatted for FAT 32 before using.

When using the sample code for the first time, you will need to set the real time clock. To do this, ensure a backup battery is installed on your board and then enter the time you wish to set using the subroutine SetRTC(). You would normally set this a few minutes into the future, as we will need to synchronise the time later. Also, make you you remove the comments that disable the call to SetRTC(). For example,

' set the clock, if required...  
SetRTC()

You now need to

  • Build and then program your sample code into the main Firewing development board.
  • Wait until a clock or watch shows the same time you previously programmed, then press the reset button. This will synchronise the real time clock time to real world time.
  • Put the comment back in before the call to SetRTC().
  • Build the program again and reprogram. This will ensure that next time your code runs, the real time clock value is not changed.

The full source code can be download from here.

Program Listing

' enable this line if using a 3 line LCD
' #option LCD_DOGM = DOGM_163

' file imports...
imports LCDDogm                      ' import DOGM LCD library
imports DS1307                       ' import RTC module
Imports OW                           ' one wire, used for search
Imports DS18B20                      ' temperature sensor module
imports SD                           ' secure digital (SD) module

' program variables...
private DS18B20_Available As Boolean = False ' DS18B20 is available flag
private Time As RtcTime                      ' time variable
private Date As RtcDate                      ' date variable

' the event is triggered each time the OW module is asked to
' perform a search - in this example, we are going to be looking 
' for an DS18B20 device, which has a family ID of 0x28 (owDS18B20)...
Sub OnDeviceFound(command As Byte, family As Byte, ByRef romID() As Byte, ByRef abort As Boolean) Handles OW.OnSearch
   If command = owSearchROM And family = DS18B20.Family Then
      DS18B20_Available = True   ' mark as available
      DS18B20.ROMID = romID     ' set the unique ROM id... 
      abort = True              ' no more searching required   
   End If
End Sub

' main program entry point...
sub Main()  
   dim sdAvailable as boolean = SD.Init() = errOK 
   dim canWriteToSD as boolean = true   
   Console.Write("sdAvailable = ", cstr(sdAvailable),13,10)

   ' look for attached temperature sensor...
   OW.Search()
   If DS18B20_Available Then DS18B20.SetResolution(Resolution.Is9Bit)

   ' clear LCD and set backlight        
   Dogm.Clear  
   Dogm.SetBacklight(160)  

   ' set the real time clock, you should only have
   ' to do this once if backup battery is installed... 
   ' SetRTC()   

   ' loop forever...
   while true

      ' read time and date...
      Time = DS1307.ReadTime()
      Date = DS1307.ReadDate()  

      ' display time and date to LCD...
      Dogm.WriteAt(1,1,Str(Time.Hour, 2),":",Str(Time.Minute,2),":",Str(Time.Second,2))
      Dogm.WriteAt(2,1,GetDay(Date.DayOfWeek))
      Dogm.WriteAt(2,5,Str(Date.Day,2))
      Dogm.WriteAt(2,8," ", GetMonth(Date.Month)," 20",Str(Date.Year,2))

      ' key control... 
      dim Key as byte = Keypress
      select Key    

         ' key down
         case 2 : 
            Dogm.SetBacklight(Dogm.GetBacklight - 1)
            delayms(10)   

         ' key up
         case 4 : 
            Dogm.SetBacklight(Dogm.GetBacklight + 1)
            delayms(10)

         ' key right...
         case 3 :     
            Dogm.SetContrast(Dogm.GetContrast + 1)
            delayms(100)

         ' key left...
         case 5 :     
            Dogm.SetContrast(Dogm.GetContrast - 1)
            delayms(100)            
      end select   

      ' if enter pressed, display light sensor....
      if Key = 1 then
         dim sensor as ushort = Adc.Read(A1)
         Dogm.WriteAt(1,11,"  ", str(sensor,4)) 

      ' if enter not selected, display temperature...
      elseif Key = 0 and DS18B20_Available then  
         DS18B20.Convert()
         Dogm.WriteAt(1,11, DS18B20.AsString, &HDF, "C") 

         ' write to SD card...  
         if Time.Second > 0 then canWriteToSD = true
         if sdAvailable and canWriteToSD and (Time.Second = 0) then
            canWriteToSD = false
            if not SD.FileExists("log.csv") then
               SD.Create("log.csv")
               SD.Close()
            end if
            if SD.Append("log.csv") = errOK then 
               SD.Write(Str(Date.Day,2), "/")
               SD.Write(Str(Date.Month,2), "/")
               SD.Write(Str(Date.Year,2))
               SD.Write(",")
               SD.Write(Str(Time.Hour, 2),":",Str(Time.Minute,2))
               SD.Write(",")
               SD.Write(DS18B20.AsString)
               SD.Write(13,10)
               SD.Close()
            end if             
         end if 
      end if
   end while
end sub

' return the day of the week as a string value...
Function GetDay(index As Byte) As String
   if (index < 1) or (index > 7) then return "XXX"
   Const days(7) As String = {"MON", "TUE","WED", "THU", "FRI", "SAT", "SUN"}
   return days(index - 1)
End Function

' return month as a string value...
Function GetMonth(index As Byte) As String
   if (index < 1) or (index > 12) then return "XXX"
   Const months(12) As String = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"}
   return months(index - 1)
End Function          

' set RTC... 
Sub SetRTC()

   ' set the time... 
   With Time, Time.Mode
      .Hour = 10
      .Minute = 22
      .Second = 0
      .Is12Hour = false
      .PM = false
   End With
   DS1307.WriteTime(Time)

   ' set the date...  
   With Date
      .Day = 1
      .DayOfWeek = 1
      .Month = 4
      .Year = 13
   End With
   DS1307.WriteDate(Date)   

End Sub

' get keypress...
function Keypress() as byte
   dim voltage as ushort = Adc.Read(A0)
   Keypress = 0 
   select voltage
      case 0     : Keypress = 1  ' select
      case < 200 : Keypress = 2  ' down
      case < 400 : Keypress = 3  ' right
      case < 600 : Keypress = 4  ' up
      case < 800 : Keypress = 5  ' left
   end select
end function