Dangerous Prototypes

Dangerous Prototypes => USB Infrared Toy => Topic started by: ian on July 16, 2010, 01:35:34 pm

Title: New IR Toy sampling mode
Post by: ian on July 16, 2010, 01:35:34 pm
I'm adding a mode to the IR Toy today. The mode times each change and sends the duration. This is way more compressed than the raw irio format. First I'll get the receive timing and protocol parts done, then I'll add a way to retransmit the same format.

The basic framework is complete. The source is in SVN here, along with development compiles if you want to try it out:
http://code.google.com/p/dangerous-prot ... y-firmware (http://code.google.com/p/dangerous-prototypes-open-hardware/source/browse/#svn/trunk/USBIRtoy/IRtoy-firmware)

THe IR sample mode is entered with s or S, it responds S00 right now.
Exit IR sample mode with null (0x00)

While in IR Sample this happens:
1. the first falling edge of an IR signal starts a timer
2. the next edge copies the timer value to a buffer and resets the timer
3. if the timer interrupts, then timeout and end.

It currently uses a 16bit timer, the data is returned low byte high byte. The last sample is 0xff 0xff.

I have not worked out the timing/prescaler/protocol yet:
*Work out a 50us timer
*data protocol (8/16bits?) - include place for frequency measurement on updated hardware?
*hand tune the timer reset value to be more accurate

There's a lot of info in this thread that I'll look at next:
http://dangerousprototypes.com/forum/in ... opic=731.0 (http://dangerousprototypes.com/forum/index.php?topic=731.0)


Example output

Code: [Select]
{F9}{2B}{DE}{27}{50}{54}{9E}{51}{90}{2A}{AC}{27}{F4}{2B}{A9}{27}{90}{2A}{DD}{27}{4E}{54}{A0}{51}{C1}{2B}{DD}{27}{52}{54}{A0}{51}{84}{54}{6C}{51}{8F}{2A}{FF}{FF}

Same code a second time:

Code: [Select]
{FA}{2C}{AA}{26}{83}{55}{9F}{50}{8F}{2B}{AB}{26}{F6}{2C}{AB}{26}{F7}{2C}{45}{25}{85}{55}{A0}{50}{C2}{2C}{DD}{26}{50}{55}{A1}{50}{86}{55}{6D}{50}{90}{2B}{FF}{FF}
Title: Re: New IR Toy sampling mode
Post by: ian on July 16, 2010, 02:02:25 pm
The PIC runs at 48MHz osc, which is divided by 4 for MIPS = 12MIPS (fcyc)

12MHz= a period of
microsecond       0.0833us
nanosecond    83.333ns

so there are 600.24 counter ticks per 50us

With the 16bit counter we can count a maximum of 109 50us periods.

The timer has these prescalers:
111 = 1:256 Prescale value
110 = 1:128 Prescale value
101 = 1:64 Prescale value
100 = 1:32 Prescale value
011 = 1:16 Prescale value
010 = 1:8 Prescale value
001 = 1:4 Prescale value
000 = 1:2 Prescale value

Between a prescaler and preloading the timer maybe we can get a nice X 50us period timer. Calculations will continue...
Title: Re: New IR Toy sampling mode
Post by: ian on July 16, 2010, 02:43:00 pm
Quote
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.

I've been curious about the numbers on this.

255 (0xFE) * 50uS = 12750us = 12.75ms (the about 10ms with no samples).

 I'm going to have to setup a 50uS timer and increment it on interrupt. It would be easy (lazy) to have a 16bit 50us timer that can output the values exactly as needed, but I don;t think this crystal will allow it.
Title: Re: New IR Toy sampling mode
Post by: ian on July 16, 2010, 04:38:12 pm
Here's where I left it on the most recent update:

Using TIMER0 with a 256x prescaler gives a 21.165uS/tick timer. It is a 16bit timer so the maximum time is 1.3million uS (might want ot check that). It will count for the full 1.3million us, if there is no more output it sends oxff oxff, and 'goes to sleep'. I added a USB packet timeout so that data is sent right away, instead of hanging around until the 1.3MuS timer expires. On the other hand, the last 0xff 0xff won't come until long after the last part of the command.

Right now it outputs:
1 high 8 bits pulse 1
2 low 8bits pulse 1
3 high 8 blank
4 low 8 blank
....
0xff end of data
0xff end of data
Title: Re: New IR Toy sampling mode
Post by: ian on July 16, 2010, 04:45:30 pm
The latest code is in SVN, along with a compile if you want to load it using the bootloader.

Sample output:

Quote
{00}{2C}{00}{26}{00}{2B}{00}{26}{00}{2B}{00}{27}{00}{2B}{00}{26}{00}{2C}{00}{26}{00}{2B}{00}{26}{00}{55}{00}{50}{00}{2B}{00}{28}{00}{55}{00}{50}{00}{55}{00}{50}{00}{2B}{FF}{FF}

And a bunch, to see consistency:

Quote
{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{10}{74}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{27}{00}{54}{00}{51}{00}{2B}{00}{27}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{FF}{FF}

My IR Toy to do:
*finalize the sample protocol (how to signal end of command short-vs-long term)
*Add firmware/hardware query command
Title: Re: New IR Toy sampling mode
Post by: ian on July 19, 2010, 10:43:12 am
Time for some math, please check it :)

Each prescaler tick is 0.08333us.
The 1:256 prescaler takes 256 * 0.0833us to increment 1 on the counter (21.3333us per tick)
The 16bit timer0 can count to 65535, so the maximum interval is 1,398,077.8155us

Protocol
The protocol is very simple right now, it might need to be updated in the future.

pulse1-high8 | pulse1-low8 | blank1-high8 | blank1-low8 | ... | blankn-high8 | blankn-low8 |

The first IR pulse starts the counter, it measures the number of 21.3333us periods before the next blank. The IR Toy continues to spit out measurements until there is a full (0xffff) blank period of 1.7seconds. After a full blank period the IR Toy 'sleeps' and won't send any more data until the next IR pulse.

To get the actual width of each pulse or space:
Combine the high and low byte
Multiply by 21.3333us

Here's an example:
{00}{2B}{00}{28}{00}{2A}{00}{27}{00}{2B}{00}{28}{00}{2A}{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{28}{00}{54}{00}{51}{00}{2B}{00}{28}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{FF}{FF}{00}{0A}{FF}{FF}{00}{04}{FF}{FF}

002b (first pulse duration) = 43 = 43 * 21.3333us = 917.3319us
0028 (first blank duration) = 40 = 40 * 21.3333us = 853.332us
002a (second pulse duration) = 42 = 42 * 21.3333us = 895.9986us

Those are all pretty close to the 889us bit period of an RC5 remote.
http://www.sbprojects.com/knowledge/ir/rc5.htm (http://www.sbprojects.com/knowledge/ir/rc5.htm)

To enter IR sample mode:
First send 0x00 (raw byte value 0) to reset from any other mode. It might be good to send it 5 times to be sure it's out of SUMP mode too.
Next, send 's' or 'S' to enter IR sample mode. The IR Toy will respond with the protocol version (currently S01).
Now the bytes start flowing.

Potential issues:
1. Which byte is which, tracking the byte stream. There's no easy way to sync to the byte stream unless you track it from the start or wait for the first 0xff 0xff terminator. That's probably not a huge deal in practice, just reset (0x00, 'S') and follow it from the beginning. An alternative would be to use the first bit to flag pulse or blank periods, but there's still the issue of determining which bytes in the stream are the high and low 8bits.
2. IR Toy timeout - The IR Toy will send the 0xff 0xff terminator flag after no pin change is detected for one timer period. It doesn't care if this is a pulse or blank period, and it has no ability to let us know a pulse is longer than 1.7seconds. A continuous IR pulse, like an IR Jammer, would really mess up the bytestream. Update: we made the IR Toy a little more robust against this situation by confirming that a pulse at the start of sampling. 

Taking it further
This is just an initial test release. We need to verify the timing against a logic analyzer, and possibly hand-tune the counter and interrupt routines.
Title: Re: New IR Toy sampling mode
Post by: ian on July 19, 2010, 12:18:22 pm
I posted the latest firmware, the sampling mode documentation will be up later today.
Title: Re: New IR Toy sampling mode
Post by: dukey on July 19, 2010, 02:38:42 pm
looks like u've done a good job on the API.
Quote
1. Which byte is which, tracking the byte stream.

After 1.7 seconds of no data we will be able to track the start of the stream again anyway, so I don't invision this being a problem. Theoretically it might only be a problem if you were receiving data constantly. You could always use the final bit on the stream to indicate PULSE or SPACE. But it should be fine :)
Title: Re: New IR Toy sampling mode
Post by: rsdio on July 20, 2010, 07:32:17 am
This is a very nice protocol, Ian.  My internal format for the Mac Cocoa IR Toy front end uses basically the same thing.  Instead of 16-bit words mapped onto bytes, I'm using number objects.  But I have the exact same protocol where the first number is a pulse, and then it alternates between blank and pulse.  I had the same worries because I did not allocate any bits to flag the difference between blank and pulse.  It just seems like a logical protocol, and I never had a problem in practice.  My loops either consume two numbers at a time to stay in sync, or I have a flag which alternates so I can track pulse versus blank.

I cannot speak for anyone else, but I think your protocol is perfect for me.  Barring any bugs in the implementation, I think it's a very good design.
Title: Re: New IR Toy sampling mode
Post by: liyin on July 28, 2010, 02:23:30 pm
Does the IR/IO mode give more consistent results than the sampling mode?
Title: Re: New IR Toy sampling mode
Post by: ian on July 28, 2010, 02:29:05 pm
It depends on what you mean by consistent. The IRIO mode sends a bitstream with each slice representing a time of off and on, the sampling mode sends the number of 21.xxxuS periods each on or off period lasts. The sampling mode is preferable because it only sends data about the change, instead of a record of the pin state at each period.
Title: Re: New IR Toy sampling mode
Post by: liyin on July 28, 2010, 02:56:43 pm
Ok, I was curious from looking at the results from both modes.
Title: Re: New IR Toy sampling mode
Post by: rsdio on July 28, 2010, 10:39:26 pm
[quote author="liyin"]Does the IR/IO mode give more consistent results than the sampling mode?[/quote]Neither mode is synchronized to the sending IR remote because the sample rate is not locked to the sending unit, and thus you'll always get different bytes each time even if you repeat the same message.  Any IR decoder will necessarily have to use some kind of fuzzy logic to adapt to the data and interpret IR remote commands, regardless of the mode used.

As I mentioned, my OSX front end for the USB IR Toy internally converts data from the old mode to something exactly like the new mode.  This doesn't actually make the data more consistent, but it does make it easier to analyze.  You should still expect a lot of variation in data from specific instance to specific instance.

( ! ) Fatal error: Uncaught exception 'Elk_Exception' with message 'Please try again. If you come back to this error screen, report the error to an administrator.' in /var/www/dangerousprototypes/forum/sources/database/Db-mysql.class.php on line 696
( ! ) Elk_Exception: Please try again. If you come back to this error screen, report the error to an administrator. in /var/www/dangerousprototypes/forum/sources/database/Db-mysql.class.php on line 696
Call Stack
#TimeMemoryFunctionLocation
10.01762118744session_write_close ( )...(null):0
20.01822250336ElkArte\sources\subs\SessionHandler\DatabaseHandler->write( )...(null):0
30.01832251112Database_MySQL->query( ).../DatabaseHandler.php:119
40.09602389840Database_MySQL->error( ).../Db-mysql.class.php:273