|
|
||||||||||||||||
| 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.
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.
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:
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:
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 --
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 SubPrivate 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
|