Текст
                    :Ji3 помmgo радиолюбителю


rололобов В. Н.


<сумный дом»
своими РУКАми


NT PI"eSS
Москва





УДК 621.38 ББК 32.965 [61 Подписано в печать 22.08.2006. Фомат 84х108 1 / з2 . [ap нитура Баскервиль». .Печать офсетная. Уел. печ. л. 21,84. Тираж 3000 экз. Заказ N2 5467. rололобов В. Н. rб1 «Умный дом» своими руками / В. Н. rололобов.  М. : нт Пресс, 2007. 41б с.: ил.  (В помощь радиолюбителю). ISBN 547700484--3 Книrа адресована радиолюбителям, но может быть инте- ресна BceM кто интересуется электроникой. Описывается c<r здание системы автоматизации дома «Умный дом» на базе микроконтроллера PIC16F628A в проrрамме МРLЛВ. Компо- ненты системы и модули отлаживаются на одной макетной плате. Для всех экспериментов, опианных в книrе, можно использовать одну и ту же микросхему контроллера. Проrрам- матор, работающий с проrраммой PonnyProg2000, леrко соби- рается и не содержит дефицитных деталей. Компьютер в ла- боратории радиолюбителя превращается, фактически, в саму лабораторию. Управляющая проrрамма системы (она же  отладочная проrрамма) может быть написана на языке про- rраммирования Visual Basic или на любом дрyrом языке. В зак- лючительной части приведены справочные материалы по командам микроконтроллера PIC16F628A, схема датчика дви женин и проrрамматора для проrраммирования РIС-контрол- леров. УДК 621.38 ББК 32.965 ТJ СКАН  rР':lППА PICBDDK @ rололобов В. Н., 2006 @ НТ Пресс, 2007  оrЛАВЛЕНИЕ Предисловие....... ... ................ ....... ........................................ 6 Зачем нужна эта книrа .......................................................... 6 Из чеrо мы будем создавать систему ..................................... 8 Почему именно микроконтроллер в качестве базы ................... 9 Еще HeMHoro о микроконтроллере в качестве базовоrо элемента ... 1 О Как мы будем работать........................................................ 11 Несколько предварительных замечаний ................................ 11 rлава . 1 Базовая версия . .. . .. . . .. . .. . . . . ... . . . . . . . ... .. . . . . . . . . . . .. . . . . . .. . .. . . ... .. . .. . .. 12 «Умный дом» от АМХ и JDS ................................................... 12 Система Landmark .............................................................. 1 3 Система StarGate Х 1 О ....................................................... 27 «Умный дом» вашеrо производства ...... ...... ..... ..... ........ ........33 Темный холл ....................................................................... 33 Возвращаюсь я с р"аботы ..................................................... 34 Возвращаюсь я с работы (модификация решения) ................35 Создание эффекта присутствия..... ...... ... ......... ..... ..... ... ..... ...37 Цель проекта ............... .,.. . .. . .. .... ... .. . . . ...... ... . . . . . .. .. ........ ...... ....40 Схема и nporpaMMa релейноrо модуля .................................48 Проrрамма модуля на ассемблере........................................ 51 Проrрамма релейноrо модуля на языке С.............................. 66 Введение в работу с MPLAB ..................................................98 Релейный модуль, версия nporpaMMbI на языке С.............. 104 Первая сборка на макетной плате ...................................... 109 Схема и nporpaMMa модуля приема ИК команд ............... . 118 Проrрамма модуля приема ИК команд на языке С................ 122 ()TJ1 Ka модуля ..................................................................154 Схема и nporpaMMa МОДУJ1Я излучения ИК кодов ................166 Проrрамма модуля излучения ИК кодов на языке С.............. 167 И что получилось? ............................................................. 20 1 МОДУJ1Ь считывания ИК кодов WinLIRC ...............................202 Проrрамма для управляющеrо компьютера ........................208 Завтра ............................................................................. 220 и HeMHoro назад ....... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 226 Текст основной nporpaMMbl на языке Visual Basic .................. 228 Подведем итоrи .................................................................. 234 Ода ошибкам. ............... ............................ ............... ......... 235 . .
4 Оrлавление rлава . 2 Ка"к расширить систему ................................................... 237 Модуль цифровых вводов .......................................... .... ..... 239 Проrрамма модуля цифровых вводов на языке С ................. 241 Модуль с триаком ............................................................... 253 Модуль с плавной реryлировкой яркости ............................256 Проrрамма реryлировки яркости на языке С........................ 261 Модуль последовательноrо интерфейса ............................269 Модуль аудиокоммутатора ................................................. 269 Модуль видеокоммутатора ................................................. 270 Модуль управляемоrо усилителя ........................................271 Модуль системноrо ИК пульта управления ........................ 273 Модуль аналоrовоrо ввода для термометра .......................274 Замена проводноrо канала RS485 ......................................275 Усовершенствование базовых модулей ..............................276 Последн ие замечания ........................................................ 277 rлава . 3 То, что рядом с «Умным домом» .....................................280 М U L TI S 1М. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. 284 Усилительный каскад на транзисторе .................................. 289 CircuitMaker 2000................................................................ 297 Electric ................................................................................ 301 Сопряжение управления ..................................................... 306 .мешанные системы .......................:.................................315 азные подходы к реализации системы .............................318 rриложение ................................................:....................... 330 И К датчик движен я ........................................................... 330 Таблица команд микроконтроллера PIC16F628A ................333 Цоколевка контроллера PIC16F628A ..................................336 Проrрамматор 1совместно с PonyProg) .............................. 337 Адаптер для РIС контроллеров ........................................... 338 Внешний вид и параметры модуля общеrо назначения фирмы Advantech ................................339 Практическое применение триака в модулях системы .......339 Дополнительные замечания по иК управлению .................341 Проrрамма для компьютера в KDevelop .............................343 Вторая версия основной проrраммы на языке С++ ............... 355 Две полезные схемы .......................................................... 363 Разветвитель видеосиrнала ............................................... 363 Схемы для экспериментов с радиоканалом ....................... 367
Оrлавление 5 HeMHoro о проrраммировании на С++ ................................372 Как писать проrраммы на С++ ............................................ 373 Определение и инициализация объектов данных .................380 Написание выражений ......... .... ........ ...... ....... ... ...... ............385 Оператор предшествования ........... .................................... 389 Написание условий и создание циклов ................................ 391 Ци кл ы .............................................................................. 396 Как использовать массивы и векторы .... .... ....... .... ........ .......399 Указатели дают больше rибкости ........................................ 4е4 Запись и чтение файлов .................................................... 409 Ссылки на полезные сайты вИнтернете ............................413
 ПреДИCIIовие За..ем нужна тa книrа Мноrие не доrадываются, насколько увлекательно занятие электроникой. rораздо интереснее чтото придумывать и co здавать, чем пользоваться rOToBbIM. Проделать предлаraемые в книrе эксперименты и начать свою разработку? Это инте ресно. И может быть полезно. Например. Заработавтись за компьютером дотемна, я ча сто, особенно зимой, выхожу по темной комнате в темный коридор, натыкаясь на телефонный столик и книжные тKa фы. Используя релейный модуль, через который включена лампа на телефонном столике, я с компьютера включаю эту лам и теперь синяки от столкновения с мебелью полнос тью пропали. Например. Я люблю, если чувствую, что устаю от работы, вь.,ить чатечку кофе. Наливаю электрический чайник, BIUI ч J ero. Чтобы не жда'.(Ъ, коrда он закипит, я возвращаюсь к Kr мпьютер А коrда вспоминаю О чайнике, ero, как правило,  риходится rpTb заново. Но система напомнит мне (если я не выключу звук у компьютера), что чайник вскипел. Например. Возвращаюсь я с работы. Система встречает меня  зажиrает свет в прихожей, кипятит воду для кофе (увы, чайник я наполняю yrpOM). А коrда я переЙДУ в rости ную с чаткой кофе, она включит телевизор на проrрамме новостей, чтобы я, усевтись в любимое кресло, посмотрел, что произошло в мире за день. Свет на кухне и в прихожей, который я, конечно, забыл выключить, она выключит сама. Например. После вечерней работы я сажусь к телевизору в любимое кресло. Частенько бывает, что и вздремну. Очнув тись от дремы, чтобы не переломать сон, я быстро чищу зубы и спешу в кровать. Но не.успеваю еще заснуть, коrда система выключает телевизор 'и свет в квартире. Летом она 
Зачем нужна эта книrа 7 включает кондиционер, чтобы воздух в спальне стал прохлад НЫМ. НО К yrpy, если температура ниже 240, система включа ет обоrрев. Если спать я люблю в прохладе, то вылезать из постели предпочитаю в теплую комнату. Например. Мне нравится, уж так я устроен, принимать ro стей. Люблю я суету в прихожей, коrда, не успев попривет ствовать одних своих знакомых и предложить им напитки, я спешу к двери на очередной звонок, чтобы встретить новых пyrников, забредтих «на oroHeK». И не слитком, как ни CTa раюсь, я поспеваю всех развлечь. Если бы не система, KOTO рая и свет во время зажиrает, и музыку включает HerpoMKo, и тем, кто зател в мой кабинет, предлаrает посмотреть фильм. Все эти и мноrие дрyrие «Например» MOryr быть реализо ваны из доступных деталей своими руками с помощью систе мы, описанной в книrе. И ничто не пометает применить эти разработки не только в квартире, но и на даче, в rараже или в матине. Мне кажется, это интересно  придумывать, что бы еще система моrла сделать п.олезноrо? Экспериментировать, а за тем воплощать проекты в жизнь. Строить всеrда интересно. Строить ли ты дом или планы, отнотения с коллеrами по работе или свою первую электрон ную схему. Как мне кажется, электроника  самая удобная сфера применения творческих способностей. Особенно co временная электроника. Своими успехами электроника во MHoroM обязана новым технолоrиям. В частности, появлению компьютерных про rpaMMaM, позволяющих осуществлять полную разработкууст ройств за компьютером. Конечно, чтобы осуществить такую разработ нужно иметь компьютер. Но если для професси нальной работы следует обзаводиться одной из последних M делей, то радиолюбитель может прекрасно поладить с ранни ми моделями, стоимость которых может сравниться со стоимостью приборов В лаборатории радиолюбителя. Люби тельский осциллоrраф (я не rоворю о профессиональном) стоит столько же, а то и дороже, чем подержанный Pentium с тактовой частотой 120 мrц. Сами проrраммы (некоторые из них достаточно дороrостоящие) MOryr быть в демо--версиях, 
8 Предисловие которые имеют ОСНОВН9е оrpаничение  невозможность coxpa нения файла. Я сам порою пользуюсь подобными версиями, и это, соrласен, неудобно, но если потратить чyrь больте BpeM ни на продуманный план работы, подобное неудобство пере стает быть определяющим. Кроме Toro, для компьютера сеrод ня есть операционная система Linux. Одним из основных ее достоинств является доступность по цене и существование больтоrо количества проrрамм, распространяемых бесплатно. Систем «Умный дом», то есть систем автоматизации жи лья, в настоящее время множество. Одни рассчитаны на при менение в условиях квартиры, друrие MOryт поддерживать работу целых жилых районов. Хотя интересы радиолюбите ля MOryт простираться далеко за пределы ero мастерской (у меня  это секретер, у KoroTo, может быть, целая KOMHa та), начинать эксперименты лучше на столе. Итак, прежде чем начинать работ определимся в том, что мы намерены сделать. Небольшую систему, к которой, пусть с оrоворками, можно применить название «Умный дом». Начав с разработки отдельных компонентов системы, мы объединим их в сеть, заставив работать под управлением компьюера. В первом приближении так построены и MHO rие коммерческие варианты системы, за исключением, MO жf. r быть, специализированноrо процессора или микроконт роллера в качестве центральноrо управляющеrо устройства. Но кто метает нам заrрузить небольшую системную проrрам му в контроллер? Или что может пометать построить MOДY ЛИ так, что они будyr «общаться» между собой, не требуя «цeH ных указаний» от компьютера? И3 ..ero мы 6удем со3ДаВать систему Из Toro, что есть «под рукой». Что доступно. В качестве базовоrо элемента всей системы я предлаrаю использовать микроконтроллер фирмы Microchip PIC16F628A Причина, по которой я остановил свой выбор на этом микро контроллере, весьма прозаична  стоимость и доступность как caмoro КОнтрОJШера, так и Bcero, что необходимо, чтобы микро- схема, которую вы купили, моrла быть чеМJfО полезна. То есть проrрамматор и проrрамма обслуживания проrpамматора, 
Зачем нужна эта книrа 9 которые позволят заrрузить в микросхему вашу разработку: Проrрамма для работы с микросхемой PIC16F628A  это MPLAВ. Она свободно распространяется изrотовителями микросхем. Проrрамматор используется самодельный, рабо тающий с проrраммой PonyProg 2000, которая также распро страняется свободно. Все это проrраммное обеспечение cy ществует как для Windows, так и для Linux. По..ему именно микроконтроппер в ка..естве &аз... Не только и не столько «в поrоне за модой», но по нескольким иным причинам. Это удобно и практично. Создав одну из KOH струкций, описанных в книrе, вы леrко превращаете ее в дpy ryю, не докупая новых дороrостоящих элементов. Потеряв со временем интерес к данной теме, вы можете не отправлять макетную плату с микроконтроллером в ящик с надписью «Хлам», а использовать ее ДЛЯ построения ряда полезных схем в следующем проекте или сделать микроконтроллер ядром следующей системы. Современные микроконтроллеры  это целый мир электроники, рождающейся из одноrо элемента. Очень интересной темой, как мне кажется, моrла бы стать тема модификации старых конструкций с использованием микроконтроллера. Микроконтроллер PIC16F628A имеет встроенные блоки компараторов и тиротнcrимпульсной моду- ляции, а также энерrонезависимый модуль памяти. Ero Taктo вая частота может быть повытена до 20 мrц, а выполнение ряда команд за один такт позволит применять микросхему в диапазоне радиочастот. Есть и еще одна причина, заставивтая меня написать эту книry,  обилие новых терминов может оттолкнуть начинаю- щеrо. Человек, незнакомый с проrраммированием, может заrодя, не пытаясь разобраться, ретить, что проrраммирова иие  не для Hero. Я же пытаюсь показать (или доказать), что все не так. И проrраммы, которые вы будете использовать, и языки проrраммирования  это те же молоток или отвертка, только называются они иначе. Это инструменты. Ведь не OT талкивают вас такие термины, как мультиметр, осциллоrраф, функциональныЙ reHepaTop, варикап, термистор. Это все средства достижения ватей цели. 
1 О Предисловие в настоящий момент микросхему PIC16F628A в Москве можно купить в маrазине «Чип И Дип» или заказать по почте наложенным платежом на сайте http://www.dessy.ru. Забеrая HeMHoro вперед, хочу отметить, что я не пожалел о выборе микросхемы,  при налаживании устройств мне пришлось с<?тни раз перепроrраммировать ее. Теряя бдительность, я I:Iесколько раз устанавливал ее в панельку неправильно, но она как работала, так и работает. Одно это, как мне кажется, достойно восхищения и уважения. В качестве базовоrо эле мента всех предлаrаемых разработок можно использовать любой дрyrой микроконтроллер, но это потребует изменения Bcero комплекса проrрамм и проrрамматора. Если по какой либо причине, кроме стратеrической, есть необходимость сменить микросхему, попробуйте выбрать ее из серии PIC, поскольку со мноrими микросхемами этой серии работают проrрамматоры и проrраммы PonyProg2000 и MPLAВ. Еще HeMHoroО MItKpoKOHTponnepe в кa..ecrвe 6аэовоro .neMeнтa Коrдато основным элементом при построении схем была вакууМная лампа. С появлением полупроводников транзист ры почти вытеснили ламы. Микросхемы, укрывая в своих rryбинах тысячи транзисторов, изменили подход к разрабо ь.е электронных изделий. Все в больтей мере электронные '. : 9"зделия стали превращаться в кентавра  наполовину TpaH зисторырезисторы, наполовину проrраммы. Микроконтрол лер устранил и эту половинчатость. Он  микросхема, работа ющая на основе написанной для нее проrраммы, которая и определяет все, что микросхема будет делать (в рамках, KO нечно, своих физических возможностей). Сеrодня микрокон троллеры используются настолько же тироко, насколько вче ра использовались транзисторы, а позавчера  лампы. Стоимость микросхемы PIC16F628A (в пластмассовом корпу се DIP18)  около 100 руб. С одной единственной микросхе мой вы можете собрать, проверить, отладить и модифицир вать все модули, описанные в книrе. Вы можете придумать свои модули и проверить их работу, а также заrpузить OCHOB ную проrрамму в микроконтроллер и, используя компьютер 
Зачем нужна зта книrа 11 в качестве друrих модулей системы, проверить работу OCHOB ной проrраммы. Для проверки всех схем можно использовать одну макетную плату, добавляя элементы по мере необходи мости. И последнее  если вы после макетирования и отладки собрали rотовый вариант, спаяв схему полностью, но в про цессе эксплуатации нашли изъяны в ее работе, можно пере проrраммировать микроконтроллер в rотовой схеме, не BЫ паивая ero. Как мь.6удем ра 6отать Технолоrия проста  в основном, за компьютером Коrда по кажется, что разработка rOToBa, мы перенесем ее на MaKeT ную плату. После отладки разработки на макетной плате ее можно, при желании, повторить в виде «roToBoro изделия» с этикеткой «Made in MyLab». При налаживании всех схем я намеренно постарался использовать единственный невирту альный при бор  мультиметр. Для этих целей подойдет ca мый дешевый цифровой мультиметр, и мне жаль, что я не проверил это, но думаю, подойдет и тестер класса «Приз» или ТЛ4. Неск"копредваритen"ныхэаме.аний «Умный дом», «Смышленый дом», или «Послушный дом»  за всеми этими названиями будет скрываться ваше желание применить все, о чем rоворится в книrе, используя собствен- ные возможности и фантазию, к комнате, квартире, Koттeд жу или дому. «Умный дом» будет умен ровно настолько, Ha сколько вы ему позволите. Основная цeь этой книrи  не столько в описании rOTo вых разработок, хотя все завертенные устройства провере ны в макетном варианте, сколько в рассазе об одном из пу тей подхода к разработке. KTOTO из вас уже имеет опыт работы с микроконтроллерами. НО KTOO, возможно, не пы тался строить свои разработки на базе микроконтроллера, полаrая, что это слитком сложно. Однако работать с микро контроллером не сложнее, чем с любыми электронными KOM понентами. Было бы время и желание. 
rлава &азоваА вереИА ссумный ДОМ» ОТ АМХ и JDS CKOЬKO специалистов, столько мнений. Я часто повторяю это, поскольку р'етений может существовать множество, даже после применения всех критериев отбора. Дальнейтий выбор происходит на основе личных предпочтений. Систе мы автоматизации быта  отнюдь не исключение. Можно до бесконечности спорить, делать ли систему централизованной или децентрализованной, какую сеть использовать  компь те: ную, силовую или специализированную. За основу выбора , можно взять надежность, стоимость или доступность rOToBbIX устройств, за счет которых в будущем система может расти ряться,совеРlПенствоваться,развиваться. Полный обзор существующих систем может занять не одну книry, поэтому Я лить вкратце расскажу о нескольких систе мах, с которыми знаком, и которые находятся, в какойо мере, на ценовых полюсах систем бытовоrо назначения. Но вначале HeMHoro о том, из чеrо состоит любая система «YM ный дом»; хотя можно поразному подойти и k этому вопрос Я разделю систему на центральное управляющее устройство, исполняющие модули, средства управления, системную сеть и среду проrраммирования (она же средство отладки). Базо вые исполняющие модули  релейные модули, модули циф ровых вводов, диммеры, трансляторы ИКкоманд, KOMмyra торы сиrналов. Средства управления  универсальные пульты ИК (инфракрасный спектр) команд, специализированные 
«Умный ДОМ» от АМХ и JDS 1 3 клавишные пульты и сенсорные панели. Системная сеть  это системный интерфейс и среда передачи системных команд. Это не полный перечень, а, скорее, произвольная выборка, которая нужна в дальнейтем, чтобы определиться с реализа цией. Кроме Toro, все производители систем каждодневно co вершенствуют все составляющие своих продуктов. Не успе ваешь рассказать о новинках, предлаrаемых фирмой, как она выпускает нечто еще более интересное и привлекательное. Вместе с совершенствованием информационных технолоrий преобразуются подходы к ретениям, да и производители бытовой техники все чаще задумываются о возможности включения своих изделий в единую систему, снабжая их CTaH дартными интерфейсами. Система Landmark В настоящее время система поддерживается корпораци"ей АМХ (PНAST, Panja). Почти все модули выполнены в виде печатных плат, пред назначенных для установки в конструктив (рис. 1.1). ..-.._.-.,., I ,,  и..... :=:: : ""= .:....":?:...:.m..x.:..Joy."o Рис. 1.1. Конструктив PHAST для установки модулей С перечнем модулей можно ознакомиться на сайте произ водителя, но я приведу названия и назначение некоторых модулей из списка, который есть в моем архиве: . PLCMCU  модуль центральноrо процессора системы; . PLBAМP8  8 канальный усилитель (обслуживание aкy стических зон); 
14 rлава. 1 Базовая версия . PLBAS16  16канальный аудио коммутатор (матрица 16x16); . PLCIN7  модуль с семью цифровыми входами (для под ключения датчиков); . PLCIRIN  модуль с тремя входами для приемников ИК управляющих кодов; . PLCIROUT  модуль для подключения 4x ИКизлуча телей; . PLCRL8  релейный модуль с восьмью исполняющими реле; . PLLMLC  управляемый диммервыключатель. В конструктиве (CardFrame) расположен центральный пр<r цессор. Конструктив имеет встроенный сетевой KOHцeHTpa тор, к которому подключаются сетевые системные устройства (нацример, все выключатели света). Как и компьютерные хабы, он имеет вход и выход для объединения всех сетевых концентраторов. Средства управления в составе системы представлены ДBY мя базовыми ретениями. Это настенный клавитный пульт с дисплеем для отображения информации и переносной пульт для ИКуправления. Кроме них система поддерживает работу серсорных панелей АМХ с помощью специальноrо модуля. ПJзже ПОЯВИ)Iось множество универсальных ИКпультов упра 1 ления способных запомнить больтое количество кодов от пультов управления бытовыми устройствами. Некоторые их них, например фирмы Philips, MOryr полностью проrрамми роваться на компьютере, а затем заrружаться через СОМ или us:в-.порт. Несомненно, и сенсорные панели АМХ, и пульты Philips очень красивы (рис. 1.2) Вид и работа сенсорных панелей обустраиваются с пом(}; щью специальной проrpаммы (или проrрамм), которые в пол ной мере определяют все необходимое, подrотавливая рабо чую проrрамму для заrрузки в панель. Панели также имеют встроенный редактор, но проrраммировать их удобнее Bce таки за компьютером. Для заrрузки панелей, уже установлен HblX в систе используется существующая системная сеть. То же можно сказать и о пультах фирмы Philips (рис. 1.3). 
«Умный ДОМ» от АМХ и JDS 15  . I  .\ ' ')i; х I '. '> r "/NV' .;....:.:....:..:..:. ..: r.t> :4.:I:.д I rOCn-!НАЯ ':'- ':Щ':" :. ay:.' . !\]У IКA .: '=D ;'. '-.. .:" .'1. .' ). '\Д"'. Ъ' 'i: ...';/'<.*. :;\";' /., 1 УБOiЖ.Д -:' . "'::' . ...: ;; '-;'. .. ,..: .; ;, .."."..... . (..... .... < : " :1;1/('/" ;(/(/, "  )(". ;111 . . "'4';' ;"I!:"' . '. Ч/>:. . . N' ... .:ш.Т 21/05 ':1: j  r. .. \()(/Ib" . "..,.. Ю-IН::iП:АТ'" iН'-. .. 1 1IIМl..НЛ ,:'ПОЕ-.rl.1jFНIIЯ ciFJ-m.I...,я!JI ы "   . Рис. 1.2. Сенсорная панельАМХ ................................... ............... ................. proпlo'  .' s.. H:IS It=f ...f"L. .... 111 .... , ',#А 't:J't=Ji ..щаоо' =: -: .. .  ': i. . [ о t I -, А,. t ,-: \:>' \' \ Рис. 1.3. Пульт ProntoPro Универсальные пульты ДЛЯ ИКуправления MOryт приме- няться. практически. с любой системой. Некоторые модели поддерживают как инфракрасное управление, так и управ пение по радиоканалу. Например, пульты ProntoPro позволя ЮТ одни страницы использовать в режиме IR (инфракрасное 
16 rлава. 1 Базовая версия управление), а друrие  в режиме RF (управление по радио каналу). Какой из режимов удобнее в практическом приме нении, сказать трудно. С одной стороны, ИКуправление оrраничено помещением, в котором оно используется, а уп рвление по радиоканалу не имеет подобноrо оrраничения. Но с друrой стороны, именно возможность оrраничить об ласть управления оказывается очень важным свойством. В данном случае наилучтее решение зависйт от конкретной задачи и условий применения. Да и не следует переоцени . вать проникающую способность радиоволн. Серьезным пре пятствием на их пути может стать развитая силовая сеть или система отопления с больтим количеством металличес ких труб, скрытых в стенах. Система Landmark имеет удобную и эффективную среду проrраммирования, позволяющую работать как с проектом автоматизации обычной квартиры, так и с автоматизацией мноrоэтажной постройки. Каждый этаж в последнем случае может быть разбит на помещения, в которых будyr распола rаться устройства и датчики, бытовая аппаратура. Можно ис пользовать строительные поэтажные планы, что дает полное представление о помещениях. Проrрамма, по сути, набирается из необходимых собы тий, вызываемых пультами управления, датчиками, или вре- менем cyrOK, и ответных действий системы. Проrрамма oc нащена достаточным количеством условий. Приведу пример работы с системой Landmark После за пуска и ввода пароля новый проект выrлядит, как представ лено на рис. 1.4. Первые клавити инструментальной панели, ниже OCHOBH<r ro меню, вполне ясно подскaжyr, что делать дальте,  опреде-- литься с домом  этажами и комнатами. Рисунок этажа можно взять из проектной архитектурной документации, изобразить в редакторе Paint, встроенном в Windows, в AutoCAD или CorelDraw. Landmark поддерживает множество форматов изо ражений. Щелкнув кнопку в правом yrлу инструментальной панели, выбрав имя для этажа (поддерживается русский для задания названий, но лучте использовать анrлийский, чтобы при печати иметь как можно меньте проблем) и указав рису нок этажа, получаем результат, показанный на рис. 1.5. 
«Умный ДОМ» от АМХ и JDS 17 х . е- IID*' gtw. IP* .. ,;:.( .. . . Rooa>" ()eoq, I PI.  N....o<II! r.o.-...  r 01;) 10H'N W<'IIJOORb..'" rп:; :;i.::':: /-::.".:..".:....:.-:: . i:': 1 ' .. : . . . ! I , <' .)( . i \ : I  :4  11 . f;  ..>. ',' о.. . ..' .....". :.. '.....::' ," . '. . ': ..' . .......:""""'...... .'., "1? Рис. 1.4. Окно проекта в системе Landmark ,t .a:.Jf. t '; ""gNI' t-IJ _ ..:d'I'.11 .  : F-. ""* !'Ifi:!t Х j "",,,.4. (., -ч,  (.... .-; . "[;:.... . . . rr  ,. ,:  Рис. 1.5. Этаж в системе L.andmark 
18 rлава. 1 Базовая версия На этом рисунке мы расположим помещения проекта, пе рейдя на вторую закладку основной панели инструментов «Rooms». Для добавления помещения используем клавишу «Add» меню страницы. Впитем название комнаты. Можно изменить цвет, а можно оставить цвет, предлаrаемый про rраммой. Затем нарисуем помещения, используя левую кноп ку мыти для фиксации положения линии. ЕqIИ впоследствии понадобится поправить положение зафиксированной точки, можно установить курсор на эту точку и, удерживая левую кнопку мыти, переместить опорную точку в нужное место. Продвиrаясь дальте по основной инструментальной пане ли, можно понять, что необходимо сделать, поскольку следу ющая кнопка носит название Design. А пока вид проекта в плане помещений представлен на рис. 1.6. -W<........................,........,...............,.,... . . . l . . .,+ .,  .. . .. х "":,......"::....: 1/iIiII:.... d'I ,,' r . .. :j?< ::  j(ft ':..tfIЦ :J.I :..-rrlo .& а..:.;.:: r j I . ..==, . .." .;'.:"- .-.," ..:::-...:::.{....-...-..:-.)..:-.,- ., ".::-" .:-:';.'::-. Рис. 1.6. Разбивка проекта на комнаты Если теперь перейти на вкладку Design, получим вид про екта, изображенный на рис. 1.7. На инструментальной панели страницы (справа) все yc ройства, поддерживаемые системой. Их нужно расположить по комнатам, в соответствии с реальным положением дел. 
«Умный ДОМ» от АМХ и JDS 19  ." .. CIIhW.' ""*' .'. "',.,: /;'  11.  I . 11 . '" .. .... "" .!." х. . ."0 .... ";:.;. ":::'::::-':"::'::'K;. :... '1"'.... (""" r N'N!J I ..... .' П:':':I . f, : (' .:' .; 1:" .1'-' :r. П . f . '''' : t . f " . - .. . J ! , 1 , I  '. I 1:: f"'f r-': f!!"":" ....:.;      Рис. 1.7. Проект. подrотовленный к размещению оборудования Для начала расставим свет (клавита с лампочкой). Щелкаем, отыскиваем в подменю лампочку, обозначаем помещение, например «rостиная» И, удерживая левую кнопку мытки, пе ретаскиваем лампочку в нужное место (рис. 1.8). ... ow  I I . r"..... ,. ....., """.'  tl. r., ::'" ....:.,.k..:. :-;:.....::.. :-.:  -"::-'{'?""'{ . .. ...:;..=:::-;...:.::..::.... .....   (o,IJYII  "A"" tf,  .t ". r'l: '. . I r ..... 'р J' ,. ... " . '" :  ;, ", /, '1 .. t  , . . , . t .  .: . в I . . . :. :.<:.....,,*,... Рис. 1.8. Размещение подсистемы управления светом 
20 rлава. 1 Базовая версия После расстановки источников света (люстр, бра, rрупп светильников), задаем нужные свойства и меняем, если это нужно, обозначения. При использовании диммеров следует обратить внимание на опцию Ramp to level gradually (nepe ходить на уровень плавно) слева в рубрике On/Off Rate (ход включения/выключения). Если не установить эту опцию, плавное включение будет в проrрамме недоступно. Остальные опции позволяют выбрать скорость нарастания яркости  Dim rate (ход выключения), установить уровень яркости в ночное и дневное время, яркость свечения индикаторов в ночное и дневное время и т.д. Задание свойств выключателей подразу мевает, что заrрузка основной проrраммы в процессор систе мы СОПРОВОЖ,lается передачей всех настроек соответствую щИМ М(>ДУЛЯl\I. После идентификации источника света на первой вклад ке Control (управление) можно управлять им в интерактив ном режиме, коrда компьютер подключен к системе. На дpy rих вкладках можно построить сцены управления светом (вместе с люстрой, щелкнув кнопку ее включения, можно включать потолочную подсветку в спальне и т.п.). Включается меню настроек (свойств  properties) двойным щелчком ле вой кнопкой мыти или щелчко правой кнопкой при пози ционировании на объекте и выборе в раскрывающемся меню раздела свойства (properties)  рис. 1.9. Расставив источники света и задав все необходимые свой ства, пора заrлянуть в раздел основной инструментальной панели Program. В данном случае я раскрыл подменю спаль ни (bedroom)  рис. 1.10. . В левом окне вкладки событий (events) в спальне обознач ны все светильники по их функциональному назначению. Обя зтельно ли это? Нет. для профессионалов, возможно, даже удобнее иной подход с обозначением помещений 1, 2, 3, а ис точников света  1 Light1, 1 Light 2 и т.д., поскольку В рабочей документации будyr таблицы соответствия Однако я считаю удобным сразу обозначать функциональное назначение поме щений и оборудования. В дальнейшем это позволит осмыслен нее подходить к проrраммированию событий  события в кyx не и спальне, мне кажется, MOryт сильно различаться. 
«Умный дом» ОТ АМХ и JDS 21 .,.e4--rtl:tII:<.;f< 1 r:-M Ь) . * . -. ". . . )1, --:-'--- t1'I I . >.  е:- .;  .'  п' 'j r.,*""", "'.....щ-, .).) r Х rтr; ::::-::1 - r: · - f' .. 1: f' f , . -- L*JI_!--- -- 1.-'-"'7.'::: ,"'1'". н- bdoonoLф , j: -  ! ' : - . _ . -_ : ' . . . -  30 : -  . ' _ . -  _ " Of  _ : _  _ ' - ; - - :_  I  . ; . '} t :; - .....- - -'--"-- -- , J"" __ > ::- -- :; w. f H.. ....s-...._-::l 1"1.:. н:: . I I I -"i""'--'- r  -",."._--,;"'- , --, ,_ . ::zС --' ,:- ,';-f ':nIi". ..:1. --,:. <" . ------- Рис. 1.9. Задание свойств модулей управления светом '- .. t ....... ""B-,gIIIr :_-<" ,- t1't I I  F....-. С.. '>11 <- ХА -:." ''':::.,. . ':" ". ..:.;:"':;...: .. - . ....- "- --"'- .:-;.....:-.}--:..:;:=:..:::-......--..-:-...... :-:.::.:::.:E."!::::.:::;..:  ... ,  __..,J *- .....,.,..... r: " n-r f  r:r -\ ___Ь -:-_: ;,-, --. -'<""i tr""*"''''):iti:, . "'-:I:::-,:-,:.::;tt..::::::::::,:::!:.::::<",:;:;>;.' - о.. '.;. .0:;- ....М...:.. , . . ...---- ".-. ......... .tТ;f::;:':{:':{'-:' .:::t-.:-:(::. SII8CiII .(9 мм 0ICa ,.11 ..... 1 :........ :. . у...... . ом-  . ....... .111.'" ... ......... n.NI <t! 1. ..... 1 :I,; : -1.. "j. : I ,p:. ,,-L . J;:'fi!i.:: /,:,!J ..:J }" . . u s,.o8   0...0. . 1. ..... , .1 .... .. ........ jj 1. ... .. . .... : .:.......:.:::: .;:-': "':"_:;;':='::':{-"- - ..... J ....... _ ,:Т1JP88 ?2- r:. Рис. 1.10. Окно проrраммирования системы Landmark 
22 rлава. 1 Базовая версия Аналоrично в проект добавляются системные устройства управления, аудио и видеооборудование, датчики и т.п. На этом подrотовка к работе с проектом заончена, можно начи нать проrраммирование. Отвлечемся HeMHoro от технических деталей. Поскольку все системы, с которыми мне приходилось сталкиваться, в равной мере позволяют осуществить, хотя бы формально, любую проrрамму, самое время определить, а что мы хотим в ней видеть? - Посмотрим, насколько просто реализовать в системе Landmark сценарий, приведенный в предисловии под назва нием «Возвращаюсь Я С работы». Я несколько изменю преды дущий вариант конфиryрации проекта, оставив прихожую, кабинет, rостиную и кухню. Расставим необходимые элементы (рис. 1.11). .' .-.r."x "'.".bIdI ':'::" ., :"":,.'.""{/i:;\{'-<.:':' ':-','\,>' .j..'::-"" ': ltI If ,<о  '. , . р<...... " 1.."'.... .<\I')<.  С""'" ;; .-:.\:>; :П:::-I/- ;' ;>:::..-....:.. .,:--:. -: ;.-  ,. t............ w - .. t'.. ......"....,: - ,....;' :'-. ." - rIr : [:.. ! ..... .1; I :f. П , 1'" I . f I А . .. t t . . ... t - .  , . .  а: r:: =- r::: ..... ." ".. . . . . '. f ': !-. .-  , W"; Рис. 1.11. Вид проекта в системе Laпdmаrkдля сценария «Возвращаюсь я С работы- Во всех комнатах я устанавливаю свет. Везде, кроме каби нета, добавляю датчики движения, в rостиной  телевизор и сенсорную панель управления, а на кухне  плиту. В rостиной я поместил и CardFrame (конструктив, в котором располо жатся модули). По команде «спецификации») оборудования 
«Умный ДОМ» от АМХ и JDS 23 (Spec) проrрамма заполнит CardFrame необходимыми MOДY лями (рис. 1.12). ,,- -,' х  .. gIW н-  11:- _ '.- f  .. . .. .' ............:::". ":' '-.:::;., ";'.::..: -......... . .::"'::... ...... ;.;...".:.;....-.,,:::..::.:.. ....3:.... :;" ..::...:.:::::..... ',"," : :... .':..'.. -- ......:.: ............. .., ':-.;". .".;..:....::. ..,..:..:::..... ,.....,.-..... ,. .-:..::.." "'"/..;'  -. :... UI м >Ie .... tllII..,. r;.",,,,, ,,,,I,.'If>fIf" V ,-О' 1:'. f"Jr i ' :. ::;:.:.........-: t.'" .:_:-.>.:.:::.,;. ....:.....<::.;..; ..:...:. ';':';':"'-:'-:.-:::':;::::'""". .. :-:.:...:;..-_ -:-:;:. :..:.;...,:-:.:.... -:...:;::::...;.:.::........" .:::..-:... .;.::<; Рис. 1.12. Размещение модулей в системе Landmark Теперь можно перейти к проrраммированию. Опитем события: я прихожу домой, сработавший датчик движения в холле зажиrает свет, включает электрочайник, чтобы, пока я переоденусь, вода для кофе вскипела. Конечно, чайник я наполняю водой и ставлю на подставку перед yxo дом на работу (рис. 1.13). Переодевшись, я перехожу в кухню, наливаю кофе и иду в rостиную. Проrрамма выключает свет в холле, электрочайник на кухне и включает телевизор в rостиной, едва датчик ДВИ жения в rостиной отмечает мое появление (рис. 1.14). Модули, которые проrрамма задействовала самостоятель но,  это модуль -процес -:..!>a, модуль, поддерживающий ceH сорную панель, модуль цифровоrо ввода. К последнему мы подключим даТ.fkiКИ движения. Еще система добавила релей вый модуль. С помощью этоrо универсальноrо модуля можно включить и выключить такой бытовой прибор, как электри ческий чайник (выключается он сам, но модуль дополнитель но отключит ero и от сети). Если параметры контактов реле 
24 rлава . 1 Базовая версия tJIII .... ohw ,,_. t1't 11 ; f'iXC$ {."  t4. .:.v, .ж.... F :.'::..; ;:;::;":' .! . .". ::.::;:{ ......:.....:. ..: :....: .; .;.J SpeooI .. ::Qd: - .";:..:: . PtCI8d , У . ..:."""" . <,.: '. I CbIOt C"'.6 .. ,:" .. hOI . hOI LфI .WM-StIiiiiII . ;;.. "I k*"-' ," :.-. .: ::.... . :): : ,{< R-м . .J..... ......-..:-..:.:.:...;.;.:.."':.......:.... ---.,. .1';') х ... .......  ,...:-::....:-:....:...... ::;-.-:..:.."..-. -.. ". .... . .  щ,"",", I,,,erю- 'ф  О, rтr ." ,::'' .:;...... .. . ... - . . Т....hoILфI... ... Т... k*"-' Geo r.....,. о.. :.:::.::::.:::.:.:-:.::-.:.:.: ,', .ir-:...... ':1t. ::' t' ( j, ! ,. 1": .11]' r hc"""t,,*l .:'.I:. ">& .  CJ SPOCМI . '" i;J о...... .. .. CbIOt ,,'6  .. hOI ::;. . . LфI . ,..,.,...............,. 1 . ' -',' '" ;jJ..  . 1" 1'"  .. -r- т... .. ........,. 01\ ("' Т.............,... ("' T.Ihe...... '.. w яоа;. r T... Рис. 1. 13. Начинаем проrраммировать сценарий «Возвращаюсь Я С работы»  (tXIe QItW .-' tf'I е 11 Iij > 1I:iI.><'"  . )(  4fIIII\ fIf:. ;:'. ":-':::":.: :'_A":: ",.,.  ;r ::if';", ...J SP8QII (э ........ oodr. g MocIo8 . poqod . у...ы.. .d о...... I ' ", ,.,. , CbIOt "".J6 i/ : ;= Т[ . . 6T""" '" .. hOI . hoILфI . hOI МOIoon s..... ,., I k*"-' ", .:: .: . : . " 3t. ": ';: . '(-. ':- 1:: " <=  :; ) ":';" ,. ..Я- ). :::': .... .:-..; t.. . :"е  . 81 " .) rrrl ..:': ... . . " . 4I...,....,И- ...  :;,FNtмnk . r....hoILфI.. . '.... k*"-' G. r.....,. 011 . . 6 '....... """'"'... :S:'::_ :;;.: =мlttlow- " '=. 11.... :r... ir"* I   '/::ro ':':!: ci!, . -:.:". .  ..J Speool ':: '" а о...... . . CbIOt .'6 ; . 6""'"9ООМ LфI ; . 6""'"9OOМPНAS' '  -- · .......,.... .hOI . 3 .. k*"-' . k*"-'Geo r...... . k*"-'LфI ......,$9tII 10.....1 0Ih8I J ..... l' r ' ', . (" о.. ;] "' .. r 1IIdOO! . . ("'01 ;-,rWlot2 r 'сО }>, . .1 1 ..__ 'fflW. J ".:: I :P' ...т..'>. I Рис. 1.14. Завершаем проrраммироватьсценари «80звращениедомой. 
«Умный ДОМ» от АМХ и JDS 25 не позволяют управлять включением мощной наrрузки, мож но применить пускатели, и реле будет включать и выключать пускатель. Модуль трансляции ИКкодов займется управлени ем телевизора. С помощью сенсорной панели я MOry леrко управлять всеми бытовыми устройствами квартиры, напри мер открыть входную дверь и включить свет в холле, если сосед (или соседка) зашел в rости на чатку кофе. . Система Landmark централизованная. Она может работать под управлением компьютера, собственноrо процессора, в который заrружается проrрамма, и переходить от управле ния с помоью компьютера к управлению от собственноrо процессора, если компьютер по какойто причине ВЫКJIюча ется. Конечно, она имеет средства орrанизации распределения аудио и видеосиrналов, охраны дома, управления КJIимати ческими устройствами и т.д. Под «и т.д.» Я подразумеваю даль нейшее описание работы с системой Landmark, что, однако, в данном случае не является uелью повествования. . А вот как среда проrраммирования выrлядит в N etLinx Stиdio  проrрамме, предназначенной для работы с процес сорами и модулями корпорации АМх. После запуска проrрам мы можно создать новый проект обычными для Windows средствами (Меню - Файл - Новый), или открыть существу ющий (рис. 1.15). Язык проrраммирования больте похож на процедурно ориентированный язык, что отражается и на среде проrрам мирования, хотя не следует забывать, что он остается специ . ализированным. Встроенный редактор позволит скопировать проrрамму в блокнот из Windows и продолжить проrрамми рование в блокноте. При наличии rOToBbIx проrраммных бло ков они леrко добавляются в проrрамму. Таким образом, даже достаточно сложную проrрамму можно быстро скомпоновать из рабочеrо материала предыдущих разработок. Если вы спе циализируетесь на работе с системой NetLinx, то кроме про rpaMMHbIx блоков, предлаrаемых производителем, у вас MHO ro своих, надеюсь, СИС1.'ематизированных, проверенных и отлаженных. Вот с установкой устройств проблем несколько 
26 rлава . 1 Базовая версия !':'X i5;rt1I:;C;i.: : У-", .:;:..::.... .:::::::: j ., G.:I'waIJIU (R8V O)j ! ."; ...  tf:1J.X IIKII'" НА",,- ::с .«"$ SOIlllC[ 1....(рIlОС."Н S'.'S) .) ( ..... ;...... :.............. ....... ....... ....... ....... .....) (. flLE Cal'lYIO IIМ: _,fttI20rJ. ., 1.\'''3! .) :-( ..... ....... ....... ....... .......... ..... ....... ... .... .....) (. 'ILE L"S' fIODtflED Oh: _'12/2М'l ".: t6:l':l .) C .......;....:........;.....................................) '" ,(е 1I11"1IfI"' 1t(I't"'''OII": 1 .) -:( ... ......................... ....... ... .............. .......) C.ttFIt[ IIfUISIOH: 11." . .) (. IILlltSl1IМ "'E ./rJ.ItIV -) (- ..) .(. се....нтS: -) -  . (...........................................................) !(.H..$UUIIC[I.... .) ( ..... ....... ....... ....... ....... ....... ....... ............) : с..... .............. ....... ....... ....... ....... ....... .....) ..(. Syst... ''''. : lli'tl1R. -) о.с .......................... .................................) ;(. IIf.V "1\''"''1': .. ( .... ................. ....... ... .... ... ....... ....... .......) ( ....... ................................... ... ....... .......) j!!..  '\ r. ;. s ('::. 1 i 1 .'.:.1.1 : ."'a<' i  ,.;).( . . lUi Рис. 1.15. Система «Умный дом- корпорации АМХ боль те. После начальноrо процесса установки устройств пр rpaMMa будет выrлядеть, примерно, как показано на рис. 1.16. .. '-' х  J..: 9,:;:::':::::\;:.,:;:l(.. ,,.'::K: .: .1.:y.!:..' '..: :'.. .....:. :;.liP.Jit .lt:.1a:: ....;IQISI"H.9.}.,... ' i:..;''i;:...:;" ..,...:.з.. . ..),. ." . 'I.::.t::JlwaCPU (R8V О) .:( .............. .............................................) 'К. 1tt(".0CIUIfI .... . р! х .  (. "tHIf' Vf"1 НК1 frOlt '''"1 -, lIXL1ak anll r"s, C1Iмnt1n 11$231 .) '1' (t[tIC'.SfRIIC (11If.1» ... .1If81(1)- »(. (' ,uSII " .) ( SIfHCII с..,..  1( 2)>> ( C.Sf . ;"1 ( 1, C8Urll 1(3). ".» ... (IIF.I<I.I) Е"$Е IF C'Uf. 1(3). 1If, (11("'. ') ) C"S1 .:t": ( 1, C8Urll 1(3)-' : . » ... (IIEI<'.2) E"SE IF C'B'. 1(1)-' 8FF (11("' .2) ) C.S1 . 1 ........, .........  ... " .::,::.: .:: :...::. .,.:....:..,ii) : .r.r'I'J I 0-';..::. ,$0:.:"" о.::: .".0.:.::'. .". о,." .;:. "=,::o :;0 .0_"= ......, . .:-...  ""F. u Рис. 1.16. Установка оборудования в системе корпорации дмх 
«Умный ДОМ» от ДМХ и JDS 27 в обеих системах после начальноrо подrотовительноrо процесса, который никак нельзя назвать сложным, мы rOTo вы присryпить к проrраммированию. Система starCate.. Х1 О Системы, работающие по протоколу X10,  это дрyrой цeHO вой полюс. Множество производителей выпускают как OT дельные компоненты, так и законченные системы автомати зации. Можно использовать централизованное построение или создать децентрализованную систему. В качестве приме ра рассмотрим систему StarGate UDS). Как и предыдущая, она позволяет быстро объединить co бытия с реакцией системы, создав проrрамму обслуживания дома. Имеет система и схожий набор устройств, в котором, как и в дрyrих системах, есть все необходимое для создания подсистем управления светом, аудио и видеооборудованием, климатической и охранной подсистемы, подсистемы управ ления, например, садовым оборудованием или rаражом. с! перечне модулей, составляющих физическое наполне ние системы, можно судить по меню, которое открывается в проrрамме после обращения к разделу Define OCHoBHoro меНIQ (рис. 1.17). При создании HOBoro проекта система добавляет начало и конец проrраммы (рис. 1.18). После запуска проrраммы и выбора New Schedule (через основное меню File или инструментальную панель  первая кнопка) в оrлавлении мы rOToBbI перечислить оборудование нашеrо проекта. Как и в случае с системой Landmark, начнем со света. В основном меню выберем Define'" XIO Device... Открывается таблица, в которой можно обозначить все источники света (но не только). В системах, работающих с сетевым протоколом X10, адрес устройств состоит из двух знаков: латинской буквы от Адо Р и цифры от 1 до 16. Bcero, таким образом, можно адресоваться к 256 устройствам, что достаточно для довольно больтой системы. Распишем CBeTO вую подсистему (рис. 1.19). Расположение выключателей света можно задать в описа нии  Location, назначение.... Description. 
28 r лава . 1 Базовая версия ::Jt;,::, :. ::: f:t"W.\Р-' . :; ::с . iI t::;':H]i:<  ::::.' 1: IC n........ :: 8C1 е.... ! =:'. I "'-' Мю-... i 8I.ndIOQIW8I... IIP'RIIw 1::=:: i IfiAC... T  UOIr  1teIpanoe... 'OМI'IIrIs  ,..::.v..:":":-:::-": .: :":"::"''',:':':\C'=-'''' 11. ..J4J · ;: t= :1 """:":::;'"fJ;:>':,:;;'.i.' i-':,';':;",, ;С'::..; '";.- ,:. ',о , .;'. .. ..':"':'".' . :' "" У '.:' - , ." :;.; .,:.,::Я Рис. 1.17. Меню устанавливаемоrо оборудования в системе StarGate . fwnt , 1М \IIIQdmrl. '.INПiН9. {I.!!'шntъ.sr.tfj ll:J ::.:.'" \.: '. \.> '" -",; .у ,..t " ,:. :,. Q i#' DQ: .  ::.:: о.' ;. Hi . ". . i: 6 .:: 1, ... 'K".;n" ..... ...... ......... . ............... ... J: : 8C1l8l\Al1IIO .:1!J, .... .!flJ. ... ;: : lCte :':'.':':''''''':;'':';'>. CIOCIe ....JWe ':" .... .............. ............,... ....х,.с..:. . .... ..... .... 1:: - --.. :. \.OCAТIQIII IIМ&ID SI' :  .::::::. ....................... .. ...... ........ ....+. .A..i........... .. ......... А . .......... · . ',,"," , ....t.............. .....;..:i.. ...................... : :.: :::::::::::::::.:.:::: ::::::::::::.! :::::::: .::::= == '.:'::'::: 5; === ===:===: .:'.;.;i . .. А" Ad' ,. 'вТ .. .===:.--:==.-:1.:'.:.=.'--:.:::":=: ::2 .... 1Iinii' .,D,8" ........................... ...............+............... . ... ..... ....... :. p.. -................... $с     11100.. . :..'11100.. ,н.о.. 11IoOw- .' ноо;.;. ! 11100.. . ; ;.'..;:.;: 11100...' 11100.. I ;5.Ё i _о.. .НО ow- ,.,';. . .. ,: r...v ц:с.,.,.,....с....1IIIW '.' . 0ieIiIit .:::',.(.--',:.,; C'O'.......-uJ'... ,.";-- . , . . ......W.......IIIIW ':.': . . '.1;. Со. . jJf. : : ... . . .. "t;... ..  . ......:.......1 . . , ............... Рис. 1.18. Создание проекта в системе StarGate я хочу повторить предыдущий небольшой сценарий «Воз вращаюсь я с работы», реализованный в системе Landmark. 
«Умный ДОМ» ОТ АМХ и JDS 29 11 ! "" · :.!.",!,. 1." 'Jfi.. ,"", . Uti [lfl Ш . (: H CIi I D <;С'Ч Т1 .../.. ., '.'" ц.« о. . "Dr;'O tj" i .' i.tjtj ,:'{! .....[J;.. Li IfAltT d.!1 dJ( ;:-':':'::; 8CNIDULIINO r-' =- :'. .:. . .10 . COOI! lWIf  , LOtA"'" eWЦD $' :t. Doo .,  "НoChor" i J!! ::Но chor ' -'-С! ";Но chor 1sj :Но chor 111 "'Ноо. 111 «Но oiir 1st 'Но chor  .Но chor 11! ";Но chor  'Нo chor .' 1sj .:'Но Chor. '  :Но chor х! .Но chor  .!:: 19 'Но chor xi .:Но chor  . 'Но chor JI! ,. N#>. Chor.. , ,1 А 1 Вoc.OOIOChrd А 2 Вoc.OOIIISconte А] Вoc.<>OOIC8I А' Вoc.OOIIМr А  I 10& 107 1.8 At 1.10 А" . 1.12 1.1] 1.1' ...1$ . А" ., .' е 1 e] с ... . .. ::: t o..= , .(" ..Ш . .' R.-. O.....V..I\eoaIaIoe.1ALU :  . " . .. 7) . "". 1Pt/11. .".с-,._ ;. ,flCf"lIII8ag4&AII( WZиIa . . ::';";::- .: .-...... :": -":';-. .:: ';:::.-.::... .- Рис. 1.19. Расстановка адресуемых модулей управления светом Поэтому выберу светильники и добавлю релейный модуль для включения электрическоrо чайника (рис. 1.20). 1r · "",,1 :.t''''!lfoI "Ir 'Кё.. '."''' . UtН;lНIi . {'ItIHH I D <;СЩ .:::1!1 х X ..1tl.? .С: d91  -=.   ;:E: ! . No.9.* .,:МOChor .. НoChor . >,Но chor J [;. .111 -'"Но chor S i:: 5. ;; J!I ':Но chor '. .  ш.. ......, ........;.... ..  . ,..,:' o.-... : "":. ::._: ..... "" "'""",,' ." 4 =-;(> -:. -:r...;:. -:. ". .. .;... ..- .18 COOI! 8CNIDULIINO А t ....,., А 2 l.9t2 10]..4,0 А' ,...... 10$ 101 107 101 А t . AtO' 1011 At2 . А,] А,' 101$ А" е t 82 8]. :8 о-. .... .... ....:.....:...:1::. .......::.:=..................::......::.::...::::::=.::;:' ..:..:..:..::::= I ?= = ..... ....... ........ ... .....?......................... .-. ..... ...... ......... ... ................ ................. .-. Е.....М 'DioМIfH а......... ,..c.w.. iAЩ a..""'-h-"""" . "'-to.lUvм......JIЩ . .,..,.,."'., ...-.,;..: .:.:-::..:-:.. :.:Y.::..: .:i:(.';::.;.. OtА'.;. f:',,'M." й ............... i ............... Рис. 1.20. Добавление оборудования для сценария . Воэвраl.ЦalOCЬ я с работы- 
30 rЛQВQ. 1 Базовая версия Осталось добавить в проект датчики движения, которые будут работать со встроенным модулем цифровоrо ввода (Define - IR and 10 Devices). Я выбираю модуль BBoдaBЫBO да, щелкаю кнопку Define и определяю свои датчики движе ния (рис. 1.21). .. fwnt ""'f.'r {м w",Мw> . 'JНПiНn. jt!I'I'l1niЪ.SfН] Irf <: ':: ': .'..:.....:......:'.....:: :;:.......':. .:... :;.р;,., 2- ,: ICМ8DUl.lIIIO '" d!l .JJ !! "r   т'с! 11.1 Ul-fl...  , '."..", ...... '.. ..:....... ...... II ,)r :". : .c'(Ji:'" . ""'4..' ....:".: .,:"',"-;i.;; 7<t1' МSt :,:\ . ..,1IfS2 )4; :,'!'., ;;; =?->$*f.\}'i::.Ч::  :=:.:::)r: :<':"_ х J' .: 'р,:::, \ .'" lit.. . Deh :  . . ': . :- »:).":;"'::'" '\; j; " );:.:{.::':;:;  . ;", .. . QIIIМ8 c::s . у.... ............... . e.IIr* .: , ..,  ' .-:.,. аа.. .. . .......:......1 " Рис. 1.21. Добавление датчиков для сценария «Возsращаюсья с работы- Сохраним выбор, и можно начинать проrраммирование. В редакторе выбираем кнопку New Event, обозначаем первое событие как comehome и к строке if с помощью кнопки Add и выбора из меню Digital Input выбираем собы тие ..... датчик движения hallMSl перешел в состояние ON (рис. 1.22). Продолжая этот процесс, с помощью кнопок New Event и Add питем проrрамму (рис. 1.23). бе системы  и Landmark, и StarGate  после заrрузки проrраммы в центральное управляющее устройство встретят меня после работы, зажryт свет в прихожей, вскипятят воду для кофе А коrда я переЙДУ в rостиную, включа телевизор, чтобы я, усевтись в любимое кресло, посмотрел, что пр изошло в мире за день. 
«Умный ДОМ» от АМХ и JDS 31 * t*'" ШhII!" *'"' 'lf1...1-t<.\ . '-'Ш1НU . t It{щно Ii-} а . .,.,. dt. . .,.ф.. 'ас :..." . ф [.:;.: -'.r .'! f..,. Ь. L:J . 'h _,.щ::.::. _... . .. д':' $:-:::  .. .... . ...., .,: :... ..: 1, ICII8IUU "МТ а, J. r ........ ................. " ... ,. .. 1: 1: 1C1I8IIU.. .:: ..}.. Н.. МS1 [)r....МS2 ".Q<.- " ->;. < 1 :,: .; ......". " . '..=-.'- ''- -. :::,_::__:,," :____x::_:_. :"_ .::  :W:<-....;'''.-i:.{J:':'.:'-'':-. Рис. 1.22. Начинаем проrраммирование сценария в системе StarGate '.' ..... :::;:,:y' :;,\:",;::.:..:.:'.>:,:,;:,.,;,\.;':<::.:::,X I ./;,:.,., ; :',, ..,Y"":"_:» -м.,,,, ..:.".;. :1f,} .:.'; .,:-.:".: : . ,1 " ",.; .:_.,,:: [&. .($...... :o ,: 2: ): r E...вiT. ....... ....... 4. ....  .: (O......J..I).. см. 1: ,.,. I 1110. М ...... ОН . ... 1. 10. 11: 12: 13: М: It: 11: 17: It:   ....: r.: ('",:о;т, "'."" . (OI:IIIw.Joo8l)" см. ,.,. (IIt O"М)III) ') IhIWII 111.. м UOНN см. 1110_ М ...... О" 1110. АI UlNI О" ... .1: 1...........». »: ICHIDUI.I 810 . I .') . .: t'.:.. Рис. 1.23. Завершаем проrраммирование сценария в системе StarGate 
32 rлаВQ. 1 Базовая версия к сказанному выте следует добавить, что ДЛЯ управления телевизором обе системы требуют дополнительноrо устрой ства, которое можно назвать модулем считывания ИКкоманд. Они предназначены для запоминания ИКкодов с пультов уп равления, чтобы эти коды можно было впоследствии воспр извести системным устройством. В системе Landmark это д полнительное устройство носит название IRIS. А StarGate работает с IR Xpander. Последнее устройство не только прочи тывает ИКкоманды с пультов и запоминает их, но может pac познавать эти команды, оно же воспроизводит их. Задание адреса устройств системы StarGate может произ водиться либо переключателями, установленными на YCT ройстве  один переключает буквы от А до  второй цифры от 1 до 16  либо проrраммно. В последнем случае, как пра вило, требуется помощь компьютера или одноrо из контрол леров Х10. Беrлый обзор двух систем «Умный дом» завертен. Зачем он понздобился? Да чтобы можно было составить представление о OM, как это выrлядит в профессиональных разработках, иметь цель и сравнить сделанное нами с профессиональными разработками. Затем, чтобы вы моrли при желании продолжить проект, опи санный в книrе, до уровня профессиональной разработки. Но не следует забывать  за видимой простотой процесса проrраммирования как в Landmark, так и в StarGate CKpЫBa ется систем, которая рано или поздно проявит все свои свойства. При первом знакомстве может возникнуть ИЛЛ зия, что проrраммирование по леrкости схоже с иrрой в кy бики: сложил так  получил домик, переложил иначе  полу чаеть паровозик. Подобная иллюзия может стать причиной Toro, что однажды... домик запыхтит и поедет... И последнее. Что следует «подверrать» автоматизации. Вот, как на это смотрят специалисты PНAST. ""'ОIlОnЖНО ав.,.ома.,.иэирова.,..С8 В принципе, любое электрическое или механическое устрой ство, любая подсистема внутри или снаружи Bamero дома M жет быть автоматизирована, хотя бы HeHaMHoro. 
«Умный ДОМ» вашеrо пронзводства ЗЗ Поскольку количество устройств и подсистем, которые вы м )жете интеrрировать с системой доматней автоматизации, orpoMHo, важно выбрать систему достаточно rибкую, расти ряемую, обновляемую и оптимальную по стоимости. Это дол жна быть система, которая леrко устанавливается, проrрам мируется и имеет проrраммный интерфейс, не требующий освоения новой техники проrраммирования каждый раз, KO rда вы добавляете в систему новое устройство. Корпорация PНAST развивает современную автоматиза цию дома, которая полностью отвечает этим требованиям. Заметьте: так как список характеристик, относящихся к раз ным системам автоматизации и компонентам, .которые MOryr быть автоматизированы, велик, система автоматизации дома может стать весьма сложной. Для преодоления проблемы вам следует обращаться к системам, с которыми вы лучте Bcero знакомы. PНAST настоятельно рекомендует тщательное изуч ние всех незнакомых систем или устройств, прежде чем вы примете ретение о внедрении их в систему Landmark. ссумный дом» BaWerO производcrва в первую очередь рассмотрим, как MOryr выrлядеть ретения, о которых упоминается в предисловии. ТеМНЬIЙ ХОIUI Сценарий ретения: работая за компьютером дотемна, чтобы выйти в темный холл, не натыкаясь на мебель, я с компьют ра включаю бра в холле. Для реализации этоrо ретения мне нужен релейный MO дуль, имеющий одно реле, и простая основная проrрамма на компьютере, которая отправляет команды «включить свет» и «выключить свет», адресованные этому модулю (рис. 1.24). Аналоrичное решение можно применить с небольшой MO дификацией (можно и со значительной) и для случая, коrда ночью приходится вставать, чтобы зайти на кухню попить или выйти в туалет. Ночной светильник в.холле избавит вас от опасности споткнуться по дороrе, но не будет резать rлаза после темноты в спальне. Модификация в данном случае 
34 rлава. 1 Базовая версия Лампа в холле ....2208 Блок питания =128 Компьютер с основной проrраммой Релейный модуль с одним реле Конвертер RS2З2RS485 СОМпорт Рис. 1.24. Структурная схема системы ДЛЯ сценария «Темный холл- относится к TO чтобы в проrрамме, заложенной в контрол . лер релейноrо модуля, один из выводов порта предназначал ся к присоединению кнопки. Эту кнопку (клавишу, выключа тель) вы можете расположить возле прикроватной тумбочки или на ней. Нажатием кнопки вы включаете и выключаете реле без участия компьютера. Кнопок можно сделать He сколько, если вы в доме не один. Коrда я rоворил о значительной модификации, то имел в виду, чо кнопку возле кровати можно снабдить радиопере датчиком, а релейный модуль  радиоприемником. В этом случае вам не понадобится добавлять провода в квартире. B03BpaIqaIOCIa. с ра601Ъ1 Сценарий ретения: по возвращении домой я открываю BXOД ную дверь. Система зажиraет свет в прихожей, кипятит воду для кофе. Коrда я перехожу в rостиную с чаткой кофе, она включа ет телевизор, выключает свет на кухне и в прихожей (рис. 1.25). Для реализации этоrо ретения мне потребуется модуль цифровых вводов, к которому подключаются repKoHoBbIe дa чики  первый, установленный на входной двери, и второй  на двери в rостиную. Мне понадобится релейный модуль с тремя реле, одно из которых включает свет в прихожей, второе  свет на кухне, третье  электрочайник. 3адейство ван будет также модуль излучения ИКкоманд с излучающим светодиодом, расположенным возле телевизора. .Основная 
«Умный дом» Bawero производства 35 nporpaMMa на компьютере будет иметь проrраммные блоки, оjслуживающие системные модули. Электрический чайник Лампа в Лампа прихожей на кухне ... 220 8 Блок питания = 128 Релейный модуль с тремя реле Системная сеть Компьютер с основной проrраммой Конвертер RS2З2RS485 Модуль излучения ИК команд Модуль цифровых вводов СОМпорт  ИК светодиод на телевизоре в rостиной ....  I : I I I Irl l ...I rерконовый датчик на двери rостиной I  ... I I I I I Irll L.. rерконовый датчик на входной двери Рис. 1.25. Структурная схема системы для сценария .Возвращаюсь я с работы» Основным собыIиемM для проrpаммы, работающей на компь ютере, в данном ретении становится изменение состояния repKoHoBoro датчика на входной двери. Это событие иницииру ет включение света в прихожей и на кухне, включение электр чайника (выключается он сам, коrда пода закипит). Следующим событием становится срабатывание repKoHoBoro датчика не двери rостиной. По этому событию проrpамма выключает свет в прихожей, на кухне, выключает электрочайник (не обязатель но). Затем через модуль излучения ИКкоманд отправляется код включения телевизора (мноrие телевизоры ВКЛЮчаются KOMaH дой выбора KOHKpeтHoro Канала) на выбранную проrpам Возвращаюсь. с ра60ты (МОДИфllкаqll. решеНII.) Сценарий ретения остается прежним (рис. 1.26). Мне не нравится держать компьютер, на котором работа ет ()сновная проrрамма, весь день включенным только для 
36 rлава. 1 Базовая версия Блок питания = 128 Электрический чайник ....2208 Релейный модуль с тремя реле Системная сеть Конвертер RS232.RS485 Модуль излучения ИК команд Модуль цифровых вводов  ИК светодиод на телевизоре в rостиной ....  I : I I I Irl l ..J rерконовый датчик на двери rостиной I ..... ... I I I I I Irll L.. ..... .....  rерконовый датчик на входной двери " Рис. 1.26. Структурная схема системы для модификации предыдущеrо сценария Toro, чтобы вечером он управлял работой системы. Я моди фицирyio модуль цифровых вводов. Теперь при срабатывании repKoHoBoro датчика входной двери он сам отправляет KOMaн ды включения релейному модулю. А при срабатывании дa чика на двери rостиной он отправит команды выключения релейному модулю и команду включения телевизора модулю излучения ИКкоманд. После модификации постоянно включенным оказывается только маломощный блок питания, обеспечивающий модули постоянным напряжением 12 В, и сами модули, потребля щие очень маленький ток. Если мне не хочется по какОЙJfО причине устанавливать re коновый датчик на двери rостиной, я MOry использовать клави ту пульта, закрепленноrо на стене в прихожей рядом с выкл чателем света. Проходя мимо пульта, я нажимаю Э1]' клави что инициирует продолжение работы Toro же сценария. BMec то repKoHoBoro датчика на двери в rостиную можно использ вать датчик движения, установленный в rостиной или замок с цифровым кодом на входной двери, который подаст команду 
«Умный дом» Bowero пронзводства 37 «встретить хозяина». Никаких переделок в системе для выпол п.:пия сценария мне делать не нужно. И, естественно, для по добноrо решения не нужен конвертер RS232RS485 (как и в последующих ретениях), но подразумевается, что компьютер вы все--таки используете, например, для выполнения первоrо или др}Тих сценариев, которые придумаете или сочтете инт ресными. Поэтому конвертер остался в системе. СоэдаНllе 3ффекта npllcyтCnIlR Практически все системы автоматизации жилья позволяют реализовать подсистему охраны. В отличие от специализир ванных систем охраны, основным достоинством которых кроме высокой надежности является возможность CTaHдapT ПQrо подключения к централизованным пультам охранных ведомств, системы автоматизации жилья позволяют создать эффект присyrствия. Посмотрим, как может выrлядеть cцe парий подобноrо ретения, например, на ватей даче зимой, коrда вы там не живете. Сценарий ретения: рано утром на террасе включается свет, который спустя несколько минут racHeT. Следом вклю чается свет в одной. из комнат. Включается радиоприемник. Через полчаса он выключается. В комнате слытатся rолоса, зажиrается свет в дрyrой комнате. Через час в доме наступа ет тишина. Но ненадолrо. Через час или два в доме вновь слышны rолоса. Включается и выключается свет. Включается и выключается радиоприемник (рис. 1.27). Для реализации ретения мне понадобится модифицир ванный релейный модуль. Я использую транзисторный ради приемник и кассетный маrнитофон с пленкой, на которой за писаны обычные доматние шумы и разrовор. В данном случае сеть используется, если управление светом удобнее разнести по дo В такой модификации один из релейных модулей бу дет модифицирован, остальные останутся универсальными. Модификация релейноrо модуля NQ 1 сведется к тому, что будyr использованы таймеры для задания интервалов BpeMe. ни, которые становятся событиями системы, а отклик сист мы на события (сиrналы таймеров) инициируется модифици рованным релейным модулем, который отправляет команды 
38 rлава. 1 Базовая версия Свет на террасе Блок питания = 128 Релейный модуль N21 с одним реле Конвертер RS2З2RS485 Системная сеть Релейный модуль N22 с одним реле Релейный модуль N23 с одним реле Радиоприемник Маrнитофон Рис. 1.27. Структурная схема системы для сценария -Эффект присутствИя» включения и выключения релейным модулям NQ2 и NQ3. Контакты реле, конечно, разрывают питающее напряжение. Если вы действительно не живете на даче, }IO хотите исполь зовать подобную подсисте для имитации приcyrствия можно подумать, например, о примеении вместо силовоrо освещ ния низковольтных маломощных светильников, работающих от батареек. Можно добавить сиrнализацию, добавив модуль цифровых вводов, к входам KOToporo подключить repKoHoBbIe датчики, реarирующие на открывание дверей и окон. А в кач стве устройства тревоrи использовать сирену: Бесспорно, BOB се не обязательно для реализации сценария задействовать сис тему. Но, если вы будете использовать систему, то в летнее время, коrда вы живете на даче, можете возложить на нее обя занности ежедневноrо полива оrорода, включения света на крыльце в ночное время и т.д. К одному из внетних проявлений rибкости систем «YM ный дом» Я бы отнес тот факт, что трудно rоворить о каких либо ретениях без привязки к конкретным объектам, к KOH кретным условиям, и даже к конкретным людям. Если вы дочитаете книry до конца, пусть и не последова тельно, а выборочно, то сможете собрать все необходимые модули, модифицировать их и соединить. Обойдется это py лей в 200500 (без учета стоимости сирены, радиоприемника и маrнитофона). Вы про верите работу системы на столе и убедитесь в ее работоспособности. В один из выходных 
«Умный дом» Bawero пронзводства 39 дней вы поедете на дачу и установите систему на месте. Про веi>ите ее в работе. Убедитесь в том, что она работает. Осталось убедиться в том, что система нужна вам именно в том виде, в каком описана в сценарии, включая сирену, cpa батывающую при открывании дверей и окон. Если ват дачный участок охраняется, то да. Имитация приcyrствия может отпуrнуть нежелательных визитеров, а сирена, если они всетаки ретат нанести визит, не только отпyrнет их, но и привлечет внимание сторожа. Если дачный участок не охраняется, то нет. Имитация приcyrствия отпyrнет тех, кто будет наблюдать за ватей дa чей длительное время, прежде чем отважится на посещение. Да и то в том случае, если не выпадет cHer. Люди в доме, не оставляющие следов на cHery, скорее убедят наблюдателя в том, что ero пытаются обмануть. Сирена, которая воет на весь поселок без появления людей, «поднятых по TpeBore», тоже не слитком убедительна. Если дверь, на которую вы установили rерконовый датчик для защиты от вторжения, не ходит ходуном под ветром, то да. В противном случае, нет, даже, если дачный поселок oxpa нят сторож. При перемещениях двери датчик будет срабаты вать, а сторож, привыкmий к ложным срабатываниям систе-- мы, перестанет обращать внимание на сирену. Да и саму систе если поселок охраняется, следует, на мой взrляд, сильно видоизменить. Модули цифровых вводов и си рену поставить в каждый дом поселка, соединив их между c бой, а лампу тревоrи (или любой индикатор) разместить в доме сторожа. Если сторож время от времени будет оставлять «сл ДЫ на cHery», то эффект приcyrствия окажется полезен. Как видно из вытесказанноrо, конкретное ретение сле дует выбирать только с учетом всех обстоятельств и особен ностей применения. Это же касается и, например, реализации описанных MOДY лей в квартире. Если вы достаточно опытны в работах с элект ричеством, можно эксперимент довести до конца, подключив к релейному модулю (или модулю с триаком) торшер или Ha стольную лам Если нет, лучте остановиться на применении светодиода. Тем более что сейчас появились светодиоды, обла дающие очень б6льтой светоотдачей. Их света вполне может хватить для подсветки TeMHoro коридора или холла. . 
40 rлаво. 1 Базовая аерсия Цепь npoeIna Цель. проекта  разработка любительской системы автомати зации жилья. За основу возьмем системы, о которых rовори лось выше. Если не вдаваться в тонкости реализации разных концепций, на первом этапе будущую систему можно предста вить в виде центральноrо управляющеrо устройства и набора модулей, выполняющих разные функции, но подчиненных одной задаче  следить за состоянием датчиков и устройств управления, чтобы на основе их состояния включать, выкл чать и переключать бытовую технику (рис. 1.28).  : rерконовый датчик I  Модуль цифровых вводов I I  Термостат I . Модуль приема ИК команд I Центральное Системная сеть управляющее устройство   (ЦУУ) I Модуль излучения ИК кодов , Релейный модуль Структура простейшей системы Рис. 1.28. структура простейшей системы с базовыми модулями r в качестве средств управления в системе промышленн ro производства используются сенсорные панели и универ сальные ИКпульты с запоминанием кодов. Не rOTOB yrверждать, что любительская разработка подоб- Horo рода устройств управления столкнется с непреодолимы ми трудностями, но если серийно производимое устройство оценивается в продаже в тысячу (и несколько тысяч) долларов, то и в любительской разработке оно может стоить не детевле. По этой причине разработку средств управления подобноrо типа лучте пока оставить за профессионалами. Мы постараем ся реализовать простую систему, в которой компьютер будет 
Цепь проекта 41 vrpaTb роль центральноrо управляющеrо устройства (и, в кa KOIrI--ТО мере, устройства управления), и которая будет иметь несколько базовых модулей: релейный модуль, модуль приема системных ИКкоманд, модуль излучения ИКкодов и модуль цифровых вводов. Каково назначение каждоrо из этих модулей? Релейный модуль. Получая команды центральноrо управ ляющеrо устройства, он включает и выключает COOTBeTCTBY ющее реле. С помощью контактов реле можно включать и выключать настольную лампу, торшер (и свет в комнате, YCTa новив модуль на место обычноrо выключателя, но я не COBe тую делать это, если вы не профессиональный электрик), телевизор или музыкальный центр. Контактами реле может включаться и выключаться электрический чайник и утюr (возможно, понa,uобится добавить более мощный контактор). С ero же помощью можно «перемещать музыку», подключая к музыкальному центру rромкоrоворители, установленные в разных помещениях. Одним словом, с помощью контактов реле можно включать и выключать все, что можно включать и выключать в принципе. Модуль приема системных ИК-команд. Системой хочет ся покомандовать. И не только с компьютера. Используем CTa рый пульт управления от видеомаrнитофона или телевизора, который завалялея на полке, и применим ero коды для управ ления системой. Модуль излучения ИК-коДов. Чтобы управлять с помощью системы телевизором или видеомаrнитофоном необходимо иметь устройство, которое излучает ИКкоды управления ими. Модуль цифровых вводов  будет соединяться с датчика ми, например, rерконовыми и по запросу центральноrо управ ляющеrо устройства будет передавать состояние датчиков. В качестве ceTeBoro интерфейса (дверка, за которой начи нается дороrа ко всем модулям системы) используем двухпро-- водный интерфейс RS485. Длина линии может достиrать 1000 м, все системные устройства включаются параллельно, линия мало подвержена влиянию наводок и сама не наводит шумов на дрyrие линии. Если для экспериментов применить четырехжильный провод, то по двум оставшимся проводам 
42 rлава. 1 Базовая версия м<?жно передавать напряжение питания для всех системных устройств. Этоrо достаточно для наших целей. Тем более что в плане деталей, которые нужны для создания интерфейса, это одна микросхема и один резистор. Какие схемы нам потребуется собрать до начала работы? Проrрамматор, работающий с проrраммой PonyProg2000 (упрощенная схема, более полная схема дЛЯ PIC контролле ров будет приведена в Приложении), показан на рис. 1.29. В ориrинальной версии есть примечание  микросхему стабилизатора напряжения LM2936Z5 не советуют менять на стабилизаторы серии 7805. Поскольку рекомендуемая мик росхема есть в продаже, я не стал пренебреrать советом, хотя, по отзывам мноrих, собиравтих проrрамматор, этим советом можно пренебречь. Список необходимых для сборки проrрамматора составляющих приведен в табл. 1.1. Таблица 1..1. Спецификация nporpaMMaTopa Н2 Обозначение Изделие Количество Цена (р.) Примечания " 1 U1 Панелька 1 21 DIP18 2 U2 LM2936Z5 1 68 Не исполь зовать 7805 3 О2,аз КТ315Д 2 10 4 О1 КТ361Д 1 5 5 O1O3 КД522 3 3 6 Z1Z3 КС147 3 6 7 Z4 КС213 1 3 8 А1 10 кОм 1 0.5 0,25 Вт 9 A3,A8A10 4,7 кОм 4 2 0,25 Вт 10 А4 100 кОм 1 0.5 0,25 Вт 11 А2,А7 1 кОм 2 1 О ,25 Вт 12 А5 2,2 кОм 1 0.5 0,25 Вт 13 С1,С2,С5 100 нФ 3 за 14 С3 1 нФ 1 5 15 С4,С6 47 мкФ 16 В 2 20 16 J1 (ОВ9) Разъем, 1 10 rнездо 
Цель проекта 43 t о ш а. "со < . """) Q) ш (/) u. () о) а.. m Q сх) v < v сх) z C\I ff <о Q .:IiI:: О ,..... а.. сх) 8. а: Q) C\I I ;:) е м 8. о s () а. сх > а NLп а. ..... u. m ос C\I сх) tO О О о а.. CX) Q а. u. ... &.. <O Q) 8. ;:) .:IiI:: О () с: а.. о) о &j (/) d s а.. C\I.x a: C")LL. () 17ZЛ€ v.:lil:: a:g
44 rnaBa. 1 Базовая версия Ориентировочная стоимость элементов  186 руб., MaKeT ная плата 100 руб. Bcero 286 руб. Проrрамматор подключается к СОМпорту (я подключал ero к СОМ2, отведя СОМ1 дЛЯ конвертера). При точной и аккуратной сборке схема работает сразу. В качестве соединительноrо кабеля между проrраммато ром и компьютером я использовал несколько проводов плос коrО'кабеля, которые были «под рукой». Думаю, подойдет Ka бель от старой «мытки» ИЛИ отрезок с витыми парами ДЛЯ компьютерной сети. Длину этоrо отрезка лучте сделать He больтой, чтобы с проrрамматором было удобно работать. Если купить макетную плату достаточных размеров, часть ее можно использовать для проrрамматора, а часть приrодит ся для конвертера RS232RS485. Остатка же хватит на MaKeT ную плату для прототипов всех модулей. У меня проrрамма тор свободно разместился на плате 90х40 мм. Конвертер RS232RS485  нужен ДЛЯ общения компьюте ра со всеми модулями системы. Он также несложен в сборке, поскольку представляет собой пару микросхем снебольтим количеством дополнительных элементов. Я использовал толь ко один резистор 120 Ом в линии. При длинной линии (в сотни метров) такой же резистор желательно поставить на конце линии, выполнив ее витой парой (рис. 1.30). Необходимые элементы конвертера приведены в табл. 1.2. Таблица 1.2. Спецификация конвертера Н2 Обозна- Изделие Количество Цена Примечания чение (р.) 1 ОА1 МдХ232АСРЕ 1 80 2 ОА2 МдХ148З 1 96 3 А1 120 Ом 0,25 Вт 1 1 4 C1C5 О, 1 мкФ 5 5 5 DАЗ LM78L05 1 68 6 С6 47 мкФ 1 20 7 ОВ9 Разъем rнездо 1 10 8 X1X2 Клеммник 1 10 Любой на 6 конт.  :I: C\I C\I М Q) т .... о.... C\I C\lSQ) Х хоо + ..... Q Z tl) C\I " О со l' М <о l' « Q u м м )S т C\I COtl)Q) « CO-& tl) Q ..... а. + ООф со a: tl) +Ht'3 S ..... м C\I Н tl) ..... C\I () <о ..... tl) ..... () C\I () м () Q) фёt; тЕ C C\I ...... м tl) СООСС a: .... Б. о с: I О () Цепь проекта 45 tl) а: I C\I М C\I (J) а: а. а. Q) ID :I: О ci "1 ..... u S а..
46 rлава. 1 Базовая версия Ориентировочная стоимость изделий  290 руб. Клеммник я использовал для подключения линии, BHeт Hero (и общеrо для всех модулей) источника питания 12 В и проводов передачи питания на макетную плату, куда YCTa новлен 4контактный клеммник. Таким же образом можно подключать все модули, соединяя их последовательно. При этом следует учитывать, что по мере удаления от общеrо ис точника питания напряжение может понижаться за счет па дения напряжения на проводах. Это сказывается на работе удаленных релейных модулей. Реле с рабочим напряжением 12 В может потреблять ток порядка 50 мА. Обе микросхемы конвертера подключены к источнику питания 12 В через микросхему стабилизатора 7805 так ж, как микросхемы MO дулей. Некоторые параметры микросхемы МAX1483 и ЦOKO левка показаны на рис. 1.31 и 1.32. МдХ3082/МдХ3085/МАХ3088 ТRANSМIТТING INPUТS OUТPUTS АЕ DE D1 ва А/У х 1 1 О 1 Х 1 О 1 О О О Х HighZ HighZ 1 О Х Shutdown AESEIVING INPUTS OUTPUT АЕ DE AB АО О Х  O.05V 1 О Х s ? O.02V О О Х Open/shorted 1 1 1 Х HighZ 1 О Х Shutdown Рис. 1.31. Таблица состояний микросхемы МАХ1483 На этом приrотовления к началу работы можно считать законченными, если вы установили на компьютере проrрам мы MPLAВ и PonyProg2000. 
Цель проекта 47 Q о CI: ш Q I « C\I tl) сх) м сх) сх) сх) о о о МММ ...... C\I U. сх) Е о Q) s о:: s :r: Q) О (/) ......... а.. m Q Q) о:: О О I с: Q s а: .... c\i СУ? Q с3 CJ Z s m « " а.. > а.. О .... о (/) Q I ш Q Q
48 rлава. 1 Базовая версия Первую разработку проведем «на бумаrе», точнее в peдaK торе проrраммы MPLAВ. После проrраммирования контрол лера «на бумаrе» перейдем к ero налаживанию в проrрамме MPLAВ. Схема и npOrpaMMa реnейноrо MOAYnR Функциональная схема модуля состоит из интерфейса, KOH троллера и aдpecHoro селектора, образующих базу для пост роения остальных модулей, а отличительной особенностью данноrо модуля является использование реле (рис. 1.33). Реле я включил через транзисторный ключ. В зависимости от KOH KpeTHoro реле, которое вы выберете, транзисторный ключ может оказаться лишним. Системная сеть Uпит+ 12 В Стабилизатор Интерфейс RS485 Микроконтроллер PIC16F628A Реле = 128 Адресный селектор Рис. 1.33. Функциональная схема релейноrо модуля я не стал устанавливать реле на макетной плате. Реле  эле мент достаточно дороrой, и нет нужды покупать ero без твep доrо намерения использовать. Вместо Hero к выходам микро контроллера были подключены красные светодиоды АЛ307. Как выяснилось позже, получилось очень полезное ретение при наладке и разработке дрyrих модулей (рис. 1.34). При сборке макета потребуются не все элементы, обозна ченные в табл. 1.3. 
Схема и проrрамма релейноrо модуля 49 + "II:t Q > CD C\I ?"" со а: м Q Q о: .... (jj шr е о :I: )S Ф с::; ф х C\I "II:t Lt) <о l' U сСОСОСОСО о: > а: а: а:а: :I: .о а s с: :I: S со ....C\lM с: .... .... ?"" « , сх) .... v C\I u ?"" <о I.L s <о Lf) CL C\I .... Q U Q а.. l' со <о Н U .... v м м со со v ?"" ?"" Lt) Q Q l' <о N ?"" Х
50 rлава. 1 Базовая версия Таблица 1.3. Спецификация релейноrо модуля Н2 О6озна- Изделие Количество Цена Примечания чение (р.) 1 ОО1 МдХ1483 1 96 .2 ОО2 PIC16F628A 1 100 Установить на панельку 3 DDЗ LM2936Z5 1 68 4 VТ1 КТ50зr 1 5 5 VD1, АЛ 307 2 3 . VD2 6 VD3 КД522 1 3 7 VD4 дЛ307 1 3 8 Р1 12В, 5А/--22О В 1 170 10 A1A3 1 кОм 0,25 Вт 3 1 11 A4A7 10 кОм 0,25 Вт 4 1 12 А8 2,2 кОм 0,25 Вт 1 1 13 С 1, С2 0,1 мкФ 2 5 14 С3 100 мкФ 16 В 1 20 15 Х1 Кл. 6 конт. 1 10 16 S1 Пер. 2 пол. 4 нап. 1 50 17 SOC DIP18 1 21 Ориентировочная стоимость элементов  558 руб В целях экономии я отказался от установки на макетную плату реле и переключателя для орrанизации aдpecHoro ce лектора, распаяв соответствующие выводы, чтобы получить один адрес. На схеме показано одно реле, но их количество можно увеличить до 78, используя все свободные выводы портов А и В. Это определяется конкретными соображения ми по применению модуля. Например, если вы планируете использовать релейный модуль в своей комнате для ВКJIюче ния торшера или настольной лампы, достаточно одноrо реле. Для безопасноrо включения лампы я советую использовать закрытую розетку со стандартным сетевым проводом. Одна из жил этоrо провода должна разрываться контактами реле. Настольная лампа включается в розетку, которая, в свою оче редь, подсоединяется к сети ....220В. При замыкании KOHTaK тов реле напряжение подается на лам Поскольку неизвест но, какой из проводов вы коммутируете: нулевой или фазный, все работы лучте производить без напряжения. / 
Схема и проrрамма релейноrо модуля 51 . После тщательной изоляции розетки и всех соединений включите лампу в вату розетку, подключите мультиметр в режиме измерения сопротивления к вилке вашеrо провода и включите реле. Мультиметр должен показать такое же сопро тивление, что и настольная лампа, если измерить ее сопро тивление. После команды выключения реле тестер должен показать обрыв. В любом случае при первом включении сле дует соблюдать осторожность, а релейный модуль сразу поме-- стить в любую подходящую пластмассовую коробку. Команды, на которые модуль должен реarировать: . включить  Rxx$xN; . выключить  Rxx$xF; . передать статус  Rxx$xS. При передаче статуса используем следующую символику: . включено  Rxx#xN; . выключено  Rxx#xF. Здесь Rxx$xN означает: R  релейный модуль, хх  два сим вола адреса от 00 до 15, $  символ команды (#  символ CTaтy са), х  номер реле от О до 7, N  включить (F  выключить). Набор и формат команд вы можете переопределить по своему вкусу или сообразуясь с целями. Для этоrо достаточно внести изменения в исходные коды, приводимые ниже. Для адресации используются четыре бита порта В (RВ4 RВ7), что позволяет адресоваться к 16 модулям. Для тех, кому не терпится опробовать rOToBbIe решения, кому это не интересно или не нужно знать, как проrраммир вать модуль, я сразу приведу текст проrраммы модуля на ac семблере, текст проrраммы на языке проrраммирования С и НЕХфайл для заrрузки в проrрамматор. Проrрамма МОДУII. на ассем611ере list p=16f628a #include p16f628a.inc ; Инициализация модуля. BCF STAТUS, RPl ; Выбор банка о. 
52 rлава. 1 Базовая версия BCF STAТUS, RPO CLRF PORTA MOVLW Ох07 MOVWF CMCON BCF STAТUS, RP1 BSF STAТUS, RPO MOVLW Ох80 MOVWF ТRISA MOVLW OxF6 MOVWF TRISB BCF STAТUS, RP1 BCF STAТUS, RPO CLRF PORTB i Настройка порта А. ; Выбор банка 1. i Настройка порта В. i Выбор банка о. iНастройка приемопередатчика USART BSF RCSTA, SPEN BCF RCSTA, RX9 BSF RCSTA, CREN BCF STAТUS, RP1 BSF STAТUS, RPO BCF TXSTA, ТХ9 ВCF TXST, SYNC BSF TXSTA, BRGH MOVLW Ох16 MOVWF SPBRG BCF STAТUS, RP1 BCF STAТUS, RPO CLRW ADDWF PORTB, О ANDLW OxFO MOVWF Ох20 SWAPF Ох2 О, 1 битами. CALL adrsim ... i Настройка приемника. ; Выбор банка 1. i Настройка передатчика. ; Выбор банка о. ; Считывание собственноrо адреса. ; Прочитаем порт В. i Нам не нужны младшие биты. ; Сохраним адрес в 20h. i Нам не нужна работа с младшими ; Преобразуем ero в символьный вид. i прочитаем из EEPROM ЗОh  состояние реле. BSF STAТUS, RPO BCF STAТUS, RP1 MOVLW ОхОО MOVWF EEADR BSF EECON1, RD ; Выбор банка 1. i Адрес считываемоrо реrистра. ; Чтение. 
MOVF EEDATA,W ВCF STATUS, RP1 BCF STATUS, RPO MOVWF ОхЗО COМF ОхЗО,l CLRW ADDWF ОхЗ О , О MOVWF PORTA Схема и npOrpaMMQ релейноrо модуля 53 w = EEDATA. Выбор банка о. Будем хранить в EEPROM в инверсном виде. ; А в реrистре ЗОh в прямомф ; Перепишем ЗОh в порт. ; ачало работы, ожидание команды, отработка первой команды. CLRW ; Очищаем аккумулятор, ждем ком?нды по USART. ;.. start:BTFSS PIR1, RCIF ; Ждем прихода первоrо символа команды. GOTO start BCF STATUS, RP1; Выбор банка о. BCF STATUS, RPO CALL cmnd ; С приходом первоrо символа начинаем обработку. . GOTO start NOP ; Обработка команды  проверка адреса, определение команды cmnd: BCF STAТUS, Z MOVF RCREG, О XORLW Ох52 BTFSS STATUS, REТURN ; Проверим, наш ли модуль R (52h). z; Если нет, вернемся in1: BTFSS PIR1, RCIF ; Ждем прихода первоrо символа адреса. GOTO inl ; Если совпадает, продолжим. MOVF RCREG, О ВCF STATUS, Z XORWF Ох21, О ; Первый символ адреса. BTFSS STAТUS, Z REТURN in2: BTFSS PIR1, RCIF ; Ждем прихода BToporo символа адреса. GOТO in2 ; Если совпадает, продолжим . 
54 r лава . 1 Базовая версия MOVF RCREG, О BCF STAТUS, Z XORWF Ох22, О BTFSS STAТUS, Z REТURN ; Второй символ адреса. iпЗ: BTFSS PIR1, RCIF ; Ждем прихода символа. GOТO iпЗ ; Если за адресом следует символ команды, продолжим . MOVF RCREG, О BCF STAТUS, Z XORLW Ох24 ; Выполнение $ (2 4h) . BTFSC STAТUS, Z CALL swtch ; Вызываем подпроrрамму выполнения. REТURN ;Подпроrрамма перевода адреса в символы, их храним в 21h, 22h. adrsim: CLRW 31h). ; Если адрес 1, запишем символы 01 (ЗОh и ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ 1 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох1 BTFSC STAТUS, Z REТURN CLRW ; Если адрес 2, запишем символы 02 (ЗОh и З2h). ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ2 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох2 BTFSC STAТUS, Z 
Схема и проrромма релейноrо модуля 55 REТURN CLRW Если адрес З, запишем СИМВОЛЫ О З . ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗЗ MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW ОхЗ BTFSC STATUS, Z REТURN CLRW i Если адрес 4, запишем СИМВОЛЫ 04. ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗ4 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох4 BTFSS STAТUS, Z REТURN CLRW ; Если адрес 5, запишем СИМВОЛЫ 05. ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗ5 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW Ох5 BTFSS STAТUS, Z REТURN CLRW Если адрес 6, запишем СИМВОЛЫ 06. ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗ 6 
56 rлава. 1 Базовая версия MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох6 BTFSS STAТUS, Z REТURN CLRW ; Если адрес 7, запишем СИМВОЛЫ 07. ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗ 7 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW Ох7 BTFSS STAТUS, Z REТURN CLRW ; Если адрес 8, запишем СИМВОЛЫ 08. ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗ 8 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох8 BTFSS STATUS, Z RE'IURN CLRW ; Если адрес 9, запишем СИМВОЛЫ 09. ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ9 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох9 BTFSS STAТUS, Z REТURN 
Схема и проrроммо релейноrо модуля 57 CLRW ; Если адрес 10 (А), запишем символы 10. ADDLW Ох31 MOVWF Ох21 CLRW ADDLW Ох3 О MOVWF Ох22 MOVF Ох20, О ВCF STAТUS, Z XORLW ОхА BTFSS STAТUS, Z REТURN CLRW ; Если адрес 11, запишем символы 11. ADDLW Ох31 MOVWF Ох21 CLRW ADDLW ОхЗ1 MOVWF Ох22 MOVF Ох20, О ВCF STAТUS, Z XORLW ОхВ BTFSS STAТUS, Z REТURN CLRW Если адрес 12, запишем символы 12. ADDLW ОхЗ 1 MOVWF Ох21 CLRW ADDLW Ох32 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW ОхС BTFSS STAТUS, Z REТURN CLRW ; Если адрес 13, запишем символы 13. ADDLW Ох31 MOVWF Ох21 CLRW ADDLW Ох33 MOVWF Ох22 MOVF Ох20, О 
58 rпaBa. 1 Базовая версия BCF STAТUS, Z XORLW OxD BTFSS STATUS, Z REWRN CLRW ; Если адрес 14, запишем символы 14. ADDLW Ох31 MOVWF Ох21 CLRW ADDLW Ох34 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW ОхЕ BTFSS STAТUS, Z REWRN CLRW ; Если адрес 15, запишем символы 15. ADDLW Ох31 MOVWF Ох21 CLRW ADDLW Ох35 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW OxF BTFSS STAТUS, Z REWRN ; Подпроrрамма включение реле по номеру. crndset: CLRW ADDWF Ох23, О BCF STATUS, Z XORLW ОхО BTFSC STAТUS, BSF Ох30, О CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох1 ; BTFSC STATpS, BSF Ох30, 1 ; Запишем в 30h (установить бит). Реле о. Z Реле 1. Z 
Схема и п р оr р амма р елейноrо МО ДУЛ Я 59 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох2 ; Реле 2. BTFSC STAТUS, Z BSF Ох30, 2 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох3 ; Реле 3. BTFSC STAТUS, Z BSF Ох30, 3 CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох4 . Реле 4. , BTFSC STAТUS, Z BSF Ох30, 4 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох5 Реле 5. BTFSC STAТUS, Z BSF Ох30, 5 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Охб ; Реле б. BTFSC STAТUS, Z BSF Ох30, 6 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох7 ; Реле 7. BTFSC STATUS, Z BSF Ох30, 7 REТURN Подnpоrрамма выключения реле по номеру. crndreset: CLRW ; Запишем в 3Gh (сбросить бит) . ADIМF Ох23, О BCF STAТUS, Z 
60 rлава. 1 Базовая версия XORLW ОхО ; Реле о. BTFSC STATUS, Z BCF Ох30, О CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох1 ; Реле 1. BTFSC STATUS, Z BCF Ох30, 1 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох2 ; Реле 2. BTFSC STAТUS, Z BCF Ох30, 2 CLRW ADDWF Ох2.3, О BCF STAТUS, Z XORLW Ох3 Реле 3. BTFSC STATUS, Z BCF Ох30, 3 CLRW ADDWF 0х2 3 , О BCF STAТUS, Z XORLW Ох4 Реле 4. BTFSC STATUS, Z BCF Ох30, 4 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох5 Реле 5. BTFSC STATUS, Z BCF Ох30, 5 CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох6 ; Реле 6. BTFSC STATUS, Z BCF ОхЗО, 6 CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох7 ; Реле 7. 
Схема и проrрамма релейноrо модуля 61 BTFSC STATUS, Z BCF Ох30, 7 REТURN i Подnpоrpамма определения команды N (включить), F ( ВЫКЛЮЧИТЬ) i или S (состояние). swtch: CLRW in4: BTFSS PIRl, GOТO in4 MOVF RCREG 1 О MOVWF Ох23 MOVLW Ох30 SUBWF Ох23, О MOVWF Ох23 in5: BTFSS PIR1, GOТO in5 MOVF RCREG, О MOVWF Ох24 ВCF STATUS, Z XORLW Ох4Е BTFSC STATUS, CALL cmdset MOVF Ох24, О ВCF STATUS, Z XORLW Ох46 BTFSC STATUS, CALL cmdreset MOVF Ох24, О BCF STATUS, Z XORLW Ох53 BTFSC STATUS, CALL stat RCIF ; Ждем прихода символа. ; Прочитаем номер реле. Сохраним номер реле в 23h. ; Запишем 30h в аккумулятор. ; Переведем символ в номер. ; Сохраним номер реле в 2Зh. RCIF ; Ждем прихода символа. ; Прочитаем команду Nвключить Fвыключить. i Сохраним команду в 24h. i Включение N (4ЕЬ). Z; Если не включить, то пропустить. Перепишем из 24h в аккумулятор. ; Выключение F (46h). Z; Если не выключить, то пропустить. ; Перепишем из 24h в аккумулятор. S (53h) запрос статуса. Z i Если не запрос caтyca, то проnyстить. ; Сохраним состояние всех реле в энерrонезависимой памяти. CLRW BSF STATUS, BCF STAТUS, MOVLW ОхОО MOVWF EEADR ; Запишем 30h  состояние реле в EEPROM. RPO; Выбор банка 1. RP1 i Запишем Oh в аккумулятор. Запишем адрес Oh в реrистр адреса. 
62 rлава. 1 Базовая версия BCF STAТUS, RP1; Выбор банка о. BCF STAТUS, RPO CLRW ADDWF Ох3 О , О ; Запишем содержимое 30h в аккумулятор. COМF Ох30,0 Инвертируем перед сохранением. BSF STAТUS, RPO; Выбор банка 1. BCF STAТUS, RP1 MOVWF EEDATA BSF EECON1, WREN ; Разрешить запись. BCF INТCON, GIE; Запретить прерывания. MOVLW Ох55 MOVWF EECON2 MOVLW ОхАА MOVWF EECON2 BSF EECON1, WR BSF INТCON, GIE; BCF EECON1, WREN ВCF STAТUS, RP1 ; BCF STAТUS, RPO ; Записать 55Ь. Записать AAh. ; Установить флаr для начала запись. Разрешить прерывания. ; Запретить запись. Выбор банка о. chkwr: BTFSS PIR1, GOТO chkwr CLRW ADDWF Ох3 О, О MOVWF PORTA BCF PIR1, EEIF REWRN EEIF ; Про верка завершения записи. . i Перепишем 30h в порт. Сбросим флаr. ; Подпроrрамма передачи статуса реле. stat: ВCF STATUS, RP1; Выбор банка о. ВCF STAТUS, RPO CLRW ; Проверим реле о. ADDWF Ох23, О BCF STAТUS, Z XORLW ОхО ; Реле о. BTFSC STATUS, Z CALL re10 CLf{W ; Проверим реле 1. ADDWF Ох23, О BCF STAТUS, Z XORLW Ох1 ; Реле 1. BTFSC STATUS, Z 
Схема и проrрамма релейноrо модуля 63 CALL re1l CLRW ; Проверим реле 2. ADDWF Ох23, О BCF STAТUS, Z XORLW Ох2 Реле 2. BTFSC STATUS, Z CALL re12 CLRW Проверим реле 3. ADDWF Ох23, О ВCF STAТUS, Z XORLW ОхЗ Реле 3. BTFSC STAТUS, Z CALL rе1З CLRW Проверим реле 4. ADDWF Ох23, О BCF STAТUS, Z XORLW Ох4 Реле 4. BTFSC STATUS, Z CALL re14 CLRW Проверим реле 5. ADDWF Ох23, О BCF STAТUS, Z XORLW Ох5 ; Реле 5. BTFSC STAТUS, Z CALL re15 CLRW ; Проверим реле 6. ADDWF Ох2З, О BCF STAТUS, Z XORLW Ох6 Реле 6. BTFSC STATUS, Z CALL rе1б CLRW ; Проверим реле 7. ADDWF Ох23, О ВCF STATUS, Z XORLW Ох7 ; Реле 7. BTFSC STATUS, Z CALL re17 ; Теперь это все отпраеим в передатчик. BSF PORTB, О ; Переключим драйвер, RS485 на передачу. BCF STAТUS, RP1; Выбор банка 1. BSF STAТUS, RPO 
64 rЛQВQ. 1 Базовая версия BSF TXSTA, TXEN; Разрешаем передачу. BCF STAТUS, RP1; Выбор банка о. BCF STATUS, RPO MOVLW Ох52 MOVWF TXREG ; Отправим символ модуля. BCF STATUS, RP1; Выбор банка 1. BSF STATUS, RPO outdatO: BTFSS TXSTA, TXIF ; Ждем отправки символа. GOТO outdatO ВCF STATUS, RP1; Выбор банка о. ВCF STAТUS, RPO CLRW ADDWF Ох21, О MOVWF TXREG ; Отправим первый символ адреса. BCF STATUS, RP1 ; Выбор банка 1. BSF STATUS, RPO outdatl: BTFSS TXSTA, TXIF ; Ждем отправки символа. GOТO outdatl BCF STATUS, RP1; Выбор банка о. ВCF STATUS, RPO CLRW . ADDWF Ох22, О MOVWF TXREG ; Отправим второй символ адреса. ВCF STAТUS, RP1; Выбор банка 1. BSF STAТUS, RPO outdat2: BTFSS TXSTA, TXIF ; Ждем отправки символа. GOТO outdat2 ВCF STAТUS, RP1 ; Выбор банка о. BCF STATUS, RPO MOVLW Ох23 MOVWF TXREG ; Отправим символ статуса. BCF STATUS, RP1; Выбор банка 1. BSF STAТUS, RPO outdat3: BTFSS TXSTA, TXIF ; Ждем отправки символа. GOТO оutdаtЗ BCF STATUS, RP1; Выбор банка о. BCF STATUS, RPO CLRW ADDWF Ох23, О 
Схема и проrрамма релейноrо модуля 65 ADDLW ОхЗ О MOVWF TXREG ; Отправим символ номера реле. ВCF STATUS, RP1; Выбор банка 1. BSF STATUS, RPO outdat4: BTFSS TXSTA, TXIF ; Ждем отправки символа. GOTO outdat4 BCF STAТUS, RP1; Выбор банка о. BCF STAТUS, RPO CLRW ADDWF Ох25, О MOVWF TXREG ;- Отправим символ состояния реле. ВCF STAТUS, RP1; Выбор банка 1. BSF STAТUS, RPO outdat5: BTFSS TXSTA, RCIF ; Ждем отправки символа. GOTO outdat5 BCF TXSTA, TXEN; Запрещаем передачу. BCF STATUS, RP1; Выбор банка о. BCF STATUS, RPO BCF PORTB, О ; Переключим драйвер RS485 на прием. REТURN iПодпроrpамма обработки статуса реле. re1O: BTFSC ОхЗО, О CALL sostn BTFSS ОхЗО, О CALL sostf REТURN re1l: BTFSC ОхЗО, 1 CALL sostn BTFSS ОхЗО, 1 CALL sostf REТURN t"e12 : BTFSC ОхЗ О , 2 CALL sostn BTFSS ОхЗО, 2 CALL sostf REТURN rе1З: BTFSC ОхЗО, 3 CALL sostn BTFSS ОхЗО, 3 
66 rлава. 1 Базовая версия CALL sostf REТURN re14: BTFSC Ох30, 4 CALL sos tn BTFSS ОхЗО, 4 CALL sostf RE'IURN re15: BTFSC Ох30, '5 CALL sostn BTFSS Ох30, 5 CALL sostf REТURN re16: BTFSC ОхЗО, 6 . I CALL sostn BTFSS Ох30, 6 CALL sostf REТURN re17: BTFSC ОхЗО, 7 CALL sostn BTFSS Ох30, 7 CALL sostf REТURN ; Подnpоrраммы образования символов состояний sostn:MOVLW Ох4Е ; Состояние  включено. MOVWF Ох25 REТURN sostf:MOVLW Ох46 ; Состояние  выключено. MOVWF Ох25 REТURN END Проrрамма peneiiHoro MOДYnR на R3IaIKeC Ф.iiп 3iJrollo8кa #define MODULNAМESIM "R" #define CМDSIM "$" #define bitset(var,bitno) ((var) 1= 1 « (bitno» #define bitc1r(var,bitno) ((var) &= (1 « (bitno») 
void putch(unsigned char); unsigned char getch(void); int initcomms () ; int simnumadr(); int cmd(); int re1on(int пит); int reloff(int пит); int relstat(int пит); Основно;; фаiin #include <pic16f62xa.h> #include <stdio.h> #include "re1eyc.h" Схема и проrрамма релейноrо модуля 67 unsigned char input; реrистра. unsigned char MODSIM1; unsigned char MODSIM2; unsigned char RELSIM; unsigned char commandreciev команды. // для считывания приемноrо / / Первый символ адреса модуля. / / Второй символ адреса модуля. // Символ реле. [6]; // Массив для полученной int MODADDR; int simendnum = о; модуля . int MODNUМ; / / Полученный адрес модуля, как число. int RELNUМ; // Номер реле. unsigned char RELSTAT = о; // Статус реле (позиционно) : 1  вкл, О  выкл. int i; / / Получение байта. unsigned char getch() { // Заданный адрес модуля, как число. / / Полный символьный номер whi1e(!RCIF) // Устанавливается, коrда реrистр не пуст. continue; return RCREG; } // Вывод одноrо байта. void putch(unsigned char pyte) { 
68 rлава. 1 Базовая версия while ( ! TXIF) continuei TXREG = byte; // Устанавливается, коrда реrистр пуст. } // Преобразуем символьный адрес в число. int simnumadr() { simendnum = о; MODSIMl = commandreciev [1]; // Первый символ номера. MODSIM2 = commandreciev [2]; / / Второй символ номера. MODSIM1 = MODSIM1  Охзо; // в виде числа. MODSIM2 = MODSIM2  Охзо; simendnum = MODSIM1*OxOA + MODSIM2; return simendnum; } / / Получение и выполнение команды. int cmd() { RELSIM = commandreciev [4]; RELNUМ = RELSIM  Охзо; switch (commandreciev [5]) { case MN M : re1on (RELNUМ) ; break; case "F": re1off(RELNUМ); break; case "S": re1stat(RELNUМ); breaki } } / / Выполнение команды включения заданноrо реле. int re1on(int пит) { bitset (RELSTAT, RELNUМ); PORTA = RELSTAT; EEADR =Охо; / / Запишем состояние реле в EEPROM. EEDATA = RELSTAT; WREN = 1; GIE = о; EECON2 = Ох55; 
Схема и проrрамма релейноrо модуля 69 EECON2 = ОХАА; WR =1; whi1e (WR); GIE = 1; WREN = о; } //Выполнение команды выключения заданноrо реле. int reloff(int пит) { bitclr (RELSTAT, RELNUМ); PORTA = RELSTATi EEADR =Охо; // Запишем состояние реле в EEPROM. EEDATA = RELSTATi WREN = 1; GIE = о; EECON2 = Ох55; EECON2 = ОхАА; WR =1; while (WR) i GIE = 1; WREN = О; } / / Выполнение команды передачи состояния заданноrо реле. int re1stat(int пит) { commandreciev[O] = "R"; commandreciev[l] = МОDSIМ1+0хЗО; commandreciev[2] = МОDSIМ2+0хЗО; соmmапdrесiеv[З] = "#"; commandreciev[4] = RELSIM; if ((RELSTAT»RELNUМ)&Ox01) commandreciev[5] = "N"; if (!((RELSTAT»RELNUМ)&Ox01») commandreciev[5] = "F"; CREN =0; / / Запрещаем прием. RBO = 1; //Переключим драйвер RS485 на передачу. TXEN = 1; / / Разрешаем передачу. for (i=O; i<6; ++i) putch(cornmandreciev[i]); for (i=0;i<1000ii++); // Задержка для вывода for (i=O; i<6; ++i) commandreciev [i] = · "; RBO = о; / / Выключаем драйвер RS485 на передачу. TXEN = О i / / Запрещаем передачу. CREN =1; / / Разрешаем прием. } 
70 rлава. 1 Базовая версия int ini tсопuns ( ) { PORTA = Охо; CMCON = Ох?; TRISA = Охо; TRISB = OxFE; RCSTA = ОЬ10010000; TXSTA = ОЬОООООl10; SPBRG = Ох68; RBO = о; / / Инициализация модуля. // Настройка портов А и В / 1 Настройка приемника . // Настройка передатчика. // Настройка режима приемапередачи. // Выключаем драйвер RS48? на передачу. // Прочитаем состояние реле из EEPROM. EEADR = Охо; RD = 1; RELSTAT = EEDATA; PORTA = RELSTAT; } void main (void) { ini tcomms ( ) ; / / Инициализация модуля. for (i=Oi i<6; ++i) commandreciev [i] = " "; commandreciev [О] = "R"; //Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах МOD.JillDR=MODADDR»4; / / Сдвинем на четыре бита. // Начинаем работать. .start: CREN =1; input = getch(); switch (input)- { case "R": / / Если обращение к релейному модулю. for (i=l; i<6; ++i) // Запишем команду в массив. { input = getch ( ) ; commandreciev [i] = input; } MODNUМ = simnumadr () ; /1 Чтение из сети. if (MODNUМ != MODADDR) break; / / Если не наш адрес. else i f ( conunandrec i ev (3] = "$") cmd ( ); / / ЕсIП1 команда. 
Схема и проrрамма релейноrо модуля 71 defau1t: goto start; } goto start; } НЕХ--фаiiп /111_ эаrруэк" . nporpaMMarop :10000000830100308A0004282030840038300D201D :100010008301392В040б8001840АО406031DОА2883 : 020020000034АА :1004Е20083018С1Е712А1А0808008301В700831247 :1004F20003130С1Е782АЗ70899000800F401F5014D :100502000310F30CF20C031C8D2A7008F407710817 :100512000318710AF5070310FOODF10D7208730448 :1005220003190034812A8301850107309F00831655 :100532008501FE30860090308312980006308316C3 :100542009800683099008312061083169B011C14DO :100552001A098312A200850008008301AD01AE01D1 :100562003008АООО3108А100DО30АОО7А1070АЗ04Е :10057200F200F3012008FOOOFI017F222108740744 :10058200AD0075080318750AAEOOF1002D08FOOOE1 :1005920008000130F000831203132908F100F10A68 :1005A200D42A0310FOODF10BD22A7008A2042208FВ :1005В200850083169ВО18312220983169АОО1С155В :1005C2008B1355309DOOAA309D009C149C18E72A7D :1005D2008B171Cl1831208000130F00083120313El :1005E2002908F100F10AF72A0310FOODF10BF52AAO :1005F2007009A2052208850083169B018312220935 :1006020083169AOOIC158B1355309D00AA309D004D :100612009C149C180A2B8B171Cl18312080083014F :100622003308A300D030FOOOFF30F1002308700738 :10063200А90071080318710АААО02Е2В2908В50017 :100642002A08B600CA2A2908B5002A08B600ED2AE7 :100652002908В5002А08В6008С2В3408463А03193В :10066200242B083A03191F2BID3A031D0800292BBE :100672009422AВ01AC01462B2B082F3E840083133E :1006820020308000АВОАО319АСОА2СО8803АРООО33 :1006920080307002063003192B02031C3D2B5230AE :1006A200AF000608A500A6010430F000260DA60C36 :1006B200A50CFOOB572B852ВAВ01AВOAAC012C0818 :1006С200803АРООО80307002063003192ВО20318С2 :1006D200762B7122A4002B082F3E8400831324085A :1006Е2008000АВОА0319АСОА602ВАЕ227008А70087 
72 rлава. 1 Базовая версия :1006F2007108А80026060ЗID802В250827060З1D66 " :10070200852В2430В200102318167122А40052ЗАОD :100712000З195D2В852В52З08301AFОО200830ЗЕ38 :10072200ВООО2108З03ЕВ1002ЗЗОВ2002ЗО8ВЗООЕС :100732002208F0002908F100F10AA12B0310FOOCA5 :10074200F10В9F2В7008FООО701СА92В4ЕЗОВ400Е7 :100752002208F0002908FI00F10AВ12B0310FOOC75 :10076200F10ВAF2В7008FОО07018В92В4б30В400В3 :1007720018120614831698168312АВО1АСО12С08СА :10078200803AFОО08030700206300З192В02031801 :10079200D42В2ВО82FЗЕ8400831ЗООО87б22АВОА49 :1007А2000319АСОАС02ВАВО1АСО12СО880ЗAFООО5З : 1007В20083З 07002Е8ЗОО3 192В0203 18E42ВAВOAD2" :1007С2000319АСОAD62ВАВО1АСО12С0880ЗAFООО1D :1007D2008030700206300З192ВО20318FА2В2ВО80З :1007Е2002F3Е8400831320ЗО8000АВОАО319АСОА29 :ОЕ07F200Е62В0610831698128З12181б0800С4 :OOOOOOOlFF с теми, кому интересно провести эксперименты, не имея опыта работы с микроконтроллерами и проrраммным обес печением или желая более детально ознакомиться с модулем, мы продолжим разrовор о том, как это все устроено. Требования к модулю: . модуль должен иметь реле, контакты KOToporo позволят подключить наrрузку с параметрами: ....220В, lOA (мощ ности наrрузки .... 2 кВт); . модуль должен иметь сетевой интерфейс RS485 (сис темная сеть); . по отнотению к системной сети модуль должен быть пассивнь м, то есть ero основным режимом работы бу дет прослушивание сети и выполнение команд, полу ченных по сети, если они адресованы модулю; . адрес модуля задается установкой переключателя в co ответствующее положение. Поскольку контроллер PIC16F628A имеет встроенный USART, мы используем ero для работы с интерфейсом RS485. Адресный селектор можно орrанизовать на микрокон троллере различным образом. Для начала используем наибо лее очевидный способ выводы порта, включенные на ввод
Схема и проrрамма релейноrо модуля 73 информации, соединим с контактами переключателя, KOTO рый устанавливает их в состояние  «1» или «О». В дальней тем мы обсудим дрyrие способы задания адреса. Четыре бита дают возможность адресоваться к 16 устройствам. Для подачи сетевых команд используем СОМпорт компь ютера с передачей байта (рис. 1.35). Биты данных Пауза ст. (линия свободна) (msb) Высокий мл. .... (Ibs)  . . со: .....:Oi : 1 : u : 2j З!4 516 t: с: :0:0: . . .... . .... . : :.7 . . . iUiUi Низкий . .  . i 4 мкс :  . . . i Jl фрейм данных  44 мкс . . . .  Рис. 1.35. биты данных RS232 из статьи на сайте http://measure.Chat.ru Каждый бит имеет длительнocrь4мкс (приданной скорости). Для обращения к релейным модулям используем дополни тельный адресный префикс «R».. Практически, мы определились со всем необходимым, чтобы приступить к построению релейноrо модуля. Команды, которые будет принимать наш модуль: . включить  Rxx$xN; . выключить  Rxx$xF. Я добавлю команду передачи модулем состояния реле: . передать статус  Rxx$xS. При передаче статуса используем следующую символику: . включено  Rxx#xN; . выключено  Rxx#xF. Здесь Rxx$xN означает: R  релейный модуль, хх  два сим вола адреса от 00 до 15, $  символ команды (#  символ CTaтy са), х  номер реле от О до 7, N  включить (  выключить). Уточним, как мы будем использовать ресурсы контролЛе ра. Для ввода информации используем встроенный в KOH тро.iIлер USART. 
74 rлава. 1 Базовая версия Использование порта В: . RВO  управление передатчиком (микросхема МAX1483). . RВ1  прием (приемник USART). . RВ2  передача (передатчик USART). Для ввода заданноrо адреса используем четыре старших бита порта В (RВ7RВ4). Использование порта А: . для подключения реле используем биты порта А (RЛО RЛ7), что предполаrает использование восьми реле; . при необходимости увеличить количество реле можно использовать свободные (если они есть) биты порта В. Мы rOTOBbI при ступить к написанию проrраммы. Основные блоки проrраммы: . инициализация (конфиryрация контроллера); . ожидание и прием команды (ожидание активности в сети, чтение команды, проверка адреса, и, если адрес совпадает с адресом устройства, выполнение команды, возвращение к ожиданию команды); . выполнение команды. Распишем это поподробнее. Иmщиализация. В этом блоке мы должны задать конфиryрацию контрол лера, переход в режим низкоrо энерrопотребления (SLEEP) и условия выхода из этоrо режима. В блоке инициализации мы прочитаем адрес, задаваемый адресным переключателем. Ожидание и прием команды. Этот блок проrраммы является основным, поскольку в сети модуль иrрает пассивную роль, то есть ожидает прихода и выполняет команду, адресованную ему. При активации сети команда прочитывается. Если префикс совпадает с префик сом модуля, а адрес  с адресом устройства, команда выполня- ется, в противном случае модуль переходит в режим ожида ния следующей сетевой команды. Адрес в слове команды сравнивается с ранее прочитанным (при инициализации) за данным адресом модуля. 
Схема и проrрамма релейноrо модуля 75 Выполнение команды запроса статуса. Этот блок проrраммы отличается от предыдущеrо, начи ная с момента получения символа S вместо N или F. Про rpaMMa должна определить состояние соответствующеrо вывода порта, переключить USART на предачу и передать статус в формате Rxx#xN, если соответствующий вывод порта  в состоянии «1», или Rxx#xF, если он в состоянии «О». После этоrо проrрамма переходит к ожиданию следую щей команды. Блокинициализацииконтроллер В первую очередь, определим, нужен ли нам режим «SLEEP», который переводит контроллер в состояние с уменьтенным энерrопотреблением. Режим очень удобен и важен в тех случаях, коrда контроллер используется в услови их батарейноrо питания. Переход в режим «SLEEP» ПрОДJIе вает срок службы батарей или время работы без подзарядки аккумулятора. В натем случае нет необходимости в поддер жании этоrо режима, поскольку модуль получает пиание от блока питания. Часть конфиryрирования необходимо выполнить при проrраммировании контроллера. Это относится к слову KOH фиryрации по адресу 2007Ь. Здесь h после цифр означает НЕХ, hexadecimal (шестнздцатеричное число). в слове KOH фиryрации устанавливаются (или не устанавливаются) биты защиты, выбирается режим работы TaKToBoro reHepaTopa и некоторые параметры, относящиеся к режиму питания KOHT роллера. Вот первый вариант слова конфиryрации для тактовой частоты 1620 мrц: . Бит 13 устанавливаем в «1»  выключаем защиту кода. . Бит 8 устанавливаем в « 1»  выключаем защиту EEPROM. . Бит 7 устанавливаем в «О»  вывод RB4 работает как цифровой канал BBoдaBЫBoдa. . Бит 6 устанавливаем в «О»  запрещаем сброс по сниже нию напряжения питания. . Бит 5 устанавливаем в «О»  вывод RB5 работает как цифровой канал BBoдaBЫBoдa. 
76 rлава. 1 Базовая версия . Бит 4 устанавливаем в «О»  режим HS reHepaTopa, кварц к выводам RЛ6 и RЛ7. . Бит 3 устанавливаем в «О»  выключаем режим включе ния по таймер . Бит 2 устанавливаем в «О»  выключаем режим работы сторожевоrо таймера. . Бит 1 устанавливаем в «1»  режим HS reHepaTopa, кварц к выводам RЛ6 и RЛ7. . Бит О устанавливаем в «О»  режим HS reHepaTopa, кварц к выводам RЛ6 и RЛ7. Слово конфиryрации будет выrлядеть так  3FOAh. Для работы BHYTpeHHero TaKToBoro reHepaTopa следует использовать кварцевый резонатор с параллельным резонан сом на 1620 мrц (рис. 1.36). OSC1 С1 C]XТAL  I I I I I I I : : RF I I ,  ... Sleep OSC2 Fosc С2 Note 1: 2: PIC16F627д1628Aj648A А series resistor тау Ье required for А Т strip cut crystals. See т аЫе 14 1 and Т аЫе 142 for recomended values of С 1 and С2 ' Рис. 1.36. Типовая схема включения кварцевоrо реэонаторадпя PIC16F628A Для частоты 16 мrц рекомендованные значения 1022 пФ конденсаторов С1 и С2. Давайте подумаем, а не использовать ли встроенный в KOH троллер reHepaTop. Будем ли мы выполнять какиелибо оп рации, требующие стабильной тактовой частоты? На стабиль ность частоты BнyтpeHHero reHepaTopa, в первую очередь, влияет температура и напряжение питания. Будут ли они 
Схема и проrрамма релейноrо модуля 77 значительно меняться? Если мы не планируем использовать модуль в уличном исполнении, температура меняется мало. Если же после входноrо напряжения 12 В мы поставим стаби лизатор на 5 В, питающее напряжение будет изменяться еще меньте. В данный момент я больте склонен отказаться от кварцевоrо резонатора и использовать внутренний тактовый reHepaTop. В этом случае есть два варианта на выбор. Для использова ния режима ER (3,6 мrц) к выводу RЛ7 микросхемы подклю чается резистор (не более 40 кОм). Вывод RЛ6 может исполь зоваться для BBoдaBЫBoдa. Второй вариант слова конфиrypации: . Биты 1310 устанавливаем в «1»  выклюаем защиту кода. . Бит 8 устанавливаем в «1»  выключаем защиту EEPROM. . Бит 7 устанавливаем в «О»  вывод RB4 работает как цифровой канал BBoдaBЫBoдa. . Бит 6 устанавливаем в «О»  запрещаем сброс по сниже нию напряжения питания. . Бит 5 устанавливаем в «О»  вывод RB5 работает как цифровой канал BBoдaBЫBoдa. . Бит 4 устанавливаем в «1»  режим ER, резистор 40 кОм подключается к RЛ7. . Бит 3 устанавливаем в «О»  выключаем режим включе ния по таймеру. . Бит 2 устанавливаем в «О»  выключаем режим работы сторожевоrо таймера. . Бит 1 устанавливаем в «1»  режим ER reHepaTopa, pe зистор подключается к RЛ7. . Бит О устанавливаем в «О»  режим ER reHepaTopa, pe зистор подключается к RЛ7. Слово конфиryрации будет выrлядеть так  3FIAh Еще более удобный вариант  использование BнyтpeHHero reHepaTopa без внешних элементов INTRC (4 мrц). Слово конфиryрации в этом случае  3F18h. 
78 rлава. 1 Базовая версия Здесь я хотел бы сделать замечание, или признание  как вам уrодно. Я впервые буду использовать контроллер PIC16F628A и пользоваться средой проrраммирования контроллера MPLAB Может возникнуть закономерный вопрос  а чему я MOry Ha учить KorOTO, если сам впервые это делаю? Если вас смуща ет данный аспект, можете обратиться к мноrочисленной ли тературе по проrраммированию контроллеров, пропустив дальнейшее, что и решит проблему. Но мне кажется, что, имея большой опыт работы, основательно забываешь TPYД ности, С которыми столкнулся в начале. Д если сам только начинаешь работать, эти трудности налицо. в блоке инициализации контроллера необходимо, в пер- вую очередь, установить конфиrypацию портов А и В. Нам потребуется установить биты порта А O6 на вывод, бит 7  на ввод (к выводу RЛ7 порта подключается резистор в режиме ER) или все выводы порта А  на вывод для режима reHepaTopa INTRC. ДЛЯ этоrо в реrистр TRISA необходимо записать «1» для входных выводов и «О» дЛЯ выходных. Ниже приведен при мер инициализации для порта А, взятый из руководства: CLRF PORTA i 1nitialize PORTA Ьу setting output data 1atches i(инициализация установкой защелок данных) MOVLW ОхО7 ;Тurn comparators off and еnаЫе pins for 1/0 functions MOVWF CMCON i (выключение компараторов для 1/0 функций) BCF STAТUS, RP1 BSF STAТUS, RPO iSe1ect Bank1 (выбор банка 1) MOVLW Ох80 iVa1ue used to initialize data direction MOVWF ТRISA ;Set НА<4:0> as outputs TRISA<5> a1ways read as '1'. iTRISA<7:6> depend оп oscil1ator mode i (в данном случае все на ВЫВОД, 7 ввод) Здесь ОхО7 означает, что число 7  шестнадцатеричное. Инициализация порта В связаа, прежде Bcero, с необходи мостью использования USART. Необходимо установить RВO на 
Схема и проrрамма релейноrо модуля 79 ВЫВОД И записать в Hero «О» (при передаче записывается «1»). Затем: . RВ1 устанавливается на ВВОД, а RВ2  на вывод; . RВ3 установим на вывод (для управления микросхемой МAX1483); . RВ4RB7 устанавливаем на ввод для орrанизации aдpec Horo селектора. CLRF PORTB 1atches ;Initialize PORTB Ьу setting output data ; (инициализация установкой защелок данных) MOVLW OxF2 ;Va1ue used to initialize data direction MOVWF TRISB Запишем необходимые данные в реrистр управления при емника USART  RCSTA (адрес 18Ь): . Бит 7  «1»  модуль включен; . Бит 6  «О»  8битный прием; . Бит 5  не имеет значения; . Бит 4  «1»  прием разрешен; . Бит 3  не имеет значения; . Бит 2  только на чтение; . Бит 1  только на чтение; . Бит О  только на чтение. Операции записи побитовые: BSF RCSTA, SPEN BCF RCSTA, RX9 BSF RCSTA, CREN Аналоrично запишем данные в реrистр передатчика USART  TXSTA (адрес 98Ь): . Бит 7  не имеет значения; . Бит 6  «О»  8битная передача; . Бит 5  «1»  разретение передачи; . Бит 4  «О»  асинхронный режим работы; . Бит 3  не используется; 
80 rлава. 1 Базовая версия . Бит 2  «1»  высокоскоростной режим; . Бит 1  только чтение; . Бит О  проверку четности мы не используем. BCF TXSTA, ТХ9 ВCF TXSTA, SYNC BSF TXSTA, BRGH BSF TXSTA, TXEN (эта команда появится коrда мы начнем передачу статуса) . Кроме Toro, необходимо задать скорость работы в реrистре SPBRG. для первоrо варианта TaктoBoro reHepaTopa (SYNC == О, BRGH == 1,16 мrц): MOVLW Ох67 MOVWF SPBRG ДЛЯ BToporo варианта TaKToBoro reHepaTopa (SYNC == О, BRGH == 1, 3,6 мrц): MOVLW Ох1 б MOVWF SPBRG В результате блок инициализации (для BToporo варианта) будет выrлядеть следующим образом: list р=lбf628а #inc1ude p16f628a.inc ; Иlnщиализация модуля ВCF STAТUS, RP1 ; Выбор банка О ВCF STAТUS, RPO Если посмотреть раздел орraнизации памяти контроллера, видно, что часть реrистров, которые мы используем, находит- ся в банке «О», а часть в банке «1». Если забыть переIUIЮЧИТЬСЯ, команды MOryт не выполняться, а среда проrраммирования MPLAВ напомнит, выводя в окне Output на странице MPLAВ SIM напоминания при трансляции проrраммы. Это были пе вые rрабли, на которые я часто наступал. CLRF PORTA ; Настройка порта А. MOVLW ОхО7 
MOVWF CMCON ВCF STAWS, RPl BSF STAWS, RPO MOVLW Ох80 MOVWF TRISA MOVLW OxF6 MOVWF TRISB ВCF STAWS, RPl ВСР STAWS, RPO CLRF PORTB Схема и проrрамма релейноrо модуля 81 ; Выбор банка 1. ; Настройка порта В. ; Выбор банка о. ;Настройка приемопередатчика USART. BSF RCSTA, SPEN BCF RCSTA, RX9 BSF RCSTA, CREN BCF STAWS, RP1 BSF STAWS, RPO BCF TXSTA, ТХ9 BCF TXSTA, SYNC BSF TXSTA, BRGH MOVLW Охlб MOVWF SPBRG BCF STAWS, RP1 BCF STAWS, RPO CLRW ADDWF PORTB, О ANDLW OxFO MOVWF Ох20 SWAPF Ох20, 1 CALL adrsim ; Настройка npиемника. ; Выбор банка 1. Настройка передатчика. ; Выбор банка о. ; Считывание собственноrо адреса. ; Про чита ем порт В. ; Нам не нужны младшие биты. ; Сохраним адрес в реrистре 20h. ; Нам не нужна работа с младшими битами. ; Преобразуем ero в символьный вид. Чтобы сравнить адрес, задаваемый переключателем, с aд ресом в слове команды, нужно преобразовать их к единому 
82 rпaBa. 1 Базовая версия виду. Здесь существует несколько возможностей. Я использую одну из них, вы можете поступить иначе. ; прочитаем из EEPROM в ЗОh  состояние реле. Необязательно хранить текущее состояние реле в энерrо независимой памяти. Но это может быть полезно и, кроме Toro, дает возможность разобраться с механизмом записи в энерrонезависимую память. Можно, например, изменить Me тод задания адреса. Использовать вместо переключателя в адресном селекторе проrраммную установку адреса  запись адреса в энерrонезависимую память контроллера. Так, в част ности, устроены некоторые промышленные модули. В этом случае перед первым использованием модуля ero переводят в режим установки адреса и проrраммно устанавливают этот адрес. Механизм записи состояния реле и адреса одинаков. BSF STAТUS, RPO ; Выбор банка 1. BCF STAТUS, RP1 MOVLW ОхОО MOVWF EEADR ; Адрес считываемоrо реrистра. BSF EECON1, RD : Чтение. MOVF EEDATA,W ; w = EEDATA. BCF STAТUS, RP1 ; Выбор банка о. BCF STAТUS, RPO MOVWF ОхЗО COМF ОхЗО,1 CLRW ADDWF ОхЗ О , О MOVWF PORTA ; Будем хранить в EEPROM в инверсном виде ; А в реrистре ЗОh в npямом. ; Перепишем ЗОh в порт. Сохранение состояния реле в инверсном виде связано с тем, что в EEPROM по умолчанию записаны единицы. При инициализации прочтение состояния приведет к включению всех реле. Чтобы избежать этоrо, будем инвертировать про читанное. В строке «CALL adrsim» мы вызываем подпроrрамму, KO торая переводит адреса в символы: Это опять--таки не обязательно делать в данном проrрамм ном блоке. Но оставлять в блоке инициализации длинный «хвост» мне не захотелось. Перевод адреса в символьное 
Схема и проrрамма релейноrо модуля 83 представление можно сделать различными- способами, я выб рал самый очевидный. Поскольку мы используем символьный обмен, я выпишу шестнадцатеричные коды некоторых символов ASCII: «О»  30Ь; «1»  31h; «2»  32Ь; «3»  33Ь; «4»  34Ь; «5»  35Ь и Т. д. «R»  52Ь; «$»  24Ь; «#»  23Ь; «N»  4ЕЬ; «F»  46Ь; «S»  53Ь ; Подnpоrрамма перевода адреса в символ (храним по адресам 21h, 22h). adrsim: CLRW ; Если адрес 1 запишем символы "О" "1" (30h и 31h) . ADDLW Ох3 О MOVWF Ох21 CLRW ADDLW Ох31 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох! BTFSC STAWS, Z REТURN CLRW ; Если адрес 2 заПИIIIем символы "О" "2" (30h и 32h) . ADDLW Ох30 MOVWF Ох21 CLRW ADDLW Ох32 MOVWF Ох22 MOVF Ох20, О BCF STAWS, Z XORLW Ох2 BTFSC STAТUS, Z RE'IURN CLRW ; Если адрес 3 запишем символы "О" "3". ADDLW Ох3 О MOVWF Ох21 CLRW ADDLW Ох33 
84 rпaBa. 1 Базовая версия MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW ОхЗ BTFSC STAТUS, Z RE'IURN CLRW ; Если адрес 4 запишем символы "О" "4" ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ4 MOVWF Ох22 MOVF Ох20, О ВCF STAТUS I Z XORLW Ох4 BTFSS STAТUS, Z RE'IURN CLRW ; Если адрес 5 запишем символы "О" "5". ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ 5 MOVWF Ох22 MOVF Ох20, О ВCF STAТUS, Z XORLW Ох5 BTFSS STAТUS, Z RE'IURN CLRW ; Если адрес 6 запишем символы "О" "6". ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗб MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW Ох6 BTFSS STAТUS, Z RE'IURN 
Схема и проrрамма релейноrо модуля 85 CLRW Если адрес 7 запишем СИМВОЛЫ "оп "7". ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ 7 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW Ох7 BTFSS STAWS, Z REТURN CLRW ; Если адрес 8 запишем СИМВОЛЫ "О" "8". ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ 8 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW Ох8 BTFSS STATUS, Z REТURN CLRW ; Если адрес 9 запишем символы "О" "9" ADDLW ОхЗО MOVWF Ох21 CLRW ADDLW ОхЗ 9 MOVWF Ох22 MOVF Ох20, О BCF STAWS, Z XORLW Ох9 BTFSS STAТUS, Z REТURN CLRW ; Если адрес 10 (Ah) запишем СИМВОЛЫ "1" "О". ADDLW ОхЗ1 MOVWF Ох21 CLRW ADDLW ОхЗ О MOVWF Ох22 MOVF Ох20, О 
86 rl1aBa. 1 Базовая версия BCF STAТUS, Z XORLW ОхА BTFSS STATUS, Z RE1:URN CLRW ; Если адрес 11 (Bh) запишем СИМВОЛЫ "1" "1". ADDLW Ох31 MOVWF Ох21 CLRW ADDLW Ох31 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW ОхВ BTFSS STATUS, Z REТURN CLRW ; Если адрес 12 (Ch) запишем СИМВОЛЫ "1" "2". ADDLW Ох3! MOVWF Ох21 CLRW ADDLW ОхЗ2 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XOW ОхС BTFSS STAТUS, Z RE'IURN CLRW Если адрес 13 (Dh) запишем СИМВОЛЫ "1" "3". ADDLW Ох31 MOVWF Ох21 CLRW ADDLW Ох33 MOVWF Ох22 MOVF Ох20, О BCF STAТUS, Z XORLW OxD BTFSS STATUS, Z RE1:URN CLRW ; Если адрес 14 (Eh) запишем СИМВОЛЫ "1" "411. ADDLW Ох31 
Схема и проrрамма репейноrо модуля 87 MOVWF Ох21 CLRW ADDLW ОхЗ4 MOVWF Ох22 MOVF Ох20, О BCF STATUS, Z XORLW ОхЕ BTFSS STATUS, Z REТURN CLRW ; Если адрес 15 (Fh) запишем СИМВОЛЫ "1" "5". ADDLW ОхЗ 1 MOVWF Ох21 CLRW ADDLW ОхЗ5 MOVWF Ох22 MOVF Ох20, О BCF STAWS, Z XORLW OxF BTFSS STATUS, Z REТURN Проrраммный блок ожиданИJI активности в сети. 1. Проверим бит RCIF в реrистре PIR1. 2. Если бит установлен, пропустим следующую команду. 3. Вызовем подпроrрамму обработки команды. 4. Вернемся к начщ Вот и вся проrрамма: start: BTFSS PIR1 RCIF ; Ждем прихода nepBoro символа команды. GOТO start CALL cmnd ; С приходом nepBoro символа начинаем обработку . GOTO start Следующая трудность спрятана как раз в этом месте, хотя я умудрился наступить на эти rрабли при обработке «in1». Разумная, как мне казалось, конструкция: start: BTFSS PIR1, RCIF i Ждем прихода первоrо символа команды. GOTO start 
88 rпaBa. 1 Базовая версия работать в режиме отладки MPLAВ не хотела. Я все перепро верил MHoroKpaTHo. Все было правильно, но анимация пр rpaMMbI безнадежно застревала, я ретил, что проrрамма не работает. Понять, в чем здесь дело, помоrло обращение к сай ту Microchip, rде на форуме этот вопрос уже обсуждалея При чина столь не очевидноrо поведения проrраммы очевидна (коrда знаеть). Отладчик в цикле опроса ждет прохождения нескольких тысяч тактов BнyтpeHHero reHepaTopa, работаю щеrо на частоте в 420 мrц до заполнения реrистра, которое происходит с частотой примерно 1 О кrц. Вдобавок, настрой ки отладчика по умолчанию делают анимацию хорото воспри нимаемой (одно или два перемещения в секунду), но дождать ся нескольких тысяч таких перемещений лично у меня ума не хватило. Обработку команды я опять оформил в виде подпроrpаммы. ; Обработка команды  проверка адреса, определение команды. cmnd: BCF STATUS, Z MOVF RCREG, О XORLW Ох52 ; Проверим наш ли модуль R (52h). BTFSS STAТUS, z; Если нет вернемся. REТURN in1: BTFSS PIR1, RCIF ; Ждем прихода первоrо символа адреса. GOTO in1 ; Если совпадает, ПРОДОЛЖИМ. MOVF RCREG, О BCF STAТUS, Z XORWF Ох21, О Первый символ адреса в реrистре 21h. BTFSS STATUS, Z REТURN in2 : BTFSS PIR1, RCIF ; Ждем прихода BToporo символа адреса. GOТO in2 ; Если совпадает, продолжим. MOVF RCREG, О BCF STAТUS, Z XORWF Ох22, О ; Второй символ адреса в реrистре 22h. BTFSS STATUS, Z REТURN 
Схема и проrрамма релейноrо модуля 89 in3: BTFSS PIR1, RCIF ; Ждем прихода символа. GOТO in3 ; Если следом символ команды, продолжим . MOVF RCREG, О BCF STATUS, Z XORLW Ох24 ; Символ команды "$" (2 4h) . BTFSC STATUS, Z CALL swtch : Вызываем подпроrрамму выполнения. REТURN ; Подпроrpамма определения команды N (включить), F ( ВЫКЛЮЧИТЬ) ; или S (состояние). swtch: in4: CLRW BTFSS PIR1, RCIF GOТO in4 Ждем прихода символа. MOVF RCREG, О MOVWF Ох23 MOVLW ОхЗ О SUBWF Ох23, О MOVWF Ох23 ; Прочитаем номер реле. : Сохраним номер реле в реrистре 2Зh. ; Запишем реrистр 30h В аккумулятор. ; Переведем символ в номер. ; Сохраним номер реле в реrистре 2Зh. in5: BTFSS PIR1, RCIF ; Ждем прихода символа. GOTO in5 MOVF RCREG, О ; Разберем Nвключить, Fвыключить, S cTa'IYc. MOVWF Ох24 ; Сохраним команду в реrистре 24Ь. BCF STATUS, Z XORLW Ох4Е ; Включение N (4Eh). BTFSC STATUS, Z; Если нет, то пропустим. CALL cmdset MOVF Ох24, О ; Перепишем из 24h в аккумулятор. BCF STATUS, Z XORLW Ох46 ; Выключение F ( 4 бh) . BTFSC STATUS, Z; Если нет, то пропустим . CALL cmdreset MOVF Ох24, О ; Перепишем из 24h в аккумулятор. BCF STATUS, Z XORLW Ох53 ; S (53h) запрос статуса. BTFSC STATUS, Z; Если нет, то пропустим . CALL stat 
90 rпaBa. 1 Базовая версия : Сохраним состояние всех реле в энерrонезависимой памяти. ; Перепиmм реrистр 3Gh состояния реле в EEPROM. CLRW MOVLW ОхОО ; MOVWF EEADR ; ВCF STAТUS, RP1 ; BCF STAТUS, RPO CLRW ADDWF ОхЗО,О ; COМF Ох30,О ; BSF STAТUS, RPO ; BCF STAТUS, RP1 MOVWF EEDATA BSF STAТUS, RPO BCF STAТUS, RP1 ; BSF EECON1, WREN BCF INТCON, GIE; MOVLW Ох55 MOVWF EECON2 MOVLW ОхАА MOVWF EECON2 : BSF EECON1, WR ; BSF INТCON, GIE; ВCF EECON1, WREN Запишем Oh в аккумулятор. Запишем адрес Oh в реrистр адреса. Выбор банка о. Запишем содержимое ЗОh в аккумулятор. Инвертируем перед сохранением. Выбор банка 1. Выбор банка 1. ; Разрешить запись. Запретить прерывания. ; Записать 55h. Записать ААЬ. Установить флаr для начала запись. Разрешить прерывания. i Запретить запись. Запись 55h и AAh относятся к обязательным при работе с EEPROM. BCF STATUS, RPl; Выбор банка о. BCF STAТUS, RPO chkwr: BTFSS PIR1, GOТO chkwr CLRW ADDWF Ох30, О MOVWF PORTA ВCF PIRl, EEIF ; RE'IURN EEIF ; Проверка завершения записи. ; Перепишем ЗОh в порт. Сбросим флаr. в этом месте работы с отладчиком я вначале проверил выполнение двух команд подряд. Все работало. Затем я впи сал запись состояния реле в EEPROM с проверкой окончания 
Схема и проrрамма релейноrо модуля 91 записи. И, естественно, обнаружил, что вторая команда пере стала выполняться. Но теперь я быстрее сообразил, что запись занимает время, в течение KOToporo успевает пройти необра ботанная часть команды. Я не стал «rородить оrород», вставив между двумя нужными командами третью, ненужную. Хочу еще заметить, что изrотовитель микросхем советует осуще ствить проверку записи в EEPROM, которая вставляется пос ле проверки завертения записи. Я этоrо не сделал. Но после создания прототипа я MOry переделать проrрам удалив из слова команды символьное представление номера модуля и номера реле, MOry сделать и проrраммное задание адреса. T rда и добавлю проверку правильности записи в EEPROM. Тр. пOllпporpaMM.' ...поnнен.. команд ; Подпроrрамма включение реле по номеру. ; Запишем в реrистр 30h (установить соответствующий номеру реле бит) . aOCffiet: CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW ОхО ; Реле о. BTFSC STAТUS, Z BSF ОхЗО, О CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох1 ; Реле 1. BTFSC STAТUS, Z BSF Ох30, 1 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох2 ; Реле 2. BTFSC STATUS, Z BSF Ох30, 2 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох3 ; Реле 3. BTFSC STAТUS, Z 
92 rлава . 1 Базовая ве р сия BSF Ох30, 3 CLRW ADDWF Ох2 3 , О BCF STAТUS, Z XORLW Ох4 Реле 4. BTFSC STATUS, Z BSF Ох30, 4 CLRW ADDWF Ох23, О BCF STATUS, z- XORLW Ох5 . Реле 5. , BTFSC STAТUS, Z BSF Ох30, 5 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох6 ; Реле 6. BTFSC STATUS, Z BSF Ох30, 6 CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох7 ; Реле 7. BTFSC STAТUS, Z BSF Ох30, 7 REТURN ; Подпроrрамма выключения реле по номеру. ; Запишем в реrистр 30h (сбросить соответствующий номеру реле бит) . cmdreset : CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW АХА BTFSC STAТUS, BCF Ох30, О CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох1 BTFSC STAТUS, BCF ОхЗО, 1 Реле о. z Реле 1. Z 
Схема и проrрамма релейноrо модуля 93 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох2 ; Реле 2. BTFSC STATUS, Z BCF Ох30, 2 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох3 ; Реле 3. BTFSC STAТUS, Z BCF Ох30, 3 CLRW ADDWF Ох23, О ВCF STAТUS, Z XORLW Ох4 ; Реле 4. BTFSC STAТUS, Z BCF Ох30, 4 CLRW ADDWF Ох23, О BCF STATUS, Z XORLW Ох5 Реле 5. BTFSC STAТUS, Z BCF Ох30, 5 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох6 Реле 6. BTFSC STATUS, Z BCF Ох30, 6 CLRW ADDWF Ох23, О BCF STAТUS, Z XORLW Ох7 ; Реле 7. BTFSC STATUS, Z BCF Ох30, 7 RE'IURN ; Подпроrpамма передачи статуса реле stat: ВCF STAТUS, RPl ; Выбор банка о. ВCF STAТUS, RPO CLRW ; Проверим реле о. 
94 rлава . 1 Базовая ве р сия ADDWF Ох23, О BCF STAТUS, Z XORLW ОхО Реле о. BTFSC STATUS, Z CALL re10 CLRW Проверим реле 1. ADDWF Ох23, О BCF STATUS, Z XORLW Ох! Реле 1. BTFSC STAТUS, Z CALL re11 CLRW . Проверим реле 2. , ADDWF Ох23, О BCF STAТUS, Z XORLW Ох2 Реле 2. BTFSC STATUS, Z CALL re12 CLRW Проверим реле 3. ADDWF Ох23, О BCF STAТUS, Z XORLW Ох3 . Реле 3. , BTFSC STAТUS, Z CALL re13 CLRW ; Проверим реле 4. ADDWF Ох23, О BCF STAТUS, Z XORLW Ох4 ; Реле 4. BTFSC STAТUS, Z CALL re14 CLRW . Проверим реле 5. , ADDWF Ох23, О BCF STATUS, Z XORLW Ох5 . Реле 5. I BTFSC STAТUS, Z CALL re15 CLRW Про в ер им реле б. ADDWF Ох23, О BCF STATUS, Z XORLW Охб ; Реле 6. BTFSC STATUS, Z CALL rе1б CLRW ; Проверим реле 7. ADDWF Ох23, О 
Схема и проrрамма релейноrо модуля 95 BCF STAТUS, Z XORLW Ох? ; Реле ? BTFSC STAТUS, Z CALL re1? ; теперь это все отправим в передатчик BSF PORTB, О BCF STATUS, RPl BSF STAТUS, RPO BSF TXSTA, TXEN BCF STAТUS, RP1 BCF STATUS, RPO MOVLW Ох52 MOVWF TXREG BCF STAТUS, RPl BSF STAТUS, RPO outdatO: BTFSS TXSTA, TXIF GOТО outdatO ВCF STAТUS, RP1 BCF STAТUS, RPO CLRW ADDWF Ох21,0 MOVWF TXREG BCF STAТUS, RPl BSF STATUS, RPO outdatl: BTFSS TXSTA, TXIF GOТO outdat1 . ВCF STATUS, RPl ВCF STATUS, RPO CLRW ADDWF Ох22, О MOVWF TXREG ВCF STAТUS, RPl BSF STATUS, RPO Переключим драйвер RS485 на передачу. ; Выбор банка 1. ; Разрешаем передачу. Выбор банка о. Отправим символ модуля. ; Выбор банка 1. ; Ждем отправки символа. Выбор банка о. ; Отправим первый символ адреса. ; Выбор банка 1. ; Ждем отправки символа. ; Выбор банка о. ; Отправим второй символ адреса. ; Выбор банка 1. outdat2: BTFSS TXSTA, TXIF ; Ждем отправки символа.. GOТО outdat2 ВCF STATUS, RPl ; Выбор банка о. BCF STAТUS, RPO MOVLW Ох23 
96 rЛQва. 1 Базовая версия оutdаtЗ: BTFSS TXSTA, TXIF GOТO оutdаtЗ ВCF STAТUS, RPl BCF STATUS, RPO CLRW ADDWF Ох2З, О ADDLW ОхЗ О MOVWF TXREG BCF STATUS, RPl BSF STAТUS, RPO MOVWF TXREG BCF STAТUS, RPl BSF STAТUS, RPO outdat4: BTFSS TXSTA, GOТO outdat4 BCF STAТUS, RPl BCF STAТUS, RPO CLRW ADDWF Ох25,0 MOVWF ТXREG BCF STAТUS, RPl BSF STATUS, RPO outdat5: BTFSS TXSTA, GOТO outdat5 BCF TXSTA, TXEN ВCF STATUS, RPl BCF STAТUS, RPO BCF PORTB, О REIURN ; Отправим символ статуса. ; Выбор банка 1. ; Ждем отправки символа. ; Выбор банка о. ; Отправим символ номера реле. ; Выбор банка 1. TXIF ; Ждем отправки символа. ; Выбор банка о. ; Отправим символ статуса реле. ; Выбор банка 1. RCIF ; Ждем отправки символа. ; Запрещаем передачу. ; Выбор банка о. ; Переключим драйвер RS485 на прием. ; Подпроrpамма обработки статуса реле. relO: BTFSC ОхЗО, О CALL sostn BTFSS ОхЗО, О CALL sostf REIURN BTFSC ОхЗО, 1 CALL sostn BTFSS ОхЗО, 1 CALL sostf rell: 
re12: re13: re14: re15: re16: re17: REТURN BTFSC Ох30, 2 CALL sostn BTFSS Ох30, 2 CALL sostf REТURN BTFSC Ох30, 3 CALL sostn BTFSS ОхЗО, 3 CALL sostf REТURN BTFSC Ох30, 4 CALL sostn BTFSS Ох30, 4 CALL sostf REТURN BTFSC Ох30, 5 CALL sostn BTFSS ОхЗО, 5 CALL sostf REТURN BTFSC ОхЗО, 6 CALL sostn BTFSS ОхЗО, 6 CALL sostf REТURN BTFSC Ох30, 7 CALL sostn BTFSS ОхЗО, 7 CALL sostf REТURN Схема и проrрамма релейноrо модуля 97 ; Подпроrpаммы образования символов состояний. sostn: sostf: MOVLW Ох4Е MOVWF Ох25 REТURN MOVLW Ох46 MOVWF Ох25 REТURN ; Состояние  включено. ; Состояние  выключено. Если теперь соединить все представленные части про rpaMMbI, проrраммирование контроллера завершится. 
98 rлава. 1 Базовая версия Вставки и примечания, которые я привел выше, IIUЯВИ лись позже, при наладке модуля, но я ретил привести их «досрочно». Очень часто у меня не хватает терпения дочи тать что-то до конца, мне не терпится начать рабоry Я пред ставил, что подобной чертой характера MOry отличаться не только я, и привел все примечания на случай, если и вы уже начали работу за компьютером. Мне очень не хотелось, что бы вы полностью разочаровались во всем преждевременно. Мы написали проrрамму для контроллера. Постараемся ее проверить и отладить в проrрамме MPLAВ. Введение в ра60ТУ с MPLAB После заrрузки проrраммы появляется рабочее окно. Вид проrраммы обычен для Windows и, думаю, не требует особых пояснений. Мы создадим новый проект в основном меню Project. - New (Проект - Новый). Задаем название relay проекту в пап ке Rela которую я советую создать в основном разделе диска в папке MPLAВ. Неоднократно я сталкивалея с проблемой, которая t{e всеrда очевидна. Мноrие проrраммы, да это и удобно, предлаrают хранить проект в папке Мои документы. Проблемы не возникает, если вы пользуетесь анrлоязычной версией Windows или русскоязычной версией nporpaMMbI. Но мноrие специализированные анrлоязычные проrраммы начинают вытворять чудеса, если вы работаете в русскоязыч ной версии операционной системы. Впервые я столкнулся с этим, коrда одна из сред проrраммирования при компиляции проrраммы стала выдавать отибку в строке l. Что она име ла в виду под строкой с отрицательным номером, я не знаю. Но отыскать отибку в правильно написанной проrрамме OKa залось не так просто. Отибка крылась в том, что проrрамма, предлаrая сохранить проект в папке Мои документы, при компиляции эту папку распознать не моrла. После содания HOBoro проекта появляется окно навиrа тор проекта. Теперь выберем микросхему контроллера в раз деле OCHoBHoro меню Configure - Select Device (Конфиryра ция - Выбор устройства). Выбираем PIC16F628A (рис. 1.37). 
Введение" в работу с MPLAB 99 <:\  /.1  :'..'.. }-. '. -." '.-= . .:..... о.." . ."'. '-..' t-........,y....". '>С'" .:. .. ......"r( ":."''10;.'" .... - "".' ...... -'w":,,, ......;. .....-....":'...t...... ......:.::. ...... ."0:.." .-. . , ,.»#k. ::.:..:. "{.: '. ,"'. ..:"::4' ..:..:,(:,-:::.:'>. ...".'..' .. '. ' , . . . ,". . .::, Q :.{.} <;:<;: .. ,. .. \,.,.. f.:d.ftI: &1:..:. .:t::. еа:; .f:i:?!.;,t'.:,"" :'.i"".'''::.',,:.;'<;}'':.',:}':;<:''\:'."{+..:....',...t,..";.;'.;:,""9:','.:':':i"'.':.",'""i,'..".::,,'. .".,.,..,...... :;1...1.... . = nl8yAnCp . ....-.. НNd8r fIet :. .CIbIкt..... ; Uw.-у'1IS ; U'Nr  :. 0Iher..... .;...:. . ... ><t... . ALL ';"" .f...,c ' В:!= _. /. .< , ...,.,." .. ... ., .. \.""'.. ,.. . . ."  :......  .-:;.... :" -..(.: ./ ...,.. mtP-.---.,. ;. ." ". ":.-...:": :. ...::;.::._;:. Рис. 1.37. Рабочее окно nporpaMMbl MPLAB 3авертив выбор, следует создать файл основной'проrрам мы. Выбираем File - New (Файл - Новый). Появляется окно редактора. Сохраним файл под именем relay.asm (File - Save As (Файл - Сохранить как...». Добавим этот файл в проект. Для этоrо щелкнем правой кнопкой мыти раздел Source Files (Исходные файлы) в окне навиrатора. В открывтемся меню выберем Add Files (Добавить файлы) и укажем свой файл. Для начала перенесем в окно редактора небольтой фраr мент проrраммы: инициализацию, ожидание команды и две подпроrраммы: CALL adrsim и CALL cmnd. Последние подпроr раммы  в усеченном виде. В данный момент будем использо вать адрес модуля «01». Не забудьте поставить .END в конце проrраммы! adrsim: CLRW 31h). Если адрес 1 запишем символы "О" "1" (ЗОh и ADDLW ОхЗ О MOVWF Ох21 CLRW ADDLW ОхЗ1 MOVWF Ох22 MOVF Ох20, О 
1 00 rлава . 1 Базовая версия BCF STATUS, Z XORLW Ох1 BTFSC STATUS, Z REТURN cmnd: BCF STAТUS, Z MOVF RCREG, О XORLW Ох52 ; Проверим наш ли модуль R (52h). BTFSS STAТUS, z; Если нет, вернемся. REТURN BTFSS PIR1, RCIF ; Ждем прихода первоrо символа in1: адреса. GOТО in1 ; Если совпадает, MOVF RCREG, О BCF STAТUS, Z XORWF Ох21, О продолжим. ; Первый символ адреса в реrистре 21h. BTFSS STATUS, Z REТURN BTFSS PIR1, RCIF in2: адреса. GOТО in2 MO RCREG, О BCF STATUS, Z XORWF Ох22, О ; Ждем прихода BToporo символа Если совпадает, продолжим. ; Второй символ адреса в реrистре 22h. BTFSS STATUS, Z REТURN Для отладки откроем окно наблюдения View - Watch (Вид - Наблюдение), в котором выберем реrистры STATUS, WREG, PIR1,EEDATA,RCREG,20h,21h,22h, ЗОh.Необходимые реrистры открываются кнопкой с обозначением стрелки вниз, правее располаrается названия реrистра рядом с кноп кой ADD SFR (Добавить наблюдаемые). Ее следует щелкнуть после выбора реrистра (рис. 1.38). Реrистры без имени (20h, 21h и т. д.) мы добавляем, пр сто вводя адрес в колонку Address (Адрес) на новой строке. Добавим и EEPROM через выбор View - EEPROM (Вид .. EEPROM). Установим в качестве текущеrо симулятора пр rраммный (Debugger" Select Tool- MPLAВ SIM (Отладчик" Выбор средства - MPLAВ SIM». Создадим два файла input.txt 
Введение в работу с MPLAB 1 01 .:......,.!:...;...... . "." ..... .-:-. ......... :::. .,ж ;::,.::/:_ .fI ::.,.:::.,!:.. _....'-...-...,.,.'_._..,_...''..-..-..'.-," '.!;9.'J::;:I':[,';' ,..e''. ..-: 1;1: ':;'d'.'U'...,.тф'о:, :; - tl.:'!.lч :,.:!t. .......у".......:...:.......:....-. ......: .'. .... ." - __"-.-,.,, ;'i. ;"_>- ,-:., -. . ....,...... Ii .... -. ....... ..................... .::J. ..... ........... . . ..:. :..,.........-;." ." ........ .. ..=."::":. .'::'::'::.:.:.::.:...:::::..:;;;:.':;::'/-:-::?=:'=::.:::'::::::::;::--:-:;: ;.:.::..:Ч:{:;,:,:.::':,:'{:\"f..:::.:"::.:;>;":: :Й::;:::;:.\.:':':'::':;"::':::::;. ..:::::,,:::x:.:::::t.::.::;:.'::.j:::-:.}::.=:-::.:::::..5J:. . ur .......... -' ,:__.. _'_-" _ ш ..,. ,___.., , ""'''- I ... 1(1r.. о 8а "t.l.T1.-"8. : ... о.::.. о : ..oJt4rA C'.. ug.':a, .8rIL»8М..... . ".f'WII:. '2'h. 8Пss st.l.t\tS. I 8n11811 :А = '",Y:i::';;:':::';':'::'"""':',::':':J (:1 .. . "fSR-. r .. ,.,}  .--" ':;'-',:-у!I..} ,:' . 'INDf тus 0..00 INTCON G ОХОО -- OPТIONA(G РС1. PCl.ATH H 1;': \101'" PlR1 " ..... PORТА : ,;; . АаТА SPlRG STATUS Т1СОН Т2СОН ТМАО ТМА1 ТМА'''' TNR'L ТМА2 TRISA TRIS8 . ТXIIEG . ....... " ... щW.. 2*.. ". ТXSTA I :". ..*.._. c:..WR. .,:-::::""":.,:..,:-:,:,,,.....;":::..;';,:.;::.......:.:.:..w:-.x......,;."" ';.'_:';" ... :"";A';"" ' ::: ::., ",.,..-....-.'". .." ш, ..,.<.,,=..,,' ..:'..,:';:'_":':,',.",'."::,'.:'.:".:, :':'::,:::,:'-:, ;",..".>.,:,: - -;>::.::,'ll{е,'(iS,,;:  : ",..- j. <>O(.?,".,__;' .. .. ,.. Рис. 1.38. Окно наблюдения Watch и output.txt (File - New (Файл - Новый». В файле input.txt, K<r торый открывается в окне редактора, запишем слово команды RO 1 $ в виде строки в кавычках. Сохраним этот файл (File - Save (Файл - Сохранить». Теперь сделаем установки отладчика (Debugger - Settings... (Отладчик - Установки...) ): зададим ча стоту процессора 4 мrц, на вкладке Uartl 10 установим опцию Enable Uartl 10, укажем входной файл input.txt (browse) и BЫ ходнй output.txt. Подтвердим замену последнеrо файла и YCTa новим опцию Rewind Input. Изменим значение на вмадке AnimationjRealtime на 1 мс. Щелкнем Применить и ОК. Вклю- чим в окна View - Output (Вид - Вывод). Создадим новый сценарий, который позволит ввести адрес, имитируя пере ключатель. Для этоrо выберем в основном меню Debugger - Stimulus Controller - New Scenario (Отладчик - Управление симуляцией - Новый сценарий). Выберем вывод RВ4 в окне Pin/SFR (Вывод/Наблюдаемые). В окне Action (Действие) выберем Set High (Установить в высокое состояние). Щелк нем кнопку со стрелкой вправо в колонке Fire (Запустить). . 
1 02 rлава . 1 Базовая версия Сохраним сценарий ПОД именем relay и свернем ero (не закро- ем, а свернем!). Теперь откроем окно (Configure - Configuration Bits (Конфиrypация - Биты конфиrypации», rде установим биты, записываемые по адресу 2007Ь. Должно получиться слово 3FIAh. Закроем ЭТО окно (рис. 1.39). '" , ": .'" '". . "'" ". .. .... ...... "" ",' .... -.., ". .....:;..... '''''''- ".".",:. ,; .... . . ;.......... "';":' ,", :.. ..".. ". -. '". ". :... . .  ,.:'.'AF : ':.. ':,,; 1.JJ?'.Z:;:. .: ;i#;J { "..', :c:MX.: . .::.i; <1,Jt:';;:j:' : :-;. . ....,.......... .. .:...=::-'.C'.':i.':''.:::.'.............. "":- .:-:.....">: .:"...... { .  ... :  ',.". '.. .. : ..- ::, :' . ::': /.. : .: .ii{') JJ :щ ; .' '.  ф1 ,.::. .' ... 'W'($ ОС'" '." .............. ......"".:: 0000 ' rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... ......,..,:.. .&.. 0010 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... I .'. .', 0020 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... "::' 0030 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... 0040 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... 0050 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... 0060 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... 0070 rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr rr .... ."' с:."...... ,. ""0/,.,.,..,...,',.,::,'" .,.: . ..,'. .' .::: .,': :".,.,,:.,. .{:...."j...' :.,"" ...."..'" ,,:><-:" """...',".' :' ..:,w.*'.,";' ."'; ,,"'f '.:: '.".. 'и', . "L'' ." "''. &:;;u;;'i, .......... ........ ... 00Ii0nr, E f:::=; ; . ,,:','::"'. "/.. .{ 'о. o.\baaI<,.""'" !3 _.,' .' .:.... '.:.:: ::.;....:"""'''. ..'.._..).._" .-." о. ....;-...'. :. 00' O . ,.,::_ ..... ........ . "':.,.  . EETA ... ...  _::.._ .':..d$ . "'; ..... ,.,<.,:;.;...' Jk.i': 0003 SТAТIIS nlG ржа1 ЕОАТА 0х0020 0.0021 0.0022 ОХООЗО ;.'' ;.;':?<" . ооос OOVА 0020 0021 0022 0030 ,-:<'. .. 0.18 ОаОО ОаОО 0.00 ОаОО охоо 0.00 ОаОО 'i- :..(»:' . . ..,..0I!r. '. .".0.... .!i'"  '......"": .,.,...........'.,i"<f.':. .ш.,..'>( ......"..,>,.. "::'" """.' .::,,'<::>""': : ;:. .:".-::$.,,::.::::-f>Jи..=» .. :=';.'л: .':'.. ;.....:-. _X;.O-:_:::-.:...::-::::::.........:.:-::!...:.:;:.:::_ .- '.;' .' ....::..._ . A....._.-... Рис. 1.39. Установки наблюдения и отладки в завершение этих процедур упорядочим окна (Windows - Tde Horizontal1y (Окна - Расположить rоризонтально», coxpa ним все (File - Save All (Файл - Сохранить все» и добавим в проект файл todo.txt, который предварительно создадим и п<r местим в раздел Other Files (Дрyrие файлы) менеджера пр<r екта. В файле todo.txt будем вести план работы. Теперь откомпилируем проект Project - Build All (Пр<r ект - Компоновать все). Сохраним и вид проекта File - Save 
Введение в роботу с MPLAB 1 03 Workspace (Файл - Сохранить рабочую область). Мы rOToBb к отладке проrраммы. После выхода из nporpaMMbI MPLAB и подтверждения coxpa нения вида проекта, новой заrрузки проrраммы и открытия проекта (Project - Ореп (Проект - Открыть» мне приходит ся обнулять адрес Oh в ЕЕРАОМ, щелкать Fire (Запустить) в Sce"ario (Сценарий), и вводить адреса 20h, 21h и т.д. в окне Watch (Наблюдение), которые, как пишет проrрамма, Not Fou"d (Не найдены). Я не уверен, что дернул за все веревоч ки, но... пока ничеrо лучшеrо не получилось. Если вы правильно перенесли проrрамму, то, щелкнув на инструментальной панели кнопку запуска проrраммы, вы увидите анимацию, а в реrистре RCREG (приемный реrистр USART) появятся шестнадцатеричные коды символов из строки файла input.txt. Можно вписать в ячейку по адресу ОЬ EEPROM значение 1h и увидеть, как оно переписывается в реrистр 30Ь. Есть еще несколько полезных возможностей. Одна из них  проверить работу с определенноrо места. Для этоrо OCTaHO вим анимацию (кнопкой паузы на инструментальной панели), установим курсор в нужной строке и щелкнем правой кнопкой мыши. Выберем в раскрывающемся меню Set РС at Cursor (Установить счетчик команд к курсору). Теперь, щелкая зна чок Step I"to (Шаr внутрь) на инструментальной панели, мы можем отследить все изменения. в окончательном виде я работаю в среде, которая показа на на рис. 1.40. Кроме написания nporpaMMbI на ассемблере среда MPl.AВ поддерживает написание проrрамм на языке С. Существуют компиляторы разных производителей. Я использую дeMOHCT рационную версию кросскомпилятора Hi-Tech. Посмотрим, не будет ли проще написать проrрамму на языке С? 
104 rлава . 1 Базовая версия  ..11. .. .... ОС.....". ..... .. ..... .... ..............,/' ...":. ........... .. .-..... N .... .. ..,. ..... ...... .... .... ......,/' ." .". . ..... .. .."" . !! ... .  . _..: _ к ' ': . ....>.;,.Hi....::. ...:.::. .:. :::.......iy"*f?(;-;...-"f$...:.. - ;:." . :::" ...... о:;. :.::/". -:....: :: ....:,/'......:>. .. ..... .:::-: ": . -:.' .:: :. .")..' "", . ......... ..,,/' ." . .' ........... ")." ."!: . '. i":> -.-.-. :_ ;0.: __ -_ ,'. -':.: :ot... .. .,;.\:"':.: 1iI..... 0000 00 _ "" "rr " " " " " " """ " .. .. . . ,..,...... 0010 """""" " " " " " " " " " " ..... i" .reI8y..... I 0020 """"""",r"""""" " " . . .. . 1 НмdIr.... . 0030 """""""""""""""". . . . . , QItect.... 0040 """""""""""""""". . .. . ; u..,..... 0050 ',,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, .....  u.. 0060 """""""""""""""" ..... 1iI"" 00'70 """""""""""""""". . . . . .todD ьс . .... .." ;..}......... =-. ':" ..'-:::.-:::) ".:,: =:::..-;.. :;:. .. .;>:." ": . :";.:'.. . /. .;" / ........ , rPL'" . OIIIU- ....... " ':;--<' ,.',. :..... :::::.... . ".., .  .. '".... '.  ..::: : :::. . . . F= :;::=.J3::;:::;;;>;{t  j=::' ::........ ;t/<.;:i/..:: '';'<;J<: . . t AofUft 'ССР1СОМ '.' :.... .. t .:.-<;;;:' . . 0"0 -":. !.':-- ;:.:.;".;;./:-..:., ОООС ржаl 009А III>АТА 0020 Ох0О20 0021 ОХОО21 0022 OxOQZJ  Ох0О30 ',.:'.;;,,:: :,q,:;<: 1QМ .. .:.c"'A . ....:; . Охоо ОхОО 0..00 0.00 0.00 0.00 ' i: ":-': :':.:''":' ..;;;;......... -,. . ...-. w.,;""/,:': .. ::;)С::Э*t.tЮi,.  $!к ,,,....<-.<-,,.;,,.,.,,,.,,.,-.,,.-,'.',,,.. " ":-:'" у ..;.::--:--::.."..... ._::..:.:: c.....:.:::.:. :.'Y.._.:.:.::i:-::::..._.-:o::::::(..... -..:If« :": : ":..::......: ::"._;:::" ... Рис. 1.40. Окончательный вид окна проекта репейный MOAYnb, версия nporpaMMbl на яэыеe С Выбор языка проrраммирования происходит при задании в Project - Select Language Toolsuite (Проект - Выбор языко вых средств)  рис. 1.41. Кончно, компилятор Hi-Tech должен быть установлен соrласно инструкции. Создадим файл заrоловка и основной файл. Добавим в фай лы заrоловка нужный нам контроллер. Остальная часть рабо ты мало, чем отличается от работы на ассемблере. В этой Bep сии проrраммы я не сохраняю состояние реле в EEPROM Фа;;n 3anJlI08кa #define MODULNAМESIM "RIt #define CМDSIM "$" #define bitset{var,bitno) ((var) 1= 1 « (bitno» 
Релейный модуль, версия проrраммы на языке С 1 05 ...:/::(.;, ,'k.',...'.i:. !i't.. ":...:,;L.:....,i''..::;:: .... ,:'",'..'..' . "',: :"".",:: .....-- . .',. у ". --..., ......, ". ': "'":: ..,. ....: ,.,:-:-;<.,...: ..:::::.. ji... J t)::.::.j;:.,;i "'.;:" /d.'8... _:;;_ ._... t, .i'...):\ J._ ?;;}' ..;"':  ; :- :A' 'f' .... ...TEOtPlCtT..... , . .:. -.-..-....- _,О '"" ""', -"'IC\ .' . ",. ;. ::._." . .. : л. . .::". /....... :- У' I'ICC............. ... PICt..... рсс.... .. )...... .... .......:- :-;'",.." . .:_;-. :....... .;)0.;..:;......... ..:.."::::......../'. ._.,_.,__ ,....J.' -i_ "у-..,.;. ':: .< .-' .........-.. -- 'T--'"-J- ', :.::. :......:..:......... -..:..:.- ;.: :;.:..k"::o:.t;.' ,"{:,..;;"::;.:»,,:- -_::.. ;.' .,> ....>-:;>,. -". ... .....'Т.; --',. '......'4.......'.. ,"'. iiI"' ..5wot .... -..... .... ()bjod .... . .Uw-.y.... - 0d8 .... Рис. 1.41. Установка языка проrpaммирования С #define bitclr(var,bitno) ((var) &= (1 « (bitno») void putch(unsigned char)i unsigned char getch(void)i int initcomms ( ) ; int simnumadr(); int cmd(); int relon(int пит); int reloff(int пит); int relstat(int пит); OcIlO_IIO;; фаЙII #include <pic16f62xa.h> #include <stdio.h> #include .releyc.h. unsigned char inputi реrистра . unsigned char MODSIM1; unsigned char MODSIIO; unsigned char RELSIMi / / Считываем содержимое приемноrо / / Первый символ адреса модуля. / / Второй символ адреса модуля. // Символ реле. 
106 rлава . 1 Базовая версия unsigned char COММAND; int MODADDR; int sim1num = о; int sim2num = о: int simendnum = int MODNUМ; int RELNUМ: int RELSTAT = о: / / Символ команды. // Заданный адрес модуля, как число. о; // Полученный адрес модуля, как число. / / Номер реле. // Статус реле (позиционно): 1  вкл, О  выt:п. // Получение байта. unsigned char getch() { while(!RCIF) // Устанавливается, коrда реrистр не пуст. continue; return RCREG; } // Вывод одноrо байта. void putch(unsigned char byte) { PORTB = 1; TXEN =.1: while (!TXIF) continue: TXREG = byte; 1/ Переключим драйвер RS485 на передачу. // Разрешаем передачу. // Устанавливается, коrда реrистр пуст. } // Преобразуем символьный адрес в число. int simnumadr() { simendnum = о: sim1num = getch(); // Чтение первоrо символа номера. MODSIM1 = sim1num; / / Сохраним первый символ. sim2num = getch ( ) : / / Чтение BToporo символа номера. MODSIM2 = sim2num: / / Сохраним второй символ. sim1num = sim1num  Охзо: // От первоrо символа к числу. sim2...-.num = sim2num  Охзо; // От BToporo символа к числу. simendnum = sim1num*'"'xOA + sim2num; / /Объединим в одно число. return simendnum; } 
Релейный МОДУЛЬ, версия проrраммы на языке С 1 07 / / Получение и выполнение команды. int cmd() { input = getch(); RELNUМ'= input; RELSIM = RELNUМ; RELNUМ = RELNUМ  Охзо; switch (COММAND = getch()) { // Номер реле в символьном виде. // Номер реле в числовом виде. // Прочитаем команду. case "N": relon(RELNUМ}; / / Если команда включить. break; case "F": re1off(RELNUМ); // Если команда выключить. break; case "S": relstat(RELNUМ);// Если команда передать состояние. break; } } // Выполнение команды включения заданноrо реле. int relon(int пит) { bitset (RELSTAT, RELNUМ); // В RELSTAT побитовое состояние реле. PORTA = RELSTAT; //Установив бит, переписываем в порт А. } //Выполнение команды выключения заданноrо реле. int re1off(int пит) { bitc1r (RELSTAT, RELNUМ); PORTA = RELSTAT; // Сбросив бит, переписываем в порт А. } // Выполнение команды передачи состояния заданноrо реле int re1stat(int пит) { putch ( "R" ) ; putch (MODSIM1) ; рutсh(МОDSIМ2); putch( "#") ; putch (RELSIM) ; / / Отпрвляем символ R. / / Первый символ номера модуля. / / Второй символ номера модуля. // Символ статуса. // Символ номера реле. 
1 08 rлава . 1 Базовая версия if ((RELSTAT»RELNUМ)&Ox01) putch("N"); // Установлен ли бит? if (!((RELSTAT»RELNUМ)&OOl» putch("F"); // Сброшен ли бит? putch (ОхОА) ; } int initcomms () { PORTA = ОхО; CMCON = Ох?; TRISA = Ох80; TRISB = OxF6; RCSTA = Ох90; TXSTA = Ох4 i SPBRG = Ох16; INТCON=O; / / PORTB = о; } void main(void) { iпitсоП1II\? () ; 11 Только дпя вывода в файл! ! ! ! ! ! / / Инициализация модуля. // Настройка портов А и В. // Настройка приемника. // Настройка передатчика. // Настройка режима приемапередачи. Запретить прерывания. // Выключим передатчик драйвера RS485. / / Инициализация модуля. // Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. // Начинаем работать. start: input = getch(); whi1e (input ! = MODULNAМESIM) не нас. MODNUМ = simnumadr ( ) ; if (MODNUМ == MODADDR) { input = getch()i// Ждем, если //Чтение из сети (файла). / / Если наш адрес модуля. input = getch(); if (input == CМDSIM) cmd(); } goto start; } / / Если символ команды. Это не тедевр проrраммирования на языке С, но работа ет. В качестве входноrо файла КОl\:fанд я использовал input.txt 
Первая сборка на макетной плате 1 09 (примечания ниже только для книжноrо варианта, в файле их делать не следует) TaKoro вида: "noperat" Проверим, не будет ли мешать посторонняя команда "LОЗ$ЗN" Проверим, не отвечает ли модуль на обращение к друrим модулям "R11$2N" Проверим, не отвечает ли модуль на чужие адреса "RОЗ$2N" Включим второе реле третьеrо релейноrо модуля "R01$2S" Проверим, не отвечает ли модуль на чужие адреса "RОЗ$2S" Запросим состояние BToporo реле третьеrо релейноrо модуля "R15$lN" Проверим, не отвечает ли модуль на чужие адреса "RОЗ$lN" Включим первое реле TpeTbero релейноrо модуля "RОЗ$lS" Запросим состояние первоrо реле третьеrо релейноrо модуля "R03#lF" Проверим, не отвечает ли модуль на передачу состояния "RОЗ$lF" Выключим первое реле третьеrо релейноrо модуля "RОЗ$lS" Запросим состояние первоrо реле третьеrо релейноrо модуля "RОЗ$2S" Запросим состояние BToporo реле третьеrо релейноrо модуля Получаем выходной файл output.txt: RОЗ#2N RОЗ#lN RОЗ#lF RОЗ#2N Теперь, пока вы опробуете работу в среде MPLAВ, я, по жалуй, прерву работу над книrой. Поеду и куплю все необхо димое для сборки конвертора RS232RS485, проrрамматора и создания прототипа. Затем соберу прототип на макетной плате, а коrда закончу и проверю, поделюсь впечатлениями. Первая с60рка на макетной nnaтe Пришло время поделиться впечатлениями. Подсчитав свои финансовые возможности, я отказался от некоторых запланированных покупок и решил упростить проrрамматор, поскольку в настоящий момент собираюсь pa ботать только с контроллером PIC16F628A. Я убрал из схемы 
11 О rлово . 1 Базовая версия проrрамматора внешнее питание, из схемы адаптера к про rpaMMaTopy  все панельки, кроме 18ножечной, и использо вал батарейку «Крона» в качестве BHyтpeHHero источника питания (для высоковольтноrо режима проrраммирования). На макетной плате я тоже установил панельку ПОД микросхе- му, с тем, чтобы проверить все схемы на одной макетной плате. К схеме конвертера я добавил стабилизатор на 5 В. Кабель от разъема DB9 конвертера RS232RS485 я распаял на плате конвертера, хотя вначале собирался использовать разъем. После исправления нескольких монтажных ошибок (и эти «rрабли» имели место) я ретил проверить проrрамматор, поскольку не в полной мере был уверен, что правильно pa зобрался со схемой. С проrраммой MPLAВ проrрамматор, естественно, не pa ботает. В Интернете- есть схемы проrрамматоров, работаю щих с MPLAВ. Они не настолько сложны, чтобы их не исполь зовать, но я ретил, что лучте воспользоваться проrраммой PonyProg2000, схему проrрамматора к которой собрал. При ходится скачивать последнюю версию проrраммы, поскольку в предыдущей нет контроллера PIC16F628A.   _:-')"':::'V='''-''''''''7-'''-:'<';' .I'o . ...-:..:=.;...--.;н:---.....;,,;., "'.'.": .:.:" ...>  ......"..;=-... ..".., ....,. :... -;.::. '" '. .' Q '. .'  2  ...'." :. . "} . ..:.... ":"'..8 . . ." . .................:: .... :.. . ...:.... ........ ... .. ........ ,' .." . ';., .:AC..'};;'.':<. ':.:."  ...  . . ..1 ," "" .....: .......1""""".,...,....,......,..,....., .... ,.. y...,.. N' .':;: "'. ".' '1",.."и,;...w.q. ...,. ;"",:,,,':';'., , ';"'''''"'''':''14:'''';  . : . t . ;. .  . " . :< . ' . ': .  . .  . . . = . . . . . : . ' . : . ' . . . %; ... .. . }". .. .""" . :.*i8 о( . ..... . . . . ", :« . ....... ...................t..-.:.....,;;.:./::." ......f..:.{"':!::;.':...y ::-: :., ;:..-. '.": ,.,,#о,/,,ф" j i t ;Ef::: : .:. . "-". . '.\:;".oмWlIмt .. C", . !):,,: :;!I"::?.", .. :.e()98' 1) \'.д)f : ,; .. ,. ". .л....:... . :" ...:...  )-: ...:; /7 .: .#;... . ." . . . '' : '. "" " . ..... .,. -."",".. ". .... . 'i.; 1.;' <:Ж::'''  . Рис. 1.42. Проrpaмма PonyProg2000 
Первая сборка на макетной плате 111 Первое, что я делаю после запуска проrраммы  выбираю устройство в меню Device - Pic 16 micro (Устройство - Pic 16 micro) или в окотках на панели. После выбора устройства проверяю работу порта в меню Setup (Interface Setup... (Yc тановки интерфейса), используя СОМ2порт), задаю номер порта и SI Prog 1/0. После щечка кнопки Probe (Проба) я получаю сообщение  Test Ok. Затем провожу калибровку (меню Setup - Calibration (Установки - Калибровка») и опять получаю одобрение. На этом везение заканчивается. Вставляю микросхему в панельку, и первое, на что отважи ваюсь  щелкаю кнопку чтения Read Device (Прочитать устрой ство) на инструментальной панели. Итоr показан на рис. 1.43.  I!f.:./' :0'.'" о.. '00 :i.' :.o/>;-'(: «:' ;'i:,ч:::,.?оt.'.ОО  !' : <or.";t2! , J\;::;,:.'o ..>... ,oJo'f;il ;:. .. - . . ........ .   Рис. 1.43. Первое сообщение nporpaMMbl PonyProg2000 Проrрамма не распознает микросхе Обращаюсь на сайт, с KOToporo «срисовал» проrрам В разделе типовых вопро сов И ответов нахожу похожую ситуацию и рекомендацию воспользоваться кнопкой Ignore (Иrнорировать). Что и ocy ществляю. Процесс проходит успетно, о чем сообщает проrрамма, но в буфере сплотные едu'Н,uуъt, а у меня сплотные сомнения  прочитал ли я хоть чтото? Я отключаю разъем от СОМпор та, получаю сообщение об успешном чтении, но в буфере одни 'Н,улu, а тест порта не проходит. Появляется надежда, что я чтто читаю. Вторая волна сомнений касается вопроса: работает ли микросхема, если я не записал биты конфиryрации, опреде ляющие режим работы TaKToBoro reHepaTopa контроллера, ведь я еще ничеrо не записывал. Поэтому ретаюсь записать биты конфиryрации, выбрав режим работы TaKToBoro reHe ратора INTRC (сэкономил, отказавшись от покупки кварца). В меню Command - Security and Configuration Bits... 
112 rлаво . 1 Базовая версия (Команда - Биты конфиryрации и защиты) устанавливаю флажки (рис. 1.44). r, .ur...n.M" Ьh$,;:'i;i''''''''''';4-<.:(::''':>' ,''''':" - \.._-""' :. "- <- ':'<0--."- «'" - .. ........ J'I' .{...Х". . :'.r'_':;::;'-;':[j,::;';:;J(;;::;ti:.:i:::';: ;:::::i-::-':-::::-\;':::::,;: : :.::.... -:'')t:I:;';:::'':_":''''-{(jJР:IQi1-:;ri:-, .-,"."," ':-_'..... .n ',,_ ъ t!}'  : ,:-< ',..- - .. - - -!1;'::;;!> ..$'......:)- t:-: ;:.:'f IР-А:( .f'МIj:,;I _.. "-:.')::-.:". :: .-:-: :.:-:...j.;. .. - __о ... Рис. 1.44. Задание слова конфиryрации микроконтроллера Сознаюсь, что, не разrлядев, как устанавливаются биты, я cдe лал все наоборот  поставил rалочки там, rде должны быть нули. Я полаrал, что, отметив биты, установлю их в единицу, а в результате закрыл все проrраммирование. Пришлось испра вить свою ошибку. Биты конфиrypации записались, я сбрасываю их и читаю. Появляется надежда, что вопрос с проrраммированием p шен. Но первые «мяrкие» rрабли, на которые я наступаю  пр rpaMMa ведет себя не так, как я от нее ожидаю. Я заrружаю в проrрамматор файл, созданный по версии, написанной на языке с. В итоrе, я MOry записать в контроллер все нули или все единицы. Но стоит м.не попытаться изменить в буфере хотя бы один байт, используя возможность редактирования в меню Edit - Edit Buffer enabled (Редактирование - Буфер редактирования доступен), чтобы записать чтото дрyrое, как контроллер полностью обнуляется. С этой проблемой я долrо не MOry разобраться, поскольку не понимаю, вина ли это пр rpaMMbI, или я чтото делаю не так. Я работаю с проrраммой впервые и, судя по ошибке с установкой бит конфиrypации, MOry сделать множество ошибок. Конечно, все попытки обой ти проблему успехом не увенчались. Устав от проб и ошибок, я решаю изменить подход  если я не CMOry запроrраммировать контроллер, то сама микросхема, 
Первая сборка на макетной плате 11 3 которую я так береry, мне будет не нужна. Либо я CMOry ее за проrраммировать, либо выброшу сраз Я ретаюсь сделать попытку проrраммировать ее как мик росхему друrоrо типа. Удачной оказывается попытка про rраммирования РIСlБХ84. И я решаю, что имнно так я буду ее проrраммировать, а биты конфиryрации запишу под эrи дой PIC16F628. Это неудобно, но не покупать же дороrой пр rpaMMaTop! Итак, я MOry записать в микросхему чтото кроме нулей и единиц. Я заrружаю НЕХфайл, созданный проrраммой, написан ной на языке С, используя на инструментальной панели кноп ку Read Program Memory (FLASH) (Прочитать память про rpaMMbI) . Вторые «мяrкие» rрабли выrлядят так  вся проrрамма не занимает и двух строк в буфере. Я в это не верю. Поскольку файл имеет растирение НЕХ, я пытаюсь просмотреть ero HEXpeдaKTopOM и не вижу ничеrо, кроме символьной запи си. Тоrда я открываю файл блокнотом: :10000000830100308A0004282030840038300D201D :100010008301392B04068001840A0406031D0A2883 :020020000034АА :1004Е20083018С1Е712А1А0808008301В700831247 :1004F20003130СIЕ782АЗ70899000800F401F5014D :100502000310F30CF20C031C8D2A7008F407710817 :100512000318710AF5070310FOODF10D7208730448 :1005220003190034812А8301850107309FО0831б55 :100532008501FE30860090308312980006308316C3 :100542009800683099008312061083169B011C14DO и Т. д. Признаться, не ожидал. Пришлось yrлубиться в PYKOBOД ства и понять, что этот файл предназначен для заrрузки в проrрамматор и формат файла имеет вид: : ВВААААТТННН... ННСС [де вв  количество байт в строке файла, АААА  адрес за писи данных, ТТ .... указатель типа строки (00  данные, 01  конец файла, 02  адрес cerMeHTa, 04  линейный адрес), ННН...НН  собственно данные, а ее  контрольная сумма строки. 
114 rЛQва . 1 Базовая версия и данных в файле, конечно, больте, чем я получаю в бу фере. В чем причина? После Toro как я понял, что после пер вых строк идет безусловный переход по адресу, находящему ся в ко'нце проrраммной области, а первый адрес после перехода лежит вне буфера, стало понятно, почему я не по лучил в буфере ничеrо интересноrо. Первой приходит мысль исправить адреса в файле НЕХ. Но это потребует изменения контрольных сумм, которые придется либо рассчитывать на калькуляторе, либо писать проrрамму пересчета. Сущность же проблемы состоит либо в том, что файл подrотовлен под заrрузку в проrрамматор, работающий с MPLAВ, ибо в том, что срок действия дeMOH страционной версии компилятора языка С закончился. В размышлениях  купить компилятор (какимто образом) или найти знакомых, работающих с микроконтроллерами и «напроситься В rости», чтобы поработать некоторое время на чужом компьютере (меня эти походы изрядно «притомили»), Я ретаю поступить иначе. Делаю последнюю попытку  компилирую проrрамму в MPLAВ J:UIЯ микросхемы PIC16F627A, которая имеет объем памяти проrраммы вдвое меньше, чем моя PIC16F628A. Теперь, заrружая НЕХфайл в проrрамму PonyProg2000, Я вижу больше пары строк в буфере. Записываю этот файл (ДЛЯ микросхемы PIC16X84), используя кнопку Write Program Memory (FLASH) (Записать память проrраммы). Записываю биты конфиrypации (для микросхемы PIC16F628). Проверяю в меню Command - Verify All (Команда" Проверить все) и получаю подтверждение правильности записи, затем перено ту микросхему на макетную плату, rде собран интерфейс и установлены светодиоды. С этоrо момента опять начинаются «железные» rрабли. Ничеrо у меня, естественно, не работает. Первое, что следует сделать,  определиться, что у меня работает, а что нет. Уверен ли я, что проrрамматор у работа ет? Нет. Уверен ли я, что проrрамма написана правильно? Нет. И т.д. Я понимаю, что «нет»  это самое определенное, что я получил к настоящему моменту. 
Первая сборка на макетной плате 11 5 Тоrда я решаю последовательно удалять эти «нет». В Ин тернете нахожу пример проrраммирования на языке С для микроконтроллеров PIC  простая проrрамма, которая за ставляет светодиод миrать. #inc1ude "pic16f62xa.h" #define bitset(var,bitno) ((var) 1= 1 « (bitno» #efine bitclr(var,bitno) ((var) &= (1 « (bitno») main () { unsigned int k; CMCON = Ох07; TRISA = 0Ь11111110; repeat: for (k=O; k<45000; задержки. bitset(PORTA, О); for (k=O; k<45000; bitclr(PORTA, О); goto repeat; } //Компараторы выключены. / / RAO выход. k++); //"Пустой" цикл для временной //Выставить на RAO высокий уровень. k++); / /Выставить на RAO низкий уровень. //ПОБТОРИТЬ ещё раз. я компилирую ее и проrраммирую микросхему. После YCTa новки на макетную плату и включения питающеrо напряжения я получаю первое «да». Светодиод миrает. По меньтей мере, проrрамматор работает. Теперь я хочу проверить работу конвертера RS232RS485. Удобнее Bcero было бы использовать осциллоrраф. Но у меня нет ничеrо кроме мультиметра с набором обычных функций измерения напряжения, тока, с.опротивления. Коечто я, все--таки, проверить MOry. Для этоrо мне потре буется проrрамма работы с СОМпортом. Можно написать на любом из языков проrраммирования то, что работало бы с СОМпортом. Но это займет время (позже это приходится сделать). Нахожу вИнтернете проrрамму ПОД названием RS232Pro, в которой я CMOry 25 дней поработать бесплатно. Есть, правда, предложение зареrистрировать проrрамму, но сайт, rде предлаrается ее зареrистрировать, отсутствует. Дy маю, 25 дней  это срок, коrда я либо получу положительные результаты, либо откажусь от Bcero. 
116 rлаВQ . 1 Базовая версия Проверяю, включив мультиметр, на измерение постоянн ro напряжения на пределе 20 В входные напряжения от СОМпорта. Некоторое время уходит на то, чтобы понять, что нужно щелкать кнопку RTS OFF в проrрамме RS232Pro, но, наконец, я деаю и этот решительный mar. Затем отправ ляю в порт последовательность символов 12345, и вижу, что у меня меняется напряжение на выводе TXD. Меньте, но Me няется напряжение на выводе 3 микросхемы МAX1483. XOTe лось бы проверить линию RS485. для этой цели я пытаюсь передать простой текстовый файл с помощью проrpаммы RS232Pro, встав мультиметром на линию (в режиме измерения постоянноrо напряжения на пределе 20 В). Напряжение заметно меняется. Это убеждает меня, что конвертер, может быть, и не совсем правильно, но работает. Порт цмодуль я настраиваю на скорость 9600,8 бит дaH ных, 1 стоповый бит без бита четности. Первым делом, я упрощаю проrрамму релейноrо модуля, оставив только один символ R на прием, который сразу зажиrает светодиод. Mo дуль не работает, но обращение к документации на микросхе му контроллера PIC16F628A заставляет меня задуматься в правильности выбора скорости. Я проверяю, меняя значение реrистра SPBRG, разные скорости (соответственно, каждый раз перепроrраммируя контроллер), пока не зажиrается CB тодиод. Скорость оказывается равной 2400 (я даже не уверен, что ее не следует снизить до 1200). Модуль начинает реаrиро вать на команды, передаваемые с компьютера. В данный момент мне кажется, что дальте все образуется само собой, и модуль заработает. Но получается не совсем так. He даже удается получить ответ от модуля на запрос о co стоянии реле. Ответ HeMHoro странный, но, хотя бы какой то, он есть. Теперь беда дрyrая. Одно выполнение команды, один ответ на запрос о состоянии реле. и модуль «виснет». Он не реаrирует больше на команды до момента вклю-чения пос ле сброса питания. Я человек терпеливый, но и мое терпение истощается по мере продвижения к выполнению поставленной задачи. rлавная 
Первая сборка на макетной плате 117 беда  я не уверен, что проrрамма RS232Pro ПОДХОДИТ для pa боты. По этой причине отправляюсь к знакомым. чтобы Ha писать проrраммку для работы с модулем. Думаю, я так Haдo ел им, что они дарят мне старенькую версию Visua] Basic (не совсем полную), которую KTOTO из них получил на презента ции во время одной из конференций. Мне важно, что версия работает. Итак, я создаю заrотовку для среды проrраммирования (о чем речь пойдет в конце этой части книrи), куда добавляю три кнопки: одну  для отправки команд, дрyryю  для полу чения команд и последнюю  для Toro, чтобы полученные команды отобразить. Используя оба варианта работы с СОМпортом, я посте пенно начинаю понимать, что после получения команды зап роса состояния реле модуль начинает передавать ответ, но одновременно читает все, что есть на линии RS485. Прочи тав же обращение к релейному модулю. свой номер модуля, он пытается реаrировать на эти события. то естъ, при передаче .модулем в сетъ 'Ка'Кuхлuбо да1t1tыlx 1tуж1tо датъ время 1ta передачу  это во-первыl,' u от'КЛ1ОЧuтъ на время переда'Чu приемник  это во- вторых. Не с первоrо раза получилась и запись состояния реле в EEPROM  скоро сказка сказывается, да не скоро дело дела ется. Вот такие впечатления, которыми я обещал поделиться, остались у меня после посещения маrазина и попытки пре творить в жизнь компьютерную версию разработанноrо MO дуля. Коrда я написал, что отправляюсь в маrазин, и поделюсь впечатлениями, я и сам не ожидал, что впечатлений будет так MHoro. Конечно, отсутствие опыта, не совсем подходящие средства разработки, разница между тем, что нарисовано на бумаrе, и тем, что будет создано на основе этоrо рисунка  все так, но... Я не ожидал, что столько «rраблей» окажется на пyrи реализации достаточно простой конструкции. Однако продолжим создание запланированных модулей. 
118 rлова . 1 Базовая версия Схема и nporpaMMa модуnя приема ИК-команд Первый вопрос  зачем нам нужно чтолибо, имеющее OTH шение к инфракрасным кодам? Домашняя аппаратура  телевизоры, музыкальные цeHT ры и т.п.  управляется с помощью пультов дистанционноrо управления, излучающих команды в ИКдиапазоне Чтобы управлять аппаратурой с компьютера (проrраммно), нам п требуется излучатель ИКкодов  модуль, который по KOMaH де компьютера будет излучать необходимые ИКкоманды. Для работы этоrо модуля нам потребуется еще и считыватель ИКкодов. Кроме Toro, пора подумать об устройствах управ ления в системе, причем хотелось бы иметь нечто достаточ но дешевое. Одним из устройств управления, как мы ретили, станет компьютер. Можно подумать о создании устройства управле ния с использованием клавиатуры: нажатие клавити отправ ляет в системную сеть команду управления. Но и у омпьютера, и у клавитноrо модуля есть небольшой недостаток: их удобно держать на стене или на столе, но не на кресле, rде мы проводим достаточно MHoro времени. Воп рос о клавишном модуле управления пока отложим и paCCMOT рим возможность управления с помощью CTaporo пульта от видеомаrнитофона или телевизора, которые давно отправи лись бы на свалку, если бы не завалялись на полке. В этом слу чае нам нужен модуль приема инфракрасных кодов. Что собой представляют инфракрасные коды, излучаемые пультами управления? Не вдаваясь в теоретические тонкости, можно CKaaTЬ так: коrда на пульте управления, положим, телевизором нажима ется клавита, установленный в нем светодиод (ИКдиапазо- на) начинает миrать. При этом он воспроизводит последова тельность вспышек с некоторой частотой (от 20 до 400 кrц) и пауз, которые в совокурности и есть код управления. Каж - дая клавиша имеет свой набор вспытек и пауз. Клавити раз ных пультов излучают разные коды управления, частота 
Схема и проrрамма модуля приема ИК-команд 119 (несущая частота) вспытек также может различаться. В кач стве примера приведу структуру кодов управления фирмы Sony: Technica1 Info Code 1ength (длина кода): 12 bits (15 bits для некоторых функций видеокамеры) Carrier (несущая): 40kНz ++ Header (Заrоловок): + ++ . . 4T Т ++ 1 кодируется: + ++ . . 2T Т ++ О кодируется: 1 . . 1 + ++ TT т = 550us при6лизительно Пауза между данными: 25ms data: hhhhxxxxxxyyyyy л л MSB LSB хххххх command (команда) уууууу address (номер аппарата) Таким образом, сначала идет заrоловок длиной в 2,75 мс (инфракрасный свет миrает с частотой 40 кrц), затем пауза в 0,55 мс и код, В качестве KOToporo для простоты рассмотрим последовательность 1001. Он будет соответствовать вспышке в 1,1 мс, паузе в 0,55 мс, вспышке в 0,55 мс, паузе в 0,55 мс, вспытке в 0,55 мс, паузе в 0,55 мс, вспышке в 1,1 мс, паузе в 0,55 мс, паузе в 25 мс. Уф! Как будyr выrлядеть коды дрyrих производителей? Скорее Bcero, иначе. Есть несколько рекомендаций по применению 
120 rЛОВQ . 1 Базовая версия ИК"КОДОВ, а производители вольны придерживаться их или нет. Кодирование лоrической единицы может производиться переходом (фронтом) от паузы к вспытке, лоrическоrо нуля обратным переходом. 3аrоловок может oTcyrcTBoBaTb и т.д. Мноrие универсальные пульты управления, запоминаю ЩИе ИКкоды, фиксируют длительность посылок и пауз, ждут длинной паузы между посылками, означающей завершение команды, а затем сохраняют значения в формате собственн ro времени, которое зависит от тактовой частоты синхроrе нератора. Если при воспроизведении кода они MOryr менять несущую частоту, то записывают служебную информацию, ее определяющую. Как и в предыдущем проекте, вначале приведу схему (рис. 1.45) и проrрамму. В табл. 1.4 перечислены все необходимые элементы Таблица 1.4. Спецификация модуля приема инфракрасныx кодов Н2 Об03на Изделие Количество Цена Примечания чение (р.) 1 ОО1 МАХ1483 1 96 2 ОО2 PIC16F628A 1 100 Установить на панельку 3 ОО3 LM2936Z5 1 68 4 ОО4 TSOP17 (16) 1 10 5 VD1 дЛЗ07 1 3 7 А1 1 кОм 0,25 1 1 8 А2 12 кОм 0,25 8т 1 1 9 А3 100 Ом 0,25 8т 1 1 10 A4A7 10 кОм 0,25 8т 4 4 11 С 1, С2 0,1 мкФ 2 6 12 С3 100,0 мкФ 16 8 1 5 13 С4 4,7 мкФ 58 1 3 14 Х1 Клеммник 4 к 1 3 15 81 Перекл. 2 пол., 4 н 1 5 16 80cket DIP18 1 21 Панелька Для обращения к модулю с запросом принята новая ИК команда  Cxx$OS (аналоrично команде запроса статуса релей Horo модуля). 
Схема и проrрамма МОДУЛЯ приема ИК"команд 121 tD C\I ,...  + ,... ..... м  ,... m О ,...  Q. О О VJ  t--- х 1i :I: (,) М C\I са о- сп rrтr1  са о- -е- :I: s са  ф s о- с о::   il)ф""  () tDtDtDtD на:а:а:а:  са  ф  о:: са :I: .о ,... Ln О ,...C\lM  S ,... ,... ,... ,... ,... с « s ::r со :I:  C\I S ,... CD о- u. t: Ф Lt) ari C\I ,... О ()  о а:: ,... ,... со ф u s Н а. ,... ,...  м () м со со  ,... ,...  Lt) '0 о  ,... C\I ,... Х 
122 rлава . 1 Базовая версия Ответ модуля  Cxxkkk, если команда пришла, и Схх# f f, если новая ИКкоманда не приходила. Здесь ХХ, как и ранее,  двухбайтовый адрес модуля, kkk  три байта символов номера команды от 001 до 255, ff под тверждает отcyrствие изменений за время опроса. Проrрамма MOДYIIR приема ИК-команд на Rэь.ке С Фаiin эаronО8ка #define MODULNAМESIM "С" #define CМDSIM "$" void putch(unsigned char); unsigned char getch(void); int ini tcomms ( ) ; int simnumadr(); int cmd(); Фаiin проrра..ъ, #include <pic16f62xa.h> #inc1ude <stdio.h> #inc1ude "irrecfn1.h" unsigned char input; реrистра. unsigned char MODSIM1; unsigned char MODSIM2; unsigned char IRSIM1i unsigned char IRSIM2; unsigned char IRSIМЗ; unsigned char commandreciev [6]; //. Массив для полученной команды. int РНОТОСОМЕ = о; // Флаr активности фотоприемника. int MODADDR; / / Заданный адрес модуля, как число. unsigned char IRCOММAND = о; int MODADDR; / / Заданный адрес модуля, как число. int sim1num = о; int sim2num = о; int simendnum = о; int MODNUМ; int i; // Считываем содержимое приемноrо / / Первый символ адреса модуля. / / Второй символ адреса модуля. / / Полученный адрес модуля, как число. 
Схема и проrрамма МОДУЛЯ приема ИК"команд 1 23 int k; int 1; int т; unsigned char getch() { whi1е((!RСIF)&(RВЗ  1)) // Устанавливается, коrда реrистр не пуст. continue; return RCREG; } void putch (unsigned char byte) { // Вывод одноrо байта whi1e(!TXIF) // Устанавливается, коrда реrистр пуст. continue; TXREG = byte; } int ini tсопuns ( ) / / Инициализация модуля. { PORTA = ОхОО; CMCON = Ох?; // Настройка портов А и В. TRISA = ОхОО; TRISB = OxFE; PCON = Ох8; / / Тактовая частота 4 мrц. RCSTA = ОЫО010000; // Настройка приемника. TXSTA = ОЬОООО0110; // Настройка передатчика. SPBRG = Охб8; // Настройка режима приемапередачи. INTCON = ОхО; / / Запретить прерывания. RВO = ОхО; // Выключим передатчик драйвера RS485. PIE1 = ОхО; / / Настройка таймера 1, запрет прерывания. T1CON = ОхО; // Выбор BнyтpeHHero reHepaTopa, бит 1 в ноль. ТМRH = ОхОО; ТМR1L = ОхОО; IRCOММAND = ОхО; / / Определим номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. } // Преобразуем символьный адрес в число. int simnumadr() 
124 rлава . 1 Базовая версия { simendnum = Охо; MODSIMl = commandreciev [1]; // Первый символ номера. MODSIM2 = commandreciev [2]; // Второй символ номера. MODSIM1 = MODSIM1  Охзо; MODSIM2 = MODSIM2  Охзо; simendnum = MODSIM1*OxOA + MODSIM2; return simendnum; } int ircmd () { int Ь = о; CREN = о; whi1e (RB3 == о) continue; // Ждем окончания заrоловка. for (ь=о; Ь<8; Ь++) //Обработаем наши импульсы. { while (RB3 != о) continue; / / Дождемся импульса. time (); / / Включаем таймер 1. whi1e (!ТМR1IF); / / Дождемся такта. T1CON = Охо; / / Выключаем таймер. ТМR1IF = Охо; // Сбросим флаr. if (RB3 == о) // Если низкий уровень, то "1". { IRCOММAND = IRCOММAND +1; / / Запишем это. time (); // Включаем таймер 1. whi1e (! ТМR1IF) ; / / Дождемся такта. T1CON = ОхО; / / Выключаем таймер. ТМR1IF = Охо; // Сбросим флаr. } e1se // Высокий уровень, значит "о". { IRCOММAND = IRCOММAND; // Запишем это. } if (Ь<7) IRCOММAND = 1 RCOММAND< < 1 ; / /Сместимся влево на бит. } РНОТОСОМЕ = ОхО; МО = ОхО; М1=Ох1; for (т=О; т<4; ++т) { 
Схема и проrрамма модуля приема ИК"команд 125 for (1=0; 1<10000; ++1); } CREN = 1; Мl = о; } int cmd ( ) { CREN = 1; inpиt = getch(); switch (input) { case "С": // Если обращение к фото модулю. for (i=l; i<б; ++i) // Запишем команду в массив. { input = getch(); commandreciev [i] = input; } MODNUМ = simnumadr ( ) ; / / Чтение из сети. if (MODNUМ ! = MODADDR) break; / / Если не наш адрес. e1se if (commandreciev [3] = "$") // Если команда. { if (commandreciev [5] = "5.) irstat(); } defaи1t: break; } } void time () { / / Таймер 1 для чтения ИК. ТМR1H = OxFD; переполнения. ТМR1L = Ох43; T1CON = Охl; / / Установка числа циклов до / / FFFF минус 700 (2ВСЬ). / / Включение таймера. } int irstat ( ) { int ircom; int ircoml; int ircom2; int ircom3; 
126 rnaBa . 1 Базовая версия cornmandreciev[O] = "С"; cornmandreciev[l] = MODSIM1+0x30; commandreciev[2] = MODSIM2+0x30; ircom = IRCOММAND; // Преобразуем команду в символы. ircoml = ircom/Ox64; IRSIMl = ircom1 + Ох30; ircornQ = (ircom  ircoml*Ox64)/OxA; IRSIM2 = ircom2 + ОхЗQ; irсоmЗ = (ircom  ircoml*Ox64  ircom2*OxA); IRSIM3 = ircom3 + Ох30; if (IRCOММAND == О) { commandreciev[3] = "#"; cornmandreciev[4] = "f"; cornmandreciev[5] = "f"; CREN =ОхО; / / Запрещаем прием. RBO = Ох1; //Переключим драйвер RS485 на передачу. TXEN = Ох1; // Разрешаем передачу. for (i=O; i<6; ++i) putch(commandreciev[i]); for (i=0;i<1000;i++); // Задержка для вывода. for (i=O; i<6; ++i) commandreciev [i] = " "; RBO = ОхО; // Выключаем драйвер RS485 на передачу. TXEN = ОхО; / 1 Запрещаем передачу. CREN =Охl; / /Разрешаем прием. } else команда. { соrnmandrесiеv[З] cornmandreciev[4] cornmandreciev[5] / / За время между двумя запросами пришла ИК = IRSIM1; = IRSIM2; = IRSIM3: CREN =ОхО; /1 Запрещаем прием. RBO = Ох1; //Переключим драйвер RS485 на передачу. TXEN = Ох1; / / Разрешаем передачу for (i=O; i<6; ++i) putch(commandreciev[i]); for (i=0;i<1000;i++); /1 Задержка для вывода. for (i=O; i<6; ++i) commandreciev [i] = " n; RBO = ОхО; / / Выключаем драйвер RS485 на передачу. TXEN = ОхО; / / Запрещаем передачу. 
Схема и проrрамма модуля приема ИК"команд 127 CREN =Ох1; /1 Разрешаем прием. } IRCOММAND = ОхО; / / мы передали команду, она больше не нужна . } void main(void) // Начнем работать. { initсопuns () ; /1 Инициализация модуля. for (i=O; i<б; ++i) cornmandreciev [i] = " "; commandreciev [О] = "С"; РНОТОСОМЕ = ОхО; МО = ОхОО; // Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. start: М2 = Ох1; /./ Чтобы видно, что модуль включен. /* Нет ИКсиrнала, проверим сеть */ CREN =Ох1; if (RCIF) cmd () ; if (lRВЗ) /1 Появился ИК сиrнал. { CREN =ОхО; for (k=O; k<ЗО;++k); 1/ Поставим задержку. if (lRВЗ) /1 ИК сиrнап не пропал? { РНОТОСОМЕ = Ох1; МО = ОхО1; // Обработаем ИК команду. ircmd (); РНОТОСОМЕ = ОхО; МО = ОхОО; goto start; } } e1se { РНОТОСОМЕ = ОхО; МО = ОхОО; CREN =Ох1; } goto start; } 
128 rnaBa . 1 Базовая версия НЕХ-фаiiл дп_ эаrруэк. . nporpaMMarop :10000000830100308A000428203084004C300D2009 :100010008301102A04068001840A0406031D0A28AD :02002000003 :1002D8008301861D71298C1E6C291A080800FD30BF :1002E80083018F0043308E009001900A080083013B :1002F800CB00831203130CIE7D294B0899000800ВC :10030800F401F5010310F30CF20C031C9229700898 :10031800F40771080318710AF5070310FOODF10DCl :10032800720873040319003486298301B901BA01DC :100338003СО8А4003D08А500DО30А407А5070АЗ052 :10034800F200F3012408FOOOFI0184212508740764 :10035800B90075080318750AВAOOFI003908FOOOE9 :1003680008008301850107309F0083168501FE3050 :10037800860008308E00903083129800063083166D :100388009800683099008B018312061083168C013F :10039800831290018F018EOIAOOI0608A700A80111 :100ЗА8000430FООО280DА80СА70СFООВD629080083 :1003В8008ЗО118166С21A6000В2AADОlADОААЕО107 :1003C8002E08803AF00080307002063003192D02A2 :1003D8000318FA296C21A6002D083B3E84008313DC :1003E80026088000ADOA0319AEOAE429992170088D :080ЗF800А9007108ААО0280603 ':10040000031D042A27082906031D08002430BE0006 :100410005330COOOB62A2608433A031D0800E129DC :10042000B521AD01AEOI1D2A2D083B3E840083138A :1004300020308000АООАО319АЕОА2ЕО8803АРООО81 :1004400080307002063003192D02031C142A433039 :10045000ВВООАВОIАСОI05100608А700А8010430Е1 :10046000F000280DA80CA70CFOOB312A0515181662 :100470008C1ADC218619582A1812AFOIB0013008F5 :10048000803AF000803070021E3003192F020318EA :100490004D2AAFОА0319ВООАЗF2А8619362ААВО142 :1004AOOOAВOAACOI05145D22AВOIACOI0510362A84 :1004ВОООАВОIАСОI05101816362А8301СI01С20137 :1004C0001812861D612ACI01C2018619652A73218D :1004DООООСIС682А90010СI08б19752ААООА732139 :1004ЕООООСIС702А90010СI0762А20084208803Апl :1004FOOOF000803070020730031941020318822A8D :100500000310AOODCI0A0319C20A4208803AF00084 :1005100080307002083003194102031С652ААВОIС8 :10052000АСОI05108514В301В4013408803АРООО21 
Схема и nporpaMMa модуля приема ИК-команд 129 :10053000803070020430031933020318В32АВ1016А :10054000B2013208803AFOOOA7307002103003196F :1005500031020318АР2АВ10АО319В20АА12АВ30А59 :1005БООО0319В40А952А1816851008004330830130 :10057000BB002408303EВC002508303EBD002008EA :10058000С500С601б430F200F3014608F1004508D9 :10059000FOOOB1237408C7007508C8004708303E52 :1005AOOOA1006430F200F3014808F1004708FOOOBO :1005ВОО084214б08F1004508FОО07408FО02031С8D :1005СОООF1037508F1020А30F2000030F301В123АЗ :1005DОО07408С3007508С4004308303ЕА2000А300б :1005EOOOF200F3014408F1004308F000842174088C :1005FOOOC9007508CA006430F200F3014808F10030 :100600004708F00084214608F1004508F00074080E :10061000F002031CF1037508F1024908F002031C03 :100б2000FI034А08F1027008Сl007108С2004108D4 :100б3000303ЕА300АО08031Dб32В2330ВЕООбб30АС :10064000ВFООСООО18120614831б98168312ADО15D :100б5000АЕО12Е08803AFОО0803070020б30031997 :100ббОО02D0203183D2В2D083В3Е84008313000808 :100670007B21AпOA0319AE0A292ВAD01AE012E086C :100б8000803AFОО083307002Е83003192D0203181D :100690004D2ВADОА0319АЕОАЗF2ВADОlАЕО12Е085А :100БАОО0803AFОО080307002063003192D020318Е2 :1006B000AA2B2D083B3E8400831320308000ADOA16 :1006C0000319AEOA4F2B2108BE002208BF002308E1 :1006DОООСООО18120614831б98168312ADОlАЕОlDD :1006ЕОО02Е08803AFООО803070020б3003192D0287 :100БFООО0318842В2D083В3Е8400831300087В21С4 :10070000AпOA0319AEOA702ВAD01AE012E08803A76 :10071000F00083307002E83003192D020318942B87 :10072000ADОА0319АЕОА8б2ВAD01АЕО12Е08803А40 :10073000FОО080307002063003192D020318АА2Б3б :100740002D083ВЗЕ8400831320308000ADОА03193Е :10075000АЕОА962ВОб10831б981283121816АО01б3 :1007БООО0800FБ01FllFВВ2ВFО09FООА0319Fl0391 :10077000Fl097б17Fб1773088039FбОбF31FС72ВВ1 :10078000F209F20А0319F303F309С72ВFб01F40186 :10079000F50172087304031DD02BFOOlFl01003440 :1007АОООlF30Fб040310FбОAF20DF30D031СD32ВDl :1007BOOOF30CF20C73087102031DE02B7208700237 :1007C000031CE82B7208F0027308031C730AF10281 :1007DОООF40DF50DF60ВFб1AD82ВF61FF42ВF409D1 
1 30 rлава . 1 Базовая версия :1007ЕОООF40А0319F50ЗF5097408F2007508F3001В :1007F000761F0034F009FOOA0319F103F1090034FF :OOOOOOOlFF А для тех, кто не потерял интерес к процессу разработки собственных модулей и не спетит, я продолжу рассказ. Итак. Какие требования мы предъявим к натему модулю приемника инфракрасных кодов? Учтем, что основная задача модуля  принимать коды, которые мы назовем системными. В качестве системных кодов, удобно было бы взять числа от 1 до 255 в формате выте разобранной структуры ИКкода. На данном этапе примем этот вариант. Повторим еще раз, как будет выrлядеть системный ИКкод. Вспытка с несущей частотой 37 кrц длительностью 2,2 мс (заrоловок). Байт KO манды от 1 до 255 с соответствующими вспышками и пауза ми. Пауза 25 мс между командами. Требования к модулю: . модуль должен принимать системные 'ИКкоманды с H сущей частотой 37 кrц; . модуль должен ответить на запрос центральноrо управ ЛЯI9щеrо устройства (компьютера) по интерфейсу RS485, обозначив номер принятой ИКкоманды. Несколько слов о комплектующих элементах. Разумнее Bcero, с моей точки зрения, использовать фотоприемник TSOP1737  рис. 1.46  (если вы задействуете пульт с Hecy щей частотой 37 кrц, в противном случае следует выбрать дрyrой фотоприемник из этой серии). На рис. 1.47 схема ero включения. / GND . Vs OUT Рис. 1.46. Внешний ВИД И ВЫВОДЫ фотоприемника 
Схема и проrрамма модуля приема ИК-команд 1 31 Application Circuit TSOF 17.. 4.7т ТМ3 ** ; Out 9612108 +5V -GND Рис. 1.47. Типовая схема включения фотоприемника TSOP Конденсатор 4,7 мкФ желательно располаrать непосред" ственно около фотоприемника, если между модулем и при емником несколько метров провода. Подобное может про изойти, если вы не удовлетворитесь про веркой на макетной плате, а захотите воплотить модуль в жизнь и при этом рети те убрать сам модуль подальте, а на виду оставить только фотоприемник. Фотоприемник невелик по rабаритам, ero можно приклеить с помощью двустороннеrо скотча на панель телевизора. Именно в этом случае я советую непосредствен но к ножкам фотоприемника припаять конденсатор 4,7 мкФ. На выходе фотоприемника формируются сиrналы (рис. 1.48): в отсyrствие команд ero выход в высоком состоянии; при Ha личии ИКпульсаций (с частотой 37 кrц), он переходит в низ кое состояние. Output Signal. (see Fig.1 О) Vo VOH 94 8134 VoL t Рис. 1.48. Типовой видсиrнала на выходе фотоприемника Здесь время Топ соответствует посылке ИКимпульсов, Toff  паузе. Можно приступать к написанию проrраммы. Как и прежде, для установки заданноrо адреса используем четыре старших бита порта В (RВ7RВ4). Для работы с сетью применим встроенный в микроконтроллер блок USART, а фотоприемник подключим к выводу RЛ6. Добавим еще CBeтo диод для индикации наличия сиrнала, который подключим 
132 rлава . 1 Базовая версия к выводу RЛО. Поскольку остальные выводы портов нас не ин тересуют, отметим только, что в отличие от предыдущей KOH фиrypации порта А  вывод RЛ6  следует установить на ввод (в предыдущем варианте порт работал на вывод) Основные блоки. проrраммы: . инициализация модуля; . ожидание активности приемника USART; . ожидание активности от фотоприемника; . обработка сетевой команды от компьютера; . обработка ИКкоманды от фотоприемника. В предыдущей проrрамме мы моrли спокойно ждать актив ности в сети и ни о чем не заботиться, в этой проrрамме нам приходится откликаться на два события  активность в сети и активность фотоприемника. Будем считать, что rлавное  это ожидание активности фотоприемника, и попробуем предста вить, что будет происходить при работе с реальной системой. Каждое слово команды, состоящее из 6 байт, занимает (байт  44 мкс) 0,264 мс. Положим, мы добавим 0,5 мс между командами. Основное занятие компьютера  постоянный опрос MOДY лей, поскольку проrрамма должна выявлять события (измене ние состояния модулей) и выполнять действия, COOTBeTCTBY ющие этим событиям. В данном плане модуль, который опративает и сеть, и фотоприемник, должен отслеживать изменения в обоих источниках. Пока модуль «слушает» сеть, он не «слытит» фотоприемник, и наоборот. Вероятно, разумно было бы использовать механизм преры вания, хотя бы для работы по прерыванию с фотоприемни ком. Основанием стал бы тот факт, что в сети циркулируют запросы состояния, на которые модуль постоянно «отвлека ся». При этом леrко пропустить изменение состояния фото-- приемника. НО для начала попробуем оценить ситуацию. Мы определили длительность заrоловка ИКкоманды в 2,75 мс. Основное назначение заrоловка  дать «понять» фо-- топриемнику, что далее последует команда. Таким образом, изменение состояния фотоприемника с целью «привлечь внимание» контроллера модуля будет длить ся около трех миллисекунд. За это время успеет пройти 
Схема и проrрамма модуля приема ИК-команд 1 ЗЗ около 10 (длительность слова команды в сети около 0,3 мс) слов команды. А это дает основания предполаrать, что модуль успеет все «оценить» И перейдет к приему ИКкоманды. В OT сутствие прерываний он примет команду полностью, если это системная команда, прежде чем вернется к прослушива нию сети. Однако скорость поступления ИКкоманд едва ли будет превышать 0,3 с (интервал между двумя нажатиями на одну и ту же клавишу). То есть, за время между поступлениями KO манд у компьютера будет возможность ослать около 1 000 за просов. В итоrе, если мы не планируем проrрамму, которая будет нуждаться в 2000 запросов, а пользователь не будет иr рать на клавитах управленя, как на рояле, особых проблем возникнуть не должно... Мы не собираемся строить очень разветвленную сеть с больтим количеством устройств. Но даже если бы мы этоrо захотели, то моrли бы увеличить CKOPQCTb работы в сети с 9600 бит / с (в натих рассуждениях) до 115 000 бит/с. Это из менение увеличило бы число возможных запросов до 12 000. Реальное время между командами я бы тоже оценил в ззо с, что позволило бы увеличить количество возможных сетевых запросов до 120 000. Если это не поможет, что ж, переделаем все полностью! Итак, предварительная оценка, не исключаю, что отибоч ная, позволяет нам считать возможной работу модуля без ис пользования прерывания. На том и порешим. Писать проrрамму на ассемблере или на языке С? Я, пожа луй, пока не перестанет работать демонстрационная версия компилятора С, использую эту возможность. &лок .".q.an.эаq.. модул. Не мудрствуя лукаво, поправим и используем в этом блоке код предыдущеrо модуля. int initcormns ()" { PORTA = ОхО; CMCON = Ох?; TRISA = ОхСО; ТRISB = OxF6; 11 Инициализация модуля. // Настройка портов А и В. // Здесь только RAб на ввод 
134 rлава . 1 Базовая версия RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох16; INТCON = о; PORTB = о; } / / настройка приемник а . // настройка передатчика. / / настройка режима.приемапередачи. / / запретить прерывания. // Выключим передатчик драйвера RS485. Впок 06pa6orк. команд.' ФО'f'опр"емн.ка Пока RЛ6 в высоком состоянии «( 1» ), ничеrо не надо делать. Проверим состояние USART. Если обращение идет не к Ha тему модулю, делать ничеrо не надо, вернемся к определе-- нию состояния RЛ6. Я, как мне кажется, весьма рассудительно подошел к этому блоку nporpaMMbI. Но сомнения остаются. Я не уверен, будет ли она вообще работать, переключаясь с прослушивания от одноrо источника к друrому. Я, пожалуй, выделю блок и проверю ero до написания oc тальной части проrраммы. Не забудьте установить нужное состояние конфиrypации (3FIAh) по адресу 2007Ь! Мне понадобится файл зarоловка: #define MODULNAМESIM "С" #define CМDSIM "$" void putch(unsigned char); unsigned char getch(void); int ini tcomms ( ) ; int simnumadr(); int cmd(); и файл проrраммы: #inc1ude <pic16f62xa.h> #inc1ude <stdio.h> #inc1ude "irrec.h. unsigned char input; реrистра. unsigned char MODSIM1; unsigned char MODSIM2; I / Считываем содержимое приемноrо I / Первый символ адреса модуля. / / Второй символ адреса модуля. 
Схема и проrрамма модуля приема ИК-команд 1 35 unsigned char COММAND; // Символ команды. int MODADDR; / / Заданный адрес модуля как число. int sim1num = о; int sim2num = о; int simendnum = о; int MODNUМ; / / Полученный адрес модуля, как число. int РНОТО; int РНОТОСОМЕ = о; int FLAG = о; / / Временная переменная. unsigned char getch() { whi1e (!RCIF) ; пуст. .continue; return RCREG; } // Устанавливается, коrда реrистр не // Вывод одноrо байта. void putch(unsigned char byte) { PORTB = 1; TXEN = 1; while( !ТXIF) continue; TXREG = byte; } int initcomms () { PORTA = Охсо; CMCON = ох?; TRISA = Охсо; TRISB = OxF6; RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох16; INТCON=O. PORTB = о; } int cmd() { // Переключим драйвер RS485 на передачу. // Разрешаем передачу. // Устанавливается, коrда реrистр пуст. / / Инициализация модуля. // Настройка портов А и В. // Насройка приемника. // Настройка передатчика. // Настройка режима приемапередачи / / Запретить прерывания. // Выключим передатчик драйвера RS485. / / Получение и выполнение команды. 
1 36 rлава . 1 Базовая версия input = getch(); } // Преобразуем символьный адрес в число. int simnumadr() { simendnum = о; sim1num = getch(); /1 Чтение первоrо символа номера. MODSIM1 = sim1num; / / Сохраним первый символ. sim2num = getch ( ) ; / / Чтение BToporo символа номера. MODSIM2 = sim2num; / / Сохраним второй символ. sim1num = simlnиm  Охзо; sim2nиm = sim2nиm  Охзо; simendnum = sim1num*OxOA + sim2nиm; return simendnum; } // Начнем работать. void main(void) { initconuns (); / / Инициализация модуля. //Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MOD....ADDR»4; / / Сдвинем на четыре бита. start: РНОТО = PORTA; // Начинаем работать. if (РНОТО&Ох40) РНОТОСОМЕ = о; // Нет ИКсиrнала. if (!(РНОТО&Ох40» РНОТОСОМЕ = 1; // Появился ИКсиrнал. while (РНОТОСОМЕ == 1) / / Обработаем ИК команду. { FLAG = 1 ; break; } // Нет ИКсиrнала, проверим сеть. input = getch(); while (input == MODULNAМESIM) { FLAG = О ; break; } goto start; } 
Схема и проrрамма модуля приема ИК-команд 1 37 В файл input.txt запитем: "R03$ONn "C03$OS" Перед началом проверки запустим RВ4 Set High (YCTaHO вить в высокое состояние), RВ5 Set High и RЛ6 Set High на Stimulus Controller (я изменил адрес с 01 на 03, а фотоприем ник на вводе RЛ6 перевел в пассивное состояние). Переменная FLAG. покажет, попадаем ли мы в нужное место проrраммы. Впоследствии мы вместо нее будем вызы вать подпроrраммы обработки команды cmd () и ИКкоманды ircmd ( ). Кнопками RЛ6 Set High и RЛ6 Set Low мы будем имитировать изменение состояния фотоприемника. Вроде бы работает. Хотя, признаюсь, получилось не сразу  я забыл задать слово конфиryрации по адресу 2007Ь. Перейдем к обработке ИКкоманды (обработку команд сети, я думаю, возьмем из предыдущей проrраммы, подпра вим, попробуем). После получения заrоловка и паузы в 0,55 мс мы можем ожидать прихода Bcero двух сочетаний импульспауза. Ноль  это импульспауза одинаковой длительности 0,55 мс. Едини ца  импульспауза, rде импульс  1,1 МС, а пауза  0,55 мс. Таким образом, нам нужны два интервала в 1,1 МС И 0,55 мс. для получения интервалов можно воспользоваться таймерами или отсчитать их в пустом цикле. Я воспользуюсь второй воз можноcrью. Все команды, кроме переходов, выполняются за один Ma шинный цикл (200 не при частоте 20 Мfц). Положим, что при частоте 4 Мfц машинный цикл равен 1 мкс. Тоrда нам нужно досчитать до 1100 для промежyrка в 1,1 мс И до 550 для KOpOT Koro промежyrка. Сравнивая эти промежyrки времени с приходящими им пульсами, мы можем определить, единицу или ноль получаем в ИКкоманде. Более Toro, мы можем установить только один счетчик до 550 (для верности возьмем 560) для вычисления байта команды. На практике при первой проверке я успевал нажать кноп ку RЛ6, чтобы имитировать приход ИКкоманды. Теперь не 
1 38 rлава . 1 Базовая версия успеваю. Слитком все быстро. Попробуем поискать, не MO жет ли MPLAВ помочь с симуляцией, как это было в случае с USART. И действительно, как любил повторять один из моих зна комых, «rрамотная проrрамма!». В разделе Debugger - SCL Generator (Отладчик - SCL reHepaTop) находим New Workbook (Новая рабочая тетрадь). Щелкаем и открываем окотко, в котором можно настроить имитатор работы фо- топриемника. В очередной раз наступив на rрабли (вместо Toro чтобы почитать описание), я начинаю понимать, что в первой KO лонке нужно задать текущее время, выделяя события. Для этоrо следует, щелкнув кнопку со стрелкой правее надписи Time Units (Единицы времени), выбратьмкс (us). Событием в данном случае будет изменение состояния вывода RЛ6 пор- та А, которое мы зададим, щелкнув большую клавишу Click here to Add Signa1s (Щелкните здесь, чтобы добавить сиrна лы). Из раскрывающеrося меню выберем RЛ6 и получим еще одну колонку с этим именем. Теперь в колонку Time (dec) впитем десятичные значения текущеrо времени (мкс), а в колонку RЛ6  состояния входа, соединенноrо с фотоприем ником. Не следует забывать, что в отсyrствие активности фотоприемник на выходе имеет высокий лоrический уро- вень (<<1»). Первый ИКсиrнал, с которым я хочу работать, выrлядит так: 10000000. Если вернyrься к разrовору об ИКкомандах и выбранному ретению по системным командам, то сиrнал, поступающий с фотоприемника на вход RЛ6, должен выrлядеть, как показа- но на рис. 1.49 и 1.50. Значения, которые следует проставить, представлены в табл.1.5. Нет сиrнала 3аrоловок 2750 МКС Единица 1100 МКС Ноль 550 МКС Ноль 550 мкс 550 МКС Проверка 550 МКС 550 МКС И т.д. 8 бит Рис. 1.49. Схема сканирования бит ИКкомаНДbl 
Схема и проrрамма МОДУЛЯ приема ИК-КОМQНД 1 39 ........,JCll  fi J'  .. -" ... . -. ." ". - ., .. ..... "1............ .":,." ............ -..".. ". '. :.... о"" ;БJji : j:w. i1i. ..":' ,I,j:(..:I;' ;;:,!i:iiiь, Л, ,,>. . ..ш.....А... . .".. ...:...." :.....: ...-..... ...........- . ". . ,i" . "'. "":7*( . '.;. . :1". >.. :'>:i,fj(':y.Y;:*{":' ...:.; &'\,.' "  . ..... ",,'л:.,;.,., : :.:: . T"'  ::''''  i ' t' <:.. < . .<:. ;'1 .' " &..00 & .............. j, 0021 lltCOIILUID 0.0000 .. " &..10'... 110 ... ... ... . ооос ,1.' 0.00 '.;'>' &.100  ........ Н, ... 000, ТО,. охОО I "  ! ::; ?t:..,;... ...., , ..' ш..=.. .. . :'ш. ....     <.:-:' ,   ' <j :ш::<:=<*", к--..... . ........ 08&00000 .:.:. ...1 о;  ". 1 ',!'' ....................   ...   ... .' ..1::.:.:Clш..  .O.._. . 1 01 1 1 1 .;;... ..... .................................................................. .....  11.... ta'OIOd fnlll f...  $8с . 1 ( :..lI8dI8dlUCC8tn.lty 1 CF. i ...,... ... "1:' .............................. 1 :; .171  1 .ч. I J il ! , .. .,:;,u. ....1JIfCIQI4CIk .. : .... С -":'_ . "," f'1eIr;.....:::; - :.:.: -»," "<  х 'f/:=:'::';::"==::''" . . . '':'.1 ;:}" '" ".' :о,.,. .,. .1!Ir., ....... -/..,., .'. . Рис. 1.50. Заполнение SCL Workbook Таблица 1.5. Задание временных интервалов в сценарии ИКкоманды Time RA6 Мои пометки (в книrе) 10000 О Через 1000 мкс приходит заrоловок АА6 = О 12750 1 Через 2750 мкс заrоловок заканчивается АА6 = 1 13300 О Через 550 мкс приходит 7й бит (единица 1100 мкс) 14400 1 Перебивка 550 мкс 14950 О Ноль 550 мкс 6й бит 15500 1 Перебивка 550 мкс 16050 О Ноль 550 мкс 5й бит 16600 1 Перебивка 550мкс 17150 О Ноль 550 мкс 4й бит 17700 1 Перебивка 550 мкс 18250 О Ноль 550 мкс 3й бит 18800 1 Перебивка 550 мкс 19350 О Ноль 550 мкс 2й бит 19900 1 Перебивка 550мкс 20450 О Ноль 550 мкс 1 й бит 21000 1 Перебивка 550 мкс 21550 О Ноль 550 мкс Ой бит 22100 1 Перебивка 550 мкс 47100 1 Пауза между командами 25 000 мкс 
140 rлава . 1 Базовая версия ИКкоманда имеет вид 10000000 или 80Ь. Теперь нужно сохранить Workbook и, щелкнув кнопку Generate SCL From Workbook (rенерировать SCL из рабочей тетради), сохранить .sсlфайл. Для использования этой имита ции ИКкоманды в Simulus ControIIer необходимо щелкнyrь кнопку Attach (Прикрепить), указав сохраненный прежде .sсlайл. После сохранения Workspace все необходимое будет появляться при заrрузке проекта. Спасибо создателям проrраммы MPLAВ, которые позабо тились о возможности работы с портами BBoдaBЫBoдa в раз ных их применениях! Теперь я собираюсь проделать следующее: при активиза цИИ RЛ6 я перейду к функции обработки ИКкоманды: . пропускаем заrоловок; . пропускаем перебивку в 550 мкс; . при активизации RA6 приходящим битом запустим «ожи далку» на 560 мкс (HeMHoro длиннее импульса в 550 мкс), после которой про верим состояние ввода RЛ6; если это ноль, бит «1», если единица,  бит «О» (на схеме сканиро-- вания это обозначено словом «Проверка» ); . если единица, еще раз включим «ожидалку», если ноль, не будем этоrо делать; . запитем бит в переменную IRCOMМAND, сдвинем вле во на одну позицию; . все это проделаем с 8 битами ИКкоманды. Поскольку я человек ленивый, моя «ожидалка» самая про-- стая: for (i = о; i<560; ++i); 1/ Ждемс Было ли это наказанием за лень, или я не справился с Ha стройками сценария, но, промучивтись несколько aCOB, BЫ ЯСНИЛ, что во время выполнения цикла for сценарий подхва тывает циклы команды и успевает выполниться весь, прежде чем осуществляется выход из цикла ожидания. Я пробовал в качестве единиц измерения 1iше Units и циклы (сус) и МКС (us)  не помоrло. Конечно, хорото бы выяснить, в чем проблема, но единож ды наказанный за лень, я ретил из двух зол выбрать меньшее, 
Схема и проrрамма модуля приема ИК-команд 141 орrанизовав «ожидалку» на таймере, как это и положено. Пока я, чертыхаясь, пытался оживить проrрамму с циклом for, я заметил, что цикл while не метает работе сценария. В конечном счете, эта часть проrраммы (в состоянии пр верки) получилась следующей: #include <pic16f62xa.h> #inc1ude <stdio.h> #include "irrec.hn unsigned char input; реrистра. int РНОТОСОМЕ = о; int MODADDR; int IRCOММAND = о; / / Считываем содержимое приемноrо // Флаr активности фотоприемника. / / ЗадаННЫЙ адрес модуля, как число. unsigned char getch() { whi1e (!RCIF) continue; return RCREG; } // Устанавливается, коrда реrистр не пуст. // Вывод одноrо байта. void putch(unsignedhar byte) { PORTB = 1; TXEN = 1; whi1e ( ! TXIF) continue; TXREG = byte; } int ini tcormns ( ) { PORTA = ОхСО; CMCON = Ох?; TRISA = Охсо; TRISB "= OxF6; RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох16; INТCON=O; / / PORTB = о; // Переключим драйвер RS485 на передачу. // Разреmаем передачу. // Устанавливается, коrда реrистр пуст. / / Инициализация модуля. /./ Настройка портов А и В. / / Настройка приемник а . // Настройка передатчика. // Настройка режима npиемапередачи. Запретить прерывания. // Выкдючим передатчик драйвера RS485 
142 rпOBa . 1 Базовая версия PIEl = О; T1CON = о; } / / Настройка таймера 1, запрет прерывания. // Выбор BНYTpeHHero reHepaTopa, бит 1 в ноль. int ircmd () { int Ь = о; whi1e ((PORTA&Ox40)== о) continue;// Ждем окончания заrоловка. for (ь=о; Ь<8;++Ь) // Обработаем наши импульсы. { whi1e ((PORTA&Ox40) != о) continue; // Дождемся импульса. time (); // whi1e (! ТМR1IF) ; T1CON = ОхО; ТМR1IF = ОхО; if ((PORTA&Ox40) Включаем таймер 1. // дождемся такта. / / Выключаем таймер. // Сбросим флаr. == о) // Если низкий уровень, то "1". { IRCOММAND = IRCOММAND + 1 ; / / Запишем это. tiще (); // Включаем таймер 1. while (! ТМR1IF) ; / / Дождемся такта. T1CON = ОхО; / / Выключаем таймер. ТМR1IF = ОхО; // Сбросим флаr. } e1se // Высокий уровень, значит "о". { IRCOММAND = IRCOММAND +0; / / Запишем это. } IRCOММAND = IRCOММAND«l; //Сместимся влево на бит. } // Уехали мы в смещениях на бит далеко, поэтому IRCOММAND = IRCOММAND»l; / / сместимся вправо на бит. РНОТОСОМЕ = о; } int cmd() { " input = getch(); // switch (COММAND = getch()> { 
Схема и проrрамма модуля приема ИК-команд 143 / / case "N": relon (RELNUМ) ; // break; / / case "F": reloff (RELNUМ) ; / / break; // case "8": relstat(RELNUМ); / / break; // } } void time () { ТМR1H = OxFD; переполнения. ТМR1L = ОхА7; T1CON = Охl; // Установка числа циклов до // FFFF минус 600 (258h). / / Включение таймера. } void maln(void) { 1/ Начнем работать. initcomms(); // Инициализация модуля. //Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. start: if (PORTA&Ox40) РНОТОСОМЕ = о; // Нет ик сиrнала. if (!(PORTA&Ox40) РНОТОСОМЕ = 1; // Появился ИК сиrнап . while (РНОТОСОМЕ == 1) { // Обработаем ИК команду. ircmd (); break: } // Нет ИКсиrнала, проверим сеть. . input = getch () ; whi1e(input == MODULNAМE8IM) { cmd (); break; } goto start; } 
144 rлава . 1 Базовая версия Все это получилось не сразу, но, вроде бы, заработало. T перь осталось проверить проrрамму с друrими вариантами ИКкода. Например, с команДОЙ 00100000, или 20Ь. 10000 о Через 1000 мкс прИХОДИТ заrоловок RA6=0 12750 1 Через 2750 мкс заrоловок заканчивается RA6=1 13300 О Через 550мкс приходит 7й бит 13850 1 Перебивка 550 мкс 14400 О Ноль 550 мкс 6й бит 14950 1 Перебивка 550 мкс 16050 О Единица 1100 мкс 5й бит 17150 1 Перебивка 550 мкс 17700 О Ноль 550 мкс 4й бит 18250 1 Перебивка 550 мхе 18800 О Ноль 550мкс 3 бит 19350 1 Перебивка 550 мкс 19900 О Ноль 550 мкс 2 бит 20450 1 Перебивка 550 мкс 21000 О Ноль 550 мкс 1 бит 21550 1 Перебивка 550 мкс 22100 О Ноль 550 мкс Ой бит 22650 1 Перебивка 550 мкс 47650 1 Пауза между командами 25000 мкс С комаНдой 10000011, или 83Ь: 10000 О Через 1000 мкс приходит заrоловок RA6=0 12750 1 Через 2750 МКС заrоловок заканчивается RA6=1 13300 О Через 550 мке приходит 7й бит (единица 1100 мкс) 14400 1 Перебивка 550 мкс 14950 О Ноль 550 мкс 6й бит 15500 1 Перебивка 550 МКС 16050 О Ноль 550 мкс 5й бит 16600 1 Перебивка 550мкс 17150 О Ноль 550 мкс 4й бит 17700 1 Перебивка 550 мкс 18250 О Ноль 550 мкс 3й бит 18800 1 Перебивка 550 мкс 19350 О Ноль 550 МКС 2й бит 19900 1 Перебивка 550мкс 20450 О Единица 1100 мкс lй бит 21550 1 Перебивка 550 МКС 22100 О ЕДиница 1100 мкс Ой бит 23200 1 Перебивка 550 мкс 48200 1 Пауза между командами 25000 мкс 
Схема и проrрамма модуля приема ИК-команд 145 и можно двиrаться дальте. Предстоит добавить обработ ку запросов по системной сети, преобразование позиционно ro кода ИКкоманды в символьный вид. Функцию обработки запросов по системной сети, подправив, я возьму из версии проrраммы для предыдущеrо модуля. Можно слеrка изменить и сценарий имитации работы фотоприемника, добавив задание адреса модуля (пусть он пока остается «03») и подключение к порту А фотоприемни ка RЛ6 == 1. Для этоrо в Workbook SCL Generator кнопкой Click here to Add Signals добавим еще три столбца: RВ4, RВ5 и PORTA, а в конце (как в табл. 1.5.)  информацию, представленную в табл. 1.6. Таблица 1.6. Добавление к таблице временных интервалов Time RA6 АВ4 АВ5 РОНТА Мои пометки (в книrе) 10000 О Через 1000 МКС приходит заrоловок, Ад6=0 И т.д. 47100 1 Пауза между командами 25000 МКС 5 1 1 40 Начальная инициализация адреса фооприемника Теперь при запуске проrраммы будет задан адрес модуля, и фотоприемник установит вывод RЛ6 в «}». В итоrе получилась (не слитком аккуратная) следующая проrрамма: #inc1ude <pic16f62xa.h> #inc1ude <stdio.h> #inc1ude nirrec.hn unsigned char input; реrистра. unsigned char MODSIM1; unsigned char MODSIM2; unsigned char IRSIM1; unsigned char IRSIМ2; unsigned char IRSIМЗ; int РНОТОСОМЕ = о; /1 Считываем содержимое npиемноrо / / Первый символ адреса модуля. / / Второй символ адреса модуля. / / Флаr активности фотоnpиемника 
146 rЛQВQ . 1 Базовая версия int MODADDR; int IRCOММAND = о; int simlnum = о; int sim2num = о; int simendnurn = int MODNUМ; // Заданный адрес модуля, как число. о; / / Полученный адрес модуля, как число. unsigned char getch() { whi1e( !RCIF) / / Устанавливается, коrда реrистр не пуст. continue; return RCREG; } /1 Вывод одноrо байта. void putch(unsigned char byte) { PORTB = 1; TXEN = 1; while ( ! TXIF) continue; TXREG = bytei } int ini tcomms ( ) { PORTA = Охсо; CMCON = ох?; TRISA = Охсо i TRISB = OxF6; RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох16; INТCON=O; PORTB = о; PIEl = о; T1CON = о; // Переключим драйвер RS485 на передачу. // Разреmаем передачу. // Устанавливается, коrда реrистр пуст. / / Инициализация модуля. // Настройка портов А и В. // Настройка приемника. // Настройка передатчика. / / Настройка режима приемапередачи. / / Запретить прерывания. // Выключим передатчик драйвера RS485. 1/ Настройка таймера 1, запрет прерывания. // Выбор BНYTpeHHero reHepaTopa, бит 1 в ноль. / / Определим номер модуля. MODADDR = PORTB; // Номер модуля в старших битах. MODADDR=MODADDR»4; / / Сдвинем на четыре бита. } // Преобразуем символьный адрес в число. 
Схема и проrрамма модуля приема ИК-команд 147 int simnumadr() { simendnum = О; sim1num = getch(); // Чтение первоrо символа номера. MODSIM1 = sim1num; / / Сохраним первый символ. sm2num = getch(); // Чтение BToporo символа номера. MODSIM2 = sim2num; / / Сохраним второй символ. sirn1num = sim1nurn  Охзо; sim2num = sim2num  Охзо; simendnum = simlnum*OxOA + sim2num; return simendnum; } int ircmd ( ) { int Ь = о; whi1e ((PORTA&Ox40)== О) continue;// Ждем окончания заrоловка. for (Ь=О; Ь<8;++Ь) { whi1e ((PORTA&Ox40) != О) continue; импульса. time (); // whi1e (!ТМR1IF); T1CON = ОхО; ТМR1IF = ОхО; if ((PORTA&Ox40) //Обработаем наши импульсы. / / Дождемся Включаем таймер 1. '/ Дождемся такта. / / Выключаем таймер. / / Сбросим флаr. == О) / / Если низкий уровень, то "1". { IRCOММAND = IRCOММAND + 1 ; / / Запишем это. time (); / / Включаем таймер 1. whi1e (! ТМRIIF) ; / / Дождемся такта. T1CON = ОхО; / / Выключаем таймер. ТМR1IF = ОхО; // Сбросим флаr. } e1se // Высокий уровень, значит "О". { IRCOММAND = IRCOММAND +0; 1/ Запишем это. } IRCOММAND = IRCOММAND«l; / /Сместимся влево на бит. } / / Уехали мы в смещениях на бит далеко, поэтому IRCOММAND = IRCOММAND»l; / / сместимся вправо на бит. 
148 [пава. 1 Базовая версия РНОТОСОМЕ = о; } int cmd() { MODNUМ = simnumadr ( ) ; if (MODNUМ == MODADDR) { //Чтение из сети (файла). / / Если наш адрес модуля. input = getch(); if (input == "$") // Если символ команды. { while ((input = getch(»!= "S"); // Ждем. irstat(); } } ) void time () { ТМR1H = OxFD; переполнения. ТМR1L = ОхА7; TICON = Ох1; // Установка числа циклов до // FFFF минус 600 (258h). / / Включение таймера. } int irstat() { int ircom; int ircom1; int ircom2; int ircom3; ircom = 1 RCOММAND ; / / Преобразуем команду в символы ircom1 = ircom/Ox64; IRSIM1 = ircom1 + Ох30; ircom2 = (ircom  ircom1*Ox64)/OxA; IRSIM2 = ircom2 + Ох30; ircom3 = (ircom  ircom1*Ox64  ircom2*OxA); IRSIM3 = ircom3 + Ох30; putch ("С") i putch(MODSIM1)i putch (MODSIIO) ; if (IRCOММAND == О) / / Команда не менялась. 
Схема и проrрамма модуля приема ИК-команд 149 { putch ( " # " ) ; ри tch ( " f" ) ; ри tch ( " f" ) ; putch(OxOA)- // Только для вывода в файл!!!!!! } e1se / / За время между двумя запросами пришла ИК команда. { putch (IRSIM1) ; putch ( IRSIIO) ; putch(IRSIM3); putch (ОхОА) ; / / Только ДЛЯ вывода в файл!!!! ! ! } IRCOММAND = О; / / мы передали ИК команду, она нам больше не нужна. } void main(void) { // Начнем работать. ini tcornms ( ) ; / / Инициалу!зация модуля. / / Про читаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. // Начинаем работать start: if (PORTA&Ox40) РНОТОСОМЕ = о; // Нет ИКсиrнала. if (! (PORTA&Ox40) РНОТОСОМЕ = 1; // Появился ИК сиrнал . whi1e (РНОТОСОМЕ == 1) { // Обработаем ИКкоманду. ircmd (); break; } // Нет ИКсиrнала, проверим сеть. input = getch(): whi1e(input == MODULNAМESIM) / / Если в сети обращение к модулю . { cmd (); break; // Обработаем сетевую команду. } goto start; } 
150 rпaBa . 1 Базовая версия в настоящий момент меня уже одолевают сомнения. Пока активность в сети не метает приему ИКкоманд. Не будет ли она метать, коrда появится функция обработки запросов? Можно попытаться рассчитать это, но расчеты MOryr оказать ся достаточно сложными. И не будет ли мешать прием ИК команд системным запросам? Не стану считать, попробуем, посмотрим. В крайнем случае, если не забуду, в основной проrрамме системы при отсылке запроса о состоянии модуля ИКприем ника, сделаю паузу и при отсyrствии ответа повторю запрос. Есть и еще одно сомнение  не будет ли в реальных усло виях неправильно считываться ИКкоманда? Здесь тоже мож но чтонибудь придумать. Например, повторять системную команду трижды, а в модуль добавить три считывания, при нимая в качестве команды ту, которая совпадает дважды. На данном этапе я предпочту отложить решение проблем до момента их появления, хотя, как мне кажется, самое время обо всем позаботиться. Работа выте приведенной проrраммы происходит при input.txt TaKoro вида: "R03$ON" "R01$ON" "C03$OS" Опция Rewind Input на странице Uartl 10 установлена. В результате имитация сетевых команд постоянно «крyrит- СЯ», принимая три команды, последняя из которых запрати вает состояние модуля фотоприемника. Результат работы проrраммы выводится, как и раньше, в файл output.txt: C03#ff// Команда не менялась СО3131// Пришла команда 131 (десятичная) или 10000011 двоичная C03#ff// Команда не менялась после последнеrо запроса C03#ff// Команда не менялась C03#ff// Команда не менялась 
Схема и проrрамма модуля приема ИК-команд 151 По дороrе я еще раз наступил на rрабли. Внеся исправления в проrрамму, я обнаружил, что она не желает работать. Во вся- ком случае, работать так, как мне хочется. Пытаясь понять, в чем дело, я MHoro раз просматривал проrрамму, пока не обна.. ружил, что один из операторов имеет тот же цвет, что и ком.. ментарий. Как это получилось? Я использую MHoro одностроч" ных комментариев (тоже следствие лени) и если в конце строчноrо комментария не нажат ввод при удалении промежyr.. ков между операторами проrраммы, следующий воспринима.. ется проrраммой как продолжение комментария. Чтобы частично развеять сомнения, я хочу переделать проrрамму для тестирования: . проверить, правильно ли будет работать проrpамма, если после первой ИКкоманды вторая придет через 50 мс; . проверить, MHoro ли запросов о состоянии модуля про пускается, если это происходит. Для этоrо в папке, rде лежат все проекты, я создам еще . одну папку, которую обозначу, добавив test к имени. Скопи.. рую туда содержимое папки модуля приемника ИКкоманд. Переименую все файлы, добавив test (исключая файлы input и output). Затем открою этот проект в проrрамме MPlAВ, настрою, добавлю в сценарий второй ИКкод, счетчики и по пробую ответить на два вопроса, которые задаю себе сейчас. Переделки В раздел переменных добавим (я использую rлобальные пе ременные, чтобы их леrче было отслеживать, поскольку ло кальные переменные до обращения к функциям не видны): int COUNTER = о; А в основной проrрамме  счетчик после вызова команды обработки сетевых команд: /* Нет ИКсиrнала, проверим сеть */ input = getch()i whi1e(input == MODULNAМESIM) / / Если в сети обращение к модулю. 
152 [лава. 1 Базовая версия { cmd (); ++COONТER; break; / / Обработаем сетевую команду. } goto start; Результат эксперимента  за время прохождения двух ИК команд (8Зh и 20h) счетчик досчитал до 5. Файл input.txt, который «крyrится» без перерывов выrля дит так: "RОЗ$ОN" "R01$ON" "СОЗ$ОS" Обращение к модулю приемника ИК команд "RОЗ$ОN" IROl$ON" "СОЗ$ОS" Обращение к модулю приемника ИК команд Файл output.txt получился следующим: СО3#ffКоманда не обновлялась С03131 Команда 131 (8Зh) СО3#ffКоманда не обновлялась СО3#ffКоманда не обновлялась С03032 Команда 32 (20h) Таким образом: . ИКкоманды не потерялись за непрерывно следующи ми сетевыми командами; . ИКкоманды прочитались правильно; . между приходами ИКкоманд запрос статуса правильно отображал отсyrствие обновления. Посмотрим, как это все выrлядит во времени. Первая ИКкоманда приходит через 10 мс И заканчива ся через 24 мс, вторая приходит через 60 мс И заканчивается через 73 МС после начала работы. Сетевые команды начина ЮТ поступать сразу после начала работы. Каждая сетевая K<r манда занимает около 6,3 мс (имеет 60 бит, проходящих со скоростью ....9600 бит/с). До начала ИКкоманды при такой скорости должна прой ти одна сетевая кома!lда. За время считывания первой 
Схема и проrрамма модуля приема ИК-команд 153 ИКкоманды « 1 О мс  6 мс) + 24 мс) = 28 мс пройдет 4 комаНДБI. После завершения первой и до конца второй пройдет 73 мс  24 мс = 49 мс, что соответствует 78 командам. Таким образом, за все время пройдет 12 13 команд. То есть, файл input прочи тается дважды или HeMHoro более. Что дает 45 обращений к модулю приемника ИКкоманд. Файл output фиксирует 5 обра щений, счетчик фиксирует 5 обращений. Для большей уверенности посмотрим, как распределяют ся сетевые обращения: . за время от начала работы до завертения считывания ИКкоманды проходит 5 системных запросов, среди которых один к ИКприемнику; . в выходном файле этому соответствует один ответ об отсyrствии обновления команд; . следующая команда во входном файле это запрос к MOДY лю; . В выходном файле на втором месте стоит ответ о при ходе команды 131 (к этому моменту считывание первой команды завершено); . до завертения считывания второй комаljДЫ проходит семь системных команд, среди которых два обращения к модулю приемника; . в выходном файле два ответа  команда не обновлялась (предыдущая уже передана); . следующая сетевая команда  запрос о состоянии MOДY ля приемника, который следует сразу за завершением считывания ИКкоманды, ответ  команда 32 в BЫXOД ном файле. Если я ничеrо не напyrал, даже при короткой основной проrрамме (центральноrо управляющеrо устройства), коrда запросы о состоянии модуля приемника идyr достаточно час то, ответ успевает доходить до адресата. Если учесть, что в тестовом варианте две команды проходят с интервалом в 36 мс, что в 1030 раз быстрее реально отправляемых команд  (интервал между двумя нажатиями на одну и ту же клавишу составляет от 0,3 до 1 с), то запас, я думаю, есть. Конечно, мои подсчеты не страдают излитней продуман- ностью и точностью, но я на время ретил успокоиться. 
154 rлааа . 1 Базовая версия OTnaAKa MOAYnR Прототип я делаю на той же макетной плате, на которой c бирал релейный МО.lo/ль. По этой причине я включаю фот приемник на вход RВ3. ДЛЯ индикации приема ИКкоманд дополнительно использую вывод RЛО, к которому уже под ключен светодиод. Коrда устанавливается флаr прихода ИК команды, светодиод включается. Флаr снимается  светодиод выключается. i f (! (RВЗ&ОхОl) ) { РНОТОСОМЕ = 1 i RAO = ОхОl; } e1se { РНОТОСОМЕ = о; RAO = ОхОО; } ВОТ и очередные «rрабли»! Приоритет приема ИКкоманд хорото бы закрепить oдн значно. Например, так: { whilе((!RСIF)&(RВЗ == 1» /* устанавливается, коrда реrистр не пуст */ continue; return RCREGj } я выделил добавленный фраrмент. У прототипа фотопри- емник подключен к выводу RВ3. Смысл добавленноrо фрar- мента в том, что на сетевые запросы ответ будет, если модуль не занят приемом ИКкоманд, то есть RВ3 == 1. Неплохо было бы защитить модуль от помех по RB3. При включении может «проскочить» короткий нулевой импульс (на чем я и споткнулся), и модуль перейдет в режим приема ИКкоманды, которой нет. Поправил я это так: start: if (RВЗ&ОхО1) // Нет ик сиrнала. { 
Отладка модуя 1 55 РНОТОСОМЕ = О; МО = ОхОО;. break; } if (! (RВЗ&Ох01) ) { // Появился ИК сиrнал. for (k=O; k<30; ++k); 11 Поставим задержку. if (!(RВЗ&Ох01» // ик сиrнал не пропал? { РНОТОСОМЕ = 1; МО = ОхО1; } } e1se { РНОТОСОМЕ = о; МО = ОхОО; break; } я добавляю задержку, а затем еще раз проверяю наличие активности фотоприемника. Короткий случайный импульс проскочит за время задержки, а длинный импульс команды приведет механизм считывания в действие. Помоrло. Если в первый раз после включения питания (сразу или через He сколько секунд) модуль «подвисал» на приеме ИКкоманды, то после исправления перестал. Итак, модуль получает команду. Возможно, распознает ее. Он даже передает ее по запросу через RS485. А что получит ся, если команда не единичная, то есть в том случае, коrда идет поток одинаковых команд? Что будет, если команды не системные, а чужие? Не знаю. Первое, что приходит в rолову  запустить еще один тай мер сразу после завершения считывания ИК:-команды. И пока он не завертит отсчет времени больтий, чем занимают 23 команды, не принимать ИКкоды. Попyrно я пытаюсь воспр извести код, аналоrичный тому, что использовал в отладчи ке MPLAB, из проrраммы WinLIRC, аппаратный модуль KO торой имеет излучающий светодиод. Проходит два дня. Результаты не впечатляют. Коды про читываются не слитком уверено. Я увеличиваю интервал сканирования с 600 до 700 мкс, но совсем не удовлетворен 
156 rЛQва . 1 Базовая версия стабильностью работы модуля. В отличие от релейноrо, MO дуль пр.иема системных ИКкоманд мне совсем не нравится. Он, вроде бы, работает, но... В конечном счете, я меняю излучатель кодов. Использую ориrинал  старый пульт от видеомаrнитофона Sony: Меняю второй таймер на обычный цикл в команде считывания KO дОВ (выделено в тексте проrраммы), попутно ретаю внести исправления в сдвиr на один бит. У меня получился лишний сдвиr, который я после получения ИКкоманды убирал обрат ным сдвиrом. После замены переменной IRCOMMAND с типа int на unsigned char я стал терять стартий бит. . Замена всех этих «шатаний из стороны В сторону» оказа лась простой (изменение выделено). Если я не ошибаюсь, эт<r ro достаточно. int ircmd () { int Ь = о; whi1e (RВЗ == о) con'tinue; / / Ждем окончания заrоловка. for (Ь=О; Ь<8; Ь++) //06работаем наши импульсы. { whi1e (RВЗ != О) continue; /1 Дождемся импульса. time (); // Включаем таймер 1. whi1e (!ТМR1IF); / / Дождемся сброса таймера. T1CON = ОхО; / / Выключаем таймер. ТМR1IF = ОхО; // Сбросим флаr. if (RВЗ == О) / / Если низкий уровень, то "1". { IRCOММAND = IRCOММAND + 1 ; / / Запишем это. time (); // Включаем таймер 1. while (!ТМR1IF); / / Дождемся сброса таймера. T1CON = ОхО; / / Выключаем таймер. ТМR1IF = ОхО; / / Сбросим флаr. } e1se // Высокий уровень, значит "о". IRCOММAND = 1 RCOММAND ; / / Запишем это. if (Ь<7) IRCOММAND = IRCOММAND«lj //СмесТ1llМСЯ влево на бит. } РНОТОСОМЕ = ОхО; 
Отладка модуля 157 НАО = ОхО; Мl=Ох1; fQr (ш=О; ш<З; ++ш) / / перестаиеи принимать :ИКltоды. for (1=0; 1<10000; ++1); НА1 = Охо; } Здесь на выводе порта А RЛ1 я использую еще один CBeTO диод, чтобы видеть окончание команды. В результате модуль хорото распознает команды от пуль та видеомаrнитофона. Чувствительность высокая, распозна вание стабильное (рис. 1.51). " .. .. -\"1''1'  . 1ft . . .:. ... ,;-.. . Щ( . :;k . . . J . :-....... ::_ :::1 .!:l i .,' .: .."....,.,... .  П . n :'. : :: :. fQ...... 'у ". .,.. " .. , Jt.  .. у" ,  .. .:.. <... ... . " .  . : .\:  C.>f.'{t;.'/'..: ..: .... " 'l'/;:: . . ,....... . . ;, .! ..  1.. $А \< : .. .  ,'J ' '.... IUI 1х . са' .... .:". ,.. . "'''.;' ::.:. . . .",'. "';: .' '. .-::-',:: ' CHSOSC14064 а. '. 21 :11.00> Pec:ket О i. ..nt '.' ",.\ .:, »433134243053 ''''' ".. " C14S0SC14064 ,:.. '" ". 21 :11 :06> Pec:ket О i. ..nt "'. . .» 43 31 34 24 30 53 .  , C14S0SC14064 4Y," . l :...- . :)..' '14108 . . .. .. .. . .,0" :":':_r .14ai. ' :..;..::;.t.Щi"У::'$>m#5>i:'<'!:':' < '.4i_i?i. :;:" t<i .:;?TJ/""1 ' Iv j ZJ ."" Рис. 1.51. Прием ИКкодов модулем Не удовлетворяют меня только два момента: . иноrда во время паузы между приемами ИКкоманд зап рос по сети «подвешивает» модуль внераспознанном месте (помоrло сокращение времени этой паузы); . коды с пульта плохо соrласуются с моими ожиданиями. . 
158 rлава . 1 Базовая версия Вот сравнение кодов, прочитанных с помощью WinLIRC в режиме распознавания, и кодов, которые транслирует MO дуль В ответ на запрос по сети RS485: Номер канала 1. Модуль возвращает номер команды 001  00000001 (С14001  в ответ на запрос статуса). 7F2h  11111110010 (инверсия 00000001101), без послед них трех бит 0000001. . Номер канала 2. Прочитано модулем 129  10000001 3F2h  01111110010 (инверсия 10000001101), без послед них трех бит 10000001. Номер канала 3. Прочитано модулем 65  1000001 5F2h  10111110010 (инверсия 01000001101), без послед них трех бит 1000001 Номер канала 6. Прочитано модулем 161  10100001 2F2h  01011110010 (инверсия 10100001101), без послед них трех бит 10100001. Номер .канала 9. Прочитано модулем 017  10001 772Ь  11101110010 (инверсия 00010001101), без послед них трех бит 00010001. power. Прочитано модулем169  10101001 2В2Ь  1010110010 (инверсия 0101001101), без последних трех бит 0101001. Команда включения канала 1 в записи WinLIRC  7F2h, но я определяю единицу и ноль, как это описано в технической информации о кодах Sony, которой располаrаю, а в WinLIRC сделано наоборот. Можно инвертировать код. Кроме Toro, я использую 8битовый код, а ориrинальный код  11 битовый. Тоже не страшно, отбросим три последних бита. Смущающим меня обстоятельством служит то, что команды каналов 1 и 2 не совпадают, как я ожидал после превращений с инверсией и отбрасыванием. Аналоrичная история с командой power. Пока я не понимаю, как это происходит. 
Отладка МОДУЛЯ 159 Шутка калькулятора, который отбрасывает первые нули! Но понял я это позже. Последнее, что я делаю, измученный борьбой с «собствен ной rениальностью»,  проверяю работу модуля в заrотовке под среду проrраммирования. Модуль работает. Я использую два кода: номер включения канала 1  для тестирования KO манды, а канала 2  для включения лампы. Оба кода стабиль но работают. Думаю, пока следует остановиться. Основная задача  получить модуль считывания системных команд, которые стабильно распознавались бы системой, достиrнута. При этом, как это и планировалось, используетс старенький пульт от видеомаrнитофона. А если чтото осталось непо нятно, что ж... Будем надеяться, что это позже прояснит ся (рис. 1.52). ,", ,,"': <-:.::::t. Х"'. >,,;,){.::<fi':)',. .,> ,,:?,,y,';(:'}:":;"'7:'<\j:..,,9 ;(х;:;' ;«::... .... ..,.:;.';: . :. ". ., . ,..;",.. ;... /" ". '"'."'."'.:::" :':....':<,.../.' :  (':'' ."." ,::,'. . :: , . ,j, sl ...... ... ; ..,.>!;:;:;>.<:i <;;>,<,. . ." "" С ': . . . . . .. .....:..: ....;,.: . ." .,0'"." " "....... .. -..,. . . .... . .:, i . .' . . ..,' ' , . '." ',', о', . . -.- .:; <; . .' и :. ;. . :.. .' .... 1 :., } : :>.,' ''1.: .... .,:>'. ':, "f" " . f' . .('i:'.('::. -':.-s-.Y"'...:.c.::::':.- .- ."  ....: о'"...... ::J;.. : ....: .... .> ."........'.:.....'.. В:::"):::";?У,:",: }:-:::;.,,"',:...::... .......i--....... .:: 4  .';,0j,>..;'P,"":.,.> "",,j,:,<,.' - :в:}-} -::::.;t :. . >- <:'..:> ..:--: ._  . ..... ; .;:} : i:.: . "," ....': ;- . ".-.. . ,'.-.. .... " .... .. .... "," . .'.  - . . ;: К АЛ. '1'. "-:k' :; ., '.(" :.: ..:ОМ......::.::..:.: '-.:':;;.y...<..::( 1- .:_.-.....c-... ..... _.....-'<:..::'" .t-....-:- ::::,:.:........={$.: : .N ..," Ж'("", "'.' .. ,.Пl '. " i ',..:.....; " J ::- ." у..:""::;".: ;._:.:. :  -'. . ..... :. .'. .:>:;;;:;.::. .:::  . :'.'; ..:'.:...:.;::.:;;:;.  '" ........ ... . .. ": . .". л о.. ';'. .- >:: у"о '_0 ".<..._  :.. о;. . ........,..  > .,;. з.:.;.1,;::t . 1 :; : . .  ..J!>) : :: .:  : "... "..:J.: _" .,.1.':- . _;)::" ..:  :#:; . .  ... .;..: ', . . i1 .. ," .... "," -..... ......... .... -.::. ........ -.-:.... ............::....v..... ...... ,...... ..,::: ..... ...........-;.:=';...:.:. "o':;.-....,..:.{.:....#.  Рис. 1.52. Работа модуля с основной проrpaммой 
160 rлава . 1 Базовая версия Самым непонятным для меня оказалось то, что попытка ис пользовать- третий светодиод для индикации включенноrо MO дуля  Я несколько раз вытаскивал микросхему из панельки без отключения питающеrо напряжения  успехом не увенча лась. Я попробовал разные варианты включения. Ничеrо не получилось! Мистика!? в данный момент проrрамма модуля приема системных кодов получилась такой. файл зarоловка: #define MODULNAМESIM "С" unsigned char getch(void); · int ini tcomms () ; int ircmd (); int cmd (): void time () ; void timecmd(); int irstat(); файл основной проrраммы: #inc1ude <pic16f62xa.h> #inc1ude <stdio.h> #inc1ude "irrecOl.h" unsigned char input; / / Считываем содержимое приемноrо реrистра. unsigned char MODSIM1; / / Первый символ адреса модуля. unsigned char MODSIM2; / / Второй символ адреса модуля. unsigned char IRSIM1; unsigned char IRSIМ2; unsigned char IRSIМЗ: unsigned char commandreciev [6]: / / Массив для полученной команды. int РНОТОСОМЕ = о; / / Флаr активности фотоприемника. int MODADDR; / / Заданный адрес модуля, как число. unsigned char IRCOММAND = о; int sim1num = о; int sim2num = о; int simendnum = о; int MODNUМ: // Полученный адрес модуля, как число. 
int i; int k; int 1: int т; unsigned char getch() { Отладка модуля 1 б 1 whi1е(!RСIF)&(RВЗ  1») continue; return RCREG; } // Коrда реrистр не пуст. // Вывод одноrо байта. void putch(unsigned char byte) { whi1e (!TXIF) continue; TXREG = byte; } int ini tcomms ( ) { PORTA = ОхОО;. CMCON = Ох?; TRISA = Охоо; TRISB = OxFE; PCON = OxFF;" // RCSTA = ОЫОО10000; TXSTA = ОЬОООООll0; SPBRG = Ох68; N,8,1. INТCON = ОхО; RBO = ОхО; PIE1 = ОхО; T1CON = ОхО; ноль. ТМR1H = ОхОО; ТМR1L = ОхОО; IRCOММAND = ОхО; MODDR = PORTB; MODADDR=MODADDR»4; } // Коrда реrистр пуст. / / Инициализация модуля. // Настройка портов А и В. Тактовая частота 4 мrц. // Настройка приемника. // Настройка передатчика. //Настройка режима приемапередачи 2400, / / Запретить прерывания. // Выключим передатчик драйвера RS485. / / Настройка таймера 1, запрет прерывания. // Выбор BНYTpeHHero reHepaTopa, бит 1 в / / Обнулим таймер. /* Определим номер модуля * / // Номер модуля в старших битах. // Сдвинем на четыре бита. // Преобразуем символьный адрес в число. int simnumadr{) 
162 rлава . 1 Базовая версия { simendnum = ОхО; MODSIM1 = commandreciev [1]; MODSIM2 = commandreciev [2]; MODSIM1 = MODSIM1  ОхЗО; MODSIM2 = MOPSIM2  Охзо; simendnum = MODSIM1*OxOA + MODSIM2i return sЫmendnum; // Первый символ номера. // Второй символ номера. } int ircmd ( ) { int Ь = о; whi1e (RВЗ == о) continuei // Ждем окончания заrоловка. for (Ь=О; Ь<8; Ь++) //Обработаем наши импульсы. { whi1e (RВЗ != О) continuei / / Дождемся импульса. t ime (); / / Включаем таймер 1. . whi1e (!ТМR1IF) i / / Дождемся сброса таймера. T1CON = ОхО; 1 / Выключаем таймер. ТМRIIF = Охо; / I Сбросим флаr. if (RВЗ == О) // Если низкий уровень, то "1". { IRCOММAND = IRCOММAND + 1 ; / / Запишем это. time (); // Включаем таймер 1. while (!ТМRIIF); // Дождемся сброса. T1CON = Охо; / / Выключаем таймер. ТМR1IF = ОхО; 1/ Сбросим флаr. } e1se // Высокий уровень, значит "О". IRCOММAND = IRCOММAND; / / Запишем это. if (Ь<7) IRCOММAND = IRCOММAND«l; / /Сместимся влево на бит. } РНОТОСОМЕ = ОхО; МО = ОхО; НА1=Ох1; for (m=О; m<З; ++m) // Перестанем принимать ИК. for (1=0; 1<10000; ++1); М1 = ОхО; } 
Отладка модуля 163 int cmd ( ) { if (commandreciev [5] = "S") irstat(); } void time () { / / Таймер 1 для чтения ИК. ТМR1H = OxFD; переполнения. ТМR1L = Ох4З; T1CON = Ох1; // Установка числа циклов до // FFFF минус 700 (2BCh). // Включение таймера. } int irstat() { int ircom: int ircom1; int ircom2; int irсоmЗ; commandreciev[O] = "с": commandreciev[l] = MODSIM1+0x30; commandreciev[2] = МОDSIМ2+0х30: ircom = IRCOММAND: / / Пре06разуем команду в символы ircom1 = ircom/Ox64; IRSIM1 = ircom1 + Ох30; ircomQ = (ircom  ircom1*Ox64)/OxA; IRSIM2 = ircom2 + ОхЗОi irсоmЗ = (ircom  ircom1*Ox64  ircomQ*OxA); IRSIM3 = ircom3 + Ох30; if (IRCOММAND == О) { commandreciev[3] = "#"; // Команда не менялась. comrnandreciev[4] = "f"; commandreciev [5] = "f ".; CREN =ОхО; / / Запрещаем прием. RBO = Ох1: //Переключим драйвер RS485 на передачу. TXEN = Ох1; / / Разрешаем передачу. for (i=O: i<6; ++i) putch(commandreciev[i]); 
164 rлава . 1 Базовая версия for (i=0;i<1000;i++)i // Задержка для вывода. for (i=O; i<6; ++i) commandreciev [i] = " "; RВO = ОхО; // Выключаем драйвер RS485 на передачу. TXEN = ОхО; / / Запрещаем передачу. СRБN =Ох1; // Разрешаем прием. } e1se / / За время между двумя запросами пришла ИК команда. { соmmaпdrесiеv[З] = IRSIM1; commandreciev[4] = IRSIM2; commandreciev[5] = IRSIМЗ; СRБN =ОхО; / / Запрещаем прием. RBO = Ох1; //Переключим драйвер RS485 на передачу. TXEN = Ох1; // Разрешаем передачу. for (i=Oi i<6; ++i) putch(commandreciev[i]); for (i=Oii<1000;i++); // Задержка для вывода. for (i=O; i<6; ++i) commandreciev [i] = " "; RBO = ОхО; // Выключаем драйвер RS485 на передачу. TXEN = ОхО; / / Запрещаем передачу. СRБN =Ох1; / / Разрешаем прием. } IRCOММAND = ОхО; / / мы передали команду, она больше не нужна. } void main(void) { // Начнем работать. ini tcomms ( ) ; / / Инициализация модуля. for (i=O; i<6; ++i) commandreciev [i] = " "; commandreciev [О] = "с"; //Прочитаем и преобразуем номер модуля. MODADDR = PORTB; // Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. RЛ2 = Ох1; // Чтобы видно, что модуль включен. 11 Так и не получилось!! // Начинаем работать. start: if (RВЗ) // Нет ИКсиrнала. { РНОТОСОМЕ = ОхО; RЛО = ОхОО; 
Отладка модуля 1 65 } i f (! RВЗ ) { // Появился ИКсиrнал for (k=O; k<ЗО;++k); // Поставим задержку. if (!RВЗ) // ИКсиrнал не пропал? { РНОТОСОМЕ = Охl; RЛО = ОхО1; } } e1se { РНОТОСОМЕ = ОхО; RЛО = ОхОО; } while (РНОТОСОМЕ == 1) { // Обработаем ИКкоманду. ircmd (); break; } // Нет ИКсиrнала, проверим сеть. CREN =Ох1; input = getch(); switch (input) { case "С": // Если обращение к фото модулю. for (i=l; i<б; ++i) // Запишем команду в массив. { input = getch(); commandreciev [i] = input; } MODNUМ = simnumadr(); // Чтение из сети. if (MODNUМ != MODADDR) break; / / Если не наш адрес. e1se if (commandreciev [З] = "$") cmd(); // Если команда. default: goto start; } goto start; } 
166 rлава . 1 Базовая версия Схема и nporpaMMa MOAYnR И3llу..еНИR ИК-КОДОВ Модуль должен получать команду по сети и излучать ИКкод. В принципе, ИКкоды в «собственном формате» системы MOJYf храниться в EEPROM (можно использовать внетнюю энерrонезависимую память). Если мы хотим превратить M дуль излучения инфракрасных кодов в универсальный пульт ИКуправления, запоминающий коды дрyrих пультов, допол нительная внетняя память может оказаться обязательной составляющей. Для этой цели можно добавить к модулю ф топриемник и подпроrрамму считываниязапоминания. Но вернемся к конкретной задаче (рис. 1.53). Ниже приведена таблица составляющих (табл. 1.7). Таблица 1.7. Спецификация модуля изпучения ИК-КОДО8 N5t Обозначение Изделие Количество Цена (р.) 1 ОО1 МДХ1483 1 96 2 ОО2 PIC16F628A 1 100 3 ОО3 LM2936Z5 1 68 4 VD1 АЛ307 1 3 5 VD2 АЛ144Д 1 20 6 С 1, С2 О, 1 мкФ 2 2 7 С3 100,0 мкФ 168 1 5 8 R 1, А2 1 кОм 0,25 8т 2 1 9 A3A6 10 кОм 0,25 8т 4 1 Ориентировочная стоимость элементов  297 руб Команды: Ixx$nP и байты данных, rде n  количество повторов. Байты данных в файле input.irc на диске компьютера, за писанные с помощью HEXpeдaKTopa: 02 02 32 В1 26 5D 26 26 26 5D 26 26 26 5D 26 26 26 26 26 5D 26 5D 26 26 26 5D 26 26 FF 
Схема и проrрамма модуля излучения ИК-КОДОВ 167 А1 Х1 7 6 МдХ1483 4 2 3 6 J!1 51 10 5 11 12 13 5 Рис. 1.53. Принципиальная схема модуля излучения ИКкодов Проrрамма МОДУJlRиэпучеНИR ИК-КОДОВ на Rэыеe С Фаiin ronoBKa .#define MODULNAМES1M "1" unsigned char getch(void)i int ini tcomms ( ) ; int cmd (); void irtrns ( ) ; Основно;; фаiin #include <pic16f62xa.h> #include <stdio.h> #inc1ude nirtransfn1.h" unsigned char input; // Считываем содержимое приемноrо реrистра. unsigned char MODSIM1; / / Первый символ адреса модуля. unsigned char MODSIM2 i / / Второй символ адреса модуля. unsigned char commandreciev [6]; // Массив для полученной команды. 
168 rлава . 1 Базовая версия int MODADDR; int MODADDR; int simendnum = о; int MODNUМ; int i = о; unsigned char Ь = о; int с = о; int d = о; int k = о; int 1 = о; int m = о; / / Заданный адрес модуля, как число. // Заданный адрес модуля, как число. // Полученный адрес модуля, как число. unsigned char ircmd [60]; команды. unsigned char getch() { // Массив для прочитанной ИК while( !RCIF) / / Устанавливается, коrда реrистр не пуст. continue; return RCREG; } int ini tcorpms ( ) { PORTA = ОхО; CMCON = Ох?; TRISA = ОхО; TRISB = OxFE; RCSTA = ОЬ10010000; TXSTA = ОЬООООО110; SPBRG = Ох68; RBO = о; CREN =1; / / Инициализация модуля. // Настройка портов А и В. // Настройка приемника. // Настройка передатчика. // Настройка режима npиемапередачи. // Выключаем драйвер RS485 на передачу. / / Определим номер модуля. MODADDR = PORTB; // Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. for (i=O; i<61; ++i) ircmd[i] = ОхОО; i = о; RЛ2 = 1; } // Преобразуем символьный адрес в число. int simLnumadr() { 
Схема и проrрамма модуля излучения ИК-КОДОВ 169 simendnum = о; MODSIM1 = comrnandreciev [1]; // Первый символ номера. MODSIM2 = comrnandreciev [2]; // Второй символ номера. MODSIM1 = MODSIM1  Охзо; MODSIM2 = MODSIM2  Охзо; simendnum = MODSIM1*OxOA + MODSIM2; return simendnum; } int cmd ( ) { i=O; // Принимаем данные. whi1e ((input = getch(» != OxFF) { ircmd[i] = input; ++i; } ircmd[i] = input; } void irtrns () { 1 = о; for (1 = о; 1<4; T+1) { с = зi whi1e (ircmd[c] != OxFF) команды. { // Наш байт окончания // Импульс. Ь = ircmd [с] ; ++с; whi1e (Ь != о) { НА1 = 1; RЛ1 = 1; НА1 = 1; RЛ1 = 1; НА! = 1; RЛ1 = 1; НА1 = 1; 
170 rлава . 1 Базовая ве р сия НА1 = 1; НА1 = 1; НА1 = 1; НА1 = 1; НА1 = 1; НА1 = о; НА1 = о; Ь; } / / Пауза. Ь = ircmd[c]; ++с; while (Ь != О) { НА1 = о; НА1 = о; НА1 = о; НА1 = о; НА1 = о; НА1 = о; НА1 = о; НА1 = О; НА1 = о; НА1 = о; М1 = о; НА1 = о; НА1 = о; НА1 = о; Ь; } } for (m=О; m<156З; ++т); // Пауза в 25 мс. } for (i=O; i<61; ++i) ircmd[i] = ОхОО; i = о; } void main(void) { // Начнем работать. ini tcomms ( ) ; / / Инициализация модуля. for (k=O; k<6; ++k) commandreciev [k] = " "; commandreciev [О] = "1"; 
Схема и проrрамма модуля излучения ИК-КОДОВ 171 //Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах MODADDR=MOD:"ADDR»4; / / Сдвинем на четыре бита. / / Ждем прихода команды и данных. start: RЛ2 =1; input = getch(); switch (input) { case "I": // Если обращение к модулю ИК команд. for (k=l; k<6; ++k) // Запишем команду в массив. { input = getch(); commandreciev [k] = input; } MODNUМ = simnumadr (); / / Определим, к кому адреcyюrся. if (MODNUМ ! = MODADDR) break; / / Если не наш адрес. else if (commandreciev [5] == "Р") { and ( ) ; / / Если команда. irtms ( ) ; / / Отправим ИК команду на излучатель. } default: goto start; } goto start; } НЕХ-фаiin Дn8 эаrррки в nporpaMMar.p :10000000830100308A0004282030840078300D20DD :1000100083012D2B04068001840A0406031D0A288F :020020000034М :100552008ЗО18С1ЕА92АIА080800FС01FD01031060 :10056200FBOCFAOC031CВC2A7808FC077908031858 :10057200790AFD070310F80DF90D7A087B040319B7 :100582000034B02A8301AC01ADOID02A2C083C3ED4 :100592008400831323088000ACOA0319ADOM92240 :1005A200A300230FC72A2C083C3E84008313230890 :1005В200800008008301В401В5013708АОО03808А3 :1005C200A100D030A007AI070A30FAOOFB012008El :1005D200F800F901AE2221087C07B4007D08031857 
172 rлава . 1 Базовая версия :1005E2007DOAВ500F9003408F8000800830185018E :1005F20007309F0083168501FE30860090308312FB :100602009800063083169800б830990083120бl00D :100б1200181бОб08А400А5010430F800250DА50С43 :10062200A40CF80BOF2ВAC01AD012D08803AF80099 :10063200803078023D3003192C020318292B2C0834 :100642003С3Е840083138001АСОА0319ADОА1б2ВС9 :100б5200АС01AD0105150800F722АЕОIAFО13А2В3Е :100б62002Е083б3Е8400831320308000АЕОА031920 :100б7200AFОА2F08803AF800803078020б3003195А :100б82002Е02031С312В4930В6000б08А400А50136 :100692000430F800250DA50CA40CF80B4B2B7C2B79 :1006A200AE01AEOAAF012F08803AF800803078021E :1006В2000б3003192Е020318бА2ВА922А3002Е08б2 :1006С2003б3Е8400831323088000АЕОА0319AFОАб2 :100БD200542ВDВ227808АБО07908А700250б031D03 :1006E200742B24082606031D7C2B3B08503A031D5D :1006F2007C2ВC32283230515A922A300493A03199F :10070200512B7C2B8301B001B101B001B101DE2B71 :100712000330А800А901С52В28083С3Е840083139Е :100722000008А200А80А0319А90АА2080319А92В02 :1007320085148514851485148514851485148514EF :10074200851485148514851485108510А203962ВВ3 :100752002808ЗС3Е840083130Q08А200А80А03195В :10076200А90АА2080319С52В8510851085108510СА :1007720085108510851085108510851085108510CF :1007820085108510A203B22B28083C3E84008313F7 :10079200000F8D2ВВ201В3013308803AF8008б308б :1007A20078021B30031932020318DB2BB20A031939 :1007В200В30АСD2ВВООА0319В10А3108803AF8000б :1007C20080307802043003193002031C892ВAC01FB :1007D200AD012D08803AF800803078023D300319CF :1007E2002C020318FD2B2C083C3E8400831380014D :OE07F200ACOA0319AD0AEA2ВAC01AD010800F8 :OOOOOOOlFF Возвращаясь к представлению в некотором «собственном формате», попробуем «прикинуть», как все будет выrлядеть. EEPROM хранит 128 байт. Если мы будем использовать модуль излучателя ИКкодов для одноrо устройства, сколько управляющих команд нужно для Hero в системе? Возьмем, например, DVDпроиrрыватель. Какие команды нужны пользователю, чтобы смотреть фильмы? Проиrрать, Стоп, 
Схема и проrрамма модуля излучения ИК-КОДОВ 173 Предыдущий фраrмент, Следующий фраrмент, rромче, Тише, ВЫКЛЮЧИТЬ звук, команды курсора Влево, Вправо, Вверх, Вниз, Ввод, Меню. Для pOBHoro счета возьмем 15 команд. Таким образом, на одну команду мы можем потратить 8 байт. MHoro это или мало? Ответ на вопрос следовало бы искать в следующем раз деле  «Модуль считывания инфракрасных кодов», проведя считывание всех интересующих нас ИКкоманд. В данный момент я ретаю, что нет смысла хранить коды в модуле воспроизведения ИКкоманд, будем хранить их на компьютере. Предварительно примем формат команды вида, показанноrо в табл. 1.8. Таблица 1.8. Предnолаrаемый формат ИКкода Устройство Команда Повторов Коэффициент ЧаС1'ота ? байт ? байт байт байт 2 байта Импульс Пауза и т .д. EOF 2 байт 2 байта байт О При этом в отличие от предыдущих модулей, модуль излу чения должен получать по сети не только команду, но и дaH ные, следующие за ней. Если мы определим префикс модуля с помощью латинской буквы «1», команда может выrлядеть СЛ дующим образом: Ixx$nP и байты данных, rде n  количество повторов. Я думаю, что повторов от О до 9 должно хватить. Байты данных начнутся с байта коэффициента и закончат ся нулевым байтом. Мы не знаем, сколько именно будет пе редано байт. Для определенности возьмем 50 байт. Значит, все данные будут переданы приблизительно через 50 мс. После приема данных модуль может начать воспроизведение ИКкода. Таким образом, задержка между нажатием на клави ту управления и отправкой управляющеrо ИКкода будет не более 0,1O,2 с. Думаю, не слитком MHoro. Осталось два момента, которые мене сейчас не ясны. Пер вый  хватит ли места в реrистрах контроллера для xpaHe ния команды. В первых двух банках памяти 176 байт OTBeдe но для реrистров общеrо назначения. Полаrаю, этоrо хватит, но хранение в двух банках... 
174 rлава . 1 Базовая версия Второй момент, смущающий меня, относится к некоторой вероятности Toro, что передаваемые данные, а это байты, совпадут с видом команды. Не думаю, что это очень вероят но, но эту неприятность мы можем отслеживать на этапе за писи ИКкода. Если, паче чаяния, это произойдет, воспользу емся коэффициентом пересчета, преобразовав данные к дрyrому ви Теперь мы rOToBbI начать разработку HOBoro модуля. За основу возьмем предыдущий модуль, у KOToporo исполь зуем вывод RA6 на выход. К этому выводу порта мы будем подключать светодиод ИКдиапазона (излучатель, или ИК эмиттер) . Как оычно, я создаю папку в рабочей папке MPLAВ, KOTO рую называю irtrans, и копирую в нее все файлы предыдуще ro модуля. Теперь я открываю в проrрамме MPI.AB предыду щий проект, но уже из этой папки. Сохраняю ero под новым именем  irtrans, а также файл заrоловков и проrраммы, меняю их в менеджере проекта, включая файл todo.txt, Ha страиваю установки Debugger. Осталось поменять файлы сце.- нария, удалить из папки все старые файлы, и можно начинать рабо Вся эта процедура необязательна. Можно открыть новый проект, но при этом не следует забывать, что все ero настрой ки следует сделать заново. Задать рабочую тактовую частоту контроллера и скорость выполнения анимации. Иначе мож но наступить на rрабли, которые подстереrали нас в самом начале работы. В отличие от предыдущих данный модуль при настройке должен прочитывать из файла input.txt последовательность данных. Вернемся к рекомендациям изrотовителя микроконт- роллера PIC16F628A и после строки команды в файле input.txt впитем данные в виде тестнадцатеричных чисел, записан ных в столбик и завертаемых командой OAh. Но сначала под rотовим их. Возьмем код из раздела «Модуль считывания ин фракрасных кодов». pulse 2455 3аrоловок space 532 pulse 1291 Единица арасе 506 
Схема и проrрамма МОДУЛЯ излучения ИК-КОДОВ 175 pulse 664 Ноль space 533 pulse 1266 Единица ерасе 533 pulse бб Ноль space 591 pulse 1211 Единица ерасе 533 pulse 685 Ноль space 515 pulse 693 Ноль space 526 pulse 1271 Единица ерасе 506 pulse 1265 Единица ерасе 533 pulse 666 Ноль space 557 pulse 1241 Единица ерасе 533 pulse 664 input.txt "R03$ON" "I03$5P" Команда обращения к модулю трансляции ИК команды 01 01 25 97 числа) 09 14 02 Е3 04 4А 02 4А 02 4А 02 Е3 04 4А Количество повторов Коэффициент Частота несущей 37 кrц МЛаДШИЙ байт импульса заrоловка (шестнадцатеричноrо Старший байт импульса заrоловка Младший байт паузы Старший байт паузы Младший байт импульса единицы (1251 МКС  среднее) Старший байт импульса единицы Младший байт паузы единицы (586 мкс  среднее) Старший байт паузы единицы Младший байт импульса нуля (586 мкс  среднее) Старший байт импульса нуля Младший байт паузы нуля (586 мкс  среднее) Старший байт паузы нуля Младший байт импульса единицы (1251 мкс  среднее) Старший байт льса единицы Младший байт паузы единицы (586 мкс  среднее) 
176 rлава . 1 Базовая версия 02 Старший байт паузы единицы 4А Младший байт ИМПУЛl;lса нуля (586 мкс  среднее) 02 Старший байт импульса нуля 4А Младший байт паузы нуля (586 МКС  среднее) 02 Старший байт паузы нуля Е3 Младший байт импульса единицы (1251 МКС  среднее) 04 Старший байт импульса единицы 4А Младший байт паузы единицы (586 мкс  среднее) 02 Старший байт паузы единицы 4А Младший байт импульса нуля (586 мкс  среднее) 02 Стq.рший байт импульса нуля 4А Младший байт паузы нуля (586 мкс  среднее) 02 Старший байт паузы нуля 4А Младший байт импульса нуля (586,МКС  среднее) 02 Старший байт импульса нуля 4А Младший байт паузы нуля (586 мкс  среднее) 02 Старший байт паузы нуля Е3 Младший байт импульса единицы (1251 мкс  среднее) 04 Старший байт импульса единицы 4А Младший байт паузы единицы (586 мкс  среднее) 02 Старший байт паузы единицы Е3 МлаДШИЙ байт импульса единицы (1251 мкс  среднее) 04 CTap байт импульса единицы 4А Младший байт паузы единицы (586 мкс  среднее) 02 Старший байт паузы единицы 4А М}Iадший байт импульса нуля (586 мкс  среднее) 02 Старший байт импульса нуля 4А Младший байт паузы нуля (586 мкс  среднее) 02 Старший байт паузы нуля Е3 Младший байт импульса единиuы (1251 мкс  среднее) 04 Старший байт импульса единицы 4А Младший байт паузы единицы (586 мкс  среднее) 02 Старший байт паузы единицы 4А Младший байт импульса нуля (586 мкс  среднее) 02 Старший байт импульса нуля 00 Завершающий нулевой байт Конечно, файл не должен содержать моих пометок. Я ис пользовал одинаковые усредненные числа. Прав ли я? Это можно будет проверить только при воспроизведении. На дaH ном этапе это не иrрает роли. Позже, возможно, мы напитем проrрамму, которая будет упаковывать считанные данные. Посмотрим. 
Схема и nporpaMMa МОДУЛЯ излучения ИК-КОДОВ 177 Теперь нам нужно позаботиться о том, rде мы будем xpa нить полученные данные. Для этой цели используем массив беззнаковых символов: unsigned char rcmd [53]; Я задал массив длинною в 53 байта. Вообще мы не знаем, какой длины получится массив, но можно вернуться к этому позже. Основной переделке подверrается функция прочитыва ния команды. За последним символом команды · Р' следуют данные. Количество повторов мы получаем перед командой. Но мы оставили под это байт данных. Поэтому пока будем ИI'норировать количество повторов в команде. Ожидаем · Р · , начинаем заполнение массива. Основная часть проrраммы: // Начинаем работать. // Ждем прихода команды и данных. start: while(input != MODULNAМESIM) input = getch()i // Ждем обращения к модулю. cmd (); / / Обработаем сетевую команду. goto start; // Обработка сетевой команды. int cmd() { MODNUМ = simnumadr ( ) ; if (MODNUМ == MODADDR) { while (input != "Р") input = getch()i // Ждем. if (input  "Р") // Если символ завершения команды { // Чтение из сети (файла). / / Если наш адрес модуля. // Принимаем данные. while (i<54) { input = getc}l ( ) ; ircmd[i] = input; ++i; } } } } 
178 rлаВQ . 1 Базовая версия Перед запуском проrраммы я не забываю установить в высокое состояние биты, имитирующие переключатель aдpe са модуля (RВ4, RВ5 в окне Stimulus Controller). Очередные .rрабли, на которые я наступаю,  проrрамма не pa ботает. После первоrо символа в реrистре приемника USART появляется 02. .Это не номер модуля. дальше ничеrо не получа ется. Не пытаюсь разобраться, просто добавляю в файл input.txt еще пару команд перед командой обращения к модулю. "R02$lN" "R01$lN" "IОЗ$5Р" Теперь проrрамма работает, массив заполняется. Добавив ero в наблюдение, можно посмотреть, как он заполняется, и есть ли печатные символы в натих данных. После заполнения массива мы rOToBbI передать ИКком у нас три временных интервала: pulse 2455 3аrоловок space 532 pulse 1291 Единица Несущая частота  37 кrц период --27 мс. Через время --13 МС будем менять состояние вывода RA6 порта А, если у нас в масси ве записан импульс. Можно, как в проrрамме предыдущеrо модуля, использо вать встроенные таймеры контроллера. Но для начала попро 'буем использовать простые циклы. void irtrns () { i = о; с = з; / / в первых трех байтах служебная информация. while (ircmd[i] != о) // Наш байт окончания команды. { // Импульс. Ь = ircmd[c+1]; // Сначала прочитаем старший байт. Ь = Ь«8; // Сместимся на один байт. Ь = Ь + ircmd[c]; //Сложим байты, получая длительность импульса. с = с + 2; // Сместимся на два байта. 
Схема и проrрамма МОДУЛЯ излучения ИК-КОДОВ 179 whi 1 е' (Ь ! = о) { for (d=0;d<14;++d) RA6 = 1; // Теперь с частотой в 37 кrц for (d=0;d<14;++d) RA6 = о; // будем создавать несущую // частоту. Ь; . } // Пауза. Ь = ircmd[c+l]; Ь = Ь«8; Ь = Ь + ircmd[c]; //В этой переменной мы храним длительность паузы. с = с + 2; while (ь != о) { for (d=0;d<28;++d) RA6 = о; // Передаем паузу. ь; } } } в rлобальные переменные я добавил несколько индексных переменных. Их можно добавить локально, но rлобальные переменные удобнее наблюдать. int i = о; int Ь = о; int с = о; int d = О; Пытаясь передать массив, я обнаружил, что по умолчанию он не обнуляется, поэтому в раздел инициализации модуля я добавляю обнуление массива. Проблема, которая возникает без этоrо обнуления, состоит в том, что мы записываем байт, а работаем с двухбайтовыми числами. Нулевой байт записы вается в конец массива, но второй байт не нулевой, тоrда как условие while (ь != о) // rде Ь  целое. for (i=O; i<61; ++i) ircmd[i]  о; // Обнуление массива. теперь, вроде 4 бы все работает, но мне хочется посмотреть, что транслируется излучателем, соединенным с выводом 
180 rлава . 1 Базовая версия RЛ6. Проrрамма позволяет воспользоваться проrраммным. лоrическим анализатором. Для этоrо я выделяю всю часть void irtrns ( ) , правой кнопкой мыти вызываю раскрываю щееся меню, в котором выбираю раздел Add Filter - in Trace (Добавить фильтр - в Трассировку). Теперь, во View (Вид) OCHOBHoro меню добавляю к рабочему окну Simulator Trace (Симулятор трассировки) и жду, коrда заполненный массив начнет транслироваться. Я ожидаю, что мне удастся увидеть весь передаваемый через RЛ6 код. Запускаю Simulator Logic Analyzer (Симулятор лоrическоrо анализатора), в котором с помощью кнопки Channels (Каналы) вхожу в меню выбора отслеживаемых выводов. Затем выбираю RЛ6 и добавляю вывод в наблюде ниеАdd (Добавить). Вопреки желаемому, потратив достаточно MHoro времени, получаю очередное напоминание о «rраблях». Удается зафик сировать только фраrменты. Пытаюсь добавить управление еще одним выводом порта А  RЛО, устанавливая единицу перед формированием импульса и сбрасывая в ноль при пау зе. Единственное, что получилось,  это ряд фраrментов, по казанных ца рис. 1.54 1.56. RAO  -  . 500m О I 100ххю.Q I 1500m О Рис. 1.54. Первый фраrмент эксперимента с лоrическим анализатором Первый из фраrментов относится к моменту завертения передачи заrоловка. Во втором следом за заrоловком переда ется единица. На последнем фраrменте видно, что передача несущей сменяется паузой. Не ryCTO. Оставлю проrрамму модуля, удалив управление выводом RЛО, и проверю работу модуля, коrда соберу ero. У меня нет уверенности, что частота несущей  37 кrц (или близка к ней), 
Схема и проrрамма модуля излучения ИК-кодов 181 r+; '/  О- ,- " _ .,. !::'6fil1iiI '. ,. /:' RДO - ". _.::::_. ::: ...... , " '1 l' . I t I . I I , smm.Q 1ШDЮ.Q 1smm.Q 2fXXXXX).Q Рис. 1.55. Второй фраrмент эксперимента с лоrическим анализатором W<t-. - О"'. .'. Af.-:_g- f r: f __ RA6 RДO I 41ЮХЮ.Q I 419(Ю).Q I 42OOXIO.Q Рис. 1.56. Третий фраrментэксперимента с лоrическим анализатором а длительность ипульсов и пауз не требует дополнительной калибровки. Пока я не MOry сделать больше, оставлю все, как ecrь. #include <рiс1бfб2ха.h> #include <stdio.h> #include .irtrans.h. unsigned char input; реrистра . unsigned char MODSIM1; unsigned char MODSIM2; int MODADDR; int MODADDR; int sim1num = о; int sim2num = о; int simendnum = о; int MODNUМ; int i = о; int Ь = о; int с = о; / / Считываем содержимое приемноrо / / Первый символ адреса модуля. // Второй символ адреса модуля. / / ЗадаННЫЙ адрес модуля, как число. / / ЗадаННЫЙ адрес модуля, как число. / / Полученный адрес модуля, как число. 
182 rлава . 1 Базовая версия int d = О,; unsigned char ircmd [60]; unsigned char getch() { while(!RCIF) // Устанавливается, коrда реrистр не пуст. continue; return RCREG; } // Вывод одноrо байта. void putch(unsigned char byte) { PORTB = 1; TXEN = 1; while( !ТXIF) continue; TXREG = byte; } int ini tcomms ( ) { PORTA = ОхО; CMCON = Ох?; TRISA = Ох80; TRISB = OxF6; RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох16; INТCON=O; PORTB = о; //Переключим драйвер RS485 на передачу. // Разрешаем передачу. // Устанавливается, коrда реrистр пуст. / / Инициализация модуля. // Настройка портов А и В. // Настройка приемника. /1 Настройка передатчика. / / Настройка режима приемапередачи. / / Запретить прерывания. 11 Выключим передатчик драйвера RS485. / / Определим номер модуля. MODADDR = ЮRТВ; / / Номер модуля в старших битах. MODADDR=MODADDR»4; / / Сдвинем на четыре бита. for (i=O; i<61; ++i) ircmd[i] = о; } / / Преобразуем символьный адрес в число. int simnumadr() { simendnum = о; sim1num = getch(); номера. MODSIMl = sim1num; sim2nurn = getch()i //Чтение первоrо символа / / Сохраним первый символ. / /Чтение BToporo символа номера. 
Схема и проrрамма модуля излучения ИК-КОДОВ 183 MODSIM2 = sim2num; / / Сохраним .второй символ. sim1num = simlnum  Охзо; sim2num = sim2num  Охзо; simendum = simlnum*OxOA + sim2num; return simendnum; } iпt cmd ( ) { MODNUМ = simnumadr(); // Чтение из сети (файла). if (MODNUМ == MODADDR) / / Если наш адрес модуля. { while (input != "Р") input = getch(); // Ждем. if (input  "Р") // Если символ завеI?шения команды. { i=O; / / Принимаем данные. while (i<S4) , { input = getch(); ircmd[i] = inputi ++i; } } } } void irtrпs () { i = О; с = з; while (ircmd[i] != О) / / Наш байт окончания команды { // Импульс. Ь = ircmd[c+1]; Ь = Ь«8; Ь = Ь + ircmd[c]; с = с + 2; МО = 1; whi 1 е (ь ! = О) { for (d=0;d<14;++d) RAб = 1; for (d=0;d<14;++d) М6 = о: b; 
184 rлава . 1 Базовая версия } // Пауза. Ь = ircrnd[c+l]; Ь = Ь«8; Ь = Ь + ircmd[c]; с = с + 2; МО = о; while (ь != О) { for (d=0;d<28;++d) RAб = О; ь; } } } void main(void) { // Начнем работать. initcomms () i / / Инициализация модуля. / /Прочитаем и преобразуем номер модуля  MODADDR = PORTBi // Номер модуля в старших битах. MODADDR=MODADDR»4i // Сдвинем на четыре бита. // Начинаем работать. / / Ждем прихода команды и данных. start: while(input != MODULNAМESIM} input = getch()i / / Ждем обращения к модулю. cmd (); / / Обработаем сетевую команду. irtrns ( ) ; / / Отправим ик команду на излучатель. goto starti } Все получается разумно и красиво, лrично и rpaMoTHo. Ай , , да я. Смущает одно. Коrда я проверяю времена, соответствую щие картинкам анализатора, получаю совсем не то, что XOTe лось бы. В моем приборном арсенале нет записывающеrо oc циллоrрафа. Представив, как я пытаюсь поймать и измерить последовательность импульсов ИКкоманды обычным осцил лоrрафом (если вам не приходилось, попробуйте), я решаю вернуться к MPLAВ. Верю я тем, кто создал эту замечательную проrpамму! И начинаю понимать, что совсем не «Ай, да я!». rде-то я ошибаюсь. 
Схема и проrрамма модуля излучения ИК-КОДОВ 185 Напишем простую проrраммку: #include <рiс16fб2ха.h> #include <stdio.h> int d = о; "int с = о; int iпitсопuns () { PORTA = ОхО; CMCON = Ох?; TRISA = Ох80; TRISB = ОхFб; RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох1б; INТCON=O; PORTB = о; } void main(void) { / / Инициализация модуля. // Настройка портов А и В. / / Настройка приемника . // Настройка передатчика. // Настройка режима приемапередачи. / / Запретить прерывания. // Выключим передатчик драйвера RS485. initcomms () ; // Начинаем работать. / / Здесь поставим точку останова. start: for (d=0;d<2;++d) RAб = 1; for (с=0;с<2;++с) RAб = о; goto start; } Настроим, установив тактовую частоту контролЛера 4 мrц, все, что настраиваем обычно. Выделим с помощью Add Fil- ter - in Trace строки, выделенные в тексте, и в пошаrовом режиме сделаем четыре mara по проrрамме. Посмотрим, что нам рисует лоrический анализатор (рис. 1.57). Время, определяемое в циклах команд контроллера для состояния «О»,  около 75 циклов, или 75 мкс. Но я устанавли ваю, как я полаrал, вывод RЛ6 в ноль на один цикл. В состоя- нии «1», что по моим предположениям тоже должно COOTBe ствовать 1 мкс, я «зависаю» на 78 мкс. Проверяю MapKpOM (рис. 1.58). 
186 rлава . 1 Базовая версия r-;--:- " - . " .. "- .... .. I+:'<\;:r' Q" .» ,';.,;, :I. ;:; g ':.: r' , I 1 g.,..!....!,...!..,.!..., G I ЕЮ.о 100.0 120.0 140.0 160.0 1ЕЮ.о 200.0 Рис. 1.57. Отображение лоrическим анализатором пошаrовых команд .. . ....-.:.. -с..;. ..... "" ...... ....'оС...,....... .-.;;........  1 Q} ...щ. + ........  """" I ' .......... I  , . I . , , 41 , I I I I I I I , I , . I . I . . , . I I , I . I I , ЕЮ.О 100.0 120.0 140.0 160.0 1ЕЮ.о 200.0 Рис. 1.58. Измерение интервала времени маркером Так и есть. Не нравится мне это, но пока я не понимаю, в чем дело. Включив в Simulator Trace режим просмотра в инжене ных единицах, я получаю следующую картинку за один пр<r ход моих циклов for (вид проrраммы в трассировщике MPLAВ)  рис. 1.59. Это не полная картина трассировки, строки следуют до номера 45, что соответствует моменту времени в 115 мкс от начала процесса. r:F?" ;."" .->" >, '4 , .. , r   1........ ш.... .. I , , . l' . II II I . I I I I I I I I l' I I I l' I I I I II , l' I I I II I l' I 70.0 75.0 ЕЮ.о 85.0 90.0 950 100.0 105.0 110.0 115.0 Рис. 1.59. Определение интервала времени одноrо прохода цикла for и я медленно начинаю понимать... Это в своем правильном лоrическом мире, описанном язы ком С, я за одну команду успеваю перейти от «О» К «1» и об ратно. В реальном мире контроллера это занимает ровно столько времени, сколько требует команд. На 82й микрос кунде текущеrо времени я устанавливаю RЛ6 в единицу, что трассировщик отображает в 12й строке командой BSF Ох5, Охб (рис. 1.60). 
Схема и проrрамма модуля излучения ИК-КОДОВ 187 R , 1I , . . I. , . . " , I' J f...... " } ' '' , , " , ' : , '<',. ,"" "'"',', "',.,','.'"',,',,',"".>;,",,..'' ,",,"":,',",' ,:,', ", ,)( ,. " '"' """", , "! :t:!i:,iI ':::'::fj*r,: ',:'.,,"':1,:;.:j',._ ;" ,:Р,,!А ',I,. ;':;::':::,J:.;.t:::, "', , ",. "".,"" ":"""" ',\и., 'Q" , :... "., о 07ОI 01&% CLar Ох12     1 07Dr 011.3 CLar Ох23     а 0710 0823 IIOVF Ох23. I 0013 00 0023 00 . 0711 3...0 ZoaLI ОхlО I  I 00 . 0712 ooro IКNП Ох70   0070 10 5 0713 3080 IЮlfl.I 01180 I  I 10 . 0714 0270 I1I8П Ох70. I 0070 10 0070 00 7 0715 3002 IЮlfl.I Ох2 I  I 02 1 071. 1903 IПIК Ох3. Ох20ОО3 lr -  . 0717 0222 I1I8П 01122. I 0012 00 0022 ,1 10 0711 1103 IПIК Ох3. О 0003 18   11 070 0000 lIQf 0000 00   12 0711. 1705 15, 0115. Ох. 0005 00 --  13 0711 o.uz DlCr Ох22. r 0012 00 0022 01 1. 071С 1903 IПIК Ох3. 01120003 11   15 0710 0000 110. 0000 00   1t 0711 2rlo оото Ох7еО -   - 17 071r 0000 tюP   -  11 0710 0823 IIOVF Ох23. I 0013 00 ооzз 00 1. 0711 3...0 ZoaLI 0...0 I  I 00 20 0712 ooro 80VП Ох70   0070 10 21 0713 3080 IЮlfl.I ОхIO I - I 10 22 0714 0270 I1I8П Ох70. I 0070 80 00'70 00 23 0715 3002 IЮlfl.I Ох2 I  I 02 24 071. 1903 Iтrsc: Ох3. Ох2 0003 Ir   25 07" 0222 11I8П 01122. I 0012 01 0022 rr .. 0711 1103 IПIК Ох3. О 0003 11  - 27 071. 0000 lIQf 0000 00   28 0711. ''705 II, Ох,. Ох' 000. 40  - 2. 0711 o.uz DlCr Ох22.' 0012 01 0012 02 30 071': 1903 IПIК 0113. Ох20ОО3 11   31 0710 0000 lIQf 0000 00   32 0711 2rl0 оото Ох7еО     33 07и 0000 lIQf     34 0710 0823 IOVI' Ох23. I 0013 00 0023 00 JS 0711 31.80 ZoaLI 0...0 I  I 00 3 0712 ooro 80VП Ох'70 -  00'70 10 T, "''Т""-'J<""""'. " ;,' , 'I8CIUd8 c,Lo1te.211..b> 'laclUd8 c8Cd'o.b> ':","""и-:'::',"'" "f; '70. 000e. 71.000e' 72.000е-' 73.000е-' 74 .000e, ".000e' 76.000e' 77 .000e. 71.000e' 7tI.000e' 1O.000е-' 11.000e' .2 .000e, 13.000е-' 14.000е-' . 15.000е-' ".000e, 17.000e' ".000.--' ".000e, 9O.OOOe. .1.000e' .2.000e' 13 .000e, '4.000e' ".000e, ".000e. ".000е-' ".000e, ".000e, l00.000e' 10l.000e' 102.000e' 10'.000e' 104.000e' 105.000e' IO'.OOOe' ". "./.: -::<) '-';;,,:" :..;. :-.::...:.:....-:.:.. '.:'..:'/'::.::_:,,:: ".-.. -::":::r-:.-::}::::::-:::\.:.. ):. y\::.;::.:==>.(./. ..:."::;":" .:'... :'.':-",:(:.:;..:':..:-::. А 1", 1 '; . ::': '> 1" i':; k 1" 1'-- 1'" ," j.-. '., < ".-<"""':. .:-(.--r- '.,"',"f"!'.''':' D ,,' ," "а" ....'" . ".с-". ,_." ...... . ". ..... . ." '-.:;'-:: ", _.. :::;.":., ._. ""':."":..'Z;'. :.;-::.. .::.. и.. ..::_. .: .. ..:.; :':'::.<h... ." ;__,а'< Рис. 1.60. Вид nporpaMMbl в трассировщике MPLAB Спасибо проrраммистам. создавшим nporpaMMY MPLAB сидеть бы мне за осциллоrрафом. чертыхаясь. долrо и бе зуспешно! Спасибо тем. кто учил меня писать nporpaMMbl в машинных кодах. KorAa я начал заниматься микропроцессорной техни- кой; тем. кто терпеливо пояснял мне. как правильно отсчиты вать «branch» в командах! Посыпав rолову пеплом, как и полаrается, попробуем из менить ситуацию к лучшему. В первую очередь, постараемся добиться, чтобы циклы были одинаковы. Я же хочу получить меандр частотой 37 кrц. Экран в данный момент выrлядит, как показано на рис. 1.61 (я добавил внешний цикл for). Изменив часть проrраммы и манипулируя числами, я He сколько меняю результат (рис. 1.62): start: а = О; while (а<100) 
188 rлава . 1 Базовая версия { for (d=0;d<3i++d) RAб = 1; for (с=О;с<2;++с) RAб = о; ++а; } goto start; ri 1i_ "'I; ;j1t...:"' ''''','' "'" ......., '..,. :'х.: ;: ,.. .. ::.,: .::..;;. ':'' ':T: .; :f..;;:::;'I;'.'.;.:,:::{:;A" О""'4{" :ЙМ<У';;' 'i!tt{"""'/"""""""""" .;€:. ::(<. ::.'.'.' :,....t)...,.:.-y( : .  : ;:':::;..?'c: :';!f;tl.:::'::::]: ы :- Q НМd8r..... r' . {; ";:;;:-':: : pcllNЪ:. h ; t8tr..J." 0IIj0Ct ..... Ltlr8rY ..... : ow...... - ':::E.:-/:'-:'-:::.,:::: ::::'.' .: ...:. . ... . ;:',: ..,:,с;;,' ... .;. :.;:;:':'.::ij,::':' ,.,..д., "''. e::':%f<" :?' ,;(.;" '1{':):/':;.:'::...I  ..A}::<j' .< , ....".....:.;.:. . ..w, tt)N .., .:: lIOJIj "" J,!I_ :" '(;;.1. оои d 002 Z с: 0020 .:::'  ...."<, ,,', "'..: tIO It. t,<:) dl.play. ID5U. 111.. 1Тe 1. .......18'1 111 1'''''''7,,*1' S.t.ill 0IlOO02 0.0002 0.0004 .. :':;-.. -:- :. :t.::::.>::w-.("-::-:};;::......:::":::=:::-::;_;:,,'=:::_::.. *:....:.;.::-': 11 ........... РаОО1'8'" ,'" g l!;.. ""J.'-' . ';;'"':':"'"'"":"::''':'''':'':W: "':.:.".:':.,-- :>'%"'Y"":"""':""\";::;.C?,:;....'. ;1:....:.:':J>\*-T ...., : у..... "1!-:>,.. ';.: :'.:.,.,.:",'" '..)1( f..f"'. МfUl5aI" ..." . '.' , 13  i _ С.."а, ....loНa..... с _ 1.6-C;.«f.,.t.. ... . .1; ,... 'c-(\.....l:...' ... . о. , .... aen, ... .t.ti.tic Tot.l JЮ.  Tot.l R.\II  ., word8 (С 3") 7 byt.. (] 1") , Jf r:1 L.oeded O\bOOI<.....S\..2\lмt...Z.cot  ВUlLDSVCCEEOEO TueNovISI4S8.262005 G .. -:-:.-:-"., .....::::/ -::....y..."...,."..:::-:-;.X;... "';;-. ае.' "". - ".' . .." "'... .' "".< , ."'" .' Рис. 1.61. Экран отладки в MPLAB I +яot '.' :9 '0" .:, . .I .3&tii. I '(. I RМ j H , , , . !l-:-,:-.--Q. . , QД I 600.0 650.0 100.0 750.0 0.0 Рис. 1.62. Исправленный интервал времени несущей частоты Меандр я получаю, но частота несущей остается близка к 8 кrц, тоrда как мне нужна частота раз в пять выше. Пока я вижу несколько решений  повысить в пять раз тактовую ча стоту контроллера, настроить внешний reHepaTop на частоту 37 кrц или использовать внутренние резервы контроллера 
Схема и проrрамма модуля излучения ИККОДОВ 189 Попытка использовать таймер несколько улучшила ситуа ЦИЮ, но не в полной мере. Последний вариант, не затраrива ющий коренных переделок всей проrраммы или модуля, BЫ rлядит следующим образом: start: а = о; for (а=О i a<100i++a) { RAб = 1; RAб = 1; RЛ6 = 1; RAб = 1; М6 = 1; RAб = 1; RAб = 1; RAб = 1; RAб = 1; RAб = 1; RAб = О; RAб = о; } goto start; Получившийся при этом сиrнал показан на рис. 1.63. r+'': Q v"':".: ow ""_ fiI'. r/  . ;.Ц,-. -.:......:с:. 1 rn шш []l] IJШ I , I , , I I I I , I , , , . I , . . I I , I . , I I , , I I . . I I . I I , . 120.0 130.0 1.tO.0 150.0 160.0 170.0 1Ю.О 190 О Рис. 1.63. Исправленное значение величины несущей частоты Период сиrнала в 27 мкс соответствует частоте несущей 37 кrц. Это не самое изящное ретение. В первую очередь, теперь следует отказаться от изменения несущей частоты ИКкоманды «на лету». Модуль будет работать с фиксирован ной несущей частотой. Посмотрим, можно ли поправить пр rpaMМY модуля. Не забудьте проверить модуль приема ИКкодов Нет ли и там подобной ошибки! 
190 rлава . 1 Базовая версия с несущей частотой положение несколько улучшилось, но времена посылок раз в 10 превытают реальные. Первое, что мне ПРИХОДИТ в rолов  уменьшить в 1 О раз времена в файле input.txt. В этом есть и привлекательная сторона  теперь Mac сив, в котором я храню времена, становится не двухбайтовым, а однобайтовым. Но посылки все еще слишком длинные. Укорачиваем их еще вдвое, разделив значение времени на два уже в проrрамме. И последнее «заметание мусора под ковер»  деление в файле input.txt всех значений на 1,38. Мне не нравится то, что я делаю. Но в итоrе я получаю результат, показанный на рис. 1.64. [.E>..c: 'C' :' <. j. ,.' rr; .; :;J i... < .'. RAO RA6 , , . I J I I , I . I I . . . . . I . 45(ХХ).о 5(Ш).Q 55(0),0 6ШМ).о Рис. 1.64. Вид ИКсиrнала на экране лоrическоrо анализатора Это даже больше, чем я ожидал. BepHe, я ожидал этоrо в начале работы, но, не справившись с лоrическим анализат ром, отказался от попыток получить подобную картинку. ЗдеСI:"несущая, если ее увеличить, выделив затемненный уча сток сиrнала RЛ6 с помощью мыши и клавиши выбора на ин струментальной панели (пятая слева), выrлjЩИТ, как показа но на рис. 1.65, заrоловок имеет время, как на рис. 1.66, а единица и пауза, рис. 1.67 и 1.68, соответственно. 1:+:: .;.; .;:' . .") \. LJ .,. >. , r... RA6 RAO I 48150.0 , I I I I , , 1 I 48200.0 48250 О 48»:1.0 Рис. 1.65. Вид несущей частоты 
Схема н проrрамма модуля излучения ИК"КОДОВ 19-1 J+"  <> .'4 r,."..'  . r. / . . (.; RДO Rд6 f . I , I I J J I I I I "5(0)..0 5(0))..0 55(ХЮ,О 6(0))..0 Рис. 1.66. Вид заrоловка 1+: · . Q" 'С'" .'4; _ g ''. r """ fi-" Rд6 RДO . I I I , . . I . . . . ..500>..0 soo:ю о 55(0).0 6(0)).0 Рис. 1.67. Видединицы 1:"" + . '.  <> :"У" IT." .. .'4 , ..  '   Rд6 RДO . I 1 I , I . I I I , I ,,5(0)..0 soo:ю о 55(0)..0 6(0))..0 Рис. 1.68. Вид паузы Времена близки к ориrинщ Последние rрабли, на кото.. рые я умудряюсь наступить  в функции обработки массива: void irtrns ( ) { i = О; с = 3; while (ircmd[i] 1= О) // Наш байт окончания команды. 
192 rлава . 1 Базовая версия забываю, заменить i на с. Вот так: void irtrns () { i = о; с = зi while (ircmd[c] != О) / / Наш байт окончания команды. Без этоrо, закончив передачу ИКкоманды, проrрамма ме- няет байт, из KOToporo я начинаю позже вычитать, и, вычитая из нуля, я получаю опять ненулевой байт, который при пр верке циклом while вместо завершения работы функции Ha чинает «пороть чушь». для отправки я распаковываю массив не с caMoro начала, а с Tpeтbero байта, поскольку в первых трех байтах (от О до 2) у меня служебная информация (с = 3), а в этом месте поменять я забыл. Итоrовая проrрамма выrлядит так: #include <pic16f62xa.h> #include <stdio.h> #include "irtrans.h" unsigned char inputi реrистра. unsigned char MODSIM1; unsigned char MODSIM2i int MODADDR; // int MODADDR; // , int simlnum = о; int sim2num = О i int simendnum = о; int MODNUМi / / полученный адрес модуля, как число. int i = о; int с = о; unsigned char ircmd [60]; unsigned char Ь = о; // Считываем содержимое приемноrо / / ПервbIЙ символ адреса модуля. / / Второй символ адреса модуля. Заданный адрес модуля, как число. Заданный адрес модуля, как число. unsigned char getch() { while(!RCIF) // Устанавливается, коrда реrистр не пуст. continuei return RCREG; } 
Схема и проrрамма модуля излучения ИК-кодов 193 // Вывод одноrо байта. void putch (unsigned char byte) { PORTB = 1; TXEN = 1; while ( ! TXIF) continue; TXREG = byte; } int initcomms ( ) { PORTA = ОхО; CMCON = Ох?; TRISA = Ох80; TRISB = OxF6; RCSTA = Ох90; TXSTA = Ох4; SPBRG = Ох16; INТCON=O; PORTB = о; //Переключим драйвер RS485 на передачу. // Разрешаем передачу. // Устанавливается, коrда реrистр пуст. / / Инициализация модуля. // Настройка портов А и В. // Настройка приемника. // Настройка передатчика. // Настройка режима приемапередачи. / / Запретить прерывания. // Выключим передатчик драйвера RS485. / / Определим номер модуля. MODADDR = PORTB; / / Номер модуля 8 старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. for (i=O; i<61; ++i) ircmd[i] = о: } /1 Преобразуем символьный адрес в число. int simnumadr() { simendnum = О; sim1num = getch(); // Чтение первоrо символа номера. MODSIMl = sim1num; / / Сохраним первый символ. sim2num = getch(); // Чтение BToporo символа номера. MODSIM2 = sim2num; / / Сохраним второй символ. sim1num = sim1num  ОхЗО; sim2num = sim2num  ОхЗО; simendnum = sim1num*OxOA + sim2num; return simendnum; } int cmd() 
194 rлава . 1 Базовая версия { MODNUМ = sirnLnumadr(); // Чтение из сети (файла). if (MODNUМ == MODADDR) / / Если наш адрес модуля. { while (input != "Р") input = getch(); // Ждем. if (input  "Р") // Если символ завершения команды. { i=O; input = getch()i / / Принимаем данные. while (input 1= ОхО) { ircmd[i] = input/Ox2; input = getch(); ++i; } } } } yoid irtrns ( ) { i = о; с = з; while (ircrnd[c] ! = о) / / Наш байт окончания команды { / / ИМпульс. Ь = ircmd[c]; ++с; while (Ь 1= О) { М6 = 1; RAб = 1; RAб = 1; RAб = 1; RAб = 1; М6 = 1; RAб = 1; М6 = 1; RAб = 1; RAб = 1. , RAб = 1; 
Схема и проrрамма модуля излучения ИККОДОВ 195 М6 = 1; RAб = 1; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; Ь; } // Пауза. ь = ircmd [с] ; ++с; while (Ь != о) { RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; RAб = о; М6 = о; Ь; } 
196 rлава . 1 Базовая версия } } void main(void) { // Начнем работать. initcormns (); / / Инициализация модуля. //Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах. MODADDR=MODADDR»4; // Сдвинем на четыре бита. // Ждем прихода команды и данных. start: while (input ! = MODULNAМESIM) input = getch ( ); / /Ждем обращения. cmd (); irtrns(); goto start; // Обработаем сетевую команду. / / Отправим ик команду на излучатель } Если ее запустить, набраться терпения и дождаться pe зультата, он будет выrлядеть, как показано на рис. 1.69 (отсле живание RЛО я убрал, оно было полезно только для определ ния времен). I I I I I , I , . I I I . , 2(0))..0 mю..о шm..о 5(Ш)..о ШXIO.О Рис. 1.69. Итоrовый вид ИКкода Именно такой сиrнал мы моrли бы увидеть на записываю щем осциллоrрафе, если бы воспроизвели ИКкоманду с пуль та устройства перед фотоприемником (без встроенной обра ботки сиrнала). Картинка не была бы столь четкой, вероятно, но бьта бы очень похожа. Видно, что сиrнал начинается с за rоловка (pulse), затем следует короткая пауза (space), после нее  единичная посьтка несущей со своей паузой и Т.Д. ПО этой картинке можно прочитать сиrнал  10101001101. 
Схема и проrрамма модуля излучения ИК-КОДОВ 197 Вернувтись к началу этоrо раздела, мы найдем данную команду. Проверить работу модуля с этой командой можно несколь кими способами (собрав модуль): прочитать команду с пульта и с модуля считывающим устройством и сравнить результаты или отправить команду на устройство, которое этой KOMaH ДОЙ управляется. Работает устройство  работает и команда. Однако прежде чем проверять работу собранноrо модуля, есть смысл проверить ero работу в MPLAВ с друrими KOMaH дами. У меня есть несколько считанных команд, проверкой работы которых я и хочу заняться, записав их для этоrо в новый input.txt файл. Попробую понять, что из этоrо получа ется. Вот как выrлядит команда Pl.AY одноrо из устройств фир мы Sharp (в представлении, приведенном к виду, который получился бы с помощью считывания в WinLIRC). Исходный вид: 4000 d101 4000 d101 4000 с700 4000 с700 4000 с700 4000 с700 4000 d101 4000 с700 4000 с700 4000 с700 4000 d101 4000 с700 4000 с700 4000 d101 4000 с700 4000 бf2Ь После первоrо преобразования: 0040 Импульс 01d1 Пауза 0040 Импульс 01d1 Пауза 0040 Импульс и Т.Д. 00с7 0040 ООс? 0040 ООс7 0040 00с7 0040 01d1 0040 00с7 0040 00с7 
198 rлава . 1 Базовая версия 0040 ООс7 . 0040 01dl 0040 00с7 0040 00с7 0040 01d1 0040 00с7 0040 2b6f Времена  64 (0040), 465 (Oldl), 199 (ООс?), 11119 (2b6f). Первый импульс  256 мкс. Что предполаrает коэффициент 4. Тоrда времена  256 мкс, 1860 мкс, 796 мкс, 44 476 мкс. И, HaK нец, в том виде, с которым мы начали работать (справа в шес тнздцатеричном представлении): pulse 256 врасе 1860 pulse 256 ерасе 1860 pulse 256 ерасе 796 pulse 256 ерасе 796 pulse 256 ерасе 796 pulse 256 ерасе 796 pulse 256 ерасе 1860 pulse 256 ерасе 796 pulse 256 ерасе 796 pulse 256 ерасе 796 12 87 12 87 12 ЗА 12 ЗА 12 ЗА 12 ЗА 12 87 12 ЗА 12 ЗА 12 ЗА я разделил на 13,8 и перевел в НЕХформат 
Схема и проrрамма модуля излучения ИК-кодов 1 99 pulse 256 12 врасе 1860 87 pulse 256 12 врасе 796 ЗА pulse 256 12 врасе 796 ЗА pulse 256 12 ерасе 1860 87 pulse 25"6 12 ерасе 796 ЗА pulse 256 12 ерасе 44476 С96 Осталось заменить данные в файле input.txt. Посмотрим, что получится. Общий вид полученных импульсов изображен на рис. 1.70, а времена: первой паузы рис. 1.71, второй паузы и импульса рис. 1.72 и рис. 1.73. И период несущей частоты, рис. 1.74, похож на «настоящий». Rд6 FIДO 1828 r-' I I I I . . . . I .." J I . I I I I . 4500) О 500)).0 5500).0 6(0)) о 6500:1.0 700XI О Рис. 1.70. Вид контрольноrо ИКкода ............   . .. ...;;' :. "." ,,"'- FIДO    1828    1---------- Rд6 I I l' l' I r l' . I l' I I I I I I I , 4500) О 5WЮ.о 5500).0 6(0)).0 6500:1.0 7OOXI.O Рис. 1.71. Вид первой паузы контрольноrо ИКкода 
200 rлава . 1 Базовая версия ":-: :;'':''. ... :.'..-.::.:' .": . .". .:. . ....0_. . ". :_._:." :." Х' ..<:": о". ......... Z . Rд6    18   RAO I . I I . I I I I I I I '1 I I I I I I (5Ш).0 5WXI О 5500:1.0 ." 6OOIO.O 65(Q) О 7tXXIO.o Рис. 1.72. Вид второй паузы контрольноrо ИКкода 1+1::.;:: '<;:(/ il Dr;;;"'J"  'r .". Rд6 RДO . I I I I I I I . I . , I I , . , I I , I I I . I . , I I , .9500.0 500)).0 50500.0 51(ХХ).0 51500.0 52(ХХ).о Рис. 1.73. ВидимnyльсзконтрольноrоИКкода FБ:::.' ":Q.: . '", ;:4 .0 .!.: "." -1 r". .>: FIДO ..... .....   26'   ....   ..........  . I I I I . I I I . . . . I I I I 50500.0 5(Ш).о 50100.0 50000.0 5(9XJ.o 51(ХХ).о Рис. 1.74. ВиднесущейконтрольноrоИКкода Для сравнения посмотрите, как выrлядят информацион ные импульсы в проrрамме, из базы данных которой взяты ИКкодыShаrр (рис. 1.75). Сравнивая ero с видом импульсов, представленных как RAO на рисунке вида контрольноrо KOД, можно убедиться в их схожести. А времена (256 мкс против 259, 1860 мкс пр тив 1828, 796 мкс против 825) не столь разительно отличают ся. Несущая, правда, уехала к 38,5 кrц, но это может быть и не совсем точно измеренное значение (маркер несколько съехал с фронта импульса). 
Схема и проrрамма модуля излучения ИК-КОДОВ 201 Рис. 1.75. Вид импульсов кода Sharp и ..то поnyqиnось? Приступая к разработе, мы вполне разумно определились в том, что хотим от данноrо модуля. В процесс е разработки, столкнувшись с трудностями, мы не менее разумно отказа лись от части первоначальных запросов. Написав первую Be сию кода проrраммы, выrлядевшую вполне «рассудительно И лоrично», мы отказались от нее. Предполаrая хранить значе ния текущей длительности интервала в двух байтах, мы для ускорения работы проrраммы приняли однобайтовый вари ант хранения. С точки зрения обучения это яркий пример Toro, как не надо делать. С практической точки зрения это пример Toro, как приходится иноrда поступать, чтобы справиться с пробл мой, обойдя ее хотя бы на время. В нашем случае, пытаясь овладеть приемами работы с про rраммой MPLAВ и одновременно создав некоторую люби тельскую систему, мы в праве принять несколько решений: . оставить все, как есть  мы не можем менять частоту несущей ИКкоманды «на лету», но пока не убедились, что это нужно, можем не тревожиться; как выrлядит проrрамма, изящно или нет, после заrрузки ее в KOH троллер едва ли будет комулибо интересно; все что требуется, так это чтобы модуль исправно работал; . можно собрать модуль, опробовать и, если работает, за быть о существовании проблем; . и, наконец, третье ретение пересмотреть все, что cд лано, и создать модернизированные версии тех же MO дулей;.к концу работы появится больте опыта, чаще бу дет приходить в rолову мысль о том, что если бы знать раньше, можно было бы сделать и лучше! Лично я склоняюсь К тому, что, коrда появятся эти мысли, тоrда и займемся модернизацией. А пока рисуем схему и ОТ- правляемся в «Чип И Дип», собираем модуль. 
202 rлава . 1 Базовая версия Напомню формат, который мы «перелопатили» , И дей ствия, которые мы осуществляем, вопреки первоначальным замыслам. Формат записи в файл ИКкоманды представлен в табл. 1.9. Таблица 1.9. Новый вариант формата ИКкода Устройство Повторов Коэффициент Импульс Пауза и т .д. EOF байт байт байт байт байт байт О Импульс и пауза  это времена в мкс, деленные на 13,8 после прочитывания в проrрамме WinLIRC в виде шестнад цатеричных чисел. Затем, в проrрамме, они будут еще раз разделены на 2. в nporpaMMe в настоящий момент не используется служеб ная информация, относящаяся к устройству, количеству по второв и коэффициенту. Позже, если решим модернизиро вать модуль, мы дополнительно сделаем несколько выходов, которые будут выбираться по записи «Устройство», добавим обработку количества повторов и, возможно, используем KO эффициент 13 или 14 для деления времени, полученноrо при noAroTOBK(a кода, самой проrраммой. Если решим, что следу ет внести изменения в модуль. MoAYnb с..итыаниRR ИК-КОДОВ WinLIRC Будем работать в проrрамме WinLIRC, доступной для свобод Horo использования, с соответствующим модулем в качестве считывающеrо устройства для предварительной подrотовки ИКкодов. Излучатель WinLIRC, возможно, используем для rенерации системных ИКкодов. Схема фотосчитывателя и излучателя для работы с пр rраммой WinLIRC показана на рис. 1. 76. Проrрама доступна на сайте http://winlirc.sourceforge.net. Элементы, необходимые для сборки фотосчитывателя приведены в табл. 1.10. 
МОДУЛЬ считывания ИК-КОДОВ WinLIRC 203 ОТА4 WinLIRC приемникпередатчик VD2 IC1TSOP1738 Рис. 1.76. Схема приемника WinURC Таблица 1. 1 о. Спецификация фотосчитывателя Н2 Обозначение Изделие Кол-во Цена (р.) 1 'С1 TSOP 1738 1 40 2 IC2 78L05 1 за 3 VD1, VDЗ 1N4148 2 5 4 VD2 АЛ 144Д 1 20 5 А1 4,7 кОм 0,25 Вт 1 1 6 А2 2 кОм 0,25 Вт 1 1 7 С1 4,7 мкФ 16 В 1 20 8 Х1 ОВ9 rнездо 1 10 Вид платы может быть таким, как показано на рис. 1.77. . ; '.f!' ': ..-эr. ..... ".... af:. .... . :.... .. ., "Н ., .. . ::'"'.... ."" " ':.::> ..' . .,.... --- .-.. 0(0 .."  ,ОСР', .-,:.- " ;" . -" . . . ". .? '-0.' "..t. .> . ..',. . .' <%\ 'А. ,о. _. < .  . \.. . '. . . ....:.., . .' ) '. . .-;. .. ." . . у ", ;';"':. '. Рис. 1.77. Плата фотоприемника WinURC 
204 rлава . 1 Базовая версия Проrрамма WinLIRC работает в двух режимах при прочи тывании ИКкодов. В первом режиме она определяет COOT ветствие кода стандарту и создает текстовый файл, в KOTO ром записаны параметры кода. Во втором режиме она непосредственно выводит во встроенное окно времена посы лок И пауз 'ИК команды (рис. 1.78). "- '"    . t.. .........;. :". ,'-.t-- . "h - . . ..- . <. ,., ... *"# "6'- <.+.. .'. ...1 -w-..  -" .....  1t.......& '" '. ' . - 1 l' .'  (--- l4'! ,t..;,.. : ., ,., ..  ',: ".. .  '"-.д.:. ": ",.' :::...... .., .'\...',. .  \"" .......' .'. .,.I..'\J' .'1' '"' "1<!'!." ... . .......... '.. .,...... "'-... '''",' ."",v ,........ . #f< , .. ., ...... х .: '\. '.. _'\...,..  , 1!'0......., . J . ." ,J- . , .'''..э...", .' .  .  q.  :. .. .  ,-' "\  v ..; . ... ..". ... .'Зw...... '..,. .... .'... '...i' "'"J' '". /" ..... .. .. ". .' , 'r... .... "\ '. <.« · ,.>  "., -''''''', . .. ..,. ': .,,,. .: ':' ':' .... "" """', -7 ' ,;....... ,"... "", ..., :..  ..., ,-. I iIt  . . .:.:-,;;......,. : ....:  'Oi', ! .... ,,:,..r'4',..: .:!....... ':,' '.  ". .,:"'\, ........... .м.....-:.:: . ..' JW . . )rQ .. ). .: ,;. ..... '.".. '"....:""::" f": :\:.: ..,-' .. ....::'. ....."'". ,..".....r' .. ... . "'-.... .1: ""." :'.,  ";"'''''' "";",1,;: '»' .","" .' <>...... . ..... ...."!r""""l ;. ,: ::: Рис. 1.78. Вид nporpaMMblWinURC Появление в правом yrлу панели значка rI означает, что проrрамма работает. Правой клавишей мыши с помощью это ro значка можно вывести окно проrраммы на экран. Кнопкой Browse задать файл конфиryрации. А, щелкнув кнопку Raw Codes, прочитать ИКкоманду. Думаю, что ДЛЯ считывания команд мы используем второй метод, поскольку существует MHoro кодов, не читаемых пер вым. Файл, записанный с помощью проrраммы WinLIRC, BbIr лядит следующим образом: Коды с пульта VCR Sony Прямое считывание, клавиша power 
Модуль считывания ИК"кодов WinLIRC 205 Outputting raw mode2 data. space 12856572 pulse 2455 space 532 pulse 1291 space 506 pulse 664 space 533 pulse 1266 space 533 pulse 665 space 591 pulse 1211 space 533 pulse 685 space 515 pulse 693 space 526 pulse 1271 space 506 pulse 1265 space 533 pulse 666 space 557 pulse 1241 space 533 _ pulse 664 space 24527 pulse 2463 space 579 pulse 1219 space 534 pulse 664 space 534 pulse 1266 space 534 pulse 666 space 531 pulse 1266 space 534 pulse 663 space 536 pulse 662 space 567 
206 rлово . 1 Базовая версия Реально эта запись получается еще длиннее, если пульт при нажатии клавити постоянно воспроизводит одну KOMaH ду до тех пор, пока клавита не будет отпущена (рис. 1.79).  - . . -". .., .". -: : .. . ';.t :;,'.t. " . . (. .... . ;:. . -) )... "'ff={.«(r. .:, :...". :.: : Х., .. ......;<':.... ..: E:I ': .. ':, .... -;.{ : .:'; . :".0(: ....' "0; '. '''''i'' )\....'" =711 ' · ,;,:.; ,1 ., /".":'  "... .....>'(."ar4'.' """ . . )"'.r- "f. т; ::;<t'  .,., : .,,:::' '. ""<, ..' '. j :'B:'; . . "О Рис. 1.79. Считывание ИКкода проrраммойWiпURС Собственно, команда, интересующая нас, содержится в следующей записи: Outputting raw mode2 data. pulse 2455 'space 532 -pulse 1291 space 506 pulse 664 space 533 pulse 1266 space 533 pulse 665 spae 591 pulse 1211 space 533 
pulse 685 space 515 pulse 693 space 526 pulse 1271 space 506 pulse 1265 space 533 pulse 666 space 557 pulse 1241 space 533 pulse 664 space 24527 Модуль считывания ИК"кодов WinLIRC 207 Здесь pulse  вспышка излучателя с частотой, положим, 36 кfц, а space  пауза между вспытками. Раскрасим эту запись в соответствии с тем, что rОБОРИЛОСЬ о кодах Sony Быте: pulse 2455 3аrоловок space 532 pulse 1291 Едишща арасе 506 pulse 664 Ноль space 533 pulse 1266 Едишща врасе 533 pulse 665 Ноль space 591 pulse 1211 Едишща врасе 533 pulse 685 Ноль space 515 pulse 693 Ноль space 526 pulse 1271 Едишща арасе 506 pulse 1265 Едишща арасе 533 pulse 666 Ноль space 557 pulse 1241 Едишща врасе 533 
208 rлава . 1 Базовая версия pulse 664 space 24527 Пауза между командами Числа здесь  времена в микросекундах. Код, если записать информационное представление, выrлядит как 10101001101 в двоичном виде или 54D в шестнздцатеричном. Конечно, хор ото бы хранить команду в информационном представлении, в виде двух байт. В этом случае в EEPROM можно было бы хранить до 64 команд. Но не все ИКкоды таковы. Некоторые имеют до 48 бит, то есть в информацион ном представлении требуют 6 байт. Есть команды, состоящие из двух последовательно воспроизводимых команд и, вдоба вок, длиннее 48 бит. Можно придумать систему шифрования кодов (с целью их сжатия), но мне кажется, что пока лучше отказаться от идеи хранения кодов в модуле передатчика ИКкоманд. До поры до времени будем хранить их на компьютере в файле данных, который будет прочитываться при работе основной проrрам мы. При трансляции кода он будет передаваться по систем ной лJ:lнии, запоминаться модулем излучения ИКкоманд и воспроизводиться им. В этом случае в модуле нам предстоит запомнить только одну команду, которая снимает оrраниче ния на общее количество команд и сложность их хранения в плане длинных кодов. Итак, мы бем прочитывать ИКкоды с пультов устройств с помощью проrраммы WinLIRC, обрабатывать вручную, за писывать их в текстовый файл (или файлы) и воспроизводить по мере необходимости, передавая соответствующему MOДY лю. В этом случае формат команды можно оставить таким, каким мы пользовались при работе с модулем трансляции. На этом мы можем завершить первую версию в части ис полняющих модулей. Пришло время создания основной про rpaMMbI для управляющеrо компьютера. Проrрамма ДnЯ упраВnRlOщеrо KOMnblOTepa До начала работы еще раз перечислим модули, которые мы разработали для системы: 
Проrрамма для управляющеrо компьютера 209 . релейный модуль; . модуль приема системных ИКкоманд (от cтaporo пульта); . модуль трансляции ИКкоманд для управления бытовой аппаратурой. Модулей HeMHoro. Но даже на их основе можно создать множество очень интересных версий системы, например «Умный кукольный домик» (Барби  достаточно боrатая кyк ла, чтобы иметь свой умный домик) для дочери или младтей сестренки. Если не усложнять задачу по созданию управляющей про rpaMMbI, в качестве среды разработки основной проrраммы и отладки системы я предлаrаю использовать Visual Basic или любую доступную и удобную для вас среду разработки. Я выб рая Visual Basic только по той причине, что «это у меня есть». Вдобавок, вариант Visual Basic упрощает работу с СОМпор том. Я пробовал создание подобной среды п'роrраммирова ния на языке С++ в KDevelop под управлением операционной системы Linux. Все работает. Все удобно. Среда разработки КDevelop входит в дистрибyrив Linux, который стоит около 350 рублей. Тоже, как мне кажется, очень хороший вариант. Перечислим команды модулей, которые MOryт потребо ваться при написании основной проrраммы. Релейный модуль. Возможно, мы не будем запрашивать статус реле, используя только команды включения и выключ ния. Возможно, используем три модуля с адресами 01, 02, 03, которые будyr располаrаться в трех комнатах и включать Ha стольную лампу в кабинете, торшер в rocTI [ной и бра в холле: . включить  Rxx$xN; . выключить  Rxx$xF, rде хх  это 01, 02, 03; х после сим вола команды «$»  это «1» (будем использовать только по одному реле в модуле); . передать статус  Rxx$xs; при передаче статуса исполь зуются следующие символы:  включено  Rxx#xN;  выключено  Rxx#xF. Модуль приема системных ЯК-команд. Используем один модуль, который расположим в rостиной. 
21 О r лава . 1 Базовая версия Запрос статуса  Cxx$OS (аналоrично команде запроса CTa туса релейноrо модуля). Ответ модуля  Cxxkkk, если команда пришла, и Схх# f f, если ИКкоманда не приходила. Модуль трансляции ИК кодов. Предположим, что мы по команде с системноrо пульта будем включать и выключать телевизор. То есть, нам потребуется отправлять команду power для телевизора, которую предварительно прочитаем с помощью WinLIRC и обработаем, записав в файл с растире нием .1rc. Какой я представляю себе в настоящий момент работа щую проrрамму? При запуске nporpaMMbI отображается пользовательский интерфейс, который проверяет работу модулей и запускает основную проrрамму. Помещений, rде будyr установлены модули, три  кабинет, rостиная, холл. В Visual Bas.ic, как и в дрyrих средах проrраммирования, есть удобное средство создания пользовательскоrо интерфей са проrраммы  форма (Form). Этим мы и воспользуемся. Заменим название формы (свойство Caption) на «Куколь ный умный домик». В редакторе изображений создадим икон ку, которую вставим, используя свойство Icon 111. Теперь OT кроем три Frame, которые назовем соответственно Кабинет, rостина.и, Холл. Получим картинку, показанную на рис. 1.80. В редакторе изображений нарисуем изображения выкл ченной и включенной ламп  и . Их мы используем впоследствии для отображения состояния ламп (или реле). Вставим картинки в каждое из ранее нарисованных помеще ний на форме (добавив PictureBox с вкладки General), доба вим клавиши, которые будyr управлять этими лампами (с по мощью реле). Картинки наложим одна поверх дрyrой. Получим вид формы, показанный на рис. 1.81 (последние две картинки не совмещены). Напомню, что картинки с изображением включеннойлам пы мы наrрадим свойством Visible False, а для ввода кода нуж но дважды щелкнуть кнопку на форме, например «Лампу включить», И вписать небольтой текст: private suь ReleyOlonClick() Forrn1.Lampoff.Visible = False 
Проrрамма для управпяющеrо компьютера 211 '"":" ,. ':2:Z;it,.<;w j!':; ,. "::;r'""i-:" :.:_,...( .. .. . :.:....:.; :.... .... .  .... ,. .7:jHi. : f;;{ :;:' ': :q? Рис. 1.80. Окно основной nporpaMMbl проекта (, :  .. . . :.,1 :} J "" " .... -<, . .'.; ...'. " :" "'"у'.. .riJ . ,,' :?,"' , ." .... ....,..., ... :" . .. := ':.:: ;:. ... .::: .:.: .t\ ;:-::':... ..' :: ." :<: ..::::.:-::;.:_: . \;;.\;.а,.>х':' ;::';:it....:" :..;.;. ..',,:;;: ,! .,;;,:.' ;:if..j;i. \'  с, ,:1; , ;К ',;. ..>.. :Ji   . .' , f . . .  . ' . :' . , ..:JJ:. . ...},'" : :'х"  ..;""" 1:- >ti :{;;,i'l; 'if25:1:l ,+'.::Щ :jУfi i.:.  ...:I :.: :;......:. '"(.:.."::" ,. :"':b-::.:::::::':":' , < ') '$. '''',-. :a\ .'';' '  ::'j,\ . . .. ....... .. . .. . .,..r  ': ::;  :J,  ': Рис. 1.81. Форма nporpaMMbl проекта с расставленными лампами Forml.Lampon.Visible = True End Sub 
212 rпaBa . 1 Базовая версия в этом фраrменте я выделил то, что создает Visual Basic при щелчке кнопки на форме. Расположим в rостиной пульт управления, с KOToporo будем принимать команды (он cbIrpaeт роль модуля фотоприемника) и телевизор, которым мы будем управлять с помощью модуля излучателя ИКкоманд. Картинки нарисуем в rрафическом редакторе и наложим одну на дрyryю (конечно, cooTBeтcTByкr щие, как с лампами). Добавим код, аналоrичный вытеупомяну тому фраrменту кода, и получим работающую заrотовку, KOT рую, в первую очередь, можно использовать для тестирования модулей. Клавити включения и выключения ламп будyr посы лать команды модулям и менять картинки в соответствие с состоянием  «Включено» или «Выключено». Аналоrично мы поступим и с остальными модулями. А пока можно проверить отображение будущих идей. Поскольку мы планируем использовать два режима рабо ты  тестовый и основной,  я думаю, есть смысл сделать rлав ное меню с двумя режимами работы. Для этой цели на форме v u щелкнем правои кнопкои мыти и в открывтемся меню BЫ берем Редактор Меню. С ero помощью создадим меню с oc новным пунктом Режим и двумя подпунктами: Проверка и Работа. При выборе режима Проверка (щелкаем этот раздел меню) мы сделаем видимыми все клавити: pri vate SUb mnuTestClick ( ) Forml.Releyoloff.Enaыldd = True Form1.Reley01off.Visible = True Form1. Reley02off. Enaыldd = True Form1.Reley02off.Visible = True Form1.Reley03off.Enaыldd = True Fоrml.RеlеуОЗоff.visiЫе = True Forml.Releyolon.Enaыldd = True Form1.Reley01on.Visible = True Form1.Reley02on.Enaыldd = True Form1.Reley02on.Visible = True Form1. RеlеуОЗоп. Enaыldd = True Fоrm1.RеlеуОЗоп.VisiЫе = True Forml.photo01on.Enaыldd = True Form1.Photo01on.Visible = True Form1.IRemitter01off.Visible = True 
Проrрамма ДЛЯ управпяющеrо компьютера 21 3 Form1.IRemitter01off.Enabled = True Forml.IRemitterOlon.Visible = True Form1.IRemitterOlon.Enabled = True Forml.PhotoOloff.Enabled = True Form1.PhotoOloff.Visible = True End Sub При переходе в режим Работа мы их уберем «с rлаз дo лой» : Private Sub muWorkClick() Forml.ReleyOloff.Enabled = False Form1.Reley01off.Visible = False Forml.Reley02off.Enabled = False Form1.Reley02off.Visible = False Fоrm1.RеlеуОЗоff.EnаЫеd = False Fоrm1.RеlеуОЗоff.VisiЫе = False Form1.ReleyOlon.Enabled = False Forml.Reley01on.Visible = False Form1.Reley02on.Enabled = False Form1.Reley02on.Visible = False Fоrm1.RеlеуОЗоп.ЕпаЫеd = False Fоrml.RеlеуОЗоп.VisiЫе = False Forml.PhotoOlon.Enabled = False Forml.Photo01on.Visible = False Forml.IRemitterOloff.Visible = False Form1.IRemitter01off.Enabled = False Forml.IRemitter01on.Visible = False Form1.IRemitter01on.Enabled = False Form1.PhotoOloff.Enabled = False Forml.Photo01off.Visible = False End Sub Теперь работающая проrрамма будет выrлядеть в двух pe жимах, как показано на рис. 1.82. В проrрамме я использовал обозначения ReleyO lon ( of f) , PhotoOloff (оп) иIRеmittеrОlоn (off) дляклавитуправ ления Лампу включить и т.д. Клавита Команда?  запрос фотоприемнику. Обозначения содержат адрес модулей ReleyOl, Reley02, Photo01 и т.д. Не троrая режим работы, попробуем орrанизовать работу с портом COM1. Для этих целей используем возможностьдо бавить элементы управления. Я добавил требуемый элемент 
. 214 rпaBa . 1 Базовая версия : .. ...! j< 'imt.,.. .>:;/, P+ m.t ;:; '$  "," . ..--- ," .......- . .; ':{:'- ..:..\;:::;:>::JT.:. ::.. ," .:.;. ... <  """ .. .:. . _:.:....:;: ...:.... /)'" J';..: ."/  . .,. ... . :.;!/.. "" ; T;.... . . .;;.;;;. " ;f. ' . ;:;7\;:::K;::'''{<", . 9. : .:: ." .,-.::.,"< ": ::.. ':;1 :.п,>" ...:: J.: :. ..!:  i?:_._ \':.':.:::'f:' :.:.... .:' ;!' ';;.. . " '.' : t .  t :f:: . i . .;S :.: ::'-': ":/'.::'" ",,: :. . {(':. '.. . "'':'!<t...'_''.' , .) ; . ; [3 ...... " . ... ..... '..", .....- (". :', ;. . : ': :. -;" " - .;: .:. .. . , ,"- 1.,:&::;..;t;-;';::,":;ilJ -:.. х ." ';'. . '» "'.  :. }-i:'J >:... -л_::'(::"':": ( о>. 400.) ".  .1 , 4"". ". ..,..... _....: ""'.' Ч.' . , . 1 ' . . ;...: . . ". ." 41 А,: , I ,1 . tf ;: ,, r ,:: '! ': ': '.;,:. t :': . ;{ :  . ; .. . :] .':,:'. ,. _. ., .; '., Рис. 1.82. Окно nporpaMMbl проекта с расставленными устройствами и меню управления MSComm на панель Ноте в Visual Basic, которую ,создал, чтобы не переrружать основную инструментальную панель. Этот элемент переносим на форму для использования в проrрамме. Для добавления элемента на инструментальную панель открываем в меню Проект раздел Компоненты и ставим флажок напротив Мiсrоsоft Сотт Control6.0 (рис. 1.83). После добавления элемента управления на форму он CTa новится доступен для использования (рис. 1.84). Признаться, я хотел сделать два варианта этой nporpaMMbI: на Visual Basic и Delphi, блаrо, есть возможность поработать и с той, и с друrой средой проrраммирования. Но в Delphi, уста- новив необходимый компонент VCL, я не cMor им воспользо- ваться по причине отсутствия на это лицензии. Может быть, я что-то сделал не так, но не стал без нужды озадачивать тех, кто дал мне возможность поработать на компьютере, и пере шел на Visual Basic, решив, что в этой среде Мiсrоsоft не 
Проrрамма для управпяющеrо компьютера 21 5 потребует лицензии. Еще раз повторю, что, возможно, чтото сделал не так, как должно в Delphi, но... описывать работу с СОМпортом «вручную» в данный момент я считаю преждев ременным. Да и зачем, если именно ДЛЯ облеrчения работы придуманы VCL, OLE и прочие заrадочные составляющие co временных сред проrраммирования?     -  *"". i  , :: , :: , . , . "  , . .  . , . :: . . , ,'. j , . . ' , Ш ''';.. '"" ':"''=:"'A" ,:";,,,:,":;",,;  с ',,, . . ',,' "; ,"""''''',V.:,' »'>,," ",.:' ,{ ....':;, .{.,,:::,..,., 1'' <':<.';':',".' :"'h"':" !t:,f н .;1t.k\. ,, ' :.': " . ' , . , : ::.: . : . и.. , : , у"< , ' . ,. " " , ". . ,. , .. , : . . . " - , : ,. ' . :" . ':- , , , ': , I.e . ' " ,. _ ",.". " . " .,1IIPioI ., , . ' , . . . ,, : , :. . . 1 , : . . . . . .. JItr ,.:. " ,' . . J ,.. . . " , . . ' ,, ' : '  :.: . . : ,  . . . " , .. ,  ,., ' ' , : , : , ':: .: , . .: '. .. . , : " , : , ' . : . ; , ; ':.. ...." ...., _. . .... .... "#'. . .  '. , . . '-.' ., .....-  . . . ' ::: '. . : : ; :, ; . ' , : r . ,' . i :, . .  , : . : . ': . : : . , ; . i .  .. ; , . . : .  . : .  :  .. . . :: , : : : .: '' .  ,. .: , . . : . .. . , ,: " . : , ? ' . ' , : .  .  , > : : . :: : : . : . : . . , " , ' , : ""  .: < .:' . r.:LfDМIt.A(tIyeXControlmocUt ",' '.; :;. :':': :':. :...':. . .. . <,. :',' ..:у..  CМet_NII1.0Type!.h.., .. ." J.:...."::'}.::.'::.::,. ; (. ... arн.o... , PkIgIn , ':.. ',:- ":'.ff:. ::;,; .: ., , '.... ",' , h,:,:J ,'" '-': :.: i::::-ХOlt8сontrol6.0«)Ш)8) r;;J ... . , '::':" , . , . . . . ' -' , '1%': .,,:.. ' : ' , ' ,, " .: " " ' . " . .. . . :' . , ,: :,., " " , ' ,',: " :. ' , ' ,:, ' . . ', ' ,, " :, ' ' r .:;"<'" ПМаosdtAQвntСontrol2.0 e".." .'. с', J ::':',.:l,: :..,:e o......  :::==(0LED8), ',..,  ;;J: .:; . f!. < ' (bf+t' ij:::=.,C=oI6S:::) ;,:>i::;,/.:,;: 't >;. , .. r':,:; r..':Мaosdto.t88ou'WJUstControk6.0 ... ;.;.  ....: : ... ' .. о;, . d 1.:1  [:: Мaosdt DlteGrld Сontrol6.0 (0LED8) :: )f с Мaosdt Dltil.ist Control5 6.0 (0LED8) ".' ,-- , >.;; t J :': . ;,.:: },  cc,"" .  /"':':=;?З''; Е::::t,:,1;;:t::j ' ... ..' ';'-:'..o:.' ';';..0:- J.' ,'.:..:":', ;:.;.;./ . ".'-:. ::......:).. :'.<-:.......:, . «w. ...--:- :.;.х-::':л:-...... \... о[ .-:-...... .. .::,...:..::...;... ::.:..;.:.;....;.....:;.:.: о..:.:::. &; ,.l,f .., .:' -. ...... .( ..... ... ;J: :,.,;:..:  , : fJ, rii,'r:Д: :;:t?}:::<*?:.:.::;: :.-:::;..:: Рис. 1.83. Установка СОМпорта в Visual Basic в режим проверки добавим инициализацию порта: private sub mnuTestClick() Form1.МSCamm1.CammPort = 1 Form1.МSCamm1.Settings = "9БОО,N,8,1" Form1.МSCamm1.PortOpen = True Forml.ReleyOloff.Enabled = True Form1.ReleyOloff.visible = True И т .д. End Sub Как и в рабочий режим. Изменим управление релейны ми модулями в режиме тестирования, добавив реальные KO манды. 
216 rлава . 1 Базовая версия :J ? :':, ::T:1t.H У: .....;i.,.y: ;;i::I: У. .. .;,. '-'':;';:".;:--::{:- ::-,." (;o.:' .Пt::;;,:f...t.: f-oun'IА"V;' Х.';:..:.".:..;,",..... .!..... ; .>.. ..:ь  ::;-llfщ . .::.. .. \?.;. : ;..   "" . ': ..}::,... :. ;."..' <; ." ":'. . ,,::. ,&"., ,,' . . . '. :::&::.:-:;:::. k:.j;;.- 1 i :r.:"j:;; "- ":::: !I  .%" .... '\ .:....:...:;..::":xz. :: :; .. .". . .- ..; I .. .' Ш """"':,. . "... :.. .... . -R'. . .;':". '. ..... $:";". . . .. . '" ...... .... .' . ..."....... ....  ":... ".{ . ..:-- ....., . :'. :-:".. ). . . . . .. ;...... :4?j;:tЁ.: Zii.-' :.;,::!? 1>к-;  ...:t:::::: ....: .". ... .  .' ." .. ''. ." ..:;;: .:: .;::.=:.:.,,;::: t"l.:::'::' ':?J. :t:;.:;.- t:Z:::,:'::.i .) .-:t): ':'ifi:; .:..::.Y1.:::i.;r.......4.:. ;.; ..-":::f.j-: ... ":..  :.r;.",::«. i;'::7ф.t: .f:: ....:t:. 'fZl ... .. ...x . ш......ш.... .. ш ., ). ::.: ':.".:..:;:.:{:.:x.:-.: ..:.::>{ .::;.::;: )..': .. ........ ..... ..... .. .... : .::. :' :' :: ,::, .s :;; .. ,. , .. ... ..., . .  . ., , . . .  :;:. " ..... :: ',': .. : . . . , . . .... .'. , . р . . . , . . . . . . . . "..;:. , . . ." " ". ..::' ',< .,:-> ,.' '",: ,... ,,. . ":', "  .. . . .. .... .. . . . : -:S- .:.:.:..:: . ... ... . .  : , , '1 ..' . . .:. . <:..;.'. .;;t,;J"/;Jt ::" ,; ;A ..: { ' .".:  <. ,..';... (:., , :.; Рис. 1.84. Форма проекта С установленным СОМпортом Команда ВКJIЮЧИТЬ лампу: Private Sub Reley01onClick() Form1.МSComml.OUtput = "R01$1N" Form1.МSComml.OUtput = "R01$lS" If Form1.MSComml.Input = "R01#1N" Тhen Form1.Lampoff.Visible = False Form1.Lampon.Visible = True End If End Sub Команда ВЫКJIЮЧИТЬ лампу: Private Sub Reley01offClick() Form1.МSComml.OUtput = "R01$lP" Fоrm1.ИSСomml.outрut = "R01$lS" If Porm1.МSComml.Input = "R01#lP" Тhen Form1.Laтpon.Visible = False 
Проrрамма для управляющеrо компьютера 217 Form1.Lampoff.Visible = True End If End Sub Пока я не вставил код инициализации порта при заrрузке проrраммы, поэтому при запуске проrраммы и попытках Ha жать на клавишу Включить лампу появляется сообщение об ошибке. Это сообщение служит напоминанием, что нужно выбрать режим Проверка. Вторая особенность работы про rpaMMbI  лампа, которую я хочу включить или выключить, не реаrирует на команды. Причина в том, что релейный модуль, настроенный соответствующим образом, я пока не включал. Будем надеяться, что с включенным модулем проrрамма будет работать правильно. С надеждой на это важное допущ ние исправим работу всех релейных модулей аналоrично первому. Например, для TpeTbero модуля (реле в модуле NQ1): private Sub Reley03offClick() Form1.МSCanm1.Output = "RОЗ$lF" Form1.МSCanm1.Output = "RОЗ$lS" If Fo:rml.МSComm1.Input = "RОЗ#lF" Тhen Form1.Braon.Visible = False Form1.Braoff.Visible = True End If End Sub Теперь попробуем обработать прием системной ИКко манды модулем приема ИКкодов. Для режима проверки нам достаточно одной системной команды. Пусть это будет KOMaн да 001. private Sub PhotoOlonClick() Form1.МSCanm1.Output = "C01$OS" If Fo:rml.МSComm1.Input = "СОl001" Тhen Forml.IRcmndoff.Visible = False Form1.IRcmndon.Visible = True Else Form1.IRcmndon.visible = False Form1.IRcmndoff.Visible = True End 1 f End Sub 
218 rпaBa . 1 Базовая версия Работу клавити Нет команды оставим без изменений. Пришло время разобраться с командой включения телеви зора. Подrотовим файл, возможно, внеся некоторые исправ ления в файл input.txt. Мы ero использовали с проrраммой МРLЛВ при разработке модуля ИКкоманд. Изменим ero растирение, превратив в файл input.irc, который я разме щаю на диске D в папке barby: 02 02 32 Вl 26 5D 26 26 26 5D 26 26 26 5D 26 26 26 26 26 5D 26 5D 26 26 26 5D 26 26 00 я оставил пробелы между числами, чтобы числа леrче чи тались, но эти пробелы не нужны в реальном файле. private Sub IRemitterOlonClick() Form1.ТVoff.Visible = False Forml.ТVon.Visible = True intFН = FreeFile() Open "D: \barby\input. irc" For Input Ав intFН Do Until EOF(intFН) Line Input #intFН, strString strCmnd = strCmnd & strString & vbLf Loop Form1.MSComml.OUtput = "IOl$5P" Forml.MSCormnl.Output = strCmnd End Sub Вот  получилась кнопка. Я честно «срисовал» весь фрar- мент проrраммы из полноrо руководства по Visual Basic 6.0 Михаэля Райтиrера и rеральда Муча (издание BНV: «Ирина», Киев, 2000), которое обнаружил на книжной полке. Проrpам ма не протестует против этоrо фраrмента, у меня тоже пока нет оснований для протестов. Вторую клавишу управления телевизором можно снабдить этим же кодом. MHoroe зависит от команд включения и BЫK лючения. Мой старый телевизор включается подачей KOMaH ды канала, а выключается клавитей power. Пока это не прин ципиально, важно только, чтобы в файле input.irc была правильная команда. Перед проверкой работы проrраммы в режиме тестирования я удалил строки: Forml.MSCormnl.PortOpen = False Form1.MSCormn1.CormnPort = 1 
Проrрамма для управляющеrо компьютера 21 9 Forml.MSComm1.Settings = "9600,N,8,1" Form1.MSComml.PortOpen = True из Pri vate ВиЬ muWorkClick ( ) . Обозначил ее свойство Visible равным False (в редакторе меню убрал флажок в оп ции Включено) и добавил к фраrменту щелчка кнопки меню Проверка строку Forml. mnuWork. Enabled = True, а к фрarмен ту щелчка кнопки меню Работа  Forml.rnnuTest. Enabled = False. Добавил еще один пункт в основное меню Стоп, рабо ту KOToporo описал так: private Sub mnuStopClick() Forml.mnuTest.Enabled = True Form1.mnuWork.Enabled = False Forml.MSComml.PortOpen = False End Sub Причина этоrо, полаrаю, понятна  «заплатки» для пра вильной работы СОМпорта, который нужно во время OTKpЫ вать и закрывать. Чуть позже поправим (если не забудем) нате лоскутное одеяло, а теперь настал, как rоворят, момент истины. До написания блока Работа основной проrрамы следует проверить ее тестовую часть. Пришла пора собрать модули, подключить конвертор к компьютеру, а модули  к конвертеру, и запустить проrрамму. Но это завтра. Сейчас время позднее, я не успею дома переписать проrрамму, раз ложиться возле компьютера и коечто проверить. Однако меня беспокоит фраrмент чтения из файла. Что же я прочи таю? Попробую в очередной раз схитрить, HeMHoro времени у меня еще есть (рис. 1.85). Хитрость в добавленной кнопке в верхней части с именем wrem, надпись на которой я убрал, а перед отправкой ИКко манды кнопкой Телевизор включить добавил строку, Bыдe ленную ниже: Private Sub IRemitter01onClick() Forml.ТVoff.Visible = False Form1.ТVon.Visible = True intFH = FreeFile() Ореп "D:\barby\input.irc" For Input As intFH Do Unt i 1 EOF ( intFH) Line Input #intFH, strString 
220 rпOBO . 1 Базовая версия ... .... "(...:> .  " (. . ,.)  ..... )" ...... ,....  ";.  " , ' , . ", '":-.. .,. ..'" ',':.;:::.;;':::""".: \;:.::" .....;..(..}: .:..... .."-::'. . .. '.' о.. .' . ":-:':", >.:-:.::../:.: .....::..'";.:. :", ...":'..'.-.."!-' f;:.... ..'..... ;!, ". ;;  [CC "',.7"t ;::"",o",1 :.:=:..:....::...i::.::::::..x:..:..---=)::-;:-:::::-.'=:._.:.:... ,,'О ." "#.."$;':.c..' . Lj ..... ..... . ... '[:::1; , П '" - ." 0'- . ':. _:.. . :. . ....;.1' . . . ' , "" . .. " . /. . .... " . - . . - .... -. -. ..- '" .;/ .." . ....: 0(:": .'. .....;,.-. . о. о . . . о. . . . . ":.  ,"  " ,', о о ;,. .1' . -.. r:\-' .;:  . .:.: :.' :.- ..;...c.' . .,'4 .=rlt ,. ::::. ::-(: :...:.:...:...:=...{ :х;: ::..::,,>:.' ::..-i:.:::::{' -;::. ,!f , "«,,?";,..II[! .i: " ..o,/..',...J : , .tII" o,o;::;;:f ! 'o:I ;; t .:o".'}I ! I/' ,';I _ :.- :::=-.: .:.:x: :::;._::- .:::.: ::_:: :: -,.:-.:;. ::":.." <; ....::. .: О:. о". . ._.. . "" о .". .-...:.......... .... - Рис. 1.85. Окно проекта с выводом тестовой информации strCmnd = strCmnd & strString & vbLf Loop Forml.wrem.Caption = strCmnd Forml.MSConun1.Output = "I01$5P" Forml.MSConun1.0utput = strCmnd End Sub После чтения из файла input.irc и до отправки строки в СОМпорт Bce t что было про читано, выводится на эту клави ту в качестве названия. Пока у меня не остается сомнений (спасибо Михаэлю Рай тиrеру и rеральду Мучу), я MOry спокойно провести сеrоднят ний вечер у телевизора. А завтра начну проверять модули, но это будет завтра... Завтра Вот «Завтра» И пришло. Ранее уже описана проверка релейноrо модуля и модуля приема системных ИКкоманд. Осталось проверить модуль 
Проrрамма для управnяющеrо компьютера 221 трансляции ИКкодов. Предполаrаю следующий ПОРЯДОК про верки. Подключаю модуль. Отправляю с компьютера команду трансляции ИКкода и читаю ero с помощью WinLIRC в режи ме прямоrо чтения кода. Первая правильная мысль  не устанавливать для излуче.. ния светодиод ИКдиапазона, а использовать три светодиода АЛ307, которые уже установлены на макетной плате. Возмож но, красный светодиод «прихватит» И ИКдиапазон. Первый результат. После включения клавити Телевизор включить и отправки ИКкода модуль «виснет», а проrрамма WinLIRC хладнокровно выводит результат: Outputting raw mode2 data. space 6025710 pulse 1086 space 994 pulse 1074 ерасе 1301 pulse 1057 space 978 pulse 1185 space 1011 pulse 1448 space 979 pulse 1147 space 983 pulse 1155 space 1002 pulse 1158 space 1014 pulse 1441 space 998 pulse 1145 space 992 pulse 1133 space 1002 pulse 1163 space 1012 pulse 1442 space 998 pulse 1136 
222 rnaBa . 1 Базовая версия space 976 pulse 1157 space 981 pulse 1156 space 977 pulse 1158 space 977 pulse 1130 space 1068 pulse 1467 space 951 pulse 1156 space 1053 pulse 1427 space 978 pulse 1159 space 999 pulse 1160 space 954 pulse 1183 space 1013 pulse 1466 space 950 pulse 1104 Я повторяю эксперимент несколько раз, постепенно при ходя к выводу, что удобнее фиксир,овать результат в записи короткие (О) и длинные (1) импульсы, чтобы удобнее было сравнивать с исходным кодом. Воспроизводимый код: О О 01 О О О О 1 О О О О О О О 1 О О О О О О О 1 О О О О О 000000100010000000100 Повторное воспроизведение дает тот же КОДt что уже xo рото. Но ориrинальный код имеет вид (в том же виде): 3аrоловок 01 0001 0001 000001 01 0001 00 Структура похожа, но сам код... Первое, что я делаю,  убираю все отладочные вставки в проrрамме модуля. Попyrно «смахиваю» функцию putch ()  модуль работает «молча»  И убираю настройки контромера, относящиеся к настройке передатчика. Модуль не подает при знаков жизни. Возвращаюсь на исходные позиции. Не помоraет. 
Проrрамма ДЛЯ управляющеrо компьютера 223 Изменяю количество байтов, принимаемых в массив записи команды, с 54 до 29 (реальных). И это не помоrает. Возможно, вам быстрее, чем мне, приходит в rолову мысль  а что я читаю из файла input.irc? В отладочной про rpaMMe MPLAВ я записывал символы. И читаю, надо пони мать, символы. А ожидаю числа. Открываю файл input.irc в HEXpeдaKTope и меняю сим волы на числа. Пробую: Oиtputting raw mode2 data. space 10739323 pulse 3650 space 732 pulse 1951 space 733 pulse 834 space 755 pulse 1983 space 684 pulse 859 space 719 pulse 2009 space 667 pulse 833 space 759 pulse 811 space 740 pulse 1937 space 742 pulse 1977 space 704 pulse 844 space 726 pulse 1978 space 705 pulse 832 space 2487801 3аrоловок 010001000100000101000100 Пытаюсь разобраться с временами, что не сложно,  уменьшить числа в файле input.irc. Меняю коэффициент с 13,8 на 19. Мне не нравится, что первое нажатие клавити 
224 rлова . 1 Базовая версия Телевизор включить не воспроизводит код, требуется по вторное нажатие. Но времена становятся ближе к исходным. Делаю попытку включить маrнитофон. Неудачно. Одна из причин этоrо может оказаться в единичности посылки кода. «Родные» коды идyr сплотным потоком. А если попробовать четыре повтора с паузой в 24505 мс? Пробую переделать про rpaMМY для реализации четырех повторов. Делаю паузу меж ду повторами с помощью цикла for. Заодно пытаюсь понять, отчеrо и rде зависает модуль. Дополняю еще одно число в файл .irc, чтобы цикл воспро изведения в проrрамме модуля заканчивалея правильно. То есть, чтобы проrрамма не «зависала» на отсyrствующем чис ле длительностью в пауз Попyrно меняю условие заверше ния чтения с количества чисел (29) на байт завертения фай ла «00». В какойто момент видеомаrнитофон даже удается вклю чать и выключать, нажимая клавишу Телевизор включить. Но модуль продолжает виснуть. На все это уходит два ДНЯ «борьбы с собственной rениально стью». Но есть и моменты проблесков. Проблема, которой закончилась отладка модуля приема ИКкодов. превратилась в ясное понимание. что лень не BcerAa хороша. Чтобы не создавать весь проект полностью. я КОПИРУЮ пре дыдущий в друryю папку, правлю имена файлов и т.д. Но. по.. правляя nporpaMMY при отладке. порой забываю. с какой из папок я работаю. Если бы не лень, я создавал бы новый про ект, открывал новые файлы... Словом, получилось так. что исходный текст я правил в одной из папок. а компилировал в друryю. Даю себе слово впредь в менеджере проекта yдa лять и добавлять все файлы заново. Посмотрим! За время отладки в rолову приходила мысль, что заверше ние файла байтом «00», может какимто образом влиять на зависание. Но как? Коrда не остается никаких разумных ва- риантов, и я устаю от бесконечноrо перепроrраммирования микросхемы, я меняю в файле input.irc завершающий байт с 00 на FF: а коэффициент  на 25. 
Проrрамма для управляющеrо компьютера 225 Модуль перестает «виснуть», маrнитофон исправно вклю чается и выключается. Проrрамма модуля имеет к этому Bpe мени вид, представленный в начале раздела. В основной проrрамме фраrменты для клавит елевизор включить и Телевизор выключить к концу наладки выrлядят так: private Sub IRernitterOloffClick() intFH = FreeFile() Open "D:\barby\inputl.irc" For Input As intFH Do Until EOF(intFH) Line Input #intFH, strString Loop Forrn1.MSComrn1.0utput = "I14$5P" For i = О То 10000 Next i Form1.MSComrn1.Output = strString For i = О То 20000000 Next i Form1.ТVon.Visible = False Forrn1.ТVoff.Visible = True End Sub Private Sub IRemitter01onClick() intFH = FreeFile() Open "D:\barby\inputl.irc" For Input As intFH Do Until EOF(intFH) Line Input #intFH, strString Rem strCmnd = strCmnd & strString & vbLf Loop Rem Forml.wrem.Caption = strCmnd Form1.MSComrn1.Output = "I14$5P" .For i = О То 10000 Next i Form1.MSComrn1.0utput = strString For i = О То 20000000 Next i Form1.тvoff.Visible = False Forrn1.тvon.Visible = True End Sub 
226 rлаВQ . 1 Базовая версия и HeMHorOH a Поскольку в первой версии единственным средством управ ления служит старый пульт от видеомаrнитофона (или теле визора), хотелось бы быть уверенным, что все будет работать правильно (или, хотя бы, будет работать). HeMHoro перед лаю основную проrрамму: Dim ext As Boolean private Sub mnuWorkClick() Form1.mnuTest.Enabled = False Forml.Commandl.Enabled = False Form1.Command1.Visible = False Form1.Reley01off.Enabled = False Forml.ReleyOloff.Visible = False Form1.Reley02off.Enabled = False Form1.Reley02off.Visible = False Fоrm1.RеlеуОЗоff.ЕпаЫеd = False Fоrml.RеlеуОЗоff.VisiЫе = False Form1.Reley01on.Enabled = False Form1.Reley01on.Visible = False Forml.Reley02on.Enabled = False Forml.Reley02on.visible = False Fоrm1.RеlеуОЗоn.EnаЫеd = False Fоrm1.RеlеуОЗоn.VisiЫе = False Form1.Photo01on.Enabled = False Forml.Photo01on.Visible = False Form1.Photo01off.Enabled = False Form1.Photo01off.Visible = False Form1.IRemitter01off.Visible = False Forml.IRemitter01off.Enabled = False Form1.IRemitter01on.Visible = False Form1.IRemitter01on.Enabled = False Forml.work End Sub Sub work () 1)) Form1.KeyPreview = True Form1.MSComm1.Output = "C14$OS" For i = О То 10000000 
Проrрамма для управляющеrо компьютера 227 Next i strAnsw = Forrnl.MSComml.Input Forml.wrem.Enabled = False Form1.wrem.Visible = False Form1.Refresh Select Case strAnsw Case "C14$OSC14001" Form1.Lampoff.Visible = False Form1.Lampon.Visible = True Form1.Refresh Case "C14$OSC14129" Form1.Lampoff.Visible = True Form1.Lampon.Visible = False Forml.Refresh Case "С14$ОSС1419З" Forml.Torsheroff.Visible = False Form1.Torsheron.Visible = True Form1.Refresh Case "С14$ОSС140ЗЗ" Forml.Torsheroff.Visible = True Form1.Torsheron.Visible = False Form1.Refresh Case "C14$OSC14161" Form1.Braoff.Visible = False Form1.Braon.Visible = True Form1.Refresh Case "C14$OSC14097" Form1.Braoff.Visible = True Form1.Braon.Visible = False Forml.Refresh Case "C14$OSC14065" ext = True End Select Loop While ext = False 
228 rnOBa . 1 Базовая версия Forml.Commandl.Enabled = True Forml.Commandl.Visible = True Form1.Refresh End Sub Переделка касается добавления ФУНКЦИИ work (), rде про rpaMMa «крутится» В цикле после включения режима Работа, ожидая ввода ИКкоманд с пульта. Команды включают и BЫ ключают «лампы» на форме. Модуль приема системных ИК команд я проверял и полаrал, что с ним не возникнет про блем. Я отибался! При тестировании модуля он правильно отвечал на ИК команды. Но, коrда запросы пошли часто, во время прохож дения бесконечноrо цикла основной команды модуль стал «виснуть. Пришлось вернуться к ero наладке. В итоrе про rpaMMa модуля приобрела вид, представленный в начале опи сания модуля. Теперь модуль не «виснет», основная проrpамма «крyrится» В цикле. По командам с пульта лампочки на форме включаются и выключаются, а, нажав на цифру «3» на пульте, я покидаю режим работы и MOry выключить основную проrрамМ)'. Здесь тоже есть момент, который меня не устраивает, но с ним, я думаю, можно разобраться позже. Он относится к выходу из цикла в основной проrрамме. Если я пытаюсь OCTa новить проrрамму с помощью меню или закрыть ее привыч ным для Windows образом, ничеrо не получается. Проблема в том, что проrрамма «крутится» В цикле, из KOToporo может выйти только по событиям, включенным в этот цикл. А един ственное событие  прием команды, отправляемой клави тей «3» с пульта. Я думаю, это ретаемый .вопрос, но к ero ретению мы вернемся позже. Текст основной nporpaMM". на .зыке Visual Basic Pim strAnsw As String Dim ext As Boolean Spb work() D:> Form1.KeyPreview = True Form1.MSComm1.OUtpиt = "D14$OS" 
Проrрамма для управnяющеrо компьютера 229 For i = О То 10000000 Next i strAnsw = Forrn1.MSComm1.Input Rern Form1.wrem.Caption = strAnsw Form1.wrem.Enabled = False Form1.wrem.Visible = False Form1.Refresh Select Case strAnsw Case "C14$OSC14001" Form1.Lampoff.Visible = False Form1.Lampon.Visible = True Form1.Refresh Case ".c14$OSC14129" Form1.Lampoff.Visible = True Form1.Lampon.Visible = False Form1.Refresh Case "С14$ОSС1419З" Form1.Torsheroff.Visible = False Form1.Torsheron.Visible = True Fonn1.Refresh Case "С14$ОSС140ЗЗ" Fonn1.Torsheroff.Visible = True Form1.Torsheron.Visible = False Fonn1.Refresh Case "С14$ОБС14161" Form1.Braoff.Visible = False Form1.Braon.Visible = True Form1.Refresh Case "C14$OSC14097" Form1.Braoff.Visible = True Form1.Bron.Visible = False Form1.Refresh . Case "D14$OSD14240" ext = True End Select Loop While ext = False Forrn1.Command1.Enabled = True Form1.Command1.Visible = True Form1.Refresh End Sub Private Sub Command1Click() 
230 rnOBO . 1 Базовая версия Fonnl.Command1.Caption = "Test run" Fonn1.Command1.Enabled = True Form1.wrem.Caption = " Forml.MSComm1.Output = "R14$lN" For i = О То 10000000 Next i strAnsw = Fonn1.MSComm1.Input Fonn1.wrem.Caption = strAnsw Fonn1.Command1.Caption = "Test R" Fonn1.Command1.Enabled = True End Sub " private Sub IRemitter01offClick() intFH = FreeFile() Open "D:\Ьarby\inputl.irc" For Input As intFH Do Until EOF(intFH) Line Input #intFH, strString Loop Fonn1.MSComml.Output = "I14$5P" For i = О То 10000 Next i Fonn1.MSComm1.Output = strString For i = О То 20000000 Next i Fonn1.ТVon.Visible = False Fonn1.ТVoff.Visible = True End Sub private SuЬ IRemitterOlonClick() intFH = FreeFile(} Open "D:\Ьarby\inputl.irc" For Input As intFH Do Until EOF(intFH) Line Input #intFH, strString Rem strCmnd = strCrnnd & strString & vbLf p Rem Fonn1.wrem.Caption = strCmnd Fonn1.MSComm1.Output = "I14$5P" For i = О То 10000 Next i Fonn1.MSComm1.Output = strString For i = О То 20000000 Next i Fonn1.ТVoff.Visible = False 
Проrрамма для управляющеrо компьютера 231 Forrnl.ТVon.Visible = True End Sub Pri vate SUЬ mnuStopClick ( ) Forrnl.mnuTest.Enabled = True Forrn1.mnuwork.Enaыldd = False Forrnl.MSComml.PortOpen = False End Sub private Sub mnuTestClick() Forrnl.mnuWork.Enabled = True Forrn1.MSComml.CommPort = 1 Forrn1.MSComml.Settings = "2400,N,8,1" Forrn1.MSComm1.PortOpen = True Forrn1.Reley01off.Enabled = True Forrn1.Reley01off.Visible = True Forml.Reley02off.Enabled = True Forml.Reley02off.Visible = True Fоrm1.RеlеуОЗоff.ЕnаЫеd = True Fоrrnl.RеlеуОЗоff.VisiЫе = True Forrn1.Reley01on.Enabled = True Form1.ReleyOlon.Visible = True Form1.Reley02on.Enabled = Jrue Form1.Reley02on.Visible = True Fоrml.RеlеуОЗоп.Enаblеd = True Fоrm1.RеlеуОЗоп.Visiblе = True Form1.Photo01on.Enabled = True Forrn1.PhotoOlon.Visible = True Form1.IRemitter01off.Visible = True Forml.IRemitter01off.Enabled = True Form1.IRemitterOlon.Visible = True Form1.IRemitter01on.Enabled = True Form1.Photo01off.Enabled = True Form1.PhotoOloff.Visible = True End Sub Private Sub mnuWorkClick() Form1.mnuTest.Enabled = False Forml.Cornmandl.Enabled = False Forml.Cornmand1.Visible = False Forrnl.Reley01off.Enabled = False Form1.ReleyOloff.Visible = False Forml.Reley02off.Enabled = False 
232 rлава . 1 Базовая версия Forml.Reley02off.Visible = False Fоrml.RеlеуОЗоff.Епаblеd = False Fоrml.RеlеуОЗоff.VisiЫе = False Form1.Reley01on.Enabled = False Forml.Reley01on.Visible = False Form1.Reley02on.Enabled = False Form1.Reley02on.Visible = False Fоrml.RеlеуОЗоn.Еnаblеd = False Fоrml.RеlеуОЗоп.Visiblе = False Forml.Photo01on.Enabled = False Form1.PhotoOlon.Visible = False Form1.PhotoOloff.Enabled = False Forml.Photo01off.Visible = False Forml.IRemitterOloff.Visible = False Form1.IRemitter01off.Enaыldd = False Form1.IRemitterOlon.Visible = False Form1.IRemitterOlon.Enabled = False Form1.work End Sub Private Sub Photo01offClick() Forml.IRcmndon.Visible = False Forml.IRcmndoff.Visible = True End Sub . private Sub Photo01onClick() Form1.wrem.Caption = " Forml.MSComml.OUtput = "C14$OS" For i = О То 10000000 Next i strAnsw = Forml.MSComm1.Input If strAnsw = "C14$OSC14001" Then Form1.IRcmndoff.Visible = False Form1.IRcmndon.Visible = True Form1.wrem.Caption = strAnsw Else Form1.IRcmndon.Visible = False Form1.IRcmndoff.Visible = True Forml.wrem.Caption = st-rAnsw End If If strAnsw = "C14$OSC14129" ТЬеп Forml.Lampon.Visible = True Forml.Lampoff.Visible = False " 
Проrрамма для управляющеrо компьютера 2ЗЗ Forrn1.wrem.Caption = strAnsw End If End Sub private Sub Reley01offClick() Form1.MSComm1.Output = "R14$OF" Forrn1.MSComm1.Output = "R14$OS" For i = О То 10000000 Next i strAnsw = Form1.MSComm1.Input If strAnsw = "R14$OFR14$OSR14#OF" ТЬеп Form1.Lampon.Visible = False Form1.Lampoff.Visible = True End If End Sub private Sub Reley01onClick() Forrn1.MSComm1.Output = "R14$ON" Forrn1.MSComm1.Output = "R14$OS" For i = О То 10000000 Next i strAnsw = Form1.MSComm1.Input If strAnsw = "R14$ONR14$OSR14#ON" ТЬеn Form1.Lampotf.Visible = False Form1.Lampon.Visible = True End If End Sub Pri vate Sub Reley02offClick () Forrn1.MSComm1.Output = "R14$lF" Form1.MSComm1.Output = "R14$lS" For i = О То 10000000 Next i strAnsw = Form1.MSComm1.Input Form1. wrem. Caption = strAnsw If strAnsw = "R14$lFR14$lSR14#lF" ТЬеn Form1.Torsheron.Visible = False Form1.Torsheroff.Visible = True End If End Sub private Sub Reley02onClick() Form1.MSComm1.Output = "R14$lN" 
234 rлава . 1 Базовая версия Forml.MSComm1.Output = "R14$lS" For i = О То 10000000 Next i strAnsw = Form1.MSComm1.Input If strAnsw = "R14$lNR14$lSR14#lN" Then Form1.Torsheroff.Visible = False Form1.Torsheron.Visible = True End If End Sub Private Sub RеlеуОЗоffСliсk() Form1.MSComml.Output = "R14$2F" Form1.MSComm1.Output = "R14$2S" For i = О То 10000000 Next i strAnsw = Form1.MSComm1.Input If strAnsw = "R14$2FR14$2SR14#2F" ТЬеn Form1.Braon.Visible = False Form1.Braoff.Visible = True End If End Sub private Sub RеlеуОЗоnСliсk() Forml.MSComm1.Output = "R14$2N" Form1.MSComml.Output = "R14$2S" For i = О То 10000000 Next i strAnsw = Forml.MSCornm1.Input If strAnsw = "R14$2NR14$2SR14#2N" ТЬеп Forml.Braoff.Visible = False Forml.Braon.Visible = True End If End Sub Подведем итоrи Первая версия системы завершена. Конечно, даже после отладки модулей в MPLAВ пришлось обратиться к работе с макетом. Думаю, это в первую очередь, связано с тем, что несколько разработок  это еще не опыт работы. Но можно надеяться на изменение ситуации со временем. Полезный вывод из сделанных ошибок  при 
Подведем итоrи 235 проrраммировании на языке С труднее учитывать реальное время. Например, устанавливая задержку с помощью операт ра цикла for, который на С выrлядит, как один оператор, не следует забывать, что на ассемблере операторов будет значи тельно больше. Наконец, еще один вывод  работать с дeMO версиями  это создавать себе дополнительные проблемы. Тем не менее, план, который мы наметили для первой части работы, реализован: есть модули и среда проrраммиро вания системы, пусть не столь красивая и удобная, как в KOM мерческих реализациях, но работающая. В целях удетевления первых экспериментов (я уже rOBo рил об упрощении проrрамматора) настоятельно рекомендую использовать одну макетную плату. Моя макетная плата KpO ме интерфейсной микросхемы, стабилизатора напряжения и панельки под контроллер имеет три красных светодиода АЛ307 и фотоприемник TSOP с ero «атрибyrами». Макетная плата позволила отладить, все три модуля. При этом светоди од АЛ307 я использовал в качестве излучателя ИКкоманд. Что касается внешнеrо вида rOToBbIx образцов, если вы решите их сделать: значительная часть оборудования может располаrаться в шкафах, силовых или слаботочных, то есть быть скрытой от rлаз. Кроме Toro, сеrодня можно купить под ходящие коробки и коробочки вполне приятноrо «ToBapHoro» вида. В частности, есть коробки с макетными платами He скольких размеров, предназначенные для установки Ha DIN рейку (то есть в ткаф). Они имеют весьма респектабельный вид и удобны для сборки модулей. А этикетки можно очень удачно печатать на принтере. Так что получить вполне при емлемый внетний вид для своих разработок по силам любо му. Тем более что и промышленные образцы зачастую имеют очень «прозаический», хотя И хорошо исполненный, KOH структив. Возвращаясь к предисловию, добавлю небольшое послесло вие к первой части. Ero можно назвать «Ода ошибкам». Ода оwи6кам Любоrо из нас отибки сердят, вызывают раздражение, MOryт подорвать веру в собственные силы. Не принято в книrе, 
236 rлава . 1 Базовая версия источнике знаний, делать множество отибок. Но, если BДY маться, не нати ли отибки, как нати rлаза и уши, ведyr нас к знаниям? Как палка слепоrо, они позволяют определять пре пятствия, заставляют задуматься, правильным ли пyrем дви rаешься? Собственные отибки запоминаются лучте и служат дольше. Коrда я попадаю в безвыходную ситуацию, коrда OT сyrствие ретения подобно беспросветному мраку, мне пом<r raeT простой прием  я не пытаюсь найти правильное peтe ние, я принимаю заведомо отибочное. С ним я работаю до Toro момента, коrда оно либо трансформируется в правиль ное ретение, либо подсказь1вает путь к HeM Самое плохое, что поджидает меня в этом случае,  напрасно потраченное время. Но напрасно ли оно потрачено? Двиrаясь неверным пyrем, я всетаки делаю MHoroe, что позже применяю в дpy rих случаях, но в схожих ситуациях. Со временем, с накоплен ным опытом приходит интуитивное видение решений. Но это относится, в первую очередь, к узкой области деятельно сти. Стоит выйти за пределы этой области  и ватей интуи ции понадобится тросточка, чтобы пройти весь пyrь без бо лезненных падений. Я не люблю отибаться, не люблю признаваться в отибках. Я вообще не люблю ошибки! Но по нимаю их пользу, как необходимость и пользу rорьких ле карств. Во второй части книrи мы разработаем еще несколько полезных модулей. Возможно, «причетем» уже rOToBbIe. Воз можно, создадим среду проrраммированя больте похожую на профессиональную версию. Посмотрим... 
rлава Как расширить систему в этой части книrи я предлаrаю растирить набор модулей. В первую очередь, за счет разработки модуля цифровых вводов. Почему я не включил модуль цифровых вводов в первую часть? Модуль, в основном, предназначен для подключения дaT чиков с «сухими контактами» или аналоrичным выходом, име ющих два состояния  включено и выключено. Это противо пожарные датчики, датчики охраны. К модулю цифровых вводов можно подключить пороrовые датчики освещенности: освещенность достиrла некоторой величины  датчик замы кает контакты; освещенность упала  датчик выключает KOH такты. Такими MOryт быть датчики температуры, влажности, давления. положения, термостаты и т.д. Больтой интерес в этом ряду представляют датчики движения. С их помощью леrко орrанизовать автоматическое управление светом в KO ридоре, прихожей или на лестнице. Часть датчиков, например датчики освещенности и TeM пературы, достаточно просто изrотовить самостоятельно. Но пирометрические датчики движения даже в собственном ис полнении MOryт оказаться слитком дороrими. Использовать противопожарные или охранные датчики в самостоятельном исполнении я не вижу смысла  они должны быть очень Ha дежны, так как требования к устройствам, обрабатывающим их сиrналы, очень жесткие. Кроме Toro, если вам захочется 
238 rлава . 2 Как расширить систему разработать устройства подобноrо назначения, то не COCTa вит труда сделать это самостоятельно. Однако я не peKOMeH довал бы возлаrать больтие надежды на использование caM дельных противопожарных и охранных устройств. Тем не менее, мы разработаем модуль цифровых вводов, а в приложении я постараюсь привести хотя бы одну схему датчика движения. Расширение состава модулей, кроме модуля цифровых вводов, осуществим за счет замены реле в релейном модуле на аналоr твердотельноrо реле, состоящий из оптопары и триака. Подобный модуль, рассчитанный на подключение aK тивной наrрузки ламп накаливания, хорошо подойдет для включения и выключения света. Мощность наrрузки может составлять 500600 Вт, а rабариты позволяют встроить M дуль В обычный выключатель света. Попyrно мы рассмотрим возможность плавной реryлировкц яркости света. Использование релейноrо модуля для подключения музы кальноrо центра к rромкоrоворителям, установленным в дpy rих помещениях, решает вопрос о распределении звука. Но в ситуации, коrда вы намерены в дрyrом помещении не только слушать музыку, но и смотреть фильмы, полезным может OKa заться аудиокоммyrатор. О модуле подобноrо назначения мы тоже поrоворим. Посмотрим, нельзя ли ero применить и для коммyrации видеосиrнала. Конечно, все описанные устройства имеют основное Ha значение  исследование возможностей микроконтроллеров. Предполаrается, что они будут собраны на макетной плате, разложены на столе, а по окончании экспериментов отпра вятся в ящик С деталями для разборки «по случаю». Вместе с тем, KOМYO, возможно, приrлянется идея применить разра ботки в своей комнате или квартире. Если в квартире не за ложено больтоrо количества проводов для орrанизации сис темной сети, прокладывание проводов может представлять некоторые сложности. Есть несколько решений, позволяю- щих избежать этоrо при орrанизации системной сети. Я уже упоминал протокол Х1 О  использование силовых проводов в качестве «среды обитания» системных сиrналов. При выб<r ре этоrо решения настоятельно рекомендую воспользоваться 
Мо дул ь ци фровых вводов 239 rотовыми изделиями, например, обративтись в фирму «YM ВЫЙ дом». Дрyrое решение  радиоканал или использование инфракрасноrо излучения для передачи сетевых сиrналов. Эти возможности мы обсудим. И, конечно, постараемся расширить средства управления. Добавить к компьютеру и старому пульту от телевизора что то, не менее успетно решающее эти задачи. Модуnь ЦИфРОВЬIХ вводов Зачем нужен модуль цифровых вводов, я уже rоворил. Что же он собой представляет в плане постановки задачи? Модуль дол жен иметь некоторое количество входов, каждый из которых может быть замкнут на общий провод или разомкнут. В ответ на запрос центральноrо управляющеrо устройства модуль пе редает состояние своих входов. К входам присоединяются дaT чики. Кроме уже упомянутых это MOIyr быть датчики, реrист рирующие состояние бытовой аппаратуры. Например, датчик состояния телевизора, реrистрирующий, включен он или BЫK лючен. Применение подобноrо датчика особенно актуально, если телевизор, как это зачастую получается, управляется с помощью ИКкоманд. Поясню. Стандартная ситуация: систему можно построить таким образом, что управление будет происходить по времени cy ток. В час ночи, если вы ложитесь спать раньте, система мо- жет выключить все бытовые приборы, весь свет в доме (или квартире), всю аудио и видеоаппаратуру, которые моrли oc таться включенными. Однако есть одно «но». ИКсиrнал BЫK лючения некоторых телевизоров, мноrих' музыкальных цен- тров и видеомаrнитофонов полностью совпадает с сиrналом включения. Если одна из команд прошла мимо системы, вме- сто выключения устройства вы включите ero. Обычно в про- rpaMMe управления можно устанавливать флаrи состояния. Каждое включение телевизора устанавливает флаr ТVON, а выключение сбрасывает ero. А если телевизор оказался вы- ключен из сети? Флаr будет успетно устанавливаться и сбра сываться, не ретая проблемы. Можно применить релейный модуль, подключая телеви зор, музыкальный центр и остальное оборудование к сети 
240 rЛQВQ . 2 Как расширить систему через контакты реле. Но хотелось бы иметь запасной вари ант. Таким вариантом станет датчик, который фиксирует ток в проводах подключения бытовой техники. Лучте использо вать, например, датчик Холла для определения тока в цепи но можно применить и чтонибудь попроще. Об этом мы по rоворим ниже, но подобный датчик подключить к системе разумнее Bcero с помощью модуля цифровых вводов или сам модуль сделать частью датчика. Есть очень удобные и детевые датчики, которые называ ЮТ «rерконовыми». Они удобны для установки на двери или окна. На основе TaKoro датчика можно орrанизовать aBTOMa тическое включение и выключение света в ванной или туале те При первом открывании двери свет включается, при BTO ром выключается. «rерконовый» датчик, конечно, к системе подключается через модуль цифровых вводов. Если YCTaHO вить датчик на входную дверь, а в основной проrрамме поста вить счетчик, можно орrанизовать подпроrрамму определе ния момента, коrда все покидают квартиру или дом. Этот момент может быть отправной точкой для принудительноrо отключения от сети всех электроприборов и перекрывания вводов воды во избежание протечек. Или включения систе мы имитации присутствия людей в доме, что используется, как часть подсистемы охраны. Позже, коrда KTOTO приходит домой, такой датчик можно использовать для орrанизации сцены обслуживания, которую я описал в предисловии как «Возвращаюсь Я С работы...». Таким образом, модуль цифро вых вводов вполне можно отнести к базовым и обязательным модулям системы «Умный дом». Я хочу обсудить еще одно применение модуля цифровых вводов  в качестве интерфейса к клавишным устройствам управления. Имея 8 входов, подобный модуль может работать с устройством управления, снабженным 8 клавишами Этоrо достаточно для мноrих задач управления. Если же использо вать матрицу 4х4 для построения клавиатуры, количество подаваемых команд увеличится до 16, а количество использу емых выводов порта останется равным восьми. Модуль цифровых вводов леrко сделать из проrраммы для релейноrо модуля. Перенаправим все выходы, предназначенные 
Мод у ль ци фровых вводов 241 для подключения реле, на вход. Будем отслеживать состоя иие всех входов и записывать их. Остается только переда вать их состояние в ответ на запросы rлавной проrраммы, как это было с системными ИКкомандами в модуле приема ИКкодов. Присвоим командам модуля цифровых входов префикс, например D, и получим формат запроса: Dxx$OS rде хх  два символа номера модуля от О до 15, а О после $  . «заставка» для под,цержки формата. Формат ответа модуля тоже, очевидно, будет: Dxxyyy . rде ууу  символьное представление десятичноrо числа, OTO бражающеrо состояние входов (как это было сделано для при емника ИКкоманд). Проrрамма МОДУЯR цифровых вводов на Rэыке С Входы RЛОRЛ2 я оставил для выхода, к ним подключены индикаторы. Файл эаroловка void putch(unsigned char); unsigned char getch(void); int initcomms(); int simnurnadr(); int cmd () i int dinstat{); ОСНОВНОЙ файл #include <pic16f62xa.h> #include <stdio.h> #include "digin.h" unsigned char inputi реrистра. unsigned char MODSIM1; unsigned char MODSIM2; I / Для считывания приемноrо / / Первый символ адреса модуля. // Второй символ адреса модуля. 
242 rлава . 2 Как расширить систему unsigned char commandreciev [6]; // Массив ДЛЯ полученной команды. int MODADDR; int simendnum = о; модуля . int MODNUМ; // Полученный адрес модуля, как число. unsigned char DINSTAT = OxF8; // Статус позиционно: 1  вкл, О  выкл. unsigned char DINSIM1; unsigned char DINSIM2; unsigned char DINSIМЗ; int i; / / Заданный адрес модуля, как число. / / Полный символьный номер / / символы состояния для передачи. // Получение байта. unsigned char getch<) { while ( ! RCIF) continue; return RCREG; // Коrда реrистр не пуст. } // Вывод одноrо байта. void putch(unsigned char pyte) { while ( ! TXIF) continue; TXREG = byte; 1/ Коrда реrистр пуст } // Преобразуем символьный адрес в число. int simnurnadr() { simendnum = о; MODSIM1 = commandreciev [1]; // Первый символ номера. MODSIM2 = comrnandreciev [2]; // Второй символ номера. MODSIMl = MODSIMl  Охзо; MODSIM2 = MODSIM2  Охзо; simendnurn = MODSIM1*OxOA + MODSIM2; return simendnurn; } / / Получение и выполнение команды. int cmd() { switch (commandreciev [5]) { 
Мо ду ль ци фровых вводов 243 case "S": dinstat(); break; } } // Выполнение команды передачи состояния. int dinstat ( ) { int din; int dinl; int din2; int din3; din = DINSTAT; // Преобразуем состояние в символы. dinl = din/Ox64; DINSIMl = din1 + Ох30; din2 = (din  dinl*Ox64)/OxA; DINSIM2 = din2 + Ох30; din3 = (din  din1*Ox64  din2*OxA); DINSIM3 = din3 + Ох30; сопunапdrесiеv[О] = "D"; сопunаndrесiеv[l) = МОDSIМl+0хЗО; сопunапdrесiеv[2] = МОDSIМ2+0х30; сопunаndrесiеv[З) = DINSIM1; сопunаndrесiеv[4] = DINSIM2; сопunаndrесiеv[5] = DINSIM3; CREN =0; / / Запрещаем прием. RBO = 1; //Переключим драйвер RS485 на передачу. TXEN = 1; / / Разрешаем передачу. for (i=O; i<6; ++i) pиtch(commandreciev[i]); for (i=0;i<1000;i++); // Задержка для вывода. for (i=O; i<6; ++i) cornmandreciev [i] = " "; RBO = о; // Выключаем драйвер RS485 на передачу. TXEN = о; / / Запрещаем передачу. CREN =1; / / Разрешаем прием. Мl = о; DINSTAT = OxF8; / / Сбросим состояние. } int initcomms () { // Инициализация модуля. 
244 rлава . 2 Как расширить систему PORT = OxF8; CMCON = Ох?; TRISA = OxF8; TRISB = OxFE; RCSTA = 0Ь10010000; TXSTA = ОЬОООООI10; SPBRG = Ох68; RBO = о; МО = 1; } // Настройка портов А и В // Настройка приемника. // Настройка передатчика. // Настройка режима приемапередачи // Выключаем драйвер RS485 на передачу. void main(void) { / / Инициализация модуля. ini tcomms ( ) ; for (i=O; i<6; ++i) conunandreciev [i] = " "; conunandrec i ev (О] = "D"; //Прочитаем и преобразуем номер модуля MODADDR = PORTB; / / Номер модуля в старших битах MODADDR = MODADDR»4; // Сдвинем на четыре бита. // Начинаем работать. start: CREN =1; if ((PORTA&OxF8) != OxF8) { DINSTAT = DINSTAT&PORTA; Мl = 1; } if (RCIF) // Если пришел запрос по сети. input = getch ( ) ; switch (input) { case "D": / / Если обращение к модулю. for (i=l; i<6; ++i) // Запишем команду в массив. { input = getch(); conunandreciev (i] = input; } MODNUМ = simnumadr ( ) ; / / Чтение из сети. f (MODNUМ != MODADDRJ break; else // Если не наш адрес. 
Мод у ль ци фровых вводов 245 i f ( commandrec i ev [З] = .. $ ") cmd () ; default: goto start; //Если команда. } goto start; } ВЫВОДЫ порта Д AДOAД2 на время работы с макетом я про rраммирую так, чтобы индикатор на выводе АДО включался при включении модуля, а индикатор на выводе АА 1 отображал наличие изменений состояния входов модуля При настройке проrраммы в MPLAВ я использую данные, показанные на рис. 2.1. . :"" О _.,. '$о. orkbook . (Untftted] I pn J A.ef Actions . дdv Pn J Aegi$ter.. oock. S A  .I ' ,'; , ....  . > , I TineUnh) U$ ..:J OAepeatkt '.. . ( . T Ад? RA61.Aд5! АДА АВ7 ABS! AB5i АВ." CSckhefetoAddSigIab :А: () (bin) () 1 (binl '(bin) Ibln) (bin) L(bn) i (bin ) .. .-" - . .. .. . . ш .. .-'? ..F ,  :  : : ' , , о ... .... ... . .....<. .1 2ООХ) 1 1 О 1 ! 1rOXЮ 1 1 1 1 151Xn1 О 1 1 1 I I 1'. I I j .- u:.. - -.. :v.- -------_ :-:-:.-....-.. [ .Q.eIete Row I Iave wOlkbookf 1, E)It. 1 : ( H 1 ; ( jienerete 50. flOl'В Workbook ] . .. ... Рис. 2.1. Отладочные данные В этом файле мноrие переменные и функции я оставил в обозначениях, близких к исходным. Я уже rоворил, что co бираюсь переделать проrрамму из проrраммы релейноrо модуля. Часть текста, подправив, я взял из текста проrрам мы модуля приемника системных ИКкоманд. Правка была минимальной. Здесь мне хотелось бы еще раз вернуться к вопросу о Ha писании текста проrраммы. Мноrие переменные в представ ленном выше тексте обозначены так, что трудно понять, для каких целей они служат. Функции не облеrчают понимание их назначения. Вернувшись к тексту после нескольких недель 
246 rлаВQ . 2 Как расширить систему перерыва, начинаеть понимать, что лучше было бы все cдe лать иначе. Удобно обозначать переменные, чтобы леrко было понять их назначение. То же касается и функций. Для этоrо есть MHoro правил, которые лучше поискать в PYKOBOД ствах по проrраммированию. Но есть один момент в работе над текстом. Переменную удобно обозначить, например, int digi talinputclose. Однако, используя эту переменную дe сятки раз, переделывая проrрамму столько же раз, ты пони маешь, что каждый раз вписывать это мноrословное название переменной утомительное занятие. Можно, конечно, копи ровать название из текста проrраммы. НО для этоrо прихо дится возвращаться к началу, затем искать место, rде ты раб<r тал. Можно поступить иначе, и это будет полезно во всех отношениях  использовать файл todo.txt. В нем перечислить все переменные и функции, попyrно описав их. Переключ ние между файлами быстрое, а копирование не сложное, по скольку перечень переменных и функций можно сделать KO ротким. При проверке макета (а для ero проверки я использую Tec товую часть основной проrраммы, исправив обращение к oд ному из модулей на обращение к модулю цифровых входов  D14$OS), первое, что мне не нравится, но не является неожи данностью,  это поведение входов. Думаю, причина в OTcyr ствии «подтяrивающих») резисторов. Я впаиваю на макет подтяrивающие резисторы (резисто ры между плюсом питающеrо напряжения и выводом) на BXO ДЫ, и картина действительно меняется  макет полностью перестает реаrировать на тестовые команды! Создается впечатление, что или конвертер RS232RS485, или интерфейс RS485 макета вытли из строя. В моем pac поряжении только мультиметр. Не самый удачный вариант Первое, что приходит в rолову после нескольких неудачных попыток оживить модуль,  внести в проrрамму изменение: при инициализации переключить драйвер RS485 на переда чу (бит RBO). ' Бит переключается, что уже хорошо. Затем, манипулируя индикаторами на выводах RAORA2, я начинаю проверять, в чем дело? И проблема оказывается в простой халатности  при 
Мод ул ь ци фровых вводов 247 переделке проrраммы релейноrо модуля Я, хотя и намеревал СЯ, не изменил основную часть проrраммы, которую собирал ся позаимствовать от проrраммы фотоприемника. После изме нения проrраммы модуль цифровых входов стал работать вполне убедительно. в тексте выше приведена уже исправленная версия nporpaMMbI. Теперь осталось проверить работу модуля в основной про rpaMMe в режиме Работа. В этом режиме проrрамма не pea rирует ни на что, кроме сетевых событий. Ранее для выхода из режима Работа я использовал ИКкоманду. Сейчас я хочу использовать изменение входа RЛ3, внеся для этой цели из менения в основную проrрамму: Sub work () [о Form1.KeyPreview = True Fоrm1.МSСoпm1.OUtрut = "D14$OS" For i = О То 10000000 Next i strAnsw = Form1.MSComm1.Input и т.д. до строки Савв "D14$OSD14240" ext = True End Select Таким образом, я поменял обращение к модулю (было об ращение к модулю фотоприемника) и условие выхода Проrрамма работает. НЕХ-фаiin модуn. "ифров". ВВОДОВ Выводы RЛОRЛ2 используются в «макетном варианте) для индикации! :10000000830100308АООО42820308400403016200С :1000100083010330C200FF30C10040308400413012 :100020001A2083019E2A04068001840A0406031D07 :1000300013280034F00026208000840A040870068B :10004000031900341В288312031ЗС100С21ВЗ1287В 
248 rлава . 2 Как расширить систему :10005000421В392842088АО04108С10А0319С20А12 :1000600082008313421883174108С10А84000008Е4 :02007000080086 :1004860083018СIЕ432АIА08080083013408533А54 :10049600031D0800FC2A8301BF00831203130CIEFO :1004A600502A3F0899000800F401F5010310F30CE7 :1004B600F20C031C652A7008F40771080318710A08 :1004C600F5070310FOODFI0D7208730403190034DB :1004D600592AF8308301850007309FOOF8308316CB :1004Е6008500FЕ30860090зое31298000630831611 :1004F60098006830990083120610051408008301DD :10050600AD01AE013008A4003108A500D030A40723 :10051600A5070A30F200F3012408FOOOFI01572282 :1005260025087407ADО075080З18750ААЕООF100ВА :100536002D08F00008006C22AВOIAC01AВ2A2B0899 :100546002F3E8400831320308000AВOA0319ACOAC7 :100556002СО8803АРООО80307002063003192ВО216 :10056600031СА22А4430АРООО608А700А8010430Е5 :10057600F000280DA80CA70CFOOBВC2AEA2AAВ0148 :10058600AВOAAC012C08803AF000803070020630CD :1005960003192B020318DB2A4322A6002B082F3E41 :1005А6008400831326088000АВОА0319АСОАС52А07 :1005B60082227008A9007108AA002806031DE52AFO :1005С60027082906031DЕА2А2430В2004822181БF5 :1005D6000508F839F83A0319F32A0508C005851401 :1005E6008C1EF72A4322A6002608443A0319C22A7B :1005F600EA2A83014008B900BA016430F200F30127 :100606003A08FI003908FOOOB0237408BB007508F9 :10061600ВC003B08303EA0006430F200F3013C0809 :10062600FI003B08F00057223A08FI003908FOOOC3 :100636007408F002031CFI037508F1020A30F20097 :100646000030F301B0237408B7007508B800370806 :1006560030ЗЕА1000А30F200F3013808FIО03708F5 :10066600F00057227408BD007508BE006430F20021 :10067600F3013C08F1003B08F00057223A08FI006C :100686003908F0007408F002031CFI037508F10242 :100696003D08F002031CF1033E08F1027008B500A4 :1006А6007108В6003508303ЕА2004430АРОО240879 :1006В600З03ЕВОО02508303ЕВI002008В2002108С7 :1006С600В3002208В4001812061483169816831273 :1006D600AВ01AC01772B2B082F3E84008313000857 :100БЕ6004Е22АВОА0319АСОА2С08803AFОО080307F :1006F6007002063003192B02031C6E2ВAВOIAC01F2 
Мо ду ль ци фровых вводов 249 :100706002C08803AF00083307002E83003192B027F :100716000318912ВАВОА0319АСОА832ВАВОIАСО16Е :100726002C08803AF00080307002063003192B0244 :100736000318A72B2B082F3E84008313203080003C :10074600АВОАО319АСОА932В0610831б9812831270 :1007560018168510F830C0000800F601FI1FBA2BF4 :1007б600FОО9FООА0319FI03FI097б17F617730871 :100776008039F60БF31FС62ВF209F20АО319F303В2 :10078600F309C62BF601F40IF50172087304031D83 :10079БООСF2ВFО01F10100341F30F6040310F60АЕ6 :1007A600F20DF30D031CD22BF30CF20C730871023D :1007ВБООО31DDF2В72087002031СЕ72В7208FОО280 :1007СБО07308031С730AFI02F40DF50DF60ВF61АО5 :1007DБООD72ВF61FF32ВF409F40АО319F503F509D1 :1007E6007408F2007508F300761F0034F009FOOA69 :ОА07F6000З19F103FI090034F8348F :OOOOOOOlFF Пришло время поrоворить о датчиках, с которыми можно провести эксперименты, используя модуль цифровых вводов. Я уже rоворил, что наиболее интересными датчиками бу дyr датчики движения, противопожарные датчики, датчики температуры (пороrовые измерители температуры), датчи ки положения (в частности, repKoHoBbIe). Рассмотрим их по порядку, начиная с простейшеrо  rep KOHoBoro датчика. rерконовый датчик (название происходит от сокращения «rерметизированные контакты») представляет собой пару: маrниточувствительные контакты в стеклянной колбе и по стоянный маrнит. Реальный датчик, конечно, имеет пласт массовые корпуса и для контактов, и для маrнита. Коrда KOH такты попадают в поле постоянноrо маrнита, они замыкаются (или переключаются для варианта с контактами на переклю чение). Естественно, соединив один вывод контактов с BЫBO дОМ модуля цифровых вводов, а дрyrой  с общим проводом модуля, мы получаем сиrнал о взаимном положении KOHTaK тов и маrнита. Если контакты укрепить на дверной короб, а маrнит  на дверь, при закрытой двери контакты замкнут ся, а при открытой разомкнутся. Этот сиrнал можно исполь зовать в основной проrрамме, чтобы инициировать любые события. 
250 rлава . 2 Как расширить систему Положим, мы установили rерконовый датчик на входную дверь. Теперь вполне можно реализовать проrрамму «Возвра щаюсь я с работы...», о которой я rоворил в предисловии. Ha помню: «Возвращаюсь я С работы. Система встречает меня  зажиrает свет в прихожей, кипятит воду для кофе (конечно, чайник я наполняю утром). А коrда я перехожу в rостиную с чашкой кофе, она включает телевизор на моей любимой про-- rpaMMe новостей, чтобы я, усевшись в любимое кресло, посмот- рел, что произошло в мире за день. Свет на кухне и в прихо-- жей, который я, конечно, забыл выключить, она выключит сама» . Для реализации подобной проrраммы все, собственно, есть. Можно установить repKoHoBbIe датчики на дверь туалета, а основную проrрамму построить так, чтобы при первом OT крывании двери свет в туалете включалея, а при втором OT крывании выключалея. Естественно, в систему необходимо добавить релейный модуль для управления светом или MO дуль С триаком, о котором речь пойдет ниже. repKoHoBbIe датчики, несмотря на всю свою просто MO ryт найти множество применений в экспериментах с сист мой «Умный дом». Рассмотрим, как можно сделать датчик температуры. В качестве датчика температуры можно использовать TepMO резистор. Сделав делитёль из терморезистора и обычноrо pe зистора, ПОДlUIючив напряжение к делителю, можно снимать сиrнал напряжения на терморезисторе при изменении TeM пературы. Теперь осталось подключить компаратор и реле, чтобы при достижении HeKoToporo значения напряжения реле включалось (с модулем цифровых вводов можно исполь зовать вместо реле транзистор с открытым коллектором). Используя в качестве обычноrо резистора пару из перемен Horo и постоянноrо резистора, можно изменять заданное Ha пряжение срабатывания. Подобных схем великое множе ство, при необходимости вы можете использоват любую. Можно построить и свою схему, в основе которой может ле жать чувствительность к температуре не только терморезис тора, но транзистора и т.д. 
Мод ул ь ци фровых вводов 251 Как в системе можно использовать подобный датчик? Ha пример, можно настроить датчик на срабатывание при TeM пературе ниже 15° и поместить термочувствительный эле мент за окном. В качестве индикатора «похолодания» можно использовать свет в прихожей. Действия проrраммы будут следующими: температура за окном упала ниже 15°. Коrда открывается входная дверь, снабженная repKoHoBbIM датчи ком, свет в прихожей выключается и включается вновь  не забудьте теплое пальто! Я уже rоворил, что, управляя бытовой аппаратурой с по мощью ИКкодов, сталкиваеться с проблемой определения ее текущеrо состояния  включен телевизор или выключен? Здесь тоже можно использовать датчик температуры ДЛЯ бе зусловноrо выключения телевизора в заданное время, по скольку включенный телевизор rреется, а выключенный нет. Датчики движения. Насколько я понимаю, они появились как датчики в составе охранных систем. Есть несколько раз новидностей подобных датчиков. С моей точки зрения, наи более интересны пирометрические датчики движения. Но они достаточно дороrи. Более детевыми MOIjТ оказаться мик роволновые датчики. Есть еще один вид датчиков, которые MOIjТ найти практи ческое применение даже при самостоятельном изrотовлении. Это датчики протечек. Датчики, реаrирующие на появление воды там, rде ее не должно быть. Установив подобные датчи ки возле батарей отопления, в местах ввода rорячей и холод ной воды, возле стоков раковин, можно избежать серьезных неприятностей при появлении протечек воды. Сиrнализируя об аварии, система выручит вас на этапе, коrда еще не поздно перекрыть вентили или перестать пользоваться раковиной и вызвать специалиста для устранения неисправности. Хотя надежнее, я думаю, будут всетаки rOToBbIe датчики. Есть еще одно применение модуля цифровых вводов, о котором я упоминал раньте,  системное устройство управ ления. Само системное устройство управления  это клавитный пульт. Контакты при нажатии клавити замыкают один из BX дОВ модуля на общий провод. Восемь входов модуля позволяют 
252 rлава . 2 Как расширить систему сделать простой пульт с восьмью клавишами, что позволяет подать восемь команд. Достаточно ли этоrо? Достаточно для управления всеми светильниками в комнате. Или всеми oc новными светильниками в квартире. Этоrо хватит для управ ления одним аудио или видеоустройством, например видео маrнитофоном. Но управлять телевизором будет неудобно, поскольку трудно будет ввести номер канала. Для ввода HOMe ра канала обычные пульты имеют цифровую клавиатуру с цифрами от О до 9. Чтобы увеличить количество клавиш уп равления, достаточно добавить кнопки не с одним контактом на замыкание, а с двумя. Если первые восемь кнопок будут менять состояние одноrо бита, то остальные  состояние двух бит одновременно. Для случая использования модуля с клави атурой в проrрамму контроллера следует добавить задержку на 1 O50 мс перед определением состояния входов: if ((PORTA&OxFF) != OxFF) { for (i=Oi i<1000i i++)i DINSTAT = DINSTAT&PORTA; } Необходимость в задержке связана с «дребезrом» KOHTaK тов и неодновременным замыканием контактов у ДBYXKOHTaK тных кнопок. Применение кнопок с двумя замыкающими контактами, то есть замыкающими первый вход и второй, первый и Tpe тий и т.д. одновременно, позволит добавить на пульт еще семь клавит управления. Одновременное замыкание BToporo и TpeTbero, BToporo и четвертоrо и т.д.  добавит еще шесть клавит. Даже 21 клавити управления для пульта, мне кажет ся, более чем достаточно для любых применений этоrо реше ния к построению клавишноrо пульта управления. Поже мы обсудим вопрос о том, что можно сделать в экс периментах, если в квартире не заложено достаточно боль moro количества проводов, а менять проводку нет возможно сти. Я имею в виду использование радиоканала. Это же ретение можно применить и к пульту управления, построен ному на основе модуля цифровых вводов, для превращения ero в переносной пульт управления. 
Модуль с триаком 253 Резюме. Мы расширили возможности системы за счет ново.. ro устройства  модуля цифровых вводов. Рассмотрели и не.. сколько применений этоrо модуля. И, как мне кажется, с по явлением HOBoro модуля система приобрела новое качество. Модуnь с триаком Релейный модуль, описанный в самом начале, универсален во мноrих отнотениях. Он позволяет, выбрав соответствующее реле, коммутировать настольные лампы и электрический чайник, переключать rромкоrовор-ители и коммутировать входы усилителя (с не очень высоким качеством). На базе релейноrо модуля можно изrотовить выключатель света, который в состоянии заменить обычный. Конечно, в этом случае потребуется подвести провода системной сети. Но, если rоворить о замене обычноrо выключателя света на системный, лучше изменить способ управления сетильни ком. Конечно, если это не лампа HeBHoro света, которую рекомендуется включать с помощью реле. Есть хоротий KOMмyraTop для ламп накаливания  триак. Триак, или семистор  упеавляемый полупроводниковый при бор, который в отличие от тиристора может использоваться в цепях переменноrо тока. При мощности наrpузки дО 500OO Вт ему достаточно небольшоrо радиатора в виде металлической пластины по размерам выключателя света. Задача управления этим KOMмyraTopoM тока, при всей ее видимой простоте, M жет оказаться весьма интересной. Очень хоротее ретение эта задача получила с появлением оптопары  светодиод и фот триак. Подобные микросхемы, насколько я знаю, выпускает фирма Toshiba в серии TPL (ТРL30б1, TPL3041) и несколько производителей  серия МОС (рис. 2.2.и 2.3). Светодиод оптрона включается в модуль управления светом, как включаются индикаторы, при этом полностью изолируя . модуль от силовой сети. Триак оптрона подключается к управ ляющему электроду мощноrо триака. Стоимость же микросх мы и триака может оказаться меньте, чем стоимость реле. Схема модуля с триаком может выrлядеть, как показано на рис. 2.4. 
254 rлова . 2 Как расширить систему Тиристорные оптопары Наименование Схема N2 UKOMM., Iсраб., ВХ.. ZeroCross* Uиз., кВ Тип пик., В МА корпуса МОС3020 10 PDIP6 МОС3021 10 400 15 7,5 PDIP6 МОС3023 11 400 5 7,5 PDIP6 МОС3041 11 400 15 * 7,5 PDIP6 МОС3042 11 400 10 * 7,5 PDIP6 МОС3061 11 600 15 * 7,5 PDIP6 МОС3062 11 600 10 * 7,5 PDIP6 МОС3063 11 600 5 * 7,5 PDIP6 Рис. 2.2. Тиристорныеоnтопары Схема 1 О 6 5 4 * 1 2 3 Рис. 2.3. Оnтопарадля модуля с моей точки зрения, подобноrо выключателя достаточно ДЛЯ системы. Но применение триака в качестве коммутатора для управления светом открывает возможность плавной ре- ryлировки яркости света. Для тех, Koro заинтересуют экспе- рименты в этой области, можно предложить следующее ре- тение. 
Модуль с ТРИQКОМ 255 m N  + ф v C\I v о ("') () о   oo v Lt') (О....... m ттт а: а: а: а:  ....... а:  <t сх) v C\I  (о u. (о C\I  Q () Q а: ....... сх) (о н   v ("') () ("') сх) сх)  ..... .....  Q Q  .......  х о  C\I ("')   Lt') (о ...J Lt') C\I О v О u') m о C\I C\I II со М со &  э со s а. ... u о::    со  Q) )( ()  C\I U s а. 
256 rлава . 2 Как расширить систему MoAYnb с nпавной реryпировкой яркости Плавная реryлировка яркости света триаком связана с тем, что яркость ламп накаливания зависит от эффективноrо Ha пряжения. Чем оно ниже, тем меньше яркость. Устройства подобноrо типа имеют название «диммер». Тиристор или триак открывается сиrналом, подаваемым на управляющий электрод. Осциллоrрамма напряжения на наrрузке, лампе накаливания представлена на рис. 2.5. Упра8 ляюw.ий сиrнал : .................... ........................ . . . I , , Рис. 2.5. Осциллоrрамма напряжения при тиристорном управлении в верхней части отображено напряжение, интересующее нас, а внизу  переменное силовое напряжение 220 В. При подаче управляющеrо сиrнала триак открывается, и напряжение полностью падает на наrрузке. При переходе напряжения через ноль триак закрывается. Напряжение на лампе накаливания появится только после прихода следующе ro управляющеrо сиrнала. В данном случае частота управляю щих сиrналов 100 rц. Усеченное синусоидальное напряжение на лампе накаливания в данном случае равнозначно подклю чению лампы к напряжению"" 110 В. Яркость лампы YMeHЬ шается. Сдвиrая момент подачи управляющеrо сиrнала ближе к M<r менту перехода напряжения через ноль (рис. 2.6  маркерами помечены моменты подачи управляющеrо сиrнала), мы полу чим большую яркость. Удлиняя время подачи управляющеrо сиrнала после перехода напряжения через ноль (рис. 2.7), мы получим меньшую яркость свечения лампы. 
Модуль с плавной реryлировкой яркости 257 . . .... ""'1" . . . . . ...}.. .....................; . . . . .  ....:......  .... ...{....... ..... ...r...... .. ... : . Рис. 2.6. Осциллоrрамма напряжения на светильнике при увеличении яркости : I .. ..... ..... ... ... ..... .... , ... .. ..... .. ...... .. .. .... ""'1 .. ... .. .... .. r .. ... .. .... ...... .. ... ... ..... ".. . .. .. ..... ,... .. .. ... . : 1 t I I . r  t ( ..  . .. I С ..  W  _. ..w.._........w..._.....v..._..............._................_..._.........._............_...... I С 4' .. .. . I .. . & J С . I t  . . I . . . I . -о .. .... ..  .. .. .. ...  "с. ... .. .. .. ..... .. .. .. .. ... .. r .. .. .. ...... ...... .. .. .. .... "1" .. ... .. .... r" .. .. .. I . . : I .. .. t I I С . .. .... .... .. 1. .. ..... .... .. '.. .. .... .... .. .... .... .. .. .... ........... .. ..... ...1 .. .. .. .. .. ..!. .... .. .. ;  . 1 I t а : r t I I . :1 :" I t ,  t I I : : с , 4' .. .. .. , Рис. 2.7. Осциллоrрамма напряжения на светильнике при уменьшении яркости При построении модуля следует включать светодиод опт рона в нужные моменты времени, изменяя яркость свечения настольной лампы или торшера. И настольная лампа, и TOp тер включаются в розетку, имеющую фазовый и нулевой про вод. Орrанизовать сканирование силовоrо напряжения для выявления переходов через ноль не сложно, получатся раз ные решения, зависящие от конкретных условий реализации. А вот при использовании модуля вместо обычноrо выкл чателя мы столкнемся с трудностью  отсyrствием нулевоrо провода в зоне выключателя. Без Hero мы не можем синхр низировать подачу управляющих сиrналов на триак с MOMeHTa ми перехода напряжения через ноль. Если бы нулевой провод был в зоне выключателя, для получения синхронизирующих импульсов можно было бы использовать дрyrой тип оптрона: светодиод  фототранзистор. Светодиод через конденсатор (чтобы не устанавливать резистор больтой мощности) и рези стор (оrраничивающий ток через светодиод) мы подключили 
258 rлава . 2 Как расширить систему бы между фазой и нулем силовоrо напряжения. При обычном светодиоде (не двухполярном) мы получили бы возможность отмечать один из двух переходов через ноль за период силово ro напряжения. Но как быть, если нулевой провод OTcyrCTBY ет? Можно поступить двояко  В том месте, rде будет YCTaHOB лен системный блок питания 12 В, соединить общий схемный провод с защитным заземлением. При этом в точке установки модуля на место выключателя мы будем иметь возможность сделать схему синхронизации. Второй вариант  подключение цепи оптрона для синхронизации управления параллельно триа Напряжение на нем выrлядит, как показано на рис. 2.8 или на рис. 2.9. . .... .. -: .. .... ..... .. :-.. ...... ..... .. .... .... -- .. .. .... .... , .. .. .... .- . .. r с... .. " I . . . . ..:. -   .I .     1- . -   . Рис. 2.8. Осциллоrpaмма напряжения на триаке при боЛЬШОЙ яркости . . . -",.--"r.--""._."'''.''.--r-.''.-- . . I 1:. .. ....... .: .......... .. .. ...: ....; .... .... ....:. .... .... "1" ..... .... ..1. .. ...... .  I I I . t t t t t . t , ... с . .. Рис. 2.9. Осциллоrpaмма напряжения на триаке при маленькой яркости Как видно из рисунков, мы можем осуществить синхрони зацию. Определивтись со схемой реryлировки, постараемся p тить, как будем реryлировать яркость  плавно или ступенями. 
Модуль с плавной реryлировкой яркости 259 в любом случае мы будем реryлировать яркость ступенями, но их можно сделать маленькими или большими. На мой взrляд, rpадация переходов с тремячетырьмя уровнями яркости в пол ной мере устроит любоrо. А больтинству пользователей ДOCTa точно будет двух ступеней  полная яркость и треть яркости. Вопрос этот не принципиальный, и каждый ретит ero сам. Второй аспект данной проблемы  использовать ли для Bp менной задержки подачи управляющеrо импульса встроенный таймер или пустой цикл в проrрамме? Или реализовать эту процедуру с использованием BCTpoeHHoro в микроконтроллер PIC16F628A блока ШИМ. тим  аббревиатура названия сп соба Широтно-Импульсной Модуляции. Я остановлюсь на MaK симально наrлядном варианте  использую пустой цикл. Наконец, последнее, что меня в настоящий момент может беспокоить,  не будет ли свет «миrать»? Причина этоrо бес покойства в том, что контроллер будет осуществлять несколь ко процессов: . сканировать напряжение сети ....220 В для определения моментов перехода напряжения через ноль, нужных для синхронизации; . запускать управляющий импульс, который включит три ак, по истечении времени задержки после обнаружения перехода через ноль напряжения сети; . прослушивать порт USART с целью выявления команд, адресованных модулю. Системные команды следуют одна за дрyrой. Модуль будет реаrировать на все команды, даже коrда они адресованы не ему. Пока модуль разбирается с системными командаМИ t он может пропускать управление триаком, а светильник бу дет выключаться. Попробуем «прикинуть», как это будет выrлядеть. Дли тельность полуволны частой 50 rц составляет 1 Оме. Возьмем средний интервал «свободноrо» ОТ управления времени 5 мс. С дрyrой стороны при скорости в сети 2400 бит / с прием oд Horo байта займет около 4 мс. Остается надеяться, что я He правильно понимаю работу USART. Проверим. Если не полу чится, Я rOToB отказаться от реryлировки яркости. Но тем, 
260 rлава . 2 Как расширить систему кому очень хочется иметь модуль выключателя света с pery лируемой яркостью, пока можно предложить: . поэкспериментировать с изменением тактовой частоты контроллера до 20 мrц и скоростью сетевой работы 115 200 бит/с; . поэкспериментировать с работой по прерыванию (ДЛЯ сетевых команд); . в основной проrрамме все команды и запросы переме жать паузами, что замедлит сетевую работу системы, но может оказаться не столь ощутимо, в конечном счете; . если совсем ничеrо не получится, использовать BHe тнюю микросхему обслуживания управления включе ния света, например контроллер для связи с системой, а полученное время задержки переписывать во BHe тний счетчик, который будет синхронизирован с часто- той сети 50 rц, и подавать управляющие импульсы на оптрон; . поискать, нет ли еще какихлибо интересных решений. Тем не менее, попробуем реализовать проrрамму и прове рить ее работу в MPLAВ. Требования к модулю диммера: . . реryлирование яркости лампы накаливания на 3 ypOB нях: полная яркость, половинная яркость, минимальная яркость; . получение команд от центральноrо управляющеrо YCT ройства в формате L14$lN, rде 1  полная яркость, 5  выключение; . статус модуль не передает. Для тех, кто хотел бы запративать состояние диммера, я думаю, не составит труда взять эту часть проrраммы из пре дыдущих решений. Аналоrично обстоит дело и с уровнями яркости, командой выключения и полноrо включения. Реализация модуля. Вывод RA3 подключим к сканирующ му оптро Переход через ноль будет отображаться состоя нием «1». Для OCHOBHoro проrраммноrо модуля контроллера два события  появление системной команды и импульс син хронизации с силовой сетью  будyr служить точками отклика. 
Модуль с плавной реryлировкой яркости 261 Переделав текст проrраммы) немнзrо «повозившись» С устранением остаточных ошибок после переделки, я внача де сталкиваюсь с проблемой (в отладчике MPLAВ) плохой об работки сканирования силовой сети. Справившись с этим, я никак не MOry получить изменение яркости (предполаrае мой) изза Toro, что сетевые команды «пропадают». В конеч ном счете, проrрамма приобретает следующий вид. Проrрамма реrynировки .ркOCI"И на .зыке С Файл 3аroлов.в void putch(unsigned char); unsigned char getch(void); int initcomms(); int simnumadr(); int cmd () ; Основной файл #include <pic16f62xa.h> #include <stdio.h> #include "dimmer.h" иnsigned char input; // для считывания приемноrо реrистра. unsigned char MODSIM1; / / Первый символ адреса модуля. unsigned ch?r MODSIM2; // Второй символ адреса модуля. int LEVEL = 1 О о; / / Уровень яркости. иnsigned char commandreciev [6]; // Массив для полученной команды. иnsigned char COММAND; / / Флаr прихода сетевой команды. int MODADDR; / / Заданный адрес модуля, как число. int simendnum = о; / / Полный символьный номер модуля. int MODNUМ; / / Полученный адрес модуля, как число int 1; int k; // Получение байта. иnsigned char getch() { while(!RCIF) // Коrда реrистр не пуст. continue; return RCREG; } . 
262 rлава . 2 Как расширить систему // ВЫВОД одноrо байта. void putch(unsigned char byte) { while ( ! TXIF) / / Коrда реrистр пуст. continue: TXREG = byte; ,} / / Преобразуем символьный адрес в число. int simnurnadr() { simendnum = о; MODSIM1 = commandreciev [1]; // Первый символ номера. MODSIM2 = commandreciev [2]; // Второй символ номера. MODSIMl = MODSIM1  Ох30; MODSIM2 = MODSIM2  Ох30; simendnum = MODSIM1*OxOA + MODSIM2; return simendnurn; } / / Выполнение команды. int cmd ( ) { commandreciev [О] = "L"; for (i=l; i<3; ++i) /1 Запишем номер модуля. { input = getch(); comrnandreciev [i] = input; } MODNUМ = simnumadr (); / / Полученные номер, как число. if (MODNUМ == MODADDR) / / Если номер модуля совпадает. { MODNUМ = о; for (i=3; i<6; ++i) { // Запишем команду в массив. input = getch(); commandreciev [i] = input; } commandreciev [4] = " 3 " ; 11 для получения иmmc'фаЦИИ. LEVEL = (commandreciev [4]  Ох30) * Ох64; //Уровень яркости. for (i=O; i<6; ++i) commandreciev [i] = " "; 
Модуль с плавной реryлировкой яркости 263 COММAND = О; / / Сбросим флаr команды. } else { for (i=O; i<6; ++i) commandreciev [i] = " n.//Очистим массив. COММAND = О; // Сбросим флаr. } } int initcomms() { PORTA = О; CMCON = Ох7; TRISA = ОЬООО01000; TRISB = OxFE; RCSTA = ОЫО010000; TXSTA = ОЬООООО110; SPBRG = Ох68; RBO = о; CREN =1; МО = 1; } / / Инициализация модуля // Настройка портов А и В. // Настройка приемника. // Настройка передатчика. // Настройка режима приемапередачи. // Выключаем драйвер RS485 на передачу. void main(void) { / / Инициализация модуля. ini t comms ( ) ; for (i=O; i<6; ++i) commandreciev [i] = " "; COММAND = О; // Прочитаем и преобразуем номер модуля. MODADDR = PORTB; / / Номер модуля в старших битах MODADDR = MODADDR»4; / / Сдвинем на четыре бита. // Начинаем работать. start: if ((RAЗ == l)&(COММAND == о» // Сканирование 220 В, если нет { // сетевой команды. for (k=O; k<LEVEL; k++) М1 = о; М1 = 1; if (RCIF) // Если пришла команда по сети. { COММAND = 1; / / Устанавливаем флаr команды. 
264 rлава . 2 Как расширить систему input = getch(); if (input == "L") cmd(); // Если наш модуль. else COММAND = о; // Иначе сбросим флаr. } } goto start; } Выделенная строка добавлена только для получения иллюст рации, как это описано ниже. Вначале приведу таблицу настроек (рис. 2.10). .-. ..--.... .--. ........ ",.,;:;!::J@;tY.!(;t "О '. . ,,:.':::,:". ....: '."'::.:.:'.'.' ,:. ....,- . ...' '.', <'. ,... <." ":{::::-:::':::::::':':::::::::::)}';::::-:-:::::.:;J:'.:;:::::_:::.::.:;:::.;X:' -:-::'___:-:::: ___ ... ". .:"::::'::::.:::: . :.:. _:._."." '';'  1.- . PnJAActiom;. _!A ._ A_. RerT.! : (;':;;:if'.iС...:...,.,."-,,,.,., ...,.,...,....,... . .....ш...', .., .,.... ....: "..; ..-. [ ' i IttilI:::f' . iCldilwetOМisq..,; , :1 . : . . . , . ' . ' . . . > :  . . _ш. ___ _ .. ;. .. ...i . -.--  1-.. ш.l.... . r LJ ;, :ii. Н=н '   _-=-===- .' ::. ..+Ш+..._ .+  : _Ш'шшш''ш_ш 'ш' ШШШ.. ' ш! ;Ш !: , Ш 8,' ._..:.::..-:J  ....-- '.i" __.:_-:'; .: .: .-:::::: ' ;.:;.' "..... . _ .;.;.;.;.;.," ..... "0 .... ..." ш. - " '".. ....: .-_ _:..:., .... . ':':', ':-:' . . - ;.-: :.-:"?й( .-:V:. J 1::=:::=,::,;=, {I" uflll!Цlnow"H,, >:=,; :,., - "',.;: : П Т . J . ш::::.;.-;.: .::::.......:.: у:. .:,.. jo ....... . . Рис. 2.10. Таблица настроеКСТИМУЛQВ Эти настройки пришлось продолжить до времени 140 000. При наладке я выбрал единицы измерения  циклы. Этим не оrраничилось  пришлось изменить частоту с 4 мrц на 20 мrц, изменить основной текст в функции при ема команды, закомментировав часть текста: int стд() { /* commandreciev [О] = "L" i .for (i=li i<Зi ++i) 11 Запишем номер модуля. { input = getch()i commandreciev [i] = inputi 
Модуль с плавной реryлировкой яркости 265 } MODNUМ = simnumadr(); / / Чтение из сети. if (MODNUМ == MODADDR) { MODNUМ = О; for (i=3; i<6; ++i) { / / Запишем команду в массив. input = getch(); cammandreciev [i] = input; } */ commandreciev [4] = "3"; LEVEL = (commandreciev [4]  ОхЗО) * Ох64; for (i=O; i<б; ++i) commandreciev [i] = " "; COММAND = о; /* } else { for (i=Oi i<6i ++i) commandreciev [i] = COММAND = о; */ " ". , } } Только после всех этих обманных маневров мне удалось получить иллюстрацию к тому, что я хотел сказать. После по лучения команды интервал от момента перехода напряжения сети .....220 В через ноль, до момента включения триака, OTMe ченный на рис. 2.11 маркером, меняется на новый интервал, отмеченный на рис. 2.12. Что можно сказать в данный момент? Отработка сканиро вания и включения выrлядит нормально (рис. 2.13 и 2.14). Уровень яркости определяется переменной LEVEL, KOTO рая изменяется командой, получаемой от компьютера. На этих рисунках видно, что импульсы управления идyr с часто той 100 rц (10000 мкс). Вышеприведенные картинки, полу ченные «жульническим пyrем», дают надежду на то, что KO манду от компьютера всетаки удастся прочитать. Мои опасения по поводу «миraнил» света, скорее Bcero, беспочвен ны. Их лучше отнести к опасениям по поводу отработки ceT вых команд. 
266 rлава . 2 Как расширить систему ."1 :.::...,...:....::''' : "..:::, . '.,:,:::i::::;..::','<::':.':":':' . "'-',-.=-. 'О:'.".. '. . :" :  ;f;.".::;, .. " ',,: ..:  . ' ;< " -( ....->: 9 -_ -_-о ?' - . , +; ::?.: ,'О' (..:: о:;:: .1 .;: ' -  -- r .,::. ;.,,\:::.: ( I АА1 2052 .! RAЗ I I I I , . I I I I I , I , I , , I . I . I . . I I , I 9500).0 10ОП1.0 1(&0).0 1100ю.о 11500:1.0 12ООЮ.О 12500:).0 Рис.2.11.луправлениятриаком :J_:!!.! ;:.  ;:{: <::':;:::: ". Q Х.! « , l..NJmeb W;::fo': ,::. ,;. .1. :: ,,1 r АА1 RAЗ I . I . , I . I I I I I I I I I I I I I , I I I I , I I . , I I I 9500)0 10ОП1.0 1(&0).0 1100ю0 11500:1.0 12ООЮ.о 12500:).0 Рис. 2.12. Изменение управления триаком ._. Н.". . .;:":':.:t:":; '.'.:.:. . ':"'-""':'''-:$: .... «-:- -:-:M,',>'.' ._ ':..-..,," :..;.' ,.".-'  :  ;<::<.<' " ,,< , ''"< ' +;. + /: - O'::.:.:.:;r :::;: gJ r! ".... Q .'.Х J\enneI$ АА1 ' 1 ; RAЗ I . I J I I I I I I I . . I , I I I I I I I I I r I I I I I I 1100ю.о 11500:1 О 12ООЮ О 12500:).0 1ЭООЮ.о 13500) о Рис. 2.1 з. Л изменения яркости 
Модуль с плавной реryлировкой яркости 267 .. .Ana. . . .,<.::;.'.'.:.:'/.:.! ,:,:,::\:!? ?) .. ... ...... ....... - r+'<,< .'.;. .:., .i. ,;.. _ liI [). : ,. :: . . .. t"L.. . ... ... . , .'i . !.: . '::T:eS.: $ :'.' . '.:. . > :. : . . . . .  ,. : . . . : . ': . ':"<..,.;." ..."....,,,...ш. .,.'"....; ,.. Now. WDCa ' r-..... ., "  ...f. ;.;:: > . . >. .... .., ..." "... ... ..".. ."."" ......"."..'::'<,::.;'::.,',",..:.,"',::-'. :.\;.",  '::::;.1 ...._... .....л'{ .._ . :....:-;.. .; Ад1 RдЗ , I I . . I I I . . I I . . I I I I . . I I I I I . I . I . I I , 100ю.о 15003.0 2OOXI.o 2500:).0 эоою О 3500).0 400)).0 .. Рис. 2.14. Дpyroe значение яркости Для очистки совести мне следовало про верить работу MO дуля на макете. Но я не хочу работать с силовой сетью .....220 В. 3авертая разrовор о диммере, приведу НЕХфайл модуля управления яркостью. НЕХ-файп модуп8 уnравпеНИ8 8pKocr..o :10000000830100308АОО0428203084003530162017 :1000100083010330B800FE30B7003530840037303C :100020001A2083012E2B04068001840A0406031D76 :1000300013280034F00026208000840A040870068B :10004000031900341B2883120313B700B81B31288F :10005000381В392838088АО03708В70А0319В80А44 :1000600082008313381883173708В70А8400000802 :02007000080086 :1005B20083018C1ED92A1A0808008301B400831211 :1005C20003130C1EE02A340899000800F401F50117 :1005D2000310F30CF20C031CF52A7008F4077108DF :1005E2000318710AF5070310FOODFI0D7208730478 :1005F20003190034E92A8301850107309F0008307E :1006020083168500FE3086009030831298000630F3 :100612008316980068309900831206101816051484 :1006220008008301AC01AD012F08A1003008A2002F :10063200D030AI07A2070A30P200F3012108F0002E :10064200F101E72222087407AC0075080318750A45 :10065200ADOOF1002C08F0000800FC22A801A9015D :100662003В2В28082Е3Е8400831320308000А80АЕА :100672000319А90А2908803АРООО80307002063076 
268 rлава . 2 Как расширить систему :1006820003192802031C322ВA0010608A400A501AD :100692000430F000250DA50CA40CFOOB4B2B83129B :1006A2000313851D502ВA008031D522ВAA01AВ0179 :1006B2002B08803AF0003608803A7002031D632B43 :1006С20035082А028312031303186С2В8510ААОА19 :1006D2000319AВOA592B85148C1E502ВA001AOOAВA :1006E200D922A3004C3A031D782B7A23502ВA00168 :1006F200502B4C308301AEOOA801A80AA9018C2B13 :10070200D922A30028082E3E8400831323088000E8 :10071200А80АО319А90А2908803АРООО8030700259 :10072200033003192802031С812В12237008А60030 :100732007108A7002506031DA02B24082606031D09 :10074200E62ВA601A7010330A800A9012908803AD7 :10075200F000803070020630031928020318BD2B06 :10076200D922A30028082E3E840083132308800088 :10077200A80A0319A90AA72B6430F200F301320870 :10078200FOOOF101D030F0070318F10AFF30F10751 :10079200Е7227408В5007508В600А801А901290866 :1007А200803AFОО080З070020630031928020318Е4 :1007В200Е42В28082Е3Е8400831320308000А80АРО :1007C2000319A90AD02ВAOOI0800A801A901290830 :1007D200803AF000803070020630031928020318B4 :1007Е200FС2В28082Е3Е8400831320З08000А80АА8 :OE07F2000319A90AE82ВA001080064340034A2 :OOOOOOOlFF Файл предназначен для экспериментальных целей. Добав лю еще несколько слов: . если эксперименты с диммером не приведyr к успеху, можно рассмотреть вариант применения более мощно ro микроконтроллера; . использовать решения, о которых я rоворил выше; . применить, что проще, два контроллера, один из KOTO рых будет общаться с системной сетью, а второй управ лять триаком; . и не забудьте: если вы ретите сделать выключатель с реryлируемой яркостью, (что никак не отражено в pe ализации) следует предус.мотретъ oд'IlY Шlи две 'JC1l0nXU для руч 1l0Z0 упра8лe1lUЯ! · в режиме ручноrо управлени можно сделать следую щее  одна из кнопок при кратковременном нажатии 
Модуль аудиокоммутатора 269 полностью включает свет, при удержании медленно YBe личивает яркость; вторая кнопка проделывает то же самое, но с выключением; думаю, вам не составит труда изменить проrрамму для поддержки этих добавлений. А я продолжу рассказ о модулях, которые MOryт войти В систему. Модуnь nocneAOBaTenbHoro интерфейса Некоторые устройства позволяют управлять ими по интер фейсу RS232, что предпочтительней ИКуправления, если известны команды управления устройством. Это может быть проиrрыватель СDдисков, проектор или видеокамера наблю дения. Модуль позволяет пересылать команды по системной сети к устройству с преобразованием их к интерфейсу RS232. В данном случае, я думаю, можно применить конвертер RS485RS232. Если есть желание растирить возможности модуля, мож но сделать модуль с несколькими выходами RS232, добавив контроллер и мультиплексор, переключающий порты RS232. Это только идеи, а не решения. Ретения, я думаю, вам инте реснее найти самим. Далее в книrе пойдет речь о сметанных системах. При объединении устройств разных систем в единую сеть модуль последовательноrо интерфейса может избавить вас от поис ка сложных ретений. Модуnьаудиокомм утarо ра Еще один модуль, который может найти применение в сист ме, это модуль аудиокоммyrатора. В принципе, достаточно коммyrации rромкоrоворителей с помощью релейноrо модуля. Но можно коммyrировать линейный выход, например Сl).про- иrрывателя и радиоприемника, с аудиовходом телевизора. Для этой цели, используя релейный модуль, можно вместо реле включать соответствующие электронные ключи. Детевле BC ro использовать ключи цифровой 561 серии. Микросхема 
270 rлава . 2 Как расширить систему К561 ТК3 (функциональный аналоr 4066) вполне успетно pa ботает в качестве управляемоrо ключа. Микросхема допускает двухполярное питающее напряж ние, при этом она передает низкие частоты от «О». Но микро- схема допускает и однополярное включение питающеrо напря жения. При этом сиrнал лучше передавать через конденсатор соответствующей емкости. При реализации H следует забы вать, что KOMмyraTop должен позволять подключение к одно- му выходу источника сиrнала нескольких входов приемников, но не наоборот. Если вам понадобится сделать миктер (смеси тель сиrналов), несколько выходов следует подключать к одно- му входу через развязывающие резисторы. Для аудиокоммyrатора важно проверить, не ухудшается ли в значительной мере соотнотение сиrнал/тум. Конечно, я не имею в виду применение подобноrо модуля для аппара туры класса HiEnd. Модуnь видеокоммутатора Еще более интересными мне представляются эксперименты по превращению модуля аудиокоммyrатора в видеокоммyrа тор. Я не уверен, что это осуществимо, но попробовать стоит, используя новые цифровые микросхемы серии 1561 или 1564. Собственно, видеокоммyrатор вотнотении лоrики ничем не разнится с аудиокоммyrатором. Необходимо только соrласова.. ние наrрузки. Видеоцепи работают на сопротивление 75 Ом, то есть, подразумевается коаксиальный кабель с волновым со- противлением 75 Ом, и разъемы желательно применять COOT ветствующие. KOMмyraTOp должен быть соrласован. Этоrо мож но достиrнуть, применяя входные и выходные усилители на микросхемах, хорошо работающих с видеосиrналом (я прим нял, коrда возникла необходимость, микросхемы ЛD8055ЛN). Ero второе отличие от аудио KOMмyraTopa  полоса частот. Для видеокоммyrатора она должна быть не менее O6 мrц при композитном сиrнале. 
Модуль управляемоrо усилителя 271 МОДУJlЬ ynpaBIIReMOrO УСИlIитеJlR На основе микросхем усилителей в сочетании с управляющим контроллером, добавив реле для подключения питающеrо напряжения к усилителям и схемы ключей на микросхемах K561TK3 (или аналоrичных электронных ключей), можно реализовать модуль управляемоrо усилителя (в частности, мноrоканальноrо). Реле будет ВКЛЮЧ,ать и ВЫЮIючать питание усилителя по команде компьютера. Ключи будyr коммyrиро вать резистивный делитель для ступенчатой реryлировки rромкости по командам компьютера или системноrо устрой ства управления. А управляющий контроллер, вероятно, бу дет мало отличаться от примененноrо в релейном модуле. С введением в систему управляемоrо усилителя растиря ются возможности отображения информации. Коrда я rOBo рил оприменении уличноrо термометра в системе, то пред лаrал «помиrать светом», если температура за окном ниже, чем 15°. rораздо приятнее получить сообщение от (:истемы в виде rолосовоrо напоминания: «Не забудьте одеться теплее! На улице мороз!». rолосовые системные сообщения можно орrанизовать на компьютере, особенно, если вы используете компьютер для управляющей проrраммы. В качестве альтернативы  неисп равный телефонный аппарат с цифровым автоответчиком. Сам телефонный аппарат может быть неисправен, а aBTOOT ветчик вполне работоспособен. Сеrодня, порой, выбрасыва ют и вполне исправные телефонные аппараты, заменяя их аппаратами, позволяющими подключить тричетыре трубки. А телефонные аппараты с цифровым автоответчиком лет десять назад стоили не дороже обычных. Можно собрать и самому цифровой модуль для записи и воспроизведения rолосовых сообщений. Интересно было бы использовать микроконтроллер, АЦП и внетнюю память для сохранения оцифрованных сообщений. Но вернемся к усилителям. 
272 rлава . 2 Как расширить систему Сейчас можно недороrо приобрести микросхемы вполне качественных усилителей небольтой (по сеrодняшним Mep кам) мощности. С мощностью усилителей вопрос особый. Необходимая для создания нормалI:>НОЙ звуковой картинки мощность очень сильно зависит от применяемых rpoMKoroBo рителей. Вернее от их фактическоrо кпд. Тяrа к усилителям большой мощности возникла, в первую очередь, изза жела ния передать низтие частоты звуковоrо диапазона. Чем ниже желаемая частота, тем труднее ее воспроизвести, что требу ет больтей мощности от rромкоrоворителя и усилителя. Но не следует забывать, что в реальном помещении небольтой площади без специальной и достаточно сложной (и дороrой) обработки помещения воспроизвести частоты ниже 4050 rц слитком сложно. А если оrраничиться нижней частотой BOC произведения 4050 [ц, при правильной конструкции акусти ческоrо оформления необходимая мощность усилителя MO жет не превышать 5 1 О Вт. Но это тема совсем дрyrоrо разrовора. В отношении системы мне хотелось бы добавить HeKOTO рые соображения. Давайте, подумаем, в каких случаях нам требуется звук в помещениях без ИСТОЧI-IИКОВ звука: . есть больтие любители послутать люб.имую музыку в ванной; . приятно, коrда к вам приходят rости, включить музыку в прихожей или rостиной, чтобы в ожидании обеда под музыку пить коктейли; . в столовой, rде собрались rости, можно включить музы ку, которая слеrка заrлушит стук ножей и вилок и позво лит соседям по столу переrоворить без Toro, чтобы при влекать внимание Bcero стола; . наконец, после обеда можно и потанцевать в холле. я привел несколько примеров применения аудиодистри буции в реальной системе YMHoro дома. Какой в данных слу чаях разумно реализовать вариант физическоrо построения аудиоподсистем. Во всех выте перечисленных случаях лучте использовать встроенные потолочные rромкоrоворители. И, я почти уверен, работающие в режиме «моно». Получить от стереосистемы с потолочными rромкоrоворителями 
Модуль системноrо ИКпульта управления 273 качественную звуковую картину, мне кажется, слитком слож но, да еще и на больтой площади! Нужно ли заботиться о большом динамическом диапазоне звука? А какой в этом прок, если музыка должна оставаться «мяrким фоном». То есть, больтая мощность не нужна. Нужно ли передавать весь звуковой частотный спектр? Не думаю. Скорее следует позаботиться о том, чтобы, оrраничив частотный спектр снизу частотой 60 70 rц, не забыть оrрани чить ero сверху частотой 1012 кrц, учтя при этом особен ность восприятия звука при небольтой rромкости и внеся частотную коррекцию. Правильно построив эту часть устрой ства звуковоспроизведения, можно оrраничиться уровнем rромкости, имеющим одно приемлемое значение, что изба вит от необходимости реryлировать rpoMKocTb. Словом, не следует переоценивать возможности «звука сверху», затрачивая силы на получение очень хоротих пара метров звучания, если они никоrда не будут применяться. Лучше позаботиться о правильном построении Bcero тракта и подобрать музыку, которая была бы приятна rостям, не OT влекала их ни от беседы, ни от вкусной еды за столом. И, например, если вы намерены озвучить свою ванную KOM нату, не пытайтесь получить нечто небывалое, используя самое высококачественное оборудование. Условия воспроизведения звука не позволят реализовать все эти преимущества. Высококачественное оборудование требует специальноrо помещения с хоротей акустической обработкой. Если вы MO жете себе позволить подобное помещение было бы хорошо, если б специалисты из лаборатории акустики проверили по мещение с помощью своих приборов. Это позволит внести коррекцию в оборудование с целью получения максимально ro качества звука в данном конкретном случае. Модуnь системноrо ИК-пуnьта управпеНИR На базе решений для модуля цифровых вводов и модуля уп равляющих ИКкодов можно разработать системный пульт с небольтим количеством команд. В качестве излучающеrо 
274 rлова . 2 Как расширить систему светодиода можно использовать светодиоды от старых пуль тов управления (или купить аналоrичный) или любой CBeT диод ИКдиапазона (либо захватывающеrо ИКдиапазон). В последнем случае их следует включать короткими импуль сами с током, превытающим средний допустимый ток, но с больтой скважностью. Так, кстати, работают и промышлен ные пульты управления (если не все, то некоторые). Конечно, :QОЗМОЖНОСТИ TaKoro пульта будyr оrраничены, как в количестве управляющих клавиш, так и в количестве системных кодов. Но о том, как можно увеличить количество клавит для управления, мы rоворили в разделе, относящем ся к модулю цифровых вводов. А увеличение количества сис темных кодов зависит от реализации. Взяв за основу простей тие ИКкоды, можно создать функцию воспроизведения TaKoro кода, rде параметр, меняющий код, может иметь зна чение, умещающееся в одном байте. В этом случае энерrоне зависимая часть контроллера уместит достаточно MHoro KO дов. Я не знаю rOToBoro ретения, но полаrаю, вам будет интересно попробовать реализовать этот вариант модуля в составе системы. Подразумевается, что пульт управления будет переносным, а в этом случае не забудьте, что контрол лер предлаrает энерrосбереrающий режим управления. Модупь aHanorOBoro ввода ДnH термометра Модули аналоrовых вводов, как мне кажется, чаще требуются в профессиональной деятельности, в технолоrических про цессах. Там, rде есть необходимость считывать показания дaT чиков, отображающих непрерывно меняющиеся параметры в тироком диапазоне. Но я не исключаю интерес со стороны любителей к co зданию подобных устройств. С моей точки зрения, систем ное устройство лучше сделать в виде самостоятельноrо MO дуля целевоrо назначения, что избавит от необходимости прокладывать экранированные провода. И только после oro как продумано ero применение в системе. Даже ДOCTa точно простая задача отображения непрерывно меняющейся 
Замена npOBOAHoro канала RS,485 275 информации, например температуры, может быть проще решена с помощью специализированноrо АЦП, соединенно ro с дисплеем. Как это сделано в мультиметре. Получается простая, надежная и мноrофункциональная конструкция. Это, конечно, не означает, что я исключаю возможность построения датчика полностью на микроконтроллере. Это моrло бы быть интересной задачей. Замена проводноrо канаnа RS485 Для тех, кто, проведя первые эксперименты с системой, п желал бы использовать дома чт<YrО из разработок, препятстви ем к реализации задуманноrо может стать отcyrствие в доме развитой кабельной системы, необходимой для орrанизации сети. Проклздывать провода поверх плинтуса или по стенам? Можно, проведя предварительные эксперименты, попроб вать заменить провода радиоканалом. В качестве приемопере-- датчиков можно использовать rOToBbIe модули, используемые при построении управляемых авиамоделей и моделей aBTOM билей. В продаже есть и одноканальные, и мноrоканальные радио модули для радиоуправляемых моделей. Они настроены на разрешенные для этой цели радиочастоты, невелики по raбаритам и, я думаю, удобны в применении. Заменив микр схему интерфейса RS485 на подобные модули, можно попы таться обойтись без проводов. Сам я не пробовал. но желание купить модули и испытать их в работе было. При отказе от проводной связи потребуется снабдить каж дый модуль системы собственным блоком питания, но реше-- ние этой проблемы может оказаться более простым, чем пр клздывание проводов по комнате или по квартире. Хотя и с проводами  в настоящее время есть плоские кабели очень небольшой толщины. Такие кабели можно аккуратно размес. тить под обоями возле пола, и они не испортят вида комнаты. Друrим решением этой проблемы может стать использо вани е ИКканала. При этом для ретрансляции сиrнала между комнатами потребуются специальные модули ретрансляции. Их леrко сделать на базе модулей ИКприемников и ИКизлу чателей. К недостаткам решения следует отнести необходи мость в большом количестве ретрансляторов. Но в продаже 
276 rлава . 2 Как расширить систему есть ИКзеркала, которые можно использовать в качестве ретрансляторов ИКсиrналов. Словом, здесь тоже большой простор для экспериментов. Усовершенствование 6аЭОВЬlХ  модупеи Следует отметить, что все описанные в книrе модули далеки от совертенства. Хотя больтая их часть была мной провер на на макете, я не проверял их совместную работу. Подобная проверка может открыть больтой простор для творчества и по устранению недостатков, и по усовершенствованию ca мих устройств. При этом усовертенствование может KacaTb ся как увеличения функциональности, так и надежности. Сама микросхема контроллера настолько надежна, что хотя бы из уважения к этому факту следует не оставлять без вни мания вопрос надежности устройства в целом. Одним из усовертенствований, о которых я упоминал, может стать использование встроенной памяти EEPROM ДЛЯ задания адреса модуля. В промышленных разработках адрес устройства задается проrраммно. Для этой цели один из BBO дОВ устройства используется для перехода к режиму HaCTp ек. Коrда он соединен с общим проводом, при включении питающеrо напряжения модуль переходит в специальный режим настроек. o сети ему передаются параметры  адрес модуля, скорость сетевой работы,  которые модуль запоми нает в энерrонезависимой памяти. Если применить построе.- ние модуля с внетним кварцем на 20 мrц. диапазон сетевых скоростей растиряется до 115200 бит/с. Сами по себе экспе рименты с разной скоростью сетевой работы MOryт оказаться не менее увлекательными, чем разработка модулей. В этом случае возможность проrраммноrо изменения скорости рабо ты USART очень полезна. Наконец, микроконтроллер PIC16F628A не является ca мым мощным в серии РIСконтроллеров. Можно провести эк сперименты с контроллерами PIC18Fxxx или друrими. Bы бор контроллера вне профессиональной разработки может определяться разными факторами: наличием подходящеrо 
Последние замечания 277 контроллера в продаже, доступностью ero по цене. Может иrрать роль и простой интерес к конкретной микросхеме. rлавное, что я хотел показать на протяжении книrи, что oc воение работы с микроконтроллерами доступно любому, кому интересно, а интересно любому, кому нравится TBO рить, созидать, изобретать. Даже если изобретаеть велоси пед, это занятие оказывается MHoro занимательнее, чем по купка rOToBoro. ПосnедниеэамеqаНИR Как аппаратная, так и проrраммная разработка выполнена мною в макетном варианте. Я rоворил, что не намерен созда вать промышленный вариант  моя задача показать, что есть такое интересное занятие  придумывать и создавать, ис пользуя возможности компьютера, интересные устройства. По этой причине компьютер выбран в качестве OCHoBHoro управляющеrо устройства. Не. если KOМYTO захочется, не оrраничивсь экспериментами, использовать систему в CB ей комнате или квартире, я бы посоветовал рассмотреть воз можность замены компьютера на автономное управляющее устройство, выполненное на базе, например, Toro же микро контроллера PIC16F628A. Ero проrраммная память позволя ет разместить до 2 Кб управляющей проrраммы, что вполне может оказаться достаточным для управления модулями в комнате или даже квартире. Можно, если памяти окажется недостаточно, использовать друrой микроконтроллер или дополнительную память для размещения проrраммы. Проrрамму для создания основной проrраммы можно Ha писать в виде, близком к проФессиональному,  очень инте ресная задача. И очень интересно придумывать новые MOДY ли, которые были бы полезны в составе системы. Если добавить в виртуальную лабораторию на компьютере проrрамму, позволяющую провести разработку на традицион ной элементной базе  транзисторы, резисторы, KoндeHcaTO ры и т.д., возможности разработки MHoroKpaTHo увеличатся. Необычайная ибкость микроконтроллеров, надеюсь, мне удалось это показать, позволяет за счет небольших изменений в проrрамме превратить микроконтроллер в основу совсем 
278 rлава . 2 Как расширить систему дрyrоrо устройства. Даже замена элементов, которыми ynрав ляет онтроллер, без замены ero проrраммы меняет конеч ное назначение устройства  замена реле на управляемые ключи превращает релейный модуль в управляемый аудио KOMмyraTop или усилитель. И всю эту работу можно осуще ствить за компьютером, отложив покупку деталей до Toro момента, коrда вы уверитесь в необходимости создания про . тотипа, и реальности достижения цели. Несколько практических советов для тех, кто намерен не останавливаться на экспериментах, а воплотить систему в жизнь. Как все системы подобноrо назначения, эта получа ется достаточно rибкой. Она может использоваться в KOMHa те и во всей квартире, как система, управляемая с компью тера или как децентрализованная система. Достаточно HeMHoro изменить проrраммы модулей. Например, модуль цифровых вводов, используемый в качестве контроллера клавиатуры, может отправлять прямые команды модулям выключателе света (или релейным). В итоrе вы получаете автономную подсистему  в одном месте расположен пульт управления всеми выключателями в квартире (или в каж дой комнате находятся пульты управления всеми выключа телями света в квартире), а исполняющие модули располо жены рядом со светильниками. Подобным же образом можно орrанизовать любую подсистем Для опытов со светом я бы посоветовал использовать Ha стольные лампы, бра, тортеры, включаемые в розетки; за действовать для их подключения промежуточную розетку, подключаемую через контакты реле (релейноrо модуля) или триак (модуля выключателя света). Включать промежyrочную розетку в сеть следует только после тщательной проверки правильности и качества монтажа. Для тех, кто все-таки ретит заменить ттатный выключа тель света модулем и не забудет на время работ по замене OT ключить автомат в силовом ткафу, хочу напомнить, что кроме управления выключателем по системной сети следует предус мотреть ручное выключение. Например, изменив проrрамму контроллера,  установить один или два вывода порта на ввод. К этим выводам будет подключаться кнопка (или кнопки) руч Horo управления. Триак лучте установить на теплоотвод в виде 
Последние замечания 279 металлической пластины, которая одновременно может иr рать роль несущеrо элемента конструкции. Выключатель для этих целей можно подобрать удобный к переделке. Я не исклю- чаю, что можно расположить все элементы схемы модуля B ри любоrо обычноrо выключателя и использовать ero KOHTpaк ты для ручноrо управления модулем. Если вы захотите использовать датчик температуры для управления калорифером, не забудьте, что используемый вами термозависимый элемент может подверrаться воздей ствию случайных движений воздуха. Если тепловые процес сы в помещении инерционны, сам термоэлемент может об ладать значительно меньшей инерционностью. Используйте либо разнесение по температуре команд включения и выклю чения обоrревателя, либо используйте временные задержки! проверяя состояние датчика температуры дважды с HeKOTO рым интервалом времени. И последнее: я выбрал в качестве иллюстрации систему «Умный дом», но это не единственная система, кото.рую мож но реализовать с использованием микроконтроллера. Приду мывать подобные системы и создавать их, используя сеrоднят ние возможности компьютера,  увлекательнейшее занятие,' даже если не превращать ero в професеию. 
rлава " J То. ..ТО рАДОМ С cCYMHblM ДОМОМ)) Предположим, что вы человек практичный. Вам не достает только экспериментов и Toro удовольствия, которое они MOIyr принести. Дочитав описание, вы ретили реализовать систещ В том, что касается микроконтроллера, вам все понятно. Но, выбрав концепцию (одну из предложенных в Приложении) и внеся изменения в проrрамму модуля диммера, вы ретили собрать ero. Если вы, в отличие от меня, специализируетесь на тиристорных схемах управления, у вас не возникнет проблем. Но я, прежде чем начать «жечь» триаки и оптроны, постара юсь проверить, а прав ли в том, как нарисовал схему? Для этой цели я воспользуюсь одной из проrрамм, о которых пойдет речь ниже. Вы не хотите устанавливать ИКизлучатель возле телеви зора для включения ero из системы. Вам удобнее сделать мощный излучатель, который расположится в дрyrом конце комнаты. Даже воспользовавтись моим советом добавить конденсатор параллельно резистору (об этом тоже упомяну то в Приложении), вы должны определиться с величиной емкости. Ее можно рассчитать, используя постоянную Bpe мени, но помните ли вы, как это следует сделать? Положим, прочитав о модуле аудиокоммyrатора, вы поду мали, что ero можно применить не только для распределения музыки по квартире, с чем вполне справлялся релейный мо- дуль, но И для устройства интеркома. Квартира большая, кри- чать на всю квартиру  не накричиться. Берем электретный 
То, ЧТО РЯДОМ с «Умным ДОМОМ» 281 микрофон, добавляем усилитель, небольшие rромкоrоворите- ли от компьютера во всех комнатах и получаем с помощью коммутатора вполне работающую систему интеркома. Оста- лось понять, какой нужен усилитель. Первое, что мне прихо дит в rолову,  применить операционной усилитель. Но я тут же вспоминаю, что он потребует двухполярноrо питания. Есть, безусловно, схемные решения с однополярным питани ем, но я не уверен, что единственный транзистор не спра вится с этим лучше. Можно найти подходящую к случаю мик росхему. Но я MOry засомневаться, что так будет лучше, вспоминая, как MHoro лет назад пытался решить схемный ва- риант включения источника с промежуточным выходным сопротивлением. Проблема была в минимизации шумов. Одни микросхемы прекрасно работали с высоокомными ис- точниками, дрyrие  с низкоомными. А в промежутке между иими  поиск. Вне всяких сомнений, можно решить любую задачу опытным путем, но лучше вначале опробовать реше иие за компьютером. Задумавшись о создании интеркома, вы подумали, что жене леrче будет ухаживать за вашим маленьким ребенком, если в ero комнате поставить микрофон и подключить ero к интеркому, установив пороr срабатывания так, что интер ком будет включаться только тоrда, коrда ребенок заплачет. Как выбрать пороr? Вам не хочется растяrивать провода по квартире. Вы pe таете, что оснастите все модули радиоканалом. Правильно. Я посмотрел, что предлаrают производители радиомодулей. Есть очень славные образцы. Их, я думаю, можно подключить к микроконтроллеру даже без инвертеров. Но есть у них Ma ленький недостаток  цена (около 200 долларов). Прежде, чем купить с десяток подобных модулей, я бы, при всей моей лени, попробовал собрать ЧТ<YrО подходящее из транзистороврези сторовкатушек. И проверил бы схему за компьютером. Решая некоторые задачи, связанные с системой «Умный дом», все равно время от времени сталкиваешься с проблема ми, вынуждающими чтото сделать дополнительно, хотя бы только для Toro, чтобы выиrрать время. Прежде чем XBaTaTЬ ся за паяльник, я стараюсь максимально тщательно прорабо тать решение. 
282 rпaBa . 3 То, что рядом с «Умным домом» Один из примеров. Необходимо в подсистеме противопо- жарной безопасности орrанизовать индикацию состояния датчиков. Есть модуль в единственном экземпляре, имеюЩИЙ 8 реле. Датчиков 10. Кроме индикации весьма желательно добавить звуковой сиrнал тревоrи. Если TpeBora не ложная, система переходит в режим пожарноrо оповещения, отклкr чает климатическую подсистему и т.д. По первому впечатле- нию я решаю, что леrко MOry добиться желаемоrо с помощью орrанизации матричноrо подключения светодиодов с матри- цей 4х4. Но, поостыв и нарисовав предполаrаемую схему в проrрамме Multisim, как показано на рис. 3.1, я прихожу к выводу, что следует позаботиться в проrраммной части о по- очередном включении индикаторов. Я не уверен, что обратил бы внимание на эту деталь до предварительноrо paCCMOTp ния работы схемы. Среди великолепных специалистов по микропроцессо ной те,хнике, проrраммистов, для которых не составит труда привести проrрамму к виду коммерческой версии системы, далеко не редкость столь прочно забыть все, что касается aHa лоrовой схемотехники, и тоrда любые расчеты, необходимые tlUleLllt _ i ,-о, " .--41,,' jf' ifwi OO;, , - ,...:. .:,:::.i";':..  .  .,  :о., I  ::... l  ! ..  ::..,  I '" 112 . .7l1li .7110 .7l1li Т I 1 I ;. .  _.,-' А "( .: DJНr .- ' --- -'- ...."j,-." ,О, - _у, 'ц, Рис. 3.1. Орrаниэация противопожарной индикации с релейным модулем 
То, ЧТО РЯДОМ с «Умным ДОМОМ» 283 до макетирования схемы, становятся сущим кошмаром. Что же rоворить о любителе? Для всех них проrраммы, помоrаю щие обойтись без расчетов,  подарок судьбы. Значительная часть оборудования, с которым мне при шлось работать, была закуплена, коrда производители не слишком заботились о продвижении на европейский рынок. По этой причине оборудование разрабатывалось с учетом напряжения в силовой сети"" 110 В. Привезенное в нашу CTpa ну, оно переделывалось специалистами под работу с напряже вием ....220 В. Но, я почти в этом уверен, специалисты не pac полаrали всей необходимой для переделки документацией, включая тот неприятный момент, что электрические схемы оборудования отсутствовали. Позже это отсутствие сказыва лось на надежности. Время от времени оборудование BЫXO дИЛО из строя. Чтобы понять причины этоrо, приходилось внимательно разбираться с (отсyrствующей) схемой. Напри мер, так, как показано на рис. 3.2. " I ,, . ' " < \ '1  ' f "j  .п" ... . ....J41!9 .:) 71:'. с1 L1 !I! 11 !!! !!! .,!! DW  R1 .70 v1 . ,aнr nJN ПJ 01 '1МOO2OP 8ZVS$.C1' lо.а D3 1N4OO2OP с. '00rf' . !!  I  !!!  :1 а '00rf' 02 R3 I't. с3 . 2»1 ... ..., .-if....... ,. " ..... .- .  ,.j;.:..:.....,: .. 41".:': о'... ; ......-"':. ..-.:. .;. .::,.:'..:>.....-....... '" Со, WS12A '," . [. . "  f о-- ....;,..:.;.:-;. ',::') .. "<'. ...... ",...р,  .  1"" ., Иа't)( . . .r r >"r < . ' . .....  ' ..т'  "-:  : .-< "'. .... '. ." " '::.,-':: . .. ... .:::.. m'r,...... r' r *" . .....;.. ," " .:"С .. '.. j1'::l ' -7' ,9 For Fl ! - tiiS6. .. . lJJ.oШ Рис. 3.2. Диммер системы Х1 О (фраrмент схемы) 
284 rлава . 3 То, что рядом с «Умным ДОМОМ» За время, KOTOpO проходило от момента разработки об рудования, существенно изменялась сфера ero применения, компоненты, с которыми оно работало. В результате вполне исправное оБОРУДОJ3ание, собранное и включенное соrласно указаниям, прилаrаемым к нему, работало не вполне aдeK ватно ожиданиям. Найти причины подобных явлений мне неоднократно помоrало моделирование (и модификация) ero частей в проrраммах, о которых я хочу HeMHoro paCCKa зать (рис. 3.3). '." ::-:-::. .:-::. .;:.:- ;".: : E.I8   EIiC8  Tr'- IC1ds 8,8part$  ]ft"dDW l;tItI Q ra.[l J _е,()('»  't\:."."   18-l1li Q . . 1 rnUS8USt , · -- * 11;   D -а. FЗ ..-& 'f' I f. S ..:,I ?T '"'t"';t .. ............. 1t10 'CIIO ... DI It1t 240 5tOll 'N4OCМOP ... Q2 :IN3702 81011 v2 + ЭIIOIIIOtz fN I"LI JISI , = . : :' . : 1 .,.-.:: .' ;.... . ." :r UDI lt1 )'f)f 47011 UDj UD2 lt2 )'f)f IW . . . .. . ",." . ..... ._ .r.,.;.,." ....... ."  'o:,j,,:::::;i::;:::;,:;,;:,:::;;',:, ::.;::;'.;:):': ;:;;: :':'e . . .:.". Y. . ';K ..,' :' о r.. f f , J  ' "r(::J ' v '''' ;  ..;' , ", ,", t:' -;'. " " ,'(- ,.!. i J \ i 1: 1 ,1 j  ",., '. ' " " , , ',' J '" t  :";-,",' : . -=' -. . ....." . -1 .. . 1-. ... 4j < !. " , " '". .  1 f. r '"  T:" 'lT::wb:o':'.r:r r (  .......,1 ,..,...... . ," ..... 1.... ..... ," о.' H;'I ,Joo.! . ''.M;';.'" M:/O'I ';:"':. :.,. н- vt-tlOW8r  tIV.O.5A; reCeNer; tJIIiIWJI..... ,... ';"-z:- ( " . ::, . ,.. . ... ,. ( , . . ';';. ? т . 1A8Xt Far " . Fl " ......:.'..9 ......., "".. о::: -,'-:':'-': ..,9 Рис. 3.3. Расширитель ИКканалов (фраrментсхемы) в nporpaMMe Multisim 9 MULTISIM vt tIV ; . 1;: I '1:11 . 1.. i ! I ii08 I !IOII! ;!!! . i /!!!!. !. '!! :!II 1. j.... .. !..- I ,., 1"- I ,:! I jfj  т  О..  ...-;: .' Мне эта проrрамма напоминает макетную плату в сочетании с радиолюбительской лабораторией и большим ящиком, до 
MULTISIM 285 верху наполненным радиодеталями. Если не все, то orpoMHoe количество схем можно придумать и проверить, не выходя из за компьютера. Конечно, решающим моментом станет провер ка схемы на макетной плате, но ;Jначительную часть ошибок (а, может быть, и все) можно найти до покупки деталей. Я не уверен, что работы за компьютером, исключая профессио нальную деятельность, достаточно. Но мноrие неудачи при реализации rотовых схем, которые остались «явлением таин ственным и темным» в силу Toro, что плата «заросла» добав ленными и замененными элементами, удобно анализировать за компьютером. Осциллоrрамма, на которой обнаружилась ошибка, выявленная с помощью проrраммы Multisim в ДOCTa точно сложной схеме, показана на рис. 3.4. - - '" - ,-. __О , , ! I -, .;.;.  .х. ШLr Ulr -о' -,- ! , ! ....... -, , , , ! I , , - ! , I '" ...............   Рис. 3.4. Ошибка, выявленная с помощью nporpaMMbl Multisim Укороченный импульс, который вы видите на рисунке, в конечном счете, свел бы на нет все усилия, потраченные на разработку, если б не во время проведенный анализ схемы. После запуска проrраммы на экране появляются CTaндapT ные для среды Windows рабочее поле и меню. Раскрывая меню компонентов, в левой части окна можно выбрать необходи мые и мышкой перенести их на рабочее поле. В разных разде лах меню разные электронные компоненты, индикаторы 
286 rлова . 3 То, что рядом с «Умным домом» и при боры. Для перетаскивания следует подвести курсор к со- ответствующей иконке меню, щелкнуть левой кнопкой мыши и перенести компонент в поле чертежа. Выбрав все компоненты, можно разместить их наиболее наrлядным образом, используя при необходимости подменю поворота и отражения, которые появляются при щелчке пра- вой кнопки мыши выделенноrо компонента. При размеще- нии следует иметь в виду, что позже к схеме добавятся при- боры, с помощью которых вам можно будет,проверить работу схемы, настроить ее, привести к ви rOToBoмy для воплоще- ни, то есть сборки rотовой платы. Кроме Toro, можно сразу позаботиться о наrлядности схе- мы, придав ей вид, который ВАМ леrче понять. Этому моменту, как мне кажется, зачастую совсем не уделяется внимания. Дело в том, что профессиональные чертежи оформляются в соответствии с принятыми нормами и ре. комендациями [ОСТов, базирующихся на старых технолоrи- ях. В частности, стремятся к наиболее полно заполнить поля чертежа (экономя бумаry), максимально еrоупростить, чтобы облеrчить жизнь чертежникам, которым приходится MHoro- кратно. воспроизводить один и тот же чертеж. В результате чертеж, который леrко воспроизводится, трудно читается. Ситуация схожа с книrоизданием, rде применение аббревиа- туры настолько общепринято, что сделав перерыв в чтении, ты бываешь вынужден вернуться к началу  иначе не вспом нить значение мноrочисленных АБвrд, ВБлr и т.п. За компьютером вам нет смысла придерживаться этих стандартов, полезнее сделать чертеж леrко понимаемым и наrлядным, чтобы, возвращаясь к нему, вы моrли сразу уви деть схему со всеми ее особенностями (рис. 3.5). После размещения всех необходимых элементов схемы следует соединить их, используя левую кнопку мыши. Коrда курсор находится на краю любоrо из компонентов, достаточ но щелкнуть левой кнопкой, а затем провести соединение к следующему элементу схемы до появления пересечения курсора с линией в точке соединения, rде следует повторно щелкнуть левой кнопкой (рис. 3.6). 
MULTISIM 287 M,.  ,..... .' t- QI1IIInt .,... ttIIP>. ., .. <" ... DI... ., 111t61,j.1 11 ! &\IEtI 1 rti!Y9 .' . I "ф:Jl fU1 1 1 1nUIOIAI .:: f.i1 1 Х . . . . .. ';.: -../0 :"'."".::': :,''_': .:. .:."' ." .... . : .-:';':::':-:.). ";::= .::.:'::': .;.. :. :;.::,:::.":',:;":"':':::":'-:'":  ; j..шL.d " if:\ x 1  )с''!'> '.  I , :' ; r r r r r r r Fi r!Ull  ре.....: ;. !! . !!; - -tr ! ; .1'4 111 .' ...... J Qt CIII+JC -. CCiPI' CIIk( ! VI , '. У ! O'Mт ... "'Н..araI ..х С "'--. ..У  9O CIII+« , 90 CNII8CW 31'1t+Orl«< II!; , !t CoIIr. :... .. ,. '. -( ..1... -'\.. ,. . .' '4U>м:5IsТ' "" ."'''7':' :. v М .,.,' i.;," Рис. З.5. Вид nporpaMMbl МuШsim ............................... ................ ..................... .........................".,........................................."..,..,..,."..,..,............................... '«O() .. ',." . ,-' .' . '':''.:x 0.." C/It ..... ,,,..........  t- QI1IIInt .,... '" .-. ':. jJ,I>',ri ; .'Etl i [ii.$J9 '."" ";\ .'  Q . flnUlO1AI .!J .: .. J :').t: ;:}:1' .;.". ,;.,: Ч:л,J171 .{':" : . ....J .. r. t tOOOO\8I I ta Z 00eN0 .. ."." wt J.. ZNZZZZA :!..... tZV С  , с ;,,' I ,  f f ... f .   t' р, ,':'. j -"1 ....J ТI  " "',: j'" ",o,. о,.  '. .:,:.."H" I .  Рис. З.6. Соединение элементов схемы 
288 rлава . 3 То, ЧТО рЯДОМ С «УМНЫМ ДОМОМ» На схеме можно разместить приборы, выбрав их из меню приборов. Вольтметр и амперметр находятся в меню индика торов, представленном иконкой семисеrментноrо цифрово- ro индикатора (рис. 3.7). .х J:I8. _:.!IМ.,....к.. ,.......".It.....".,.. ,..:. JInIIaoIt.  " ..:' . <..".' '..'. ,.,'.,.,. ..,. ':'91.tiJIJiiI(::J' . 'iJ:' .I?t I.{I4' .I:: i{:i(J\J!1!i ''''U''IAI ., ;j. ...:. I. .tf! в ... 1 . .. х -..-; = . .., ; .. ;. ! е. "' .. ' ш1.  tOOON8 "'! ': - . '" 111 z...... . , - " =:i/l , .... ....; - . . -. ,_:::-::.:.:...:. ':.::.:.:.i:.:::=::': - ..,"-:. '.?":-'-:':=:-':-.:::-,!,:-:"":.:.:-." __:.:-.:-::..::..,:::: ";:;:.. .:::":::' . __о,'::;У:_:::,,:":::::.:., "' - -:::./::; ':::.:':::. ":.:.:: . Рис. з. 7. Простые приборы проrpзммы Multisim После включения схемы (в правом верхнем уrлу есть кнопка включения) при боры покажут измеряемые величины (рис. 3.8). Если появится необходимость изменить значения парамет- ров компонентов, их следует выделить, дважды щелкнув левой кнопкой мыши. В появившемся диалоrовом окне Component properties (Свойства компонент) следует выбрать кнопку Replace (Заменить) в нижнем левом yrлу, а затем  новое зна чение компонента. Следует отметить, что для работы схемы необходимо ис пользовать заземление, даже если схема не требует ero. Проект, который мы осуществим для знакомства с проrрам мой, может по казаться скучным  усилительный каскад на транзисторе. 
MULTISIM 289 .- fi,c- eec.  If.nttr l-  .... IМI ,.:,.,'. .. QI!QjI":;'11i"1 .!1;; [ii. ! 1 .";tо f!л  f  I InU"'1AI  .... 1J J  . !   ' .  . .. I . f   . . . .' ". .... -. ....= ","  "... .... ." о". .... -. -....-...... ..:.-:.....;.:.. .....:::::: . ":.-::.". ......." '.: ." =--.: ":..: . . .!J ; : ;;J!J!ШI '. м m . - .. ....,: . tТ. ..- !!: lt'I . 8!'! tOQat... -. 11 : .. wt t2V .. lNZ222A Ia l.oo.o... (  .! f. : [j :.;' 1:  . ..... '" it...., '::;: :fr_'ii.1i;l5. 1.:':.:" .......::.... '.':. _:- ":::":;:.:::=-:.:}:::::.:,-}: ::;-: н:м =::-:: Рис. 3.8. Измерение напряжений усиJlитеJlьный каскад на транэисторе Если открыть любой учебник по схемотехнике усилителей, можно там же найти и методики расчета усилителей. В учеб нике обязательно будет приведена классификация усилитель ных каскадов по способу включения транзистора как актив Horo элемента и свойства каскадов при разных способах включения транзисторов. Однако чаще Bcero применяют включение транзистора с общим эмиттером. Это означает, что эмиттер служит общим выводом для входной и выходной цепи. Тем, кто интересуется теоретическими аспектами BO проса, кому хотелось бы методично во всем разобраться, я MOry порекомендовать несколько книr. 1. fерасимов, Миryлин, Яковлев. Расчет полупроводнико вых усилителей и reHepaTopoB. Киев, 1961. 2. Воронков, Овечкин. Основы проектирования усили тельных и импульсных схем на транзисторах. Москва, 1973. 
290 rnOBa . 3 То, что рядом с «Умным домом» 3. П.Шкритек. Справочное руководство по звуковой схе- мотехнике. Москва, 1991. Мы же воспользуемся преимуществами, которые получа- ем от использования компьютера. Несколько слов о том, почему мне хочется начать с усили тельноrо каскада на транзисторе (рис. 3.9). Мне кажется, что знание работы транзистора закладывает основу пониманияи аналоrовой техники, и цифровой, включая микропроцессор- ную, техники. Конечно, сеrодня при разработке электронных устройств или ремонте использование микросхем подразуме- вает знание не Toro, как устроена микросхема, а Toro, какими свойствами она обладает (ее параметров ), для чеrо предназ начена и какие сиrналы использует. В этом смысле сеrоднлш няя работа с. электроникой ближе к проrраммированию на объектнориентированных языках, в отличие от проrрамми рования с использованием процедурных языков. Некоторые преподаватели информатики даже считают, что знания пр<r цедурных языков мешает быстрому освоению cOBpeMeHHoro проrраммирования. Возможно, так. Но быстрое освоение в узкой области знаний рано или поздно может завести в тy пик. я: так думаю, но спорить не rOTOB. Вот так будет выrлядеть усилительный каскад с общим эмиттером. В качестве источника сиrнала использован rehe-- ратор синусоидальноrо напряжения, а сиrналы на входе и выходе усилителя мы наблюдаем с помощью осциллоrраф. HeMHoro изменим нашу схему, как показано на рис. 3.10. В схеме появились два вольтметра переменноrо тока для измерения величины сиrнала. Как видно из рисунка (по пока заниям вольтметров), сиrнал на входе усилителя  около 6 мВ, а на выходе  2 В. Отношение выходноrо сиrнала к входному  это коэффициент усиления каскада по напряжению. Разделив 2 В на 6 мВ, мы получим, что Кн == 333. Усиление по напряже-- нию интересует нас довольно часто. Здесь уместно пояснить один момент, касающийся еди ниц измерения. Усиление мы измеряем в относительных единицах как отнотение выходноrо напряжения к входному 
MULTISIM 291  _ Idt .... !!!Ка  тt"'" 1- (jPIICN .... tI$. _ _ 'н" 6 . . . 1.t>"I('!( @!JJI _!e.I IiiJ.JQ j"jj"C;i ; ' lnu..tJIt  i ....  - .. ..с. SIS " ' 1 v2 JOмv tOOOМIDDoe ...  .... ---(. .tn"X. r": fulJ ;.. ; !а !!! ... J!j - o ...., .. ""H' """ . ., .,,8fl:OJIЭ8.....,. '" Рис. 3.9. Усилительный каскад на транзисторе с общим эмипером &i...... '1". JPdJ .__  "'.'-" ..... .'А"'" """'"':/""'';"i:" .:' .,/;;:;.:.,,-:,'::""',.;".,..",,",,:...A ,".": А,' '.' :DII#I 11:' 1'" I 1 Jii'.I.LtJ: jInU" d i :':',' ,  . . . ... . .-.. ''.-. - - .- ".- ;:..:::::.:';:.::::?:,::":.:::-::::::.:':::':;,:. -..::--_.:.-::-..... .;.' . ..с. . vt t2Y  v2 I08IV tOOOМI 0D08 ... .J .. .Щj J ЯJ I >;,... j М)IIII Рис. 3.10. Измерение входноrо и выходноrо напряжения сиrналов  ;':". )( 8/" ""J .tiЮl1 . х:.! Ii ':;=A = u;  t !; , !!I --:="? !. I I!: 1. ;  ?f. IUI-. ". 
292 rЛQВQ . 3 То, что рядом с «Умным домом» (Ку = UBbIX / UBX). Есть и друrие единицы измерения  дe цибелы. Формула перехода выrлядит так  Ку, дЕ = 201g Ку или Ку, дЕ = 201g (UBbIX / UBX). Зачем нужны дрyrие единицы? Общее усиление ДBYXKac KaдHoro усилителя равно произведению коэффициентов уси ления. А мы знаем из свойств лоrарифмов, что лоrарифм произведения равен сумме лоrарифмов. Таким образом, вме- сто сложной операции умножения можно применить более простую операцию  сложение. Порой это удобно. Вернемся к схеме. Для чеrо служат ее элементы? Сопро тивление R1 определяет базовый ток транзистора, ток кол лектора KOToporo равен некоторому параметру транзистора, называемому статическим коэффициентом усиления транзи стора, умноженному на ero базовый ток. Расчет каскада «на вскидку» можно провести так  мы определяем, что в OTCyr ствие сиrнала напряжение на коллекторе должно быть равно половине напряжения питания (чтобы симметричный сиr нал Mor усиливаться максимально, но без искажений). Зная величину сопротивления R2 == 5 кОм (сопротивления наrруз ки транзистора) и величину напряжения (12 В / 2 == 6 В), можно леrко определить необходимый ток коллектора. Ток коллектора равен половине напряжения питания, деленной на сопротивление наrрузки (6 В / 5 кОм == 1,2 мА). Ток коллект<r ра связан с током базы величиной статическоrо коэффициен та усиления транзистора по току в схеме с общим эмиттером (Вет == 200 для данноrо транзистора 2N2222): IK == Вет х Iб) rде IK  ток коллектора, Iб  ток базы. Таким образом, ток базы должен быть в 200 раз меньше, то есть 6 мкА. Через резистор R1 должен протекать ток в 6 мкА, а напряжение на нем должно быть равно напряжению пита ния минус напряжение базаэмиттер транзистора. Для расче- тов «на вскидку» последним можно пренебречь, приняв напря жение на резисторе равным напряжению питания. Тоrда величина резистора R1 будет равна отношению напряжения питания к току базы транзистора  12В / 6мкА (то есть, 2 МОм). Что мы и сделали. Остался вопрос, почему величина резистора R2 выбрана равной 5 кОм? Эта величина обычно определяется входным сопротивлением следующеrо каскада. Например, можно считать, что наш усилитель будет подключен 
MULTISIM 293 к усилителю мощности. Линейный вход усилителя мощности имеет, примерно, такие параметры: входное напряжение  250 мВ, входное сопротивление  47 кОм. Если выходное сопротивление каскада будет на порядок ниже, то есть 4,7 кОм, входное сопротивление УСИЛИ1;еля мощности не бу дет мешать работе каскада. Выходное же сопротивление Kac када не превысит сопротивления наrрузки транзистора, pB Horo 5 кОм. Усиления каскада в 300 единиц по напряжению, казалось бы, достаточно для мноrих целей. Так сиrнал обычноrо дина мическоrо микрофона, который будет включен вместо reHepa тора, имеет порядок 1 мВ, а выходной сиrнал в 300 мВ COOT ветствует уровню стандартноrо линейноrо входа усилителя мощности. Чеrо нам еще желать? Но если мы посмотрим на реальные схемы, то увидим, что они имеют несколько иной вид (рис. 3.11). Что получилось с усилением? Кн == 100мВ / 5мВ (Кн == 20). Усиление снизилось более чем в 10 раз. Зачем же нам нужны лишние детали  резисторы R3 и R4, и потеря усиления? . ;--i- .... I!IК. ,..... J(fIhht 1- gPIION .... ... .D'I$I'.I"I.I ?I  ff Hii. 1 J '.',. 1 0  Q I  I lnU....... ...... . с  .::: .  ... j · 1 = . = ... ;J   '!] Р.' Ю]  .!J. .., ". ;( . . :...;.. ..:. .=.11 ,,' [jЦIЩI . ..'.' !t .. I!J Д= . .:9.. ..С! cz:r .... . vt !ZV t .  .;. .!,; . .. . . VI 1ОооУ tCIOOМO 0ООе ... .. !! -. .: .' :'!". .. [: :\ 8;':  '.""1' ".: I .: "';:":. , '" l I , :: с:. ...,,:- .. ...  ....::.. .:....-. ,. ""':__ ......'.::,.; ':.:',,:< J ,. .,. .N.>.::.:,.:,.,::":,,,:,,:,,:::,:,.,..' Рис. з. 11. Типовая схема каскада с общим эмиттером 
294 rЛQва . 3 То, что РЯДОМ с «Умным домом» Дело в том, что, в первую очередь, полупроводники очень чувствительны к изменению температуры. Это их свойство часто используют, изrотавливая из полупроводников датчики температуры. У транзистора с изменением темпераrypы OK ружающей среды изменится ток коллектора, что сместит на- пряжение на коллекторе и может привести к искажению сиr нала. Аналоrично действует изменение напряжения питания. Попробуйте повлиять на ток коллектора, меняя величину c<r противления' резистора R1, и понаблюдайте за формой сиrна ла на экране осциллоrрафа. Этоrо же можно добиться, меняя температуру в диалоrовом окне условий моделирования (Simulate - Analyses - Temperature Sweep). Для этоrо нужно проставить новое значение температуры в строке Values OT крывающеrося диалоrовоrо окна и щелкнyrь кнопку Accept. Дополнительные элементы схемы призваны стабилизиро вать параметры усилительноrо каскада. Если обратиться к рис. 3.9, можно заметить, что входной и выходной сиrналы находятся в противофазе. В нашей схеме (рис. 3.11) резистор R3 в сочетании с входным сопротивлением каскада обрзует параллельную обратную связь, а резистор R2  резистор пос ледовательной обратной связи. Обе обратные связи  отри цательные по постоянному току  стабилизируют все пара метры усилительноrо каскада. Посмотрим, что произойдет, если ток коллектора возрас тет. Напряжение на коллекторе транзистора падает, ток че рез резистор R3 уменьтается, что приводит к уменьшению базовоrо тока транзистора, а, следовательно, и тока коллек тора, paBHoro величине базовоrо тока, умноженноrо на CTa тический коэффициент усиления транзистора. Похожие изменения происходят и при наличии резисто ра R2. Увеличение тока коллектора приводит к увеличению падения напряжения на этом резисторе. Ток базы зависит от напряжения между базой и эмиттером транзистора, KO торое при увеличении падения напряжения на резисторе R2 уменьтается (оно равно разности напряжения между базой и общим проводом и падением напряжения на резисторе R2). С уменьтением напряжения между базой и эмиттером yмeHЬ тается ток базы, а, следовательно, ток коллектора. 
MULTISIM 295 Есть еще один из достаточно важных параметров KaCKa да, на который отрицательная обратная связь влияет блаrо творно. Верхняя rраничная частота усилителя на рис. 3.9 составля ет примерно 2,3 мrц (частота, на которой коэффициент уси ления уменьшается на 3 децибела). Верхняя rраничная часто та усилителя на рис. 3.11  более 16 мrц. для определения этой частоты можно построить частотную характеристикууси.тtителя  зависимость усиления от частоты. В средней части частотной характеристики rрафик идет rори зонтально, а после верхней rраничной частоты происходит спад усиления в 20 дБ на декаду (то есть, изменение частоты .в 10 раз приводит к спаду усиления на 20 дБ или в 10 раз). Частотную характеристику можно строить по точкам. Изме нив часто определить выходное напряжение, вновь изме нить частоту и измерить выходное напряжение и т.д. Про rpaMMa Multisim предлаrает воспользоваться для этой цели прибором  плоттером Боде. При работе с приборо не сле дует забывать, что он работает тоrда, коrда на входе схемы включен reHepaTop переменноrо напряжения (ero параметры не существенныI.. Кроме Toro, включив схему, можно не обна ружить частотной характеристики на экране плоттера Боде. Скорее Bcero, причина в том, что она выте выделенноrо окна. Изменяя параметр F вертикальноrо отклонения, можно найти пропажу (рис. 3.12). KOМYTO подобные простые объяснения MOryт показаться излитне простыми. Но почему-то в сложных ситуациях имен но об этих простых вещах вспоминаеть в последнюю оче редь. Впрочем, это дело вкуса. Так выrлядит частотная характеристика усилительноrо каскада. Для получения фазовой характеристики на плотте ре Боде следует включить клавишу Phase в верхней части прибора. Знание фазовой характеристики усилительноrо каскада позволяет определить устойчивость усилителя после BBeдe ния отрицательной обратной связи. На rраничной частоте фаза сиrнала изменяется на 45 о и продолжает изменяться со скоростью 450 на декаду (относительно фазы на входе). При 
296 rЛQВQ . 3 То, что рядом с «Умным домом» . . x ., 1.«.."" .В-' .,......;,,.I-  ....., ем ' :b..IQj:':ii' Ч'!ii: : ei 1Н " t\Iё.f ;'.Iii .' ..' 1loI!!I.Qf f: I '''U'''''' .!f ' : f ....!!Jf ь: '..' ,*: .....<  tJ .,  = . ..с. ; " !  iQj1  1.' :. ! Q1I! .':;.; ";а а"': f . vt .ZY :!I  ::5  ri c yi  i VI tOмy tOOOМr 0ООе ... ,:.  rи I<rt' iY1JJ>, tЗ' : ;  i  """"" ... -.. .......... ... . F.!!tl " F.!!tl ,f... :I 1O+tr: . .r............i...*. · [' .iih.. ; .!!;J.  f .. "! .t:",-p .0tIt: ".::': .... .'.....",. .. '......<.,-,-..-...,. "'.' """""'''''''''''''''''''''''''''''.''''' '.,.',."..,.'.".,.',..,. . iff8r 0-.3).' .-- iU4 Рис. 3.12. Частотная характеристика каскада на плоттере Боде этом отрицательная обратная связь на не которой частоте превращается в положительную. Если при этом усиление больте единицы, усилитель превращается в reHepaTop. По скольку часть сиrнала с выхода усилителя приходит на ВХОД в фазе с входным сиrналом, складывается с ним, увеличивая выходной сиrнал, часть KOToporo складывается с входным... Пожалуй, этоrо KpaTKoro введения будет достаточно. Mory только добавить, что первые иллюстрации сделаны в новой версии проrраммы, которая, что бросилось мне в rла за в первую очередь, весьма пополнилась в части используе мой измерительной аппаратуры. Осциллоrраф не только выrлядит, как настоящий, но и позволяет покрутить ручки, включить меню настроек на экране. Используемые микро схемы пополнились, например, РIСконтроллерами. Про rpaMMa, как и предыдущие версии, очень наrлядна и удобна для ретения быстро возникающих неотложных проблем. Имеет интеrрированный компоновщик рсв (рис. 3.13). Единственный существенный для меня недостаток про rpaMMbI  стоимость полной профессиональной версии боль те 4000 долларов. А демоверсия (именно ее я использовал 
CircuitMaker 2000 297 1- ........ . ......Уо' "" :. . -':.. М,...... ..."'С  "М"..." :. .. ". ......  -:" :.-:-....-.;." ...w.... .....:- .. -,-м...; 7;" .... , . ......... .,.:... .. ... \" :..:::- ... ..... .... о,". ,', . ,".. о.. ........... .?::- ," . .....:-:-.. 0.0 ..... -..0.;.... «- ':'" .:::....::. .......: ,..-:. =--..::.::-....: ........Х:.. .:.:..... ... .j,J"i CopporT... ....   ,.  о иjt..,1.IIoa 1 .-'-' 1'1. ..- .. . "",.-.... " :" .... ..... о'. " .......... . ...... . .........- .r:?{. . .......:. :: ::1:::lf;:. .;:.2 :,,:)-. .. М>Щ йд .-, ..:,'::.-.'. Рис. 3.1 з. Вид платы в r:wporpaMMe Ultiboard 9 для иллюстрации) завертает работу на моем компьютере че рез несколько дней, и в отличие от предыдущих версий, pa ботающих без сохранения файла, не имеет приборноrо дo полнения.Увы! CircuitMaker 2000 Эта проrрамма не менее удобна, чем предыдущая. Она He сколько дешевле. Bcero 1500 долларов, что не мешает мне забыть о возможности ее приобретения. Проrрамма помоrа ет строить как цифровые схемы, так и работать с аналоrовы ми (рис. 3.14). И нельзя сказать, что просмотр сиrналов в этой проrрам ме неудобен. Наоборот, все удобно и наrлядно (рис. 3.15). Проrрамма поможет вам проверить идеи при создании охранной подсистемы. Не всеrда очевидно, каким образом орrанизовать работу этой подсистемы. «На вскидку» peтe ние выrлядит просто: сработал датчик  бей TpeBory. Без продуманноrо подхода реализация может дать обратный эффект, в первую очередь, за счет ЛОЖНIХ срабатываний. 
298 rЛQВQ . 3 То, что рядом с «Умным ДОМОМ» (ft ri? ;:: ; .; . H ,--'.: }:. ,:. ), ';: . ;:.', :":':.: ":'-::i<.::..;:"-; '; tJ. .. 3D ;; iIt ;J [ -". -... ". :-". ....::... ::- ''':-''- .j . ' ; :!' {: ::.:;;:::.+ :' ,,-,..:::/:.; '-"'.. -" " :, . ';' :::::; ;? - . +v t.; - ( 1<." ... - ". .. :"' .::: :' }=-'":: . ':::-:.: :::_:-'- :.::: :: :w- и. .»::!о ...::-ж-...... .: :-.;:.::: :.:::"'::'ic.....: ".У'. : .":" :....:<?'..: ':>" .+ . :-- .. '[ ...... 'f.....J'".. . Рис. 3.14. Клавиатура в nporpaMMe CircuitMaker . . . Ci:t ( j';' . j " :::' ' ;;, ;4:':':' :::iIJ..7\..'j.;.j': ; y! :; ::)( .. -- 1:] !;r ::,5rm. _ _ , .' n)t.:. С' .,g; !-*У': о" ."-"-'.-".. -,;4-;. ':В:' ....... : 01 ZJD 4 ;i:(:::t.; 0-\' : - J,iзrfJ.-& "" ., !Ii и 4.7It u 4.7It u 1181 .1" .=. l" .х: "):.- ::.;..y;,.,..: ]i;'п ..; ;.......'r':. c.nor 2. c.nor 1 _: 1<1 ; - . ....... ....... -." .. ......... ...-........-............ -.... ....... "-. .- . ".' ;.'<)1»0" CJIo\v j IJX)roV i , о ,:о;.. I WJмV ' 1000-.... ... : :'" ....... .: I ,.. ... ! / .;;; .::::::::::::...:; ' .1S00m \JI )n , ,ro. ..т, .. ''::.. ' :'''': -::.: : -: '-.=-: ':-.:.r:.. .:.......--; . -;....:. '.;;'; -' ........ ....-..... .:":;, '.::" . /: .. ;,. .... . ry;.,. . Рис. 3.15. Усилитель в nporpaMMe CircuitMaker
CircuitMaker 2000 299 Затем последуют срабатывания системы, если вы забудете (или не успеете) снять ее с режима охраны и т.п. Самым лучшим ретением в подобной ситуации станет тщательное продумывание, в котором поможет проrрамма CircuitMaker (рис. 3.16). -мw., 11'"'......_,.."  t. . ".";-"< . -.. .-... .. ....: ... :-!:-....... *J.: .....i-; },!; -,-,."", ..,-- -. ". ;.. " p'g.  :t,,-'_',' 1\.1 ;,.?'; .,:t .... ''1J,:Щ!::1 .......1  'I ;.' , 's., SiZtI t jj,;j-. '-'-;-и..'-'  :,'  Ta. ,X.. ,;1 ;1 .... м;! . , .",-'''' 1;: . ....... ,- Е. ._, CONIIIOn 1 . ы -. о. . . ": .....;.. "": ". . ...... .Н....:" .... ....--!!lk. ..:- :' +у  . . ... !i ЕпаЫе Alarm ":'"  ..........-............................. ", .. iH.....:= '. . . - . . . . :. ..:.... ..,  ''''. .''Qo'< . :'. ".k." ':. ';': ... . . .... Рис. 3.16. Подсистема охраны в nporpaMMe CircuitMaker Как и предыдущая, она имеет часть, предназначенную для создания печатной платы. Современная любительская TeXHO лоrия. позволяет сделать печатную плату очень хорошеrо каче ства. Если использовать поверхностный монтаж, выполнение платы может мало отличаться от промытленноrо. Я имею в виду использование лазерноrо принтера для нанесения рисунка. В этом случае наличие возможности выполнить раз водку в той же проrрамме, rде разработана схема, скорее обя зательно, чем желательно (рис. 3.17). Я не сомневаюсь, что для мноrих из вас высокая стоимость проrрамм не является препятстцием для их использования. И не думаю, что вытеупомянутыми проrраммами оrраничи вается выбор. Я только хотел подчеркнуть, что, используя 
300 rЛQВQ . 3 То, что рядом с «Умным домом» микроконтроллеры, не следует забывать о микросхемах по. проще: транзисторах и резисторах, конденсаторах и транс- форматорах. (J) с m ОI  :D c...  :АС...... .....  ......   r;iI  )1 & 1""' ..."  .. r'  10 g g \  11  FI! о а 1.......... ::; I А.- О n  1- О ro ...  IU" 111 J: (J) н  10 1 I mc... "t....... :1 ""'" (] :!2с,.) I о ;: » .... ...,:А С т 1: f ... ... ...      ..- ЗЗQfO' ( .Iu 1.. ,.... «' 1 I Ifo r::-==1 Е  ... o  ...,. 'W' I С Т . ) .........   II  "-З fo...'J  CI('  I=: 7(11O' :    ..... ,",' о [ I .......  ..-4 '"'" )r.1ALI   .7(110' ..... О 00 t442  I .1Чё '"'" '"о ) 14 О I  ,ос . 91  М1-12 Ос...  47('" I .-о О ... ....... (<4 ! Т Iё C т:  ('.1 .r i"'" .!: ""' ... о. L: (l'С  a "'L.-. Ia  L О. "'... 11"---' ,   ,..--- о t 4 ...  ........ "'.  '..... .......  'J с" '"-  ..  '  1-  ,......... 11"" ,.......... ) .......j .. ....... .......... f""""""'""4  tf;1 :r-----4 I .,........,-4 I  А   g L COPlJr'Qht Се' сОI;Ю TRAXMAKE ..... F"Q11 ]n1rnotl(lnol Lirll1:d т т ...\.. ..  "   "'u  +-' С 11' с О Q. r: о L) N О s)  r N 52  R Рис. з. 17. Вид печатной платы в nporpaMMe TraxMaker Даже такой возможностью, как просто отрисовать cxeM Не следует пренебреrать. Одно дело мысленно нарисовать схему, в которой леrко ошибиться, скажем, забыв, что счет- чик  десятичный, а не двоичный. Дрyrое дело  нарисовать ее на бумаrе. Правда, у меня бумаrа после недолrой работы со схемой превращается в rрязное подобие ретета  следствие MHoroKpaTHbIx переделок. Для рисования есть удобные rpa- фические средства. Коrда-то я использовал AutoCAD LT, но возможность нарисовать и проверить работу, хотя бы в первом приближении, мне кажется очень полезной. Поскольку использовать дороrостоящие проrраммы я не MOry, то пытаюсь отыскать проrраммы, которые доступны 
Electric 301 мне по цене. В частности, в последнее время все активнее использую операционную систему Linux, для которой про- rpaMMHoe обеспечение стоит MHoro дешевле, и существует великое множество бесплатных проrрамм. Следующая про rpaMMa доступна в двух версиях: для Windows и для Linux. Она, как мне кажется, больте предназначена для разработ ки микросхем, судя по началу руководства к ней. Кстати, py ководства весьма объемистоrо и подробноrо. Electric Сразу оrоворюсь: хотя я подозреваю, что в проrрамме можно моделировать великое множество схем, я попробовал работу только простейтей схемы. В настоящий момент проrрамма мне не требуется, и я не хочу тратить время на ее освоение до Toro момента, коrда в этом будет необходимость. Проrрам му можно найти на сайте http://www.staticfreesoft.com. Для работы проrраммы необходимо установить пакет J ava (в последних версиях это не обязательно). Полаrаю, как и у меня, он найдется в дистрибутиве под именем jre1.5.0 1asp.i386.rpm или аналоrичным. Проrраммы для установки в Linux имеют растирение .rpm, но не для всех дистрибутивов. После установки пакета можно запускать проrрамму. Я YCTa НОВИЛ ее первоначально в своей домашней папке, но затем перенес в папку /usr/etc. Для запуска создал кнопку запуска (ярлык) с командой javajar /usr / etc/ electricJarmdi, rде пос ледние символы (mdi) означают, что я хотел бы видеть все части проrраммы в едином окне, что необязательно. После запуска проrраммы появляется окно, в котором можно сразу обратиться к руководству пользователя, которое находится в разделе Help - User's Manual (рис. 3.18). Надеюсь, вам это руководство поможет больте, чем мне. Оно достаточно подробно, хорошо иллюстрировано, удобно в обращении. Но написано, как мне кажется, для пользователей Windows, хотя есть все уточнения и для Mac, и для пiхпользо вателей. Чтобы убедиться в том, что проrрамма работает, можно сделать следующие, возможно, инеправильные таrи. 
302 rлава . 3 То, что рядом с «Умным домом» , r11'; :::1 ... bri U ',. CI M8IIII.i  . j.. . IOI: r" Т",. , Ф EIIRO: ...  1 InIПIOUCtlon .. О 2' BISiC EaIIInO ..1i:J 3. н-ratt"" .. Cl4 DisDI&Y .Cl5 .lns "06 <Ioav8n<tdE4a1llO .. s2 7: Т ethnOlOll'" "Cl8. Cr...1ng 'Te< C2g YOOlS .. &:2 10: УМ JEU8 F.' F Using the Electr1c™ VLSI Design System 3 S'tven М. RuЬb1  Novembu 1. 200S  V8l'llcm влз - . t I «trM= . .,- _.  .- ...... ".' '. --'  . . .. . . :':':;'Ii.::," ::.,.'.: ./s..."tt{:;.':"::l;' ':»':I:e::i6\::I- . ....ddA""'C>e..1 (;': J::i "Vн-w nn.....с "'''(1.", ....:S:;..... :t-: "1 .. = .' HJO DD J II r> ;. .....1  ... i 7.-< -{) 4 .-{ · txPadAmp :::h ф, ...u:1J'I11 \. .... . " .... .:-... .:. . '. .....  .......:.......... .  Ii"  '" --..... """ *''''''' : 1.. ....чI 1.-.11.1 B{ 1111 , . . ....,... . :.:::: t l '-: ". : I  :. -+ ",., . .. . . ...  """'" :  . ?: I l ' .  . ,'  J . : r . J ..... - '.: :. .: I ПСIt'IIt8ОМS сиllt- 20.........,.....,-Мes.. Рис. 3.18. Окно руководства пользователя в Electric Сохраним библиотеку с помощью меню Fi)e - Save Library As..., rде  открывтемся диалоrовом окне выберем заранее созданную в своей доматней папке подпапку с названием Electricprojects. Открывать папку лучте кнопкой Open. Затем изменим nonameJelib на любое имя первоrо проекта, например firstJelib, и щелкнем появившуюся кнопку Save. Выберем в меню раздел Се)) - New Се))... В диалоrовом окне, которое появится, выберем schematic и впитем имя first в окне для имени первой схемы. Подтвердим выбор кнопкой ОК. Надпись об отсутствии Се)) пропадает, вместо нее появ ляется курсор в виде крестика. Выберем слева в проводни ке ярлычок Components, а в открывшемся меню компонен тов  схему И (на рис. 3.19 видно меню компонентов). Схема И  верхняя правая, ее мыткой перенесем на рабочее поле чертежа: Теперь, если поводить маркером по картинке, видно, как на полуокружности задней части объекта появляются три крестика: один  в верхней части, второй  посередине, Tpe тий  в нижней части: Если выделить верхнюю метку левой 
Eledric 303 fl1r1l. . ... . .. . f.... fll" 1;.." fM8I1 }llno WltlcI8w 1001 11.... .Ii"!J' . 't Ча i:'\: .:,'::: "'1':: .: ;.' ;м,;' .r .; .( .;' .. .' . . ""t;fifSЦ5d1j ((.iфi.....  ....... V-:,.. .., --':1 / .' :, '...'..... Q "J .: ...:......,  F.l1! f:J1I .". 1:S Ii Ii +.В О []9 <.}. &а:  .-. ...х .' . ........ ................. .................................. hO"/v1id1.1r/,,1.r1C.JIroj/1'trn ].11!) ....1tton r" r .. "" ..... :t' ё'аЕАП: HOOёAA4" 5IIE: 'М! TECtt IOR8II1tc: . ,. . 'О,. <". ":.,, . ;.. - '"n (м. . ii" Рис. 3.19. Окно с панелью компонентов кнопкой мыти, а затем, удерживая правую кнопку, провести линию в сторону базовой линии фиryры, которую, возмож но, потом нужно будет выделить, то (иноrда мне удается дo биться этоrо, просто, сразу щелкнув правой кнопкой мытки в момент, коrда маркер выделяет метку) получим результат, показанный на рис. 3.20. В разделе меню Export - Create Export, в диалоrовом окне для Export Name зададим «а». В окотке же пониже выбе рем input. И по доброй уже традиции щелкнем ОК. Теперь в разделе Тооl - Simulation (Built-in) - ALS: Simulate Current Cell, щелкнув все в правильной последовательности, получим pe зультат, показанный на рис. 3.21. Теперь можно закрыть окно наблюдения; выделить ниж нюю метку аналоrично верхней и через раздель меню Export и Тооl получить отображение обоих входов. Выделив метки входов курсором и щелчком левой кнопкой мыти, пра вой кнопкой можно «уд.тiинить» входы микросхемы. Можно перенести буквы, обозначающие входы, вперед, чтобы мик росхема приобрела более привычный вид. Для упрощения 
304 rлава . 3 То, ЧТО рЯДОМ С «УМНЫМ ДОМОМ» sdlntauc !.". .. ;71", ,. :.'.; I ' .:>, , ;[j:: ::J ,,;...., >f{ "'.. ? - -: "j;: :.:- .-;:: :.i) ". ..:.:x...... :::.. .::.....:......, .. ....,.._.... ,;........-...:. : . ;..... ::[ I.:<, l  ) ". ." .-v.""" - II8flretКe ..мt ) .'. :...... :1 r;- :.. . ... -:'"-- .'. 11 . >  .  -Не'" то ereat. n04М 'A/Id' t111g Idded: 1 wlre arcs . 1 ..... ,f" .. .' . "' .  .,. . .. . , 5a.(Cfm NOOЕ: АН{'--и.'1 roI(f: "" OIЖI-7.Sd) псtt SCIIetQIk а" r? 18 ..1 о.. : t (1, 1" Рис. 3.20. Окно с выбранной схемой И и диалоrом Export .,.,.,.."..,....".,............. ..,......",. ,..т:..,.,.,....,...,....у...;...., ... .;,.и,..,.... ;... ...... "о ... (IМ f". {..II fJlp8ft 1eW 1IМIeW 1." ие.. ' !.Ij1SJ  ;: W  [ :.. } '''''+. . ;. 1 :..;. ;:.. fJi:...r;;;:r.,i..+' IJ; .8 fIn1:f\n\{sdI} ;./' .;.'./, ,. . ..;... . .,$,. .. .,., . f;щr .ц7tJ:,.;:t;f.:t ; . iIItk . .. , ::;-<:( У'.< , .: . . I !>.. . $.:. . ::...:. * t\:... ? :::":;'* '...д.: .. ...,.' . :.: :.!-:: : .. ..._.... .'Х..: . 0'-:': :.;......:. .: '.::_-::' : НC)ТJII!IКt SШСТED . ";,." ..*-y """ . ".."". .;,0". ".<-. "j.:(/" .",,: __"Х".. '.(."'. , . ""'SR. ..; ..,., ..' З:: +ш:ш<.... .. ..),; '..' E\d: llОаl C.WUI f?E : . ;:t>.. 1;.. . _ X=. .. .". .:';! t . ,. ИJ:: .::;' ,., 4.:* :'< ..,..т .... :-... !IiIIIIIIJ "X=. ;.:.::. .'.:S:;t' . )('7 Slze .". пttt _dМlll-к Рис. 3.21. Окно наблюдения в проrрамме Electric .;.., * а""" 181 .Of..i v! а" .181 OIIU: 111.s I,a 
Electric 305 последней процедуры я на вкладке проводника проекта Explorer в верхней части левоrо окна раскрываю проект first (Current), выделяю название окна схемы firs (sch) правой кнопкой мыти. Появляется раскрывающееся меню, в KOTO ром Я выбираю раздел Edit in N ew Window. После открытия окна можно закрыть предыдущее, а в новом окне леrче Bыдe лить буквы и перетащить их в новое место. Для оживления окна наблюдения выделяем вход, напри мер «Ь» (я полаrаю, что раздел меню Tool- Simulation (Built in) - ALS: Simulate Current Cell уже пройден), через Bыдe ление метки входа «Ь» на дуrе. Затем в меню выбираем Tool- Simulation (Builtin), rде, в свою очередь, щелкаем пункт Set Clock оп Selected Signal. Соrлатаемся с предло женной частотой (О К). Вид окна наблюдения сразу изме нится (рис. 3.22). " 1A ... ., ,... М..,.... ... .".н ;;H"'CIt;IO" ..........,.....,_".. .,........«-., """,,""'...' .... '. 'н', ........ ш .... "<,,... ....,. .. .'. :lJ";;jjwo [1Ie It j;ell IМcнt Iew WilМl8W 1." u.... )ii 1iiI:,.J "rlo\ tIfI);'! :,1 t(l:1..; .t} ('w,....;:.:," .'; .. : . fIrЯ:1tnt(5dII . .1 L..en ' c.......III , ... . .. "., ,  .AI.S............IIrя ... ,. ... ". ...... ..... ,. ..J&, · , (] uren  6\........... .9 ++. М-:4011 ,.., bt: , lU11. ,.,с;:.-.... ОеIUl: 11818. .=',:: .... .. .... " r c::Iaнo...l I '- 1 i"D" .. Ф 'OI I : ОNO ' : 1(" JV8S ф ....j .} 4' f<.,.' "  ,. <-' ..' ."  '." .. .' .,.4 $'..  а" ri' IS __/ .. .. :",:'.:: :.:::.? .. _;::_:__:.:-:. : "'".::;.:... ;.' ." . . I х= _х= I j ! 1, 11 ! I 11:: ,1,  :"18 х= .. I .01 . I . SВ.КnD нoor: AIмI!'....2'! .оп L' 0iZ.-7. П:СR ...  I ...J .... ."':0-- .:"",::.,<".::".\,,:--.:,;::,; >,",...:\".,.,.,.:,:,::.":.,,, Pii",,' I 1- Рис. 3.22. Окно наблюдения при включенном тактовом reHepaTope 
306 rлава . 3 То, что рядом с «Умным домом» Воспользуемся клавитами управления, подобными клави- там аудио и видеопроиrрывателей под надписью Рапеll, запустим время клавитей Play. И, коrда подвижной маркер дойдет до временной отметки 6080 nS, остановим ero клави- тей стоп. Мне приходится быстро нажимать ее несколько раз. Теперь вернемся к чертежу, выделим вход «а», войдем 8 меню Тооl - Simulation (Built-in) и выберем пункт Set Signal High at Main Time. Вид окна наблюдения изменится, что, с моей точки зрения, свидетельствует о правильном отображе- нии событий. Сиrнал на выходе появляется в тот момент, коrда он принимает значение лоrической «1» на входе «а». Повторно запуская маркер клавитей «Play» и останавли- вая ero через некоторое время у отметки, например, близ- кой к 120 ns (мы оставили вход «а» на схеме в выделенном состоянии), входим в раздел меню Tool- Simulation (Built- in), но теперь выбираем пункт Set Signal Low at Main Time. Вид окна наблюдения меняется, и мы получаем вариант ра- боты схемы, управляемой по входу «а» И тактовым reHepa- тором по входу «Ь». Если временной интервал задавать с помощью таймера на микросхеме 555, думаю, он будет ра- ботать. с нужными временами, а этих таймеров можно сде- лать несколько. Если, в свой черед, к выходу микросхемы И подключить светодиод, ИК или АЛ307, как это было в пер- вой части книrи, а частоту TaKToBoro reHepaTopa выбрать равной 37 кrц, можно придумать альтернативную схему из лучения ИКкоманды. По крайней мере, мы получили пачку импульсов, rотовую к употреблению (рис. 3.23). Добавлю еще одно замечание  проrрамма позволяет со- здать, подобно pcb-проrрамме, вид печатной платы, но я не пробовал. Сопряжение управnения Наличие нескольких телевизоров в сеrОДllятнем быту далеко не редкость. Телевизор в rостиной, DVD-проиrрыватель, ви- деомаrнитофон, телевизор на кухне, в спальне. Как лучше со-- rласовать подключение всех источников видеосиrнала, можно 
Сопряжение управления 307 ... -:.... . i':,........... ...;" ." .. ..: . .. . :.::.>;,,;.-.-':::., -.:.... ,"."," .... ... ." ',::t"f'"ям.. 0.:21$ . .. , l '" t ... {1t-- ". ....., ..: ...'. ,.!J..." . .-=:::'."-.:". ';.):..:: >:-..{;.. '.::.,i...: . :. .:. .'0. :....". ..' .' :'> .1t.,,_ « , ., .","« л a rI' 181 ... о,' \ "'' f I ALS ....... .. nrltflf . t t ..l!ay!.u.:...: I & .... 1 1 '" 1+ .. . . ""CIIU 1.1111 "'4." ' ., JJdJO NI.' . .. '. . ...... .. AND..z . ' ;"о . О' оно /t.... jOtS Ф OIlS ;; .. ... .". ::. -< .: ,,",..;.121: 114ulI: 114.16111" . 'ем., ()(I: 160111 !. с.... 1 OelU: ..5.1....1 , L r  -.l , t , . .._.__... о.. ."" .... ....._............ .. ......... ................. ..._.. ................. _х= l' I  1 I I I I х: "..f ....................... . ... - -. I .. ........ .............._...... .... ....... о.. .._......... ........ , 'х: , t NCmIIN(; 5ШСТШ "ze 1.... псtt sdм...uc: H2. ..' :. '. . .":_  . 0'0 _ "':-";'" _," '., .'. ':._ . :.'".. CIIiO ,: Рис. 3.23. Окончательный результат наблюдения посмотреть в Приложении. В системе «Умный дом» распреде- ление видеосиrнала по всем помещениям, естественно, сопро- вождается распределением управления (рис. 3.24). Как это может выrлядеть? Из приведенной схемы ясно, что DVDпроиrрыватель, расположенный в rостиной, управляется дополнительно из спальни и кухни. Не вдаваясь в детали устройства видеокоммyrатора, я хочу предложить вам рассмотреть следующий сценарий. Простуда уложила вас в постель. Пользуясь случаем, вы ретили посмотреть новый фильм, который купили накануне. Уютно расположившись в спальне, вы смотрите фильм, а дo матние, чтобы не беспокоить вас, досматривают очередную серию очередноrо сериала на кухне. Серия закончилась. Вати доматние вспомнили о фильме, который собирались посмотреть вчера и даже установили в проиrрыватель, но не успели посмотреть. Они нажимают на пульте управления кнопочку DVD и... Как и положено, 
308 rлава . 3 То, что рядом с «Умным ДОМОМ» к телевизору в спальне к телевизору на кухне Блок питания =128 к выходу DVD  Фотоприемник " в спальне Модуль видео коммутатора Модуль приема ИК команд Системная сеть Конвертер RS2З2RS485 Модуль излучения ИК команд Модуль приема ИК команд  ИК светодиод на DVDпроиrрывателе в rостиной  Фотоприемник " на кухне Рис. 3.24. Подключение DVDпроиrрывателя ктелевизорам команда power, воспроизводимая модулем излучения ИКко манд, выключит DVDпроиrрыватель на самом интересном месте, коrда интриrа фильма заставляет вас забыть о просту- де. Система «Умный дом» в данном случае позаботится о том, чтобы вам о ней напомнить. Но я знаю, что вы человек предусмотрительный, и, хотя нет единоrо мнения, как лучте орrанизовать работу уст- ройств, управляемых из разных помещений, вы предусмот рели в nporpaMMe управления подобную ситуацию, нарисо вав, например, алrоритм управления, представленный на рис. 3.25. Но к телевизору вы можете подключить и видеомаrнито- фон, а также использовать телевизор в качестве акустической зоны, подключая ero к музыкальному центру. В этом случае алrоритм усложнится. Этому будет способствовать и наличие большоrо количества помещений с развитой системой средств управления и устройств, управляемых из разных по- мещений. После завершения проrраммы управления системой она приводится в действие. При этом трудно разобраться во всех сложных ситуациях. Конечно, вы постарались предусмотреть 
Сопряжение управления 309 Нажата клавиша DVD да Подключиться к DVD Включить DVD. установить флаr Переключитьвидео коммутатор Рис. 3.25. Алrоритм управления DVDпроиrрывателем все, коrда разрабатывали алrоритм управления. Но все ли вы предусмотрели? В аналоrичной ситуации я поступаю следующим образом. Нарисовав алrоритм, я проверяю ero с помощью вспомоraтель ной проrраммы, для создания которой можно использовать любую современную среду проrраммирования. Я использовал Delphi и KDevelop с одинаковым успехом. Можно воспользо ваться любой средой проrраммирования и любым языком. Единственное, как мне кажется, важное условие  леrкое co здание rрафических примитивов и управление их свойствами. В данном случае проrрамма не будет конечной целью, она  лишь средство избавить вас от сомнений в правильности при нятоrо решения. Проrрамма, в сущности, описывает ваш алrоритм, а rрафи ческая часть изображает устройства управления, управля емые устройства, возможно, флаrи и переменные. Выrлядеть работающая проrрамма может, как показано на рис. 3.26. На рис. 3.26 изображены устройства управления и управ ляемые устройства, которые при включении меняют цвет, флаrи и т.д. 
310 rлава . 3 То, что рядом с «Умным домом» , _ npuo.... п.,.. Сеет... . . 11 .  8ТJI, ZI М-..:za . -. - . . ." ..... :...'..... ...;......... ,."0... ;...........'.. ",- fi1Sf' :<}1 . ....)..: .' . нome CInema w:.я kl1l<T -"::.:;: r ", ЕI ,." ,i' ",. ..... .:: '}:;,:; .. :.:t' r  ' щ O,oyn,:.:'! i Ш ; :;. ' l\:"QVQ.:,:: f ; "','f:',., : :... "": Y:"";''<':C{ >:"" ",БVo'Inus 'DVO l ' .' ..rмjт' ! }LE t. :.: /   '.' = h -: ;;',; a ОУО t : : l: ::'j i;;"'тv M ! !e;; :'l: f  ( . :: .  . '4In ,  . , . _" . : .  . OVD " '  ' " ' , ' " " " " . ' . -",,::' "..:t 4-;: .:".:::..:1'":; -t--:.-,: x;':'.., '::'::" ..-. ::.";;....):; _: '"'? .,;....... .- . .,';.Ф.:' .--::., :;:::".:.: ......... "'. . '," .,." ";;.:.;-::H''-,".:":-' -::.',..:::"v,.::_:.:::" ....-:.<:....""'::.. .: "-::'"":..:"'.:.: jri. "J ::.:m't.:..:'....;,:_ Кор и.а .' '1 ... 'p0d!50. fWl пun. prajslpod!O'Sltlpad:I; &11. КDe.., 110..< ...-: . CIIIA Рис.'З.26. Проверка алrоритма управления Ниже я привожу фраrмент проrраммы, чтобы по казать, что в ней используются только rрафические примитивы и изменение их свойств. Написать такую nporpaMМY не соста- вит труда. void test: :cinТVONSlot () { cinТV = true; cinNТV = true; cinAVproc = true; cinAVprocf>setBackgroundColor("Red"); // AVprocessor Cinema cinntvf>setВackgroundColor("Red"); // NТV Cinema cintvf>setВackgroundColor("red"); extroneqipl>setText("EXTRON\n NТV>Cinema"); extroneqipl>setBackgroundColor("red"); // EXTRON NТV Cinema projequip>setText("Projector\n NТVComposit"); projequip>setBackgroundColor("red"); av......Procequip>setВackgroundColor("red"); av......Procequip>setText("AV Processor\n NТVЗD"); 
Сопряжение управления 311 Light>setBackgroиndColor(IBlack"); } void test::cinТVOffSlot() {if (cin.....AVproc) { cinAVproc = false; cin.....AVprocf>setBackgroиndColor(ILightGrey"); // AVProcessor cin'IV =false; cintvf>setText ("cinтv") ; cintvf>set13ackgroиndColor (ILightGrey"); / / тv cinNТV = false; cinntvf>setText (lcinNТV") ; cinntvf>setBackgroundColor(ILightGrey"); // NТV extroneqipl >setText ("EXTRON") ; extroneqip1>setBackgroиndColor(ILightGrey"); extroneqipl>setText("EXTRON\n NТV>Cinema"); //Extron Cinema projequip>setText("Projector\n NТVComposit"); projequip>setВackgroиndColor(ILightGrey"); av.....Procequip>setText ("AV Processor\n NТVЗD") ; av.....Procequip>setВackgroиndColor(ILightGrey"); Light>setВackgroundColor(IWhite"); if (cinDVD) { cinDVD = false; cindvdf>setBackgroиndColor("LightGrey"); // DVD DVDinиse = false; dvdinиsef>setBackgroиndColor ( "Yellow" ); / / DVD dvdequip>setText ( "DVD" ) ; dvdequip>setВackgroиndColor(ILightGrey"); } if (cinVCR) { cinVCR = false; vcrequip>setBackgroиndColor(ILightGrey"); vcrequip>setText ( "VCR 11 ); / / VCR } if (cinCD){ cinCD = false; cincdf>setBackgroиndColor(ILightGrey"); // CD CDinиse = false; cdinиsef>setBackgroиndColor(IYellow"); // CD cdequip>setText ("CD") ; 
312 rлава . 3 То, что рядом с «Умным домом» cdequip>setВackgroundColor("LightGrey"); } } } void test::cinNТVonSlot() { if (cin'IV) { if (!cinDVD) { cinNTV = true; cinntvf>setBackgroundColor ("Red"); / / NТV Cinema extroneqipl>setText("EXTRON\n NТV>Cinema"); extroneqipl>setBackgroundColor("red"); // EXTRON NТV Cinema projequip>setText("Projector\n NТVComposit"); projequip>setВackgroиndColor("red"); av.....Procequip>setText("AV Processor\n NТV3D"); // 3D sound } else { cinNТV = trиe; cinntvf>setBackgroиndColor ("Red"); / / NТV Cinema cinDVD = false; cindvdf>setBackgroиndColor ("LightGrey"); / / DVD DVDinиse = false; dvdinusef>setBackgroиndColor ("Yellow"); / / DVD extroneqipl>setText("EXTRON\n NТV>cinema"); // Extron Cinema projequip>setText("Projector\n NТVComposit"); av.....Procequip>setText("AV Processor\n N'IV3D"); // 3D .sound dvdequip>setText ("DVD") ; dvdequip>setBackgroиndColor ("LightGrey"); / / DVD } } } void test::cinDVDonSlot() { if (cin'IV) { if (!DVDinиse){ cinNTV = false; 
Сопряжение управления 3 1 3 cinntvf>setBackgroиndColor("Light Grey"); // DVDinuse = trиe; dvdinиsef>setBackgroиndColor("red"); // DVD cinDVD = trиe; cindvdf>setBackgroиndColor("red"); // DVD dvdequip>setBackgroиndColor("red") · dvdequip>setText ("DVD for cinema"); / / .DVD av.....Procequip>setText("AV Processor\n DVDDoIby"); av.....Procequip>setBackgroиndcolor("Red"); // DVD DolbyDigital projequip>setText("Projector\n DVDSvideo"); // DVD } else{ cinNТV = false; cinntvE>setBackgroиndColor("Light Grey"); // av.....Procequip>setText ("DVD") ; av.....Procequip>setText (" AV Processor\n DVDDoIby"). / / DVD DolbyDigital projequip>setText("Projector\n DVDSvideo"); // DVD } } } void test::cinDVDoffSlot() {if ((cinТV)&&(!cinVCR)&&(!cinCOMP»){ if (cinDVD) { cinNTV = true; cinntvf>setBackgroиndColor ("Red"); / / NТV Cinema cinDVD = false; cindvdf>setBackgroundColor("LightGrey"); // DVD DVDinиse = false; dvdinиsef>setBackgroиndColor("Yellow"); // DVD projequip>setText("Projector\n NТVComposit"); av.....Procequip>setText("AV Processor\n NТV3D"); // ЗD sound dvdequip>setText ("DVD") ; dvdequip>setBackgroиndColor(LightGrey"); // DVD } При нажатии клавиши пультов управления я «включаю И выключаю» устройства (меняю цвет), устанавливаю и сбрасы ваю флаrи  словом, контролирую свое нехитрое хозяйство. 
314 rЛQВQ . 3 То, ЧТО РЯДОМ с «УМНЫМ ДОМОМ» Запустив проrрам я начинаю беспорядочно щелкать по всем клавишам устройств управления. Моя задача  проверить не возникает ли тупиковая ситуация, подобная описанной выте, при какихлибо управляющих сиrнадах. Используя этот нехитрый прием, я убедился, что допускал ошибки в алrорит- мах даже после их тщательной проверки на бумаrе. В первую очередь, это ошибки, которые я называю для себя отибками последовательности действий. Описывая алrоритм, зачастую укрупняеть операции. Например, в алrоритме, приведенном выте, я записал включить DVD, установить флаr. В действи- тельности команда включить DVD распадается на ряд команд, каждая из которых может ветвиться: вывести устройство из режима ожидания, открыть лоток для установки диска, зак- рыть лоток, включить меню, выбрать из меню режим про- смотра и т.д. Каждому действию соответствует своя последо- вательность нажатия клавит на пульте. Коrда «крутить» алrоритм на бумаrе, леrко проrлядеть возможные ветвления и отибки в последовательности. Особенно, если работа, как это часто бывает, происходит в условиях дефицита времени. Использование проrраммы для проверки проrраммы (воз можно, есть математические методы, решающие эти пробле- мы, но нет времени с ними разобраться) позволяет до введе- ния в систему неких действий проверить, не приведyr ли они к нежелательным результатам. И удалить, как минимум, тупи ковые ситуации. Сами по себе эксперименты в этой области достаточно интересны. Но, если вы от экспериментов перетли к дей- С,твиям, не забывайте, что выявление дефектов в действую- щей системе сложнее, чем на стадии проекта. Возвращаться к уже сделанному, коrда первоначальный интерес сменился желанием пользоваться системой без проблем, совсем не xo чется. А раздражение, которое может вызывать «поехавшая крыта YMHoro дома», не стоит нескольких дополнительных усилий, приложенных в начале работы. Кроме Toro, вы все делаете для себя. Я уже rоворил, что не все придерживаются точки зрение, что сопряжение уп- равления следует делать. Вам тоже, возможно, это покажется 
Смешанные системы 31 5 литним. Соrласен. Но прием, о котором я рассказал, может быть полезен и в дрyrих случаях. СмеwаИИЬlе систеМЬI Вы завершили эксперименты с модулями, предложенными в начале книrи, и отважились на создание собственной систе мы на базе этих модулей. Вы все тщательно продумали, опро бовали, реализовали. Осталось насладиться результатами. Но вот беда  вам приrлянулся уrловой диван для rостиной, по нравилось, что у Hero есть бар и полка, на которую можно положить роман для чтения на сон rрядущий. В полке есть лампочка, которую вы включаете, коrда читаете роман. Розет ка для включения лампочки есть, выключатель разместился на проводе, включаемом в розет Но вам не нравится, что этот выключатель вы не можете добавить в систему. Это раз дражает всякий раз, коrда вы им пользуетесь. Вместе с тем, вам не нравится идея прокладывать новые провода к дивану. Вы только завертили про кладку проводов. Как поступить в этом случае? Есть разные пути ретения  использовать радиоканал, ИКканал для передачи команд управления. Если же вдобавок вы хотите использовать возможности управления яркостью, но не хотите самостоятельно изrотавливать диммер, то самое лучшее ретение  применить устройство дрyrой системы. Об этом я хочу рассказать HeMHoro подробнее. Если вам приходится использовать устройства дрyrой сис темы, в первую очередь, вам помоryr специалисты, представ ляющие продукцию той фирмы, на которой вы остановили свой выбор. Например, вы используете систему X10, но в каче- стве основной панели управления хотите использовать COBp менную красивую сенсорную панель фирмы Crestron. Уверен, специалисты фирмы, у которой вы приобрели оборудование X10, возможно, проектировали вашу систему, и помоryr вам в этом. Так фирма «Умный дом» предлаrает больтое колич ство устройств Х1 О, но одновременно она представляет и пр дукцию Crestron. 
316 fЛQВQ . 3 То, что рядом с «Умным домом» Но вернемся к «суете BOKpyr дивана». Вы не хотите менять всю систему, но желаете использовать модуль Х1 о. В этом слу. чае я советую использовать компьютерный интерфейс для управления этим модулем. Интерфейс будет включен, если вы используете управляющую проrрамму на компьютере или любом удобном месте, воспользовавшись прямой связью мо- дулей в системе. Для ретения проблемы управления модулем X10 вам по- требуется дополнительно подключить конвертер RS485 RS232 к системной сети, а к нему  интерфейс компьютера для системы X10. Использовать при этом придется систему команд протокола X10. В некоторых случаях дополнительные устройства MOryт работать по интерфейсу RS485. Если известна система ко- манд управления этим устройством, то трудности при интеr рации устройства в систему, сделанную своими руками, не должны возникнуть. Если система команд не известна, но команды управления достаточно просты, можно попытаться «подсмотреть» команды управления. Используя любую про rpaM работающую с СОМ-портом, rотовую или написанную самостоятельно на основании тех рекомендаций, что есть в книrе, подключите компьютер через конвертер RS232RS485 к линии и подайте команды от WTaTHoro устройства управле- ния. Проrрамма для СОМ-порта должна работать на чтение сиrналов линии. Такой нехитрый прием позволяет узнать команды управ- ления, которые можно использовать вдальнейтем. Иноrда отсутствие команд управления не связано с тем, что они скрываются изrотовителем оборудования. Скорее, оборудова- ние, которое вы хотите использовать в своей системе, пред- назначается для использования в друrой системе. Или прото кол работы слитком сложен для быстроrо повторения вне системы. В последнем случае, если вы располаrаете достаточ- ными финансовыми возможностями, ват опыт работы позво- ляет разобраться с этим, а интерес к экспериментам выше желания повторять rOToBbIe решения, то эксперименты с включением сенсорных панелей в систему MOryт оказаться 
Смешанные системы 3 17 очень увлекательными. При этом желательно, но не обяза !ельно, проводить их с панелью, связанной с системой интер фейсом RS485. В этом случае вы можете использовать все рекомендации, описанные в книrе. Вообще вопрос использования в самодельной системе yc ройств друrих систем связан с протоколом их работы. Здесь все зависит от Bamero опыта, знаний, желания разобраться во всем и, конечно, финансовых возможностей. Применение в системе сенсорных панелей необязатель но. Они не дают выиrрыта в надежности, несколько pac тиряют возможности в отображении информации. Но и ca мые детевые сенсорные панели, которые мне доводилось видеть, несомненно, украсят систему. Любая, даже очень сложная, система «Умный дом» в идеальном варианте не видна. Она спрятана в силовых или слаботочных шкафах, укрыта в мебели или встроенных в стены стойках. Един ственное, что остается на виду,  устройства управления. В этом смысле современные сенсорные панели MorYT YKpa сить комнату. По ключевым словам «HomeAutomation» в поисковых сис темах Интернета можно найти MHoro доматних страниц, посвященных созданию систем доматней автоматизации. Некоторые авторы приводят подробное описание своих про ектов, схемы, проrраммы, включая исходные коды. Что-то из сделанноrо дрyrими любителями может прийтись вам по душе. Или один из проектов увлечет вас. Например, есть описания управляющих проrрамм, не уступающих профес сиональным, а вы не стремитесь к созданию собственной проrраммы. Или проект не имеет некоторых модулей, KOTO рые есть в вашей системе, а ориентирован только на куплен ные модули дрyrой системы. Опять речь идет о смешанных системах. И все, что сказано выше, применимо к смешанным системам любительскоrо диапазона. Применение друrих любительских разработок открывает значительно больше возможностей, чем использование куп ленных устройств. Я имею в виду, что любители всеrда най дут возможность поддержать друr друrа, помочь друr друry. 
318 rлава . 3 То, ЧТО рядом с «Умным домом» KTOTO хорото разбирается в проrраммировании, кому"то леrче работать с аппаратурой. Совмстными усилиями вы быстрее и лучте выполните любой проект. В этом смысле сметанные системы в любительской практике,  скорее, пра- вило, чем исключение. раэныe nOДXOAbl к реапиэаqии системы rоворя о сметанных системах, я упоминал друrие системы, но не рассказывал о них. Приведу фраrмент статьи, воспол- няющий этот пробел. Вначале  коммуникации в системе автоматизации дома. Для создания работающей системы автоматизации дома мы должны растирить управление оборудованием дО КОН- KpeTHoro устройства, KOHKpeTHoro места или уровня замкну- той цепи. Чтобы сделать это, необходима некоторая точка сосредоточения, осуществляющая сетевое взаимодействие и позволяющая командам и данным перемещаться между сис- темными компонентами. Ком"анды должны иметь возможность достиrать оборудо- вания везде в доме, rде бы оно ни располаrалось. Наиболее развитые системы автоматизации дома осуществляют двух" стороннюю связь, допуская обратную связь от управляемоrо устройства к контроллеру или проrрамме. Есть несколько схем системной коммуникации, каждая СО своими достоинствами и недостатками. Самые лучшие систе- мы автоматизации дома используют системный центр, кото- рый объединяет несколько типов соединений, зависящих от выбранноrо оборудования и ero использования. Наиболее общие типы системных центров включают: . типовую проводку В доме; . несущие силовых линий; . коаксиальный кабель; . специализированные соединители витых пар; . низковольтную проводку; . беспроводные радиочастотные сиrналы; 
Разные подходы к реализации системы 319 . беспроводные инфракрасные сиrналы; . оптический кабель. Если вы хотите использовать типовую проводку дома в качестве системной основы, вати возможности будут He сколько оrраничены, но все же в ватем распоряжении OCTa нется достаточно MHoro функций, предназначенных для автоматизации. Добавив модули контроллеров со специальны ми возможностями коммуникаций по силовым проводам, или используя беспроводные связи, вы сможете интеrрировать значительное количество оборудования в автоматизирован ную систему дома со значительным объемом централизован Horo управления. Но что вы сможете сделать без использования этих воз можностей? Без изменения имеющейся проводки? Обычно управление оборудованием и автоматизация оrраничены в возможностях управлением, которое было включено в обо рудование. Например, телевизор и видеомаrнитофон MOryT управляться с переносноrо пульта, микроволновые печи имеют встроенные возможности проrраммирования, а сис тема полива имеет свой собственный проrраммируемый контроллер. Вы можете также заменить старые «rлупые» устройства такими же, но «разумными». Так, термостат с ручной установкой может быть заменен проrраммируемым термостатом, а выключатель с детектором движения может сменить старый ручной выключатель. Некоторые из этих разумных устройств MOryт поставляться с приспособления ми беспроводноrо управления, хотя все это, в основном, работает только с конкретным устройством или нескольки ми подобными. Принципиальным оrраничением стандартной проводки является то, что без дополнительных коммуникационных воз можностей управление оrраничено конкретными устройства ми. Оrраничен эффективный радиус действия удаленноrо управления. Например, вы можете использовать переносной пульт управления для управления ли проrраммирования видеомаrнитофона, но он работает, только если видеомаrни тофон расположен так, что может получить инфракрасный 
320 fлава . 3 То, ЧТО рядом с «Умным домом» сиrнал от пульта  вы не можете управлять маrнитофоном из друrой комнаты или с дрyrоrо этажа. Система X10 использует стандартизованный протокол и множеств команд, поддерживающих множество задач авто- матизации. Она реализуется на коммуникациях силовых ли- ний, накладывая сиrнал с высокочастотной несущей (120 кrц) поверх 60 rц (или 50 rц) несущей силовой линии. Х1 О контроллеры MOryr включаться в любом месте домаш- ней проводки. Команды от контроллеров передаются через внутреннюю питающую сеть и не оrраничены какой-либо ттатной длиной цепи (межфазовые мосты позволяют сиrна- лам переходить с фазы на фа,ЗУ обычной трехфазной сети). Специальные блокирующие устройства MOryr быть установле- ны в силовом ткафу для оrраничения перемещения сиrналов X10 вне системноrо пространства, в дрyrие дома или поме- щения с той же силовой цепью. Любые команды посылаемые контроллерами X10 по ДО- матней проводке будyr получены всеми ХlО-приемниками или модулями в этой системе. Некоторые модули MOryr не только принимать, но и отправлять сиrналы. Коrд модуль получает команду, он ПFореряет «адрес», до- бавляемый к команде,  не ему ли она адресована. Если коман- да предназначена друrому модулю, команда иrнорируется. Коrда соответствующий модуль получает KOMaH он действу- ет соrласно ей, включая или выключая что-либо, уменьшая яркость света, пересылая команду друrому устройству и т.д. Команды X10 оrраничены множеством из 16 команд, на- зываемым cтaидapтиъt.М, фуu'К'Цuо'Но.лъ'Нъt.М м'Ножеством. Однако больтинство модулей распознает только базовое функцио- нальное множество из семи команд. Были также развиты растиренные пакеты кодов для уве- личения функциональности при передаче, полезные для сис- темы автоматизации дома при управлении такими подсисте- мами, как управление климатом, охранная, аудио и т.д. Однако изза природы технолоrии X10 это снижает быстродействие, увеличивая количество циклов питающей сети, используемых для передачи дополнительной информации. 
Разные подходы к реализации системы 321 Коды адресации описываются 4битовым кодом «дома» (буквы AP) и 4битовым кодом «устройства» (номера l 16)  A-I, A7, c 14, C9 и т.д. Для активизации одноrо или более модулей на выполне вме функции пакеты сообщений с кодом «дом/устройство» передаются' всем модулям, которым команды предназначе вы. Это «оклик» модулей. Затем отправляется друrой пакет сообщений с описанием кода функции. Выбранные одули выполняют эти функции. Модуль «освобождается» после при хода кода функции, если первое полученное сообщение с KO дОМ «дом/устройство» адресуется не ему, или если это функ ция  «все выключить». Два наиболее общих типов модулей Х1 О  модул'и управ пения освещением и управления бытовыми электроприбо рами. Модули управления освещением обычно управляют активной наrрузкой, например лампами накаливания, и MO ryт включать и выключать их или реryлировать яркость CBe чения. Модули управления бытовыми приборами использу ют реле для включения и выключения присоединенных К ним устройств. Контроллеры Х1 О MOryт быть отдельными подключаемы ми устройствами или соединяться проводами в систе He которые из них просты, только С несколькими основными функциями управления, тоrда как друrие MOryT содержать встроенные таймеры, часы и возможности доступа к телефо ну. Контроллеры обычно имеют встроенные клавиши, ци ферблаты и т.д., чтобы осуществля'ть пользовательский ин терфейс с системой. Друrие устройства, добавленные для улучшения системы X10,  это радиочастотные (RF) и инфракрасные (IR) KOH троллеры и модули. Они используются как вспомоrательные в ситуациях, не перекрываемых технолоrией передачи по силовым проводам. Например, охранная система может за действовать радиочастотные датчики для дверей и окон. KOH троллер «базовая станция» получает радиокоманду от датчи ка, переводит ее в команду Х1О и отсылает в силовую сеть. Естественно, расширение полезности системы Х1 О подобным 
322 rЛQВQ . 3 То, что рядом с «Умным домом» образом влечет за собой ее удорожание и увеличивает слож- ность без какоrолибо улучшения в части надежности. В самых больших системах MOryт потребоваться повтори- тели, коrда ослабление сиrналов становится проблемой. Система Х1 О достаточно дешевая и леrко устанавливаемая, поскольку большинство ее компонентов используют имеющу. юся в доме процодку как среду связи. Однако есть некоторые неудобства: u U . для силовых линии характерен «шум», уменьшающии возможности передачи; . тополоrия проводки часто неизвестна, особенно для старых проводок; . ослабление сиrналов в силовой сети непостоянно и час- то непредсказуемо, что оrраничивает возможности пе- редачи; . друrие технолоrии MOryт одновременно использовать силовые линии для коммуникации и взаимодействовать с коммуникациями X10; . более оrраниченное множество команд, чем у друrих технолоrий; . скорость передачи данных низкая, оrраничивается при- менением в тех случаях, коrда время не критично, и неважна передача больших объемов данных; . требует, по меньшей мере, одноrо передатчика (кон- троллера) для передачи или «ввода» сиrнала в силовую про водку, а также отдельный приемник (системный интерфейс) для каждоrо управляемоrо оборудования или цепи; . некоторые плохо продуманные устройства XIO MOryт иметь коллизии при совместных передачах. Новые улучтения в технолоrии XIO увеличивают воз- можности системы, но и являются источником проблем. Исполнение этой технолоrии довольно трудно поддается усовершенствованию  требует дополнительных затрат и сложности, что противоречит назначению системы X10: детевой системы, которая одинаково хороша для большин- ства нужд домашней автоматизации. 
Разные подходы к реализации сиСтемы 323 Новые модули XIO все время развиваются для расшире ния Kpyra задач. Как правило, они MOryт быть передатчика МИ, приемниками или приемопередатчиками, MOryт разра батываться для управления специфическими типами оборудования. Итак, что может делать модуль? Вот непол ный список: . переключение  включать и выключать сетевые устрой- ства, такие как лампы; . реryлировка уровня/ скорости  непосредственно pe ryлировать яркость света и управлять скоростью дви rателей; . теле/аудио/видеоконтроллеры  посылают специ альные команды друrим устройствам: телевизорам, ви деомаrнитофонам, радиоприемникам, аудиоустрой ствам и т.д.; . ХlОсовместимый термостат может показы1атьь темпе ратуру; . датчик освещенности, датчик температуры, датчик ветра; . управление открыванием/закрыванием; . автоответчик и т.д. Некоторые ведущие производители оборудования X10  Honeywell, Leviton, Advanced Control Technologies, IBM, и X10 USA Стандарт CEBus позволяет использовать множество ceTe вых сред, ВЮIючая: . витые пары; . коаксиальный кабель; . инфракрасные сиrналы; . радиочастотные сиrналы; . оптоволоконные сиrналы; . сиrналы по силовым сетям; . аудио/видеошины. Коммуникационное оборудование CEBus, язык и прото кол реализованы на микросхеме, сделанной фирмой Intellon Corporation, Ocala, Florida. Intellon продает микросхему 
324 rЛQВQ . 3 То, что рядом с «Умным домом» производителям для встраивания в их разработки. Intellon может также производить специальные ОЕМ CEBus продук- ты и средства разработки. Системы автоматизации дома CEBus MOryr устанавливать- ся в жилом доме с использованием существующей проводки 110 В или 220 В для обмена данными. В случаях, коrда'это не оптимально для передачи данных, например в случае видео сиrналов, предлаrаются дополнительные возможности, осо- бенно там, rде проводная связь не слишком удобна или слиш- ком дороrа. Для целей удаленноrо управления обычно ис пользуются инфракрасные или радиоканалы. Технолоrия CEBus может встраиваться в конкретные бытовые приборы или устройства удаленноrо управления, включаемые в сете- вую розетку. Стандарт CEBus включает такие технолоrии, как спект- рально модулированный поток в силовых линиях. Спектраль ный поток начинает модуляцию на одной частоте и изменяет ее за время цикла. Начиная сиrнал с частоты 100 кrц, ero ча- стоту линейно увеличивают до 400 кrц за период 100 МКС. иrнал (<<высокое» состояние) и отсyrствие сиrнала (<<низкое» состоние) MOryr воспроизвести простейшие цифры, поэто- му пауза между ними не требуется. Лоrическая «1» может воспроизводиться отсутствием (или наличием) сиrнала в течение 100 мкс. Лоrический «О» воспроизводится отсутствием (или наличием) сиrнала в те- чение 200 мкс. Это означает, что длительность передачи переменная и зависит от количества «}» или «О». Вне зависимости от используемой среды в CEBus управля- ющие данные канала транслируются со скоростью 8000 бит в секунду. Среда также может нести канальные данные. Про- пускная способность будет зависеть от возможностей среды. Управляющие сообщения CEBus всеrда имеют один формат. Сообщение содержит адрес получателя, но не имеет инфор- мации о маршруте, так что получатель может быть rде уrодно в сети, в любой среде. Управляющие каналы CEBus несут сообщения о статусе и команды. Эти сообщения состоят из строк или пакетов байт 
Разные подходы к реализации системы 325 данных, которые MOryr иметь переменную длину, зависящую от количества данных в сообщении. Пакеты MOryr быть в COT ни бит длиной. Минимальный размер пакета  64 бита. Он занимает промежyrок времени 1/117 с на передачу и прием. Есть команды для назначения каналов данных, но в значи- тельной мере стандарт CEBus заботится о спецификации уп равляющих каналов. Включение каналов данных не специфи цировано в стандарте CEBus. Адрес устройств устанавливается аппаратно при произ водстве и допускает 4 млрд. комбинаций. CEBus имеет также определения языка объектноориентированноrо управления, включающеrо такие команды, как увеличить уровень, быстро вперед,перемотать,пауза,пропустить,температуруподнять или опустить на один rpaдyc и т.д. Сообщения MOryr быть адресованы (посланы) KOHKpeTHO му устройств Может использоваться и специальная aдpeca ция для обращения ко всем устройствам сети или некоторой rруппе устройств. Адреса бывают индивидуальными или rрупповыми. Устройства MOryт принадлежать более чем к одной rруппе. Заметьте: не все CEBus совместимые устрой ства поддерживают rрупповую адресацию. Это определяетсS;l производителем и моделью. Технолоrия CEBus позволяет устройствам располаraться в . любом месте сети на любом расстоянии, независимо от среды, если они имеют соответствующий ДЛЯ нее СЕВusинтерфейс. Сообщения, посылаемые из среды одноrо типа в дрyryю, пр ходят через маршрyrизирующую цепь. Мартрyrизатор может быть отдельным устройством или интеrрироваться в бытовой прибор. Управляющие сообщения распределяются между CEBusyc тройствами и маршрутизаторами. Централизованный KOH троллер не применяется для управления доставкой. Никакая специальная тополоrия в CEBus не стандартизируется. Все точки соединения управляемых устройств в среде обрабаты ваются лоrически так, как если бы они были на той же шине. Это означает, что все управляемые-устройства в каждой среде чувствуют поступление пакетов данных одновременно. Все 
326 rлова . 3 То, что рядом с «Умным домом» устройства прочитывают адрес получателя в сообщения, но только те, кому они адресованы, получают остальную часть со- общения и отвечают на нее. Соблюдаются требования по аудио/видео, но специфика- ции совертенно не были реализованы в ЕIA. Они описывают мноrоконтроллерную шину, состоящую из восьми витых пар. Она разработана для BнyтpeHHero соединения rруппы домaIП- Hero оборудования в небольтом пространстве (в одной КОМ- нате). Максимальная длина кабеля  30 футов. Кабель несет три аудиоканала, четыре видеоканала и управляющий канал. Единственный разъем используется для подключения кабеля к управляемому устройств Вотнотении коаксиальноrо кабеля CEBus определяет двухкабельную систему. Один кабель присоединяется к источ. никам сиrнала в доме (камеры, маrнитофоны и т.д.) , а дрyrой используется для распространения сиrнала к любому прием- нику в системе. Любые внешние видеосиrналы MOryr комби- нироваться с сиrналами от источников в доме. Система Echelon базируется на наличии разумно управля- емых устройств (узлов). В системе Echelon, также называемой LопWоrksсетью, соединение между устройствами может быть либо одинкодному (распределенное управление), либо ведущийведомый (централизованный контроль). Об- щий протокол используется в обоих случаях. Какой бы вариант ни ИСПОЛЬЗ0Вался (централизованный или распределенный), каждый узел имеет высокий уровень встроенной разумности. Компьютерные возможности узлов допускают распределение функций процесса по всей систе- ме. Например, температурный датчик на Echelon технолоrии может быть предварительно запроrраммирован для анализа прочитанной локальной температуры и фильтрации резуль-. татов, так что к центральному контроллеру или дрyrому узлу будут направляться только определенные изменения. ФунК- ции управления тоже MOryr распределяться по всей системе, обеспечивая наилучшую производительность и надежность. Узлы соединяются один с дрyrим на основе равноправия, используя общий протокол. Каждый узел содержит BнyrpeH- нюю разумность, поддерживающую протокол, управляющие 
Разные подходы к реализации системы 327 ФУНКЦИИ и функции процесса, а также включает интерфейс BBoдaBЫBoдa, который присоединяет микроконтроллер узла к коммуникационной сети. В каждом узле больтинство этих возможностей реализовано на одной микросхеме, называе мой Нейрончип, и производимой в нескольких версиях фир мами Motorola и Toshiba. Технолоrия Echelon Lon Works явля ется открытой, но патентованной. Подход Echelon не предусматривает использования имею щейся проводки для коммуникации. Соответственно, требу ет дополнительной проводки при установке, что избавляет от проблем и оrраничений, связанных с применением сило вой проводки, как в системах подобных X10. Передача идет MHoro быстрее и значительно надежнее, не требует интер фей са подключения к силовой сети, не зависит от постоян ных или меняющихся условий в проводке. Вдобавок, Echelon не оrраничено никакими исключительными типами сетевых коммуникационных проводок/ соединений. Допустимо мно- жество передающих и соединительных устройств. Поддержи вается вход в Ethernet, Тl, Х.25, Bitbus, Profibus, СЛN, Modnet, SINEC, Grayhill, Opt022 (digital), OptoMux, Modbus, ISA bus, STD32 bus, PC/104 bus, УМЕ bus и ЕХМ bus. Встроенные возможности Нейрончипа предлаrают ши- рокий Kpyr вычислительных и разумных функций, осуществ- ляемых на локальном уровне, но технолоrия Echelon Lon Works не оrраничена процессами узловоrо уровня, она поддерживают также возможность работы с хостприложе- пиями, которые работают на иных процессорах, чем любой из Нейрончипов. Должен быть компонент микропроцессо ра, который использует Нейрончип в качестве коммуника ционноrо сопроцессора или Wiпdоwsориентированный персональный компьютер, который связан с системой через серийный порт или адаптер РС. Эти прилоения позволя- ют добавить в систему серверы, консоли или мониторы, и MOryT про водить централизованное управление для не pac пределенных систем автоматизации. Они также предназна чены для переноса имеющихся приложений, работы утилит сложноrо ceTeBoro управления и создания входов в друrие системы. 
328 rЛQВQ . 3 То, что рядом с «Умным домом» Типичный узел в системе Echelon предназначен для про- стых задач. Такие устройства, как датчики приближения, пе- реключатели, диммеры, датчики движения, реле, контролле- ры моторов, maroBbIe двиrатели и т.п., MOryT быть узлами сети. Объединенное множество коммуникационных узлов создает супермножество сложных функций управления, тре- буемых для автоматизации дома. В системе Smart House управляющие сиrналы для быто- вой техники, информация о состоянии, данные сообщений приходят по одному каналу и используют тот же самый про- токол. Исключение составляют видеосиrналы и телефонные данные. Базовая тополоrия состоит из звезды с ветвями, относящи- мися к. электрическим ответвлениям цепей. В концентрато- ре звезды находится системный контроллер, который обыч- но располаrается в непосредственной близости от сетевых выключателей электросистемы дома. Системный контроллер включает бесперебойное питание, экранирование от наво- док, GFI, телефонный ввод и наконечник для коаксиальноrо кабеля. Системный контроллер выполняет следующие задачи: . обслуживание системы; . пересылку данных бытовым приборам; . планирование обслуживания. Все пересылаемые сообщения поддерживаются систем- ны1M контроллером. Smart House имеет специализированный формальный язык для управления приборами и сообщений о состоянии. Система Smart House базируется на трех rруппах кабелей или типах: . ответвляющих кабелях  силовых и цифровых; они со- стоят из силовоrо кабеля и отдельноrо цифровоrо кабе- ля (четырехпарноrо, витоrо); одна витая пара  для дан- ных, друrая  для передачи сиrнала синхронизации, а оставшиеся две не используются или MOryr быть ис пользованы для отдельных ветвей; 
Разные подходы к реализации системы 329 · прикладных кабелей  постоянное напряжение для дaT чиков и цифровых данных; . коммуникационных кабелей  телефонные провода и коаксиальный видео кабель. Проводка Smart House наиболее подходит для новых раз работок, поскольку предотвращает необходимость в последу ющих переделках. Настенные выключатели не соединены непосредственно с розетками. Они соединяются прикладными кабелями, что включает коммуникационные каналы. Коrда выключатель \ разомкнут или замкнут, сиrнал поступает к системному KOHT роллеру, который действует в соответствии с проrрамми руемыми таблицами для управления различными лампами или розетками. Такой подход позволяет. осуществлять пере распределение приборов и переназначение выключателей, при котором тот же самый выключатель может выполнять разные функции, зависящие от времени дня или друrих фак торов. В системе Smart House определена двойная система KoaK сиальных кабелей. Снижающие кабели несут видеосиrналы от источников  кабельноrо телевидения, спyrниковых Tape лок, антенн и т.д. Поднимающие кабели несут видеосиrналы от внутренних источников  видеомаrнитофонов, компью терных терминалов и т.п. Наконечники сервисноrо центра Smart House комбинируют эти поднимающиеся и снижающи еся сиrналы для распределения по снижающим коаксиальным кабелям. Этот подход аналоrичен системе CEBus. Телефонный вход осуществляет функции интеркома и дo ступа системы Smart House для операций с удаленным управ лением. Специфическое звучание звонка отличает вызов по интеркому от звонков остальных телефонов в доме. Телефон ный вход включает модем для целей удаленноrо управления. Тональные сиrналы с внешнеrо телефона MOryт активизиро вать проrраммируемые посылки данных для действующих приборов или сервисов в доме. Доступ закрыт паролем. Ин струкции синтезированным rолосом поддерживают удален ный контроль. 
Припожение в эту часть книrи я включил некоторые справочные мате- риалы. Мноrие из описаний, в частности, описание caMoro KOH троллера, можно в переводе на русский язык найти на сайте российскоrо представительства производителя микросхемы. ИК-дат"ик движеНИА Схема датчика взята из Интернета. Приведена схема, скорее, для ознакомления, чем для повторения (рис. П.1). Пироэлектрический сенсор изrотовлен из кристалличес кото материала, который rенерирует поверхностный элект- рический заряд, коrда подверrается HarpeBY ИКизлучением. Изменяющееся количество заряда может быть измерено чув- ствительным FЕТустройством, встроенным в сенсор. Эле менты сенсора чувствительны к излучению в широком диа пазоне, так что в корпус Т05 добавлен светофильтр для оrраничения проникающеrо излучения диапазоном от 8 до 14 мкм, который наиболее подходит Для обнаружения излу чения от тела человека. Как правило, вывод 2 FET соединен через отводящий pe зистор примерно в 100 кОм с общим проводом. И приходит на двухполярный усилитель, имеющий цепь оrраничения сиrнала. Усилитель обычно бывает фильтрующим с частотой 
ИК-датчик движения ЗЗ 1 среза 1 О rц для удаления высокочастотных шумов и сопро вождается компаратором, реаrирующим как на положитель ные, так и на отрицательные переходы выходноrо сиrнала сенсора. Хорошо отфильтрованное напряжение питания от 3 до 15 В должно быть присоединено к выводу 1 FET. ТYPICAL CONFIGURATION +V FRESNELLENS \ THERMAL ENERGY .. .. .. / AMPLIFIER СОМРАААТОА OUTPUT IR FILTER Рис. п. 1. Структурная схема датчика движения Сенсор PIR325 имеет два чувствительных элемента, объе диненных в вольтокомпенсирующую конфиryрацию. Это предотвращает воздействие сиrналов при вибрации, измене нии температуры и засветке. Человек, проходя перед ceHCO ром, активирует первый элемент, а затем  второй, тоrда как друrие факторы воздействуют на оба элемента сразу и KOM пенсируются ими. Источник излучения должен пересекать сенсор в rоризонтальном направлении, коrда выводы 1 и 2 расположены rоризонтально, так что элементы последова тельно подверrаются воздействию ИКизлучения. Перед ceH сором обычно устанавливается фокусирующее устройство. Типовое применение  в схеме с исполняющим реле (рис. П.2). Резистор R10 и конденсатор С6 изменяют время, в течение KOToporo реле RY1 активизировано после обна ружения движения. В качестве фокусирующеrо устройства используются лин зы Френеля. Линзы Френеля  это выпуклые в разрезе линзы, сжатые в себя так, чтобы принять форму плоской линзы с сохранением оптических характеристик, но меньшей толщины. Блаrодаря этому они менее подвержены абсорбционным потерям. 
ЗЗ2 Приложение u о l1J со u) at) v (\') L() v Q U N М о:: s :r: ..... Q) (f) соЕ * !:i U-r-- s m О + O> t1: > a:-r-- са N а:Т"'" т"'" S + -:r .... I са L() t1: + са Q) х () о:: са :r: .lI S с: s ::r :r: s а. С N С CO vo..... u а:Т"'" о,.....Е s Q. .::t:. О ,..... ,..... а: .::t:. Ng а:,..... N..... оЕ о ,..... ,..... а: Q.
Таблица команД микроконтроллера PIC16F628A ЗЗЗ Та6пиqа команд микроконтроппера PIC16F628A Табпица п. 1. Описание попей кодов операций PIC16F628A Попе Описание f Адрес реrистра (от ОхОО до Ox7F) W Рабочий реrистр (аккумулятор) Ь Бит, адресуемый внутри 8битовоrо реrистра k Константа или метка х Не обслуживаемое расположение (= О или 1). Ассемблер будет rенерировать код с х = о. Это рекомендованная форма использования для совместимости со всеми проrраммными средствами Microchip d Выбор адресата: d = О, сохранить результат в W; d = 1, сохранить результат в реrистре f. По умолчанию d = 1 label Имя метки TOS Тор of Stack (Верх стека) РС program Counter (Счетчик команд) PCLATH Program Counter High Latch (Защелка старшеrо байта счетчика команд) GIE Globallnterrupt ЕпаЫе bit (Бит rлобальноrо разрешения прерываний) WDT Watchdog Timer/Counter (Watchdog Таймер/Счетчик) ТО Time out bit (Бит окончания по времени) РО Power down bit (Бит сброса по питанию) dest Адресуется либо реrистр W, либо определенный положением реrистр [ ] Опции ( ) Содержимое  Назначить <> Поле бита реrистра Е Во множестве italics Пользовательский термин (шрифт courier) 
ЗЗ4 Приложение с со N со L&. со ,... (,) а: са Q. Ф 1:; 1:; о Q. .. ж О ] I:t ж са :1 о ф ] ж a:t О Ж U О s ж са ':1' Ф :1 м м s C\I C\I C\I C\I C\I C\I C\I C\I C\I C\I C\I C\I C\I C\I Q. t: ?'"" ?'"" C\I ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" N ..u N u .. : () () са u Q Q .. са () N N N N N N N N () () () N (,) ?'"" О ?'"" О c:t о о о о о о о )3; = = :Е о = = = :Е :Е :Е :Е :Е :Е = :Е = :Е о :i "о "о ?'"" О "о "о "о "о "о "о "о ?'"" О "о "о "о "о "о a:t О ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" О ?'"" О О О О ?'"" О О О О .. ?'"" О О О О ?'"" ?'"" ?'"" ?'"" О О О О О О ?'"" ?'"" ?'"" S ?'"" ?'"" О О О О О О ?'"" О О О ?'"" ?'"" О ?'"" ?'"" \о О О О О ?'"" О ?'"" ?'"" ?'"" О ?'"" О О ?'"" ?'"" О ?'"" О . о о о о о о о о о о о о о о о о о о ,... о о о о о о о о о о о о о о о о о о ] ........ ........ s C\I C\I ......... ......... ::r ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" ?'"" :s: о о () :s: ..... ::r S S () О JS t:; t:; О :I: са () () :I: Ф Q, Ф Ф Ф о. )S ...... Ф 1:0 о. ф СО .б .б ..... \о () С фо. ф с: О () с: > 0-& S s м t:; Ф :I:S м ф О й j5 J:1' () () й Ф О. с: s: sф > > о. ф ID с: с: s: ...... ф J S t:;: о О() О О rn J s: rnrn О Q, 5.0 О. О. s: О m СО t: t: ...... rn СО ...... ф () ...... ...... ........ S о. м () ф .о .о ф ф :s: S ф ?'"" ...... ...... ...... ...... ф :s; t:; с: S ф 3" L. srn.o 3" S s :1' rn rn ф ...... :I:0 СО Q ф .о :I: :I: :I: :I: .о .о .о Q, ..о ..... .о ф o.s ф ф ф ф Q () () о. СО S () :J:Srn ф ф ф ..о о:: J Ж Ф S S СО са j5 s t:; CO Ф Ф Ф Ф J с: :I: :I: () :I: Q u * () () О 0.\0 О. О. О. О. Q ф ф О S S Ф Ф S :z: О й S S с: фо о. о. rn rn J С :z: t:; :s: J J O Ф Ф :I: :I: Ф Ф Ф :о О () О са () О О t::[ S S t::[ t::[ s: :s: са t: t: :I: () () аз t: s: ID О Q, :s: 'd 'd :z: са Ф 'd 'd 'd 'd 'd :s: 'd 'd ... "с' ... 'd S i Q, ... ... ц,..., ц,..., ... 'd 'd ... ... ... ж О ц,..., ц,..., ... ... ... ц,..., ... ц,..., ц,..., ц,..., ц,..., о ж ц,..., I ц,..., ц,..., N ц,..., N ц,..., ... ... I :1 са tж.. tж.. cf.) cf.) tж.. I ц,..., ц,..., tж.. tж.. Ф Q. ):!: З tж.. tж.. tж.. tж.. tж.. tж.. $ з р.. ж ф са Q u u u u > р.. р:) ос( с Q ...:1 ...:1 О z z о о о ...:1 :::J О ::Е о 10 ,с::с u u u Q Q н н Н Z u) u) х . N t: са ::1 S 1:; \о са
Таблица команд микроконтроллера PIC16F628A ЗЗ5 C\I C\I т-- т-- М М I'.!. N Q Q () () а. а. Q Q О О () N ..... N ..... () N О т-- О т-- о о о т-- т-- о о о о т-- т-- О о о о о .:::L т-- о о т-- т-- о о т-- .о .о .о .о о о о о .о .о .о .о х т-- О О О О О Х О .о .о .о .о т-- о о о о о о о т-- О т-- О т-- т-- О О О О О т-- О О т-- О О О т-- т-- т-- т-- О О т-- т-- О О О О О т-- т-- т-- т-- т-- т-- т-- т-- О О О т-- т-- О т-- О О т-- т-- О О О О т-- т-- т-- О т-- т-- т-- О т-- О О т-- т-- ........ ........ C\I C\I ......... ......... т-- т-- т-- т-- т-- т-- C\I т-- C\I т-- т-- C\I C\I C\I т-- т-- т-- :s: :s: о. :r .Q ф са .Q JS Q, s > ф s )s rn .о с () :s: > СО о: rn "о JS > () о С: > )s S )S СО r:: :I: О С: са :I: :I: О. СО СО Ф s о о :s: о. о L.. .., j5 СО rn :s: rn О сп С: о. :z: о. ф () :I: () а2 > :о о. :I: О ...... C::I: са :I: L.. * () :I: О. СО С: О :s: ...... () о :s: о s а. ...... :I: ф () о. о ф ф () * s :z: () :о С: о. о. о. :I: О М sф о .о ф () \о sm О :I: Ф С: О С: S :s: s \0з \00 :I: ........ ф() а. 3'() \о .о .00 :I: О СО О ()о 3':0 s м м L. С: s () s rn Q :о ф .о s o. CO () .00 s .о () s Q () а. m 0.\0 о.() :s: .о "O :I: Ф .о J :I: S О :I: S..c СО О Ф :I: ф() ф> u: s о СО () )S 'j"CO о. о. о. х () Q СО j5 () СО rns ms :s: * rn ().., ф Q ф rn rn rn ф ф ь S o o о м SCO о. о. м м м О. J :z: :z: () :I: J () о.() о.() :s: JS J Ф Ф О О О Ф :о :z: О t:ф t:ф Ф () аз о......... t: аз t: аз аз аз t: аз :s: са к:; са Ia О са Q, Q, :s с ... ..Q ..Q >- :z: :s: ф ..Q ..Q :s: I I I :s: ... ... ц..... щ :r I а. ... ... са E--t о ц,..., ц,..., tJ u) Q, з з з н З с4 З З I u) u) ф ...:1 ...:1 ....:1 О ....:1 tж.. ....:1 :::J ...:1 ...:1 :s: tж.. tж.. tж.. С Q Q ...:1 E--t а:: > E--t E--t E--t а:: tJ u) E--t E--t Q ,с::с ...:1 О О О ...:1 :::J О 10 о ,с::с tJ tJ с> н а:: а:: а:: u) u) х
ЗЗ6 Приложение Примечания. 1. Коrда модифицируется реrистр 1/0 как функция сама по себе (то есть, MOVF PORTB, 1), используемое зна чение будет то же, что значение на самом выводе. Ha пример, если данные на выводе, конфиryрированном как ввод «1», сбрасываются внешним устройством воз вращаемые данные  это «О». 2. Если эта инструкция выполняется на реrистре TMRO (и применено d = 1), предделитель будет очищен, если назначен для 1imerO Module. 3. Есл счетчик команд (РС) модифицируется или прове ряемое условие истинно, инструкция требует двух цик лов. Второй цикл выполняется как NOE QOKoneBKa KOHTpOnnepa PIC16F6ZSA PDIP SOIC о Rд2/АN2/RЕF  1 RA3/AN3/CMP1  2 АА4/Т ОСК1/ МР2  3 RA5/MCLR/Vpp  4 Vss  5 T8/INT  6 А81/АХ/ОТ  7 А82/ТХ/СК  8 А8#/ССР1  9 18  RA1/AN1 17  RAO/ANO 16  RA7/0SC1/CLKIN 15  RA6/SDC2/CLKOUT 14  VDD 13  R87rr10SI/PGD 12  R86rr10S0rr1CKI/PGC 11  А85 10  R84/PGM Рис. п.з. Цоколевка контроллера PIC16F628A 
П р оr р аммато р (совместно с PonyProgl ЗЗ7 Проrрамматор (совмес.тно с ponyprog) О N .... N М V &l) <о ,... со cn м,..... O.q (,) + I (,) > м Lt) > u I Lt) D: N + <.D m м Q о о) C\I Z а. с> (; ф с; ..J с; с: О а. '"' :::> :> с: C\l0 ..... Х O м > о (f) I N о: .... z C\I со Е ,..... N а. Е O.q о N I + I 1 ,..... со се (; ш 0.:::> се '""')'""') со ею ею ею а. О .q oq- oq- о. о .... .q oq- v а. О z с: ш м C\I со ..J Q Q Q ш ф (f) Q х а: U <t О m с:: ш о (f) s <t Q. .... m се О о. <t а: ш (f) О '- а. ,о) о а. c;s с '""') '- о)
ЗЗ8 Приложение Адаптер ДЯR PIC-контропперов  а3  Ф ... Ф  о а. ... u ф а; fЛ I Е l .... м  а.а. , ::::> , О ...... =; z .... NM &n(O r--co Q)  8  m ....' т r1 u.. с: О ......0 ()......  <Cb u.; се се::] О >0:: о:: о:: о:: (о Q. U NU о: Ы'" ОЫ со о о.  i5 U....   i    M  C6'....NM U < Zmmmm О о:: С) о:: о:: о:: о:: v) N О .q,..... a: .q >.q MN .... м .... O.S  М О a: U....NO:: Х UUU   >i Q   ....  U о v) () а::  с) о:: UJ ....  с < U о: >- а. о ... а3   as а. L. о а. r:: :iIt as а. ф ... с:  а3  Ф х ()  с u s: а. N ::::> r-- (O&N  М N ....0 u C r--co&nv со     Q <D   U о v) u о:: ....N  f м ::) со 
Практическое применение триака в модулях системы ЗЗ9 Внешний вид и napaMeTpbl MOAYnR 06щеrо наэна..ения фирмы Advantech ЛDАМ 4060. Модуль релейноrо цифровоrо вывода (рис. П.6): . 2 релейных выхода типа А (двухпозиционный вывод); . 2 релейных выхода типа С (трехпозиционный вывод); ( :.. '" "," о.""" , .. л \ ' , ,,' o' Рис. П.6. Внешний вид модуля АDАМ Параметры контактов реле по переменному току: 125 В @ 0,6 А, 250 В@ 0,3 А, по постоянному току: 30 В @ 2 А, 110 В @ 0,6 А Интерфейс RS485 Практи..ескоеприменениетриака в МОДУПЯХ системы Хотя на протяжении всей книrи я старался подчеркнуть, что все модули системы, как и сама система, предназначены для проведения экспериментов за компьютером или за столом, думаю, среди читателей найдутся желающие воплотить в жизнь отдельные модули или на базе предложенных модулей создать свою систему. Для тех, кто знаком с техникой безо пасности и может работать с напряжением 220 В, в справоч ной части книrи я хочу привести несколько практических советов по применению триака в модуле управления светом.
340 Приложение Для этих целей вполне подойдет триак Q6025L6, Х44081 или аналоrичный. В реальных конструкциях, с которыми мне приходилось сталкиваться, вполне успетно работают триаки с допустимым напряжением 400 В в закрытом состоя- нии, но лучте использовать 600-вольтовый вариант если есть возможность выбора. Второе, о чем мне хотелось бы сказать,  это способ управ- ления. Ниже я привожу реальную схему включения оптопары (рис. П.7). Включение диммера начинается с реле, контакты KOToporo КР подключают наrрузку. Кроме тех соображений, которые мне не ведомы, подобное подключение обеспечива- ет большую электрическую безопасность. В Интернете есть статьи по тиристорному управлению, и, прежде чем прини- мать окончательное ретение, я советую почитать рекоменда- ции по выбору KOMмyraTopa. Или поискать эту информацию В литературе. Если вы не планируете реryлировать яркость све- тильника с помощью триака, желательно включать ero сразу после перехода ceTeBoro напряжения через ноль (или в мо- мент перехода через ноль). Если же вы собираетесь реryлиро- вать яркость, оптимальным, как мне кажется, было бы УДОВ- летвориться несколькими уровнями яркости и не включать триак в моменты, коrда сетевое напряжение близко к ампли- тудному. Светильник кр  МТ2 Х44081 МТ1 G Фаза 2.4 кОм о Х44081 МТ1 G МТ2 Рис. п. 7. Схема управления триаком Хотя оба используемые в схеме резистора MOryт иметь мощность 0,25 Вт, я советую составлять каждый из двух резис- торов по 0,25 Вт. Например, резистор 2,4 кОм  из двух рези- сторов по 1,2 кОм. Это вызвано не необходимостью в увели- чении мощности, а необходимостью увелчить допустимое 
Практическое применение триока в модулях системы 341 падение напряжения на резисторах, поскольку для резистора типа ОМЛТ при мощности 0,25 Вт допустимое напряжение  250 В. В сети амплитуда напряжения может быть больше. По возможности, лучте использовать триак в корпусе с изоляцией пластины крепления от вывода МТ2 (они суще ствуют в обоих исполнениях), если триак будет устанавли ваться на теплоотвод, служащий одновременно и KOHCTPYK тивным элементом. Иначе теплоотвод может оказаться под высоким напряжением. При выборе типа полупроводника по току следует учиты вать, что лампы накаливания при включении имеют мини мальное активное сопротивление, которое увеличивается по мере разоrрева нити накала. В любом случае, настоятельно рекомендую обратиться к информации по триакам (или тиристорам) до принятия pe mения о покупке деталей. Современные триаки 3Q вполне успетно работают не только на активную наrрузку, но и на реактивную, что позволяет применять их для реryлирования скорости вращения двиrателя, например вентилятора. Очень интересное предложение по реryлированию Ha пряжения на инерционной наrрузке я встретил на одном из сайтов. Сущность идеи состоит в том, чтобы циклически пропускать несколько полуволн переменноrо напряжения. Скажем, для получения 70% яркости свечения лампы накали вания из десяти полуволн напряжения пропускается три, а семь приходят на наrрузку. Желательно их распределить paB номер нее по всему циклу. Выrода от подобноrо способа уп равления в том, что ключ открывается в моменты перехода напряжения через ноль, не создавая помех в сети, что xapaK терно для фазовоrо способа реryлировки. доnоnнитеnьныe эаме..аНИR по ИК-управпениlO Проrрамма WinLIRC позволяет не только считывать ИК коды, но и воспроизводить про читанные команды. Воспро изведение  чисто проrраммное, возможно, по этой причи не оно показалось мне не слитком уверенным. Но оно работает, что вы можете использовать в своих целях. На 
342 Приложение сайтах, посвященных работе проrраммы, неоднократно за- давался вопрос о том, как следует изменить схему излучате- ля, чтобы модуль WinLIRC можно было отнести дальте от управляемоrо устройства.. Простейтее решение  в приме- нении транзисторноrо ключа, работающеrо на последова тельно соединенные светодиод и токооrраничительный резистор, который, в свою очередь, зашунтирован конден- сатором. Величина емкости конденсатора зависит от пара- метров светодиода. Идея же заключается в том, что свето- диод питается короткими импульсами больтоrо тока. Любой светодиод допускает кратковременную подачу им- пульсов тока, во MHoro раз превытающеrо средний допус- тимый. Скважность импульсов при этом зависит от конк- peTHoro типа прибора и может меняться от 100 для одних типов светодиодов до 3 для друrих. В экспериментах, описанных в книrе, я использовал све- тодиод АЛ307В, размещенный на макетной плате. При этом видеомаrнитофон Sony упранлялся с расстояния около 1 О см. Для увеличения расстояния между модулем и управляемым устройством (если надо) можно, конечно, применить специ- ализированный ИКизлучатель или воспользоваться при емом, который описан выте. Обязательно ли использовать дополнительный транзис- торный ключ? Я бы использовал ero, как rоворится, на вся- кий случай. Но, если вы уверены, что контроллер не будет выведен из строя, не используйте литних элементов. Если вместо микросхемы фотоприемника TSOP вы буде- те использовать фотоприемник друrоrо типа, то можете столкнуться с явлением, которое однажды сильно озадачи- ло меня. Использовался модуль фотоприемника, который транслировал полученные ИКкоманды, для передачи команд из разных помещений на IR Xpander (системы Х1 О). Последний кроме запоминания и воспроизведения ИК-ко- дов был способен распознавать коды, которые он предвари тельно запомнил. Эти коды впоследствии можно было ис- пользовать для инициирования любых сценариев в системе «Умный .дом». 
Проrрамма для компьютера в KDevelop 343 Первая проверка дала положительные результаты, но за тем начались странные явления. IR Xpander то исправно выполнял команды, то не реаrировал на них. При этом инди катор на панели показывал получение ИКкоманд в моменты полноrо отсутствия ИКизлучения. Сделав неправильные предположения опричинах этоrо явления, я понизил напря жение питания фотоприемника, что дало положительные результаты. Только MHoro позже я выяснил причины этоrо эффекта, разбираясь с друrим устройством. Для увеличения чувствительности фотоприемника компаратор, стоящий после фотоэлемента, имел пороr, очень близкий к уровню шумов. При неблаrоприятных изменениях окружающей cpe ДЫ шумы пересекали пороr компарации и транслировались как сиrнал, который и заставлял IR Xpander надолrо заду маться. Эксперименты с ИКкомандами весьма интересны и увле кательны, но не следует оrорчаться, если чтото не получает ся. Я пробовал оценить, насколько уверено распознаются коды устройством, для этоrо предназначенным. Коды раз ных производителей распознавались им с достоверностью от 9098% (ИКкоды одних производителей оборудования) до 5lO%. Проrрамма ДВА KOMnblOTepa в KDevelop Причина, по которой я хочу рассказать о друrой среде про rраммирования, именно KDevelop, работающей с операци онной системой Linux,  в ее большей доступности дЛЯ MHO rих, чем Visual Basic. Эта среда проrраммирования входит в состав мноrих Liпuхдистрибутивов. Хотя она и не един ственная в них. Итак, я .предполaraю работать с релейным модулем. По этой причине я проrраммирую микроконтроллер соответствующим образом и заrружаю на компьютере ASPLinux. Я уже rqворил, что эта операционная система поставляется с orpoMHbIM коли чеством приложений, в частности, и для разработки проrрамм. 
344 Приложение Запускаем проrрамму KDevelop. Моя версия в данный момент предоставляет в меню запуска возможность выб. рать язык проrраммирования и вариант проекта, хотя это можно сделать и несколько позже. Итак, я запускаю KDevelop в разделе OCHoBHoro меню Приложения - Разра- ботка - KDevelop KDE/C++. Если это первый запуск, ни один проект не открывается, если повторный запуск, открывается последний проект, над которым вы работали. Для создания HOBoro проекта предыдущий следует закрыть и выбрать в меню KDevelop Проект - Новый проект (рис. П.В). $ - .'-,--------. ,----.-,------,--,-,-,-, ------------>--,--,-->-.,-, - - - -- - - I( 8Йn l)IUq вид [)Joeкт C6CJPq <>ТIIOa Q,eНIPММ  CJPeМC: t:teCТPCItiIКa tnpввq ;..8 Q Q. \a 1.F  C"jAOfu """" (11" , -, Q об..,.. t J;  li я -' f..:-Q-!fXi "5f' _,о i.-I ! е  AppIItIlllon tllll1ewor1t (KPIIIt3)  ! \\К.. PIUgin WIIh cdg page j 1AКFIe PIUgjn кнтм.Р8ft PIUgin Кlcker ДPPIet .KIO SIaVe KOIIc:e PIIIt -Кonqueror N8VIgI8Ian Р.... PIUgIn ! - \\NOIU'I vlSUllllzIlllon PIUgin t- :== lPPIC8IOn J ,; iSImpIe Dnlprbased КОЕ  . J _SImPIe КОЕ APPIiC:ariOn . ::- . 1 . _VJlkmNoIIun -n .Имnорт 1113 кее. """' '- L  >Ш.< ,.,..ЖI!НIIIII- 1. -- i . ! · f I i ) i о [)CIЦ38Т1> все W86natt.I f1X*ТI [  .' - имя ,...nD*.... I - fвсnonoженме:  KCIНe'IН08 pacnono*eнмr  (нееерно) '1 J ; }t'' ./ -:" h.,y ;.ov-. j ._:"'. у Co НOIIbIЙ npoettТ'lII3 w86noнa ->"--'.-- ....,-.-,." ".- -., .. f1oмcx.  -КansaII Рис. П.В. Создаем проект в KDevelop в диалоrовом окне выбираем С++ - KDE - Simple Designer based КDE Application, задаем имя проекта (в дaH ном случае  book) и место ero расположения (в данном слу чае  домашняя папка пользователя)  рис. П.9. Теперь нам остается щелкнуть несколько раз кнопку Next, при этом можно сделать уточнения, относящиеся к проекту, но эти действия можно осуществить и позже. Заканчивается 
Проrрамма для компьютера 8 KDevelop 345  .b'n Ql88КII В"IA ()Ioetcr СБОРКа Oт CUeНВPММ окно CJP8МC t:fктpotiiкa  "QQ -:;J:P,$ Ccuцm,$jO",II ". Q 06tIIМ8 ( " W', : Q- '-Х:  1 в' В&e Li_- " I  АрplCatIon t"emewOflr. (KPerts) , _К818 PIUgin WIIh сonlg Рlg8 .KFiIe PIUgtn tt.KНПvLP PIUgIn -'Kickllf Applet f)KIO slave ..KOIIc:e P .9.Konqueror NavIg8Ion Р-пе\ PIUgIn No8lUn vtsuaJiz8!ion plugin .Scons-b8sedКМОI  .SImPIe ОСОР 5erVef I jbl81JJ '-I:..t...i:iJ..............IИ"t" I $Simple КОЕ AppIlCabOn ,_VJeIUn NoIIUn ' .. , f(S1mp1' .' ,  )( f , t- . I r-- i НtfIoWorldl ,- I r; :. 'r; <  м.r;,7 J I - ! Generus 8 SinPIe КОЕ appIcllllon ; I WIth DI1e Qt-designer based WIdget I I ! '" I I c80icтм 1l1мя npмnoженмя: I bookZ I f8СlIOJ1Oж.....: !Ihom elvtadimlff , KOttr4НOe p8Ct1QllOJКaнмe: Ihom;,_;. I  11 t if) I -" .:  ,',,'i ;   . L:::::.: . . 'jQ,,оI,j--riaмёК.-u.з-;m.!tiil C НIItII>М l1PC*Т ИS wa6noнa Рис. П.9. Выбираем тип проекта в KDevelop оформление проекта, коrда кнопка Next превращается в кнопку rOTOBO, которую и щелкаем в последний раз, получая проект. Щелкнув на правой инструментальной панели ярлычок Automake Manager, открываем окно менеджера, в котором можно открыть все файлы проекта и файлы заrоловков двой ным щелчком кнопки мы тки. Я открыл файл bookwidgtbase.ui (рис. П.1О). Файл интересен тем, что относится к встроенному peдaK тору интерфейса проrраммы. Окно с кнопкой Click Ме! по явится после компиляции и сборки проекта при запуске про rpaMMbI. Для компиляции и сборки сначала в основном меню выбираем Сборка - Запустить automake и др... В нижней части открывается окно сообщений, rде показывается про цесс сборки (рис. П.1l). Затем мне приходится сделать лит нее «телодвижение»  после одноrо из экспериментов в KDevelop с разными язы ками проrраммирования мне приходится поправлять файл configure.sh, который находится в папке проекта book. 
346 Приложение , . . '. ,. ""' i.b";"; . ":' 8iUI . [)ЦIIq &111 [)Joeкт СБОРКа ...Oт CUВН8PММ facnona.....  C8J)IIМC t:f8Cтp--  . .. .:..\ ". :.j3: ";.] f! :.:  :;..1!!i  n):lf: .".". .'1. щ ol о' (\' 6; Ii: iIlll:: 1I1 I . ...  ! iII LIneEClI  jtJ  spin80x , TaEcIt --: .... Вul!an, ;....:. <';., Co :::: viiNi, ,,\" . . D8t8base ' 1"Р'4 ':,. \;... ". J: == 1"Р'4 (КОЕ). VIIIws (КОЕ). COntIIner (K  ! (КОЕ)'\.., '  . ....! .... :;,._! \  :..iJ"'v..:!I'-ПОМСО ,.".. " .. 11  0;1 :;' 11 ,. \" ....:.. -.:... ... 06I.etmi .  "",,"ё н.э..... ..х..':"<- ....,...  "'. . I ...lbase   ф< b . . ushSIA.. ,  l8beI . lIbeI 11 Ьес "ounCIO ' ВI 'tl .. '1 i I cursor Вlc ... icon ВI TIXt. I mouseTrac iF.,e focusP. ;NoFocus Ce@rs........../...SI  0:....::.:.........10. !no I ' . "". , :по .. raslzeМode ,Auto , ВltoolТ1. .....  ВI wt\atsТhls " ,._... _:... . О." J' :,I.;:  :"" , . Ео .....booll2 (Прorp-ММ8. bln) i l' . book2 срр _. ' 1 ,. book2w1CPP 1: F-m8In срр !! .. . д8нн1.Je I shеldeзktор Н ..  Дaнн..le I shellrt i I ':д8ннI.Je е nмктorp.....1IX 11 .Э.ОЛ08О1С I noinst ..!. {I 1]  KonsoIIt Рис. П.1 о. Встроенный rрафический редактор KDevelop \o...' (,1... "M .11"'tIr  "'  !'!'> I<O'>n-i.>р 8iUI [)IIIQ EIиA [)Joeкт C6CJPq Or   QIIНO :  Q. Q  fd 9  ..... ..... се .]  {-< а s\ f'    I( no b1ctIon ) .lj :  :;::J о Q  at о' 1) , I.t  a.cPP ... I#. : CJPeМC t:JIICТPOiIQ  1 fj t l .11 J, .:. !..t(, ....b00k2.kdev.lop ! ft' I!!;doc !!!ре -''-l  /- ..". .... ... ... ... ........ .............. ........... ... ... ...... ... ... ......... .. "о,nе tt:, ttO# 6>7 \":....J..J. с;.,.':.,lсЬс... .  . 'f,n.l. ..ro..r.... .... "... .oLI..r., )'4"О С'.а ,.....t,.J.ut. ,.,: I'td'c.,. &'Y le tn:a.. rlW> е.,.... oL ем CНfJ c:.......l Pu&l.., L..co.... .. ".,..::.."...., DY . 111» ,.... $oLc.nt 'CNIld.eC'4>1I1 .ttlS..r ",."..tCJD  С''' сп» :'"rc..., 06 .. (.е 7..:J11,. с-,.е 10ft' IIJ. l.t... .........4>n. '111.1. p.-orgrtlJ8> i d"'t....D"c., in ен bc tl>et tt ."J. J:.. "..tu.1. . 1tJ''!'fЮti1' AIlr ItAlcANirr; ",'eJкout .v." с.!). J t.:I If.rr"'=}' oz ,.Cf«:,..»lTU:z.rrf .... '!TNIIS:f 1"01< JI .UT:'C"I. ,1.'1t,.:>36. 11... CIo. CIt'.J .........1 tubl.&:: LJ<"'8IJ". ftU r. d.C.J 1..  !"! Х '' I I 1: I w 1 J , I .,rr  " I е L... booll2 (Прorp........ . bIn) i : . book2.cpp I fл 'cr'"' .b.cntJ. Ь.у. 1Н"'8J . <"'0#7 , с... :;w 0.".,..1 ..wl"'..:" "'4'.".. .:tutq ws.t:JII С....1. #)14:'0"'..1 .11 nt... .....Jt. t.o t.ts. I'r.. 3,;,te..z. '-""UlhМt ,OIJ. ll'lc... 1# ,...,:.. .....се .. 6uJt. '.10, .t<o.coC"n, 11,\ 02JJ:"'''C, CI.I"tA. ; a' ! ф; 8a.JU:l.. ck...""1ndO..b : 8a.JU:l.. ck1ue.l....,., .: 811u:1.. ."OD'k.J: .Ь. . . 8I1u:1.. ."oD'k.2"iq..b. book2wldget.cpp ..  . ::-.т.In срр  1! . :  I shelldesktop .. x'H" e I shellrt ... .: ... ....j>..Дaнн..18 О nмктor <. I1 iIi "'""ЭwQl108CЖ I nDII'Ist 1; 1; 1,;,.. .... POS1j)rOCessing MekeIe templas .... Cre8llng dlteltime StImP .... FinlShed 8Don't rurget to М1/cOl'1l1g\п ..fyou haven't CIOne 50 In 8 WhIIe. м1 Jccnlglп h.1p .... Ycnewнoe  ... ;1 ,"o!l= :  ..",.:. .- )<1."'.'-" ':-:0' j. . ..y ..,',. '. 1(114 КanIOIt CТ:;Ц "., ,. >.. ......J I   6Рсж;hЗ2ЙiТА8К А OБЫiiюE . r 1 Рис. п. 11. Окно процесса сборки проекта 
Проrрамма для компьютера 8 KDevelop 347 я открываю файл текстовым редактором, удаляю показанную часть текста почти в самом начале файла и сохраняю файл: # Support unset when possible if ( (МАIL=БО; unset МAIL) 11 exit) >/dev/null 2>&1; then asunset=unset else asunset=false fi Без этой операции появляются сообщения об отибках при конфиryрировании проекта, которое запускается в разделе OCHoBHoro меню Сборка - Запустить configure. После завер шения этоrо процесса можно запустить сборку Сборка - Со- брать проект или сразу запустить проrрамму Сборка - Вы- полнить проrрамму, что приведет к сборке проекта и запуску проrраммы. Есть еще один момент, который привел меня в замеша тельство, но, возможно, это тоже результат моих экспери ментов. Не получалась работа с rрафическим редактором интерфейса. Для ero нормальной работы в опции проекта Проект - Project Options - Поддержка С++ на вкладке Автодополнение кода в части Code Complection Databases понадобилось с помощью кнопки Добавить добавить под держку Qt (рис. П.12). После создания базы проблема перестала беспокоить. Qt, насколько я понимаю,  это мощная библиотека, подцержи вающая rрафику. Разработана она фирмой Trolltech. Все rpa фические объекты интерфейса  объекты этой библиотеки. Но вернемся к проекту. Если теперь щелкнyrь кнопку появившеrося окна book Click Ме!, появится традиционное для языка С  Hello World! Таким образом, почти незаметно для себя мы написали пер- вую проrрамму на языке С++, работающую с операционной системой Linux. Теперь хотелось бы эту проrрамму превратить в то, что нужно нам. Меня беспокоят некоторые аспекты пред стоящей работы, но для начала я, выключив работающую 
348 Приложение ". tIDQaI2-111с. I'IJJI."  .....':р.х  npokn-КOIwIoIt .х . 06щме - МОДУ"  · :. аУпр..мн_ вере :. Под-pllCllа С++ .. ..JJ!.:J АДDПOIIН8Н1481(QД8 L ДCIC1)fП8. CO"7.Qat"II<' .patllll «,.1>«011 )( ....,  ММММC: : 400:МIWIМCi I 4 I i I вw60p WJlllOT.... \ UJaБI10ftЫ фllЙJlое ..;. . l1cмrtмetП- npoкr 03 . 1(8 СИМIIOl108 мз бмблмотекм KDElrbs . )ф8Нl41lИЩlIfJ1  "n\rpo'?,!! с."'" ,r,'af< It.?  <ЬN. O'I!+'" ';' t> '114 4t/1,Iще "OCr'Ot Q3arpyэ1(8 CммeOJ108 мэ ЛlO6oro катaлorа I хр8Нl411МЩ8 I<J1aCCOl  ." <f , .:" х J) СnмcOll ф8ЙJloе 1 . . : " . . nOддePU& с..  "' t."..:. "   ! .. .. . i : : ,: tI...;;" П.,--тры еоnlgure ! 11..-:;.,  .J1 П8р--тры 3lfJyCка :;:::: .-.;:t 1] !: UiIJ ,..... o;tмeнa . !! ' ПpмnoжeI'W.., I'\1ocмoтppal1lНil : .= ,'!1 VriqWJ :iI Помск. фIiuI8x ld. э....т. .- KonsoI8 . O QТOЧI\МТ..ОI;\crIО' 11 пep8Мeтpbl npоекта ! строк8: з  2з вет ДВКД ОБЫЧНОЕ . ..... . fr..';i..- , ' . , ." о ,I,ID088II1Ъ... J : I .. i( ! а bln) ,1 l"2:;.:: " .  Q1мeнa ар  П8р--тры .... i 8х Рис. П.12. Добавление подцержки Qt проrрамму, возвращаюсь в редактор интерфейса к файлу bookwidgetbase.ui. С этой небольтой проблемой я столкнусь позже, но хочу устранить ее сейчас. Существо проблемы в том, что возникают некоторые неприятности с изменени ем интерфейса, а, изменив интерфейс, я не CMOry справить ся с размерами окна при запуске проrраммы. Окно OCTaHeT ся в том же первозданном виде, что и при первом запуске. Основу интерфейса, как и в дрyrих средах проrраммиро вания, составляет форма, на которой размещаются кнопки, этикетки и т.д.  все составляющие формы. Кроме нее OTKpЫ та инструментальная панель (слева), менеджеры проекта, свойств формы и ее составляющих (справа). Для устранения проблемы, вероятно, есть более правиль ные пyrи, но я потел следующим  щелкнув правой кнопкой мыти форму, в раскрывающемся меню выбирал пункт Разор- вать расположение. Теперь я MOry работать с формой. На форме в данный момент одна этикетка  label, и одна кнопка  button. Для начала я увеличу размер формы и поменяю местами компо ненты, изменив их размер (рис. П.13). 
Проrрамма для компьютера в KDevelop 349  . т. 1>0..... 1d1ml'  '" g, '" K! !) 8Йn [р8ц &\А (]роект СБОРКа OтDUЦ cueнapмм fllCt1ClЛOJIC.....  CIPeМC tj8c1J)Clilq cnp8eкa  QQ [? 13:""....  .'>   . (n__tio )I:::+ ::J  O Q . 1ft. (Jf- i1' 1) .(  : Ii 111 :: 11 н I .:... :. *' iI , '. ш _.,.. I 11 } ..': .:eIb . -& I COIlllllOn Wld.""'\.. > . .- f - .......IONO.... .. ..{;JIc:t\ Меl . . ;[:t  Tex!Labef  .. ... Spec8f f;- !>I ,1 1 :- col'lt8lrler; . ! i VItWs   I t! O """""""- 1< ,nput"' I ., DiSP  I " , ' :OE  вuttons (КОЕ) ,. . IПPUt iKOE) ,.. '. . 'v!ёWs (КОЕ)  . }l' (KOE  G,-"::"';;'S' ( KDE ) '""'- . J; 1DE"j . . i JboеЖ2 1 ! ... НogM8IIbН08 388ePUJ8>1IiII ... ': I  .f#..- paпмчiIi O .  qflOS(   )( . . . - ..... . - О," .... .....' -."О'- -...."'.....,. .......-. - ,,' " 111 х'  х .. . " .. .  .. . . . . .. ." "1: .. .! :.:::::: :::::" :" : I I I у..... :.ф-- ..з.....m.. . . "1"', :,'П Рис. П.1З. Работа с формой в KDevelop Кнопку я позже использую для работы с портом, а этике ку  для вывода сообщений о состоянии порта. Добавим раз делители, как показано на рис. П.14. Щелкнув правой кноп кой мыти форму, выбираем в раскрывающемся меню Lay Out in а Grid. Теперь при запуске проrраммы окно приобре-- тает вид, который бы мне хотелось видеть. Однако вернемся к проблемам, вызывающим у меня бес покойство. Я бы сформулировал это так: «Плохо, коrда забы ваешь то, что не знаеть. Особенно, если забываешь, что ты этоrо не знаеть!». Производственная необходимость некоrда заставила меня обратиться к языку С++, на котором я написал небольшую проrраммку. Для знакомства с языком я законспектировал ориrинальную версию книrи Липпмана «Основы С++». С тех пор прошло достаточно времени, чтобы я все забыл. По этой причине я добавлю «шпарrалку», постаравшись не использовать сложные синтаксические или проrраммные конструкции. Первое, что я запишу, поскольку всеrда пyrаюсь. 
350 Приложение '4 I"ox.l<:' ", 1""'11" ""'1m!, ьо< 1.:> t., IY"":y,,,d1"fl- о" 111, I((), "IOI>  [)ЦIIq '. &111 .. []роект СБОРКа Oт  f8Ct1Q/1OxettМ8 QIIНO Сep8IIc   .'  Q. Q a'f!. ai   ...   ') tl а ':fI ':,. .l .o 'о :I1i  =:i r:1 О Q  щ' at: fJ' 1) cf;, If ;. ii  . . . н I .... ,7' "// /"1' "/ .. ,'. . . utbnll' /tIulfllllv .;':,". :.:::;.':':,:,,;' :. ;.::::; :::: :-:":: :: ::;..:::':"':: J ;. .';' '!-.. . .'.... . .  : ..::::;::.::::::::,:: :...: : : . ,  o 1"P'4Q<DE', .... ... .........  X ' t-; : : : : :  : : . . . : : : : : : : ;  l) .. .. .................. ... "  ;i.iФE) 'i о<i5fiМ)''''-.... .: ,,:  !":! Х .iI' 06I.etmi Чne.;i'., ..,.... " '. ,'" " КJ1ecc. .. booetbase  ,о е:! buttol\ . . US == > :: ;:  IВ n8IIIe etbase .. I  itnebl8d IТM IВ slzeP .::: (j IВ mlnllllumSlze О. О i IВ 1118X1n'unS1z. 32161. Э 1 . IВ slzelnc:remert О. О 1 1 .. :,baё :.... i . IВ Q " I . f IВ с .tIOn . . .ec!........... "..:....!" icon .. texlLlbet 1 at.8bet I ii"iёOn TIXt specer7 2!!!8:'" Пiousетiiiё" F"5i .; .j: !. !: ( . : , : [ =".::.. .. .", .".N , о., .... '-   V ..no..c.r.. ф-AIмк З-iё 'I\. OI'ISOItj  , : 'e:,:9, .., < .... .... .. .. , .. <.. LЦI!1жнмтI на форме Д/ItIIII:Т88I(IiI specer "' '' . !. Т'мкт"'; Рис. П.14. Придание форме нужноrо вида Указатели в с. Пустъ м-ъ, u.мee.м перe.мeu1lУЮ с u.мe1leм var типа int (целое): int var; Теперь создадим друzyю перемe1l1lУЮ, 'Которую 1lазовем: int* pvar. Появuвшаяся звездllЧ'Ка 20вopuт, 'Что перемe1l1lая p var  это у'Казателъ. Если теперь м-ъt npиcвO'UМ этой переМe1t1l0Й следующее З1lа'Чe1tue: pvar = &var, то в пepeмe1lпoй p var будет хра1luтъся адрес первой перемe1l1tОЙ. Положuм., естъ e11j,e одпа пере.мe1l1tая: int newvar МЪt м-оже.м добавuтъ 'К первой перемe1l1lОЙ едU1lU1J,у, присвouв pe зулътат п0вой пере.мe1l1tОЙ: newvar = var + 1 
Проrрамма для компьютера в KDevelop 351 Но в ЯЗЪt",е С то же ,Можно заnисатъ, uсnолъзуя у",азател'О. newvar = *pvar + 1 звездач",а в данио,М случае ZOBopum о то'м, 'Что ,мъt исnолъзуем зна'Че иие nерe.мe1t1lОЙ, адрес ",оторой хранит nepе.менная pvar. ЮКUМ, образо'м, &var  у",азЪtвaem, 'Что исnолъзуemс.я адрес nере- меииой var. int* pvar pvar  это указателъ, *pvar  nаказЪtвает, 'Что исnолъзуem- с.я зна'Чe1luе nере.мe1tНОЙ, на ",отОРУю у",азЪtвает p var. У",азатели Mozym у",азЪtватъ на nере.меннъte, ФУН"'1j,ии, apyzue указатели и т. д. Не знаю, поможет ли вам моя шпарrалка, но для себя я ее оставлю, тем более что в «с++» без звездочек, разбросанных по всему тексту, шаry не ступить. Еще одна деталь. Коrда я впервые столкнулся с КDevelop, это была версия без интеrрированноrо в нее редактора интер-- фейса. Для этих целей использовалась отдельная проrрамма Qt Designer (она и сейчас входит в дистрибyrив). И это не единственная возможность создать rрафический интерфейс, как и KDevelop не единственная среда разработки на языке с. Объединение проrраммы на языке С++ и rрафическоrо инте фейса выrлядело несколько иначе, что заставляет меня, как мне кажется, сейчас делать MHoro ненужноrо. Но я не собира юсь поразить воображение пользователей необычным дизай ном проrраммы, по причине чеrо не хочу пока разбраться с этим вопросом. В памяти осталось, что Qt Designer использу ет понятие слотов. В моем представлении, слот  нечто вроде rнезда, в которое вставляется модуль, как в материнскую lUIaтy вставляется модуль памяти. Используется и понятие сиrналов, что для меня равносильно понятию использования выводов разъема. Через ero выводы модуль получаеТ сиrналы от мате- ринской платы или сам передает сиrналы материнской lUIaTe. . И, действительно, открыв в КDevelop файлы bookwidget.cpp и bookwidget.h, в последней находим слот: public slots: /*$PUBLICSLOTS$*/ virtual void buttonclicked(); 
352 Приложение А в первой находим сиrнал, относящийся к этому слоту: void bookWidget::buttonclicked() { if ( label>text().isEmpty() ) { label>setText( AHello World!" ); } else { label>clear(); } } Этим для начала я и воспользуюсь, хотя, подозреваю, ecrь более простые способы реализовать то, что мне надо. В первую очередь я хочу переименовать кнопку из button в portopen. Я делаю это на вкладке bookwidgetbase.ui. В Object Explorer выбираю button, а в Property Editor в rрафе пате меняю имя с button на portopen. Щелчком правой кнопки мыти OTKpЫ ваю меню, выбираю Слоты, rде меняю имя слота. Повторяю это, выбирая Соединения, rде в разделе слот указываю новое имя. Затем меняю, чтобы не пyraться в файлах .срр и .ь имя: void bookWidget::portopenclicked() virtual void portopenclicked(); Сохраняю эти файлы. Пытаюсь сохранить файл bookwidgetbase.ui, но он не хочет сохраняться. Тоrда в выпа дающем меню формы выбираю Разорвать расположение, сохраняю файл и повторяю Lay Out in а Grid, сохраняя файл. В итоrе проект собирается и запускается. В редакторе ин терфейса я добавляю кнопки, которые называю portclose и ButtonGroup (и то, и дрyrое из меню common Widgets СЛ ва). Текст rруппы кнопок я меняю на rостиная (двойной щел чок текста на форме открывает редактор текста). Пока не за был, я вношу добавления в файлы bookwidget.cpp: void bookWidget::portcloseclicked() { } ; и bookwidget.h: virtual void portcloseclicked(); 
Проrрамма для компьютера в KDevelop 353 Затем открываю в редакторе интерфейса раздел Слоты и добавляю новый слот с помощью кнопки Добавить ФУНК- цию: portcloseclicked() Отказываюсь rенерировать новый класс. Добавляю новое соединение с помощью раздела Соединения и кнопки Но- вое, щелкая левой кнопкой мыти ячейки таблицы: Sender  portclose Сиrнал  clicked() Receiver  bookwidgetbase Слот  portcloseclicked() И все сохраняю. Для завершения этоrо этапа работы я добавляю еще две кнопки Свет включить, Свет выключить и из раздела инст рументальноrо меню Display этикетку PixmapLabel. Их я пока не оформляю. С PixmapLabel история простая  я попытался сделать включение и выключение ламп, как это делал в Visual Basic, но не получилось. Я не стал на этом «зацикливаться» И ретил обойти проблему. В rрафическом редакторе KolourPaint я делаю полоску 350х30, которую закрашиваю в желтый цвет, а картинку сохраняю как light (рисунок Portable Pixmap) в папке проекта. Теперь картинку по умолчанию я поменяю на свой рисунок, который и будет изображать включенный свет (рис. П.15). Под кнопкой Свет выключить на основной форме я pac положил еще одну TextLabel, которую назвал answer. Ее я предполаrаю использовать для получения ответа от релей Horo модуля для запроса статуса реле. Вот, собственно, что я предполаrал сделать в rрафичес ком плане. И хотя по дороrе я несколько раз наступал на 'rрабли, это были еще не «те» rрабли. С caMoro начала меня беспокоила и продолжает беспоко ить сейчас возможность работы с СОМпортом. Среда про rраммирования в явном виде не предоставляет мне такой возможности, как это было в Visual Basic. Первое, что прихо дит В rолову,  поискать в Интернете. И не напрасно. Я Hax жу пакет qextserialport O.9.0, автор KOToporo: 
354 Приложение ,'. . 1. '!"",,,.)IjI"'I' bQol.' t. l»'<I.'>wrd'f''1b.' I - $(' .м..,р /  rf х . l)Jaq ВIi\Д (]poetcт tбopq Oт CUaМePММ eвc:nonoxeнмe QICНO CIJ)8МC tf8C:ТD*a  . . ::'. Q Q. З:":&ii :  i' .,;.ru iU а  ,  1 )  1t1+. :t:j ::з о Q , lI.i' CIl б 1) , (i; ii:. I . н I .:.. .. iI , 1 1 !   ; ... ':::.:.:. :...i c ! ". · ",' · " j 1- 'CIC ';,,  ,... - - ." о О," .. О . . . . " . . . -.' . . 1 T.. та.  C8OiC'nIO '. = : . }п',;}}:ч:. _Q.q::Шv '=d I - :: I r  ,.: IВ sizePoIq. l'  ..!'I.. .. 1-' .._.---  .",1 ,.<,:. : , : : ' 1 :: ::=:е ЭZ767. .! VIews". ,::.".х;:..... : : I . :: IВ sizelnc:rement О, О L  " ":} . J  , ..........: " ' :: ,. "' С' :  001, DIspIay(КDE . .1 , .. :. ....,......... ,! .. -- I..... . . ' (КDE) . ' .' ,....,.. Н..'.".А ...., ..... о" :::  Чя.м.!1VI8tC.. II1IUt (КDE ':::,  .":'-' ,'. ... . . , . А '.' . .- ",.'.., ,.., , . . . ....... ....... .:. '. '-0.,  VIews(КDE) ". .-.;' : 7:-.':: . .:::.   8!!I... ;et....... ".  (КDE)". :.-.:::" ........... ...................................... :" .M1 .. '1 Gr8phIc s (КОЕ)  1 lbeI 1 .. . .> . i 1 11IUt(IФЁ:Р iм <;,.. ." spacer2 ! cu_ '. . .< "х' ,1:;:",h,',,:'( :' .. button . ,": '*0'-'.  ........". ../,._........" .".""'.'//.." .'.'.' .0.-'. ..... ..';.,;' '..".'.... .... .? '. '.. . .. '..' '..'. . . . ._. ........ ..0...' ... .. ...1./ .'" . Q6sNI6oNWt , 1;00. -т;" . " 314........ .  rue . I .. JbOOIC2 J ... Нapм&/IIotI08  ... i ; , '1 ' .  ::'.." ''O. ,VeVbl.nrw.x..... i".Коп.ОмPrQbIмItQТочкм-к-  cr8QSU': .., ЩI!III04МТ8 на форме ДIIIt 8C'11IIIIat t8Xt 18beI Рис. П.15. Изображение включенноrо света в nporpaMMe \class PosixQextSerialPort \version o.o (prealpha) \author Wayne Roth предлаrает исходные тексты классов объектов для KpOCC платформенноrо применения при работе с последователь- ным портом. С объектами разных классов мы, в сущности, уже рабо- тали, коrда создавали интерфейс. Почитав у Липпмана то, что относится к классовой сущности языка С++, я в какой то мере осознал, что класс  это классно. Но как применить навеняка очень полезное и rpaMoTHoe творение Вэйна Рота к моей простенькой проrрамме, я понять не Mory. Однако почти уверен, что есть разные пути и способы, и по: чти уверен, что я их не знаю. Для начала я просто создаю собственный класс, который добавляю в проrрамму. Посколь ку этот механизм работает, я, не мудрствуя лукаво, добавляю в проrрамму исходные тексты проrраммы, написанные Вэй ном Ротом. Для моих целей хватает posixqextserialport и qextserialbase. Я добавляю в проект и файлы заrолов ков, и основные файлы. 
Проrрамма для компьютера 8 KDevelop 355 Второй, быть может не менее важный для меня момент осознания,  куда и что добавлять? Я понимаю, что следует записать: #include <posixqextserialport.h> #include <qextserialbase.h> но куда? И опять я t не мудрствуя лукаво, добавляю эти записи в файл, rде происходят все события моей проrраммы,  bookwidget.cpp и ero файл заrоловка. Не знаю, насколько это правильно, но это срабатывает. Проrрамма транслируется без отибок, проект собирается. Кстати, проект, который я собирал, я назвал так же, как в Visual Basic  barby (по име ни боrатой куклы  Barbie). К этому проекту и обратимся в дальнейшем. ЫО rpафический интерфейс выrлядит практически так же, как выте приведен ный. Файл barbywidget.cpp (аналоrично файлу bookwidget.cpp) выrлядит следующим образом. Втора. вереи. основной nporpaMMbI на .зыке С++ * Copyright (С) 2006 Ьу Vladimir Gololobov * vgololobov@yandex.ru /******************************************************** * * * * * This program is free software; уои сап redistribute it and/or modify * * it under the terms of the GNU General Public License as published Ьу * * the Free Software Foundation; either version 2 of the License, or * * (at your option) апу later version. * * * * This program is distributed in the hope that it will Ье useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR  PARTICULAR PURPOSE See the * * GNU General Public License for more details. * * * * Уои should have received а сору of the GNU General Public License * 
356 Приложение * along with this programi if not, write to the * Free Software Foundation, Inc., * 59 Temple Place  Suite 330, Boston, МА 021111307, USA. * *********************************************************/ * * #include <qlabel.h> #include <posixqextserialport.h> #include qextserialbase.h> #include Abarbywidget.h A char commandon[7] = "R14$lN"; char commandof[7] = AR14$lFA; PosixQextSerialPort comPort(A/dev/ttySOA); // Это позволяет использовать rотовый класс. barbyWidget::barbyWidget(QWidget* parent, const char* name, WFlags fl) barbyWidgetBase(parent,name,fl) { light>sеtЕпаЫеd(FАLSЕ)i//Здесь light  этикетка с желтой картинкой. } barbyWidget::barbyWidget() {} /*$SPECIALIZATION$*/ void barbyWidget::portopenclicked() { comPort.setName(A/dev/ttySO"); // Далее следуют установки порта СОМ1. comPort.setDataBits(DATA8)i comPort.setStopBits (STOPl); comPort.setBaudRate (BAUD2400)i comPort.open(O)i if (comPort.isOpen(» { label>setText( Aport ореп" ); // Это переделанная этикетка. \ 
Проrрамма для компьютера в KDevelop 357 } void barbyWidget::portcloseclicked() { comPort.close(); if (!comPort.isOpen(» label>setText( "port close A ); } void barbyWidget::lightonclicked() { comPort.writeBlock(commandon, 6); light>setEnabled(TRUE); } void barbyWidget::lightoffclicked() { comPort.writeBlock(commandof, 6); light>setEnabled(FALSE)i } #include "barbywidget.moc" Файл заrоловка barbywidget.h: /*************************************************** * Copyright (С) 2006 Ьу Vladimir Gololobov * * vgololobov@yandex.ru * * * * This program is free softwarei уои сап redistribute it and/or modi fy * * it under the terms of the GNU General Public License as published Ьу * * the Free Software Foundationi either version 2 of the License, or * * (at your option) апу later version. * * * * This program is distributed in the hope that it will Ье useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR А PARTICULAR PURPOSE. See the * * GNU General Public License for more details * * * 
358 Приложение * Уои should have received а сору of the GNU General Public License * * along with this programi if not, write to the * Free Software Foundation, Inc., * 59 Temple Place  Suite 330, Boston, МА 021111307, USA. * ********************************************************/ * * #ifndef BARBYWIDGETH #define BARBYWIDGETH #include Abarbywidgetbase.h A #include <posixqextserialport.h> #include <qextserialbase.h> class barbyWidget : public barbyWidgetBase { Q...OBJECT public: barbyWidget(QWidget* parent = О, const char* name = О, WFlags fl = О ); ....barbyWidget()i /*$PUBLICFUNCTIONS$*/ public slots: /*$PUBLICSLOTS$*/ virtual void portopenclicked(); // Это бывшая клавиша buttom. virtual void portcloseclicked(); // Далее добавленные клавиши. virtual void lightonclicked(); virtual void lightoffclicked()i protected: /*$PROTECTEDFUNCTIONS$*/ protected slots: /*$PROTECTEDSLOTS$*/ } ; #endif 
Проrрамма для компьютера в KDevelop 359 После запуска проrраммы, щелчка кнопки СОМ] от- крыть и кнопки Свет включить получаем вид проrраммы, показанный на рис. П.lб. --$ t 8тр. ZJ..... 1И1 4tI 1 _ п".......... п..QII ССТ'" e. ... . . Камn..or"l) -..' .. к HJdHIII ".. ДOlfOlIll""" nаПICО!  ЯЬ ;ваТ\1"" vl u,nlr _. ....{ r" .,.'> ' t. Elocfrlf: ARCHI'J  з-фыn.\, :.: r.roc:тмнм. ......;....... од n;: \ I ,c..т. pcn ...... 1I.000)Ha .," i ",""'Jfiho.. ("'J .. 0601... f  r*t"",.обоа., :  'GlUPI . .;( I . 1.f.ТlF 1..- '{f} СШАEI:', Рис. П.16. Вид работающей nporpaMMbl Первая неожиданность  проrрамма работает, но модуль не реаrирует на команды. Ситуация повторяет начало рабо ты с портом в части проверки конвертера. Первое, что yдa ется проверить с помощью мультиметра,  наличие измене ний сиrналов на входе конвертера. Если поменять порт (то ecrb /dev/ttyS1), напряжение на сиrнальном-выводе рстанется неизменным. Это хорото. Но плохо, что модуль не реаrиру ет на команды. На всякий случай я возвращаюсь к проrрам ме на Visual Basic и проверяю работу модуля. Сомнений не Остается  модуль отрабатывает команды. Пользуясь тем, что модуль работает, проверяю сиrналы интерфейса RS485 в проrрамме, работающей с Visual Basic. Затем я перезаrружаю операционную систему и запускаю 
360 Приложение проrрамму из KDevelop. Спустя некоторое время, удается за метить, что сиrнал RTS на 3 выводе микросхемы МAX1483 сбрасывается в «О» при открытии порта. Добавление в про- rpaMМY в разделе настроек после открытия порта исправля- ет ситуацию. Модуль выполняет команды. comPort.opn(O); comPort.setRts (FALSE); 11 Добавпекная строка Теперь остается разобраться с командами запроса статуса реле. Модифицированная проrрамма выrлядит следующим образом: #include <qlabel.h> #include <posixqextserialport.h> #include <qextserialbase.h> #include "barbywidget.h" char commandon[7] = AR14$lNA; char commandof [7] = "R14$lF"; char commandst[7] = "R14$lS A ; char answerst[19] = А int i = о; posixQextSerialPort comport(A/dev/ttySOA); barbyWidget::barbyWidget(QWidget* parent, const char* пате, WFlags fl) : barbyWidgetBase(parent,name,fl) { light>setEnabled(FALSE); } barbyWidget::barbyWidget() {} /*$SPECIALIZATION$*/ void barbyWidget::portopenclicked() { comPort.setName("/dev/ttySOA)i comPort.setDataBits(DATA8); comPort.setStopBits (STOPl); 
Проrрамма для компьютера в KDevelop 361 comPort.setBaudRate (BAUD2400); cornPort.open(O); cornPort.setRts (FALSE); answer>setText(P И}; if (comPort.isOpen(» { label>setText( "port open" ); } } void barbyWidget::portcloseclicked() { comPort.close(); if (!comPort.isOpen(» label>setText( "port close" ); answer>setText(" И); } void barbyWidget::lightonclicked() { comPort.writeBlock(commandon, 6); соmРоrt.writеБlосk(соmmапdst, 6); while (!comPort.atEnd(»; for (i=0;i<100000000;++i); comPort.readBlock(answerst, 18); answer>setText(answerst); if (answerst[17] == "N") light>setEnabled(TRUE); } void barbyWidget::lightoffclicked() { comPort.writeBlock(commandof, б); comPort.writeBlock(commandst, б); while (!comPort.atEnd(»; for (i=0;i<100000000;++i); comPort.readBlock(answerst, 18); answer>setText(answerst); if (answerst[17] == "F") light>setEnabled(FALSE); } #include "barbywidget.moc" 
362 Приложение в основном, изменения касаются чтения ответа в буфер порта после отправки запроса: while (!comPort.atEnd()); for (i=0;i<100000000;++i); comPort.readBlock(answerst, 18); Пустой цикл for добавлен, чтобы ответ был полностью получен. Массив char answerst [19] служит для чтения бу- фера ввода порта, и сохраняемые им команды содержат все, что было отправлено (рис. П.17). , _ n,..IIOJI(..... "... Сие,.... .. .  8тр 1!3...... 13:37 1(000nbIorl1P 1(""731<' . ..:. . -- " ",. ; EleI:'nc ДOllа qq nan",a по,ьзовэrе1t<l..I-,QmJf .1iW rc OМi J rrОС1'МН8Я'  '7'"": ..., AflCl-1lV f"". ....«. ... :-. ,. I l' ,. ) сеет 1t4UIIO'IПD.J i Ceeт:  I ОАТЕ port ..... .1..I_I"fl..14". kоози а .  .) . . -liIr/lJlJo...  r - 0608... t!':I 8dmIr - OIIa8щ j ." GI 4 U1.nfl 1: США а Рис. П.17. Прием ответа модуля в nporpaMMe в правом нижнем yrлу формы отображается содержание этоrо массива. Поэтому в проверке ero содержимоrо я про веряю только последний символ: if (answerst [17] == "N") Возможно, не лучтим образом, но механизм работает. По команде выключения света свет на картинке выключается. 
Разветвитель 8идеосиrнала 363 На макете, естественно, по команде включения света зarора ся индикатор, который racHeT по команде выключения света. Запланированная часть работы выполнена. Две поnеЭНЬlе схемы Первая схема относится к настенному выключателю, работа ющему по протоколу X10. Что полезноrо можно почерпнуть из этой схемы? Например, орrанизацию сканирования сети и управления триаком. Схему я привожу, как она сохранилась в архиве (рис. П.18). Вторая схема  датчик движения. Датик работает по pa диоканалу. Стоит он в Москве 36 долларов. Возможно, есть и более низкие цены на эти датчики. Если вам захочется поэк спериментировать с датчиками движения, и вы можете себе позволить купить ero, он может казаться более разумным ретением, чем сборка собственноrо датчика движения,  линза, мне кажется, сложна для самостоятельноrо изrотовле ния, и может стоить достаточно дороrо. Кроме Toro, можно использовать в экспериментах передатчик, которым снабже но устройство. Протокол X10 использует разные команды дЛЯ IR и RFпосылок, если я не отибаюсь. Но с этим можно разобраться на месте, если вы захотите использовать датчик движения вместе с ero радио каналом (рис. П.19). Раэветвитеnь видеосиrнаnа Подключение бытовой аудиоаппаратуры к системе, думаю, не вызовет затруднений. Даже к линейному выходу музыкальноro центра или видеомаrнитофона можно параллельно вклю чить несколько приемников (телевизоров или управляемых усилителей) без заметноrо ухудтения качества звука. Если же вы используете системный aYд>"'9KoMмyraTop, добавить развя зывающие усилители тоже несложно. Можно использовать транзисторы, проверить работу предполаrаемой развязки в проrраммах, о которых я rоворил выше, и добавить к cxe ме KOMмyraTopa дополнительные элементы. 
364 Приложение -......- Т""" с.с О JS 0(,) S . .... c. :t: m S а.И U Е> om O ф13 ('1) Q) .... .... '1:) . m= JS U>(J)(J) Jr JS ]5 :I: IJ JS S (,) S :I: m ' :I: S а. s U ,из U @ ф (J) Q) .... Q) ::) '1:) . '1:) 00 со :J:U ::>О 11 JS ::о :t: (,) m а. о о Z > I I CO,.....<DLt') ('I) Т"""О Т"""Т"""Т"""Т"""Т"""Т"""Т"""Т""" 1"- <о (/) as а. ф u. s а. E:t о m > '" I '" Q) Q) )( r... U m < СО с: ci s n.
+V +V c I .I..B1 А1 I LED1 Разветвитель видеосиrнала 365 +V С2 +V А1 .J РВ1 HOUSE) Рис. П.19. Схема датчика движения MS 12А Еще проще можно орrанизовать работу, применяя опе рационные усилители. Практически любой из них обеспечит необходимую полосу пропускания. Усиления не требуется, а добавить реryлировку усиления можно с целью обеспече ния одинаковой rромкости всех приеМНИI\ОВ сиrнала. HeMHoro сложнее обстоят дела с «перемещением» видео сиrнала. По этой причине я привожу схему, опубликованную в журнале «Радио» (рис. П.20). Как правило, выходное сопротивление всех источников видеосиrнала рассчитано на подключение коаксиальноrо кабеля с волновым сопротивлением 75 Ом. Такое же входное сопротивление имеют приемники. Если для передачи сиrнала вы используете коаксиальный кабель, использование разветвителя ясно. Но, если у вас нет желания вместе с проводами системы укладывать еще и KoaK сиальный кабель, для системных нужд можно использовать 
366 П р иложение ОА1   47 мкх168 ВХОД видео 0.1 мк + 5..12В 3 [> 8 + +U 2 56 Выход видео 1 Выход видео 2   47мКх168 0.1 мк + 5..128 5 [> 4 + +U 6 56 Выход видео 3 Выход видео 4 ОА1 AD812AN Рис. П.20. Схема разветвителя видеосиrнала витую пару в кабеле (САТ 5), имеющем 4 витые пары, а OCTaB тиеся пары применить для передачи видеосиrнала. Волновое сопротивление витой пары, если я не отибаюсь,  120 ОМ. Разветвитель видеосиrнала в этом случае должен иметь резис торы на выходе микросхем 120 Ом. Входное сопротивление приемников желательно тоже увеличить до 120 Ом, иначе, в этом я убедился на собственном опыте, второе изображение на экране телевизора будет слитком заметно. Оно возникает изза отражений в несоrласованной линии. Особенно удобно использовать разветвитель подобной KOH струкции, коrда в одно помещение вы проложили коасиаль ный кабель, а в дрyrое вынуждены передавать сиrнал по витой паре. В такой ситуации просто установите одно из сопротив лен ий на выходе микросхемы 75 Ом (в ориrинале 56 Ом), а дрyrое  120 Ом. Или примените две микросхемы. Возмож ность менять усиление в активном разветвителе сиrнала oкa зывается не только полезной, но и необходимой. Есть недороrой набор, предлаrаемый фирмой Мастер КИТ,  NM2901. С ero помощью вы соберете разветвитель видеосиrнала rораздо быстрее. Есть и дрyrое ретение  при менить конвертер ДЛЯ преобразования видеосиrнала в радио-- сиrнал на частоте одноrо из свободных каналов телевидения, 
Схемы для зкспериментов с радиоканалом 367 а этот радиосиrнал подметать к эфирному телевидению. Те- перь обычный «краб», который у вас уже работает, «переме- стит» видеосиrнал по всему дому. Конвертер сделать несколько сложнее, но ero преимуще ство в том, что вы можете к радиосиrналу добавить и звуко вой сиrнал. Отпадает необходимость в заботах о коммyrации и передаче звука. Можно также купть rOToBbIe конвертеры подобноrо рода, но стоят они дороже, чем пара микросхем. схемыnRзксnериментовB с радиоканапом Если вам захочется провести эксперименты с радиоканалом вместо проводной связи модулей, то: . лучте было бы воспользоваться rотовыми радиомоду лями, но дороrо; . не забывайте, что вати эксперименты MOryт метать ватим соседям; . не забудьте о проrраммах, о которых rоворилось выте; . проверяйте все решения на устойчивость; . может существовать множество интересных ретений, что само по себе  целое «поле чудес» для творчества. Схемы, приведенные на рис. П.21, надеюсь, помоryт вам начать эксперименты. Я не помню источник, откуда появи лись эти схемы в моем архиве, думаю из литературы по ради управляемым моделям. Хоротие решения можно найти в co ответствующей литературе. Интересно было бы использовать цифровые схемы для этих целей. Я встречал подобные устрой ства в Интернете, но эксперименты в этой области не прово- дил, поэтому не rOToB предложить rOToBoe ретение. Элементы схемы: С1 == 0,1 мкФ, C2C4 == 200 пФ, С5 == 1000 пФ, C6C7 == 520 пФ, СВ == 10 пФ. R1 == 2,4 кОм, R2 == 4,3 кОм, R3 == 2,4 кОм, R4 == 4,7 кОм, R5 = 100 Ом. L1, L2, L5  дроссели индуктивностью 50 MKrH (5060 вит ков провода ПЭЛШО 0,1, намотанных виток к витку на Kap касе диаметром 5 мм). 
368 Приложение А1 С5 + UПИТ МОДУЛЯЦИЯ 0-1 С1 А2 РИС. П.21. Схема АМ прередатчика на 27 мrц L3L4  катушки, намотанные на одном каркасе диамет- ром lOMM проводом ПЭЛШО 0,35 виток к витку и имеющие 6 и 8 витков. VТ1  транзистор практически любоrо типа, например KT3102, Vf2, высокочастотный транзистор типа rт311 или аналоrичный. Напряжение питания Uпит == 45 В. Режим питания reHepaTopa выIокойй частоты, собранноrо на транзисторе VТ2, определяется значениями резисторов делителя R1R2, а режим работы caMoro транзистора Vf2  значениями резисторов делителя R3R4 и резистора R5, KO торый задает, в основном, рабочий ток транзистора Vf2. Конденсаторами С6 и С7 передатчик настраивается на частоту 27 Мfц. На работу высокочастотноrо reHepaTopa больтое влия ние оказывает выбор транзистора VТ2, который должен быть достаточно высокочастотным, в противном случае re нератор может не возбуждаться на частоте 27 мrц. Назначение reHepaTopa, собранноrо на транзисторе Vf2,  выработать сиrнал высокой частоты, который станет «Hecy щей» для информационноrо сиrнала, подаваемоrо на вход, обозначенный на схеме как «модуляция». Именно модулиру ющий сиrнал и передаст информацию, которую мы хотели бы перенести «через эфир»: речь диктора или музыку 
Схемы для экспериментов с радиоканалом 369 вещательной радиостанции, сиrнал дистанционноrо управ ления моделью и т.п. Модуляция высокочастотноrо сиrнала информационным происходит блаrодаря изменению амплитуды несущеrо сиr нала при изменении питающеrо напряжения reHepaTopa. Транзистор Vf1, на вход KOToporo поступает медленно изме няющийся (по сравнению с rенерируемым сиrналом) ин формационный сиrнал, в такт с ним изменяет напряжение питания задающеrо reHepaTopa, тем самым «модулируя», Ha полняя нужной нам информацией сиrнал с частотоji 27 мrц. Модулированный высокочастотный сиrнал через антенну WA1 излучается в пространство и может быть принят прием ником, настроенным на частоту, на которой работает BЫCO кочастотный reHepaTop. Конечно, для устойчивой работы передатчика на выбран ной частоте желательно стабилизировать высокочастотный reHepaTop кварцевым резонатором, но для эксперименталь ных целей это не обязательно. Если у вас нет опыта по работе с радиоустройствами, я бы посоветовал следующий порядок работы: использовать пр rpaMMbI, о которых я рассказывал, для проверки работы cxe мы на компьютере. Изменяя величину резистора R4 в дели теле R3R4, постараемся определить, что будет происходить с током В эмиттерной цепи транзистора VТ2 (рис. П.22). Схему я несколько изменил, приблизив ее к ретению, K торое предполаraется использовать в экспериментах. В пе вом случае резистор имеет одно из крайних значений. Ток, который показывает амперметр, составляет доли микроамп ра. Переведем ero в дрyrое крайнее значение (рис. П.23). Ток во втором положении резистора при наличии ВЧиr-- нала значительно возрастает. Теперь, собрав передатчик, п стараемся настроить ero так, чтобы ток в измеряемой цепи составил lO20 мА. Есть надежда, что при этом передатчик излучает сиrнал. Полезно воспользоваться простой схемой 'для проверки работы передатчика (рис. П.24). Компоненты схемы  WA1, тонкий металлический штырь длиной 2030 см; Cl 3пФ, С2 конденсатор переменной eMKOC ти с воздушным диэлектриком емкостью 520 пФ, С3 150 пФ; 
370 Приложение ..:t' ';:...,.:.......< .. < . . < ;{H \.!} '" .':: -?-y, ... "'. "" ... $ ''; .I.IHY,." tlUМLIII , :*:{:;:1::::* ': B "12'.:*ki:':.r .': .._..  -- . I ?  lсэ "lJXJtI R2 2.0 .111 v LA 3.Q.t4 J'!'l I -  .11. R5 .:. 5Y 4.31d1 св IIIQ# I[f .. " -f" '1'f . :.1' =! :12!!... 1'l'_ .....'- . :1If .__ ... ....л.. ...f. \IIIIW ... . \IIIIW О)'. M1.",{.j 1. 1, ._-, ',,'-"', -."'- _ n.. .'-' "'-,.-.' 'f':;4 :.:.:; :.-;:::.._:} Рис. П.22. ТОК эмипера при отстутствии ВЧсиrнала :<;[r i   >;::":'; tI uм LIII  !.; 1ПIl't i 1 1 .и v 1") 51 ......, J.. сэ "lJXJtI R2 24110 LA R5 ch.:' 'V 5V 4.31d1 .... "" . . ";  : ... ? .. : - ,,, ... "-. ....... .,'... , ..-.:: , .-- J :rI/:' _, м..., v :,8 "',' ....;. -. . . I " -(4 "'-<;;- .. ':?iJ: :; .. ; . "'" J. i!! .. ." '= Wt ::s r- i :1  .. !.. ..... J1' ;'ti .... ".У 'D.n_. >. -..... .....- ' _ ' _ , . , ...л.. , __ _, ' \IIIIW :,......... ., 1 ., .fR' .':'.,> . .iнN;:... . ..".- .. ... 1:':' .,::< .  lri«\: . ,.е , '"'" . __'H ' fr ''-: 'f::;' Рис. П.2З. ТОК эмипера при наличии ВЧсиrнала ;,' V -.,. .'. - . 
Схемы для экспериментов с рОДИОКаНаЛОМ 371 у: WA 1 С1 Рис. П.24. Индикатор поля VD1 Д2В; катушка L1, намотанная на каркасе 12 мм и имеющая 1214 витков провода ПЭВl 0.8 с отводом от середины, ин дуктивность катушки L2 30 MKrH, РА1 микроамперметр на ток полноrо отклонения 100 мкА. В качестве микроамперметра можно использовать мультиметр, включенный в режим изме рения тока. По сyrи, индикатор поля  детекторный приемник, Harpy женный на микроамперметр. Можно вывести ручку KOHдeH сатора входноrо контура (С2) на переднюю панель и проrра дуировать индикатор с помощью reHepaTopa стандартных сиrналов, к выходу KOToporo подключают отрезок монтажно ro про вода длиной 2030 см, а антенну индикатора располаrа ют рядом. Изменяя частоту reHepaTopa, настраивают индика тор на максимальное отклонение стрелки микроамперметра и считывают частоту со ткалы reHepaTopa. Для экспериментов можно использовать входную часть приемника. Соберем приемник по схеме, показанной на рис. П.25. Схема приемника (данные можно использовать те же, что и у передатчика на 27 мrц, а конденсатор Сl взять емкостью в 100 пФ) предлаrается ДЛЯ экспериментов. Может быть ис пользована любая друrая. В качестве транзисторов VТ1, VТ2 можно задействовать транзисторы rT311 или аналоrичные. Для соединения радиоприемника с микроконтроллером PIC 16F628A интересно было бы использовать встроенный KOM паратор или установить внетний. В крайнем случае, использ<r вать быстродействующий операционный усилитель в качестве компаратора или микросхемы серии К561. Здесь MHoro вариан тов, rлавное добиться стабильной раБотыI радио канала 
372 Приложение WA1 СЗ C1J: =; + + Uпит С2 R2 Рис. П.25. Схема приемника на 27 мrц для экспериментов с радиоканалом После сборки приемника, используя в качестве модулиру- ющеrо сиrнала передатчика reHepaTop на 400 rц, следует под- ключить приемник к усилителю и настроить ero так, чтобы тональный сиrнал бьт слытен при разнесении приемника и передатчика на расстояние в несколько метров. Хорошо бы настроить передатчик на 27 мrц, но как это сделать без из- мерительных приборов, я не знаю. Лучте не увлекаться мощ- ность передатчика, оrраничив расстояние YBepeHHoro при- ема несколькими метрами. Убедивтись в работоспособности радио канала, можно приступить к экспериментам по передаче управляющих сиr- налов. Не забудьте, что при отcyrствии управляющих сиrна- лов, передатчик должен быть выключен. HeMHoro о nроrраммировании на С++ Поскольку при проrраммировании микроконтроллера я ис- пользовал язык С, мне показалось уместным добавить хотя бы несколько слов о языке. Но я не сделаю это лучше, чем с. Липпман. Коrда мне понздобилось познакомиться с языком, я использовал ориrинальную версию ero книrи «Essential С++». Фраrменты Moero конспекта (или перевода) я включаю в Приложение, но советую эту книry приобрести. 
HeMHoro о проrраммировании на С++ 373 Как писать nporpaMMЫ на С++ Положим, нам нужно написать простую проrрамму, отправ ляющую сообщение на терминал пользователя, которое про сит ввести имя. Мы прочитываем введенное имя, сохраняем, чтобы использовать в дальнейтем, и, наконец, приветству ем пользователя по имени. Прекрасно, откуда начнем? Начнем там, откуда начинают ся все проrраммы на С++  с функции, называемой main () . main ( ). Внедряемая пользователем функция в следующей основной форме: in t та i n ( ) { // код нашей проrраммы далее} rде int  это ключевое слово языка С++. Ключев'ые слова  предопределенные имена, имеющие особое значение в язы ке. int представляет встроенный целый тип данных. Фу1t'К'ЦUЯ  независимая последовательность кодов, произ водящих некие выкладки. Она состоит из частей: возвращае Moro типа, имени функции, списка параметров и тела Функ ции. Рассмотрим каждую из нихх по очереди. Возвращаемый тип функции обычно представляет резуль тат вычислений (выкладок). main () имеет целый возвращае мый тип. Значение, возвращаемое main ( ) , показывает, было ли выполнение натей проrраммы успетным. По соrлате нию main () возвращает «О» при удачном выполнении. Heнy левое значение показывает, что чтото идет не так. Имя функции выбирается проrраммистом из соображе пий наилучтим образом определить, что функция будет дe лать. min () и sort ( ) , например,  хоротие имена функций. f () и g () не так хороти. Почему? Они менее информативны в отнотении назначения функции. main 'He ключевое слово. Система компиляции, выполня- ющая нату проrрамму С++, предполаrает, что функция mai () предопределена. Если мы забудем включить ее, про rpaMMa не будет работать. СПJ:lСОК параметров функции заключен в крyrлые скобки и размещен за именем функции. Пустой список параметров, 
374 Приложение как у main ( ) , обозначает, что параметры функции не переда- ются. Список параметров,  обычно разделяемый запятой пере- чень типов данных, которые пользователь может передать функции при ее выполнении. (Мы rоворим, что пользова- тель вызывает или активизирует функцию). Например, если мы напитем функцию min ( ) , возвращающую наименьшее из двух значений, ее список параметров должен определить типы двух значений, которые мы сравниваем. Функция min () для сравнения двух целых чисел может быть определена сле- дующим образом: int min(int val1, int va12) { // код проrраммы следует здесь ...} Тело проrраммы заключено в фиryрные скобки {}. Оно содержит последовательность кодов, которая осуществляет все действия функции. Двойная прямая косая черта / / озна- чает пояснения, заметки проrраммиста по какимто аспектам кодов. Они предназначены для читающих исходный текст проrраммы и выбрасываются при компиляции. Все, следую- щее за прямой двойной косой чертой до конца линии, отно- сится К комментарию. Ната первая задача  написать вывод сообщения на тер- минал пользователя. Ввод и вывод в языке С++ не предопре- делены. Вернее, они поддерживаются объектноориентиро- ванным классом иерархии, встроенным в С++ как часть стандартной библиотеки языка. Класс  тип данных, определяемых пользователем. Меха- низм работы классов  метод добавления типа данных, рас- познаваемоrо натей проrраммой. Объектноориентирован- ная иерархия классов определяет семейство относительных типов класса, например терминала и файловоrо ввода, тер- минала и файловоrо вывода и т.д. С++ предопределяет небольтое множество основных ти- пов данных: булевы, символьные, целые и с плавающей точ- кой. Хотя они служат основой для Bcero проrраммирования, мы не будем сосредотачивать на них внимание. Кинокамера, например, должна иметь положение в пространстве, обыч- но представляемое тремя числами в формате с плавающей 
HeMHoro о проrроммировонии на С++ 375 точкой. Камера должна, кроме Toro, иметь ориентацию в пространстве, описываемую еще тремя числами с плаваю щей точкой. Есть еще одно отнотение, описывающее OTHO шение расстояния до камеры к высоте предмета. Оно пред ставлено единственным числом с плавающей точкой. На очень 'примитивном уровне можно сказать, что камера представлена семью числами с плавающей точкой, тесть из которых образуют две rруппы координат х, у, z. П роrраммиро вание на это низком уровне требует, чтобы мы направляли нашу мысль то назад, то вперед  от манипуляций с абстракт ной камерой к манипуляции с семью числами с плавающей точкой, представляющими камеру в проrрамме. Механизм классов позволяет нам добавить в проrрамму уровни абстракции типов. Например, мы можем определить класс трехмерных точек для представления локализации и ориентации в пространстве или класс Камер, состоящий из двух объектов класса трехмерных точек и числа с плавающей точкой. Мы все еще представляем камеру семью числами с плавающей точкой. Но разница в том, что в натей проrрам ме мы теперь можем напрямую манипулировать с классом Камер, а не с семью числами с плавающей точкой. Определение класса обычно разбивается на две части, каждая из которых представлена своим файлом: фйлом за rоловка, производящим объявление операций, поддержива емых классом, и файлом текста проrраммы, который coдep жит реализацию этих операций. Для использования класса мы включаем в проrрамму файл заrоловка. Файл заrоловка делает класс узнаваемым проrраммой. Стандартные библиотеки ввода/вывода в С++ вызываются из библиотеки iostream. Она содержит подбор ку связанных классов, поддерживающих ввод и вывод на пользовательский терминал и в файлы. Чтобы использовать библиотеку класса iostream, мы должны включить ассоции рованный с ней файл заrоловка: #include <iostream> Для обращения к терминалу пользователя мы используем предопределенный объект класса, названный cout (произ носится «си ayr»). Мы направляем данные, которые хотим, 
376 Приложение чтобы cout написал, пользуясь оператором вывода ( « ), сл ДУЮЩИМ образом: cout « "Please enter your first naт: "; Это представлено выражением проrраммы С++, малень ким независимым кусочком проrраммы на С++. Это аналоr предложения в обычном языке. Выражение завертается точ кой с запятой. Нате выражение питет строчку символов (отмеченных кавычками) на терминале пользователя. Ка- вычки идентифицируют CTpO они не отображаются на тер- минале. Пользователь видит: Please enter your first пате: Ната следующая задача  прочитать ввод пользователя. Прежде чем мы сможем прочитать имя, напечатанное пользователем, мы должны определить объект, в котором сохраним информацию. Мы определим объект, обозначив тип данных объекта и дав ему имя. Мы уже видели один тип данных int. Но трудновато использовать ero для хранения чьеrолибо имени. Больте подходит тип данных из стандар- тной библиотеки CTpoKoBoro класса: string username; Это определяет username, как объект CTpoKoBoro клас- са. Определение названо заявительным предложением. Это предложение не будет приниматься до тех пор, пока мы не сделаем строковый класс известным проrрамме. Мы осуществляем это включением файла заrоловка CTpOKOBO ro класса: #include <string> Для чтения ввода с терминала пользователя, мы использу ем предопределенный объект класса, называемый cin (произ носится «СИ ин»). Мы используем оператор ввода ( » ) для направления cin на чтение данных с терминала пользователя в объект подходящеrо типа: cin » username; 
HeMHoro о проrраммировании на С++ 377 Последовательности вывода и ввода появятся на термина ле пользователя следующим образом (ввод пользователя OT мечен жирным трифтом): Please enter your first name: anna Все, что нам остается сделать,  поприветствовать польз вателя по имени. Мы хотим, чтобы вывод выrлядел так: Hello, anna ... and goodbye! Понимаю, это не верх совертенства. Но терпение  мы только начали. Позже мы научимся более изящным вещам. Первый шаr для вывода приветствия  перенаправить ero на следующую строку. Мы сделаем это, написав символ новой строки в cout: cout « I \п I ; Символы обозначаются двумя апострофами. Существует две разновидности символов: печатные символы: буквы ( · а', · А' и т.д.) , числа и знаки препинания (. ; " · . и т.д.), И He печатные символы: символ перевода строки ( I \n · ) или табу ляция (. \ t ,). Поскольку нет символьноrо представления непечатных символов, самый общий пример  символ пере- вода строки и табуляция, они представляются специальной последовательностью из двух символов. Теперь, перейдя на новую строку, мы хотим воспроизвес ти Неllо: cout « "Hello, "; Дальте нам нужно вывести имя пользователя Оно coxpa нено в строковом объекте username. Как мы сделаем это? Так же, как и с дрyrими типами: cout « username; Наконец, мы завертаем приветствие, сказав «прощай» (обратите внимание, что строка символов может содержать оба вида: как печатные, так и непечатные символы): cout « " ... and goodbye! \п" ; 
378 Приложение В основном, все встроенные типы выводятся тем же пу- тем  помещаем значение справа от оператора вывода. На- пример, cout « "3 + 4 = " . , cout « 3 + 4; cout « "\n"; дает следующий вывод: 3 + 4 = 7 Так же, как мы определили новые типы класса дЛЯ НС. пользования в приложении, проводим привязку оператора вывода для каждоrо класса. Это позволяет пользователям класса выводить ero отдельные объекты совершенно одина- ковым образом со встроенными типами данных. Вместо написания отдельных выводов каждый на своей строке мы можем объединить их в одно предложение: cout « "\п" « "Hello, " « username « .. .... and goodbye! \n" ; В завертении мы можем завертить main ( ), используя выражение return (возврат): return О; return  ключевое слово С++.. Выражение, следующее за ним, в данном случае «О», представляет результат выполнения функции. Напомню, что возвращаемое функцией значение «О») rоворит об успетном завертении работы. Соберем кусочки вместе  получим нату первую завер шенную проrрамму на С++: #inclиde <iostrearn> #iпclиde <striпg> using narnespace std; // пока не объясняю этоrо ... i n t та i n ( ) { striпg иsername; cout « ""Please enter your first пате: "; 
HeMHoro о проrраммировании на С++ 379 cin » usernamei cout « "\n" « "Hello, .. « username « " ... and goodbye! \n"; return о;} После компиляции при выполнении этот KД проиведет следующее (МОЙ ввод подсвечен жирным шрифтом): Please enter your first пате: аnnа Hello, anna ... and goodbye! Одно выражение я не пояснил: using namespace std; Посмотрим, CMOry ли Я объяснить это, не напуrав вас. (Сделайте rлубокий вдох!). using и namespace  ключевые слова С++. std  имя стандартной библиотеки namespace. Все, выбираемое из стандартной библиотеки (как объекты CTpoKoBoro класса, класса iostream  cout и cin) заключено внутри, std namespace. Конечно, ват следующий вопрос: а что такое namespace? namespace  метод упаковки библиотечных имен, при KO тором они MO:ryr быть использованы в окружении пользова тельской проrраммы без появления коллизий. (Коллизия имен обнаруживается, коrда есть два использования OДHO ro и Toro же имени в приложении, так что проrрамма не может различить их. Коrда такое случается, проrрамма не может продолжать работу, пока не разретится KOH фликт имен). Namespaces  способ, оrраждающий види мость имен. Для использования объектов CTpoKoBoro класса и класса iostream  cin и cout  внутри натей проrpаммы мы должны не только включить файлы заrоловков string и iostream, но так же сделать имена видимыми с std namespace. Использова ние директивы: using namespace std; простейший метод сделать имена внутри namespace (про странство имен) видимыми. 
380 Приложение Опреде.nеиltе It ltиltqlta.nltзаqltА 06ъектов даии...х Теперь, чтобы завладеть вниманием пользователя, выпол ним короткий тест. Мы отобразим два числа из числовой последовательности и предложим пользователю yraдaTb сле дующие значения в последовательности. Например, The values 2,3 from two consecutive elements of а numerical sequence. What is the next value? Эти значения  третий и четвертый элементы из последо вательности Фибоначчи: 1, 1, 2, 3, 5, 8, 13 и т.д. Последова тельность Фибоначчи начинается с двух элементов  единиц. Каждый следующий элемент это сумма двух предтеству ющих. Если пользователь введет 5, мы поздравим ero и спросим, хочет ли он попробовать друryю числовую последователь ность. Любое друrое введенное значение  неверно, и мы спросим пользователя, хочет ли он поrадать еще. Чтобы поддержать интерес к проrрамме, мы сохраним текущий счет, основанный на отнотении правильных OTBe тов к числу попыток. Проrрамма нуждается, по меньтей мере, в пяти объектах: объекте CTpoKoBoro масса для сохранения имени пользоват ЛЯ, трех целых объектах класса для запоминания по очереди попыток, числа попыток, числа успетных попыток, и объект класса чисел с плавающей точкой для запоминания счета. Для определения объектов данных мы должны ввести имена и тип данных. Имена MOryr быть любыми комбинаци ями букв, цифр, подчеркиваний. Буквы реrистрозависимые. Каждое из имен username, Username, uSeRnArnE и userName относится к разным объектам. Имя не должно начинаться с цифры. Например, lname неправильно, namel  правильно. Также имя не должно co впадать с ключевыми словами языка. Например, delete  ключевое слово языка, так что мы не должны использовать 
HeMHoro о проrроммировонии на С++ 381 ero в натей проrрамме. (Это объясняет, почему оператор удаления символа из CTpoKoBoro класса  это erase ( ) , а не delete ( ) ). Каждый объект должен быть cBoero типа данных. Имя объекта позволяет нам обратиться к нему непосредственно. Тип данных определяет область значений, сохраняемых объектом, и количество памяти, необходимой для запомина ния этоrо значения. Мы видели определение username в предыдущем разде ле. Перенесем то же определение в новую проrрамму: #include <string> string username; Класс  проrраммноопределенный тип данных. С++ TaK же подцерживает множество встроенных типов данных: бу левы, целые, с плавающей точкой и символьные. Ключевые слова, ассоциированные с каждым из них, позволяют нам определить тип данных. Например, для запоминания значе ния, введенноrо пользователем, мы определим объект цело ro типа: int usrval; int  ключевое слово языка определяющее, что объект usrval  целоrо типа. Оба объекта: число попыток, сделан ных пользователем и число правильных ответов,  объекты целоrо типа. Разница только в том, что мы бы хотели дать им начальное значение «О». Мы можем вывести каждое на OT дельную строку: int numtries = о; int numright = о; или определить их в одной строке через запятую: int numtries = о, numright = о; в общем, лучте придерживаться правила инициализиро вать объект данных, даже если значение только обозначает, 
382 Приложение что объект не имеет полезноrо значения вовсе. Я не инициа- лизировал usrval, потому что значение будет получено непосредственно из пользовательскоrо ввода прежде, чем проrрамма как-то использует объект. Альтернативный вариант инициализации  использовать так называемый конструкционный синтаксис int numtries(O); Почему есть два инициализационных синтаксиса? Хуже Toro, почему я сейчас об этом rоворю? Что ж, посмотрим, отвечает ли мое объяснение на оба вопроса. Использование оператора присваивания для инициализа ции притло из языка С. Оно хорошо работает с объектами данных встроенных типов и классами объектов, которые MOryт быть инициализированы единственным значением, например строковым классом: string sequencename = "Fibonacci"; Однако данный способ не так хорош ДЛЯ класса объектов, которые требуют нескольких значений для инициализации, как, например, класс стандартной библиотеки комплексных чисел, rде каждое требует двух значений: первое  для дей ствительной части, второе  для мнимой. Альтернативный конструкционный синтаксис был введен для поддержки мно- rозначной инициализации: #include <complex> complex<double> purei(O, 7); Странная нотация скобок, следующая за cornplex, означа- ет, что класс комплексных чисел  класс таблонов. Класс таблонов позволяет нам определять класс без специфика- ции типа данных одноrо или всех членов класса. Класс комплексных чисел, например, состоит из двух чле- нов объекта данных. Один представляет реальную часть чис- ла, второй  мнимую. Эти члены должны быть числами типа данных с плавающей точкой, но KaKoro? С++ поддерживает три типа чисел с плавающей точкой: единичной точности, представляемых ключевым словом float; двойной точности, представленной ключевым словом double; и растиренной 
HeMHoro о проrраммировании на С++ заз точности, представленной двумя ключевыми словами long double. Механизм класса таблонов позволяет проrраммисту OT кладывать определение типа данных, используя класс табло- нов. Это дает ему возможность вставить «заrлушку», которую позднее он заполнит реальным типом данных. В предыдущем примере использовался выбор данных типа класса комплек сных чисел double. Что ж, возможно, появляется больте вопросов, чем полу- чается ответов. Это происходит от Toro, что таблоны, поддер- живаемые С++, двух инициализационныIx синтаксисов для встроенных типов данных. Коrда встроенные типы данных и проrраммно определенный класс типов имеют разный иници ализационный синтаксис, невозможно написать таблон, KO торый поддерживает и встроенный класс, и класс типа дан- ных. Унификация синтаксиса упрощает разработку таблонов. К сожалению, раскрытие синтаксиса приводит к появлению еще больтей пyrаницы! Счет пользователя должен быть значением с плавающей точкой, поскольку возникает нецелое отнотение. Мы опре делим ero типом double: double usrscore = 0.0; Нам также нужно сохранить место для ответов пользова теля yes/no: Make another try? Try another sequence? Мы можем сохранить ответы пользователя в СИМВОЛЬНОld объекте данных: . char usrmore; cout « "Try another sequence? Y/N? "; cin » usrmore; Ключевое слово char относится к символьному типу. Символ окаймляется апострофами, обозначая 'а', · 7 " I ; · И т.д. HeKO торые специальные встроенные символьные обозначения при ведены ниже (их иноrда называют эскейп последовательности): \n' newline (новая строка) "\t" tab (табуляция) "\0" null (нуль) "\". single quote (апостроф) "\'" double quote (кавычки) "\\" backslash (обратная косая черта) 
384 Приложение Например, для создания перевода на новую строку и табу- ляции перед вводом имени пользователя мы можем написать: cout « "\n" « "\t" « username; Можно также объединить в строку отдельные символы: cout « "\n\t" « usernamei Обычно мы используем эти специальные символы в бук- венной строке. Например, для представления пути к файлу в системе Windows необходимо ставить обратные косые чер- точки: "F:\\essential\\programs\\chapter1\\ch1main.cPP"i С++ поддерживает встроенный булев тип данных для представления значений true/false. В натей проrрамме, например, мы можем определить булев объект для контроля над необходимостью вывода на дисплей следующей числ<r вой последовательности: Ьооl goforit = true; Булев объект обозначен ключевым словом bool. ОН M<r жет сохранять два буквенных значения: true или false. Все определенные объекты данных затем модифицируют- ся в ходе нашей проrраммы. goforit, например, в конеч- ном счете, установится в false, а usrscore обновляется с каждой попыткой пользователя. Иноrда необходимо наличие объекта для представления постоянных значений: максимальноrо числа попыток, опре- деляемых для пользователя или значения числа «пи». Объек- ты, сохраняющие эти значения, не будут меняться по ходу проrраммы. Как мы можем предотвратить случайное измене.- ние данных объектов? Заручиться подцержкой языка, объя- вив эти объекты, как const: const int maxtries =3; const double pi = 3.14159; Объекты const не MOryr изменяться после инициализации их значения. Любые попытки переустановить значение объек- та const приведyr к отибке при компиляции. Например: maxtries = 42; // error: объект const 
HeMHoro о проrраммировании на С++ 385 Написание выражений Встроенные типы данных поддерживаются набором опера торов: арифметических, лоrических, отнотения, CTPYKТYpo образующих. Арифметические операторы не имеют особен ностей, исключая деление целых и получение остатка. // Арифметические операторы + сложение а + Ь  вычитание а  Ь * умножение а * Ь / деление а / Ь % остаток а % Ь Деление двух целых значений выдает целое. Любой OCTa ток отсекается, и это не окруrление. Остаток получается с помощью оператора %: 5 / 3 результат 1 тоrда, как 5 % 3 имеет результат 2 5 / 4 результат 1 тоrда, как 5 % 4 имеет результат 1 5 / 5 результат 1 тоrда, как 5 % 5 имеет результат О В каких С.!lYЧаях мы нуждаемся в операторе получения oc татка? Представьте, что мы хотим печатать не более BOCЬ ми слов В линии. Если количество слов меньте восьми, мь] выводим пробелы после слов. Если строка состоит из BOCЬ ми или более слов, мы выводим переход на новую строку (newline): const int linesize = 8; int cnt = 1; // это выражение выполняется MHoro раз со // строками, представленными разными значениями, / / и cnt увеличивается на единицу при каждом проходе... cout « astring« (cnt % linesize ? " " : "\n"); Выражение в скобках за оператором вывода, похоже, не имеет для вас значения, пока вы не освоите условный опера тор (? :). Результат выражения  либо пробел, либо переход на новую строку  в зависимости от Toro, нулевое или Heнy левое значение принимает оператор остатка. Посмотрим, какой смысл мы можем ему придать. Выражение cnt % linesize превращается в ноль, коrда cnt достиrает значения linesize; иначе оно не равно нулю. 
386 Приложение Что это означает для нас? Условный оператор имеет основ- ную форму: expr? executeifexpristrue: executeifexprisfalse; выражение?выполнятьесливыражениеистинно: выполнятьесливыражениеложно; Если expr (выражение) принимает значение true, выра- жение, следующее за знаком вопроса, выполняется. Если expr принимает значение false, выполняется выражение, следующее за двоеточием. В натем случае выражение CTaH вится либо пробелом, либо переводом на новую строку для оператора вывода. Условное выражение обрабатывается как ложное (f al se), если ero значение равно нулю. Любое ненулевое значение принимается как true. В примере, пока cnt не делится на восемь, а результат не нулевой, выполняется переход опера- тора по условию true, и печатается пробел. Оператор CTpyктypHoro присваивания дает краткую нота- цию при применении арифметической операции для зада ния объектов. Например, чтобы не писать: cnt = cnt + 2; проrраммист С++ обычно питет: cnt += 2; // прибавить 2 к данному значению cnt Структурное присваивание применимо к каждому ариф- метическому оператору: +=, +, /=, и %=. Коrда к объекту прибавляется или вычитается 1, про rраммист С++ использует операторы увеличения или yмeHЬ тения: cnt++; // добавляет 1  значению cnt (инкремент) cnt; // вычитает 1 из значения cnt (декремент) Существует префиксная (до) и постфиксная (после) раз- новидность операторов увеличения и уменьтения. В пре- фиксном написании объект увеличивается или уменьшается на 1 до Toro, как ero значение используется: int tries = о; cout « "Are уои ready for try #"« ++tries « "?\n"; 
HeMHoro о проrраммировании на С++ 387 tries увеличивается на 1 до вьшода ero значения. В постфикс- ном написании значение объекта вначале используется в Bыpa жении, а затем увеличивается (или уменьтается) на 1: int tries = 1; cout « "Are уои ready for try #"« tries++ « "?\n"; Теперь значение tries выводится до Toro, как увеличива ется на 1. В обоих примерах значение 1 выводится. Каждый из операторов сравнения принимает значение true или false. Их Bcero тесть: == равно а == Ь != не равно а != Ь < меньше чем а < Ь > больше чем а > Ь <= меньше чем или равно а <= Ь >= больше чем или равно а >= Ь Вот пример Toro, как мы можем использовать оператор равенства (эквивалентности) для проверки ответа пользова теля: Ьооl usrmore = true; char usrrsp; // спросим пользователя хочет ли он продолжить // прочитаем ответ в usrrsp if (usrrsp == "N") usrmore = false; Условное выражение if выполняет предложение, следую- щее за ним, если выражение в скобках принимает значение true. В данном примере usrmore устанавливается в false, если usrrsp равно 'N'. Если usrrsp не равно 'N', не дела ется ничеrо. «От противноrо», используя оператор HepaBeH ства, можно написать так: if (usrrsp != "Y")usrmore = false; Проблема с проверкой usrrsp только на значение 'N' в том, что пользователь может ввести ответ в нижнем реrист- ре, то есть 'n'. Мы должны распознать оба значения. Одна из стратеrий  добавить else: if (usrrsp == "N") usrmore = false; 
388 Приложение else if (usrrsp == "n") usrmore = false; Если usrrsp равно 'N', то usrmore устанавливается в false и больте ничеrо не делается. Если оно не равно 'N', выполняется else. Если usrrsp равно I n 1, то usrmore при нимает значение false. Если же значение usrrsp не равно ни тому, ни дрyrому, значение usrmore не определяется. Одна из распространенных отибок начинающих про rраммистов  использование оператора присваивания при проверке равенства, как показано ниже: // раз, и присвоили usrrsp символ "N" // а теперь всеrда условие принимает значение true if (usrrsp = "N") // Лоrический оператор ИЛИ (1 1) предлаrает альтернатив ный пyrь проверки истинности во множественных выраже ниях: if (usrrsp == "N" I I usrrsp == "n")usrmore = false; Лоrический оператор ИЛИ становится истинным (true), если любое из выражений истинно. Левое выражение прове ряется первым. Если оно истинно, следующее выражение не проверяется. В натем примере usrrsp проверяется на pa венство 'n', только если оно не равно 'N'. Лоrический оператор И (&&) становится истинным, толь ко если оба выражения истинны. Например, if (password &&validate(password) && (acct = retrieveacctinfo(password») // процесс доступа ... Верхнее выражение проверяется первым. Если оно лож но, оператор И принимает значение false, а остальное BЫ ражение не проверяется. В данном случае информация дo ступа принимаеся только при введении правильноrо пароля. 
HeMHoro о проrроммировании на С++ 389 Лоrический оператор НЕ (!) принимает значение true, если выражение, которому он принадлежит, имеет значение false. Например, вместо записи: if (usrmore == false) cout « "Your score for this session is " « usrscore < < " Буе! \ n " ; мы можем написать: if (! usrmore) ... Оператор nредwествоваии. Есть одна «заморочка» В использовании встроенных опера торов  при комбинации нескольких операторов в одном выражении порядок выполнения операций определяется предустановленным уровнем приоритетности для каждоrо. Например, результат выражения 5 + 2 * 10 всеrда равен 25 и никоrда 70, поскольку оператор умножения имеет больтий приоритет, чем оператор сложения. В итоrе 2 всеrда умножа ется на 10 прежде, чем складывается с 5. ;- Мы можем переопределить приоритет, взяв в скобки опе рацию, с выполнения которой хотели бы начать. (5 + 2) * 10, например, принимает значение 70. Для операторов, о которых я rоворил, предопределенные уровни приоритетности написаны ниже. Оператор, KOTO рый выте, имеет больтий приоритет, чем тот, что ниже. Операторы, расположенные в одну линию, имеют порядок определения слева направо. лоrическое NOT арифметическое (*, /, %) арифметическое(+, ) отношение «, >, <=, >=) отношение (==, !=) лоrическое AND лоrическое OR присваивание 
390 Приложение Например, для определения четности i val мы можем на- писать: ival % 2 // не совсем хорошо Наше выражение проверяет результат оператора остатка. Если i val четно, результат нулевой и лоrический оператор НЕ становится истинным. Иначе, если результат ненулевой, лоrический оператор НЕ принимает значение false. Во вся- ком случае, так нам хотелось бы. К сожалению, результат выражения совершенно иной. Наше выражение всеrда будет ложным, исключая значение ival, равное нулю! Более высокий приоритет оператора лоrическоrо отри- u цания приводит к тому, что он выполняется первым, деи- ствуя на i val. Если i val имеет ненулевое значение, резуль- тат  ложный, в противном случае  истинный. Полученное значение становится левой частью операции получения остатка. False становится «О» при использвании в ариф- метических операциях, а true принимает значение «1». В результате порядка выполнения операций выражение превращается в 0%2 для любых значений ival за исключе- нием нуля. Хотя мы не хотели получить данный результат, он не является отибкой, по крайней мере, языковой ошибкой. Это лишь неправильное представление натей задуманной проrраммной лоrики. Компилятор об этом, конечно, не до- rадывается. Порядок выполнения  это одна из причин, зат- рудняющих проrраммирование на С++. ДЛЯ правильноrо выполнения выражения мы должны изменить порядок вы- полнения с помощью скобок: ( i val % 2) / / ok Чтобы избежать этих проблем, необходимо поближе П знакомиться с порядком следования операторов в С++. Я вам не помощник, в том смысле, что раздел не содержит ни пол- Horo перечня операторов, ни полноrо представления поряд- ка следования операций  Toro, что я показал, должно хва- тить только для начала. 
HeMHoro о проrраммировании на С++ 391 Написание усповий и соэдание qиКIIОВ По определению, выражения выполняются по разу по мере прохождения проrраммы, начиная с первоrо выражения main ( ) . в предыдущих разделах мы кратко rоворили о Bыpa жении if. Оно позволяет нам выполнять по условию одно выражение или их последовательность, основываясь на BЫ числении истинности условия. Дополнение else дает воз можность проверить несколько условий. Циклические Bыpa жения позволяют выполнять одно выражение или их последовательность, основываясь на вычислении истиннос ти. Следующий псевдокод проrраммы использует два цикла (#1 и #2), один условный оператор if (#5), один условный оператор ifelse (#3), и второй условный оператор, назы ваемый switch (переключатель) (#4). // Pseudo code: Основная лоrика проrраммы  пока пользователь хочет уrадывать последовательности { #1 вывести на дисплей последовательность пока уrадано неверно, и пользователь хочет уrадать еще раз { #2 прочитать rипотезу увеличить счетчик попыток если уrадано правильно { #3 увеличить счетчик уrадываний установить gotit в true } else { выразить сожаление по поводу неудачной попытки сделать запрос на основании текущеrо номера попыток пользователя // #4 спросить пользователя, хочет ли он попытаться еще раз и //прочитать ответ, если пользователь отвечает нет // #5 установить goforit в false } } } 
392 Припожение усло.....е ...раже.... Условия выражения i f должны быть записаны в круrлых скобках. Если они истинны, выражение, непосредственно следующее за i f, выполняется: /1 #5 if (usrrsp == "N" I I usrrsp  "п") goforit = false; Если должно выполниться несколько выражений, они должны быть заключены в фиryрные скобки, следующие за if (это называется блоком выражений): //#3 if (usrguess == nextelem) { /1 начало блока выражений numright++; gotit = true;} // окончание блока выражений Общая ошибка начинающих  забыть отметить блок: // рраз: пропущена отметка блока // только numcor++ относится к if, // а gotit = true; выполняется вне условия if (usrguess == nextelem) numcor++; goti t = true; Выполнение goti t отражает намерения проrраммиста. К сожалению, оно не отражает поведение проrраммы. Нара- щивание numcor относится к условному оператору if и BЫ полняется только тоrда, коrда попытка пользователя эквива лентна значению nextelem. gotit, однако, не относится к условному оператору, поскольку мы забыли обозначить два выражения как блок. В этом примере goti t всеrда устанав- ливается в значение true независимо от Toro, что делает пользователь. Условный оператор if так же поддерживает расширение else. Else представляет одно выражение или блок выраже ний, которые будут выполняться, если условие принимает значение false. Например, if (usrguess == nextelem) { 
HeMHoro о проrраммировании на С++ 393 /1 пользователь уrадал } else { // пользователь не уrадал } Дрyrое использование оператора else  объединить два условных выражения. Например, если попытка пользовате ля неудачна, мы хотим варьировать ответ в зависимости от числа попыток. Мы должны написать три проверки как неза висимые условные выражения: if (numtries  l)cout « "Yyx! Хорошая попытка, но не совсем. \п" ; if (numtries  2)cout « "Mдa. Извини. Опять неправильно. \п"; if (numtries == 3)cout « "Aa, это труднее, чем моrло показаться, не так ЛИ?\П"i Однако только одно из трех условий может быть истинным одновременно. Если одно из условий верно, остальные долж ны быть ложны. Мы можем отобразить зависимость между выражениями i f, объединив их вместе с помощью выраже ний ifelse: if (numtries  1) cout « "Yyx! Хорошая попытка, но не совсем\n"; else if (numtries  2) cout « "Mдa. Извини. Опять неправильно.\п"; else if (numtries == 3)cout « "Aa, это труднее, чем моrло показаться, не так ЛИ?\П"i else cout « "Похоже, дальше бесполезно!\п"; Первое условное выражение выполняется. Если оно истин но, выражение, следующее за ним, выполняется, а последова тельность el se i f  нет. Если же первое условное выражение ложно, выполняется следующее, затем следующее, пока одно из условий не становится истинным или numtries не CTaнo вится больше 3,  все условия ложны, и последнее else выпол няется. 
394 Припожение Один из неприятных аспектов использования вложенных ifelse  трудности с правильной их лоrической орrаниза цией. Например, мы хотели бы использовать ifelse для разделения лоrики проrраммы на два случая: коrда пользова тель yraдbIBaeT и коrда он не yraдbIBaeT. Первая попытка не работает совсем, как мы и планировали: if (usrguess == nextelem) { // пользователь уrадывает } else if (numtries == 1) else /1 ... выводим вопрос if (numtries == 2) else // ... выводим вопрос if (numtries == з) else /1 ... выводим вопрос // ... выводим вопрос // теперь спросим у пользователя, хочет ли он еще раз уrадать // но только, если он не уrадал // рраз! и куда же мы воткнем это? Каждая пара elseif непреднамеренно была сделана аль тернативой удачной попытки. В результате нам некуда поме-- стить вторую часть кода для поддержки неудачных попыток. Вот правильная орrанизация: if (usrguess == nextelem){ // пользователь уrадал} else { // пользователь не уrадал if (numtries == 1) else / / ... if (numtries == 2) else / / ... if (numtries == з) // ... else // cout « .Желаете попробовать еще? (Y/N) "; char usrrSPi cin » usrrSPi if (usrrsp == "N" I I usrrsp  .n") goforit = falsei} 
HeMHoro о проrраммировании на С++ 395 Если значение проверяемоrо условия имеет интеrраль ный тип, мы можем заменить набор ifelseif выражени ем swi tch: . // равноценно ifelseif выше switch (numtries) { case 1: cout « "Yyx! Хорошая попытка, но не cOBceM\n" break; case 2: cout « "Mдa. Извини. Опять неправильно.\п"; break; case з: cout « "Aa, это труднее, чем моrло показаться, не так - ли? \ п" ; break; default: cout « "Похоже, дальше бесполезно!\п"; breaki } Ключевое слово switch с последующим выражением в круrлых скобках (да, имя объекта работает, как выражение). Выражение должно вычисляться как целое значение. Серия меток case, следующая за ключевым словом switch, опреде ляет постоянное выражение. Результат выражения сравнива ется с каждой из меток case по очереди. Если есть совпаде ние, выражение, следующее за case, выполняется. Если совпадений нет, и метка default присyrствует, выполняется выражение, следующее за ней. Если же нет ни совпадений, ни метки default, не делается ничеrо. Почему я поместил выражение break в конце каждой MeT ки case? Каждая метка case проверяется по очереди на co впадение со значением выражения. Каждая несовпадающая метка case пропускается по очереди. Коrда обнаруживается совпадение, выражение, следующее за меткой, выполняется. Увы, выполнение продолжается со следующими метками, пока не будет достиrнут конец меток. Если значение numtries, 
396 Приложение например, равно 2, и если нет выражений break, вывод бу дет выrлядеть так: // output if numtries == 2 and // we had forgotten the break statements Mдa. Извини. Опять неправильно. Aa, это труднее, чем моrло показаться, не так ли? Похоже, дальше бесполезно! Вторая метка case совпадает, все метки case, следующие за совпадающей, также выполняются, пока не завершается оператор. Этот алrоритм дает выражение break. Вы можете спросить: почему выражение switch так устроено? Вот при мер этоrо провала, который придется в самый раз: switch (nextchar) { case "а": case "А" : case "е": case "Е" : case "i": case "1": case "о": case "О" : case "и": case "U" : ++vowel cnt; break;// . . . } ЦИКllЬ. Циклы выполняют выражения или блоки выражений до тех пор, пока выражение условия не становится истинным. Ната проrрамма требует двух циклов (один вложен в дру- rой). Пока пользователь желает yraдbIBaTb последоватеЛЬН<F сти: { выводить на дисплей последовательности пока доrадка неверна, а пользователь желает уrадать еще раз} цикл while в С++ вполне подходит для нашей цели: Ьооl nextseq = true; // показать следующую оследовательность? bool goforit = true; // пользователь хочет продолжить уrадывание? -Ьооl gotit = false; // пользователь уrадал? int numtries = О; // количество попыток int numright = о; // количество правильных ответов 
HeMHoro о проrраммировании на С++ 397 while (nextseq == true){ // вывести на дисплей последовательность для пользователя while ((gotit == false) &&(goforit == true»{ int usrguess; cin » usrguess; numtries++; if (usrguess == nextelem) { gotit = true; numcor++; } else { // // // if false; } } // конец вложенноrо цикла while cout « "Want to try another sequence? (Y/N) " char tryagain; cin » tryagain; if (tryagain == "N" I I tryagain  "n")nextseq = false; } // конец while(nextseq == true) пользователь не уrадал сказать, что ответ неверен спросить, еще уrадываем? (usrrsp == "N" I I usrrsp  "п") goforit = Цикл while начинается с вычисления выражения условия в круrлых скобках. Если оно истинно, выражение или блок выражений, следующий за циклом while, выполняется. Пос ле выполнения выражения (блока) выражение условия об новляется. Этот цикл обновления/выполнения продолжает ся, пока условие не станет ложным. Обычно некоторое условие внутри исполняемоrо блока устанавливает условное выражение в состояние false. Если выражение условия ни коrда не становится ложным, мы rоворим, что отибочно попали в бесконечный цикл. Наш внешний цикл while выполняется, пока пользова тель не скажет, что хочет остановиться: Ьооl nextseq = true; while (nextseq == true){ // ... if (tryagain == "N" I I tryagain  "n")nextseq = false; } 
398 Припожение rде при инициализации nextseq в false блок выражений не будет выполняться. Вложенный цикл while позволяет пользователю выполнять множество аналоrичных попыток. Цикл может быть прерван внутри выполняемоrо блока выполнением выражения break. В следующем фраrменте кода цикл while выполняется, пока triescnt не станет paB но maxtries. Однако если пользователь дает правильный ответ, цикл прерывается выражением break: int maxtries = зi int triescnt = о; . while (triescnt < maxtries){ // прочитываем попытку пользователя if (usrguess == nextelem) break; // прерываем цикл triescnt++;// more stuff } Проrрамма может иметь быстрое завершение текущеrо выполнения цикла, выполнив выражение continue. Напри мер, рассмотрим следующий фраrмент проrраммы, в котором все слова, в которых больте четырех букв, отбрасываются: string word; const int minsize = 4; while (cin » word) { if (word.size() < minsize) // прерываем этот цикл continue; // попадаем сюда, только если слово // больше или равно minsize ... processtext(word);} Если слово меньте minsize, выполняется выражение continue. Результатом выполнения выражения continue яв ляется прерывание текущеrо прохождения цикла. Остаток тела цикла while (в данном случае  processtext () не BЫ полняется. Вернее, цикл начинается заново, с новым вычис лением условия, которое прочитывает дрyrое значение CTp ки в word. Если word больте или равно minsi ze, полное тело цикла выполняется. В этом случае все слова, имеющие боль те четырех букв, отбрасываются. 
HeMHoro о проrраммировании на С++ 399 Как исnопЬЗ0Вать массив... и вектор... Ниже приведены первые восемь элементов из шести число вых последовательностей: Fibonacci: 1, 1, 2, 3, 5, 8, 13, 21 Lucas: 1, 3, 4, 7, 11, 18, 29, 47 Pell: 1, 2, 5, 12, 29, 70, 169, 408 Triangular: 1, 3, 6, 10, 15, 21, 28, 36 Square: 1 , 4, 9, 16, 25 , 36, 49, 64 pentagonal: 1, 5, 12, 22, 35, 51, 70, 92 Наша проrрамма должна выводить на дисплей пары эле ментов из последовательности и позволить пользователю yraдaTb следующий элемент. Если пользователь yraдbIBaeT и желает продолжить, проrрамма должна вывести на дисплей следующую пару элементов, затем третью, и так далее. Как мы можем это сделать? Если следующая пара берется из той же последовательно сти, пользователь, разrадавтий одну пару, yraдaeT их все. Это не интересно. Так что будем брать следующую пару из друrой числовой последовательности при каждом проходе OCHOBHO ro цикла проrраммы. Теперь будем ВВIВОДИТЬ на дисплей максимум шесть пар элементов за сессию: по одной паре из каждой из тести пос ледовательностей. Мы постараемся сделать это так, чтобы при выводе на дисплей пары элементов не знать, из какой числовой последовательности будет взята пара при следую щем проходе цикла. Каждый проход должен иметь доступ I< трем значениям: паре элементов и элементу, следующему за ней в последовательности. Ретение, которое мы обсудим в этом разделе, использует контейнерный тип, способный поддржать смежную после довательность целых значений, которые MOryr быть доступ ны не по имени, а по позиции' в контейнере. Мы запомнили 18 значений в контейнере как подборку тести rрупп: первые v два в rруппе представляют пару для вывода на дисплеи, Tpe тий  следующий элемент в последовательности. При каждом проходе цикла мы добавляем три индексных значения, про ходя по тести rруппам по очереди. 
400 Приложение в С++ мы можем определить контейнер либо как BCTpoeH ный массив, либо как вектор класса стандартной библиоте ки. В основном, Я рекомендую использовать класс векторов, а не встроенные массивы. Однако есть резон использовать массив, и важно понять, как использовать оба варианта. Для определения BCTpoeHHoro массива мы должны об значить тип элементов массива, дать ему имя и обозначить размер  количество элементов, которые массив должен co держать. Размер должен быть константой, то есть выражени ем, которое не меняется во время выполнения проrраммы. Например, следующий код объявляет pellseq массивом из 18 целых элементов. const int sesize = 18; int pellseq[sesize]; Для определения 'объектов класса векторов мы должны вначале включить файл заrоловка vector. Класс векторов  шаблон, поэтому мы определяем тип элементов в уrловых скобках, следующих за именем класса. Размер помещается в круrлых скобках, он не обязательно должен быть постоян ным выражением. Следующий код определяет pellseq как объект класса векторов, содержащий 18 элементов типа int. По определению каждый элемент инициализируется в «О». #include <vector> vector<int> pellseq(sesize); Мы добираемся до элементов: массива или вектора, опреде ляя ero ПО;JИЦИЮ в контейнере. Этот элемент индексируется с использованием оператора списка индексов ([]). Одна потен циальная «незадача» В том, что первый элемент находится в позиции «О», а не «1». Последний элемент индексируется на 1 меньте, чем размер контейнера. Для pellseq правильные индексы  от О до 17, а не от 1 до 18. (Эта ошибка настолько распространена, что заслуживает иметь собственое имя: пе- чально известная оffЬупшибка). Например, для получе- ния первых двух элементов последовательности РеП мы пишем: pellseq[O] = 1: // присваиваем 1 первому элементу pellseq[l] = 2; // присваиваем 2 второму элементу 
HeMHoro о проrраммировании на С++ 401 Вычислим следующие десять элементов последовательнос ти РеП. Для прохождения через элементы вектора или масси ва мы обычно используем цикл for  дрyrой базовый цИКЛ С++. Например, for (int ix = 2; ix < sesize; ++ix) pellseq[ix] = pellseq[ix  2] + 2*pellseq[ix  1]; Цикл for состоит из следующих элементов: for (начальное значение; условие; индексация) выражение; Начальное значение выполняется единожды перед BЫ полнением цикла. В натем примере ix инициализируется как «2» перед началом выполнения цикла. Условие служит для контроля над циклом. Оно вычисляет ся перед каждой итерацией цикла. Так что, сколько итераций при вычисленном условии равном true, столько раз выраж ние выполняется. Выражение может быть единственным или блочным. Если первое условие не удовлетворяется, выраж ние не выполнится никоrда. В нашем примере условие пров ряет, меньте ли ix, чем seCLsize? Индексация вычисляется после каждой итерации цикла. Она обычно используется для модификации начальноrо зна чения объекта и проверяется в условии. Если первое вычис ление условия принимает значение false, индексация не выполнится никоrда. В натем случае ix увеличивается с каж дой итерацией цикла. Для вывода элементов мы проходим через следующие операции: cout « "ТЬе first " « sesize« " elements of the Pell Series:\n\t"; for (int ix = о; ix < sesize; ++ix)cout « pellseq[ix] « " "; cout « "\n"; при желании мы можем обойтись без начальноrо значения, индексации или (реже) условия для цикла for. Например, мы можем переписать предыдущий цикл как: int ix = о; / / ... for (; ix < sesize; ++ix)// ... 
402 Приложение Точка с запятой необходима, чтобы показать пустое на- чальное значение. Нат контейнер содержит второй, третий и четвертый элементы каждой из тести последовательностей. Как мы за- полним контейнер подходящими значениями? Встроенный массив может специфицироваться инициализационным списком, содержащим список значений, разделенных запя- тыми для всех элементов или подмножества элементов: int elemseq[sesize] = { 1, 2, З, // Fibonacci З, 4, 7, // Lucas 2, 5, 12, / / Pell З, 6, 10, //Triangular 4, 9, 16, // Square 5, 12, 22 // Pentagonal } ; Количество значений, записанных в список инициализа- ции, не должно превытать размера массива. Если мы предла- raeM меньте значений, чем размер массива, недостающие эле- менты инициализируются как «О». При жедании мы можем позволить компилятору вычислить размер массива на основа- нии количества значений, которые включаем в список: // компилятор рассчитает размер в 18 элементов int elemseq [ ] = {1 , 2, З, З, 4, 7, 2, 5, 12, З, 6, 10, 4, 9, 16,5, 12, 22}; Класс векторов не поддерживает список инициализации. Несколько нудным ретением будет присвоение значения каждому элементу отдельно: vector<int> elemseq(sesize); elemseq[O] =1; elemseq[1] =2; // ... elemseq[17] =22; Еще одна альтернатива  инициализировать встроенный массив и использовать ero для инициализации вектора: int elemvals[sesize] = {1, 2, З, З, 4, 7, 2, 5, 12,3, 6, 10, 4, 9, 16, 5, 12, 22 }; 
HeMHoro о проrраммировании на С++ 403 // инициализация elemseq значениями elemval vector<int> elemseq(elemvals, elemvals+sesize); elemseq получает два значения. Эти значения в действи тельности адресованные  они отмечают диапазон элемен тов, с которым вектор будет инициализирован. В этом случае мы отметили 18 элементов, содержащихся в elemvals и KO пируемых в elemseq. А теперь посмотрим, как мы можем .использовать elemseq. Одно различие между встроенными массивами и классом векторов состоит в том, что вектор знает свой раз мер. Нат предыдущий цикл for проходил через BCTpoeH ный массив. Посмотрим, велика ли разница при использо вании вектора: // elemseq.size() возвращает число элементов // содержащихся в векторе elemseq cout « "The first " « elemseq. size ()« " elements of the Pell Series:\n\t"; for (int ix = о; ix < elemseq.size(); ++ix) cout « pellseq[ix] « " "; curtuple представляет собой индекс в текущей после довательности, выводимой на дисплей. Мы инициализиру ем ero в (О»). С каждьм проходом цикла мы добавляем «(3» в curtuple, устанавливая ero для индексации первоrо элемента следующей последовательности для вывода на дисплей: int curtuple = о; while (nextseq == true &&curtuple < sesize) { cout « "The first two elements of the sequence are: " « elemseq [curtuple] « ", " « elemseq[curtuple + 1] « "\nWhat is the next element? "; // if (usrguess  elemseq[curtuple + 2]) // правильно! // if (usrrsp  "N" 11 usrrsp  "п") nextseq = false; else curtuple += Зi } 
404 Приложение Полезно бьто бы сохранять путь к последовательности, которая в настоящий момент активна. Запомним имя каждой последовательности как строку: const int maxseq = 6; string senames [maxseq] = {"Fibonacci", "Lucas", "Pell", "Triangular","Square","pentagonal"}; Мы можем использовать seCLnames следующим образом: if (usrguess == elemseq[curtuple + 2]) { ++numcor; cout « "Very good. Yes, .. « elemseq[curtuple + 2] « " is the next element in the " « senames [curtuple / З] « .. sequence. \n" ; } Выражение сurtuрlе/З получает по очереди О, 1,2,3,4 и 5, индексируя в массиве строк элементы, которые иденти Фицируют активную последовательность. Ука3аТеJlII дalOT 6o.n..we rll6ИОСТII Нате ретение по выводу на дисплей в предыдущей секции имеет два основных недостатка. Впервых, оно оrраничено выводом шести числовых последовательностей  если пользо- втель yraдaeT все тесть, проrрамма сразу завертится. BBTO- рых, она всеrда выводит те же самые тесть пар элементов в той же последовательности. Как же увеличить rибкость про- rpaMMbI? Одно из возможных решений  создать тесть векторов, по одному на каждую последовательность, рассчитанных на одинаковое количество элементов. На каждом проходе цик- ла мы выбираем пары элементов из разных векторов. При повторном использовании вектора мы возьмем пару элемен- тов из дрyrой части вектора. Это приблизит нас к устране- нию обоих отмеченных недостатков. Как и в предыдущем ретении, хотелось бы иметь «про- зрачный» доступ к разным векторам. В предыдущем разделе мы достиrали «прозрачности» за счет доступа по индексам, а не по имени. На каждом проходе цикла мы увеличивали зна- чение индекса на 3. Сам код оставался неизменным. 
HeMHoro о проrраммировонии на С++ 405 в этом разделе мы добьемся «прозрачности» тем, что бу дем обращаться к вектору косвенно, через указатель, вместо обращения по имени. Указатель вносит определенный ypo вень косвенности в проrрамму. Вместо Toro чтобы работать с объектом напрямую, мы будем работать с указателем, coxpa няющим адрес объекта. Мы определим указатель, который будет адресоваться вектору чисел целоrо типа. При каждой итерации цикла мы будем модифицировать указатель, aдp суясь к разным векторам. Фактический код для манипуляций с указателями не изменится. Использование указателей дает два преимущества натей проrрамме: увеличивает rибкость проrраммы и добавляет уровень rибкости, отсутствующий при прямой работе с объектом. Этот раздел убедит вас в правдивости о?оих yт верждений. Мы уже знаем, как определять объект. Следующее Bыpa жение определяет i val как объект целоrо типа int, инициа лизированноrо значением l02: int ival = 1024; Указатель сохраняет адрес объекта данноrо типа. Для оп ределения указателя мы добавляем к имени типа звездочку: int *pii // pi указатель на объект типа int pi  указатель на объект типа int. Как мы должны иници ализировать ero для указания на i val? Определением имени объекта, примерно так: ival; // определяет значение ival Мы определяем ассоциированное значение, в натем слу чае 1024. Для получения адреса объекта, а не ero значения, мы добавляем оператор адресации (&): &ival; // определяет адрес ival Для инициализации pi как адреса i val запитем сле дующее: int *pi = &i val ; Для доступа к объекту, адресуемому указателем, мы долж ны разыменовать указатель, что даст содержимое объекта по 
.406 Приложение адресу, содержащемуся в указателе. Для этоrо добавим звез- дочку к указателю, следующим образом: // разыменовываем pi для доступа к объекту им адресуемому if (*pi != 1024) // читаем *pi = 1024; // пишем Сложность инициализации с использованием указателя, как вы видите, исходит от запутывающеrо синтаксиса. Ви- ною тому двойственная природа указателя. Мы можем мани- пулировать адресом, содержащимся в указателе, а можем манипулировать объектом, на который он указывает. Коrда мы питем: pi; // определяет aдpc сохраняемый в pi то фактически управляем указателем объекта. А коrда мы пишем: *pi; // определяет значение объекта адресуемоrо pi то управляем объектом, адресуемым pi. Вторая сложность в понимании указателей  возможность отсутствия aдpecyeMoro объекта. Например, коrда мы пишем *pi, это может быть, а может и не быть причиной краха про- rpaMMbI при выполнении. Если pi адресуется к объекту, разы- меновывание pi работает совертенно правильно. Если же pi не адресуется к объекту, попытка разыменовать pi влечет непредсказуемое поведение проrраммы во время выполне- ния. Это означает, что коrда мы используем указатель, то должны быть уверены, что он адресуется к объекту, прежде чем сделаем попытку разыменовать ero. Указатель, который не адресуется к объекту, имеет адре- суемое значение «О» (иноrда ero называют нулевым указате- лем). Любой тип указателя может быть инициализирован, или определен со значением «О»: // инициализация каждоrо указателя без адресации к объекту int *pi = о; double *pd = о; string *ps = о; 
HeMHoro о проrраммировании на С++ 407 Для защиты от разыменовывания нулевоrо указателя мы проверяем указатель, чтобы убедится, что ero адресуемое значение не равно «О». Например, if (pi && *pi != 1024)*pi = 1024; Выражение: if (pi && ...) становится истинным, только если pi содержит иной адрес, чем «О». Если оно ложно, оператор И не выполняется во BTO ром выражении. Для проверки мы обычно пользуемся опе ратором лоrическоrо отрицания НЕ: if (! pi) 11 истинно, если pi установлено в О А вот нати тесть объектов векторов последовательностей: vector<int> fibonacci, lucas, pell, triangular, square, pentagonal; На что похож указатель вектора объектов целоrо типа? ЧТО Ж, в общем, указатель имеет такую форму: (типобъектаказывающеrона * имяказателяобъекта) typeofobjectointedto * nameofointerobject Нат указатель адресует тип vector<int>. Назовем ero pv и инициализируем нулем: vector<int> *pv = о; pv может адресоваться каждому вектору последовательн сти по очереди. Конечно, мы можем определить pv aдpeca цией к каждой последовательности: pv = &fibonacci;// ... pv = &lucas; но этим при носится В жертву «прозрачность» кода. Альтер нативное ретение  запомнить адреса каждой последова тельности в векторе. Этот прием позволяет нам добраться. до них «прозрачно», через индекс: const int secnt = 6; // массив secnt указателей на // объекты типа vector<int> 
408 Приложение vector<int> *seaddrs[secnt] = {&fibonacci, &lucas, &pell, &triangular, &square, &pentagonal}; seqaddrs  это встроенный массив элементов типа vector<int>*. seCLaddrs [О] содержит адрес fibonacci BeK тора, se<Laddrs [1]  адрес lucas вектора и т.д. Мы исполь зуем это для доступа к различным векторам через индекс, а не по имени: ector<int> *currentvec = о; // -.. for (int ix = о; ix < secnt; ++ix) { currentvec = seaddrs[ix]; // вывод на дисплей всех элементов осуществляется // косвенно через currentvec } Оставтейся проблемой с задуманной реализацией является полная предсказуемость. Последовательности всеrда Fibonacci, Lucas, РеП... Мы бы хотели сделать вывод на дисплей послед вательностей случайным. Это возможно с использованием стандартной библиотеки языка С функциями rand () или srand ( ) : #include <cstdlib> srand(secnt); seindex = rand() % secnt; currentvec = seaddrs[seindex]; rand () и srand ()  функции стандартной библиотеки, которые поддерживают псевдослучайную rенерацию. srand () активизирует reHepaTop с ero параметрами. Каждый вызов rand () возвращает целое значение в диапазоне от О до максимальноrо целоrо значения, представленноrо int. Мы должны это оrраничить числами от О до 5, чтобы они были правильными индексами seCLaddrs. Оператор остатка (%) rарантирует нам индексацию между О и 5. Файл заrоловка cstdlib содержит объявление обеих функций. Мы сохраняем указатель на класс объекта несколько ина- че, чем делали это с указателем на объект BCTpoeHHoro типа, потому что класс объекта имеет связанное с ним множество 
HeMHoro о проrраммировании НО С++ 409 операций, которые мы можем вызвать. Например, для про- верки, является ли первый элемент вектора fibonacci еди- ницей, можно написать: if (! fibonacci. empty () && (fibonacci [1] == 1» Как мы моrли бы осуществить ту же проверку через pv? Объединение fibonacci и empty () через точку называется оператором 8ъtбора члеиа. Оно используется для выбора опера ций класса через объект класса. Для выбора операции клас- са через указатель используем операторстрелку (» выбора члена: pv>empty ( ) Поскольку указатель может адресоваться к отсутствующ му объекту, перед тем как мы используем empty () через pv, необходимо проверить, что адресация не нулевая: pv && ! pv>empty() Окончательно для вызова оператора индексов мы долж ны разыменовать pv (понздобятся дополнительные скобки BOKpyr разыменованноrо pv изза более BbIcoKoro приорит та индексноrо оператора): if (pv && ! pv>empty() && ((*pv) [1] == 1» Заnис. и "теиие фаiinов Если пользователю случится запустить нашу проrрамму по. вторно, было бы здорово, если бы счет сохранялся для обе их сессий. Чтобы это стало возможным, мы должны: . записать имя пользователя и данные сессии в файл в конце сессии; . прочитать данные предыдущей сессии в проrрамму при ее повторном запуске. Посмотрим, как мы можем это сделать. Для чтения и записи в файл мы должны включить файл заrоловка fstream: #include <fstream> 
41 О Приложение Чтобы открыть файл для вывода, определим объект клас са ofstrearn (ап output file stream  поток вывода файла), пе редавая ero имя в открываемый файл: // sedata.txt открыт на вывод ofstream outfile("sedata.txt"); Что происходит, коrда мы объявляем outfile? Если ero не существует, он создается и открывается на вывод. Если же он существует, то открывается на вывод, а все данные, которые в нем содержатся, иrнорируются. Если мы хотим добавить, а не замещать данные в существу ющем файле, необходимо открыть файл в режиме добавления. Мы делаем это, передавая второе значение iosbase: : арр объекту ofstream: // sedata.txt открывается в append mode (режим добавления) // новые данные добавляются в конец файла ofstream outfile ( "sedata. txt", iosbase:: арр) ; Файл может не открыться. Прежде чем записывать в Hero, нужно убедиться, что он открылся успетно. Простейший пyrь проверки  убедиться в истинности объекта класса: // если outfile определяется, как false, // файл не может быть открыт if (-! outfile) Если файл не может быть открыт, объект класса ofstream становится ложным. В этом примере мы предупредим пользователя, выводом сообщения cerr. cerr представляет стандартную отиб cerr, подобно cout, выводится на Te}F минал пользователя. Разница в том, что вывод cerr не буфе ризуется, оно выводится сразу на терминал: if (! outfile) // по какойто причине не открывается ... cerr « "Бах! Не MOry сохранить данные сессии! \п" ; else // ok: outfile открыт, давайте писать данные outfile « usrname « " " « numtries « " " « numright « endl; 
HeMHoro о проrраммировании на С++ 411 Если файл открывается успешно, мы непосредственно BЫ водим в Hero данные, как делаем это для объектов класса ostream cout и cerr. В этом примере мы питем три значения в out f ile, последние два отделены пробелами. Endl  предопр деленный манипулятор, поставляемый библиотекой iostream. Манипулятор выполняет несколько операций с iostream, отличных от записи и чтения данных. endl вставляет сим вол перевода на новую строку, а затем сбрасывает на диск выходной буфер. Друrие предопределенные манипуляторы включают hex, отображающий на дисплее целое число в тe стнадцатеричном виде, oct, который отображает целое в восьмеричном виде, и setprecision (n) , устанавливающий точность отображения чисел с плавающей точкой в n. Чтобы открыть файл на ввод, мы определяем объект клас са ifstream (ап input file stream  поток ввода в файл), пере давая ему имя файла. Если файл не может быть открыт, объект класса ifstream определяется как ложный. Иначе, файл позиционируется в начало данных, записанных в Hero: // infile открыт в output mode ifstream infile("sedata.txt"); int numtries = о; int numcor = о; if (! infile) { // по какойто причине файл не открывается ... // мы будем предполаrать, что это новый пользователь . . . } else { /1 ok: читаем каждую линию входноrо файла // смотрим, иrрал ли пользователь раньше ... // формат каждой линиии: // пате numtries numcorrect // nt: количество попыток // пс: количество отrадываний string пате; int nt; int пс; while (infile » пате) { infile » nt » пс; if (пате == usrname) { 
41 2 Приложение // нашли! cout « "С возвращением, " « usrname« "\пВаш текущий счет" «nc «" out of " « nt « "\пУдачи!\п"; numtries = nt; numcor = пс;}}} Каждый проход цикла while про читывает новую линию файла, пока не будет достиrнут конец файла. Коrда мы пи тем,: infile » пате возвращаемое значение входноrо выражения  объект клас са, из KOToporo мы читаем infile в данном случае. Коrда конец файла достиrнут, условие true объекта класса сменя ется на false. Это причина, по которой условное выражение цикла while прерывается, коrда достиrается конец файла: while (infile » пате) Каждая линия файла содержит CTpO за которой следу ют два целых в форме: аппа 24 19 danny 16 12 ... Выражение: infile » nt » пс; читает по очереди количество попыток пользователя в nt и количество yrадываний в nC. Если мы хотим и читать, и писать в тот же самый файл, мы определяем объект класса fstream. Для открыIанияя ero в режиме дополнения мы должны передать второе значение в форме: iosbase::inliosbase::app: fstream iofile("sedata.txt",iosbase::inliosbase::app); if (! iofile) // файл не открывается по какойто причине ... rад! { // переходим к началу файла для начала чтения iofile.seekg(Q); // ok: все остальное без изменений ...} 
Ссылки на полезные сайты в И нте р нете 41 3 Коrда мы открываем файл в режиме добавления, текущая позиция  конец файла. Если мы пытаемся читать файл без перепозиционирования, то просто получаем конец файла. Оператор seekg () возвращает iofile к началу файла. По скольку он открыт в режиме дополнения, любая операция записи добавляет данные в конец файла. ссыкии на поnеэныe сайты вИнтернете Микроконтроллеры PIc: http://www.microchip.ru Электронные компоненты и наборы, рассьшка по по- чте наложенным платежом: http://www.dessy:ru http://www.chipinfo.ru http://www.interlavka.narod.ru Маrазин «Чип и Дип»: http://www.chipdip.ru Мастер Кит: http://www.masterkit.ru Системы «Умный дом»: Система XlO  http://www.ydom.ru Система АМХ  http://www.arhelect.ru; http://www.amxcorp.com Система Instabus  http://gira.ru Система Crestron  http://www.crestron.com Проrраммы для работы с контроллером: MPLAВ  http://microchip.ru PonyProg2000  http://www.LancOS.com Компилятор «С» ДЛЯ MPLAВ: http://www.htsoft.com Проrрамма для работы с СОМ-портом: http://www.software.rs232.ru Проrрамма WinLIRC: http://winlirc.sourceforge.net 
414 Приложение Сзйты С полезными проrраммами, схемами и идеями: http://alexuc.narod.ru http://www.homeautomationindex.com http://linuxha.sourceforge . net http://www.ukrocketman.com http://www.razumdom.ru http:// neolive.org/linux/ application/ http://irls.narod.ru http://www.qrz.ru/schemes / http://rf.atnn.ru http://kazus.ru/ guide/index.html http://www.cxem.net http://vksn.narod.ru /links.h tml tМ- СКАН  rР':lППА PICBDDK