PicBasic Pro, PicBasic, BASIC Stamp, Microchip PIC, 8051, and Remote Control Projects


Building a Wireless Infrared Temperature Transmitter / Receiver
Using Visual Basic & The PicBasic Pro Compiler

I receive a lot of e-mail asking how to write simple VB applications to use with PIC projects.  Most are interested in how to separate incoming data bytes, and use the separate data extracted from the serial packet.  This can be mildly perplexing if you're new to VB, but it's really not too big a chore once you've seen a few simple examples.


Screen Shot of Finished Application

It's relatively simple to receive serial data from a PIC attached directly to the PC serial port, so to make this project a little more interesting - we'll build an infrared temperature transmitter to send the remote temperature data to the PC.  For the receiver we'll use the simple circuit shown below. For the temperature transmitter we'll use the PIC16F28, a TSAL610 10° beam-angle IRLED, and the DS18B20 12-bit 1-wire temperature sensor from Dallas semiconductor..

The Receiver Circuit:

Below is a simple circuit showing how to receive the wireless IR data sent from the PIC.



PC IR Receiver Circuit

The IR Transmitter Circuit:

I prefer simple if at all possible, and with the PIC16F628 hardware PWM, we can get by with this simple circuit for our IR transmitter.  Remember that the "idle state" for inverted serial communications is logic 0..? Well, here's where knowing this comes in handy. We use this logic 0 to hold our IRLED off during non transmit periods.

This simple arrangement lets us send serial data modulated at the IR detectors band-pass frequency of 40kHz with only "2" external components. You could Pop one of these simple circuits into your next robotics application for serial IR communications on a budget.  Pretty slick don't you think...;o]

PortB.1 will send serial data to the anode side of our IRLED. Using inverted serial mode, this ensures the LED stays OFF during idle or "non-transmit" periods. The PIC16F628 internal hardware PWM is configured to output a 40KHz PWM signal on CCP1 or PortB.3. This provides the data "carrier" frequency we need when using off-the-shelf IR detector modules like the TSOP1140. We'll setup our carrier frequency or PWM to run at 50% duty.

To figure the current limiting resistor size & peak current through the IRLED, use the following calculation.

The Peak-Current through the infrared LED will be:

= the peak pulsed current through the infrared LED.
= the operating voltage. Here it is +5 VDC.
= the voltage drop across the infrared LED. For the
TSAL6100 this is ~1.6V.
= the current-limiting series resistor used between the PortB.3 I/O-pin, and the infrared LED.

We know the PIC I/O-pin can handle up to 25mA, so we'll use a 220-ohm series resistor for +5V - 1.6V = 3.4V / 220-ohm = 15mA. This keeps us well within the limitations of the PIC I/O-pin with room to spare. We'll have a peak current through the LED of approx 15mA, and an average current of Ip * Df or 15mA * 50% = 7.7mA. If you need more range just decrease the series resistor, but keep the "peak" current at or below 25mA. I get well over 30' operation with the 220-ohm resistor and the TSAL6100 IRLED. We keep plenty of these goodies in stock in our Remote Control Store HERE if you need them.

Your mileage may vary depending on ambient lighting conditions.

The Temp Sensor Circuit:

Don't guess we need a lot of explanation here. The PIC16F628 reads the temperature value from the DS18B20 via PortB.0. Pretty simple stuff here.

The PIC16F628 Code:

'****************************************************************
'*  Name    : F628_IRTX.BAS                                     *
'*  Notice  : Copyright (C) 2003 Reynolds Electronics           *
'*  Version : 1.0                                               *
'*  Notes   : PIC16F628 IR Temp Transmitter                     *
'****************************************************************
   
@ DEVICE HS_OSC, LVP_OFF, MCLR_OFF, WDT_OFF
    DEFINE       OSC 20        ' We're using a 20MHz oscillator
   
DQ           VAR PORTB.0   ' One-wire Data-Pin "DQ" on PortB.0
   
Busy         VAR BIT       ' Busy Status-Bit
   
Temp         VAR WORD      ' RAW Temperature readings
   
Sync         CON 254       ' Sync byte = 254
   
Term         CON 85        ' Data packet termination byte = 85
   
Baud         CON 17197     ' 1200 baud, inverted, N,8,1
   
Skip_ROM     CON $CC       ' Skip ROM search command
   
Start_Conv   CON $44       ' Start temp conversion command
   
Read_Scratch CON $BE       ' Read scratch pad memory command
   
' Initialize hardware PWM - IRLED 40KHz drive
   
PORTB     = %00000000  ' PortB = 0 : IRLED On PortB.1 Off
   
TRISB     = %00000000  ' PortB = all outputs
   
CCPR1L    = 62         ' Set PWM Duty-Cycle to 50%
   
PR2       = 124        ' Set PWM for 40KHz
   
CCP1CON   = %00001100  ' Mode select = PWM
   
T2CON     = %00000100  ' %00000100 = TMR2 ON 1:1  pre-scale
                           ' %00000101 = TMR2 ON 1:4  pre-scale
                           ' %00000110 = TMR2 ON 1:16 pre-scale
Start_Convert:
    OWOUT   DQ, 1, [Skip_ROM,Start_Conv]' Skip ROM search & do temp conversion
   
Wait_Up:
    OWIN    DQ, 4, [Busy]                      ' Read busy-bit
   
IF      Busy = 0 THEN Wait_Up              ' Still busy..?
   
OWOUT   DQ, 1, [Skip_ROM,Read_Scratch]     ' Skip ROM / read scratchpad memory
   
OWIN    DQ, 2, [Temp.Lowbyte,Temp.Highbyte]' Read two bytes / end com
   
SEROUT2  PORTB.1,Baud,[Sync,Temp.Highbyte,Temp.LowByte,Term]
    '                                220    IRLED
    ' 40KHz PWM Out on PortB.3 -----/\/\/\---|<|------ PortB.1 Serial
   
PAUSE   500           ' 1/2 S delay
   
GOTO    Start_Convert ' Do everything again
 

Moving On To The VB Part:

We'll stash our incoming four bytes of serial data in a four byte array.  We'll create the array using: Dim Dat(4) as shown below. We'll look for the synch byte in Dat(1) - followed by two data bytes holding the temperature value in Dat(2) & Dat(3), and then finally we'll look for a data packet terminator in Dat(4).  If we successfully receive the synch byte, and the packet terminator, it's very likely we have successfully received our two bytes of temperature data in the middle of the serial stream.

NOTE: Refer to the PicBasic Pro code above, and you'll notice we're sending the synch byte of 254, followed by the temperature high byte, then low byte, then the packet terminator value of 85. This is all used in our VB code below. Data will consist of the four following bytes.

The Synch Byte:

I randomly chose a value of 254 for the synchronization byte.  This gives us something to look for in the beginning of each data packet, and helps to "synch" the application to the external data transmitting source.  Very simple, yet effective.

Two Byte Temperature Value:

The DS18B20 temp sensor outputs temperature values in two bytes.  Notice how we take the "high byte" and convert it in Dat(2) by Dat(2) * 256, then add it to Dat(3) to form the "word" sized result from our two byte-sized temperature data variables.  Once we have re-created the word sized result, we can perform the calculation on the word to compute the temperature result. For more details on the DS18B20 temp sensor, and data formats, refer to the DS18B20 datasheet or my previous articles on using this sensor HERE.

For your convenience, I have loaded the DS18B20 datasheet onto our site HERE. Just right-click the link, and select "save as" to save the datasheet to your PC.

The Terminator:

The packet terminator will be the number 85. This gives us two bytes - the synch byte & terminator byte to use to detect possible data errors in our wireless transmission. There are other techniques like CRC, but we'll keep this one simple. This simple technique works great for sending small data packets in applications like this one.

To use thee VB code below --

bulletCreate a new project in VB
bulletCut & paste the VB code shown below into the new project
bulletDrop the MSComm ActiveX Control onto the form somewhere
bulletAdd a command button to exit the application
bulletAdd two labels to the form
bulletSelect the MSComm Control with your mouse
bulletIn the "Project Properties" window set the MSComm Control settings to 1200,n,8,1
bulletYou're ready to roll...!

Note: You will need the Pro or Enterprise version of Visual Basic which includes the MSComm ActiveX Control. The code shown below was created & tested using Visual Basic Pro v6, but should work fine with earlier versions of VB that include the MSComm ActiveX Control.. The temp conversion calculations were done on multiple lines so they would fit on this page. They get pretty long when condensed into single lines.

The VB Code:

Dim dat(4) ' Declare our 4-byte array
Private Sub Command1_Click() ' Attach code to command button for exit
   If MSComm1.PortOpen = True Then
      MSComm1.PortOpen = False
   End If
   End

End Sub
Private Sub Form_Load() ' Form Load Code
Dim TempC

    MSComm1.Settings = "1200,N,8,1" 'Set baud rate
    MSComm1.CommPort = 1            'Set comm port
    MSComm1.PortOpen = True         'Open comm port
    Form1.Visible = True            'Show the form
 Do
Start:
    For n = 1 To 4 'Get 4 Bytes in Packet
      Do
       DoEvents
        Loop Until MSComm1.InBufferCount > 0
        dat(n) = Asc(MSComm1.Input) 'Store bytes in Array
        Debug.Print dat(n) ' Debug purposes only
        If dat(1) <> 254 Then GoTo Start 'Sync byte in first element?
    Next n
        If dat(4) <> 85 Then GoTo Start 'Packet terminator in last element?
        If (dat(2) And 128) <> 128 Then 'Negative temp?
          TempC = ((dat(2) * 256) + dat(3)) * 0.0625 'Convert deg C
          Label1.Caption = "+" & (TempC) & " C"      'Display C
          Label2.Caption = "+" & ((9 / 5 * TempC) + 32) & " F" 'Display F
        End If
        If (dat(2) And 128) = 128 Then 'Negative temp?
          dat(2) = ((-dat(2)) And 7) * 256 'Invert, mask 3 lsb's, shift
          dat(3) = -dat(3)            'Invert lower byte
          TempC = (-dat(2) + -dat(3)) 'Form word value
          TempC = ((TempC + 1) * 0.0625) 'Convert -deg C
          Label1.Caption = "-" & TempC & " C" 'Display -C
          Label2.Caption = "-" & ((9 / 5 * TempC) + 32) & " F" 'Display -F
        End If
 Loop
    
End Sub

That's it..! Now you're ready to tackle your next PIC projects with your own custom VB interface, and you know how to separate incoming data bytes from the serial stream to work with. Now how about an infrared wireless temperature + A/D transmitter with VB remote display interface...?

Who said this wasn't FUN & easy....;o]

If you're new to all this, and don't own the PicBasic Pro Compiler, click HERE to purchase PicBasic Compilers - and hardware. Visit the link HERE to return to our PicBasic projects section.

Until the next project - have fun - and don't blow anything up...;o]

Regards,

-Bruce


Back to the PicBasic Projects Section

Copyright © 1999-2008 Reynolds Electronics

| Contact Information |