The easiest option for you guys, I think would be to wrap some commands in a DLL or library (preferable C) I can use, or just a c++ class. If you could provide raw timing information that would be perfect, mostly a copy and paste effort to get your receiver working. But if you can only provide decoded RC5 signals, that might require more than copy and paste, but should work nicely, albiet only with RC5 remotes.
The streamzap remote i recently supported, they gave me an API like this
extern "C" __declspec(dllimport) BOOL sz_Open(void);
extern "C" __declspec(dllimport) BOOL sz_Close(void);
extern "C" __declspec(dllimport) BOOL sz_ReadFile(BYTE *pData, LPDWORD lpNumberOfBytesRead);
extern "C" __declspec(dllimport) void sz_Flush(void);
which is perfect really. I guess you might need a little more to setup the com port correctly. Theres 2 methods I think people really use for this. A call back function in another thread, or simply polling the device every 1/10th of a second or so to see if it has data. I prefer a call back function personally, but either are fine :)
WinLIRC is back in active development. Here's what the developer said we need to do to get it working with the IR Toy.
I think I will add a new mode that measures the time between state changes, I believe that is what he means by raw timing info. That's a much less bandwidth intensive protocol than the sampling we've done previously. I don't know why the ir toy doesn't have one already :)
If the hardware is based on IRMan, the 6 byte code should map directly to LIRC_MODE_LIRCCODE. However, according to the LIRC webpage,
any, but config file receiver specific,
It says on the LIRC website that IRMan ones basically need their own config files, which kinda sucks. If possible I'd go with raw timing information. Something like this
space 1917573
pulse 3529
space 1727
pulse 477
space 412
pulse 458
space 1277
The timing is in µs. Normally receivers are accurate to 50-250µs. 250µs is probably the upper limit though. You might get problems with some remotes with that sampling. You'll have problems generating reliable config files with a resolution of 250. LIRC normally just takes an array of timing values.
Pulse times are marked with PULSE_BIT
So
400 & PULSE_BIT <- pulse
600 <- space value
The pulse bit is defined as #define PULSE_BIT 0x01000000
Hope this helps :)
[quote author="ian"]
I think I will add a new mode that measures the time between state changes, I believe that is what he means by raw timing info. That's a much less bandwidth intensive protocol than the sampling we've done previously. I don't know why the ir toy doesn't have one already :)
[/quote]
I think this will be a good edition to the USB IR Toy. What are you planning this to look like? Where you planning to emulate any existing device?
It would be great to do that, I haven't looked at it yet though. It would be good to do a RX and TX capability in this format.
Here's the documentation for The UIRT2 Protocol (http://http://users.skynet.be/sky50985/Uirt2_protocol.htm). Unfortunately it's not that easy to read. Of the three protocols RAW is the suggested one.
I have no experience with any of the UIRTs so I have no idea what shortcomings there might be in the protocol.
Raw Receive
This format is intended for allowing a host computer connected to the UIRT2 to learn IR code-strings. When in RAW mode, very little filtering is performed on received IR signals. Instead, the on/off timing information is sent to the host for processing. RAW format is a variable-length format, and can generate data streams of unlimited (theoretically) length to the host. RAW format follows the following format:
Byte 0 Interspace Hi-Byte High byte of time (in 50uS increments) since final pulse of last RAW IR reception
Byte 1 Interspace Lo-Byte High byte of time (in 50uS increments) since final pulse of last RAW IR reception
Byte 2 Pulse Width (1) Width in 50uS units of IR on time
Byte 3 Space Width (1) Width in 50uS units of IR off time
Byte 4 Pulse Width (2)
Byte 5 Space Width (2)
Byte n-1 Pulse Width (last) Width of final pulse
Byte n 0xFF Terminator
Each IR reception will stream data to the host in the above format until approximately 10mS of time elapses with no received IR energy, at which point a terminator byte (0xFF) will be transmitted.
Raw Transmit
This format is allows maximum flexibility for IR transmission but is limited as to the length of IR pulse streams. With this format, up to 23 unique pulse/space combinations can be defined and transmitted/repeated. RAW mode transmissions follow the format:
Byte 0 Interspace Hi-Byte High byte of time (in 50uS increments) since final pulse of last RAW IR reception
Byte 1 Interspace Lo-Byte High byte of time (in 50uS increments) since final pulse of last RAW IR reception
Byte 2 Pulse Width (1) Width in 50uS units of IR on time
Byte 3 Space Width (1) Width in 50uS units of IR off time
Byte 4 Pulse Width (2)
Byte 5 Space Width (2)
Byte n-1 Pulse Width (last) Width of final pulse
Byte n(n<=50) Freq/RptCnt Frequency/Repeat Count = bit 6,7 = 00 --> 40KHz mode 01 --> 38KHz mode 10 --> 38KHz mode 11 --> 36KHz mode bit 0-4 repeat counter (number of times the package is transmitted).
Note that RAW transmission requests MUST be encapsulated in the extended command structure defined below!
At first glance putting the carrier frequency last and requiring the whole message to be buffered doesn't seem to be the best idea.
I think the raw mode in the UIRT protocol is basically just for learning. On the USB-UIRT hardware I believe they use a special infra-red sensor that requires the remote to be placed like 1inch from the receiver, so maybe it's not that suitable for you guys.
I'd go with something like this.
Device resolution 50us
#define IRTOY_PULSE_BIT 0x80
#define IRTOY_PULSE_MASK 0x7F
Then each byte sent will reprisent the time of the length pulse/space data. Always multiplied by 50 to get the actual value. This is the format the windows media remotes use, or something similar. Zero can reprisent the end of the data, or no data :) Something like that would work.
On sourceforge I've uploaded the source for your plugin :)
Can be found here:
http://winlirc.svn.sourceforge.net/view ... DLL/IRToy/ (http://winlirc.svn.sourceforge.net/viewvc/winlirc/trunk/DLL/IRToy/)
The SendReceiveData.cpp class is the one that needs your own methods added to add data from your receiver to be decoded !
Here's an example for another plugin I wrote. You can see it's very similar :)
http://winlirc.svn.sourceforge.net/view ... iew=markup (http://winlirc.svn.sourceforge.net/viewvc/winlirc/trunk/DLL/StreamzapAlternate/StreamzapAPI.cpp?revision=87&view=markup)
Should build with the express (free) editions of visual studio.
Enjoy :)
Thanks Dukey, I also meant to post your email here too (files attached):
Heres the source for your winlirc plugin :)
I only assume you can write c/c++ ? It builds in vs2008 .. but should work fine with the free versions. (NO MFC)
The class you want to look at is
SendReceiveData
In the init function it creates a thread for receiving
threadHandle = CreateThread(NULL,0,IRToy,(void *)this,0,NULL);
which in my example gets stuck in receiveLoop()
In this loop when data arrives, you need to add it to the array by calling setData(numbers)
then call SetEvent(dataReadyEvent);
This example uses the polling method, ie to check every time period whether or not data has arrived. I think a call back function would be better, in this case you don't need to CreateThread() in the init function. You just need to call setData and SetEvent().
Hope this helps in some way
I'm working on the sampling mode now. I have the basic receive framework going, I just need to adjust to the timing (50us) and implement a protocol. I'll keep updates here so they're out of the driver development thread:
http://dangerousprototypes.com/forum/in ... opic=747.0 (http://dangerousprototypes.com/forum/index.php?topic=747.0)
good job Ian :)
Maybe we can get WinLIRC support soon. If you are trying to come up with a protocol, I think the longest PULSE that remote sends is something like 10,000 us. You can check http://lirc.sourceforge.net/remotes/ (http://lirc.sourceforge.net/remotes/) to see the sort of values.
Theres often a long space between the main data, and the repeat values, can be up to 100,000 us I think. There's 2 potential ways you can handle this.
The iguana receiver I supported, it just sends data constantly, so if the data is just SPACE, it keeps sending those every 1 second or so.
The streamzap API, it sends an 0xFF value to indicate an end of stream. Then when it gets the next pulse it carries on sending data. I have to time when the last data was received to when the next data was received to get the GAP or SPACE value. That works as long as the timing is okay.
I'm struggling over the 50us thing... I feel like our output should be 50us increments or divide into that. The problem is the crystal and prescaler combination make that difficult. I feel like it would be best to clone an existing setup rather than reinvent the wheel. The driver can just multiple by the correct value though, presenting a reasonable number to the application, right?
Maybe we should have a protocol that recognizes this. A header that gives the sampling multiplier, or a command that queries for the multiplier.
Of course, the new mode is based on the rawio mode, so it's possible to adjust the sampling rate too...
well, as for 50us. It doesn't have to be exactly 50us. The faster the better really, but it's a law of diminishing returns . I only suggested 50us because that's a good speed to use and that's what a few other receivers use. WinLIRC only needs raw timing information, how you get there doesn't really matter. With my audio plugin, it uses the lowest sampling rate which is around 90us I believe (11khz) (assuming i did the math right).
Depending on the sampling frequency depends on how you pack the data though. The streamzap and iMon hardware can get away with using 1 byte of data for transmissions as they use a resolution of 250us.
The simple LIRC serial receiver actually generates an interupt when it changes from PULSE/SPACE so it doesn't use a sampling resolution as such, but the timing is done on the CPU side, and basically breaks if you max out your CPU :)
I posted the latest firmware with the new sampling mode, the sampling mode documentation will be up later today. We can't get to the driver portion until next week, so there's a v1.1 prototype up as a bounty if someone wants to tackle it as a summer project.
What do you mean by the driver portion ? Anyway, I've also been working on a different plugin for WinLIRC. LIRC supports receiving timing data via UDP, and I've built a WinLIRC plugin around this, with the same protocol. The protocol is very simple. All you do is connect to a socket, then send it UDP data. If someone want to write code for the IRToy using this protocol it should be fairly easy, and you wouldn't be constrained by c/c++, java or python should be fine, as long as you can read from the serial port. And you could support both LIRC and WinLIRC with the same code !
The driver part is the driver for winlirc that supports the new mode in the IR Toy firmware. I had to make a sudden trip away from the lab this week, I won't be back to test the driver until this coming weekend.
something like this would do to convert the IRToy time values to lirc compatable ones :)
#define PULSE_BIT 0x01000000
#define PULSE_MASK 0x00FFFFFF
int pulse = 1;
int timeValue = 0;
int endValue = 0;
char array[128]; //array with values from device
for(int i=0; i
timeValue = array[i+0]<<8;
timeValue|= array[i+1];
if(timeValue==0xFFFF) endValue = 1;
timeValue = (int)((float)timeValue * 21.3333f);
if(pulse) timeValue |= PULSE_BIT;
setData(timeValue); //send data for decoding
pulse ~= pulse;
if(endValue) {
pulse = 1;
endValue = 0;
}
}