Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Infrared UART - Wireless data/control

Status
Not open for further replies.

gramo

New Member
**broken link removed**

I put together a guide on how to transmit data via IR, and thus far I have been able to get in excess of 20 meters with the project **broken link removed**

This little example all came about when I wanted to make my own IR controlled applications, but the idea of a simple IR switch didn't really phase me, I wanted something that could transmit data back and forth. Taking a step sideways, I instantly though about UART (a one wire serial protocol), and how it could be used with a concept like this.

Before I go much further, a quick burst on IR. Infrared has its flaws, the primary issue is line of sight, although the LED's I used proved to be extremely effective at dispersing IR (I could even transmit around corners). The other issue to consider - is the amount of Infrared found in ambient light from the sun. It is after all just another spectrum of light, one that can not be detected by the human eye. So how does one go about transferring data in a reliable manner that accommodates for ambient IR being present? Answer; modulation.

In this case, the modulated signal has a carrier of 38Khz, and turns on/off to encode the data. The result is bursts of 38Khz signals being transmitted. Building a reliable receiver would be a tough task, but why re-invent the wheel when there are **broken link removed** available to do the job for you. This device will remain a logic high until it detects a 38Khz signal, and then it will go low (0V) if a signal is present;

**broken link removed**

The next task is to somehow turn UART data signals into 38Khz modulated IR... Why don't we utilise the onboard Pulse Width Modulation built into almost every PIC? If you setup the PWM output for 38Khz and 50% Duty Cycle, then the next objective is to somehow turn it on/off at the same time a UART output is normally on/off. I can think of two methods, one is to use a Logic AND gate, placing the PWM signal on one input, and the UART TX on the other - the result would be Modulated UART with a 38Khz carrier. But you can do this without the requirement of external components by controlling the Tristate status (input/output) of the PWM Pin. By making the PWM pin an input, you are turning off the 38Khz signal, and of course enabling it again when returned to an output. Here's what a snippet of a modulated signal would look like;

**broken link removed**

Creating infrared light is simple, there are many types of LED's available to do the job. Make sure though, for best performance, that the Infrared LED's wavelength matches the receiver for optimal performance. To get the best range, also use a high quality and powered **broken link removed**.

**broken link removed**

The Infrared LED can utilise much more current then the PIC can output, and there are a variety of methods to drive such devices. I prefer to use the ULN2003 or Logic Level MOSFET's for jobs like this. Note that the output of the PWM is tied down to earth with a 100K resistor. This is used to instantly shunt any residual voltage to earth when the pin is made an input - not so much required with the ULN2003, but is vital with MOSFET's. The 25ohm resistor in series with the LED was calculated by R = V/I where V = 5 (supply) - 1.6 (Vf of the LED) - 0.9 (Vf of the ULN2003) and I = 0.1 (If of the LED).
Therefore R = (5 - 1.6 - 0.9) / 0.1 = 25 ohm or greater

**broken link removed**

Transmit Program:
Code:
Device = 18F2550
Clock = 8
Config FOSC = INTOSCIO_EC

Include "INTOSC8.bas"
Include "pwm.bas"
Include "IR_UART.bas"
Include "convert.bas"

Dim Variable As Byte

// start of main program
PWM.SetFreq(38000, 50)
IR_UART.SetTX(PORTC.2)
IR_UART.SetMode(umTrue)
IR_UART.SetBaudrate(sbr300)

Variable = 0

Low(PORTC.0)
While True
    Inc(Variable)
    IR_UART.Write(Variable)
    DelayMS(500)
Wend

Receiver Program:
Code:
Device = 18F2550
Clock = 8
Config FOSC = INTOSCIO_EC

#option LCD_DATA = PORTB.4 
#option LCD_RS = PORTB.0
#option LCD_EN = PORTB.1

Include "INTOSC8.bas"
Include "pwm.bas"
Include "IR_UART.bas"
Include "convert.bas"
Include "lcd.bas"

Dim Variable As Byte


PWM.SetFreq(38000, 50)
IR_UART.SetRX(PORTC.2)
IR_UART.SetMode(umTrue)
IR_UART.SetBaudrate(sbr300)

DelayMS(150)
LCD.Cls
LCD.WriteAt(1,1,"IR UART")

While True
    IR_UART.Read(Variable)
    LCD.WriteAt(2,1,Convert.DecToStr(Variable,3))
Wend

All of the User Libraries can be download from the main guide here **broken link removed**
 
Last edited by a moderator:
Spency,

Another very clever and creative demo'. Bravo!

Have you experimented with baud rates and determined that 300 baud is the most effective for the performance and distances you're getting? Also, are you using the PWM module in the receiver code?

Your demo has me very excited about potentially using a little 8 pin 12F683 device with it's built-in 8 MHz oscillator and PWM module.

Mike
 
Last edited:
Spency,

Another very clever and creative demo'. Bravo!

Have you experimented with baud rates and determined that 300 baud is the most effective for the performance and distances you're getting? Also, are you using the PWM module in the receiver code?

Your demo has me very excited about potentially using a little 8 pin 12F683 device with it's built-in 8 MHz oscillator and PWM module.

Mike

Thanks Mike :eek:

You could go faster, so long as there are at least 6 cycles of the 38Khz signal for each bit being transmitted. I have been getting the best long range results with slower frequencies though

A couple of changes to the code have been made (I left the PWM settings in the receiver and can't edit them out now, damn 15 minute edit time frame), none the less its all updated on the site.
 
Spency,

Well 300 baud seems like a very impressive rate (to me) for those distances. And that receive code minus the PWM stuff makes more sense to me now. Thanks...

Regards, Mike
 
Last edited:
PLease help...it's very urgent as I'm giving this project to my friend for the city science exhibition.....

the IR_UART library isnt working here...
I saw the impressive tutorial in gramo's site.....really great...I can diaplay the SHT11 readings along with time from DS1307 RTC on a 16*2 LCD.....Now wanna transmit it via WUART(i mean wireless UART :) ) through IR waves to another PIC.

see how is it not working. I've included the include files as I've done many times before...when I use the code :

Code:
// start of main program
PWM.SetFreq(38000, 50)
IR_UART.SetTX(PORTC.2)
IR_UART.SetMode(umTrue)
IR_UART.SetBaudrate(sbr300)
............
IR_UART.Write(DecToStr(TempA,2),".",DecToStr(TempB,2),"%")

I get errors.....
without the iR_UART codes....it compiles right..I have tested the program and appeared to work fine

even this sample program wont work....

Code:
Device = 18F2550
Clock = 20

Include "pwm.bas"
Include "IR_UART.bas"

Dim Variable As Byte

// start of main program
PWM.SetFreq(38000, 50)
IR_UART.SetTX(PORTC.2)
IR_UART.SetMode(umTrue)
IR_UART.SetBaudrate(sbr300)

Variable = 0

Low(PORTC.0)
While True
    Inc(Variable)
    IR_UART.Write(Variable)
    DelayMS(500)
Wend


Another thing to doubt most when I open the IR_UART.bas include file I see this code: which I think is a code of swordfishe's UART module..and NOT a IR_UART....I downloaded the IR_UART.bas file from **broken link removed** aka gramo's PIC....anything wrong? the IR_UART.bas file shows :
Code:
{
****************************************************************
*  Name    : SUART.BAS                                         *
*  Author  : David John Barker                                 *
*  Notice  : Copyright (c) 2006 Mecanique                      *
*          : All Rights Reserved                               *
*  Date    : 28/05/2006                                        *
*  Version : 1.2                                               *
*  Notes   : 1.2 Replaced 'rcall' with 'call'                  *
*          : 1.1 Release version                               *
****************************************************************
}
Module UART

Include "system.bas"
               
Const
   CycleCost = 20,                          // TX and RX cycle cost
   FOSC = _clock * 1000000,                 // clock (MHz)
   tcy300 = (2 * FOSC) / (4 * 300) / 2,     // 300 baud Tcy
   tcy600 = (2 * FOSC) / (4 * 600) / 2,     // 600 baud Tcy
   tcy1200 = (2 * FOSC) / (4 * 1200) / 2,   // 1200 baud Tcy
   tcy2400 = (2 * FOSC) / (4 * 2400) / 2,   // 2400 baud Tcy
   tcy4800 = (2 * FOSC) / (4 * 4800) / 2,   // 4800 baud Tcy
   tcy9600 = (2 * FOSC) / (4 * 9600) / 2,   // 9600 baud Tcy
   tcy19200 = (2 * FOSC) / (4 * 19200) / 2, // 19200 baud Tcy
   tcy38400 = (2 * FOSC) / (4 * 38400) / 2, // 38400 baud Tcy - pushing the limits, high xtals only!
   tcy57600 = (2 * FOSC) / (4 * 57600) / 2  // 57600 baud Tcy - pushing the limits, high xtals only!


// calculate baud rate constants - these figures are one
// BitTime (BT) in microseconds (us). For example, 1 / 9600 baud
// gives 104.16 us. Taking into account the TX and RX cycle costs
// yields a figure of 100 us
Public Const
   sbr300 As Word = (tcy300 - CycleCost) / (_clock / 4),
   sbr600 As Word = (tcy600 - CycleCost) / (_clock / 4),
   sbr1200 As Word = (tcy1200 - CycleCost) / (_clock / 4),
   sbr2400 As Word = (tcy2400 - CycleCost) / (_clock / 4),
   sbr4800 As Word = (tcy4800 - CycleCost) / (_clock / 4),
   sbr9600 As Word = (tcy9600 - CycleCost) / (_clock / 4),
   sbr19200 As Word = (tcy19200 - CycleCost) / (_clock / 4),
   sbr38400 As Word = (tcy38400 - CycleCost) / (_clock / 4),
   sbr57600 As Word = (tcy57600 - CycleCost) / (_clock / 4)  

// public UART modes...
Public Const
   umTrue = 1,
   umInverted = 2,
   umOpen = 4,
   umOpenTrue = umOpen Or umTrue,
   umOpenInverted = umOpen Or umInverted 

// a pin structure...
Structure TPin
   AddrPort As Word
   Pin, PinMask As Byte
End Structure 

// private variables and aliases... 
Dim 
   FTX As TPin,                       // TX pin
   FRX As TPin,                       // RX pin
   FBaudrate As Word,                 // Baudrate (1 BT)
   FHalfBaudrate As Word,             // Half Baudrate (1/2 BT)
   FMode As Byte,                     // Mode (true, inverted)
   FPacing As Word,                   // write byte pacing (us)
   FTerminator As Char,               // read string terminator character
   FIsInverted As FMode.Booleans(1)   // inverted mode flag

// public variables...
Public Dim
   ReadTerminator As FTerminator,     // read string terminator
   Pacing As FPacing                  // write pacing (us) 
{
........ETC
the the GIF imgs.....
 

Attachments

  • IR.PNG
    IR.PNG
    103 KB · Views: 325
  • IR2.GIF
    IR2.GIF
    64.9 KB · Views: 253
  • IR3.GIF
    IR3.GIF
    64.1 KB · Views: 215
  • IR4.GIF
    IR4.GIF
    55.7 KB · Views: 224
  • IR5.GIF
    IR5.GIF
    70.9 KB · Views: 229
I am a bit confused. Why did you need the libraries?

You see I did two way IR 5 years ago and did not require any fancy libraries. Of course I needed the external carrier source since I was out of counters. I hung a counter directly off of the crystal and sent the Tx line to the enable pin, instant modulator. I was then able to actually reprogram the chip over the IR link.

As to the tristate pin stuff in the link, that will limit the transfer speed unless there is some screwy hardware in the PIC that does it for you.

Dan
 
I;m a pic novice..I know PICBasic and use swordfish.
I thought the 'fancy' library's should be easy....oooh...it was not.

Ubergeek, do you built it in swordfish, or in PICBASIC?

Where are you grammmmmmmmmmmooooooo, i mean spencyyyy
 
I'm 100% sure that it's not the correct library file "IR_UART.zip>>>IR_UART.bas"...isnt the library that either gramo told or i want...
 
I;m a pic novice..I know PICBasic and use swordfish.
I thought the 'fancy' library's should be easy....oooh...it was not.

Ubergeek, do you built it in swordfish, or in PICBASIC?

Where are you grammmmmmmmmmmooooooo, i mean spencyyyy
Neither. I designed the hardware and we simply wrote bytes out to the UART. The 89V51's own boot loader could reflash the chip at the 1200bps. The recievers are actually rated for 2400bps. It is in Cybex fitness equipment.

Dan
 
Last edited:
Neither. I designed the hardware and we simply wrote bytes out to the UART. The 89V51's own boot loader could reflash the chip at the 1200bps. The recievers are actually rated for 2400bps. It is in Cybex fitness equipment.

Dan

Ok.I understand.
Seeing what to do.
 
The IR library was not the correct one, its since been fixed and can be downloaded from the **broken link removed** or **broken link removed**

The reason why I use the libraries is to allow a very simplistic approach toward programming. It also allows standard integration for selecting the appropriate defines such as UART baud/mode as you would with the original Swordfish library. For example;

Code:
IR_UART.SetBaudrate(sbr1200)
or
Code:
IR_UART.SetBaudrate(sbr300)

Let me know how it goes, I'll reply to your email just in case you miss the reply here
 
Last edited:
Thanks gramo.

It has been fixed. Though I've not checked it yet. But I'll do soon.
And I'll let you know about it.

I'll post it here.

Thanks a bunch for fixing it.
Without Digital DIY, I could never be able to learn PIC programming. I'm still learning though.....
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top