Skip to content

Instantly share code, notes, and snippets.

@probonopd
Last active September 20, 2021 19:53
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save probonopd/5793692 to your computer and use it in GitHub Desktop.
Save probonopd/5793692 to your computer and use it in GitHub Desktop.
Send Pronto Hex via an IR LED connected to Arduino Pin D9. Make sure you do not send a blank (" ") as the last character. Applied fix for Leonardo from https://github.com/probonopd/arduino-infrared-pronto/pull/1 to sendandreceive.ino -- TODO: Fix sendRaw to specify length as "sizeof(signal)/sizeof(int)" as in http://forum.arduino.cc/index.php?PH…
#include <IRremote.h>
// http://www.pjrc.com/teensy/td_libs_IRremote.html
// If one keypress results in multiple codes being output, then
// change in IRremoteInt.h:
// #define _GAP 50000
int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;
// Compare two tick values, returning 0 if newval is shorter,
// 1 if newval is equal, and 2 if newval is longer
// Use a tolerance of 20%
int compare(unsigned int oldval, unsigned int newval) {
if (newval < oldval * .8) {
return 0;
}
else if (oldval < newval * .8) {
return 2;
}
else {
return 1;
}
}
// Use FNV hash algorithm: http://isthe.com/chongo/tech/comp/fnv/#FNV-param
#define FNV_PRIME_32 16777619
#define FNV_BASIS_32 2166136261
/* Converts the raw code values into a 32-bit hash code.
* Hopefully this code is unique for each button.
*/
unsigned long decodeHash(decode_results *results) {
unsigned long hash = FNV_BASIS_32;
for (int i = 1; i+2 < results->rawlen; i++) {
int value = compare(results->rawbuf[i], results->rawbuf[i+2]);
// Add value into the hash
hash = (hash * FNV_PRIME_32) ^ value;
}
return hash;
}
void setup()
{
Serial.begin(57600);
Serial.println("READY");
irrecv.enableIRIn(); // Start the receiver
}
int c = 1;
void dump(decode_results *results) {
int count = results->rawlen;
Serial.println(c);
c++;
Serial.println("Hash: ");
unsigned long hash = decodeHash(results);
Serial.println(hash, HEX);
Serial.println("For IR Scope/IrScrutinizer: ");
for (int i = 1; i < count; i++) {
if ((i % 2) == 1) {
Serial.print("+");
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print(-(int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(" ");
}
Serial.println("-127976");
Serial.println("For Arduino sketch: ");
Serial.print("unsigned int raw[");
Serial.print(count, DEC);
Serial.print("] = {");
for (int i = 1; i < count; i++) {
if ((i % 2) == 1) {
Serial.print(results->rawbuf[i]*USECPERTICK, DEC);
}
else {
Serial.print((int)results->rawbuf[i]*USECPERTICK, DEC);
}
Serial.print(",");
}
Serial.print("};");
Serial.println("");
Serial.print("irsend.sendRaw(raw,");
Serial.print(count, DEC);
Serial.print(",38);");
Serial.println("");
Serial.println("");
}
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include <avr/io.h>
#define IR_PORT PORTB
// #define IR_PIN PINB
// #define IR_DDR DDRB
// #define IR_BV _BV(1)
#define IR_OCR OCR1A
#define IR_TCCRnA TCCR1A
#define IR_TCCRnB TCCR1B
#define IR_TCNTn TCNT1
#define IR_TIFRn TIFR1
#define IR_TIMSKn TIMSK1
#define IR_TOIEn TOIE1
#define IR_ICRn ICR1
#define IR_OCRn OCR1A
#define IR_COMn0 COM1A0
#define IR_COMn1 COM1A1
#define PRONTO_IR_SOURCE 0 // Pronto code byte 0
#define PRONTO_FREQ_CODE 1 // Pronto code byte 1
#define PRONTO_SEQUENCE1_LENGTH 2 // Pronto code byte 2
#define PRONTO_SEQUENCE2_LENGTH 3 // Pronto code byte 3
#define PRONTO_CODE_START 4 // Pronto code byte 4
static const uint16_t *ir_code = NULL;
static uint16_t ir_cycle_count = 0;
static uint32_t ir_total_cycle_count = 0;
static uint8_t ir_seq_index = 0;
static uint8_t ir_led_state = 0;
void ir_on()
{
IR_TCCRnA |= (1<<IR_COMn1) + (1<<IR_COMn0);
ir_led_state = 1;
}
void ir_off()
{
IR_TCCRnA &= ((~(1<<IR_COMn1)) & (~(1<<IR_COMn0)) );
ir_led_state = 0;
}
void ir_toggle()
{
if (ir_led_state)
ir_off();
else
ir_on();
}
void ir_start(uint16_t *code)
{
ir_code = code;
// IR_PORT &= ~IR_BV; // Turn output off (atmega328 only)
digitalWrite(9,LOW); // Turn output off
// IR_DDR |= IR_BV; // Set it as output (atmega328 only)
pinMode(9,OUTPUT); // Set it as output
IR_TCCRnA = 0x00; // Reset the pwm
IR_TCCRnB = 0x00;
//printf_P(PSTR("FREQ CODE: %hd\r\n"), code[PRONTO_FREQ_CODE]);
uint16_t top = ( (F_CPU/1000000.0) * code[PRONTO_FREQ_CODE] * 0.241246 ) - 1;
//printf_P(PSTR("top: %hu\n\r"), top);
IR_ICRn = top;
IR_OCRn = top >> 1;
IR_TCCRnA = (1<<WGM11);
IR_TCCRnB = (1<<WGM13) | (1<<WGM12);
IR_TCNTn = 0x0000;
IR_TIFRn = 0x00;
IR_TIMSKn = 1 << IR_TOIEn;
ir_seq_index = PRONTO_CODE_START;
ir_cycle_count = 0;
ir_on();
IR_TCCRnB |= (1<<CS10);
}
#define TOTAL_CYCLES 80000 // Turns off after this number of
// cycles. About 2 seconds
// FIXME: Turn off after having sent
ISR(TIMER1_OVF_vect) {
uint16_t sequenceIndexEnd;
uint16_t repeatSequenceIndexStart;
ir_total_cycle_count++;
ir_cycle_count++;
if (ir_cycle_count== ir_code[ir_seq_index]) {
ir_toggle();
ir_cycle_count = 0;
ir_seq_index++;
sequenceIndexEnd = PRONTO_CODE_START +
(ir_code[PRONTO_SEQUENCE1_LENGTH]<<1) +
(ir_code[PRONTO_SEQUENCE2_LENGTH]<<1);
repeatSequenceIndexStart = PRONTO_CODE_START +
(ir_code[PRONTO_SEQUENCE1_LENGTH]<<1);
if (ir_seq_index >= sequenceIndexEnd ) {
ir_seq_index = repeatSequenceIndexStart;
if(ir_total_cycle_count>TOTAL_CYCLES) {
ir_off();
TCCR1B &= ~(1<<CS10);
}
}
}
}
void ir_stop()
{
IR_TCCRnA = 0x00; // Reset the pwm
IR_TCCRnB = 0x00;
}
const uint16_t inputLength = 512;
void loop() {
if (irrecv.decode(&results)) {
dump(&results);
irrecv.resume(); // Receive the next value
}
if ( Serial.available() > 0 )
{
static char input[inputLength];
static uint16_t i;
char c = Serial.read();
if ( c != '\r' && c != '\n' && i < inputLength-1)
input[i++] = c;
else
{
input[i] = '\0';
i = 0;
uint16_t array[80];
uint16_t j = 0;
if ( !strncmp(input, "SEND", 4) )
{
char* p = input+4;
while ( (p = strchr(p, ' ')) != NULL )
array[j++] = strtol(p, &p, 16);
ir_start(array);
Serial.print("SENT ");
for ( uint8_t i = 0; i < j; i++ )
{
Serial.print ("0x");
Serial.print (array[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
}
}
:100000000C9463000C948B000C948B000C948B006C
:100010000C948B000C948B000C948B000C94660E4B
:100020000C948B000C948B000C948B000C948B0024
:100030000C948B000C94DA030C948B000C948B00C2
:100040000C94230F0C948B000C9439100C94871093
:100050000C948B000C948B000C948B000C948B00F4
:100060000C948B000C948B000000000024002700EF
:100070002A0000000000250028002B0000000000DE
:1000800023002600290004040404040404040202DA
:100090000202020203030303030301020408102007
:1000A0004080010204081020010204081020000012
:1000B0000007000201000003040600000000000029
:1000C00000007804F31111241FBECFEFD8E0DEBF8B
:1000D000CDBF11E0A0E0B1E0E2E9FCE202C0059092
:1000E0000D92A039B107D9F715E0A0E9B1E001C040
:1000F0001D92AE32B107E1F710E0C6ECD0E004C0CB
:100100002297FE010E943816C23CD107C9F70E940F
:1001100049120C9447160C940000EF92FF920F9333
:10012000DF93CF93CDB7DEB760970FB6F894DEBFFD
:100130000FBECDBFA82F002309F461C07E01089433
:10014000E11CF11C88E0F70111928A95E9F72983F7
:100150003A834B835C836D837E83AF83988780E291
:10016000801BE82FFF27E7FDF0954D815E816F81B1
:100170007885181684F01D861E861F86188A8827A3
:1001800099278E1B9F0B04C07695679557954795C9
:100190008A95D2F728C0202F332727FD3095DB0121
:1001A000CA01022E04C0B695A795979587950A9423
:1001B000D2F78D879E87AF87B88B04C0440F551F39
:1001C000661F771FEA95D2F789819A81AB81BC813E
:1001D00004C0B695A795979587952A95D2F7482B91
:1001E000592B6A2B7B2B49875A876B877C872985FC
:1001F0003A854B855C856D857E85AF8598898A2F8C
:1002000060960FB6F894DEBF0FBECDBFCF91DF91E1
:100210000F91FF90EF900895EF92FF920F93DF936D
:10022000CF93CDB7DEB760970FB6F894DEBF0FBEA1
:10023000CDBFA82F002309F461C07E010894E11C02
:10024000F11C88E0F70111928A95E9F729833A8336
:100250004B835C836D837E83AF83988780E2801BB2
:10026000E82FFF27E7FDF09549815A816B817C815A
:10027000181684F019861A861B861C8688279927EB
:100280008E1B9F0B04C0440F551F661F771F8A9556
:10029000D2F728C0202F332727FD3095DB01CA0174
:1002A000022E04C0880F991FAA1FBB1F0A94D2F701
:1002B00089879A87AB87BC8704C0769567955795E1
:1002C0004795EA95D2F78D819E81AF81B88504C0AC
:1002D000880F991FAA1FBB1F2A95D2F7482B592BAD
:1002E0006A2B7B2B4D875E876F87788B29853A85B4
:1002F0004B855C856D857E85AF8598898A2F609654
:100300000FB6F894DEBF0FBECDBFCF91DF910F9136
:10031000FF90EF9008952F923F925F926F927F929D
:100320008F929F92AF92BF92CF92DF92EF92FF9205
:100330000F931F93CF93DF938C011B01EA0161158B
:10034000710519F0FB0191838083209749F0CE015C
:100350000297839728F020E030E040E050E0F6C0BC
:10036000F801A1908F018A2D90E00E943C16892B04
:10037000B9F7FDE2AF1631F4F801A1908F015524D1
:10038000539407C0FBE2AF1619F4F801A1908F0156
:100390005524209719F0C031D105C1F4F0E3AF1610
:1003A00079F4F8018081883711F0883549F4F80133
:1003B000A1800E5F1F4FF2E05F2AC0E1D0E006C0CF
:1003C000209721F480E3A816E9F427C0C830D105AE
:1003D00031F1C930D10524F4C230D10531F50CC05A
:1003E000CA30D10589F0C031D105F9F4C12CD12C26
:1003F000E12CB8E0FB2E28C0C12CD12CE12CA0E4CC
:10040000FA2E22C0CAE0D0E0FCECCF2EFCECDF2EAE
:10041000FCECEF2EFCE0FF2E17C0C8E0D0E0C12CB2
:10042000D12CE12CE0E1FE2E0FC09E01442737FDC8
:100430004095542F60E070E080E090E80E94141630
:10044000C901DA016C017D0120E030E040E050E0BC
:1004500060E03E01882477FC8094982C70EDB72EE4
:10046000BA0CE9E0EB1570F48A2D81548A3118F446
:1004700099ECB92E06C08A2D81568A3150F589EA49
:10048000B82EBA0C8B2D90E08C179D0714F56F3F9A
:10049000E1F0C216D306E406F506B0F0CA01B901D0
:1004A000A40193010E94F5159B01AC012B0D311D98
:1004B000411D511D2130F0E03F07F0E04F07F0E80B
:1004C0005F0710F461E001C06FEFF801A1908F01A8
:1004D000C5CF2114310481F0662331F00150104062
:1004E000F1011183008308C051FE1AC00250104070
:1004F000F1011183008314C067FF12C050FC05C0D6
:100500002FEF3FEF4FEF5FE704C020E030E040E027
:1005100050E882E290E090932D0580932C0516C060
:1005200050FE08C050954095309521953F4F4F4F54
:100530005F4F0CC057FF0AC082E290E090932D05F8
:1005400080932C052FEF3FEF4FEF5FE7B901CA0112
:10055000DF91CF911F910F91FF90EF90DF90CF909F
:10056000BF90AF909F908F907F906F905F903F90E3
:100570002F900895FC018191861721F08823D9F7E7
:10058000992708953197CF010895FB01DC0141506F
:10059000504030F08D910190801919F40020B9F786
:1005A000881B990B08952F923F924F925F926F9202
:1005B0007F928F929F92AF92BF92CF92DF92EF92F3
:1005C000FF920F931F93DF93CF9300D000D0CDB74E
:1005D000DEB79C838B83FC010484F585E02DFA83D0
:1005E000E98375ECA72E7DE9B72E7CE1C72E71E873
:1005F000D72E63E0462E512C52E0252E312C60C0C0
:10060000EB81FC8122853385D901A20DB31DED90CC
:10061000FC90C201880F991F280F391FF9016081D2
:10062000718180E090E00E94E0143B014C0100E009
:1006300010E0C801B7010E94E0147B018C012DEC91
:100640003CEC4CE45FE30E9492159B01AC01C401B9
:10065000B3010E94431488231CF400E010E018C08A
:10066000C401B3012DEC3CEC4CE45FE30E94921515
:100670009B01AC01C801B7010E944314082F112748
:1006800007FD10950027110F001F11270F5F1F4F47
:10069000C601B50123E931E040E051E00E94F515C3
:1006A0005801CC24B7FCC094DC2CA626B726C8265B
:1006B000D9260894411C511C82E090E0280E391E76
:1006C000E981FA814E165F060CF49ACFB501C60196
:1006D0000F900F900F900F90CF91DF911F910F917E
:1006E000FF90EF90DF90CF90BF90AF909F908F9052
:1006F0007F906F905F904F903F902F900895EF9272
:10070000FF920F931F93FC019093A8038093A7037C
:100710002998219A00E810E0D8011C92A1E8EA2E5D
:10072000F12CD7011C926281738180E090E00E94DD
:10073000E01420E030E040E851E40E94921521E30B
:1007400039E047E75EE30E94921520E030E040E8A0
:100750005FE30E94DE130E94B4149B017093870034
:100760006093860036952795309389002093880002
:1007700082E0F801808388E1D7018C931092850094
:100780001092840016BA91E090936F0084E08093F9
:10079000A9031092A6031092A5038081806C808328
:1007A0009093AA038C9181608C931F910F91FF907D
:1007B000EF9008951F920F920FB60F921124EF92AF
:1007C000FF920F931F932F933F934F935F938F93BA
:1007D0009F93AF93BF93EF93FF93E090A103F090AB
:1007E000A2030091A3031091A4030894E11CF11C3F
:1007F000011D111DE092A103F092A2030093A30337
:100800001093A4038091A5039091A6030196909361
:10081000A6038093A503A091A703B091A8034091DC
:10082000A903E42FF0E0EE0FFF1FEA0FFB1F20816A
:1008300031818217930709F048C08091AA03882369
:1008400041F0809180008F73809380001092AA0302
:1008500008C080918000806C8093800081E080934C
:10086000AA031092A6031092A503242F2F5F2093B2
:10087000A90314964D915C911597440F551F30E0D4
:1008800016968D919C911797880F991F840F951F2D
:10089000049628173907C8F04C5F5F4F4093A903AF
:1008A00081E8E81688E3F80681E0080780E0180789
:1008B00060F0809180008F73809380001092AA0373
:1008C000809181008E7F80938100FF91EF91BF9195
:1008D000AF919F918F915F914F913F912F911F9178
:1008E0000F91FF90EF900F900FBE0F901F901895F3
:1008F00060917B0170917C0180E991E00E94D106BA
:1009000008958F929F92AF92BF92CF92DF92EF9213
:10091000FF920F931F93CF93DF937C01DC011C9612
:10092000CD90DC901D9760917D0170917E018AE0F1
:1009300095E04AE050E00E94A91380917D019091DA
:100940007E01019690937E0180937D018AE095E07F
:1009500060E071E00E94CB13C7010E94D302AB019B
:10096000BC018AE095E020E130E00E9431138AE08A
:1009700095E067E071E00E94CB1301E010E0C2E077
:10098000D0E05EEC852E5FEF952E42E3A42EB12CD5
:100990003EC000FF1DC08AE095E066E171E00E9464
:1009A000C813D7011A96ED91FC911B97EC0FFD1F10
:1009B000808191818A9DB0018B9D700D9A9D700DF3
:1009C00011248AE095E04AE050E00E94451316C0E9
:1009D000D7011A96ED91FC911B97EC0FFD1F8081BA
:1009E0009181889DB001899D700D989D700D112495
:1009F0008AE095E04AE050E00E9496138AE095E094
:100A000068E171E00E94C8130F5F1F4F22960C151A
:100A10001D050CF4BECF8AE095E06AE171E00E940A
:100A2000CB138AE095E06BE171E00E94CB138AE082
:100A300095E060E371E00E94C8138AE095E0B6019A
:100A40004AE050E00E9496138AE095E062E471E08B
:100A50000E94C81301E010E0C2E0D0E032E3A32E10
:100A6000B12C33C0D7011A96ED91FC911B9700FF72
:100A700012C0EC0FFD1F808191818A9DB0018B9D7A
:100A8000700D9A9D700D11248AE095E04AE050E0C7
:100A90000E94451311C0EC0FFD1F808191818A9D3A
:100AA000B0018B9D700D9A9D700D11248AE095E028
:100AB0004AE050E00E9496138AE095E068E471E015
:100AC0000E94C8130F5F1F4F22960C151D0554F28C
:100AD0008AE095E06AE471E00E94C8138AE095E03C
:100AE0006AE171E00E94CB138AE095E06DE471E069
:100AF0000E94C8138AE095E0B6014AE050E00E94E7
:100B000096138AE095E061E671E00E94C8138AE0DE
:100B100095E06AE171E00E94CB138AE095E06AE11A
:100B200071E00E94CB13DF91CF911F910F91FF9045
:100B3000EF90DF90CF90BF90AF909F908F900895EF
:100B4000AF92BF92CF92DF92EF92FF920F931F93DB
:100B5000DF93CF93CDB7DEB7C25AD0400FB6F8942B
:100B6000DEBF0FBECDBF80E991E061E971E00E9478
:100B7000F10D892B41F081E991E00E94810480E927
:100B800091E00E94D6068AE095E00E94491118166D
:100B900019060CF08AC08AE095E00E947A118D3027
:100BA000A9F08A3099F020919F013091A00191E045
:100BB0002F3F390758F4F901EF55FE4F80832F5F1F
:100BC0003F4F3093A00120939F016FC0E0919F01A0
:100BD000F091A001EF55FE4F10821092A0011092EB
:100BE0009F0181EA91E067E671E044E050E00E94F5
:100BF000C502009709F059C085EA91E09A8389837C
:100C00008E010D5F1F4FCC24DD247E010894E11C72
:100C1000F11C0DC0C901B70140E150E00E948B01F9
:100C2000F801619371938F010894C11CD11C8981D3
:100C30009A8160E270E00E94BA029C019A838983E3
:100C4000009741F7CE0103960E947F038AE095E06A
:100C50006CE671E00E94C813FF245E010894A11C99
:100C6000B11C1AC08AE095E062E771E00E94C813E7
:100C7000000F111F0A0D1B1DF801628173818AE0AC
:100C800095E040E150E00E9445138AE095E068E17C
:100C900071E00E94C813F3940F2D10E00C151D0590
:100CA00008F38AE095E00E948212CE55DF4F0FB61E
:100CB000F894DEBF0FBECDBFCF91DF911F910F9192
:100CC000FF90EF90DF90CF90BF90AF9008950F937B
:100CD0001F930AE015E0C80140E051EE60E070E0CB
:100CE0000E94C210C80165E771E00E94CB1380E941
:100CF00091E00E94080F1F910F910895DF92EF92EB
:100D0000FF920F931F93CF93DF93EC01882777FD1A
:100D10008095982F0E94E2147B018C0120E030E046
:100D200040E45FE30E94921520E030E048E452E4A2
:100D30000E9447140E94AF14C617D70714F4DD248D
:100D40001CC0DD24C801B70120E030E040EA5FE3C9
:100D50000E94921520E030E048E452E40E944714DB
:100D600020E030E040E85FE30E94DF130E94AF1410
:100D70006C177D0714F0DD24D3948D2D90E0DF9166
:100D8000CF911F910F91FF90EF90DF9008956C59D4
:100D90007F4F0E947E060895645670400E947E0632
:100DA00008956093AB031092AD03089582E08093A1
:100DB000AC03109278040895AF92BF92CF92DF9265
:100DC000EF92FF920F931F93CF93DF936B01DB01A1
:100DD0001A96CD91DC911B978A819B8168E273E220
:100DE0000E94C706892B09F480C080917804843062
:100DF00009F08CC08C819D816AEC78E00E94CC0661
:100E0000892B09F483C08E819F8160E372E00E9488
:100E1000C706892B09F47AC0F601118610868FEF78
:100E20009FEFAFEFBFEF84839583A683B78381E005
:100E300090E09183808354C08C819D8164E971E14D
:100E40000E94CC06892B09F450C02696EE24FF247C
:100E5000870123E0A22EB12C8881998160E372E0A2
:100E60000E94C706892B09F440C08A819B8160E4F7
:100E700076E00E94CC06892B69F0EE0CFF1C001F67
:100E8000111F81E090E0A0E0B0E0E82AF92A0A2BE7
:100E90001B2B0CC08A819B8160E372E00E94CC0610
:100EA000892B19F1EE0CFF1C001F111F249691E4F1
:100EB000A916B10429F0A2E0B0E0AA0EBB1ECCCF67
:100EC00080E290E0F60191878087D6011496ED923A
:100ED000FD920D931C93179781E090E08D939C9366
:100EE00021E030E040E050E004C020E030E040E0AD
:100EF00050E0B901CA01DF91CF911F910F91FF908E
:100F0000EF90DF90CF90BF90AF90089580917804DC
:100F1000843458F391CFAF92BF92CF92DF92EF9289
:100F2000FF920F931F93CF93DF936B01809178040F
:100F30008A3108F480C0DB011A96CD91DC911B97B1
:100F400088819981845F914080F4FB01118610862D
:100F50008FEF9FEFAFEFBFEF84839583A683B783B7
:100F600089E090E09183808361C08A819B8160E603
:100F700079E00E94C706892B09F45DC02696EE240D
:100F8000FF24870162E0A62EB12C30C02297888111
:100F90009981229668E572E00E94CC06892B79F14E
:100FA0008881998160EB74E00E94C706892B69F003
:100FB000EE0CFF1C001F111F81E090E0A0E0B0E0EC
:100FC000E82AF92A0A2B1B2B0CC08881998168E535
:100FD00072E00E94C706892B71F1EE0CFF1C001F06
:100FE000111FA2E0B0E0AA0EBB1E249680917804E7
:100FF00095012F5F3F4F90E0281739073CF2C5015C
:10100000019795958795F601918780870C971CF439
:101010001186108610C0D6011496ED92FD920D93A4
:101020001C93179782E090E08D939C9321E030E031
:1010300040E050E004C020E030E040E050E0B90182
:10104000CA01DF91CF911F910F91FF90EF90DF9038
:10105000CF90BF90AF900895AF92BF92CF92DF92A2
:10106000EF92FF920F931F93CF93DF936B018091C9
:1010700078048A3108F489C0DB011A96CD91DC919D
:101080001B97888199818052934080F4FB011186DF
:1010900010868FEF9FEFAFEFBFEF84839583A6831A
:1010A000B78389E090E0918380836AC08A819B81C5
:1010B0006CEA7DE00E94C706892B09F466C08C812A
:1010C0009D816CEA7DE00E94C706892B09F45DC012
:1010D0002896EE24FF248701A3E0AA2EB12C30C06D
:1010E000229788819981229666EB73E00E94CC0654
:1010F000892B79F18881998160E679E00E94C706A1
:10110000892B69F0EE0CFF1C001F111F81E090E09D
:10111000A0E0B0E0E82AF92A0A2B1B2B0CC088813A
:1011200099816CEB72E00E94C706892B71F1EE0C7D
:10113000FF1C001F111FA2E0B0E0AA0EBB1E2496E8
:101140008091780495012F5F3F4F90E02817390771
:101150003CF2C501019795958795F60191878087A7
:101160000C971CF41186108610C0D6011496ED92CF
:10117000FD920D931C93179789E090E08D939C93BB
:1011800021E030E040E050E004C020E030E040E00A
:1011900050E0B901CA01DF91CF911F910F91FF90EB
:1011A000EF90DF90CF90BF90AF9008956F927F92B5
:1011B0008F929F92AF92BF92CF92DF92EF92FF9267
:1011C0000F931F93CF93DF934B018091780482326A
:1011D00008F47AC0DB011A96CD91DC911B978A81C5
:1011E0009B816EE571E00E94C706892B09F46CC0F3
:1011F00036E0A32EB12CAC0EBD1EEE24FF248701D9
:1012000022E0C22ED12C37C0E50122978881998136
:101210006EE977E00E94C706892B69F0EE0CFF1C8F
:10122000001F111F81E090E0A0E0B0E0E82AF92A59
:101230000A2B1B2B0DC0888199816EEE72E00E94F3
:10124000C706892B09F440C0EE0CFF1C001F111FBC
:10125000D5018D919C916EE571E00E94CC06E4E091
:10126000F0E0AE0EBF1E892B11F463010FC022E027
:1012700030E0C20ED31E36010894611C711C8091AF
:10128000780490E0681679060CF4BECFC601019789
:1012900095958795D40119969C938E9318974097AE
:1012A0002CF419961C921E9218970EC0F401E48239
:1012B000F582068317838AE090E09183808321E0A2
:1012C00030E040E050E004C020E030E040E050E09A
:1012D000B901CA01DF91CF911F910F91FF90EF905B
:1012E000DF90CF90BF90AF909F908F907F906F9046
:1012F00008956F927F928F929F92AF92BF92CF92FA
:10130000DF92EF92FF920F931F93CF93DF93FB0136
:101310003A0159016801DA012D913C918485958546
:101320002817390724F071E0E72EF12C56C0C901C7
:10133000880F991F0284F385E02DE80FF91F808143
:101340009181982E892E20FD06C00CE91FEF51E0F7
:10135000E52EF12C04C004E610E0EE24FF24B801D1
:101360006C0D7D1D892D982D0E947E06892B19F00C
:1013700021E030E020C0E601CC0FDD1FB8016C0F8A
:101380007D1F892D982D0E947E06892B19F022E061
:1013900030E011C0CC0DDD1D0C0F1D1F892D982DC7
:1013A000B8010E947E06892B21F4EE24EA94FE2CDB
:1013B00014C023E030E0F501808191810196918392
:1013C0008083821793074CF011821082D3018D9194
:1013D0009C91119701968D939C93C701DF91CF91BA
:1013E0001F910F91FF90EF90DF90CF90BF90AF9043
:1013F0009F908F907F906F9008952F923F924F9281
:101400005F926F927F928F929F92AF92BF92CF9294
:10141000DF92EF92FF920F931F93DF93CF9300D051
:1014200000D000D0CDB7DEB71C015B0180917804FD
:101430008D3008F47EC081E090E09A8389831C821D
:101440001B82A3E08A2E912C8C0E9D1EC1012E01C1
:101450000894411C511CA201940109E713E00E9469
:101460007909892B09F065C0C101B501A201940178
:101470000E947909019709F05CC0C101B501A20180
:1014800094010E947909892B09F053C0CC24DD24F2
:10149000760166247724C4018D829E832FC0C1010A
:1014A000B501A2012D813E8109E713E00E9479096F
:1014B0004C01C101B501A2012D813E810E94790933
:1014C00021E08216910479F4892B99F5CC0CDD1C6E
:1014D000EE1CFF1C81E090E0A0E0B0E0C82AD92A11
:1014E000EA2AFB2A08C0892821F5019711F5CC0CBE
:1014F000DD1CEE1CFF1C0894611C711C809178049B
:1015000090E029813A81281739074CF2D5011996C4
:101510007C926E921897F501C482D582E682F7829A
:1015200083E090E09183808321E030E040E050E070
:1015300004C020E030E040E050E0B901CA01269646
:101540000FB6F894DEBF0FBECDBFCF91DF911F91D4
:101550000F91FF90EF90DF90CF90BF90AF909F9052
:101560008F907F906F905F904F903F902F90089555
:101570002F923F924F925F926F927F928F929F92A3
:10158000AF92BF92CF92DF92EF92FF920F931F9391
:10159000DF93CF93CDB7DEB728970FB6F894DEBFB1
:1015A0000FBECDBF1C014B01DB011C968D919C91A0
:1015B0001D97181619060CF0C4C081E090E09A83BC
:1015C00089831A960D911C911B97F8018281938152
:1015D0006AE67AE00E94C706892B09F4B2C082E06D
:1015E00090E09A838983D80114968D919C911597E8
:1015F00069E773E00E94CC06892B09F4A2C083E05E
:1016000090E09A8389831C821B8203E0A02EB12C78
:10161000AC0EBD1EC101B4013E010894611C711CD9
:10162000A30195010CEB11E00E947909892B09F0C7
:1016300088C0C101B401A30195010E9479090197F5
:1016400009F07FC0CC24DD24760144245524C50153
:10165000AD829E83C3016F82988756C0C101B401D9
:101660004F8158852D813E810CEB11E00E94790954
:101670003C01B3E04B16510461F4C101B4014F8148
:1016800058852D813E810E9479096816790609F0F6
:1016900058C0C101B4014F8158852D813E810CEBAA
:1016A00011E00E9479095C01E3E04E16510459F4FF
:1016B000C101B4014F8158852D813E810E94790975
:1016C000A816B906F1F56114710489F4F1E0AF16BA
:1016D000B104B9F5CC0CDD1CEE1CFF1C81E090E0E0
:1016E000A0E0B0E0C82AD92AEA2AFB2A0AC091E081
:1016F0006916710431F5AB2821F5CC0CDD1CEE1C0C
:10170000FF1C0894411C511C29813A81D4011C966C
:101710008D919C911D97281739070CF49FCF19962E
:101720005C924E921897F401C482D582E682F782C9
:1017300084E090E09183808321E030E040E050E05D
:1017400004C020E030E040E050E0B901CA01289632
:101750000FB6F894DEBF0FBECDBFCF91DF911F91C2
:101760000F91FF90EF90DF90CF90BF90AF909F9040
:101770008F907F906F905F904F903F902F90089543
:101780006F927F928F929F92AF92BF92CF92DF9291
:10179000EF92FF920F931F93CF93DF937B01FB0197
:1017A000C285D3858A819B816EEA7DE00E94C7064F
:1017B000892B09F474C08C819D8166ED76E00E94CE
:1017C000C706892B09F46BC0269600E010E0DD24E3
:1017D000CC24992488247724662483E0A82EB12C75
:1017E0008881998166EF71E00E94C706892B09F410
:1017F00056C08A819B816CED74E00E94CC06892BD7
:1018000069F098014D2D5C2D692D782D872D962D31
:1018100001E00E940C01022F016013C08A819B81AC
:1018200060E971E00E94CC06892BC9F198014D2D29
:101830005C2D692D782D872D962D01E00E940C01DD
:10184000022F132FD42EC52E962E872E782E692E7A
:101850002496F1E6AF16B10429F082E090E0A80EDC
:10186000B91EBECFC801F701048395834683578311
:101870009801872D962D00E20E948D00C901F70185
:101880002283938387E090E09183808380E390E0DC
:101890009187808721E030E040E050E004C020E004
:1018A00030E040E050E0B901CA01DF91CF911F91D3
:1018B0000F91FF90EF90DF90CF90BF90AF909F90EF
:1018C0008F907F906F9008958F929F92AF92BF926A
:1018D000CF92DF92EF92FF920F931F93CF93DF93FC
:1018E0006B0180917804823209F0B2C0DB011A9654
:1018F000CD91DC911B978A819B8168E572E00E9403
:10190000C706892B09F4A4C08091780421E030E057
:10191000281B3109220F331FC21BD30B88819981E9
:1019200068E572E00E94C706892B09F491C0F601B0
:10193000118610868FEF9FEFAFEFBFEF8483958303
:10194000A683B78388E090E09183808369C080910B
:101950007804813208F469C0D50114968D919C9168
:10196000159760EA7FE00E94CC06892B09F45DC0E0
:10197000E5012696EE24FF24870133E0832E912C87
:101980008881998168E572E00E94C706892B09F475
:101990004CC08A819B8160E476E00E94CC06892B52
:1019A00069F0EE0CFF1C001F111F81E090E0A0E029
:1019B000B0E0E82AF92A0A2B1B2B0CC08A819B81F4
:1019C00066E272E00E94CC06892B79F1EE0CFF1CD6
:1019D000001F111FA2E0B0E08A0E9B1E2496B3E206
:1019E0008B16910469F6E6E4F0E0AE0EBF1ED50159
:1019F0008D919C9168E572E00E94C706892BA9F041
:101A000080E190E0F60191878087D6011496ED92EF
:101A1000FD920D931C93179788E090E08D939C9313
:101A200021E030E040E050E004C020E030E040E061
:101A300050E0B901CA01DF91CF911F910F91FF9042
:101A4000EF90DF90CF90BF90AF909F908F900895D0
:101A5000F601A284B384D50112968D919C911397BF
:101A600060E47FE10E94C706892B09F070CFDDCFCB
:101A70002F923F924F925F926F927F928F929F929E
:101A8000AF92BF92CF92DF92EF92FF920F931F938C
:101A9000DF93CF9300D0CDB7DEB71B01FB01848568
:101AA0009585863091052CF420E030E040E050E050
:101AB00081C0F5ECAF2EFDE9BF2EFCE1CF2EF1E8A1
:101AC000DF2EE6E04E2E512C9C01220F331F3A836D
:101AD000298359C0F101A285B385F2013497EA0F39
:101AE000FB1FE080F180A40DB51D6D917C9180E01D
:101AF00090E00E94E0143B014C0100E010E0C801BE
:101B0000B7010E94E0147B018C012DEC3CEC4CE40D
:101B10005FE30E9492159B01AC01C401B3010E94D6
:101B2000431488231CF400E010E018C0C401B30182
:101B30002DEC3CEC4CE45FE30E9492159B01AC0160
:101B4000C801B7010E944314082F112707FD109503
:101B50000027110F001F11270F5F1F4FC601B5018E
:101B600023E931E040E051E00E94F5155801CC2412
:101B7000B7FCC094DC2CA626B726C826D92622E0BE
:101B800030E0420E531E89819A814816590609F0A9
:101B9000A1CFF101A482B582C682D78280E290E013
:101BA000918780878FEF9FEF9183808321E030E0E2
:101BB00040E050E0B901CA010F900F90CF91DF9142
:101BC0001F910F91FF90EF90DF90CF90BF90AF905B
:101BD0009F908F907F906F905F904F903F902F904D
:101BE00008950F931F93CF93DF938C01EB0180EB4C
:101BF00093E09B878A87809178048C871D868091EB
:101C0000AC03853009F057C0C8010E94DC0661159D
:101C100071058105910509F051C0C801BE010E94FE
:101C20008B07611571058105910509F047C0C80151
:101C3000BE010E942C086115710581059105F1F521
:101C4000C801BE010E94D608611571058105910584
:101C5000A9F5C801BE010E94FD0961157105810544
:101C6000910561F5C801BE010E94B80A61157105B0
:101C70008105910519F5C801BE010E94C00B6115CF
:101C8000710581059105D1F4C801BE010E94640C63
:101C9000611571058105910589F4C801BE010E9495
:101CA000380D611571058105910541F482E080933D
:101CB000AC031092780420E030E002C021E030E074
:101CC000C901DF91CF911F910F9108951F920F923B
:101CD0000FB60F9211242F933F934F935F936F93FF
:101CE0007F938F939F93AF93BF93EF93FF938091D5
:101CF000AB030E94E50F482F8091AE039091AF0394
:101D000001969093AF038093AE038091780484365C
:101D100018F085E08093AC038091AC038330D1F060
:101D2000843020F4823009F059C006C0843071F14B
:101D3000853009F053C04CC0442309F04FC0809156
:101D4000AE039091AF038436910508F443C010921E
:101D500078041EC0413009F041C080917804E82F1A
:101D6000F0E02091AE033091AF03EE0FFF1FE55579
:101D7000FC4F368325838F5F809378041092AF03E6
:101D80001092AE0384E08093AC0328C04423B9F4DE
:101D900080917804E82FF0E02091AE033091AF03FA
:101DA000EE0FFF1FE555FC4F368325838F5F809331
:101DB00078041092AF031092AE0383E0E4CF8091D9
:101DC000AE039091AF038536910540F085E0DBCFFF
:101DD000442321F41092AF031092AE038091AD031F
:101DE000882329F0442311F42D9A01C02D98FF91E6
:101DF000EF91BF91AF919F918F917F916F915F9183
:101E00004F913F912F910F900FBE0F901F901895FB
:101E1000F89492E09093B0009093B10084E68093A0
:101E2000B300E2EBF0E01082E081909370007894D0
:101E300082E08093AC03109278048091AB0360E061
:101E40000E94A60F08951F920F920FB60F921124B1
:101E50002F933F938F939F93AF93BF9380917D0474
:101E600090917E04A0917F04B09180043091810410
:101E70000196A11DB11D232F2D5F2D3720F02D5769
:101E80000196A11DB11D2093810480937D04909340
:101E90007E04A0937F04B093800480917904909194
:101EA0007A04A0917B04B0917C040196A11DB11D20
:101EB0008093790490937A04A0937B04B0937C047C
:101EC000BF91AF919F918F913F912F910F900FBE36
:101ED0000F901F901895789484B5826084BD84B566
:101EE000816084BD85B5826085BD85B5816085BD15
:101EF000EEE6F0E0808181608083E1E8F0E010822E
:101F0000808182608083808181608083E0E8F0E06E
:101F1000808181608083E1EBF0E080818460808358
:101F2000E0EBF0E0808181608083EAE7F0E080818F
:101F300084608083808182608083808181608083EF
:101F40008081806880831092C1000895CF93DF93D1
:101F5000482F50E0CA0186569F4FFC0134914A57E2
:101F60005F4FFA018491882369F190E0880F991FEF
:101F7000FC01E859FF4FA591B491FC01EE58FF4FC9
:101F8000C591D491662351F42FB7F8948C91932F77
:101F9000909589238C93888189230BC0623061F4EA
:101FA0002FB7F8948C91932F909589238C938881E7
:101FB000832B88832FBF06C09FB7F8948C91832B07
:101FC0008C939FBFDF91CF910895682F70E0CB0174
:101FD00082559F4FFC012491CB0186569F4FFC01F7
:101FE00044916A577F4FFB019491992319F420E0A3
:101FF00030E03CC0222351F1233071F0243028F42A
:102000002130A1F0223011F514C02630B1F0273074
:10201000C1F02430D9F404C0809180008F7703C0D0
:10202000809180008F7D8093800010C084B58F7771
:1020300002C084B58F7D84BD09C08091B0008F77C8
:1020400003C08091B0008F7D8093B000892F90E015
:10205000880F991F84589F4FFC01A591B4918C91D2
:1020600020E030E0842311F021E030E0C901089540
:1020700008951F920F920FB60F9211242F933F9342
:102080004F938F939F93EF93FF938091C00082FDB6
:102090001DC04091C6002091C2043091C3042F5F3F
:1020A0003F4F2F7330708091C4049091C50428175E
:1020B000390771F0E091C204F091C304EE57FB4F71
:1020C00040833093C3042093C20402C08091C600B1
:1020D000FF91EF919F918F914F913F912F910F9091
:1020E0000FBE0F901F901895E0911605F0911705FF
:1020F000E05CFF4F8191919120813181821B930B94
:102100008F739070892B11F00E94381008951F92E0
:102110000F920FB60F9211242F933F938F939F939B
:10212000EF93FF93209106053091070580910805F4
:10213000909109052817390731F48091C1008F7DEE
:102140008093C10014C0E0910805F0910905EA539D
:10215000FB4F2081809108059091090501968F73AE
:10216000907090930905809308052093C600FF9115
:10217000EF919F918F913F912F910F900FBE0F90F4
:102180001F901895AF92BF92DF92EF92FF920F933C
:102190001F93CF93DF93EC017A018B01DD24403054
:1021A00081EE580780E0680780E0780711F0DD24B1
:1021B000D39491E0A92EB12CEC89FD89DD2069F042
:1021C000C50108A002C0880F991F0A94E2F7808316
:1021D00060E079E08DE390E005C0108260E874E88B
:1021E0008EE190E0A80197010E9414162150304022
:1021F00040405040569547953795279580E12030CF
:10220000380720F0DD2011F0DD24D6CFE889F989E8
:102210003083EA89FB89208319A2EE89FF894081F6
:1022200021E030E0C9010C8C02C0880F991F0A948C
:10223000E2F7482B4083EE89FF894081C9010D8C6C
:1022400002C0880F991F0A94E2F7482B4083EE8959
:10225000FF894081C9010E8C02C0880F991F0A9422
:10226000E2F7482B4083EE89FF8980810F8C02C002
:10227000220F331F0A94E2F7209528232083DF9151
:10228000CF911F910F91FF90EF90DF90BF90AF9093
:102290000895DC011C96ED91FC911D97E05CFF4FC9
:1022A0002191319180819181281B390B2F733070DE
:1022B000C9010895DC011C96ED91FC911D97E05C2D
:1022C000FF4F20813181E054F040DF01AE5BBF4F12
:1022D0008D919C9111972817390719F42FEF3FEF33
:1022E00007C08D919C91E80FF91F8081282F30E065
:1022F000C9010895DC011C96ED91FC911D97E05CED
:10230000FF4F20813181E054F040DF01AE5BBF4FD1
:102310008D919C9111972817390719F42FEF3FEFF2
:1023200010C08D919C911197E80FF91F20818D911C
:102330009C91119701968F73907011969C938E9338
:1023400030E0C9010895DC0191968C919197882322
:1023500039F05496ED91FC915597808186FFF9CF25
:1023600091961C920895CF93DF93EC01EE85FF8543
:10237000E05CFF4F20813181E054F0402F5F3F4F00
:102380002F733070DF01AE5BBF4F8D919C91119721
:1023900028173907D1F3E05CFF4F80819181E05429
:1023A000F040E80FF91F6083EE85FF85E05CFF4F8A
:1023B00031832083EE89FF89208181E090E00F8CBA
:1023C00002C0880F991F0A94E2F7282B208381E02E
:1023D00089A3EC89FD8980818064808381E090E01D
:1023E000DF91CF91089510920D0510920C0588EEA3
:1023F00093E0A0E0B0E080930E0590930F05A093CA
:102400001005B093110583E891E090930B0580933C
:102410000A0582E894E0909317058093160586ECF0
:1024200094E0909319058093180585EC90E09093C3
:102430001B0580931A0584EC90E090931D05809312
:102440001C0580EC90E090931F0580931E0581ECA5
:1024500090E0909321058093200582EC90E090938A
:1024600023058093220586EC90E0909325058093C8
:10247000240584E08093260583E08093270587E088
:102480008093280585E08093290581E080932A05C3
:102490000895CF93DF930E946B0F0E946706C4E7F5
:1024A000D0E10E94A0052097E1F30E947410F9CFBB
:1024B000CF92DF92EF92FF920F931F93CF93DF9310
:1024C0007C016B018A01C0E0D0E00FC0D6016D91A4
:1024D0006D01D701ED91FC910190F081E02DC701D4
:1024E0000995C80FD91F015010400115110571F74A
:1024F000CE01DF91CF911F910F91FF90EF90DF9070
:10250000CF900895EF92FF920F931F938C01DC01FF
:10251000ED91FC910190F081E02D6DE009957C0139
:10252000D801ED91FC910190F081E02DC8016AE0A5
:1025300009959C012E0D3F1DC9011F910F91FF9020
:10254000EF900895CF93DF93EC016115710519F4B5
:1025500020E030E00FC0DB010D900020E9F711977B
:10256000A61BB70BE881F9810280F381E02DAD0154
:1025700009959C01C901DF91CF9108954F925F9217
:102580007F928F929F92AF92BF92CF92DF92EF9203
:10259000FF920F931F93DF93CF93CDB7DEB7A19731
:1025A0000FB6F894DEBF0FBECDBF2C01742ECB0149
:1025B000223008F42AE019A231E2C32ED12CCC0E2D
:1025C000DD1E822E9924AA24BB24672D752FA50118
:1025D00094010E94141679018A01C801B701A5016E
:1025E00094010E94F515472D461B0894C108D10897
:1025F0004A3014F4405D01C0495CF6014083E114A7
:10260000F1040105110521F07E2C5F2DC801DDCFFD
:10261000C201B6010E94A212A1960FB6F894DEBFC5
:102620000FBECDBFCF91DF911F910F91FF90EF9023
:10263000DF90CF90BF90AF909F908F907F905F90F2
:102640004F900895DC012115310541F4ED91FC9185
:102650000190F081E02D642F099508950E94BE122B
:102660000895EF92FF920F931F937C010E94221313
:102670008C01C7010E9482129C01200F311FC901E9
:102680001F910F91FF90EF900895EF92FF920F939B
:102690001F939A017B0100E010E0B801A7010E949E
:1026A00022131F910F91FF90EF900895CF92DF9228
:1026B000EF92FF920F931F93CF93DF93EC016A0188
:1026C0007B012115310541F4E881F9810190F08108
:1026D000E02D642F09951FC02A303105D1F477FF12
:1026E00017C0E881F9810190F081E02D6DE2099534
:1026F0008C0144275527BA014C195D096E097F09E1
:10270000CE012AE00E94BE129801280F391F04C092
:102710002AE00E94BE129C01C901DF91CF911F9156
:102720000F91FF90EF90DF90CF900895EF92FF927E
:102730000F931F937B019A010027F7FC0095102F40
:10274000B801A7010E9456131F910F91FF90EF90BF
:102750000895CF92DF92EF92FF920F931F936C0137
:102760007B019A010027F7FC0095102FB801A70103
:102770000E9456138C01C6010E948212080F191F75
:10278000C8011F910F91FF90EF90DF90CF900895B7
:102790000E94A2120895EF92FF920F931F937C0163
:1027A0000E94A2128C01C7010E948212080F191FF9
:1027B000C8011F910F91FF90EF9008955058BB27CB
:1027C000AA270ED075C166D130F06BD120F031F45C
:1027D0009F3F11F41EF45BC10EF4E095E7FB51C17D
:1027E000E92F77D180F3BA1762077307840795073B
:1027F00018F071F49EF58FC10EF4E0950B2EBA2FF0
:10280000A02D0B01B90190010C01CA01A0011124F6
:10281000FF27591B99F0593F50F4503E68F11A16A2
:10282000F040A22F232F342F4427585FF3CF469533
:1028300037952795A795F0405395C9F77EF41F1655
:10284000BA0B620B730B840BBAF09150A1F0FF0F1F
:10285000BB1F661F771F881FC2F70EC0BA0F621F0B
:10286000731F841F48F4879577956795B795F795FB
:102870009E3F08F0B3CF9395880F08F09927EE0F8D
:10288000979587950895D9D008F481E008950CD0E4
:102890000FC107D140F0FED030F021F45F3F19F0B6
:1028A000F0C0511139C1F3C014D198F39923C9F381
:1028B0005523B1F3951B550BBB27AA276217730746
:1028C000840738F09F5F5F4F220F331F441FAA1FFA
:1028D000A9F333D00E2E3AF0E0E830D091505040BA
:1028E000E695001CCAF729D0FE2F27D0660F771F68
:1028F000881FBB1F261737074807AB07B0E809F04A
:10290000BB0B802DBF01FF2793585F4F2AF09E3FDE
:10291000510568F0B6C000C15F3FECF3983EDCF3B0
:10292000869577956795B795F7959F5FC9F7880F57
:10293000911D9695879597F90895E1E0660F771FA9
:10294000881FBB1F621773078407BA0720F0621B3A
:10295000730B840BBA0BEE1F88F7E095089504D033
:102960006894B111D9C00895BCD088F09F5790F0F9
:10297000B92F9927B751A0F0D1F0660F771F881FA4
:10298000991F1AF0BA95C9F712C0B13081F0C3D0BF
:10299000B1E00895C0C0672F782F8827B85F39F05D
:1029A000B93FCCF3869577956795B395D9F73EF403
:1029B00090958095709561957F4F8F4F9F4F0895AB
:1029C000E89409C097FB3EF49095809570956195C9
:1029D0007F4F8F4F9F4F9923A9F0F92F96E9BB277F
:1029E0009395F695879577956795B795F111F8CFFB
:1029F000FAF4BB0F11F460FF1BC06F5F7F4F8F4F66
:102A00009F4F16C0882311F096E911C0772321F05B
:102A10009EE8872F762F05C0662371F096E8862FF3
:102A200070E060E02AF09A95660F771F881FDAF74A
:102A3000880F9695879597F90895990F0008550F77
:102A4000AA0BE0E8FEEF16161706E807F907C0F034
:102A500012161306E407F50798F0621B730B840B3C
:102A6000950B39F40A2661F0232B242B252B21F416
:102A700008950A2609F4A140A6958FEF811D811DB6
:102A8000089597F99F6780E870E060E008959FEFF0
:102A900080EC089500240A941616170618060906F5
:102AA000089500240A9412161306140605060895C4
:102AB000092E0394000C11F4882352F0BB0F40F44C
:102AC000BF2B11F460FF04C06F5F7F4F8F4F9F4F8C
:102AD000089557FD9058440F551F59F05F3F71F00E
:102AE0004795880F97FB991F61F09F3F79F0879575
:102AF0000895121613061406551FF2CF4695F1DFFE
:102B000008C0161617061806991FF1CF869571058D
:102B1000610508940895E894BB2766277727CB01C1
:102B200097F908950BD0C4CFB5DF28F0BADF18F0BD
:102B3000952309F0A6CFABCF1124EECFCADFA0F3C7
:102B4000959FD1F3950F50E0551F629FF001729F42
:102B5000BB27F00DB11D639FAA27F00DB11DAA1F61
:102B6000649F6627B00DA11D661F829F2227B00DAE
:102B7000A11D621F739FB00DA11D621F839FA00D39
:102B8000611D221F749F3327A00D611D231F849F89
:102B9000600D211D822F762F6A2F11249F575040E0
:102BA0008AF0E1F088234AF0EE0FFF1FBB1F661F7B
:102BB000771F881F91505040A9F79E3F510570F034
:102BC00060CFAACF5F3FECF3983EDCF38695779514
:102BD0006795B795F795E7959F5FC1F7FE2B880F2F
:102BE000911D9695879597F90895629FD001739FDF
:102BF000F001829FE00DF11D649FE00DF11D929F99
:102C0000F00D839FF00D749FF00D659FF00D9927D7
:102C1000729FB00DE11DF91F639FB00DE11DF91FFB
:102C2000BD01CF0111240895A1E21A2EAA1BBB1BDE
:102C3000FD010DC0AA1FBB1FEE1FFF1FA217B30788
:102C4000E407F50720F0A21BB30BE40BF50B661F9E
:102C5000771F881F991F1A9469F760957095809562
:102C600090959B01AC01BD01CF010895EE0FFF1FB0
:102C70000590F491E02D0994911106C0803219F06D
:102C800089508550D0F70895992788270895F8949A
:022C9000FFCF74
:102C9200486173683A2000466F722049522053639C
:102CA2006F70653A20002B00200000466F722041B1
:102CB200726475696E6F20736B657463683A200085
:102CC200756E7369676E656420696E7420726177D0
:102CD2005B005D203D207B002C007D3B0069727310
:102CE200656E642E73656E64526177287261772C0B
:102CF200002C3338293B0053454E440053454E5473
:102D0200200030780052454144590008000100007B
:102D1200000000B311581249117A115A11A311007F
:00000001FF
/*
Send Pronto Hex via an IR LED connected to Arduino Pin D9.
Make sure you do not send a blank (" ") as the last character.
Send the following command over the serial line:
# Sony12, device = 1, obc = 47
SEND 0000 0067 0000 000d 0060 0018 0030 0018 0030 0018 0030 0018 0030 0018 0018 0018 0030 0018 0018 0018 0030 0018 0018 0018 0018 0018 0018 0018 0018 03de
or
# RC5, device = 11, obc = 64
SEND 0000 0073 0000 000B 0040 0020 0020 0020 0020 0040 0040 0040 0020 0020 0040 0020 0020 0020 0020 0020 0020 0020 0020 0020 0020 0CC8
Based on https://github.com/stephenong/Arduino-IR-Remote-Control-Player
*/
#include <avr/interrupt.h>
#include <stdio.h>
#include <avr/pgmspace.h>
#include <stdint.h>
#include <avr/io.h>
#define IR_PORT PORTB
#define IR_PIN PINB
#define IR_DDR DDRB
#define IR_BV _BV(1)
#define IR_OCR OCR1A
#define IR_TCCRnA TCCR1A
#define IR_TCCRnB TCCR1B
#define IR_TCNTn TCNT1
#define IR_TIFRn TIFR1
#define IR_TIMSKn TIMSK1
#define IR_TOIEn TOIE1
#define IR_ICRn ICR1
#define IR_OCRn OCR1A
#define IR_COMn0 COM1A0
#define IR_COMn1 COM1A1
#define PRONTO_IR_SOURCE 0 // Pronto code byte 0
#define PRONTO_FREQ_CODE 1 // Pronto code byte 1
#define PRONTO_SEQUENCE1_LENGTH 2 // Pronto code byte 2
#define PRONTO_SEQUENCE2_LENGTH 3 // Pronto code byte 3
#define PRONTO_CODE_START 4 // Pronto code byte 4
static const uint16_t *ir_code = NULL;
static uint16_t ir_cycle_count = 0;
static uint32_t ir_total_cycle_count = 0;
static uint8_t ir_seq_index = 0;
static uint8_t ir_led_state = 0;
void ir_on()
{
IR_TCCRnA |= (1<<IR_COMn1) + (1<<IR_COMn0);
ir_led_state = 1;
}
void ir_off()
{
IR_TCCRnA &= ((~(1<<IR_COMn1)) & (~(1<<IR_COMn0)) );
ir_led_state = 0;
}
void ir_toggle()
{
if (ir_led_state)
ir_off();
else
ir_on();
}
void ir_start(uint16_t *code)
{
ir_code = code;
IR_PORT &= ~IR_BV; // Turn output off
IR_DDR |= IR_BV; // Set it as output
IR_TCCRnA = 0x00; // Reset the pwm
IR_TCCRnB = 0x00;
//printf_P(PSTR("FREQ CODE: %hd\r\n"), code[PRONTO_FREQ_CODE]);
uint16_t top = ( (F_CPU/1000000.0) * code[PRONTO_FREQ_CODE] * 0.241246 ) - 1;
//printf_P(PSTR("top: %hu\n\r"), top);
IR_ICRn = top;
IR_OCRn = top >> 1;
IR_TCCRnA = (1<<WGM11);
IR_TCCRnB = (1<<WGM13) | (1<<WGM12);
IR_TCNTn = 0x0000;
IR_TIFRn = 0x00;
IR_TIMSKn = 1 << IR_TOIEn;
ir_seq_index = PRONTO_CODE_START;
ir_cycle_count = 0;
ir_on();
IR_TCCRnB |= (1<<CS10);
}
#define TOTAL_CYCLES 80000 // Turns off after this number of
// cycles. About 2 seconds
// FIXME: Turn off after having sent
ISR(TIMER1_OVF_vect) {
uint16_t sequenceIndexEnd;
uint16_t repeatSequenceIndexStart;
ir_total_cycle_count++;
ir_cycle_count++;
if (ir_cycle_count== ir_code[ir_seq_index]) {
ir_toggle();
ir_cycle_count = 0;
ir_seq_index++;
sequenceIndexEnd = PRONTO_CODE_START +
(ir_code[PRONTO_SEQUENCE1_LENGTH]<<1) +
(ir_code[PRONTO_SEQUENCE2_LENGTH]<<1);
repeatSequenceIndexStart = PRONTO_CODE_START +
(ir_code[PRONTO_SEQUENCE1_LENGTH]<<1);
if (ir_seq_index >= sequenceIndexEnd ) {
ir_seq_index = repeatSequenceIndexStart;
if(ir_total_cycle_count>TOTAL_CYCLES) {
ir_off();
TCCR1B &= ~(1<<CS10);
}
}
}
}
void ir_stop()
{
IR_TCCRnA = 0x00; // Reset the pwm
IR_TCCRnB = 0x00;
}
const uint16_t inputLength = 512;
void setup() {
Serial.begin(9600);
Serial.println("READY");
}
void loop()
{
if ( Serial.available() > 0 )
{
static char input[inputLength];
static uint16_t i;
char c = Serial.read();
if ( c != '\r' && c != '\n' && i < inputLength-1)
input[i++] = c;
else
{
input[i] = '\0';
i = 0;
uint16_t array[80];
uint16_t j = 0;
if ( !strncmp(input, "SEND", 4) )
{
char* p = input+4;
while ( (p = strchr(p, ' ')) != NULL )
array[j++] = strtol(p, &p, 16);
ir_start(array);
Serial.print("SENT ");
for ( uint8_t i = 0; i < j; i++ )
{
Serial.print ("0x");
Serial.print (array[i], HEX);
Serial.print(" ");
}
Serial.println();
}
}
}
}
@ajmas
Copy link

ajmas commented May 25, 2016

Just saw this requires the library from http://www.pjrc.com/teensy/td_libs_IRremote.html to be installed. Alternatively there is https://github.com/z3t0/Arduino-IRremote , though in both cases note the following potential issue: https://github.com/z3t0/Arduino-IRremote/issues/98

This code can be used with the setup here (based on trying), but you may need to tweak things slightly: https://learn.sparkfun.com/tutorials/ir-control-kit-hookup-guide

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment