VOŠ a SŠ – COP Sezimovo Ústí II. Studijní obor Elektrotechnika
Ovladač sériové linky a Simulátor sítě
Autor: Pavel Doleček Třída: ET4A Školní rok: 2006/2007 -1-
VYŠŠÍ ODBORNÁ ŠKOLA STŘEDNÍ ŠKOLA CENTRUM ODBORNÉ PŘÍPRAVY SEZIMOVO ÚSTÍ
Výtisk č.: Počet listů:
ZADÁNÍ ŽÁKOVSKÉHO PROJEKTU 2. Název a charakter práce (obor) 1. Číslo zadání (třída, číslo žáka – příklad SG4-02/067)
Ovladač sériové linky + Simulátor sítě
ET4A-04/067
Učební pomůcky Obor: Mikroprocesorová technika a programování
3a. Zadavatel a konzultant Mgr. Pejša Jaroslav 3b. Jazyková a stylistická úprava
4. Vedoucí projektu (závěrečné práce) Mgr. Pejša Jaroslav
Mgr. Křivánková Jaroslava
3c. Cizojazyčné texty a anotace: Ing. Kováč Ivan 5. Řešitel (jméno, příjmení, třída, datum nar.)
Pavel DOLEČEK ET4A
nar. 12. 12. 1987
6. Charakteristika zadávané práce – projektu (definice problému, cíl a očekávané výsledky řešení, definice výchozích a omezujících podmínek, vstupní podklady pro řešení, uzlové body realizace)
1. Navrhnout hardware část ovladače sériové linky s klávesnicí, LCD displejem a jednočipovým mikropočítačem PIC, zařízení sestavit a oživit. 2. Vytvořit program pro řídící jednočipový mikropočítač PIC, umožňující odesílání a příjem jednotlivých bytů. Formátování dat odpovídá standardu povelové robotické školní sítě RoboCOP. 3. Vytvořit program pro PC simulující navrženou povelovou síť RoboCOP , včetně volby jednotlivých zařízení typu SLAVE. 4. Prakticky předvést ovladač v činnosti s PC.
7. Požadovaný termín odevzdání
8. Předpokládaný termín obhajoby projektu u maturitní zkoušky
20. 04. 2007 Květen 2007
-2-
9. Další formy vyhodnocení 1. Odborný předmět 2. Obhajoba u maturity 3. Český jazyk a estetika 4. Cizí jazyk
(Při nedostatku místa pokračovat na volných listech) 10. Požaduje se předložit
1. Zpracovaný projekt podle zadání COP v tištěné podobě včetně české a cizojazyčné anotace v rozsahu 1 strany A4 (25 – 35 řádek) 2. Zpracovaný reálný výstup z projektu (výrobek, materiál apod.), pokud byl součástí ŽP 3. Zpracovaný projekt podle zadání COP na CD (povinně v PDF, nepovinně další) 4. Zpracovanou prezentaci projektu na CD (povinně Power Point, nepovinně další) 5. Grafické ztvárnění projektu formou plakátu velikosti A3 (v PDF a tištěné podobě) 6. Přílohy dle uvážení autora nebo pokynů SOČ (pokud práce postupuje do SOČ) 11. Materiální zajištění (předpokládané náklady a podíl úhrady) -
-
Práce bude zpracována převážně v rámci výuky předmětu PRAXE K dispozici je veškeré potřebné technické vybavení, včetně software školy Tisk potřebné dokumentace si bude student zajišťovat sám nebo v COP za obvyklou úhradu
12. Zpracoval: Mgr. Pejša Jaroslav Podpis:
13. Zadání převzal: Pavel Doleček Podpis:
-3-
Prohlášení : Svým podpisem stvrzuji, že jsem na tomto projektu pracoval výhradně sám s použitím různých zdrojů informací, které jsou všechny uvedené v seznamu použité literatury a s použitím legálních programů, které jsou uvedeny v seznamu použitého softwaru.
_
Poděkování: Tímto děkuji vedoucímu práce Mgr. Jaroslavu Pejšovi za vedení práce a za cenné rady, které mi výrazně pomohly při řešení mého maturitního projektu. Zároveň bych chtěl poděkovat níže uvedeným lidem, bez jejichž pomoci by se má práce taktéž neobešla. Jmenovitě tedy Ing. Vladimíru Čebišovi, Mgr. Jaroslavě Křivánkové, Ing. Ivanu Kováčovi a v neposlední řadě zástupci ředitele Mgr. Milošovi Blechovi.
-4-
1. Anotace Ve svém projektu jsem se zabýval řešením problematiky povelové robotické sítě. Na naší škole je již několik let budována ovládací síť pro propojení mikroprocesorových zařízení s osobním počítačem. Síť je postavena na standardu RS232C, označovaném u PC jako sériová linka COM. Protokol předpokládá jedno ovládací zařízení typu Master a nejvýše 128 ovládaných zařízení typu Slave. Přenos dat je obousměrný, každé zařízení typu Slave může mít svou adresu. Přenášené povely mají standardní formát. První bajt je vždy adresový, po něm následuje jeden až sedm datových bajtů. Nejvyšší bit slouží vždy k rozlišení adresového a datového bajtu. Síť je optimalizována pro použití při konstrukcích robotů, automatizovaných pracovišť a podobných aplikací. Pro popsanou síť se vžil název RoboCOP. Prvním výstupem mého projektu je ovladač sériové linky. Jedná se o konstrukci s jednočipovým mikropočítačem PIC, klávesnicí a displejem. Ovladač pracuje jako zařízení typu Master. Uživatel může vytvářet a editovat povely, tyto odesílat a na displeji sledovat případné odezvy ovládaných zařízení. V principu se Ovladač chová obdobně jako program Správce povelů na PC. Ovladač lze použít se stávajícím softwarem použít jako univerzální ovladač nebo diagnostický prvek sítě. Při změně řídícího softwaru pro PIC lze Ovladač použít pro ovládání libovolného zařízení nebo konfigurace sítě. Druhým výstupem mého projektu je simulátor činnosti sítě RoboCOP realizovaný programem pro PC. Simulátor umožňuje virtuální provoz libovolné navržené sítě standardu RoboCOP. Uživatel může do sítě zařadit několik různých prvků, které odpovídají dříve vyrobeným konstrukcím typu Slave. Program simuluje chování sítě v případě, že ovládacím zařízením je buď Ovladač sériové linky, jiné PC s vhodným programem nebo obecně jakékoli zařízení typu Master, které respektuje standard RoboCOP. Program je určen jako pomůcka pro návrháře sítě, nebo jako názorná demonstrace její činnosti. Lze jej použít i pro ladění programového vybavení zařízení typu Master. V práci jsem navázal na ročníkový projekt Miloše Bučinského, který navrhl hardwarovou část Ovladače. Po sestavení a oživení konstrukce jsem v prostředí MPLab vytvořil program pro řídící jednočipový mikropočítač PIC. Pro vývoj Simulátoru jsem využil programovací prostředí Delphi 7. Pomocnými programy při ladění obou částí mého projektu se staly univerzální programy RoboCOP.
-5-
1.1. Annotation In my project I was working on the solution of the command robotic network problem. In our school the controlling network for connecting microprocesors with pesonal computer has allready been built for a few years. The network is built on RS232C standard, which is called series line COM for PC. The protocol supposes one commanding appliance of Master type and no more than 128 controlled appliances of type Slave. The data transmition is working in both directions, each Slave appliance can have its own address. The command transmited have standard format. The first byte is always determined for address, after it follows one to seven data bytes. The highest bit is always intended for recognising the adress and the data bytes. The network is optimalized for working during robots constructions, automatized working places and other similar applications. For above described network the name RoboCOP became well-known. The first issue of my project is a series line controller. It is a construction with the microcontroller PIC, with a keyboard and a display. The controller is working like a Master type appliance. User can make and edit cammand, send them and watch possible answers of the controlled appliances on the display. Actually the controller behaves itself similary to the comand controller program on PC. We can use the Controller with current software like a universal controller or a diagnostic network element. In case of change of the driving software for PIC the Controller can also be used as a control element any wanted equipment or for the network configurations. The second issue of my project is the RoboCOP network simulator realised by the PC program. The Simulator enables a virtual operatin of any proposed RoboCOP standard network. The user can include a few different elements, which respond to the Slave constructions made earlier. The program simulates the network behaviour in case that the controlling appliance is either series line controller, or another PC with suitable program, or any Master type appliance which respects RoboCOP standard. The program is intended either for the network designers, or for tuning programs of the Master type appliances. In my project I continued the Miloš Bučinský work, who had designed the hardware part of this Controller. After building and aliving the construction I have made the program for commanding microcontroller PIC in MP-Lab. For the Simulator development I used Delphi 7. Helping programs during tuning of both parts of my project were universal programs RoboCOP.
-6-
2. Úvod V dnešní době, kdy se prakticky na každém kroku setkáváme s využitím informačních technologií a mikroprocesorové techniky, se nabízí možnost jejich dalšího všestrannějšího využívání například v oblasti usnadnění práce v domácnostech, ve výrobních linkách, v dopravě nebo v každodenním životě člověka obecně. Proto jsem si vybral jako svůj maturitní projekt řešení problematiky přenosu dat mezi jedním ovládacím prvkem a ovládanými zařízeními, které mohou mít do budoucna prakticky jakýkoliv charakter. Mohlo by se jednat o zobrazovací zařízení, pohyblivé a polohovací prvky, domácí spotřebiče, domácí roboty, bezpečnostní zařízení nebo vytápěcí a klimatizační technologie. Není vyloučena ani možnost vzájemné komunikace s programovatelným automatem. Jak jsem se již zmínil výše, ve svém projektu jsem řešil problematiku řízení jednotlivých zařízení pomocí jednoho ovládacího prvku. Tím se v mém projektu stal Ovladač sériové linky. Mimo jiné bylo mým úkolem vytvořit systém menu, ve kterém se bude uživatel snadno orientovat a ve kterém bude snadno editovat jednotlivé povely, které pak následně bude moci odesílat po sériové lince. Uživatel na Ovladači také může sledovat tok přijatých dat a podle nich pak vhodně a pohotově reagovat. Jako podružnou část jsem si vybral úkol vytvořit počítačovou aplikaci, která by byla virtuální podobou reálné povelové sítě. Taktéž by měla být pro uživatele jednoduchá se snadným a přehledným ovládáním. Aplikace má na základě dat přijatých po sériové lince věrně odsimulovat činnost jednotlivých zařízení typu Slave a to v reálném čase. Zařízení typu Slave se po zachycení své nadefinované adresy aktivuje a čeká na další data. Ty mohou přicházet časově prakticky jakkoliv oddělené. Tyto data vyhodnocuje a následně provádí simulaci jim odpovídající činnosti. Obě části mého projektu mají pracovat na stejném standardu a to na standardu povelové sítě RoboCOP, která je na naší škole již řadu let budována a je problematikou využitou ve spoustě nově vznikajících zařízení s datovým přenosem.
-7-
3. Teoretická část 3.1 : Povelová robotická síť Ve svém projektu jsem navázal na práci Miloše Bučinského, který navrhl hardware část Ovladače sériové linky. Ovladač je zařízení typu Master a je určen k ovládání jiných konstrukcí typu Slave, které respektují standard povelové robotické sítě RoboCOP. RoboCOP je obousměrný ovládací protokol realizovaný na sériovém rozhraní TS232C, navržený Ing. Čebišem pro využití předávání povelů v rámci multiprocesorového zařízení, např. robota nebo automatizovaného systému. Je snadno aplikovatelný pro PC nebo PIC, používá 8 bitový formát bez parity, při rychlostí 9600Bd. Nejvyšší bit je užíván jako adresový. Nejvyšší počet adres je 128. V jednom bajtu je možné přenést 7 datových bitů. Povel se stává zásadně z jednoho adresového bajtu a jednoho až sedmi datových. Jedině zařízení typu Master dokáže ovládat povelovou robotickou síť, a to s libovolným počtem zařízení typu Slave. Každý Slave má svůj obslužný protokol.
3.2 : Historie programování v Delphi Delphi je vývojovým nástrojem, jehož první verze byla vypuštěna firmou Borland v roce 1994. Dnes – o třináct let později – patří Delphi k nejpoužívanějším programovacím prostředkům. Delphi je komplexní vizuální programovací prostředí pro operační systém Windows. Delphi vychází z tehdejšího Turbo Pascalu (dále jen TP), velmi kvalitního Pascalského kompilátoru. TP se stal po svém uvedení doslova bestsellerem. Firma Borland, výrobce TP, svůj produkt neustále zdokonalovala. Byl velmi rychlý a jedním příkazem dokázal vytvářet hotové programy. V té době byly na trhu i další jazyky jako například C, Prolog a Basic. Konkurent Borlandu, firma Microsoft, přišel s novou koncepcí programování. Uvedl na trh Visual Basic (dále jen VB), v němž bylo programování velmi zjednodušeno. Čím? No, především komponentami. Přišla doba, kdy už se mohlo rozhraní programu sestavovat graficky na obrazovce. To extrémně urychlovalo a zjednodušovalo vývoj aplikací. Už se nemusely namáhavě programovat všechny prvky programu. Borland ale šel s komponentami v Delphi ještě dále. Jejich použití bylo jednodušší, než ve VB. Jednoduše přesunete třeba tlačítko na formulář a už s nim můžete pracovat. Každá komponenta nabízí řadu vlastností, na jejichž základě je možno měnit chování komponenty a událostí, na které může komponenta reagovat. Delphi je vizuálním kompilátorem Object Pascalu. Všechny komponenty jsou v době tzv. designu viditelné, ale v době chodu programu jsou některé skryté. Proto rozlišujeme komponenty vizuální a nevizuální. Delphi má další nespornou výhodu oproti VB. Komponenty pro VB se programují v jazyce C, ale programátoři v Delphi si mohou v Object Pascalu naprogramovat své vlastní komponenty. V některých verzích Delphi jsou dokonce přiložené zdrojové texty komponent. Práce v Delphi je zjednodušena již zmíněnými komponentami a vizuálním prostředím. Delphi má v sobě integrovaný kompilátor jazyka Pascal, konkrétně Object Pascal. Komponenty jsou softwarové stavební díly, které umísťujeme do formuláře a které doplňujeme kódem. A právě práce s komponentami mě natolik nadchla, že jsem se rozhodl pracovat alespoň na části maturitního projektu v prostředí Borland Delphi verze 7. -8-
4. Praktická část 4.1. Ovladač sériové linky Ovladač sériové linky je zařízení typu Master určené pro ovládání dalších konstrukcí a zařízení, které respektují standard RoboCOP. Osazovací výkres desky plošných spojů je obsažen v příloze č. 5. Seznam použitých součástek je v příloze č. 6. Hlavní periferie Ovladače jsou : Vstupy/výstupy: Vstupy: - klávesnice – 12 tlačítek - 2 pomocná tlačítka - Sériový port COM Výstupy: -
LCD displej – 4x16 řádků (viz příloha č. 1) 2x LED dioda - červená - různé funkce - zelená - indikuje přítomnost napájecího napětí Sériový port COM
Napájení: Zdrojem napájení je adaptér 230V/12V. Vstupní napájecí napětí Ovladače sériové linky je 8-30V stejnosměrného napětí. Napájecí obvod je vybaven zelenou LED diodou pro indikaci přítomnosti napájecího napětí, dále stabilizátorem 7805 a filtračními kondenzátory. Chlazení celé desky je přirozené. PIC 16F877: U Ovladače sériové linky je hlavním řídícím centrem jednočipový mikropočítač PIC 16F877 se 40-ti vývody (viz příloha č.2) . Konektor COM: Sériová linka používá pro přenos dat pouze 3 vodiče, přičemž první slouží k odesílání dat, druhý k příjmu dat a třetí z nich je využit jako společné zemnění. Obvod MAX232C: Obvod MAX232C zajišťuje komunikaci po sériové lince. Vnitřní zapojení a popis jednotlivých vývodů obsahuje příloha č. 8.
Seznam změn v návrhu Miloše Bučinského: 1. Rezistory u všech tlačítek byly změněny z 220R na 10k z důvodu zbytečného protékání velkých proudů 2. Rezistor 82R před napájecí LED diodou byl nahrazen rezistorem 1k z důvodu oslňování očí touto LED diodou.
-9-
4.1.1. Schéma zapojení Ovladače sériové linky:
- 10 -
4.1.2. Kontrola a oživení konstrukce Na počátku své práce jsem konstrukci, která byla navržena mým předchůdcem Milošem Bučinským, musel podrobit kontrole a měření. Postupně jsem proměřoval všechny důležité funkční části Ovladače. Nejdříve jsem ověřil správnou funkčnost pomocných tlačítek a klávesnice, provedl jsem vizuální kontrolu celé desky plošných spojů a zkontroloval správnost připojení LCD displeje. Jednotlivé vývody jednočipového mikropočítače PIC16F877 jsem zkontroloval a měřícím přístrojem ověřil správnost přítomných napětí. Vše z výše uvedeného bylo vše v pořádku, jen bylo potřeba přepájet některé spoje z důvodu špatného reagování pomocných tlačítek. Dále jsem musel nahradit rezistor u LED diody (měl zbytečně malou Ohmickou hodnotu a LED dioda až příliš oslňovala oči), rezistory u klávesnice, které měly také nízkou hodnotu a docházelo k zbytečnému protékání velkých proudů. Jinak se na desce plošných spojů Ovladače sériové linky nevyskytly žádné další zásadní nedostatky. Do mikropočítače PIC16F877 jsem vytvořil primitivní program který testoval stisky všech kláves i pomocných tlačítek a na jejich stisknutí bliknul červenou LED diodou. Tím byla ověřena funkčnost jednotlivých tlačítek. Poté už zbývalo jen rozchodit LCD displej. Do onoho primitivního programu jsem přidal pár podprogramů, které sloužili k zinicializování displeje a vypsání jednoduchého textu na jeho všechny čtyři řádky.
4.1.3. Návrh způsobu ovládání Protože bylo nutné začít se zabývat programovým vybavením Ovladače sériové linky, musel jsem navrhnout, jak vůbec bude program pracovat a pomocí jakých tlačítek bude ovládán. Vzhledem k tomu, že u Ovladače je k dispozici 12 tlačítek na klávesnici a dvě pomocná tlačítka, bylo potřeba vytvořit i klávesové zkratky. Pro zadávání hodnot v hexadecimální soustavě jsem navrhl použití zkratek pro zadávání hodnot A – F, pro pohyb v menu jsem využil pravidla numerické klávesnice na PC a pro jednotlivé směrové šipky zvolil tlačítka 2, 4 ,6, 8. Jako potvrzovací klávesu jsem zvolil tlačítko #, jednomu z pomocných tlačítek byla přiřazena funkce „O krok zpět“. Podrobný rozpis klávesových zkratek a funkcí jednotlivých tlačítek se nachází v příloze č. 3.
4.1.4. Návrh struktury uživatelského menu Pokračoval jsem návrhem struktury uživatelského menu a zvolil jsem způsob vertikálního listování. Po domluvě s konzultantem se uživatelské menu skládá ze čtyř položek: Příjmač znaků – Po otevření této položky se uživateli otevře obrazovka kde boudou zobrazena poslední přijatá data řazena sestupně od posledního přijatého. Vysílač znaků – Zde může uživatel zadávat data v hexadecimální soustavě a v délce jednoho bajtu, a rovnou je bude moci odesílat po sériové lince. Vysílač povelů – Slouží k odesílání již předdefinovaných povelů po sériové lince. Definice povelů – Uživatel zde má možnost nedefinovat si své vlastní povely, jejichž hodnoty bude zadávat v hexadecimální soustavě. Možné je nadefinování maximálně osmi povelů o délce osmi bajtů. - 11 -
4.1.5. Vytváření programu pro mikroprocesor PIC V této fázi bylo nutné oba předchozí návrhy spojit dohromady, a to do programu jednočipového mikropočítače PIC16F877. K psaní a překladu jsem využil aplikaci MP-Lab IDE od firmy Microchip. Zde se zdrojový kód píše do asembleru a MPLab ho po překladu převede do souboru *.HEX, který si následně načteme v aplikaci Asix UP. Tato aplikace je komunikátorem s programátory od firmy Asix a načtený soubor *.HEX využije k naprogramování mikropočítače PIC, který je v vložen do programátoru. Nejprve jsem vytvořil úvodní obrazovku, která se zobrazí jako první po zapnutí napájecího napětí. Dále jsem navrhoval vzhledy jednotlivých obrazovek pro položky v menu, ze kterých jsem zvolil nejlepší varianty a podařilo se mi naprogramovat menu se všemi jeho položkami a obrazovkami. Vyřešil jsem listování v menu a zadávání hodnot v hexadecimální soustavě (Vysílač znaků a Definice povelů). Vytvořil jsem podprogram pro obsluhu klávesnice, kde jsem uplatnil již výše zmíněné klávesové zkratky.
4.1.6. Řešení komunikace po sériové lince Pro zajištění schopnosti Ovladače sériové linky komunikovat přes sériovou linku vznikly další podprogramy. Při jejich tvorbě jsem nahlédl do vzorových programů pro PIC a vyčetl z nich komunikační zásady. Ty jsem použil i ve svém programu a uvedl komunikaci s portem do funkčního stavu. Po potvrzení odeslání uživatelem je zvolené dato odesíláno po sériové lince po jednotlivých bajtech. Odesílání i příjem dat jsou signalizovány blikáním červené LED diody. V případě, že uživatel jakkoli pracuje s Ovladačem a po sériové lince přijde jedno či více dat, zobrazí se v pravém horním rohu displeje tzv. příznak přijatých dat. Tento příznak zhasne při shlédnutí přijatých dat v Přijímači znaků.
4.1.7. Doladění programu a závěrečné úpravy Na závěr práce jsem se věnoval závěrečným úpravám v programu Ovladače sériové linky. Tyto úpravy se týkaly především spávné funkčnosti menu a správného odesílání a příjmání dat.
- 12 -
4.2. Simulátor sítě – program pro PC 4.2.1. Návrh vizuální podoby aplikace Na počátku bylo nutné navrhnout vizuální podobu aplikace Simulátor sítě tak, aby byla práce v jejím prostředí co nejpřehlednější. Jelikož byl požadavek pracovat s více prvky najednou, vznikla myšlenka vytvořit v aplikaci tzv. pracovní plochu, která by představovala onu navrženou virtuální povelovou síť. Dále bylo nutné zvolit způsob, jakým budou na pracovní plochu přidávány prvky představující jednotlivá zařízení Slave. Jako nejlepší způsob se zdál být úzký sloupec vlevo od pracovní plochy, ve kterém má uživatel možnost listovat mezi jednotlivými prvky Slave, měnit jejich adresy a následně je přidat na pracovní plochu. Jako ohraničení těchto dvou částí byly použity komponenty „GroupBox“. S prvky, které již byly na pracovní plochu přidány se muselo také nějakým způsobem pracovat, a tak vznikla ještě jedna část aplikace. Jedná se o komponentu „Panel“ a nachází se pod pracovní plochou. Zde uživatel aplikace shlédne základní informace o vybraném prvku, může zde opět měnit jeho adresu, nebo prvek odstranit z pracovní plochy. V závěru práce ještě přibyla tabulka, kde se zobrazuje přehled přijatých bajtů, a byla umístěna do levého spodního rohu. Takto vypadá konečná vizuální podoba aplikace :
- 13 -
4.2.2. Programování základních funkcí aplikace Prvním krokem v samotném programování aplikace bylo vytvoření uživatelského menu. K tomu byla použita komponenta MainMenu. Vzhledem k tomu že se většina práce v aplikací odehrává na pracovní ploše, uživatelské menu nabízí pouze základní funkce jako ukončení aplikace, zobrazení přehledu používaných zařízení typu Slave, ukládání, načítání a vymazání pracovní plochy, zobrazení nápovědy a okna „O aplikaci“.
4.2.3. Parametry zařízení typu SLAVE Dalším krokem bylo řešení způsobu načítání jednotlivých prvků představujících jednotlivá zařízení typu slave, listování mezi nimi a jejich následné přidávání na pracovní plochu. Do levého sloupce (komponenty GroupBox) bylo přidáno pět tlačítek (komponenta Button), jeden obrázkový rám (komponenta Image), pět textových polí (komponenta Label) a jedno editační pole (komponenta Edit). Všem těmto prvkům byla asociovaná určitá funkce. Rozhodl jsem se (z hlediska komplexnosti a přidávání dalších zařízení typu Slave v budoucnu) k využití INI souborů jako zdrojů základních informací o daném zařízení typu Slave. Tlačítka Předchozí (<--) a Další (-->) slouží tedy k listování mezi jednotlivými INI soubory a jsou zobrazovány z nich načtené informace. Tlačítko pro změnu adresy je zde nastaveno tak, že změní adresu v daném INI souboru. Vybraný prvek představující jedno zařízení typu Slave uživatel usadí na pracovní plochu zvolením vhodné adresy a stisknutím tlačítka Přidat. Poté se prvek objeví na pracovní ploše ve formě bitmapového obrázku a jeho údaje jsou uloženy do jedné záložky pole proměnných. Systém souborů, který jsem zvolil pro všechny zařízení typu Slave, je popsán v příloze č. 4.
4.2.4. Ovládání v prostředí aplikace Přidávání jednotlivých prvků na pracovní plochu je tedy vyřešené. V Tuto chvíli jsem se musel začít zabývat otázkou práce s nimi a vůbec otázkou ovládání v aplikaci. Jako první vznikla procedura, která po kliknutí na daný prvek na pracovní ploše jej nastaví jako aktivní a označený prvek. Aktivní a označený prvek může být jen jeden. Zároveň tato procedura vyčte údaje o daném prvku z pole proměnných a zobrazí je v informačním panelu pod pracovní plochou. V informačním panelu se nachází ještě tlačítko pro změnu adresy. To je zde ošetřeno tak, že adresa nově zadaná se uloží k vybranému prvku do pole proměnných a zobrazí se na vybraném prvku pouze v případě, že se nově zadaná adresa neshoduje s adresami ostatních nadefinovaných prvků na pracovní ploše. V Informačním panelu se nachází ještě tlačítko Odebrat, které slouží k odebrání označeného prvku z pracovní plochy a k vymazání údajů o něm z pole proměnných. Další procedura ošetřuje událost, kdy uživatel klikne na pracovní ploše mimo nadefinované prvky. V takovém případě procedura vyresetuje údaje v informačním panelu, zajistí odznačení posledního vybraného prvku a zároveň zajistí, že žádný z prvků na pracovní ploše není aktivní. Z důvodu přehlednosti pracovní plochy byla vytvořena procedura která uživateli umožní libovolný přesun jednotlivých prvků po pracovní ploše, a to pouhým tažením myši za stisknutého levého tlačítka na myši. - 14 -
4.2.5. Zobrazování aktuálního stavu jednotlivých SLAVE zařízení Jednotlivé prvky představující zařízení typu Slave musí na základě přijatých dat měnit svou vizuální podobu. Protože prvek na pracovní ploše je bitmapový obrázek, zvolil jsem způsob překreslování tohoto obrázku pomocí komponenty Canvas, kterou Delphi 7 nabízí. Z hlediska funkčnosti na všech zařízeních typu Slave jsem vytvořil proceduru která ze dvou vstupních hodnot (adresa a dato) vyhodnotí požadovaný aktuální stav prvku. Každý stav má svůj bitmapový obrázek, kterým se překreslí původní stav daného prvku. Při překreslení má každý druh prvku dané souřadnice, odkud se má začít překreslovat. Tyto souřadnice spolu s dalšími údaji sloužícími k rozpoznání jednotlivých druhů prvků si procedura načte z pole proměnných, kam byly tyto hodnoty uloženy při přidávání prvku na pracovní plochu.
4.2.6. Komunikace s portem COM Pro komunikaci s portem je nutné použít knihovnu PORT.DLL, která obsahuje procedury a funkce sloužící ke komunikaci s portem COM. Vytvořil jsem proceduru, která na základě čítání timeru testuje přijaté hodnoty na vstupu COM portu. Tyto hodnoty převádí do binárního a hexadecimálního tvaru a zapisuje je do tabulky přehledu přijatých dat. Poté je vyhodnoceno, zda se jedná o adresový či datový bajt. Adresový bajt se uloží do adresové proměnné, která je srovnávána s adresami nadefinovaných prvků. V případě že je nalezena shodná adresa, daný prvek se stane aktivním pro příjem dat. Datový bajt se uloží do datové proměnné, která je záhy zpracována k vyhodnocení aktuálního stavu aktivního prvku. Když nepředchází adresový bajt, datové bajty jsou ignorovány.
4.2.7. Ukládání a načítání navržené sítě Jak již zde bylo řečeno, pracovní plocha s nadefinovanými prvky, které představují různá zařízení typu Slave, je virtuální podobou povelové sítě RoboCOP. Uživatel který si nadefinuje síť s několika prvky na pracovní plochu může být náhle přerušen z práce a bylo by jistě otravné znovu definovat stejnou síť se stejnými prvky. Proto jsem vytvořil dvě procedury, které pomocí přednastavených dialogů zajistí ukládání a načítání navrhnuté virtuální sítě. Protože jádrem informací o všech prvcích které jsou nadefinované na pracovní ploše je pole proměnných, je nutné ukládat a načítat právě toto pole proměnných. Uživatel si tedy v dialogu ukládání zvolí pojmenování souboru, do kterého bude uloženo pole proměnných. Bitmapové obrázky zachycující aktuální stav prvku jsou ukládány každý zvlášť pod jménem jaké si uživatel zvolil, ke kterému je přidáno číslo pořadí prvku. Druhá procedura sloužící k načítání uloženého návrhu virtuální sítě načte pole proměnných ze souboru a následně načítá bitmapové obrázky jednotlivých prvků postupně. Po načtení uložené virtuální sítě je samozřejmě možné k ní přidávat libovolně další prvky.
- 15 -
4.2.8. Závěrečné úpravy a opravy chyb K závěrečným pracím na aplikaci Simulátor sítě patřila především tvorba oken nápovědy, informací o programu (obrázek č.1), přehledu používaných komponent(obrázek č.2) a okna pro zobrazení informací o povelové robotické síti RoboCOP. Ukázky těchto oken jsou na této stránce. Dále bylo nutné ošetřit některé krizové situace pomocí vložení vhodných podmínek, proběhly také drobné závěrečné vizuální úpravy. Kompletní zdrojový kód aplikace je obsažen v příloze č. 9. Obrázek č.1:
Obrázek č.2:
- 16 -
5. Závěr Sestavení a oživení konstrukce ovladače sériové linky proběhlo podle plánu a zařízení hardwarově vyhovuje pro jakékoliv používání. Program pro PIC16F877 zahrnuje všechny inicializační podprogramy, podprogramy pro obsluhu klávesnice a LCD displeje a plně funkční je systém uživatelského menu. Dále program umí přijímat a odesílat data přes port COM po sériové lince. Tím bylo zadání splněno. V příjmači znaků se zobrazují přijatá data hexadecimálně. Vysílač znaků vysílá uživatelem zadané dato o délce jednoho bajtu. Rozšiřující položky „Vysílač povelů“ a „Definice povelů“ nebyly dokončeny z hlediska ukládání a načítání jednotlivých povelů, k čemuž bylo v plánu využít paměť EEPROM, kterou PIC16F877 obsahuje. Program Simulátor sítě je funkční podle zadání. Poskytuje uživateli výběr ze 3 zařízení typu Slave(adresovatelný sedmisegmentový zobrazovač, adresovatelný zobrazovač čtyř znaků a osmibitový LED zobrazovač) a následně simuluje jejich aktuální stav na základě dat přijatých po sériové lince. Uživatel má tedy možnost nadefinovat síť s libovolným počtem každého z těchto zařízení typu Slave včetně jejich adresy. Maximální počet všech nadefinovaných zařízení je 128 (podle standardu RoboCOP). Dále má uživatel možnost si nadefinovanou síť uložit na pevný disk PC a následně ji kdykoliv znovu načíst v její stejné podobě. V původním plánu byla zahrnuta i simulace robotické ruky, která se na C106 vyskytuje. Při návrhu animace robotické ruky se ovšem zjistilo, že by to byla práce na samostatný ročníkový projekt a tudíž robotická ruka nakonec nebyla do programu zahrnuta. V budoucnu je možné obě části použít nejen pro didaktické účely, ale také k ladění různých přenosů dat po sériové lince. Doporučuji rozšířit program Simulátor sítě o další prvky představující nová zařízení typu Slave.
- 17 -
6. Seznam použitých zdrojů informací Literatura: Matoušek, D.: Práce s inteligentními displeji LCD, BEN, Praha 2006 Bučinský, M.: Ovladač sériové linky, COP 2005 Čebiš, V.: Překlad originální dokumentace manuálu k PIC 16F877 Hrbáček, J.: Komunikace mikrokontroléru s okolím, BEN, Praha 1999
Internet: Kadlec, V.: Umíme to s Delphi , http://www.zive.cz/ Šindelář, J.: Tipy a Triky v Delphi , http://www.zive.cz/ http://www.microchip.com/
6.1. Seznam použitého softwaru Microsoft Word – školní licence Borland Delphi 7 – školní licence Asix UP – freeware na http://www.asix.cz/ MP-Lab IDE – freeware na http://www.microchip.com/ Univerzální programy RoboCOP – autor Mgr. Jaroslav Pejša Vzorové programy pro PIC – autor Ing. Vladimír Čebiš
- 18 -
7. Seznam příloh Příloha č. 1 – LCD displej Příloha č. 2 – PIC 16F877 Příloha č. 3 – Funkce tlačítek a klávesové zkratky Příloha č. 4 – Systém souborů Příloha č. 5 – Osazovací plán DPS Příloha č. 6 – Seznam použitých součástek Příloha č. 8 – Obvod MAX232C Příloha č. 9 – Zdrojový kód programu Simulátor sítě Příloha č. 10 – Zdrojový kód programu pro PIC16F877
8. Obsah přiloženého CD disku Dokumentace - MAX232.pdf - PIC16F877.pdf - Mbucinsky - Dokumentace.pdf
– dokumentace k obvodu MAX232 – překlad originální dokumentace k PIC 16F877 – složka s projektem Miloše Bučinského (ET4a 05/06) – dokumentace Ovladače sériové linky a Simulátoru sítě
Zdrojové soubory - Simulátor sítě (program pro PC) - simulator.dpr – soubor Delphi projekt - simulator.pas – soubor zdrojového kódu - simulator.dfm – soubor hlavního formuláře - simulator.cfg – konfigurační soubor - FORMS – složka se soubory vedlejších formulářů - Ovladač sériové linky(program pro PIC16F877) - osl.asm – soubor pro asemblér - osl.lst – soubor výpisu programu - osl.err – chybový soubor - osl.hex – soubor pro programátor - osl.mcp – soubor MP-Lab projekt Simulátor sítě (nutno kopírovat celou složku) - simulator.exe – spouštěcí soubor Simulátoru Sítě - port.dll – knihovna pro port COM1 - SLAVES – složka se soubory pro jednotlivá SLAVE zařízení - PR – složka se soubory přehledu komponent Obrázky - OSL - SIM - Ostatní
– obrázky a fotky Ovladače a jeho částí – obrázky použité v programu Simulátor sítě – ostatní obrázky
- 19 -
Příloha č. 1 – LCD displej - 4řádkový 16-ti znakový displej, který je řízen obvodem HD44780 od firmy Hitachi.
8-mi bitová komunikace: Zápis dat probíhá tak, že se vybaví signál RS podle toho, zda se zapisují data nebo instrukce (R/W trvale na log. 0). Poté se aktivuje vstup E a následně se na vodiče DB7 až DB0 přivedou data a potvrdí se deaktivací vstupu E. Paměti displeje: Displej disponuje dvěma typy pamětí : • DDRAM - obsahuje přednastavené znaky,
které se zobrazují na displeji. • CGRAM - umožňuje, aby uživatel vytvořil až 8
vlastních znaků. Tato možnost se používá pro definici české diakritiky.
obvykle
Tabulka obsazení vývodů displeje: Pin Signál Funkce pinu 1 VSS GND 2 VDD + 5V 3 V0 Řízení kontrastu 4 RS Register Select 5 R/W Read / Write 6 E Enable 7 DB0 Datová sběrnice bit 0 8 DB1 Datová sběrnice bit 1 9 DB2 Datová sběrnice bit 2 10 DB3 Datová sběrnice bit 3 11 DB4 Datová sběrnice bit 4 12 DB5 Datová sběrnice bit 5 13 DB6 Datová sběrnice bit 6 14 DB7 Datová sběrnice bit 7 Umístění vývodů displeje:
Kontrast displeje: - regulován pomocí potenciometru
- 20 -
Příloha č. 2 – PIC16F877 8-mi bitový jednočipový mikropočítač se 40-ti vývody Taktovací frekvence : 0 - 20 MHz Paměť programu : až 8K x 14 slov Paměť dat RWM : až 368 x 8 bajtů Paměť dat EEPROM : až 256 x 8 bajtů Možnosti periférií mikropočítače: • 8-bitový čítač/časovač TMR0 s 8-bitovou programovatelnou předděličkou • 16-bitový čítač/časovač TMR1 s předděličkou může být inkrementován v režimu Sleep z vnějšího zdroje • 8-bitový čítač/časovač TMR2 s 8-bitovým posuvným registrem a dvěmi předděličkami. • 2 moduly PWM s volbou záchytného nebo komparačního režimu • Rozlišení v záchytném režimu je 16 bitů, nejvýše 12,5 ns • Rozlišení v komparačním režimu je 16 bitů, nejvýše 200 ns • Nejvyšší rozlišení pulsně šířkové modulace PWM je 10 bitů • Synchronní sériový port s možností SPITM nebo I2CTM • Universální asynchronní port USART/SCI s možností 9-bitové komunikace • Paralelní port PSP o šířce 8 bitů řízený signály RD, WR, CS • Detekční obvod výpadku napájecího napětí BOR Možnosti zpracování analogového signálu: • 10-bitový A/D převodník s nejvýše osmi vstupy • Možnost volby signálu reset při výpadku napájecího napětí • Modul analogových komparátorů: • dvojice analogových komparátorů • nastavitelná vnitřní napěťová reference • vstupy komparátorů jsou přístupné na vývodech mikropočítače Speciální vlastnosti mikropočítače: • Počet zápisů do paměti programu typu Flash: 100.000 • Počet zápisů do paměti dat typu EEPROM: 1.000.000 • Doba uchování dat v paměti EEPROM: > 40 let • Možnost programového zápisu do paměti programu • Programování v aplikaci ICSPTM (s možností jediného 5 V zdroje) • Časovač Watchdog (WDT) s vlastním nezávislým vnitřním RC oscilátorem • Nastavitelná ochrana kódu proti vyčtení • Úsporný režim Sleep • Volba typu oscilátoru • Podpora ladění v aplikaci ICD
- 21 -
Příloha č. 3 – Funkce tlačítek a klávesové zkratky
Funkce tlačítek na klávesnici: -Klávesa # slouží jako Enter -Klávesa
má funkci Shift
-Směrové šipky se používají pro pohyb v menu
Klávesové zkratky:
-
Pomocná tlačítka :
Tyto zkratky se dají použít pouze při zadávání hodnot v hexadecimální soustavě.
T1 – slouží k navrácení do menu T2 – nevyužito
- 22 -
Příloha č. 4 – Systém souborů
Z důvodu přidávání dalších prvků, které budou představovat nově vytvořené konstrukce typu Slave, byl vytvořen jednotný systém souborů. Každý prvek má svou vlastní složku která obsahuje konfigurační soubor INI, obrázek prvku a složku, která obsahuje jednotlivé možné stavy pro daný prvek. INI soubory mají následující podobu : [slave] - nadpis cesta=slaves\slave001\ - cesta k souborům daného prvku Adress=13 - adresa daného prvku SlaveName=Display - první jméno prvku SubName= 7-mi segment - druhé jméno prvku ObrAkt=slaves\slave001\slave001e.bmp - obrázek prvku WPole1=27 - číslo udává šířku překreslovací bitmapy WPole2=46 - číslo udává výšku překreslovací bitmapy WPole3=0 - zatím nevyužito WPole4=4 - číslo určuje počet překreslovacích cyklů posunL=4 - pozice pro překreslování aktuálního stavu zleva posunT=6 - pozice pro překreslování aktuálního stavu shora TopAdr=57 - pozice zobrazení adresy od horního okraje LeftAdr=47 - pozice zobrazení adresy od levého okraje
- 23 -
Příloha č. 5 - Osazovací plán: Pohled ze strany spojů:
Pohled ze strany součástek – propojky :
- 24 -
Osazovací plán:
Pohled na desku – rozmístění jednotlivých prvků:
1. 2. 3. 4.
5. 6. 7. 8. 9.
- 25 -
Konektor napájení Konektor Com1 Červená LED pro indikaci Zelená LED pro indikaci přítomnosti napájecího napětí Potenciometr pro řízení kontrastu MAX 232 – Obvod pro řízení sériové komunikace Mikroprocesor 16F877 Pomocné tlačítko – T1 Pomocné tlačítko – T2
Příloha č. 6 - Seznam použitých součástek: C1 100 uF C2 100nF C3 10uF C4 100nF C5 100nF C6 100nF C7 22pF C8 22pF C9 1uF C10 1uF C11 1uF C12 1uF IC1 PIC16F877 IC2 MAX232 IC3 7805 JP1 Display-con JP7 Klavesnice-con LED1 Zelená LED2-C Cervena Q1 4MHz R0 10k R1 10k R2 10k R3 10k R4 10k R5 10k R6 10k R7 10k R8 10k R9 10k R10 10k R11 10k R12 4K7 R13 1k0 R14 Potenciometr R15 2K2 R16 10k R17 10k R18 4K7 R20 10R S1 S2
CPOL-EUE3.5-8 C-EU025-025X050 CPOL-EUE2-5 C-EU025-025X050 C-EU025-025X050 C-EU025-025X050 C-EU025-025X050 C-EU025-025X050 CPOL-EUE2-5 CPOL-EUE2-5 CPOL-EUE2-5 CPOL-EUE2-5 PIC16F877P MAX232 78MXXS PINHD-1X16 PINHD-1X14 LED5MM LED5MM CRYTALHC18U-V R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 R-EU_0207/10 TRIM_EU-B25P 10-XX 10-XX
E3,5-8 C025-025X050 E2-5 C025-025X050 C025-025X050 C025-025X050 C025-025X050 C025-025X050 E2-5 E2-5 E2-5 E2-5 DIL40 DIL16 78MXXS 1X16 1X14 LED5MM LED5MM HC18U-V 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 0207/10 B25P B3F-10XX B3F-10XX
rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl microchip maxim v-reg apinhead pinhead led led crystal rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl rcl pot switch-omron switch-omron
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
T2 X2 X3
NPN-TO126V NEB21R F09HP
TO126V B21R 9HP
transistor n-lumberg on-subd
1 1 1
NEB21R COM
- 26 -
Příloha č. 8 – Obvod MAX232C Popis jednotlivých vývodů:
Schéma vnitřního zapojení:
- 27 -
Příloha č. 9 – zdrojový kód programu Simulátor sítě unit ovladac; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, Menus, DB, DBClient, ComCtrls, IniFiles, Buttons, ExtDlgs, Grids, Spin, Math ; type THlOkno = class(TForm) //na formulari se vyskytuji komponenty: GBslave: TGroupBox; MainMenu1: TMainMenu; Soubor1: TMenuItem; Zavt1: TMenuItem; BtnPrev: TButton; BtnNext: TButton; BtnDelItem: TButton; GBSit: TGroupBox; S1: TMenuItem; Parametry1: TMenuItem; Help1: TMenuItem; Oprogramu1: TMenuItem; Oprogramu2: TMenuItem; Zavt2: TMenuItem; LBLSlaName: TLabel; Ulozits1: TMenuItem; N1: TMenuItem; Vymaz2: TMenuItem; Oprogramu3: TMenuItem; Ukoncitprogram1: TMenuItem; GBnahled: TGroupBox; ImgNahled: TImage; Label4: TLabel; BtnZmenaAdr: TButton; EDTZmenaAdr: TEdit; LBLsubnameSlave: TLabel; BtnADD: TBitBtn; Edit1: TEdit; Edit2: TEdit; Panel1: TPanel; LBLNazev: TLabel; LBLAdress2: TLabel; Label5: TLabel; LBLAdresStav: TLabel; BtnLoad: TButton; Timer: TTimer; Label1: TLabel; Label2: TLabel; LBLAdrSlave: TLabel; EDTZmena: TEdit; BtnChangeAdr: TButton; LVTabulka: TListView; OpenDialog: TOpenDialog; SaveDialog: TSaveDialog; BtnSmazato: TButton; N2: TMenuItem; Parametry2: TMenuItem; N3: TMenuItem;
- 28 -
procedure BtnDelItemClick(Sender: TObject); //pouzivane procedury procedure Ukoncitprogram1Click(Sender: TObject); procedure BtnChangeAdrClick(Sender : TObject); procedure KomponentaClick(Sender: TObject); procedure PresunClick(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure KompMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure KompPust(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure BtnPrijemClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure TimerTimer(Sender: TObject); procedure ZapisDato(Dato : byte); procedure GBSitClick(Sender: TObject); procedure ZmenaClick(Sender: TObject); procedure ZmenaAClick(Sender: TObject); procedure BtnNextClick(Sender: TObject); procedure BtnPrevClick(Sender: TObject); procedure BtnADDClick(Sender: TObject); procedure BtnZmenaAdrClick(Sender: TObject); procedure Oprogramu3Click(Sender: TObject); procedure BtnLoadClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Zavt1Click(Sender: TObject); procedure Parametry1Click(Sender: TObject); procedure Ulozits1Click(Sender: TObject); procedure BtnSmazatoClick(Sender: TObject); procedure Vymaz2Click(Sender: TObject); procedure Oprogramu1Click(Sender: TObject); private { Private declarations } downX, downY: Integer; dragging: Boolean; public { Public declarations } end; //------------------------------------------------------------------------------------------------------------------------------------------------string50 = string[50]; {...init TZarizeni...} type TZarizeni = record obrAkt, ObrAkce ,Adress, SlaveName, SubName, LastStav : string50; cesta, wPole1, wPole2, wPole3, wPole4 : string50; toppos, leftpos, topstav, leftstav, TopAdr, LeftAdr : integer; Image: TImage; Akt : TPicture; end; type TMCapture = Class(TControl); var HlOkno: THlOkno; AktualItem, Image : TImage; ItemsCount, posunL, posunT, TopAdr, LeftAdr, cislo, zmena, positadd, prijem, XX, i, k, x : integer; ukazatel : integer; Adress, SlaveName, obrAkt, ObrAkce, LastItem, cesta : string; CestaPrimary, SubName, wPole1, wPole2, wPole3, wPole4, s : string; dato : word; Items : array of TZarizeni; Soubor : file of TZarizeni; //--------------------------------------------------------------------------------------------------------------------------------------------------const THEDLL='PORT.DLL'; {knihovna portu COM} {z knihovny port.dll budeme pouzivat nasledujici procedury a funkce}
- 29 -
function OPENCOM(S:PCHAR):Integer;stdcall; external THEDLL; function READBYTE:Integer;stdcall; external THEDLL; Procedure CLOSECOM; stdcall; external THEDLL; {knihovnu port.dll musite mit, pokud chcete program spustit!} //----------------------------------------------------------------------------------------------------------------------------------------------implementation {Start} uses _oprogramu, _vlast, help; {== pouzivane vedlejsi formulare} {$R *.dfm} procedure THlOkno.FormCreate(Sender: TObject); begin {NASTAVENI POMOCNYCH PROMENNYCH} prijem := 0; XX:=1; k:=0; x:=1; i:=0; CestaPrimary:=ExtractFilePath(Application.ExeName); OpenCOM(PChar('COM1:09600,N,8,1')); {Komunikace s portem - open port} end; //----------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.BtnADDClick(Sender: TObject); {...Pridat prvek na pracovni plochu...} var Path, nov : string; AdrSek0, AdrSek1 : string; g, x, t, y, i, z : integer; Bitmap1, Bitmap : TBitmap; MyRect, MyOther : TRect; Begin positadd := 20; g:=0; nov := 'slave' + IntToStr(cislo); //vytvori obrazek prvku Image := TImage.Create(GBSit); //obrazek je viditelny Image.Visible := true; if Length(Items) <> 0 then Begin //do promenne ulozi delku pole promennych i := Length(Items); Repeat if Items[i-1].adress <> '--' then Begin if Items[i-1].adress = LBLAdrSlave.Caption then g := 1;//když je nalezena shodná adresa nastav priznak End; i := i-1; Until i = 0; End; if obrAkt <> '' then Begin if g = 0 then Begin if AktualItem <> nil then {..Predchozi se zmeni v neaktivni..} Begin AktualItem.Picture.Bitmap.Canvas.Pen.Color := clBlack; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(AktualItem.Width),(AktualItem.Height)); aktualitem := nil; End; {..Parametry vkladaneho zarizeni..} Image.Parent := GBSit; Image.AutoSize := true; Image.Left := 20 + 125 * cislo ; Image.Top := positadd; Image.Cursor := crHandPoint;
- 30 -
Image.Name := nov; Image.OnClick := KomponentaClick; Image.OnMouseDown := PresunClick; image.OnMouseMove := KompMove; Image.OnMouseUp := KompPust; cislo := cislo + 1; ItemsCount := ItemsCount + 1; SetLength(Items, Length(Items)+1); {pole pr.+1} {..Ukladani udaju nactenych z ini (NEXT,PREVIOUS) do pole promennych 'TZarizeni'..} Items[Length(Items)-1].SlaveName := SlaveName; Items[Length(Items)-1].SubName := SubName; Items[Length(Items)-1].obrAkt := CestaPrimary+obrAkt; Items[Length(Items)-1].Adress := adress; Items[Length(Items)-1].Image := Image; Items[Length(Items)-1].wPole1 := wPole1; Items[Length(Items)-1].wPole2 := wPole2; Items[Length(Items)-1].wPole3 := wPole3; Items[Length(Items)-1].wPole4 := wPole4; Items[Length(Items)-1].leftpos := Image.left; Items[Length(Items)-1].toppos := Image.top; Items[Length(Items)-1].cesta := cesta; Items[Length(Items)-1].leftstav := posunL; Items[Length(Items)-1].topstav := posunT; Items[Length(Items)-1].TopAdr := TopAdr; Items[Length(Items)-1].LeftAdr := LeftAdr; Items[Length(Items)-1].Image.Tag := Length(Items)-1; AktualItem := Image; AktualItem.Picture.LoadFromFile(CestaPrimary+obrAkt); Items[AktualItem.Tag].Akt := AktualItem.Picture; {..Zobrazeni adresy pridavaneho zarizeni..} if Items[AktualItem.tag].TopAdr <> 0 then Begin i := 0; Bitmap := TBitmap.Create; Bitmap1:= TBitmap.Create; AdrSek0 :=copy(LBLAdrSlave.Caption, 1, 1); AdrSek1 :=copy(LBLAdrSlave.Caption, 2, 1); Repeat if i = 0 then Begin Path := CestaPrimary+((Items[AktualItem.Tag].cesta)+('..\adress\')+AdrSek0+('.bmp')); Bitmap1.LoadFromFile(Path); End; if i = 1 then Path := CestaPrimary+((Items[AktualItem.Tag].cesta)+('..\adress\')+AdrSek1+('.bmp')); Bitmap.LoadFromFile(Path); {..nastaveni polohy prekresleni bitmapy..} x := (Items[AktualItem.Tag].LeftAdr); t := (Items[AktualItem.Tag].TopAdr); y := Bitmap.Width; z := Bitmap.Height; MyRect := Rect(0, 0, y, z); MyOther := Rect( x+(i*(Bitmap1.Width)), t, (x+y)+(i*(Bitmap1.Width)), (t+z) );
- 31 -
{..prekresleni..} Aktualitem.Canvas.BrushCopy(MyOther, Bitmap, MyRect, clBlack); Aktualitem.Canvas.CopyRect(MyOther, Bitmap.Canvas, MyRect); {..aktivni okraj..} AktualItem.Picture.Bitmap.Canvas.Pen.Color := clBlack; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); i := i + 1; Until i = 2; {..Ulozeni AktualStav do pole pr...} Items[AktualItem.Tag].Akt := AktualItem.picture; Bitmap.Free; Bitmap1.Free; AktualItem := nil; End else ShowMessage('Upozornění : Toto zařízení nepoužívá adresu!'); End else ShowMessage('Zadaná adresa je již obsazena!!'); End else ShowMessage('Není vybrané žádné zařízení!'); end; //---------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.BtnDelItemClick(Sender: TObject); {...vymazat prvek z pracovní plochy...} Begin if ItemsCount <> 0 then Begin if AktualItem <> nil then Begin Items[AktualItem.tag].Image := nil; Items[AktualItem.tag].adress := ''; AktualItem.Free; LBLNazev.Caption := 'Komponenta'; LBLAdresStav.Caption := ''; EDTZmenaAdr.Text := ''; AktualItem := nil; ItemsCount := ItemsCount - 1; End else ShowMessage('Žádné aktivní zařízení!'); End else ShowMessage('Žádné aktivní zařízení!'); End; //------------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.KomponentaClick(Sender: TObject); {.. SLAVE on CLICK...} begin if AktualItem <> nil then {..predchozi se stane neaktivnim..} Begin AktualItem.Picture.Bitmap.Canvas.Pen.Color := clBlack; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); End; AktualItem := Sender as TImage; AktualItem.Picture.Bitmap.Canvas.Pen.Color := clLime; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8;
- 32 -
AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(AktualItem.Width),(AktualItem.Height)); LBLNazev.Caption := (Items[AktualItem.Tag].SlaveName)+' : '+(Items[AktualItem.tag].SubName); LBLAdresStav.Caption := Items[AktualItem.Tag].adress; EDTZmenaAdr.Text := Items[AktualItem.tag].adress; end; //----------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.BtnLoadClick(Sender: TObject); {LOAD z ini soubooru} var IniSoub : TIniFile; IniCesta : string; begin IniCesta :=CestaPrimary+('slaves\slave001\slave001.ini'); IniSoub := TIniFile.Create(inicesta); try Adress := IniSoub.ReadString('Slave', 'adress', 'FF'); SlaveName := IniSoub.ReadString('Slave', 'SlaveName', 'NoName'); SubName := IniSoub.ReadString('Slave', 'SubName', 'NoName'); ObrAkt := IniSoub.ReadString('Slave', 'obrAkt', 'slaves\none.bmp'); ObrAkce := 'c'{IniSoub.ReadString('Slave', 'obrAkce', 'slaves\none.bmp')}; Cesta:= Inisoub.ReadString('Slave', 'cesta', 'slaves\'); wpole1:= Inisoub.ReadString('Slave', 'WPole1', 'slaves\none1.bmp'); wpole2:= Inisoub.ReadString('Slave', 'WPole2', 'slaves\none1.bmp'); wpole3:= Inisoub.ReadString('Slave', 'WPole3', 'slaves\none1.bmp'); wpole4:= Inisoub.ReadString('Slave', 'WPole4', 'slaves'); posunL:= StrToInt(Inisoub.ReadString('Slave', 'posunL', '0')); posunT:= StrToInt(Inisoub.ReadString('Slave', 'posunT', '0')); TopAdr:= StrToInt(Inisoub.ReadString('Slave', 'TopAdr', '0')); LeftAdr:= StrToInt(Inisoub.ReadString('Slave', 'LeftAdr', '0')); finally IniSoub.Free; end; {..zobrazeni udaju nactenych z ini souboru..} ImgNahled.Picture.LoadFromFile(CestaPrimary+ObrAkt); LBLAdrSlave.Caption := adress; LBLSlaName.Caption := SlaveName; LBLSubNameSlave.Caption := SubName; BtnLoad.Visible := false; end; procedure THlOkno.BtnNextClick(Sender: TObject); {NEXT} {...nacteni z ini...} var IniSoub : TIniFile; IniCesta : string; begin {Zde cislo 3 znazornuje pocet pouzivanych komponent} if XX = 3 then XX := 1 else XX:=XX+1; IniCesta := CestaPrimary+('slaves\slave00'+IntToStr(XX)+'\slave00'+IntToStr(XX)+'.ini'); IniSoub := TIniFile.Create(inicesta); try Adress := IniSoub.ReadString('Slave', 'adress', 'FF'); SlaveName := IniSoub.ReadString('Slave', 'SlaveName', 'NoName'); SubName := IniSoub.ReadString('Slave', 'SubName', 'NoName'); ObrAkt := IniSoub.ReadString('Slave', 'obrAkt', 'slaves\none.bmp'); ObrAkce := 'c'{IniSoub.ReadString('Slave', 'obrAkce', 'slaves\none.bmp')}; Cesta:= Inisoub.ReadString('Slave', 'cesta', 'slaves\'); wpole1:= Inisoub.ReadString('Slave', 'WPole1', 'slaves\none1.bmp'); wpole2:= Inisoub.ReadString('Slave', 'WPole2', 'slaves\none1.bmp'); wpole3:= Inisoub.ReadString('Slave', 'WPole3', 'slaves\none1.bmp'); wpole4:= Inisoub.ReadString('Slave', 'WPole4', 'slaves\none1.bmp');
- 33 -
posunL:= StrToInt(Inisoub.ReadString('Slave', 'posunL', '0')); posunT:= StrToInt(Inisoub.ReadString('Slave', 'posunT', '0')); TopAdr:= StrToInt(Inisoub.ReadString('Slave', 'TopAdr', '0')); LeftAdr:= StrToInt(Inisoub.ReadString('Slave', 'LeftAdr', '0')); finally IniSoub.Free; end; {..zobrazeni udaju nactenych z ini souboru..} ImgNahled.Picture.LoadFromFile(CestaPrimary+ObrAkt); LBLAdrSlave.Caption := adress; LBLSlaName.Caption := SlaveName; LBLSubNameSlave.Caption := SubName; end; procedure THlOkno.BtnPrevClick(Sender: TObject); {PREVIOUS} {...nacteni z ini...} var IniSoub : TIniFile; IniCesta : string; Begin {Zde cislo 3 znazornuje pocet pouzivanych komponent} if XX = 1 then XX := 3 else XX:=XX-1; IniCesta :=CestaPrimary+('slaves\slave00'+IntToStr(XX)+'\slave00'+IntToStr(XX)+'.ini'); IniSoub := TIniFile.Create(inicesta); try {..Nacitani promennych z ini souboru..} adress := IniSoub.ReadString('Slave', 'adress', 'FF'); SlaveName := IniSoub.ReadString('Slave', 'SlaveName', 'NoName'); SubName := IniSoub.ReadString('Slave', 'SubName', 'NoName'); obrAkt := IniSoub.ReadString('Slave', 'obrAkt', 'slaves\none.bmp'); obrAkce := 'c' {IniSoub.ReadString('Slave', 'obrAkce', 'slaves\none.bmp')}; cesta:= Inisoub.ReadString('Slave', 'cesta', 'slaves\'); wpole1:= Inisoub.ReadString('Slave', 'WPole1', 'slaves\none1.bmp'); wpole2:= Inisoub.ReadString('Slave', 'WPole2', 'slaves\none1.bmp'); wpole3:= Inisoub.ReadString('Slave', 'WPole3', 'slaves\none1.bmp'); wpole4:= Inisoub.ReadString('Slave', 'WPole4', 'slaves\none1.bmp'); posunL:= StrToInt(Inisoub.ReadString('Slave', 'posunL', '0')); posunT:= StrToInt(Inisoub.ReadString('Slave', 'posunT', '0')); TopAdr:= StrToInt(Inisoub.ReadString('Slave', 'TopAdr', '0')); LeftAdr:= StrToInt(Inisoub.ReadString('Slave', 'LeftAdr', '0')); finally IniSoub.Free; End; {..zobrazeni udaju nactenych z ini souboru..} ImgNahled.Picture.LoadFromFile(CestaPrimary+obrakt); LBLAdrSlave.Caption := adress; LBLSlaName.Caption := SlaveName; LBLSubNameSlave.Caption := SubName; s := SlaveName; End; //----------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.GBSitClick(Sender: TObject); {...CLICK MIMO...} begin if AktualItem <> nil then Begin AktualItem.Picture.Bitmap.Canvas.pen.Color:=clBlack;
- 34 -
AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); End; LBLNazev.Caption := 'Komponenta'; LBLAdresStav.Caption := ''; EDTZmenaAdr.Text := ''; AktualItem := nil; end; //-------------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.Vymaz2Click(Sender: TObject); {vymazat plochu} var i : integer; begin i:=0; Repeat Items[i].Image.Free; Items[i].adress := ''; i:=i+1; Until i = Length(Items); SetLength(Items, 0); cislo:=0; end; //------------------------------------------------------------------------------------------------------------------------------------------------{..presun komponenty..} procedure THlOkno.PresunClick(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer); Begin if Aktualitem <> nil then Begin AktualItem.Picture.Bitmap.Canvas.pen.Color:=clBlack; {predchozi aktualitem se stane neaktivnim} AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); End; AktualItem := Sender as TImage; {presouvana komponenta se stane aktivni} AktualItem.Picture.Bitmap.Canvas.pen.Color:=clLime; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); downX := X; downY := Y; dragging := True; with TMCapture(Sender) do begin MouseCapture := True; Color := clRed; end; End; procedure ThlOkno.KompMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); Begin if dragging then with Sender as TControl do begin Left := X - downX + Left; Top := Y - downY + Top; end; End; procedure THlOkno.KompPust(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Begin if dragging then
- 35 -
begin dragging := False; with TMCapture(Sender) do begin MouseCapture := False; Color := clBlue; end; end; Items[AktualItem.Tag].leftpos := AktualItem.Left; {ulozi zmenenou pozici do pole promennych} Items[AktualItem.Tag].toppos := AktualItem.Top; {ulozi zmenenou pozici do pole promennych} End; //-----------------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.BtnZmenaAdrClick(Sender: TObject); {...ZMENA ADRESY...} begin if AktualItem <> nil then if Items[AktualItem.tag].TopAdr <> 0 then Begin EDTZmenaAdr.Visible := true; BtnZmenaAdr.Caption := 'Uložit'; BtnZmenaAdr.OnClick := ZmenaAClick; End else ShowMessage('Vybrané zařízení nepoužívá adresu!') else ShowMessage('Není vybrané žádné zařízení!'); end; procedure THlOkno.BtnChangeAdrClick(Sender: TObject); Begin if XX <> 0 then if TopAdr <> 0 then Begin EDTzmena.Text := adress; EDTzmena.Visible := true; BtnChangeAdr.Caption := 'Uložit'; BtnChangeAdr.OnClick := ZmenaClick; End else ShowMessage('Vybrané zařízení nepoužívá adresu!') else ShowMessage('Není vybrané žádné zařízení!'); end; procedure THlOkno.ZmenaAClick(Sender : Tobject); var Path : string; AdrSek0, AdrSek1 : string; g, x, t, y, i, z : integer; Bitmap1, Bitmap : TBitmap; MyRect, MyOther : TRect; Begin g:=0; i := Length(Items); Repeat if Items[i-1].adress = EdtZmenaAdr.Text then g := 1; i := i-1; Until i = 0; if g = 0 then Begin try BtnZmenaAdr.Caption := 'Změnit adresu'; Items[AktualItem.Tag].adress:=EdtZmenaAdr.Text; LBLAdresStav.Caption := EdtZmenaAdr.text;
- 36 -
{..zobrazeni zmenene adresy..} if Items[AktualItem.tag].TopAdr <> 0 then Begin i := 0; Bitmap := TBitmap.Create; Bitmap1:= TBitmap.Create; AdrSek0 := copy(LBLAdresStav.Caption, 1, 1); AdrSek1 := copy(LBLAdresStav.Caption, 2, 1); Repeat if i = 0 then Begin Path := CestaPrimary + ((Items[AktualItem.tag].cesta)+('..\adress\')+AdrSek0+('.bmp')); Bitmap1.LoadFromFile(Path); End; if i = 1 then Path := CestaPrimary + ((Items[AktualItem.tag].cesta)+('..\adress\')+AdrSek1+('.bmp')); Bitmap.LoadFromFile(Path); {..nastaveni polohy prekresleni bitmapy..} x := (Items[AktualItem.Tag].LeftAdr); t := (Items[AktualItem.Tag].TopAdr); y := Bitmap.Width; z := Bitmap.Height; MyRect := Rect(0, 0, y, z); MyOther := Rect( x+(i*(Bitmap1.Width)), t, (x+y)+(i*(Bitmap1.Width)), (t+z) ); {..prekresleni..} Aktualitem.Canvas.BrushCopy(MyOther, Bitmap, MyRect, clBlack); Aktualitem.Canvas.CopyRect(MyOther, Bitmap.Canvas, MyRect); {..aktivni okraj..} AktualItem.Picture.Bitmap.Canvas.Pen.Color := clLime; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); i := i + 1; Until i = 2; {..Ulozeni AktualStav do pole pr...} Items[AktualItem.Tag].Akt := AktualItem.picture; Bitmap.Free; Bitmap1.Free; End; finally EDTzmenaAdr.Visible := false; BtnZmenaAdr.OnClick := BtnZmenaAdrClick; end; end else ShowMessage('Zadaná adresa je již obsazena!!'); End; procedure THlOkno.ZmenaClick(Sender : Tobject); var IniSoub : TIniFile; IniCesta : string; Begin IniCesta :=CestaPrimary + ('slaves\slave00'+IntToStr(XX)+'\slave00'+IntToStr(XX)+'.ini'); IniSoub := TIniFile.Create(inicesta); try IniSoub.WriteString('slave', 'adress', EDTzmena.Text);
- 37 -
BtnChangeAdr.Caption := 'Změnit adresu'; EDTzmena.Visible := false; LBLAdrSlave.Caption := EDTzmena.text; adress := EDTzmena.Text; finally IniSoub.Free; EDTzmena.Visible := false; BtnChangeAdr.OnClick := BtnChangeAdrClick; end; end; //--------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.TimerTimer(Sender: TObject); {Prijem z COM Portu + zobrazeni akt.stavu} var pom : byte; stavsentpath, Bin, pomoc : string; g, x, t, y, i, z, pomo : integer; Bitmap : TBitmap; MyRect, MyOther : TRect; Aktt : Timage; Begin dato := ReadByte; {Kdyz je na portu prijaty bajt} while dato <> 65535 do Begin Bin := ''; Pom := Dato; while Length(Bin) < 8 do {prevest z dekadickeho do binarniho zapisu} begin Bin := IntToStr(Pom mod 2) + Bin; Pom := Pom div 2; end; g:=0; x:=0; i:=0; if Length(Items) <> 0 then Begin i := Length(Items); Repeat if Items[i-1].adress = '--' then Begin pomo:=0; Repeat Edit1.Text := copy(bin,pomo+1,1); Bitmap := TBitmap.Create; StavSentPath := CestaPrimary + ((Items[i-1].cesta)+('stav\')+ Edit1.Text +('.bmp')); Bitmap.LoadFromFile(StavSentPath); {..nastaveni polohy prekresleni..} x := (Items[i-1].LeftStav); t := (Items[i-1].TopStav); y := StrToInt(Items[i-1].wpole1); z := StrToInt(Items[i-1].wpole2); MyRect := Rect(0, 0, y, z); MyOther := Rect( x+(pomo*y), t, (x+y)+(pomo*y), (t+z) ); {..prekresleni..} Items[i-1].Image.Canvas.BrushCopy(MyOther, Bitmap, MyRect, clBlack); Items[i-1].Image.Canvas.CopyRect(MyOther, Bitmap.Canvas, MyRect); {..Ulozeni aktualniho stavu do pole pr...}
- 38 -
Items[i-1].Akt := Items[i-1].Image.picture; Bitmap.Free; pomo := pomo + 1; Until pomo = 8 ; End; i := i - 1; Until i = 1; i := 0; End; ukazatel := StrToint(copy(Bin,1,1)); ZapisDato(Dato); {Zavolá proceduru pro výpis prijateho bajtu do tablky} {ADRESA} if ukazatel = 1 then {.. když je přijatý bajt adresový ..} Begin {..predchozi se stane neaktivnim..} if AktualItem <> nil then Begin AktualItem.Picture.Bitmap.Canvas.Pen.Color := clBlack; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); End; {zde se musi odstranit adresovy priznakovy bit aby bylo mozne porovnavat adresy} i:=8; x:=0; pomo:=0; {Odstrani adresovy priznakovy bit} Pomoc:='0'+ copy(bin,2,7); Repeat {Smycka prevede adresu do hex tvaru} if i = 8 then x :=1; if i = 7 then x :=2; if i = 6 then x :=4; if i = 5 then x :=8; if i = 4 then x :=16; if i = 3 then x :=32; if i = 2 then x :=64; if i = 1 then x :=128; pomo := x * StrToInt(copy(pomoc,i,1)) + pomo ; i:=i-1 Until i=1; Edit2.Text:=IntToHex(pomo,2);
{adresa v hex zapsana do pomocne edit2}
{zjisteni shodne adresy v nadefinovane siti} g:=0; x:=0; if Length(Items) <> 0 then Begin i := Length(Items); Repeat if Items[i-1].adress = Edit2.Text then Begin x := 1; {priznak nalezeni shodne adresy} g := 1; {priznak pro ukonceni vyhledavani} End; i := i - 1; if i = 0 then g := 1; Until g = 1;
- 39 -
if x = 1 then {kdyz nalezena shodna adresa} Begin Aktualitem := Items[i].Image; {..aktivni okraj..} AktualItem.Picture.Bitmap.Canvas.Pen.Color := clLime; AktualItem.picture.Bitmap.Canvas.Pen.Width := 8; AktualItem.picture.Bitmap.Canvas.Brush.Style := bsClear; AktualItem.Picture.Bitmap.Canvas.Rectangle(0,0,(Aktualitem.Width),(Aktualitem.Height)); i := 0; k := 0; End else ShowMessage('Přijatá adresa není nadefinovaná!!!'); End else ShowMessage('Není nadefinované žádné zařízení!'); End; {DATO} if (ukazatel = 0) and (aktualitem <> nil) then {.. kdyz se jedna o dato a je slave aktivni..} Begin if k = StrToInt(Items[AktualItem.Tag].wpole4) then k:=0; if bin ='00000000' then Edit1.Text:='non'; if bin ='01111110' then Edit1.Text:='0'; if bin ='00110000' then Edit1.Text:='1'; if bin ='00110101' then Edit1.Text:='2'; if bin ='01111001' then Edit1.Text:='3'; if bin ='00110011' then Edit1.Text:='4'; if bin ='01011011' then Edit1.Text:='5'; if bin ='01011111' then Edit1.Text:='6'; if bin ='01110000' then Edit1.Text:='7'; if bin ='01111111' then Edit1.Text:='8'; if bin ='01111011' then Edit1.Text:='9'; if bin ='01110111' then Edit1.Text:='A'; if bin ='00011111' then Edit1.Text:='B'; if bin ='01001110' then Edit1.Text:='C'; if bin ='00111101' then Edit1.Text:='D'; if bin ='01001111' then Edit1.Text:='E'; if bin ='00000001' then Edit1.Text:='-'; if bin ='00001000' then Edit1.Text:='S1'; if bin ='01000000' then Edit1.Text:='S2'; if bin ='00000100' then Edit1.Text:='S3'; if bin ='00010000' then Edit1.Text:='s4'; if bin ='00000010' then Edit1.Text:='s5'; if bin ='00100000' then Edit1.Text:='s6'; if bin ='01100011' then Edit1.Text:='z1'; Bitmap := TBitmap.Create; StavSentPath := CestaPrimary + ((Items[Aktualitem.Tag].cesta)+('stav\')+ Edit1.Text +('.bmp')); Bitmap.LoadFromFile(StavSentPath); {..nastaveni polohy prekresleni..} x := (Items[Aktualitem.Tag].LeftStav); t := (Items[Aktualitem.Tag].TopStav); y := StrToInt(Items[Aktualitem.Tag].wpole1); z := StrToInt(Items[Aktualitem.Tag].wpole2); MyRect := Rect(0, 0, y, z); MyOther := Rect( x+(k*y), t, (x+y)+(k*y), (t+z) );
- 40 -
{.. prekresleni ..} Aktualitem.Canvas.BrushCopy(MyOther, Bitmap, MyRect, clBlack); Aktualitem.Canvas.CopyRect(MyOther, Bitmap.Canvas, MyRect); {..Ulozeni aktualniho stavu do pole pr...} Items[Aktualitem.Tag].Akt := Aktualitem.picture; Bitmap.Free; k := k + 1; End; dato := ReadByte; end; end; //--------------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.ZapisDato(Dato : byte); {procedura pro zapis prijatych dat do tabulky} var Bin : string; New : TListItem; Pom : byte; Begin if ukazatel = 1 then LVTabulka.Font.Color := clRed else LVTabulka.Font.Color := clGreen; {pridej do tabulky dalsi radek} New := HlOkno.LVTabulka.Items.Add; New.Caption := TimeToStr(Time); {do prvniho sloupce noveho radku pridej cas prijeti} Bin := ''; Pom := Dato; while Length(Bin) < 8 do {prevest z dekadickeho do binarniho zapisu} Begin Bin := IntToStr(Pom mod 2) + Bin; Pom := Pom div 2; End; {a do druheho sloupce zapsat binarne} New.SubItems.Add(Bin); New.SubItems.Add(IntToHex(Dato,2)); {do tretiho hexadecimalne} New.ListView.Scroll(0, 3000); End; //------------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.Parametry1Click(Sender: TObject); {...OPEN...} var Zarizeni : TZarizeni; s , xeno: string; image6 : TImage; i, pppp : integer; begin i:=0; if OpenDialog.Execute then Begin SetLength(Items, 0); AssignFile(Soubor, OpenDialog.FileName); Reset(Soubor); {nacitej udaje dokud neni konec souboru} while not Eof(Soubor) do Begin Read(Soubor, Zarizeni); SetLength(Items, Length(Items) + 1); Items[i] := Zarizeni; Image6 := TImage.Create(GBSit); Image6.AutoSize := true; Image6.Visible := true;
- 41 -
Image6.Left := Items[i].leftpos ; {nacte pozici vkl. obrazku} Image6.Top := Items[i].toppos; {nacte pozici vkl. obrazku} Image6.Parent := GBSit; Image6.AutoSize := true; Image6.Cursor := crHandPoint; Image6.OnClick := KomponentaClick; Image6.OnMouseDown := PresunClick; image6.OnMouseMove := KompMove; Image6.OnMouseUp := KompPust; cislo := cislo + 1; ItemsCount := ItemsCount + 1; pppp := Length(ExtractFileName(opendialog.FileName))-Length(ExtractFileExt(openDialog.FileName)); xeno := copy(ExtractFileName(opendialog.FileName),1, pppp) ; s := ExtractFilePath(Opendialog.FileName) + xeno +'00' + IntToStr(i) + '.bmp'; if items[i].Image <> nil then Begin items[i].Image := nil; items[i].image := image6; image6.Picture.LoadFromFile(s); Items[i].image.tag := i; showMessage('Zařízení : '+ items[i].Slavename + items[i].subname + ', Adresa: ' + items[i].adress); End; i:=i+1; End; End; end; //-----------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.Ulozits1Click(Sender: TObject); {SAVE} var i, pppp: integer; meno, xeno: string; begin i := 0; if SaveDialog.Execute then Begin AssignFile(Soubor, SaveDialog.FileName); Rewrite(Soubor); Repeat Begin write(Soubor, Items[i]); pppp := Length(ExtractFileName(Savedialog.FileName))-Length(ExtractFileExt(SaveDialog.FileName)); xeno := copy(ExtractFileName(Savedialog.FileName),1, pppp) ; meno := ExtractFilePath(Savedialog.FileName) + xeno +'00' + IntToStr(i) + '.bmp'; if Items[i].image <> nil then Begin //zvlast uklada obrazek každého prvku Items[i].Image.Picture.SaveToFile(meno); End; End; i := i + 1; Until i = Length(Items); End; end; //-----------------------------zaverecne procedury------------------------------------------------------------------------------------//-------------------------------------------------------------------------------------------------------------------------------------------------procedure THlOkno.Ukoncitprogram1Click(Sender: TObject); {...Close Application...} begin {Ukonceni aplikace} Application.Terminate ; end; procedure THlOkno.Oprogramu3Click(Sender: TObject);
- 42 -
begin AboutBox.Show; {zobrazeni okna o programu} end; procedure THlOkno.FormClose(Sender: TObject; var Action: TCloseAction); begin {Komunikace s portem - close} CloseCOM; end; procedure THlOkno.Zavt1Click(Sender: TObject); begin Vlast.show; {zobrazeni prehledu komponenent} end; procedure THlOkno.BtnSmazatoClick(Sender: TObject); begin LVTabulka.Clear; {smazání tabulky přehledu přijatých dat} end; procedure THlOkno.Oprogramu1Click(Sender: TObject); begin {zobrazeni napovedy} // help end; end.
{konec prekladu}
- 43 -