Arduino, 改良那八個按鍵的特製遙控器

 

http://wp.me/ph3BR-1QB

 

I have a pen I have an apple, 據說是某小孩突然著迷的口水歌, 他要把人生裡面遇到這個讓其驚喜的 YOUTUBE 片段與人分享, 多數長輩看過, 一般都認為是很無聊的洗腦歌, 然後某爸爸很感冒, 因為小孩看了又看播了又播. 不過回頭看, 人生不是很多時候很多人都是做自己很得意但是外人看來很無聊的事情嗎 !? 自我感覺良好就可以了, 不太干擾他人的話, 其實也不需要太多干涉. 成長過程大都有這樣得行為.

同樣因為自認為有需求, 搞了一個只有八個按鍵的特製遙控器, 用的是 Arduino Uno 的板子, 不是因為愛用, 是因為快速和現成山寨, 容易上手就用了, 半天就趕製了一個 [很好用] 的遙控器, 一鍵開機, 是同時開電視機, 機上盒, 音響等等, 自動轉到預定的電視節頻道, 自動打開電視盒轉台到預定的電視節目, 自動接通對應的音響設備, 日後想要怎樣改良都可, 換了其他機器也不怕, 就這三個自動的行為, 外面付錢也買不到, 量少也太專門了, 沒商家會大量生產.

不過有個問題, 就是費電池, 用筆電的壞電池閘拆除來的一個18650電池, 大約半年需要給充電池一次, 因為初步設計匆忙只用了RC延時斷電 (原理參考這篇), 停止後是完全不漏電的, 這個設計已經在很多台沒有自動關機功能的DMM, 成功改機並使用多年的結果得到證實. 20M 電阻加上 100uF 電容, 好像15分鐘才自動斷電, 把電容換成47uF, 大概也要7分鐘, 還有是要先按 [上電], 再按 [開機], 兩個按鈕動作, 給MCU供電, 然後再按 [開機] 鍵執行程序, 也是這個原因所以必須設計用了 8個按鍵, 不然7個就好. 就這兩點已經不夠人性化或便利性, 比對一般的紅外線遙控器, 用者都是隨用隨按任意按鍵, 起碼一年不用換電池的. 費電池的原因是, Arduino Uno 的板子除了 CPU 在運作, 還有其他IC和LED, 沒有按鍵動作也在耗電, 整體運作大約要 26 mA, 算是第一版的設計, 總體來說比拿著5個不同廠牌的遙控器還要記住個別的開機程序, 這個特製遙控器是真的很好了.

為了更好, 實驗, 修改設計, 用 MCU的一個腳控制 N-MOSFET 斷電, 按鍵處理完畢馬上由MCU指令斷電, 因此立刻沒有了26mA耗電, 比第一版的設計改良很多了, 可是, 故事並非那麼簡單. 實驗完畢, 必須確認成果, MCU 雖然控制斷電成功, 但是依然耗電 0.5mA, 一直到電池沒電, 長期來看, 這個第二版的設計其實很糟糕, 因為 N-MOSFET 必須安裝在 LOW-SIDE 作為電源開關, 所以怎樣改變零件的參數都會有漏電, 沒有 P-MOSFET, 不想花錢買, 也沒有用 PNP 做 HIGH-SIDE 控制, 原因是, 必然會成功僅僅解決上面提到的兩個問題的其中一點, 不夠好. 這個第二版的設計並沒有實際使用.

第一版或第二版的設計, 整體的硬件並沒有改變, 純粹是接線多了一根或缺少一根. 樣子就這樣醜醜的, 不過堪用也實用.

Arduino IR transceiver upgrade
Arduino IR transceiver upgrade

 

 

繼續為了更好, 參考別人的建議, 這次實驗, 直接讓 MCU 睡覺, 按鍵就醒來做點事情, 完畢後繼續睡覺, 這樣一來, 就會很省電, 也不再需要8個按鍵的那個 [上電] 的動作了, 同時廢掉 Arduino 那些用不上的 LED 或 IC 等等, 整個系統就只有 MCU 本身和必要的按鍵. 沒有插麵包板的 DIP, 所以用不了 ATmega328, 退而求其次, 用了一個 ATmega8, 實驗睡覺功能, 還有耗電流的測試. 比對人家的測試結果, 用一個很陽春的砲灰表, 測電流, 居然很準確, MCU 睡覺是僅僅耗電大約 0.6uA, 比對第二版的設計實驗那個 0.5mA, 降低了約 1000 倍.

實驗的電路, 結果都說明這個方法可行,

ATmega8-sleep-wakeup
ATmega8-sleep-wakeup
ATmega8-sleep-wakeup
ATmega8-sleep-wakeup

 

源嗎是抄來的, 修改了一些, 配合 Arduino Uno 的 D13 的 LED


/* ATmega8 with internal 8Mhz clock (6cycle + 64ms) */
// lfuse = 0xd4
// ref : https://gist.github.com/mkleemann/1712180
// if need to bootload Arduino, lfuse = 0xdf, set to external 16MHz xtal
// 2016-DEC-23, xiaolaba

#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main(void)
{
//   DDRC |= (1 << PC2) | (1 << PC1);     // leds for testing
// arduino Uno, LED = D13, m328p pin 19, PB5
// uses Mega8 MCU, the same, pin 19, PB5
DDRB |= (1 << PB5); // LED for testing

DDRD &= ~(1 << PD2);    // INT0: input...
PORTD |= (1 << PD2);    // ...with pullup.

// level interrupt INT0 (low level)
MCUCR &= ~((1 << ISC01) | (1 << ISC00));

// infinite main loop
while (1)
{
// trigger leds for testing
blinkLED();
blinkLED();
blinkLED();
blinkLED();

// enable external interrupt
GICR |= (1 << INT0);

// set sleep mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);

// sleep_mode() has a possible race condition
sleep_enable();
sei();
sleep_cpu();
sleep_disable();

// waking up...
// disable external interrupt here, in case the external low pulse is too long
GICR &= ~(1 << INT0);

// disable all interrupts
cli();
}
}

void blinkLED(void)
{
PORTB ^= (1 << PB5);
_delay_ms(500);
PORTB ^= (1 << PB5);
_delay_ms(500);
}

ISR(INT0_vect)
{
// ISR might be empty, but is necessary nonetheless
//   PORTC ^= (1 << PC2);    // debugging
}

 


:1000000012C034C018C017C016C015C014C013C029
:1000100012C011C010C00FC00EC00DC00CC00BC06C
:100020000AC009C008C011241FBECFE5D4E0DEBF5E
:10003000CDBF26D043C0E4CF98B380E2982798BBC9
:100040002FEF39E698E1215030409040E1F700C0B1
:10005000000098B3892788BB2FEF39E688E121504B
:1000600030408040E1F700C0000008951F920F92D9
:100070000FB60F9211240F900FBE0F901F9018957E
:10008000BD9A8A98929A85B78C7F85BFD5DFD4DFD9
:10009000D3DFD2DF8BB780648BBF85B78F78806268
:1000A00085BF85B7806885BF7894889585B78F7739
:1000B00085BF8BB78F7B8BBFF894E8CFF894FFCFC9
:00000001FF

 

最後看看實際的運作, 這個砲灰表真的很給力, 跟人家用 HP 34401A 6位半電表量測結果 0.40uA 其實沒差多少, 當然只針對這個用途還有0.5mA降低1000倍的目標而已. 耶誕大餐早早結束, 實驗很快也做完, 紅色LED閃亮4次, MCU就睡覺了, 耗電00.6uA.

h_ttps://youtu.be/dwfQcKLv00E

 

 

下一步, 整合這些新的設計到韌體, 在自己做個比 Arduino Uno 更簡潔的硬體, 省電是最大的目標.

Arduino, Pure C programming

http://wp.me/ph3BR-1On

 

工具 :

ARDUINO MEGA2560, 用的是 AVR MCU ATmega2560

ARDUINO IDE 1.6.11

ATmega2560_PB7_LED_pin_blink
ATmega2560_PB7_LED_pin_blink

 

 

 

 

目標:

純粹 C 語言實驗, 閃亮 LED, 效果類似 ARDUINO IDE 提供的 BLINK SKETCH, 不過編碼效率和執行效率好非常多, 以前有涉獵少許這個範疇 例如這個(https://goo.gl/XFRU8Q).

其實需要用到別的 C library, 不要重新整合或者大量重寫碼, 這個方法應該是不錯的許選擇.

 

找出 ARDUINO MEGA2560 D13, 連結一個 LED, 名稱是 L.

對應 AVR ATmega2560 MUC 的 PIN 名稱是 PB7

 

ATmega2560_PB7_LED_pin
ATmega2560_PB7_LED_pin

 

抄人家的原碼來修修改改, 他的設計是用在 UNO (MCU 是 ATmega328p), LED, D13 對應的PIN 是 PB5, 將會用 ATmega2560, 所以要改成 PB7, 然後再加點油甜點錯, 改改讓自己滿意.


// Blink the LED of Arduino Mega2560 LED, pure C programming, complie with Arduino IDE 1.6.11
// xiaolaba, 2016-NOV-05

// ref  : https://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/
// Programming Arduino Uno in pure C

#include <avr/io.h>
#include <util/delay.h>

#define BLINK_SLOW_DELAY_MS 1000
#define BLINK_FAST_DELAY_MS 200
#define LED_pin 7 // LED pin# = Atmege2560 pin PB7 = Arduino Mega2560 D13

int main (void)
{
DDRB |= _BV(LED_pin); /* set LED_pin of PORTB for output*/

while(1) {
blink_fast();
blink_fast();
blink_fast();
blink_slow();
}
}

void blink_slow ()
{
PORTB |= _BV(LED_pin);    /* set LED_pin high to turn led on */
_delay_ms(BLINK_SLOW_DELAY_MS);

PORTB &= ~_BV(LED_pin);    /* set LED_pin low to turn led off */
_delay_ms(BLINK_SLOW_DELAY_MS);
}

void blink_fast ()
{
PORTB |= _BV(LED_pin);    /* set LED_pin high to turn led on */
_delay_ms(BLINK_FAST_DELAY_MS);

PORTB &= ~_BV(LED_pin);    /* set LED_pin low to turn led off */
_delay_ms(BLINK_FAST_DELAY_MS);
}

//END of program

 

 

 

最後這用 ARDUINO IDE 編譯, 上傳到板子, 就看到快閃3次慢閃一次, 重複.

 

 

 

 

參考:

http://www.atmel.com/tools/atmelstudio.aspx

https://balau82.wordpress.com/2011/03/29/programming-arduino-uno-in-pure-c/

http://yourduino.com/docs/MegaPinOut.png"

https://arduino-info.wikispaces.com/file/view/arduino-mega2560-schematic-F.jpg/346627792/arduino-mega2560-schematic-F.jpg

Intel D8751H 遇上現代的 ARDUINO

https://goo.gl/ZZXjPC

有一堆過氣的產品廢料,安了一些IC, 原來是INTEL出品,1980年的8751MCU,那種用陶瓷封裝,有個透明窗口的IC,這是第一次看到這些產品,反正不要錢,撿來,有啥用呢?

intel_8751h

有個幾個模擬器,沒有買新的89S51,也就是沒有CPU在上面,用這個8751如何?

首先,據説要用波長2537 Anmstrong紫外光燈,距離一英寸,照射那個IC上的透明的窗口,據説要30分鐘,把ERPOM裏面記載的程序清空,才可以把新的程序燒進去,據説曬太陽也可以,要一個星期的時間,或者用日光燈曬三年。INTEL的DATASHEET有些説明,http://www.datasheetcatalog.com/datasheets_pdf/8/7/5/1/8751H.shtml

第二步,就是找個燒錄器,把程序燒進去。需要用到21V和5V電壓,因爲這個產品據説當年的技術就是 8051 MCU 加上 2764之類的的 4K x 8bit EPROM 組在同一芯片誕生的,很好奇,也終于看到芯片的實際模樣。

這兩樣,都是有難度的,花錢就可以,但是又不想花這個錢來玩,所以用了一個比較笨的方法,自己做燒錄工具,選用手邊有的ARDUINO作爲燒錄器。

GOOGLE到一些現成的東西,不過還要改一大段才能達到目標,那先來讀出EPROM的内容作爲開始吧。

人家的作品 http://www.nycresistor.com/2012/07/07/stick-a-straw-in-its-brain-and-suck-how-to-read-a-rom/

人家的源碼 ,https://github.com/phooky/PROM/blob/master/tools/eeprom_read/eeprom_read.pde



#include <stdint.h>

// Set MAX_ADDR to the largest address you need
// to read. For example, for the 27C512 chips,
// you'll want to use a MAX_ADDR of 65536.
// (That's 512 * 1024 / 8.)
// A 27C256 would be 256 kilobits, or 256 * 1024 / 8 =
// 32768.
#define MAX_ADDR 65536L

// On my board, I've connected pins 26-41
// to the A0-A15 lines, and pins 2-10 to the
// Q0-Q7 lines. You'll want to change these
// pin choices to match your setup.
#define A0 26
#define Q0 2

// When you're all wired up, hit the reset button
// to start dumping the hex codes.

void setup() {
  for (int i = A0; i < A0+16; i++) {
    digitalWrite(i,LOW);
    pinMode(i, OUTPUT);
  }
  for (int i = Q0; i < Q0+8; i++) {
    digitalWrite(i,HIGH);
    pinMode(i, INPUT);
  }
  Serial.begin(115200);
}

void writeAddr(uint32_t addr) {
  uint32_t mask = 0x01;
  for (int i = A0; i < A0+16; i++) {
    if ((mask & addr) != 0) {
      digitalWrite(i,HIGH);
    } else { 
      digitalWrite(i,LOW);
    }
    mask = mask << 1;
  }
}


uint8_t readByte() {
  uint8_t data = 0;
  uint8_t mask = 0x1;
  for (int i = Q0; i < Q0+8; i++) {
    if (digitalRead(i) == HIGH) {
      data |= mask;
    }
    mask = mask << 1;
  }
  return data;
}

void loop() {
  uint32_t addr = 0;
  while (addr < MAX_ADDR) {
    for (int i = 0; i < 16; i++) {
      writeAddr(addr);
      uint8_t b = readByte();
      Serial.print(b, HEX);
      Serial.print(" ");
      addr++;
    }
    Serial.println("");
  }
  while (1) {}
}

ref :
http://dsaprojects.orgfree.com/electronics/8031-ah/e8031-ah.html

Mitutoyo 三豐 Digimatic Indicators Interface DIY, software test

http://wp.me/ph3BR-VC

前文再續, 書接上一回 (http://wp.me/ph3BR-Vq Mitutoyo 三豐 Digimatic Indicators Interface DIY)

話說這個 DIY 的項目, 硬件基本齊備, 訊號線已經 DIY 完成, 自己做3條, 節省了大約300英鎊.

餘下是測試軟件, 當然, 找現成的, 試驗成功後, 自己慢慢再修改或用專用的 MCU 就會容易很多, 起碼節省很多除錯的時間, 果然, 很順利就成功了.

nEO_IMG_DSCF7426 nEO_IMG_img262

.

.

.

測試結果的短片

h_ttp://youtu.be/Zy8_mJwUodk

.

.

試驗的圖片和筆記字料

.

.

.

debug output screen shot

nEO_IMG_debug_output

.

.

.

source code


// originated see, http://forum.arduino.cc/index.php?topic=79174.0
// modification, xiao_laba_cn@yahoo.com, 2013-07-28
// file name : digimatic-xiaolaba.pde

int req = 5; //mic REQ line goes to pin 5 through q1 (arduino high pulls request line low)
int dat = 2; //mic Data line goes to pin 2
int clk = 3; //mic Clock line goes to pin 3
int i = 0; int j = 0; int k = 0;
int signCh = 8;
int sign = 0;
int decimal;
int dpp;
int units;
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;
// char u;
byte mydata[14];

// modification, xiao_laba_cn@yahoo.com, 2013-07-28
int data_counter = 0;

void setup()
{
//Serial.begin(19200);
Serial.begin(115200);
pinMode(req, OUTPUT);
pinMode(clk, INPUT);
pinMode(dat, INPUT);
digitalWrite(clk, HIGH); // enable internal pull ups
digitalWrite(dat, HIGH); // enable internal pull ups
digitalWrite(req,LOW); // set request at high
}

void loop()
{   digitalWrite(req, HIGH); // generate set request
for( i = 0; i < 13; i++ ) {
k = 0;
for (j = 0; j < 4; j++) {
while( digitalRead(clk) == LOW) { } // hold until clock is high
while( digitalRead(clk) == HIGH) { } // hold until clock is low
bitWrite(k, j, (digitalRead(dat) & 0x1)); // edit post, added a )
}

mydata[i] = k;
sign = mydata[4];
v1= mydata[5];
v2= mydata[6];
v3= mydata[7];
v4= mydata[8];
v5= mydata[9];
v6= mydata[10];
decimal = mydata[11];
units = mydata[12];

// modification, xiao_laba_cn@yahoo.com, 2013-07-28
//      if (decimal == 0) dpp = 1;
//      if (decimal == 1) dpp = 10;
//      if (decimal == 2) dpp = 100;
//      if (decimal == 3) dpp = 1000;
//      if (decimal == 4) dpp = 10000;
//      if (decimal == 5) dpp = 100000;
}

if (sign == 8) {Serial.print("-");}
if (sign == 0) {Serial.print("+");}
//Serial.print(sign);
Serial.print(" ");
Serial.print(v1);
decimal = decimal -1; if (decimal == 0) { Serial.print(".");}  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(v2);
decimal = decimal -1; if (decimal == 0) { Serial.print(".");}  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(v3);
decimal = decimal -1; if (decimal == 0) { Serial.print(".");}  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(v4);
decimal = decimal -1; if (decimal == 0) { Serial.print(".");}   // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(v5);
decimal = decimal -1; if (decimal == 0) { Serial.print(".");}   // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(v6);
//decimal = decimal -1; if (decimal == 0) { Serial.print(".");}   // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(" ");
//Serial.print(decimal);  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
//Serial.print(" ");  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
if (units == 0) {Serial.print("mm");}  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
if (units == 1) {Serial.print("inch");}  // modification, xiao_laba_cn@yahoo.com, 2013-07-28

Serial.print(" ");    // modification, xiao_laba_cn@yahoo.com, 2013-07-28
data_counter = data_counter+1;    // modification, xiao_laba_cn@yahoo.com, 2013-07-28
Serial.print(data_counter); Serial.print(" xiao_laba_cn@yahoo.com, 2013-07-28"); {Serial.print("\r\n");}  // modification, xiao_laba_cn@yahoo.com, 2013-07-28

//Serial.println(units);  // modification, xiao_laba_cn@yahoo.com, 2013-07-28
digitalWrite(req,LOW);
delay(100);

}

.
.
.
digimatic.ATmega328-16MHz-xiaolaba.hex

:100000000C9462000C948A000C948A000C948A0070
:100010000C948A000C948A000C948A000C948A0038
:100020000C948A000C948A000C948A000C948A0028
:100030000C948A000C948A000C948A000C948A0018
:100040000C9462020C948A000C940F040C948A00A5
:100050000C948A000C948A000C948A000C948A00F8
:100060000C948A000C948A000000000024002700F1
:100070002A0000000000250028002B0000000000DE
:1000800023002600290004040404040404040202DA
:100090000202020203030303030301020408102007
:1000A0004080010204081020010204081020000012
:1000B0000007000201000003040600000000000029
:1000C00000000B0511241FBECFEFD8E0DEBFCDBF6F
:1000D00011E0A0E0B1E0E6E6FDE002C005900D927F
:1000E000A035B107D9F712E0A0E5B1E001C01D923B
:1000F000A831B107E1F710E0C4ECD0E004C02297CA
:10010000FE010E94AD06C23CD107C9F70E94450519
:100110000C94B1060C940000EF92FF920F931F9382
:100120008091370161E00E946403109251011092A6
:10013000500181E0E82EF12C012D112D96C0109276
:10014000550110925401109253011092520140C077
:1001500080913B010E94BC03892BD1F380913B012C
:100160000E94BC030197D1F3809139010E94BC0326
:10017000209154013091550180FF0EC0D801C70174
:100180000090520104C0880F991FAA1FBB1F0A9438
:10019000D2F7282B392B0FC0D801C701009052018C
:1001A00004C0880F991FAA1FBB1F0A94D2F780951D
:1001B0009095282339233093550120935401809141
:1001C00052019091530101969093530180935201F3
:1001D000809152019091530104970CF4B9CF209172
:1001E000500130915101F901E859FE4F80915401BD
:1001F000808380916C018093560110925701809109
:100200006D0180935C0110925D0180916E0180937D
:100210005E0110925F0180916F01809360011092E6
:10022000610180917001809362011092630180915D
:100230007101809364011092650180917201809335
:1002400066011092670180917301809358011092AA
:1002500059018091740180935A0110925B012F5FC4
:100260003F4F309351012093500180915001909164
:1002700051010D970CF463CF809156019091570175
:10028000089731F485E092E060E071E00E94830518
:100290008091560190915701892B31F485E092E0CD
:1002A00062E071E00E94830585E092E064E071E025
:1002B0000E94830560915C0170915D0185E092E090
:1002C0004AE050E00E945B068091580190915901EC
:1002D00001979093590180935801892B31F485E05F
:1002E00092E066E071E00E94830560915E0170918A
:1002F0005F0185E092E04AE050E00E945B06809159
:100300005801909159010197909359018093580198
:10031000892B31F485E092E066E071E00E9483056C
:10032000609160017091610185E092E04AE050E0E7
:100330000E945B068091580190915901019790931A
:10034000590180935801892B31F485E092E066E0F1
:1003500071E00E948305609162017091630185E004
:1003600092E04AE050E00E945B0680915801909133
:10037000590101979093590180935801892B31F4C9
:1003800085E092E066E071E00E948305609164017F
:100390007091650185E092E04AE050E00E945B06C2
:1003A0008091580190915901019790935901809340
:1003B0005801892B31F485E092E066E071E00E94FB
:1003C0008305609166017091670185E092E04AE0E3
:1003D00050E00E945B0685E092E064E071E00E94DC
:1003E000830580915A0190915B01892B31F485E05E
:1003F00092E068E071E00E94830580915A0190913B
:100400005B01019731F485E092E06BE071E00E94BE
:10041000830585E092E064E071E00E9483056091CD
:100420007601709177016F5F7F4F709377016093D2
:10043000760185E092E04AE050E00E945B0685E0AC
:1004400092E060E171E00E94830585E092E064E360
:1004500071E00E9483058091370160E00E9464038F
:1004600064E670E080E090E00E94AA021F910F9184
:10047000FF90EF90089585E092E040E052EC61E05B
:1004800070E00E9440048091370161E00E943E03C9
:1004900080913B0160E00E943E038091390160E061
:1004A0000E943E0380913B0161E00E9464038091C1
:1004B000390161E00E9464038091370160E00E948D
:1004C000640308951F920F920FB60F9211242F9379
:1004D0003F938F939F93AF93BF9380917C019091B3
:1004E0007D01A0917E01B0917F0130918001019644
:1004F000A11DB11D232F2D5F2D3720F02D57019603
:10050000A11DB11D2093800180937C0190937D01FA
:10051000A0937E01B0937F01809178019091790141
:10052000A0917A01B0917B010196A11DB11D80932C
:10053000780190937901A0937A01B0937B01BF91E8
:10054000AF919F918F913F912F910F900FBE0F9080
:100550001F9018959B01AC017FB7F89480917801AA
:1005600090917901A0917A01B0917B0166B5A89B29
:1005700005C06F3F19F00196A11DB11D7FBFBA2FB5
:10058000A92F982F8827860F911DA11DB11D62E00C
:10059000880F991FAA1FBB1F6A95D1F7BC012DC0F8
:1005A000FFB7F8948091780190917901A0917A0138
:1005B000B0917B01E6B5A89B05C0EF3F19F001960D
:1005C000A11DB11DFFBFBA2FA92F982F88278E0F0D
:1005D000911DA11DB11DE2E0880F991FAA1FBB1F2D
:1005E000EA95D1F7861B970B885E9340C8F221509D
:1005F00030404040504068517C4F21153105410545
:10060000510571F60895789484B5826084BD84B5EF
:10061000816084BD85B5826085BD85B5816085BDFD
:10062000EEE6F0E0808181608083E1E8F0E0108216
:10063000808182608083808181608083E0E8F0E057
:10064000808181608083E1EBF0E080818460808341
:10065000E0EBF0E0808181608083EAE7F0E0808178
:1006600084608083808182608083808181608083D8
:100670008081806880831092C1000895482F50E0E7
:10068000CA0186569F4FFC0124914A575F4FFA01D9
:1006900084918823C1F0E82FF0E0EE0FFF1FE859A6
:1006A000FF4FA591B491662341F49FB7F8948C91C4
:1006B000209582238C939FBF08959FB7F8948C91C7
:1006C000822B8C939FBF0895482F50E0CA0182551A
:1006D0009F4FFC012491CA0186569F4FFC01349123
:1006E0004A575F4FFA019491992309F444C0222399
:1006F00051F1233071F0243028F42130A1F0223060
:1007000011F514C02630B1F02730C1F02430D9F4EF
:1007100004C0809180008F7703C0809180008F7D1E
:100720008093800010C084B58F7702C084B58F7D20
:1007300084BD09C08091B0008F7703C08091B00064
:100740008F7D8093B000E92FF0E0EE0FFF1FEE5891
:10075000FF4FA591B491662341F49FB7F8948C9113
:10076000309583238C939FBF08959FB7F8948C9105
:10077000832B8C939FBF0895682F70E0CB01825527
:100780009F4FFC012491CB0186569F4FFC01449161
:100790006A577F4FFB019491992319F420E030E0D0
:1007A0003CC0222351F1233071F0243028F4213051
:1007B000A1F0223011F514C02630B1F02730C1F07D
:1007C0002430D9F404C0809180008F7703C08091D9
:1007D00080008F7D8093800010C084B58F7702C029
:1007E00084B58F7D84BD09C08091B0008F7703C030
:1007F0008091B0008F7D8093B000892F90E0880FAA
:10080000991F84589F4FFC01A591B4918C9120E0D1
:1008100030E0842311F021E030E0C90108951F92F7
:100820000F920FB60F9211242F933F934F938F93F4
:100830009F93EF93FF934091C600E0910102F091E6
:10084000020231969F012F77307031978091030219
:10085000909104022817390739F0EF57FE4F408373
:100860003093020220930102FF91EF919F918F91AB
:100870004F913F912F910F900FBE0F901F901895A1
:10088000CF93DF93EC019A01AB01E885F985203025
:1008900081EE380780E0480780E0580709F449C036
:1008A00081E090E00A8802C0880F991F0A94E2F75D
:1008B000808360E079E08DE390E00E949006215013
:1008C000304040405040CA01B90122E030E040E0F1
:1008D00050E00E949006EC81FD813083EE81FF8123
:1008E0002083EA85FB85208141E050E0CA010E8427
:1008F00002C0880F991F0A94E2F7282B2083EA850B
:10090000FB852081CA010F8402C0880F991F0A94B9
:10091000E2F7282B2083EA85FB858081088802C0C6
:10092000440F551F0A94E2F7842B8083DF91CF9107
:100930000895108220E130E0CECFDC011296ED91D7
:10094000FC911397E058FF4F219131918081918163
:10095000281B390B2F773070C9010895DC011296DE
:10096000ED91FC911397EE57FF4F208131819291C9
:100970008291E058F0408217930719F42FEF3FEF70
:1009800005C0E20FF31F8081282F30E0C9010895D0
:10099000DC011296ED91FC911397DF01AE57BF4F2A
:1009A0002D913C911197E058FF4F80819181E05843
:1009B000F0408217930719F42FEF3FEF0BC0E20FBF
:1009C000F31F80812F5F3F4F2F7730702D933C9323
:1009D000282F30E0C9010895DC011296ED91FC91B9
:1009E0001397EE57FF4F80819181929382930895E0
:1009F000FC01A085B18521898C9190E0022E02C076
:100A0000959587950A94E2F780FFF6CF0484F585E3
:100A1000E02D6083089581E491E090930602809335
:100A2000050281E891E0909308028093070285EC2B
:100A300090E090930A028093090284EC90E09093F6
:100A40000C0280930B0280EC90E090930E02809356
:100A50000D0281EC90E09093100280930F0286ECDF
:100A600090E0909312028093110284E0809313022D
:100A700083E08093140287E08093150285E08093E1
:100A8000160281E08093170208950E9403030E94DA
:100A90003B020E948C00FDCF0F931F93CF93DF93F7
:100AA0008C01EB0109C02196D801ED91FC910190D8
:100AB000F081E02DC801099568816623A1F7DF91D7
:100AC000CF911F910F910895EF92FF920F931F9373
:100AD000CF93DF938C017B01EA010CC0D7016D91AC
:100AE0007D01D801ED91FC910190F081E02DC801CC
:100AF00009952197209791F7DF91CF911F910F9141
:100B0000FF90EF900895DC01ED91FC910280F3815C
:100B1000E02D099508952F923F924F925F926F9228
:100B20007F928F929F92AF92BF92CF92DF92EF927D
:100B3000FF920F931F93DF93CF93CDB7DEB7A097AC
:100B40000FB6F894DEBF0FBECDBF1C016A017B015A
:100B5000411551056105710549F440E350E060E03D
:100B600070E020E030E00E94250656C088249924D9
:100B70005401422E55246624772401E010E00C0F26
:100B80001D1F080D191DC701B601A30192010E9486
:100B90006E06F80160830894811C911CA11CB11C95
:100BA000C701B601A30192010E946E06C901DA01D4
:100BB0006C017D01C114D104E104F104F1F681E07E
:100BC000E82EF12CEC0EFD1EE80CF91C3E010894F9
:100BD000611C711CD501C4010197A109B1096C0107
:100BE000C818D90816C0F601EE0DFF1D40814A3025
:100BF00010F4405D01C0495C552747FD5095652FB5
:100C0000752FC10120E030E00E9425060894E1081C
:100C1000F1086E147F0439F7A0960FB6F894DEBF82
:100C20000FBECDBFCF91DF911F910F91FF90EF903D
:100C3000DF90CF90BF90AF909F908F907F906F90FC
:100C40005F904F903F902F900895EF92FF920F93F7
:100C50001F93CF93DF93EC017A018B0121153105AE
:100C600041F4E881F9810190F081E02D642F09952C
:100C70001BC02A303105B1F477FF10C04DE250E0BF
:100C800060E070E020E030E00E94250610950095BD
:100C9000F094E094E11CF11C011D111DCE01B8017E
:100CA000A7012AE00E948B05DF91CF911F910F9140
:100CB000FF90EF900895EF92FF920F931F937B01A7
:100CC0009A010027F7FC0095102FB801A7010E9498
:100CD00025061F910F91FF90EF900895A1E21A2E23
:100CE000AA1BBB1BFD010DC0AA1FBB1FEE1FFF1FD0
:100CF000A217B307E407F50720F0A21BB30BE40B20
:100D0000F50B661F771F881F991F1A9469F7609566
:100D10007095809590959B01AC01BD01CF01089520
:100D200097FB092E05260ED057FD04D0D7DF0AD039
:100D3000001C38F450954095309521953F4F4F4F0A
:100D40005F4F0895F6F790958095709561957F4F68
:100D50008F4F9F4F0895EE0FFF1F0590F491E02DE8
:060D60000994F894FFCF96
:100D66002D002B0020002E006D6D00696E6368005B
:100D7600207869616F5F6C6162615F636E40796163
:100D8600686F6F2E636F6D2C20323031332D303704
:100D96002D3238000D0A0005000200030000000095
:100DA60000F8044C0564059D04C804AE04EC040078
:00000001FF