C ++ is used in wince to implement remote control TV on the handheld computer

Source: Internet
Author: User
C ++ is used in wince to implement remote control TV on the handheld computer

1. Introduction

Have you ever thought about using the IR port on your handheld computer to control your TV, hi-fi, or other videos? This article describes how to use the IR port in the handheld computer to program and control a TV.

2. Background

I have lost my vintage Sony TV remote control in recent days. This is not a problem because I bought a new remote control. However, when the TV loses its set color, I encountered a problem because it only displays black and white, and the new remote control does not have a color adjustment button. I decided to write a program on my older Jornada 525 handheld computer and use the IR port to send the correct code to TV.

There are three main protocols that can be used to send IR code to the device. Sony TV uses the 'pulse coded' method. It needs to send a data stream containing the '1' and '0' spaces separated by the header bits. These bits are modulated into a 40 kHz carrier signal. The header length is 2200 μs, The '1' is 110 μs, the '0' is 550 μs, and the space is 550 μs silence (SILENCE ). Most Sony devices use 12-bit data, which is separated into 6-bit addresses (device type) and 6-bit commands. Therefore, the data looks like this: hxxxxxxyyyyyy, where H is the first bit, xxxxxx is the 6-bit command (MSB first), and yyyyyy is the 6-bit address. I will not elaborate on this because there are many resources on the Internet to describe this protocol and list the code for different devices. Some new Sony devices use 19-bit code, and I believe other manufacturers use the same format as I described. It is also possible to write similar classes for devices using the 'Space coded' or 'shift coded' protocol.

I used Embedded C ++ to write a cirpulse class that encapsulates the ability to control Sony and Its Matching devices from a Jornada 3.0 PC running Windows CE 525. It is estimated that it can work with other matching devices and operating systems, but you need to test it!

3. Implementation Process Analysis

This cirpulse class exposes several functions that make sending IR code as easy as possible. When declaring the cirpulse class, you should call findirport (). It returns a uint describing the port number of the IrDA port, which is obtained by searching the registry. This port number is used for subsequent calls to open the IrDA port for serial communication.

Uint cirpulse: findirport ()
{
// Query the IR port number in the Registry
Hkey = NULL;
If (regopenkeyex (HKEY_LOCAL_MACHINE, _ T ("Comm // IrDA"), 0, 0, & hkey) = error_success)
{
DWORD dwtype = 0;
DWORD dwdata = 0;
DWORD dwsize = sizeof (dwdata );
If (regqueryvalueex (hkey, _ T ("Port"), null, & dwtype, (lpbyte) & dwdata, & dwsize) = error_success)
{
If (dwtype = REG_DWORD & dwsize = sizeof (dwdata ))
{
Regclosekey (hkey );
Return (uint) dwdata;
}
}
Regclosekey (hkey );
}
Return 0;
}

After obtaining the port number, you can call the open (uint) function to pass the port number obtained by calling findirport. This enables the port and sets the serial port parameters. If the port is successfully set, true is returned. This port is set to 115200 port, 8 data bits, 2 Stop bits, and parity bits. This article describes how to generate a carrier and why I use these settings.

Bool cirpulse: open (uint uiport)
{
Assert (uiport> 0 & uiport <= 255 );
Close ();
// Open the IrDA Port
Cstring strport;
Strport. Format (_ T ("Com % d:"), uiport );
M_irport = createfile (lpctstr) strport, generic_read | generic_write, 0, null, open_existing, 0, null );
If (m_irport = invalid_handle_value)
{
Return false;
}
// Set the size of the input and output buffer.
Verify (setupcomm (m_irport, 2048,204 8 ));
// Clear the read and write buffer
Verify (purgecomm (m_irport, purge_txabort | purge_rxabort |
Purge_txclear | purge_rxclear ));
// Reinitialize all IrDA port settings
DCB;
DCB. dcblength = sizeof (DCB );
Verify (getcommstate (m_irport, & DCB ));
DCB. baudrate = cbr_115200;
DCB. fbinary = true;
DCB. fparity = true;
DCB. foutxctsflow = false;
DCB. foutxdsrflow = false;
DCB. fdtrcontrol = dtr_control_disable;
DCB. fdsrsensiti.pdf = false;
DCB. ftxcontinueonxoff = false;
DCB. foutx = false;
DCB. finx = false;
DCB. ferrorchar = false;
DCB. fnull = false;
DCB. frtscontrol = rts_control_disable;
DCB. fabortonerror = false;
DCB. bytesize = 8;
DCB. Parity = evenparity;
DCB. stopbits = twostopbits;
Verify (setcommstate (m_irport, & DCB ));
// Set the timeout value for all read and write operations
Commtimeouts timeouts;
Verify (getcommtimeouts (m_irport, & Timeouts ));
Timeouts. readintervaltimeout = maxdword;
Timeouts. readtotaltimeoutmultiplier = 0;
Timeouts. readtotaltimeoutconstant = 0;
Timeouts. writetotaltimeoutmultiplier = 0;
Timeouts. writetotaltimeoutconstant = 0;
Verify (setcommtimeouts (m_irport, & Timeouts ));
DWORD dwevent = ev_txempty;
Setcommmask (m_irport, dwevent );
Return true;
}

Call the setcodesize (DWORD) function to set the number of digits to be transferred (such as 12 digits ). This can be done at any time and only once. It remains valid until the subsequent call changes it.

Finally, call sendcode (long) to pass the code to be sent.

Bool cirpulse: sendcode (DWORD lvalue)
{
DWORD dwcount;
Int I = 0;
Assert (idatalength> 0 );
// Clear the Transfer Buffer
Verify (purgecomm (m_irport, purge_txabort | purge_rxabort | purge_txclear | purge_rxclear ));
// Set the code six times by pressing the key each time
For (INT x = 0; x <6; X ++ ){
Makestream (lvalue); // send code
Dwcount = gettickcount ();
While (gettickcount () <dwcount + 26) // delay of 26 Ms
I ++;
}
Return true;
}

Note that this function calls another function makestream (long) six times, and every two calls pause for 26 milliseconds. I found that this code must be sent several times to receive responses from the device, probably to prevent false behaviors. 26 Ms is required for receiving devices to register this code before the next code appears.

This function makestream (long) writes the byte stream to the irport and ensures that the correct packet length is sent based on whether the start bit (1 or 0) exists. A buffer that contains data bytes (0xdb) exists in the form of a bytearray.

Function close () is used to disable irport after the port is used.

This function runs well on my ornada. Please refer to the following discussion to further determine the possible changes you want to make.

Bool cirpulse: makestream (DWORD lvalue ){
DWORD dwstreamlength;
// Create start pulse
Dwstreamlength = ihpulse/charwidth;
Assert (write (const char *) bpulsestream. getdata (),
Dwstreamlength) = dwstreamlength );
//************************************
// ***** Delay for a period before the next pulse arrives
//************************************
// Send a pulse in the cyclic operation code
For (INT I = 0; I <idatalength; I ++ ){
If (lvalue & 1 ){
// Create a pulse 1
Dwstreamlength = i1pulse/charwidth;
Assert (write (const char *) bpulsestream. getdata (),
Dwstreamlength) = dwstreamlength );
//*********************************
// *** Delay for a period of time before the next pulse arrives
//*********************************
}
Else {
// Create a pulse 0
Dwstreamlength = i0pulse/charwidth;
Assert (write (const char *) bpulsestream. getdata (),
Dwstreamlength) = dwstreamlength );
//********************************
// ** Delay for a period of time before the next pulse arrives
//********************************
}
Lvalue> = 1;
}
Return true;
}

I included a simple application in the source code that uses cirpulse to create a Sony TV remote control. It provides basic channel selection, volume adjustment, and on/off functions.

4. Special attention

Because the cirport class uses a serial port to connect to the IR port, a 40 kHz carrier signal must be generated, which is achieved by sending appropriate characters from the serial port. Fortunately, if we send the character 0 x dB, with 115200 port, with 8 data bits, 2 Stop bits, and parity, we can generate a carrier signal very close to 38.4khz. It is okay for all our Sony devices to receive such data.

The biggest problem is how to implement the silence period between each pulse. It is impossible for the serial port to generate this silence period, because even if you send a 0x0 character, you still get a pulse on the IR because of the Start and Stop bits. I tried it by sending different characters, based on the premise that if you do not send a carrier signal at a 40 kHz frequency, this may make the device mistakenly regard this as a silence. The advantage of this is that you can generate a bytearray containing the complete code to ensure accurate timing. However, the results are inconsistent, So I refuse to use this method, in order to enable the pause between two numbers of 0 x dB characters from the serial port. Because the latency is 550 μs, so far I have not found a way to get a pause independent of the processor speed. In my Jornada, there is no need to have a latency because each call to the write function seems to have used a suitable time limit. In any case, I am worried that you may have a random delay that can make your handheld computer work.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.