Optimalisatie van de communicatie- en meetomgeving van een aanstuurbord voor bistabiele displays

Maat: px
Weergave met pagina beginnen:

Download "Optimalisatie van de communicatie- en meetomgeving van een aanstuurbord voor bistabiele displays"


1 Faculteit Ingenieurswetenschappen Vakgroep TFCG Microsystems Lab Voorzitter: Prof. Dr. ir. André Van Calster Optimalisatie van de communicatie- en meetomgeving van een aanstuurbord voor bistabiele displays door Jochen Verbrugghe Promotor: Prof. Dr. ir. A. Van Calster Scriptiebegeleiders: ir. A. Monté en Prof. Dr. ir. J. Doutreloigne Scriptie ingediend tot het behalen van de academische graad van Burgerlijk ingenieur in de computerwetenschappen Academiejaar


3 Faculteit Ingenieurswetenschappen Vakgroep TFCG Microsystems Lab Voorzitter: Prof. Dr. ir. André Van Calster Optimalisatie van de communicatie- en meetomgeving van een aanstuurbord voor bistabiele displays door Jochen Verbrugghe Promotor: Prof. Dr. ir. A. Van Calster Scriptiebegeleiders: ir. A. Monté en Prof. Dr. ir. J. Doutreloigne Scriptie ingediend tot het behalen van de academische graad van Burgerlijk ingenieur in de computerwetenschappen Academiejaar

4 Voorwoord Van alle opties van de richting computerwetenschappen, is bij ingebedde systemen het meest plaats voor elektronica. Het was dan ook mijn bedoeling om in mijn scriptie een combinatie te vinden van zowel ontwikkeling van software als ontwerp van de onderliggende elektronica. Dat was het geval met dit onderwerp. Een extra uitdaging was het laten samenwerken van de verschillende softwaresystemen, geschreven in zowel het hoogniveau C# als het lage C/assembler niveau met daartussen een handvol C++. Een woord van dank gaat uit naar ir. Ann Monté voor een goede en leuke samenwerking. Ook bedank ik Prof. Dr. ir Jan Doutreloigne voor de begeleiding en uitleg. Toelating tot bruikleen De auteur geeft de toelating deze scriptie voor consultatie beschikbaar te stellen en delen van de scriptie te kopiëren voor persoonlijk gebruik. Elk ander gebruik valt onder de beperkingen van het auteursrecht, in het bijzonder met betrekking tot de verplichting de bron uitdrukkelijk te vermelden bij het aanhalen van resultaten uit deze scriptie. Jochen Verbrugghe, mei 2007

5 Optimalisatie van de communicatie- en meetomgeving van een aanstuurbord voor bistabiele displays door Jochen Verbrugghe Scriptie ingediend tot het behalen van de academische graad van burgerlijk ingenieur in de computerwetenschappen Academiejaar Promotor: Prof. Dr. ir. A. Van Calster Scriptiebegeleiders: ir. A. Monté en Prof. Dr. ir. J. Doutreloigne Faculteit Ingenieurswetenschappen Universiteit Gent Vakgroep TFCG Microsystems Lab Voorzitter: Prof. Dr. ir. André Van Calster ii Samenvatting In het kader van een doctoraat werd een aanstuurbord ontwikkeld om een bistabiel display aan te sturen. Vanaf een PC kunnen beelden worden afgebeeld. In deze scriptie wordt het seriële communicatiekanaal vervangen door een USB-verbinding en wordt de rol van de PC uitgebreid. Het nieuwe grafisch controleprogramma biedt totale controle over het bord. Verder wordt ook een methode voor semi-automatische vermogenmeting uitgewerkt die toelaat het vermogen te meten dat het display dissipeert bij het afbeelden van een beeld. Trefwoorden USB, C#, oscilloscoop automatisatie, 8051

6 Optimization of the Communication and Test Setup for a Bistable Display Motherboard Jochen Verbrugghe Supervisor(s): Ann Monté, Jan Doutreloigne Abstract This article discusses three enhancements to a bistable display motherboard. First, the serial PC-motherboard link is upgraded to a modern USB interface. Second, a graphical PC front end is developed to provide rich functionality, yet is easy to use. Third, a semi-automatic power measurement setup, integrated with the PC front end, is presented to evaluate power consumption during a display cycle. Keywords USB,.NET, C, oscilloscope control I. INTRODUCTION BISTABLE displays keep their image when no voltage source is connected. This makes them an excellent choice for battery-driven appliances with low refresh rates. The TFCG department has developed advanced chips that generate the complex waveforms that drive these displays. A motherboard contains a microcontroller chip, 128 KiB flash memory, an FPGA and the drivers. Via the microcontroller, a PC can upload grayscale images to the flash which are used by the FPGA to control the driver chips. A MAX232 converts between serial and CMOS levels. To enable more efficient testing, a new graphical PC front end and new microcontroller code is realised. A USB communication link ensures a high-speed connection. A method for power measurement is developed for semi-automatic testing and is integrated with the new user interface. II. USB COMMUNICATION LINK The microcontroller DS89C420 communicates with the PC using its integrated serial port. It does not sport an USB stack. Consequently, we need a USB/serial converter chip: the FT232R by FTDI. As the development of a new printed circuit board is costly, a modular solution is presented. Because level conversion is integrated with the FT232R, the MAX232 is dropped and the electronics for USB communication, placed on a separate assembly, are plugged into the socket of the MAX232. The circuit schematic is shown in figure 1. LEDs D1 and D2 light up when data is received or transmitted. The other components are resetting the chip on power-up or are decoupling signals. III. SOFTWARE A user can perform actions, defined as interactions with the display. Possible actions are uploading an image or project to the flash, downloading and displaying it. A project is a collection of 16 images. The communication is adhering to a simple protocol: ASCII commands initiate an action, the microcontroller acknowledges, parameters are sent and the action is carried out. Because of this sequential structure, they are implemented as communicating finite state machines (CFSM), one in Fig. 1. Schematic of the USB module. the PC and one in the microcontroller. A. PC front end The FT232R chip comes with a native Win32 driver. As the front end is written C# 2.0, the PC software is divided in 2 parts: 1. the DLL FT232RWrapper that wraps the native driver in an object-oriented C# class; 2. the application BDControl which provides a user interface (UI) and implements all functionality. BDControl (figure 2) has a highly object-oriented structure. Together with a layered communication model, it is easily modified to allow other communication means and additional actions. Its main classes can be summarized as following. Image and project management: these classes model images and projects. They provide functionality such as saving and loading from disk, importing and setting up the actions. GUI classes: the UI is comprised of several custom controls, derived from the C# class UserControl. Their main function is to accept user input and present results. They contain almost no business logic but serve only as glue logic. Four child windows are implemented: a project navigator, an image visualizer, a log view and a power measurement control interface. Action classes: due to their specific dependent nature, e.g. storing a project is essentially just storing 16 images, actions can be implemented as a class hierarchy. Communication classes: the lowest level of communication is controlled by the native FT232R driver. One level up is the wrapper mentioned above. This class implements the communication primitives such as sending or receiving n bytes. On the highest level, an abstract communicator takes care of processing commands such as awaiting an acknowledge. This class is used by the derived action classes. 24/05/ :33:44 D:\Data\Documents\BC3\Thesis\Verslag\Diagramma\usbmodule.sch (Sheet: 1/1)

7 B. Microcontroller code Fig. 2. BDControl. The microcontroller code, written in C, consists of 4 state machines: a main FSM calls the FSMs that implement the 3 actions store image, load image, display image. During normal operation, the controller is idle: it goes into a power saving mode. When a character is received, an interrupt is triggered and the state of the main FSM is changed accordingly in the interrupt service routine (ISR). This state subsequently calls the correct FSM. It is this approach that makes idle mode possible, as no data polling of the serial port buffers is required. Also the ISR is sufficiently short, only one variable is changed. To avoid race conditions, serial interrupts are masked during action execution. The flash chip has to be programmed on a sector-by-sector basis. 128 bytes and addresses are loaded and simultaneously programmed. Therefore, during execution of the store action, data is received from the PC in blocks of 128 bytes. They are buffered by the microcontroller and then copied to the flash memory, which is accessed as external memory. The end of a program cylce ( 10 ms) can be detected by data polling: during a program cycle an attemped read of the last byte loaded will result in the complement of the loaded data on I/O7. Once the programming has been completed, true data is valid on all outputs. De load action merely sends an image back to the PC, in one chunk. To display an image, the microcontroller needs to transfer data to the FPGA. A simple protocol is used: a reset pulse is given, data is put on the databus and a data available signal is set. This signal instructs the FPGA to cache the data. The microcontroller is running at 32 MHz, while the FPGA is running at 4 MHz. In order to meet setup and hold time constraints, and to allow the FPGA to capture the data, additional wait cycles are inserted in the code. line. Power is dissipated while displaying an image. To measure the dissipation, the voltage drop across a small shunt resister is measured which gives us the current flowing through the line. The formula P = V I gives us the power. As the voltage drop is time-dependent, the average and peak power will be computed. The voltage drop waveform is captured using the dualchannel Tektronix THS720A oscilloscope. A reset puls of the display s driving signals is used as a trigger. Two kind of measurements are defined: 1. Global measurement: measurement during a full display cycle. This is around 250 ms. 2. Local measurement: measurement during a shorter time, the window. As the scope only samples 2500 data points, a global measurement is only useful to extract windows. Local measurements with a sufficiently short window give accurate results. BDControl has been adapted to provide this new functionality. A dedicated class sets up the scope via a serial connection and initiates a display action. The received curve is processed and results are presented to the user. An example of a global and local measurement of the 60 V line is given in figures 3 and 4. Fig. 3. Example of a global measurement. Fig. 4. Example of a local measurement. Average and peak power are 99.3 mw and mw with a window length of 50 µs. V. CONCLUSION To be able to measure power indicates that all vital components function correctly: the USB communication link, the front end BDControl and the computer controlled oscilloscope. A sufficiently short window ensures accurate results. REFERENCES [1] Michael J. Pont, Embedded C, Addison Wesley Publishing Company, [2] Thomas W. Schultz, C and the 8051, Pagefree Publishing, [3] Jeroen Hoet, Automatiseren van een meetopstelling voor het opmeten van het vermogenverbruik in beeldschermen, Ghent University, Master Thesis, IV. SEMI-AUTOMATIC POWER MEASUREMENT The driver chips use 6 voltage lines: 85 V, 60 V, 55 V, 45 V, 35 V and 5 V. Here, a method is presented to measure power is one

8 Inhoudsopgave 1 Inleiding Systeembeschrijving Belangrijkste componenten Doel van deze scriptie Structuur van het werk Datamodel USB-communicatie Van serieel naar USB Software Ontwerpomgeving Concept Details van de basisacties PC-software De wrapper FT232RDevice De grafische front-end BDControl Klassen voor project- en beeldbeheer GUI-klassen Actieklassen Communicatieklassen Hulpklassen Microcontrollercode Implementatie van de acties Mini DS89C420 programmer iii

9 Inhoudsopgave iv 4 Semi-automatische vermogenmeting Opzet Methode Globale en lokale metingen Uitbreiding van BDControl Illustratie van de methode Voorbeeld Besluit 68 A Klassendiagram 69 B Inhoud van de cdrom 71 C Installatie-instructies 72 Bibliografie 73 Lijst van figuren 75 Lijst van tabellen 77

10 Hoofdstuk 1 Inleiding Binnen de groep TFCG worden geavanceerde driverchips ontwikkeld voor het aansturen van bistabiele displays. Deze beeldschermen behouden hun inhoud na het wegvallen van de voedingsspanning. Ze zijn zeer vermogenefficiënt en dus uitermate geschikt voor batterijgevoede draagbare toepassingen zoals bijv. PDA of e-book. Een nadeel is echter dat vrij hoge spanningen (tot 100 V) vereist zijn om de rijen en kolommen te adresseren. Er wordt dan ook nog steeds gezocht naar methodes om het vermogenverbruik verder te verlagen. Dit gebeurt zowel door het optimaliseren van de hardware als van de software. Wat betreft het hardwaregedeelte is er een voorlopig optimum bereikt. Aan de software zijde kan er echter nog heel wat geoptimaliseerd worden. Onder software verstaan we enerzijds het verzorgen van communicatie tussen de verschillende componenten als het uitvoeren van de nodige berekeningen als het aansturen van het display vanaf een PC. Voorlopig werd een testbordje gemaakt waarop alle aanstuurelektronica geïntegreerd is en dat eveneens de nodige componenten bevat om de communicatie met de buitenwereld te verzorgen. Hierop bevindt zich ook een FPGA en de bijhorende programmeerlogica waarmee de nieuwe software onmiddellijk kan getest worden. 1.1 Systeembeschrijving Deze sectie beschrijft het oorspronkelijk systeem waarmee verder ontwikkeld werd. Figuur 1.1 toont een blokschema. We onderscheiden drie grote componenten: ˆ het bord met eigenlijke bistabiel display en wat perifere elektronica; ˆ een aanstuurbord dat de stuur- en communicatie-elektronica bevat; ˆ een PC die een front-end biedt voor de gebruiker. 1

11 Hoofdstuk 1. Inleiding 2 communicatie 6 aansturing PC aanstuurbord bistabiel display Figuur 1.1: Overzicht van het systeem. Flash drivers μc RS232 FPGA Figuur 1.2: Structuur van het aanstuurbord. Een meer gedetailleerd beeld van het aanstuurbord is te zien in figuur 1.2. De 4 drivers werden ontwikkeld bij TFCG. Zij generen complexe golfvormen om het display aan te sturen. Daarbij wordt gebruik gemaakt van 6 voedingsspanningen: 85 V, 60 V, 55 V, 45 V, 35 V en 5 V. Voor meer informatie wordt de lezer verwezen naar [9]. Eén of meerdere beelden (zie 1.4) kunnen worden opgeslagen in het flashgeheugen. De microcontroller verzorgt de communicatie met de PC en kan beelden doorsturen naar de FPGA die op zijn beurt de drivers aanstuurt. Op het bord is een startknop, resetknop en een 4-wegs jumper aanwezig. Afbeelden van een beeld gebeurt door een druk op de startknop. De jumper bepaalt het beeldnummer.

12 Hoofdstuk 1. Inleiding 3 De microcontroller heeft 2 ingebouwde seriële poorten. De communicatie met de PC verloopt dus logischerwijs via het RS232-protocol. Assemblercode zorgt voor de communicatie met de PC, het schrijven en lezen van het flashgeheugen en het doorsturen van data naar de FPGA. De PC front-end is een eenvoudig opdrachtregelprogramma dat louter beelden stuurt naar de microcontroller Belangrijkste componenten Deze componenten vormen het kloppend hart van de schakeling. Microcontroller De DS89C420 van Maxim/Dallas Semiconductors[13] is qua instructieset identiek met de alom bekende 80C51. De processorkern is echter opnieuw ontworpen waardoor instructies tot 12 keer sneller uitgevoerd worden. Dit leidt tot een typische snelheidswinst van 10 bij gelijke trilfrequentie van het kristal. De kristalfrequentie op het aanstuurbord is 32 MHz. De eigenschappen die hier van belang zijn, zijn de twee seriële poorten, de drie 16-bit timers, het 16 KiB on-chip flashgeheugen en de energiebesparende modus (slaaptoestand). Verder is de chip in-system programmeerbaar en is hij relatief goedkoop. Flashgeheugen De Atmel AT29C2010A is een in-system programmeerbaar en wisbaar ROM (PEROM), dat gebruik maakt van flashtechnologie. Van de 128 KiB grote opslagruimte wordt slechts de onderste 64 KiB gebruikt omdat de adresbus van de microcontroller maar 16 bit breed is. 1 De toegangstijd bij lezen ( 70 ns) is klein genoeg om dat zonder wachttijden te doen. Schrijven gebeurt sector-per-sector: 128 bytes worden in maximaal 10 ms geschreven, wat ook voldoende kort is. Er is geen hoge voedingsspanning vereist voor het schrijven: 5 V is voldoende. Het vermogenverbruik is typisch 275 mw als de chip geselecteerd (het chip select signaal is geasserteerd) is. Bij een inactieve chip bedraagt de standbystroom slechts 100 µa. Field-Programmable Gate Array (FPGA) Een FPGA is een programmeerbare chip. De FPGA op het aanstuurbord is de Altera Cyclone EP1C6[1]. Zijn functie bestaat erin uit configuratiedata en beeldpixels de correcte stuursig- 1 Er kan meer geheugen aangesproken worden door met banken te werken. 64 KiB is echter ruim voldoende voor deze toepassing.

13 Hoofdstuk 1. Inleiding 4 nalen te genereren voor de drivers. Hij wordt aangestuurd door een 4 MHz klok, gegenereerd door de kristaloscillator SG Doel van deze scriptie Het doel van dit werk situeert zich op drie vlakken: in eerst instantie wordt de seriële interface tussen PC en microcontroller vervangen door een moderne USB-verbinding. Naast de veel hogere overdrachtssnelheid is USB ook veel gebruiksvriendelijker dan seriële poorten (bv. kettingen van apparaten vormen). Dat sommige PC s al niet meer uitgerust worden met een seriële poort, is daar een indicatie van. Verder is het de bedoeling dat een nieuwe, gebruiksvriendelijke front-end wordt ontwikkeld. Die moet heel wat meer functionaliteit bieden dan het opdrachtregelprogramma: naast beelden doorsturen moet ook het opsporen van fouten in de microcontrollercode een stuk makkelijker worden. Ook het initiëren van gebruikersacties zoals het laten afbeelden van een beeld moet mogelijk zijn. Een grafische interface is uiteraard gewenst. Ten derde moet het mogelijk gemaakt worden een semi-automatische vermogenmeting te doen aan de voedingslijnen. Dit gebeurt met een digitale oscilloscoop die bestuurd wordt vanaf de PC. Semi-automatisch wijst op het feit dat de gebruikers zelf een probe moet plaatsen op de gewenste voedingslijn. 1.3 Structuur van het werk Deze tekst stelt oplossingen voor voor de hierboven beschreven opgaven. Eerst wordt in hoofdstuk 2 de communicatie via USB mogelijk gemaakt. Hoofdstuk 3 beschrijft de frontend op PC en de code in de microcontroller en hoofdstuk 4 geeft een oplossing voor de vermogenmeting weer. Er wordt afgerond met een besluit. 1.4 Datamodel Voor een goed begrip van de tekst worden hier enkele termen eenduidig gedefinieerd. Een en ander wordt verduidelijkt in figuur 1.3 Beeld Een beeld bestaat uit ˆ 4 bytes aan configuratiegegevens die de FPGA gebruikt om de golfvormen te creëren;

14 Hoofdstuk 1. Inleiding 5 beeld 15 0xF000 0xE000 beeld 14 0x0124 naam 0x0104 0x2000 beelddata beeld 1 0x1000 beeld 0 configuratie 0x0004 0x0000 0x0000 project beeld Figuur 1.3: Het datamodel: schema van project en beeld en alignatie op 4 KiB grenzen. ˆ de eigenlijke visuele data: 256 bytes die een grijswaardebeeld voorstellen op een 16 x 16 raster; ˆ 32 bytes voor de naam van het beeld. Dit zijn 32 ASCII-karakters. Project Een verzameling van zestien beelden vormt een project. In het 64 KiB flashgeheugen worden de beelden opgeslagen op 4 KiB grenzen. Beelden kunnen dus theoretisch vergroot worden tot 4 KiB. Later volgt daarover meer.

15 Hoofdstuk 2 USB-communicatie Dit hoofdstuk beschrijft het aanpassen van de aanstuurelektronica. De seriële interface tussen de PC en het bord moet plaats maken voor een snelle USB-oplossing. 2.1 Van serieel... Een deel van het schema van het aanstuurbord is te zien in de volgende figuur: TxD RxD Figuur 2.1: Circuitschema van de oorspronkelijke seriële communicatie. 6

16 Hoofdstuk 2. USB-communicatie 7 De microcontroller communiceert via zijn UART 1 met de PC. De RS232-specificatie voorziet in een aantal signalen (TxD, RxD, DTR, DSR, DCD,...) waarvan hier enkel de datasignalen TxD en RxD worden gebruikt. De andere signalen dienen voor hardware-handshake en zijn hier overbodig. De poortpinnen voor TxD en RxD zijn respectievelijk P3.1 en P3.0. De bekende MAX232 zorgt voor de spanningsomzetting tussen RS232- en CMOS-niveaus naar USB Omdat de microcontroller niet beschikt over een ingebouwde USB-stack, zal de eigenlijke communicatie serieel moeten blijven: er moet dus een USB/serieel conversie plaats vinden. De FT232R van Future Technology Devices (FTDI) is hiervoor een geschikte chip. 3. Block Diagram De FT232R-chip 3.1 Block Diagram (Simplified) Page 5 VCC 48MHz Baud Rate Generator 3V3OUT USBDP USBDM 3.3 Volt LDO Regulator USB Transceiver with Integrated Series Resistors and 1.5K Pull-up Serial Interface Engine ( SIE ) To USB Transceiver Cell FIFO TX Buffer 128 bytes USB Protocol Engine Internal EEPROM UART FIFO Controller VCCIO UART Controller with Programmable Signal Inversion and High Drive TXD RXD RTS# CTS# DTR# DSR# DCD# RI# CBUS0 CBUS1 CBUS2 CBUS3 CBUS4 USB DPLL 3V3OUT OSCO (optional) OCSI (optional) Internal 12MHz Oscillator Clock Multiplier / Divider 48MHz 24 MHz 12 MHz 6 MHz FIFO RX Buffer 256 bytes RESET# To USB Transceiver Cell RESET GENERATOR TEST GND Figure 1 - FT232R Block Diagram Figuur 2.2: Blokschema van de FT232R. 3.2 Functional Block Descriptions Deze interfacebouwsteen integreert een volledige USB-naar-serieel omzetter en vergt bijna 3.3V LDO Regulator - The 3.3V LDO Regulator generates the 3.3V reference voltage for driving the USB transceiver geen cell output externe buffers. componenten. It requires an external De seriële decoupling signalen capacitor zijnto albe van attached CMOS-niveau to the 3V3OUT door regulator de geïntegreerde output pin. It also provides 3.3V power to the 1.5kΩ internal pull up resistor on USBDP. The main function of this block is to power the 1 Universal USB Transceiver Asynchronous and the Reset Receiver/Transmitter Generator Cells rather than to power external logic. However, external circuitry requiring a 3.3V nominal supply at a current of around than 50mA could also draw its power from the 3V3OUT pin, if required. USB Transceiver - The USB Transceiver Cell provides the USB 1.1 / USB 2.0 full-speed physical interface to the USB cable. The output drivers provide 3.3V level slew rate control signalling, whilst a differential receiver and two single ended receivers provide USB data in, SEO and USB Reset condition detection. This Cell also incorporates internal USB series resistors on the USB data lines, and a 1.5kΩ pull up resistor on USBDP. USB DPLL - The USB DPLL cell locks on to the incoming NRZI USB data and provides separate recovered clock and data signals to the SIE block.

17 Hoofdstuk 2. USB-communicatie 8 spanningsomzetter. De interne klok kan naar buiten gebracht worden. Verder zijn een EEPROM voor configuratiegevens, klokcircuit en USB-weerstanden geïntegreerd op de chip. De klokuitgang kan gebruikt worden om een microprocessor of externe logica te synchroniseren. De weerstanden, gedefinieerd in de USB-specificatie ([8]), zijn seriële of pull-up weerstanden op de USB-datalijnen. Verder zijn drivers voor de gangbare PC-platformen gratis beschikbaar. Figuur 2.2 toont een blokschema waarop de genoemde eigenschappen te zien zijn. Voor meer informatie wordt de lezer verwezen naar [7]. Opzet Het ontwerpen en maken van een nieuw PCB kost veel tijd en geld. Daarom is voor een modulaire opzet gekozen: de vereiste elektronica wordt opgebouwd op een kleine printplaat die in het voetje van de MAX232 geplugd wordt. Naast de voedingsspanning en massa moeten enkel de TxD- en RxD-signalen doorverbonden worden. Figuur 2.3 toont het complete schema van de module. Figuur 2.3: Het schema van de USB-module. De chip is zo geconfigureerd dat LED s D1 en D2 oplichten als er data verstuurd of ontvangen wordt. C1 en C2 ontkoppelen de USB-bus van stoorpulsen en voorkomen zo beschadiging van de USB-host. C3 sluit stoorpulsen op de referentiespanning (3V3OUT) kort naar massa. Als

18 Hoofdstuk 2. USB-communicatie 9 de schakeling op de PC wordt aangesloten, zal het signaal RESET hoog worden en wordt de chip geïnitialiseerd. Even later is het systeem klaar voor communicatie. De voeding wordt volledig betrokken uit het bord (dit noemt men een self-powered USB-device). De host moet dus geen vermogen leveren. Op figuur 2.4 is een foto van het opgebouwde prototype te zien. De FT232R wordt enkel geleverd in een SSOP of QFN behuizing; daarom werd de chip eerst op een adapterprintje naar DIL gesoldeerd. Figuur 2.4: Een foto van het opgebouwde prototype.

19 Hoofdstuk 3 Software Dit hoofdstuk beschrijft de software aan beide uiteinden van de USB-kabel: de front-end BDControl wordt voorgesteld en de nieuwe code voor de microcontroller beschreven. 3.1 Ontwerpomgeving Pc-programma De ontwikkeling van het programma gebeurde onder Windows XP. De driver van de USB-chip wordt geleverd in de vorm van een Win32 DLL. Een voor de hand liggende taalkeuze is daardoor C++. De taal C# werd echter gekozen als ontwikkeltaal voor de PC-frontend. Dit heeft een aantal redenen: ˆ.NET framework: er kan gebruik gemaakt worden van het.net framework van Microsoft. Deze bibliotheken kapselen (een groot deel van) de Win32 API in onder een object-geörienteerde vorm. Verder zijn er een groot aantal nuttige klassen aanwezig die het programmeren sterk versnellen. 1 ˆ Automatisch geheugenbeheer: de garbage collector laat toe om zich te focussen op de algoritmes en niet op het geheugenbeheer. ˆ Excepties: fouten worden in de wereld van de Win32 API kenbaar gemaakt door HRESULTs, boolese teruggeefcodes, integers,... Dit maakt het programmeren heel omslachtig. Het.NET framework gebruikt het C#-exceptiemechanisme voor een uniform model voor foutenrapportage. ˆ RAD: door de opgesomde (en andere) voordelen leent C# zich sterk tot Rapid Application Development. 1 Zogenaamd managed C++ kan wel deze bibliotheken aanspreken. Dit weegt echter niet op tegen de overige voordelen van C#. 10

20 Hoofdstuk 3. Software 11 De ontwikkelomgeving is Visual Studio 2005, een IDE waarvan een gratis Express Edition beschikbaar is. Dit softwarepakket biedt een geïntegreerde omgeving: code schrijven, compileren, linken, debuggen en grafische interfaces ontwerpen via drag-and-drop kan zonder een externe tool. De nieuwe refactoringmogelijkheden in de laatste versie bieden een snelle manier om code structureel te veranderen. Microcontrollercode De microcontroller kan geprogrammeerd worden in C of assembler. Er werd geopteerd voor C. Dit laat toe op een overzichtelijke wijze code te schrijven, zonder aan snelheid in te boeten. De firma Keil biedt de C51 optimaliserende compiler en bijhorende IDE µvision gratis ter evaluatie aan[2]. Deze evaluatieversie heeft enkele beperkingen, maar die zijn niet van belang voor dit project. Heel handig is de mogelijkheid tot uitvoeren van de code in een simulator. De ontwikkeltijd verkort hierdoor aanzienlijk. Voor het programmeren van de microcontroller is de Microcontroller Toolkit[6] van Dallas gebruikt. 3.2 Concept De grafische front-end dient in een aantal functionaliteiten te voorzien: het is een afstandsbediening waarmee het display bestuurd wordt. Daarnaast biedt het een makkelijke interface voor de gebruiker: beelden en projecten kunnen op schijf opgeslagen worden en doorgestuurd worden naar het display. Een grafische voorstelling van de beelden is te zien en configuratiegegevens kunnen onmiddelijk aangepast worden. In wat nu volgt wordt een hoogniveauvoorstelling gegeven van de interactie tussen PC en microcontroller. De PC stuurt (na input van de gebruiker) de microcontroller aan via zogenaamde acties. Mogelijke acties zijn: ˆ opslaan van beelden of projecten in het flashgeheugen; ˆ ophalen van beelden of projecten uit het flashgeheugen; ˆ laten afbeelden van een beeld. Deze acties zijn niet onafhankelijk: het opslaan of ophalen van een project komt neer op 16 keer een beeld opslaan of ophalen. We kunnen bijgevolg 3 basisacties bepalen: opslaan, ophalen en laten afbeelden van een beeld. De onderlinge afhankelijkheid van bovenstaande acties zal later handig zijn bij de implementatie in het controleprogramma.

21 Hoofdstuk 3. Software 12 Bij elke basisactie verloopt de communicatie tussen PC en microcontroller volgens een vast protocol. Figuur 3.1 toont een sequentiediagram. Eerst wordt een eenvoudige handshake uitgevoerd. De communicatie verloopt als volgt: 1. De PC stuurt een ASCII-karakter. Dit karakter bepaalt welke actie uitgevoerd wordt en is tevens het eerste bericht van de handshake. 2. De microcontroller antwoordt met een A. De ack geeft aan dat de controller klaar is om de actie uit te voeren en vervolledigt de handshake. 3. Afhankelijk van het soort actie worden nu een aantal parameters doorgestuurd en wordt de actie afgewerkt. Telkens zal de microcontroller een ack terugsturen. Als de PC na 5 seconden geen antwoord ontvangt van de microcontroller, treedt een time out op en wordt de actie afgebroken. In de volgende tabel zijn de basisacties, hun ASCII-karakter en hun bijhorende parameters samengevat. Actie ASCII-karakter Parameters Opslaan van een beeld S index (1 byte), datalengte (2 bytes) Ophalen van een beeld L index (1 byte) Afbeelden van een beeld D index (1 byte) Deze protocolstructuur leent zich uitstekend om geïmplementeerd te worden als communicerende toestandsmachines. Verder is het duidelijk dat op eenvoudige wijze acties kunnen toegevoegd worden Details van de basisacties Elke basisactie wordt hier uitvoerig beschreven en de toestandsmachines worden uitgewerkt. Een beeld opslaan in het flash Figuur 3.2 toont het sequentiediagram voor de communicatie. Een Store start de actie. Parameters zijn het beeldnummer (0 15) en de lengte van het beeld. Van dit 16 bits getal wordt de laagste byte eerst verstuurd. Na bevestiging verzendt de PC de beelddata in blokken van 128 bytes. De reden is dat het flashgeheugen beschreven moet worden in sectoren van 128 bytes. Het laatste blok kan echter minder data bevatten. Dit wordt dan door de microcontroller aangevuld met nullen tot een volledig blok alvorens het weggeschreven wordt.

22 Hoofdstuk 3. Software 13 PC µc <karakter> handshake A parameters actiespecifiek Figuur 3.1: Sequentiediagram van de communicatie bij uitvoering van een basisactie. De afgeleide toestandsmachines zijn te zien in figuur 3.3. De transities aan de PC-kant gebeuren na ontvangst van een A, de time out transities zijn niet te zien. Aan de zijde van microcontroller zijn de overgangen impliciet, i.e. na voltooiing van een bewerking. De eerste toestand START STORE UART is geen toestand van de weergegeven FSM, maar van een FSM in de hoofdlus van de microcontrollercode. Vanuit deze hoofd-fsm worden de andere opgeroepen. Meer uitleg volgt daarover in 3.5. Voor de eigenlijke implementatie van deze toestandsmachines wordt de lezer verwezen naar de delen over PC- en microcontrollercode. Een beeld ophalen uit het flash Het ophalen van een beeld is analoog (figuur 3.4). Als parameters wordt het beeldnummer en de lengte meegegeven. Omdat het volledige flashgeheugen sequentieel gelezen kan worden, stuurt de microcontroller alle beelddata onmiddellijk naar de PC. De tweede A zorgt er voor dat de PC in de juiste toestand komt. De toestandsmachines (figuur 3.5) zijn analoog aan het vorige geval en behoeven weinig verdere uitleg. Dezelfde opmerkingen blijven evenwel geldig. Een beeld afbeelden op het display Dit is de eenvoudigste basisactie. Het beeldnummer is de enige parameter. Sequentiediagram en toestandsmachines zijn te zien in figuur 3.6 en 3.7.

23 Hoofdstuk 3. Software 14 PC µc S A A <beeldnummer>, <lengte LSB>, <lengte MSB> <128 bytes blok> A < 128 bytes blok> A Figuur 3.2: Sequentiediagram van de communicatie bij opslaan PC-software De PC-software bestaat grosso modo uit 2 componenten: ˆ de object-geöriëntieerde wrapper-dll FT232RDevice die de functionaliteit van de FT232R driver inkapselt; ˆ de grafische front-end BDControl, die de acties implementeert en een gebruiksvriendelijke interface voor de gebruiker aanbiedt. De volgende secties beschrijven deze componenten. Verder uitleg is ook beschikbaar in de commentaar bij de code.

24 Hoofdstuk 3. Software 15 PC microcontroller INIT_STORE SEND_CONFIG START_STORE_UART AWAIT_CONFIG SEND_LAST_BLOCK SEND_BLOCK RECEIVE_LAST_BLOCK RECEIVE_BLOCK FINISH Figuur 3.3: Toestandsmachines voor de uitvoering van een opslaan actie. PC µc L A A <beeldnummer>, <lengte LSB>, <lengte MSB> <data> Figuur 3.4: Sequentiediagram van de communicatie bij ophalen van een beeld.

25 Hoofdstuk 3. Software 16 PC microcontroller INIT_LOAD SEND_CONFIG START_LOAD_UART AWAIT_CONFIG FINISH GET_DATA SEND Figuur 3.5: Toestandsmachines voor de uitvoering van een laad actie. PC µc D A <beeldnummer> A Figuur 3.6: Sequentiediagram van de communicatie bij afbeelden van een beeld.

26 Hoofdstuk 3. Software 17 PC microcontroller INIT_DISPLAY DISPLAY START_DISPLAY AWAIT_CONFIG FINISH DISPLAY Figuur 3.7: Toestandsmachines voor de uitvoering van een afbeeld actie.

27 Hoofdstuk 3. Software De wrapper FT232RDevice Deze C#-DLL kapselt de functies in die geëxporteerd worden door FTD2XX.DLL, de driver van de USB-chip onder Windows. Die driver is een typische Win32 driver en biedt geen objectgeöriëntieerde interface aan. Zoals gebruikelijk bij het programmeren onder het Win32-model, worden objecten (in een niet object-geöriëntieerde zin, zoals bestanden, vensters, mutexen) aangeduid met een handle die bij elke functieaanroep moet worden meegegeven. De klasse FT232RDevice kapselt zo een handle in. Een instantie van die klasse stelt dan de convertorchip FT232R voor, waarop methoden kunnen worden opgeroepen. Deze component is een pure C# klasse. Een gedeeltelijk klassendiagram is te zien in figuur 3.8. De ingekapselde handle is een private field van de klasse. IDisposable FT232RDevice Sealed Class Fields ev handle status Methods CloseDevice ClrDtr CyclePort Dispose GetDeviceDescriptors GetEventHandle GetNumberOfDevices GetQueueStatus OpenDevice (+ 1 overload) Purge ReadData ResetPort SetBaudRate SetChars SetDataCharacteristics SetDivisor SetDtr SetEventNotification WriteData Nested Types NativeMethods Static Class Methods FT_Close FT_ClrDtr FT_CreateDeviceInfoList FT_CyclePort FT_GetDeviceInfoList FT_GetQueueStatus FT_ListDevices (+ 1 overload) FT_Open FT_Purge FT_Read FT_ResetPort FT_SetBaudRate FT_SetChars FT_SetDataCharacteristics FT_SetDivisor FT_SetDtr FT_SetEventNotification FT_Write Figuur 3.8: Vereenvoudigd klassendiagram van de wrapper en de geneste klasse NativeMethods. FT232RDevice bevat een statische klasse NativeMethods die de DLL-functies van de driver importeert. Het is daarbij belangrijk dat hun argumenten correct worden gemarshald zodat

28 Hoofdstuk 3. Software 19 hun (Win32) types correct worden afgebeeld op C# types 2. Verder kent C# geen pointers 3, die worden echter heel courant gebruikt bij Win32 programmeren..net voorziet dan ook in een speciale namespace die interop services aanbiedt: System.Interop. Voorbeeld Een concreet voorbeeld van een geïmporteerde functie: een aantal bytes lezen uit de ontvangstbuffer van de chip. De declaratie van de functie FT Read in het C headerbestand van de driver is: FT_STATUS WINAPI FT_Read( ); FT_HANDLE fthandle, LPVOID lpbuffer, DWORD nbuffersize, LPDWORD lpdwbytesreturned De parameters: fthandle is een pointer naar de handle van een open device, lpbuffer een pointer naar een gealloceerde buffer waarin de data wordt geplaatst, nbuffersize de buffergrootte en pbytesreturned is een pointer naar een integer waarin het aantal effectief gelezen bytes teruggegeven wordt. Er worden dus 3 pointers en 1 integer meegegeven. De functie retourneert een FT STATUS, dit is een enumeratie met statuscodes. De corresponderende importdeclaratie in NativeMethods ziet er als volgt uit: [DllImport("FTD2XX.dll", EntryPoint = "FT_Read")] internal static extern uint FT_Read( ); IntPtr fthandle, byte[] lpbuffer, uint nbuffersize, out uint lpdwbytesreturned De DLL die de functie exporteert en het entrypoint worden bepaald door het attribuut DllImport, dat een aanroep in unmanaged code door de interop services aanduidt. sleutelwoord extern geeft aan dat de methode elders geïmplementeerd wordt (in casu in de driver). De complexiteit van het marshallen wordt in dit voorbeeld al duidelijk: de 3 pointers worden op 3 verschillende manieren meegegeven. Het Ten eerste wordt de structuur (struct) IntPtr voor de handle gebruikt. Deze is speciaal ontworpen om te gebruiken tussen talen 2 of correcter:.net CLR types 3 pointers zijn wel mogelijk in een zogenaamde unsafe context

29 Hoofdstuk 3. Software 20 die wel en geen pointers ondersteunen. De buffer is geïmplementeerd als een array, waarvan de naam eigenlijk een pointer is naar het eerste element. Het argument lpdwbytesreturned is een outputwaarde die door de aangeroepen functie wordt ingevuld; daarvoor is in C# een speciaal sleutelwoord out gedefinieerd. Dit heeft als effect dat een parameter by reference wordt doorgegeven, gelijkaardig aan een pointer. De integer nbuffersize kan als een gewone uint gemarshald worden. De klasse FT232RDevice moet nu enkel nog een methode aanbieden die deze import oproept. Dat is in dit geval de volgende methode: public byte[] ReadData(int numbytestoread) { uint bytesread; byte[] buffer = new byte[numbytestoread]; status = (FTStatus)NativeMethods.FT_Read(handle, buffer, (uint)numbytestoread, out bytesread ); if (status!= FTStatus.FT_OK) throw new IOException(status.ToString()); if (bytesread!= (uint)numbytestoread) throw new IOException("Unable to read all data from buffer"); } return buffer; De functie zal proberen numbytestoread bytes te lezen uit de chip en geeft deze terug als een byte-array. Nadat deze buffer gealloceerd is, wordt de geïmporteerde functie opgeroepen via NativeMethods. Als de oproep geslaagd is en er effectief numbytestoread bytes gelezen zijn, retourneert de functie de data. Bij fouten wordt een exceptie gegenereerd. Elke functie die door de driver FTD2XX.DLL geëxporteerd wordt, is op een analoge manier ingekapseld.

30 Hoofdstuk 3. Software 21 De statische functie GetDeviceDescriptors() geeft een lijst van DeviceDescriptors terug. Een descriptor bevat de beschrijving, het serienummer en het uniek device nummer (bepaald door Windows) van een chip. De functie OpenDevice opent een FT232RDevice door de gelijknamige functie in de native driver op te roepen en de handle als IntPtr te bewaren. Time out Zoals vermeld in 3.2 treedt er na 5 seconden een time out op als de PC geen antwoord krijgt van de microcontroller. Om dit te implementeren is gebruik gemaakt van het threadsynchronisatieprimitief semafoor of in Microsoft-jargon event. Dit is niet te verwarren met het gelijknamige gebeurtenismodel in.net. Uit de documentatie[5]: Event wait handles are not events in the sense usually meant by that word in the.net Framework. There are no delegates or event handlers involved. The word event is used to describe them because they have traditionally been referred to as operating-system events, and because the act of signaling the wait handle indicates to waiting threads that an event has occurred. Besturingssysteemevents worden in.net ingekapseld in de EventWaitHandle klasse. In een typisch scenario blokkeren een of meerdere threads op een EventWaitHandle totdat een andere thread de Set methode aanroept. Daarop zal één van de wachtende threads zijn uitvoering verderzetten 4. De acties worden asynchroon uitgevoerd door middel van een BackgroundWorker (zie 3.4.4) object. Deze klasse maakt het mogelijk om eenvoudig multithreaded programma s te maken. Naast deze workerthread, wordt de driver zelf ook op een thread uitgevoerd. Er kan een event aangemaakt worden dat gezet wordt wanneer er data ontvangen wordt. De workerthread zal blokkeren op dit event totdat de driverthread het event zet (signaled), of tot er een bepaalde tijd verlopen is. De klasse FT232RDevice bevat een EventWaitHandle object (zie figuur 3.8). De constructor bevat de volgende code: ev = new EventWaitHandle(false, EventResetMode.AutoReset, "FT232RXEvent"); Er wordt dus een EventWaitHandle object geïnstantieerd, dat niet gezet is, automatisch wordt gezet na vrijgave van een thread, en dat de naam FT232RXEvent draagt. Dit object bevat een property van het type SafeWaitHandle dat een handle is naar het onderliggende besturingssysteemevent. SafeWaitHandle is dus effectief een wrapper voor Win32 events. Andere code 4 Dit beschrijft automatic reset events. Voor meer informatie wordt de lezer verwezen naar elk goed.net boek.

31 Hoofdstuk 3. Software 22 kan dit object opvragen met de methode GetEventHandle. Om de driver het aangemaakte event de laten gebruiken wordt de driverfunctie FT SetEventNotification opgeroepen: status = (FTStatus)NativeMethods.FT_SetEventNotification( handle, FTEventMask.FT_EVENT_RXCHAR, ev.safewaithandle ); De driver zal het event dus zetten als er data ontvangen wordt. De time out kan eenvoudig gespecifieerd worden bij het blokkeren van een thread. Stel dat ev het event voorstelt, dan zal de thread die de volgende functie uitvoert blokkeren tot er een karakter ontvangen is of tot er 5 seconden verstreken zijn: ev.waitone(5000, false) Daarbij is de false enkel van belang in een synchronisatiecontext, die hier niet gebruikt wordt. De rest van de methodes komen rechtstreeks overeen met de geïmporteerde functies. Zij doen uiteraard sterk denken aan functies om een echte seriële poort aan te spreken. 3.4 De grafische front-end BDControl BDControl is een grafisch programma dat de gebruiker een interface aanbiedt voor het besturen van een bistabiel display. Het implementeert de acties vermeld in 3.2 en laat toe om georganiseerd om te gaan met beelden en projecten: ˆ beelden en projecten kunnen opgeslagen worden op schijf; ˆ beelden kunnen geïmporteerd worden uit een standaard ASCII-bestand; ˆ random grijswaardebeelden worden automatisch gegenereerd. De acties worden asynchroon, op een aparte thread, uitgevoerd om de gebruikersinterface niet te verstoren. Verder biedt het programma enkele handige features: een logboek, opslaan van gebruikersinstellingen (positie van de deelvensters, standaardbeeldconfiguratie,...),... Figuur 3.9 toont een screenshot van de applicatie. In de gebruikersinterface onderscheiden we naast het menu en de werkbalken meteen al een aantal vensters: de navigator links toont

32 Hoofdstuk 3. Software 23 Figuur 3.9: Screenshot van BDControl. het huidige project, met daarin de 16 (al dan niet lege) beelden. Onderaan is het logboek te zien in het outputvenster. Het middelste venster toont het huidig geselecteerde beeld en zijn configuratieparameters. Rechts is de uitbreiding voor vermogenmeting te zien. Alle mogelijk opdrachten zijn zowel als knop op de werkbalken, als ingang in het menu of als toetsenbordsnelkoppeling aanwezig. Uitbreidbaarheid Het programma is zo geschreven dat het eenvoudig uitbreidbaar is. Het object-geöriënteerde C# biedt daarvoor een krachtige basis, maar een intelligente opdeling van de functionaliteit is minstens even belangrijk. ˆ Acties: in is te lezen dat de acties als een klassenhiërarchie zijn geïmplementeerd: alle acties zijn afgeleid uit een abstracte basisklasse. Deze structuur volgt volledig de

33 Hoofdstuk 3. Software 24 afhankelijksrelaties tussen de acties, maar laat ook toe om eenvoudig acties toe te voegen zonder ingrijpende veranderingen. ˆ Fysisch communicatiekanaal: de communicatielogica is gelaagd. Een Communicator verwerkt abstracte hoogniveauopdrachten en gebruikt voor de eigenlijke communicatie een klasse die specifiek gericht is op een bepaald communicatiekanaal. In ons geval is dit FT232RDevice. Stel dat men wil communiceren over een ander medium (ethernet, draadloos, bluetooth,... ), dan hoeft enkel die specifieke klasse vervangen te worden. Opnieuw zijn er dan geen grote veranderingen. Het is zelfs mogelijk dit dynamisch te doen zodat de gebruiker zelf een keuze kan maken. ˆ Semi-automatische vermogenmeting: in het volgende hoofdstuk staat beschreven hoe het programma aangepast werd om vermogenmeting mogelijk te maken. Deze componenten worden in dit hoofdstuk dus niet meer vermeld. Interne Structuur Zoals bij elk niet-triviaal softwareproject geldt het verdeel-en-heers principe. De functionaliteit wordt verdeeld over een aantal delen, op het laagste niveau klassen, die interageren. De opsplitsing van de PC-software in de wrapper FT232RDevice en het programma BDControl is daar een eerste toepassing van. Een verdere iteratieve opsplitsing van BDControl levert de volgende blokken op (verzamelingen van klassen): ˆ klassen voor project- en beeldbeheer; ˆ de GUI-klassen die grafische interface voorstellen, input van de gebruiker krijgen en uitvoer weergeven; ˆ de klassen die de communicatie met de chip verzorgen; ˆ de klassen die de acties implementeren; ˆ een aantal hulpklassen. Deze logische structuur wordt in grote lijnen gereflecteerd in de gebruikte namespaces: BD.GUI, BD.Actions, BD.Util en BD.Components. Die laatste namespace bevat de communicatie-, project- en beeldklassen. In wat volgt worden deze blokken en hun inderlinge interactie besproken. Enkel de belangrijkste velden en methodes worden vermeld. Standaardmethodes zoals een ToString() overload zijn triviaal en worden achterwege gelaten, net zoals de meeste constructors. Het volledige klassendiagram, maar zonder de velden en methoden is te vinden in appendix A en toont een

34 Hoofdstuk 3. Software 25 overzicht van de applicatie. Dit biedt een aanknopingpunt voor een beter begrip van de tekst. Opmerking Hoewel we beelden definieerden met een vaste resolutie van pixels, zijn de sleutelroutines op enkele uitzonderingen na grootte-onafhankelijk gemaakt. Dit laat toe om met een minimum aan aanpassingen een ander display te gebruiken. Ook zijn alle velden privaat gedefinieerd. Via een gelijknamige property kunnen ze gecontroleerd benaderd worden Klassen voor project- en beeldbeheer Dit blok bevat de klassen die een beeld en project definiëren en een hulpklasse. Het klassendiagram is te zien in figuur ˆ BD.Components.BDImageProperties: deze klasse bevat de configuratiedata, naam en dimensies van het beeld. ˆ BD.Components.BDImage: deze klasse stelt een beeld zoals gedefinieerd in 1.4 voor. De property RawData is een byte matrix die de eigenlijke beelddata voorstelt. ImageProperties bevat de eigenschapppen van het beeld. BitmapImage is een getter die het beeld converteert naar een GDI+ Bitmap. Deze bitmap kan gemakkelijk afgebeeld worden in een venster. De methode GetByteStream genereert de bytestream die in het flashgeheugen wordt opgeslagen uit de beelddata en de configuratiegegevens. Verder is een overload van de aftrekoperator gedefinieerd die twee instanties van BDImage vergelijkt en het verschilbeeld teruggeeft. Dit is handig om te controleren of een beeld correct weggeschreven werd in het flashgeheugen. De standaardconstructor zal een beeld aanmaken van pixels, maar er is ook een overload aanwezig die arbitraire dimensies accepteert. De statisch methode ImportFromTextFile() maakt een BDImage-object aan door een ASCII-bestand te interpreteren als beeldbestand (zie verder). Hiermee kunnen dus gemakkelijk testbeelden aanmaakt worden. ˆ BD.Components.BDProject: een project bestaat uit 16 beelden, die hier in een array zijn opgeslagen. De properties Path en Name spreken voor zich. ˆ BD.Components.BDProjectManager: deze klasse neemt het beheer van projecten en beelden op zich. Er zijn methoden aanwezig om beelden en project op te slaan of op te halen uit het flash (StoreImage(), StoreProject(), LoadImage() en LoadProject)

35 Hoofdstuk 3. Software 26 BDImageProperties Class Fields CRDuringLineScan : bool CRDuringReset : bool Dimensions : Size LinetimeHigh : byte LinetimeLow : byte Name : string Methods BDImageProperties() ToString() : string BDImage Class Fields props : BDImageProperties rawdata : byte[][] Properties BitmapImage { get; } : Bitmap ImageProperties { get; set; } : BDImageProperties RawData { get; set; } : byte[][] Methods BDImage() BDImage(byte[][] rawgrayscaledata, BDImageProperties props) BDImage(int width, int height) GetByteStream() : byte[] ImportFromTextFile(string filename) : BDImage operator -(BDImage i1, BDImage i2) : BDImage ToString() : string (a) Figuur 3.10: De klassen voor project- en beeldbeheer.

36 Hoofdstuk 3. Software 27 BDProject Sealed Class Fields bdimages : BDImage[] name : string path : string Properties BdImages { get; set; } : BDImage[] FileName { get; set; } : string Name { get; set; } : string Methods BDProject(string name) BDProjectManager Class Fields comm : Communicator displayaction : DisplayAction index : int ivc : BDImageViewController loadaction : LoadAction loadprojectaction : LoadProjectAction storeaction : StoreAction storeprojectaction : StoreProjectAction Methods BDProjectManager(Communicator c, BDImageViewController ivc) comm_actioncompleted(object sender, ActionCompletedEventArgs e) : void DisplayImage(int index) : void LoadImage(int index) : void LoadProject(out BDProject project) : void OpenProject(string path) : BDProject SaveProject(BDProject project) : void StoreImage(BDImage image, int index) : void StoreProject(BDProject project) : void (b) Figuur 3.10: De klassen voor project- en beeldbeheer (vervolg).

37 Hoofdstuk 3. Software 28 en om een beeld af te beelden op het display (DisplayImage()). Al deze methoden roepen hun corresponderende acties op die het eigenlijke werk uitvoeren. Een project kan geopend of opgeslagen worden met OpenProject() en SaveProject(). Dat wordt (de)serializeren genoemd. Formeel betekent dit het converteren van een object in een bytestroom die persistent kan opgeslagen worden (en omgekeerd). Die bytestroom bevat naast de eigenlijke data ook metadata over het type van het object. De klassen BDImage, BDImageProperties en BDProject zijn geannoteerd met het attribuut 5 Serializable. Op die manier kan het standaard serializatiemechanisme van C# gebruikt worden: een formatter zal een serializeerbaar object in een stroom met een bepaald formaat converteren en omgekeerd. Een formatter moet de interface IFormatter implementeren. Het formaat kan bijvoorbeeld een XML-bestand of een binair bestand zijn. Een voorbeeld maakt dit duidelijk: public BDProject OpenProject(string path) { BDProject bdproject = null; Stream sw = File.OpenRead(path); IFormatter formatter = new BinaryFormatter(); bdproject = (BDProject)formatter.Deserialize(sw); sw.close(); return bdproject; } Het opgegeven binair bestand wordt eerst als een stroom geopend. Dan zal de BinaryFormatter het bestand deserializeren en een object van het type BDProject aanmaken en teruggeven, waarna de stroom wordt gesloten. De code voor SaveProject() is even eenvoudig. Formaat ASCII-bestand Om een tekstbestand op een correcte manier te interpreteren als beeldbestand moeten dit een specifieke vorm hebben. Grijswaardepixels worden voorgesteld door de hexadecimale getallen 00 tot FF. Een beeld heeft dus 16 rijen en 32 kolommen. Het niet mogelijk om configuratiedata te definiëren GUI-klassen Deze klassen bepalen het uiterlijk van de applicatie. Ze bestaan meestal uit twee bestanden: Klasse.cs en Klasse.Designer.cs. Hierbij wordt gebruik gemaakt van de nieuwe partiële 5 Een attribuut associeert bepaalde informatie met een element (klasse, enum, delegate,... )

38 Hoofdstuk 3. Software 29 klassen in C# 2: de definitie en implementatie van een partial class kan verspreid worden over meerdere bestanden. De Visual Studio 2005 IDE gebruikt dit idee om de automatisch gegenereerde code van de Designer waarbij vensters via drag and drop visueel opgebouwd worden te verbergen voor de programmeur. Een verdere toepassing van het verdeel-en-heers principe leidt ook tot een opdeling van de UI. Het hoofdvenster bevat een tweetal componenten die de interface vormen naar een beeld of project. Daarvoor werden klassen ontworpen die afgeleid zijn van System.Windows.Forms.UserControl, in essentie een container voor andere controls. Een van UserControl afgeleide control kan visueel opgebouwd worden in Visual Studio en erft een aantal standaardproperties en -events over zoals BackGroundColor of OnDoubleClick(). ˆ BD.GUI.MainForm: het hoofdvenster van BDControl wordt voorgesteld door MainForm. Deze klasse bevat geen business logic. Haar enige taak is het ontvangen van gebruikersinvoer en het weergeven van resultaten. Alle functionaliteit wordt door andere klassen geïmplementeerd. De meeste methodes zijn rechtoe-rechtaan event handlers die weinig uitleg vergen. Figuur 3.11 toont een sterk vereenvoudigd klassediagram. Daarin zijn enkel de belangrijke velden te zien die door de glue logic met elkaar in interactie staan. MainForm Class Form Fields bdimageviewcontroller : BDImageViewController bdnavigator : BDNavigator bdproject : BDProject bdprojectmanager : BDProjectManager comm : Communicator serialport : SerialPort WordwrapButton : ToolStripButton Figuur 3.11: De sterk vereenvoudigde MainForm-klasse. ˆ BD.GUI.BDNavigator (figuur 3.12): deze component biedt een visuele interface voor een BDProject. Het bevat daarvoor een TreeView, een aloud Windows control dat data in een boom weergeeft. Een ingang in de boom wordt een knoop genoemd. De properties SelectedImage en SelectedImageIndex geven respectievelijk het huidig geselecteerde beeld en beeldnummer terug. De private methode CreateTree() bouwt de boom.

39 Hoofdstuk 3. Software 30 UpdateDisplay() geeft de knopen een bepaalde kleur naargelang het beeld leeg is of niet. Om het hoofdvenster te laten weten dat de gebruiker een knoop geselecteerd heeft, stelt de navigator een event (nu wél in de.net betekenis, cfr. 3.3) beschikbaar: public event EventHandler<ImageSelectedEventArgs> ImageSelected; In het.net event model verbindt een event delegate een event met de methode die erop reageert. Om een event op te roepen, zijn twee elementen noodzakelijk: 1. Een klasse die event-specifieke data (toestand) bevat. Die is afgeleid van EventArgs. 2. Een delegate die naar een methode (de event handler) wijst die reageert op het event. Dit is hier EventHandler<ImageSelectedEventArgs>. BDNavigator Class UserControl Fields bdproject : BDProject parent : TreeNode tree : TreeView Properties BdProject { get; set; } : BDProject SelectedImage { get; } : BDImage SelectedImageIndex { get; } : int Methods Events BDNavigator() CreateTree() : void RefreshTree() : void UpdateDisplay() : void ImageSelected : EventHandler<ImageSelectedEventArgs> Figuur 3.12: De BDNavigator-component en een screenshot. In dit geval is de toestand het nieuwe geselecteerde beeld: public class ImageSelectedEventArgs : EventArgs { public BDImage SelectedBdImage; public ImageSelectedEventArgs(BDImage image) { SelectedBdImage = image; } } De event handler moet dezelfde parameters hebben als de delegate. De klasse EventHandler<TEventArgs

40 Hoofdstuk 3. Software 31 is als volgt gedefinieerd, waarbij het generieke 6 type argument het type is van de data gegenereerd door het event: public delegate void EventHandler<TEventArgs> ( Object sender, TEventArgs e ) where TEventArgs : EventArgs De where-clausule zegt dat TEventArgs minstens van het type EventArgs moet zijn. Afgeleide klassen voldoen uiteraard aan deze eis. Uit dit alles volgt dat de event handler die reageert op dit event, als volgt gedefinieerd is in MainForm: void bdnavigator_imageselected(object sender, ImageSelectedEventArgs e) { /* knip */ } Deze handler wordt aan het event gekoppeld door: bdnavigator.imageselected += new EventHandler<ImageSelectedEventArgs>(bdNavigator_ImageSelected); ˆ BD.GUI.BDImageViewController: voor het visualiseren van een beeld is ook een aparte component ontwikkeld. Daarbij is een vereenvoudigde versie van het Model-View- Controller (MVC) patroon gebruikt. Dat is een architecturaal softwarepatroon waarbij data (het model) en gebruikersinterface (view) gescheiden worden. De interactie tussen de twee wordt dan door een controller geregeld. Omdat deze applicatie niet extreem complex is, zijn de view en controller samengenomen in de component BDImageViewController. Het datamodel is dan BDImage. Figuur 3.13 toont de klasse, figuur 3.14 een afbeelding. Opnieuw zijn de triviale velden en methodes achterwege gelaten. Er zijn twee properties van het type BDImage: LocalBDImage is het beeld dat op de PC wordt getoond, los van het bistabiel display. RemoteBDImage kan ingevuld worden met een beeld dat terug opgehaald is uit het flash. Door de DisplayMode op een gepaste waarde te zetten, wordt of het lokale beeld, of het opgehaalde beeld, of het 6 Generics is C# 2.0 zijn te vergelijken met templates in C++ of generics in Java.

41 Hoofdstuk 3. Software 32 verschilbeeld getoond. Dit is handig om te controleren als een beeld juist is weggeschreven. Een volledig zwart verschilbeeld is correct. De geneste enum DisplayModeType definieert deze drie toestanden. De huidige toestand wordt weergeven in het venster. BDImageViewController Class UserControl Fields displaymode : DisplayModeType localbdimage : BDImage remotebdimage : BDImage Properties DisplayMode { get; set; } : DisplayModeType LocalBDImage { get; set; } : BDImage RemoteBDImage { get; set; } : BDImage Methods Events BDImageViewController(Communicator c) UpdateDisplay() : void NameChanged : EventHandler<EventArgs> Nested Types DisplayModeType Enum Local Remote Difference Figuur 3.13: De vereenvoudigde klasse BDImageViewController. De interface bevat links het beeld en rechts de configuratiedata. Stel dat de gebruiker de hoge lijntijd verandert, dan zal de bijhorende UpDown control zijn event ValueChanged oproepen. De component past dan de eigenschappen van het lokale BDImage aan: private void LinetimeHighUpDown_ValueChanged(object sender, EventArgs e) { localbdimage.imageproperties.linetimehigh = (byte)linetimehighupdown. Value; } Op die manier wordt het model vanuit de viewcontroller bijgewerkt. De andere event

42 Hoofdstuk 3. Software 33 handlers zijn analoog. Het event NameChanged wordt opgeroepen wanneer de gebruiker de naam van het beeld verandert. Het hoofdvenster reageert hierop en roept de RefreshTree() methode op van de navigator zodat die op zijn beurt de naam kan aanpassen. In figuur 3.14 zijn ook twee knoppen te zien: Save as default slaat de huidige configuratiedata als standaardwaarde op en Reset laadt de opgeslagen standaardwaarden. Figuur 3.14: Een screenshot van de BDImageViewController. ˆ BD.GUI.HeaderLabel: voor de blauwe titelbalkjes (voorbeeld in figuur 3.15) in de deelvensters is gebruik gemaakt van een afgeleide klasse van het tekstlabel System.Windows.Forms.Label: public class HeaderLabel : Label { public HeaderLabel() { this.height = 18; this.autosize = false; this.backcolor = Color.LightSteelBlue; }

43 Hoofdstuk 3. Software 34 protected override void OnPaint(PaintEventArgs pe) { // basisklasse OnPaint base.onpaint(pe); } } ControlPaint.DrawBorder(pe.Graphics, this.bounds, Color.SteelBlue, ButtonBorderStyle.Solid); Figuur 3.15: Voorbeeld van een titelbalkje. De code in de constructor zorgt voor een vaste hoogte en lichtblauwe achtergrond. Voor het donkerblauwe kader werd de OnPaint-handler herdefinieerd. De.NET klasse ControlPaint werd speciaal voor dit soort zaken ontwikkeld. Een eenvoudige oproep van DrawBorder() neemt het vuile werk voor zijn rekening. ˆ BD.GUI.AboutBox: bij een druk op het menu Help About komt een informatievenster te voorschijn dat door AboutBox wordt voorgesteld Actieklassen Om de verwerking van de acties algemeen aan te pakken en doordat ze onderling afhankelijk zijn, zijn de klassen die de basisacties implementeren afgeleid van een abstracte basisklasse Action. De afhankelijke acties zijn op hun beurt afgeleid van de basisacties. Die klassenhiërarchie is getoond in figuur De abstracte basisklasse BD.Actions.Action bevat alle velden, properties en methoden die de acties gemeen hebben. De betekenis van de abstracte get properties Description en Name spreekt voor zich; zij moeten door de afgeleide klassen ingevuld worden. De virtuele methode DoAction() wordt ook in de kindklassen geïmplementeerd. Zij bevat de eigenlijke implementatie van de acties en gebruikt de Communicator (zie 3.4.4) voor het zenden en ontvangen van data. Een boolese retourwaarde geeft het al dan niet slagen van de uitvoering aan.

44 Hoofdstuk 3. Software 35 A ction Abstract Class Fields comm : Communicator Properties Description { get; } : string Name { get; } : string Methods Action(Communicator c) DoAction() : bool DisplayAction Class Action Fields _imageindex : int Properties Description { get; } : string ImageIndex { get; set; } : int Name { get; } : string Methods DisplayAction(Communicator c) DoAction() : bool Nested Types LoadAction Class Action Fields image : BDImage index : int Properties Description { get; } : string Image { get; } : BDImage Index { get; set; } : int Name { get; } : string Methods DoAction() : bool LoadAction(Communicator c) Nested Types StoreAction Class Action Fields image : BDImage index : int Properties Description { get; } : string Image { get; set; } : BDImage Index { get; set; } : int Name { get; } : string Methods DoAction() : bool StoreAction(Communicator c) StoreAction(Communicator c, BDImage image) Nested Types LoadProjectAction Class LoadAction StoreProjectAction Class StoreAction Fields bdproject : BDProject Properties BdProject { get; set; } : BDProject Description { get; } : string Name { get; } : string Methods DoAction() : bool LoadProjectAction(Communicator c) LoadProjectAction(Communicator c, BDProject bdproject) Fields bdproject : BDProject Properties BdProject { get; set; } : BDProject Description { get; } : string Name { get; } : string Methods DoAction() : bool StoreProjectAction(Communicator c) StoreProjectAction(Communicator c, BDProjec Figuur 3.16: De hiërarchische structuur van de actieklassen.

45 Hoofdstuk 3. Software 36 Als voorbeeld wordt de tak StoreAction StoreProjectAction gegeven. De andere acties DisplayAction, LoadAction en LoadProjectAction zijn analoog geïmplementeerd. StoreAction zal een beeld sturen naar het aanstuurbord. Via de microcontroller wordt het dan in het flashgeheugen geschreven. Het beeld kan meegegeven worden bij de constructie van de klasse of nadien via de property Image. Index is het beeldnummer (0 15). Het actieprotocol leent zich uitstekend om als communicerende toestandsmachines (FSMs) geïmplementeerd te worden: zowel in de PC als in de microcontroller. Voor een grafische voorstelling wordt de lezer opnieuw verwezen naar Voor de FSM aan de PC kant is in StoreAction een genest type gedefinieerd dat de toestanden bepaalt: private enum StoreStates { INIT_STORE, SEND_CONFIG, SEND_BLOCK, SEND_LAST_BLOCK, FINISH }; De FSM zelf komt dan in de override van DoAction(). De volgende code is ontdaan van alle overbodige loginstructies. Nuttige uitleg is genoteerd in commentaar: public override bool DoAction() { byte[] data = image.getbytestream(); byte[] buffer = new byte[128]; bool done = false; bool result = false; uint curwholeblock = 0; // bepaal het aantal blokken van 128 bytes en alloceer een buffer // voor het laatste (eventueel) onvolledige blok uint numwholeblocks = (uint)data.length >> 7; // delen door 128 uint lengthoflastblock = (uint)data.length - (numwholeblocks << 7); byte[] bufferlastblock = new byte[lengthoflastblock]; StoreStates state = StoreStates.INIT_STORE; while (!done) { switch (state) { case StoreStates.INIT_STORE:

46 Hoofdstuk 3. Software 37 // ledig de zend- en ontvangbuffers in de driver comm.purge(); // commando S comm.writechar( S ); // wacht op een ACK en ga naar de volgende toestand if (comm.waitforack()) state = StoreStates.SEND_CONFIG; else done = true; break; case StoreStates.SEND_CONFIG: // verstuur het beeldnummer en de datalengte (2 bytes) comm.writebyte((byte)index); byte lo = (byte)data.length; byte hi = (byte)(data.length >> 8); comm.writebytes(new byte[] { lo, hi }); if (comm.waitforack()) state = StoreStates.SEND_BLOCK; else done = true; break; case StoreStates.SEND_BLOCK: // verstuur het huidig blok van 128 bytes if (curwholeblock == numwholeblocks) { state = StoreStates.SEND_LAST_BLOCK; break; } Array.Copy(data, 128 * curwholeblock, buffer, 0, 128); comm.writebytes(buffer);

47 Hoofdstuk 3. Software 38 if (!comm.waitforack()) done = true; curwholeblock++; break; case StoreStates.SEND_LAST_BLOCK: // verstuur het laatste (eventueel onvolledige) blok Array.Copy(data, 128 * curwholeblock, bufferlastblock, 0, lengthoflastblock); comm.writebytes(bufferlastblock); } if (comm.waitforack()) state = StoreStates.FINISH; else done = true; break; case StoreStates.FINISH: // als we hier geraken is de uitvoering geslaagd done = true; result = true; break; } } return result; De klasse StoreProjectAction zorgt voor het opslaan van een volledig project in het flashgeheugen. Ze is afgeleid van StoreAction. De property BdProject bepaalt het op te slaan project. De nieuwe override van DoAction() ziet er als volgt uit: public override bool DoAction() { for (int i = 0; i < 16; i++) { this.image = bdproject.bdimages[i];

48 Hoofdstuk 3. Software 39 } if (this.image!= null) { if (!base.doaction()) return false; } } return true; Ieder niet-ledig beeld wordt verwerkt door DoAction() van de basisklasse StoreAction op te roepen. De andere acties DisplayAction, LoadAction en LoadProjectAction zijn op analoge manier geïmplementeerd: een geneste enum bepaalt de toestanden en een override van DoAction() voert de actie in de vorm van een FSM uit Communicatieklassen De communicatie met de FT232R chip verloopt gelaagd (figuur 3.17). Een Communicator verwerkt abstracte communicatieopdrachten. De concrete communicatie gebeurt dan over een specifiek kanaal dat zijn eigen aansturing heeft. Het USB-kanaal dat hier gebruikt wordt, is ook gelaagd. Op het laagste niveau worden golfvormen, die bits voorstellen, op een draad geplaatst (fysisch kanaal). Het USB-protocol bepaalt de volgorde en betekenis van die bits. Onder Windows wordt de USB-stack aangestuurd door de chipdriver van FTDI FTD2XX.DLL. Zoals beschreven in 3.3 kapselt FT232RDevice die driver in in een C# klasse. De Communicator gebruikt deze klasse voor het concretiseren van de communicatie. Dit gelaagd model maakt het mogelijk om andere kanalen te gebruiken zonder veel te veranderen. ˆ FT232RWrapper.FT232RDevice: deze klasse in de vorm van een DLL werd al uitvoering besproken in 3.3, maar wordt hier voor de volledigheid vermeld.

49 Hoofdstuk 3. Software 40 Communicator abstracte communicatie Wrapper (FT232RDevice.dll) Win32 driver (FTD2XX.dll) USB-protocol (USB-stack) concrete communicatie Fysisch kanaal Figuur 3.17: Het gelaagde communicatiemodel. Communicator Class Fields _action : Action device : FT232RDevice devicedescriptor : FT232RDeviceDescriptor devices : List<FT232RDeviceDescriptor> ev : EventWaitHandle worker : BackgroundWorker Properties Action { get; set; } : Action Device { set; } : FT232RDeviceDescriptor Methods Events CloseDevice() : void Communicator() GetDevices() : List<FT232RDeviceDescriptor> InvokeAction() : void OpenDevice() : void Purge() : void ReadBytes(int length) : byte[] Rescan() : void WaitForAck() : bool worker_dowork(object sender, DoWorkEventArgs e) : void worker_runworkercompleted(object sender, RunWorkerCompletedEventArgs e) : void WriteByte(byte b) : void WriteBytes(byte[] b) : void WriteChar(char c) : void ActionCompleted : EventHandler<ActionCompletedEventArgs> Figuur 3.18: De klasse Communicator. ˆ BD.Components.Communicator: figuur 3.18 toont deze klasse. Via GetDevices() krijgt

50 Hoofdstuk 3. Software 41 men een lijst van beschikbare devices terug, in de vorm van FT232RDeviceDescriptors. Rescan() ververst die lijst door rechtstreeks FT232RDevice.GetDeviceDescriptors(), zie 3.3, op te roepen. Een exemplaar van die lijst kan in de property Device geplaatst worden, de communicator werkt dan met dat apparaat. De methoden OpenDevice(), CloseDevice(), Purge() en ReadBytes() roepen rechtstreeks de gelijknamige methodes van FT232RDevice aan. Voor het schrijven van data zijn drie methodes voorzien: WriteByte(), WriteBytes() en WriteChar(). Die roepen alle het onderliggende WriteData() op. WaitForAck() geeft true terug als binnen 5 seconden een Ack ontvangen wordt. Deze methode krijgt uiteraard veel toepassing bij de uitvoering van de acties. De implementatie is gebaseerd op het event notificatie mechanisme beschreven in 3.3. Asynchrone uitvoering van de acties Hierboven is reeds vermeld dat acties worden uitgevoerd op een aparte thread. Daar wordt nu wat dieper op in gegaan. De rationale die schuilt achter deze aanpak is de volgende: tijdrovende operaties zoals het downloaden van een bestand, database transacties of I/O kunnen ervoor zorgen dat een programma schijnbaar hangt. De gebruikersinterface reageert niet meer op invoer omdat de thread bezig met uitvoering van de operatie. Daarom worden dergelijke operaties op een aparte thread uitgevoerd. Het.NET raamwerk biedt een eenvoudig middel om in deze functionaliteit te voorzien: de BackgroundWorker. Een tijdrovende operatie wordt opgeroepen in de event handler van het event DoWork. De uitvoering wordt gestart door een oproep naar RunWorkerAsync(), die op zijn het event oproept. Er moet uiteraard voor gezorgd worden dat geen interface-elementen worden aangesproken in deze operaties. Onze tijdrovende operatie is uiteraard de uitvoering van een actie. Hier wordt het voordeel van klassenhiërarchie van de acties duidelijk: onze communicator werkt met de abstracte basisklasse Action. Haar virtuele DoAction() moet op een aparte thread uitgevoerd worden. Wanneer de uitvoering beëindigd is, roept de BackGroundWorker zijn event RunWorkerCompleted op. Daarin roept de communicator op zijn beurt zijn eigen event ActionCompleted op. In code: private BackgroundWorker worker;

51 Hoofdstuk 3. Software 42 // dit wordt opgeroepen als de actie uitgevoerd is public event EventHandler<ActionCompletedEventArgs> ActionCompleted; public Communicator() { worker = new BackgroundWorker(); worker.runworkercompleted += new RunWorkerCompletedEventHandler( worker_runworkercompleted); worker.dowork += new DoWorkEventHandler(worker_DoWork); } De event handlers worden opnieuw via delegates gekoppeld aan de events zelf. worker DoWork() voert de actie uit: private void worker_dowork(object sender, DoWorkEventArgs e) { // knip OpenDevice(); // knip // actie uitvoeren en resultaat inkapselen e.result = _action.doaction()? ActionResult.SUCCEEDED : ActionResult. FAILED; // indien de actie werd geannuleerd, vul het resultaat zo in if (worker.cancellationpending) { e.cancel = true; e.result = ActionResult.CANCELLED; } } CloseDevice(); In e.result wordt de status opgeslagen, een waarde uit ActionResult: public enum ActionResult {

52 Hoofdstuk 3. Software 43 } SUCCEEDED, FAILED, CANCELLED De status e wordt dan door de BackGroundWorker verder gebruikt om op het einde van de uitvoering de RunWorkerCompleted event handler op te roepen: oid worker_runworkercompleted(object sender, RunWorkerCompletedEventArgs e) { ActionCompletedEventArgs args = new ActionCompletedEventArgs(); // referentie naar de opgeroepen actie args.action = _action; if (e.cancelled) { args.result = ActionResult.CANCELLED; } else if (e.error!= null) { args.result = ActionResult.FAILED; } else { args.result = ActionResult.SUCCEEDED; } } // eigen event (van de Communicator zelf) oproepen if (ActionCompleted!= null) ActionCompleted(this, args); Hier wordt het argument van het eigen event ActionCompleted aangemaakt en met de juiste waarden ingevuld. Dan wordt het event opgeroepen.

53 Hoofdstuk 3. Software Hulpklassen De klasse Log Om het debuggen eenvoudiger te maken, of om de interne werking te observeren, is de programmacode doorspekt met loginstructies. Daarvoor is gebruik gemaakt van het uitstekende framework log4net[3]. Dit pakket maakt het mogelijk om informatie in de vorm van LoggingEvents op een gecontroleerde en gestructuurde wijze naar een bepaalde output, de Appender, te sturen. Voorbeelden zijn de ConsoleAppender, die boodschappen naar een consolevenster stuurt, of de FileAppender, die naar een bestand schrijft. De mogelijkheid bestaat om zelf eigen appenders te ontwikkelen. De boodschap wordt geformatteerd volgens een bepaalde layout. Het gedrag van de software kan tijdens uitvoering gewijzigd worden door middel van XML-configuratiebestanden. Ook bestaan er verschillende logmethodes naargelang de ernst van de boodschap, zoals Debug(), Info(), Error(),... De appenders kunnen zó geconfigureerd worden, dat ze enkel die boodschappen die ernstig genoeg zijn, gaan verwerken. De Threshold regelt dit. In BDControl is een eigen klasse Log aanwezig (zie figuur 3.19). Omdat deze statisch is, kunnen haar methodes eenvoudig worden opgeroepen vanuit elke andere klasse, zonder daar een instantie aan te maken. Deze klasse zorgt er voor dat iedere boodschap wordt uitgeschreven naar het logvenster van de applicatie. Daartoe moet de property Box naar een instantie van een TextBox wijzen. Het private veld log is de eigenlijk logger. Die wordt niet direct geïnstantieerd, maar teruggegeven door de klasse LogManager van log4net: private static readonly ILog log = LogManager.GetLogger(typeof(Log)); Het argument typeof(log) is de naam van de logger. De methoden Debug(), Warn() Error(), Fatal() en Info() roepen de gelijknamige methoden op van log. Bijvoorbeeld: public static void Fatal(object o) { log.fatal(o); updatebox(); } De aanroep van updatebox zal de boodschap uitschrijven naar het logvenster. Daar wordt straks op terug gekomen. Boodschappen worden in een geheugenbuffer opgeslagen door een MemoryAppender. Een PatternLayout neemt het formatteren voor zijn rekening. Deze klasse zal op basis van een patroon een LoggingEvent converteren in een string. Dat is in dit geval:

54 Hoofdstuk 3. Software 45 Log Static Class Fields box : TextBox layout : PatternLayout log : ILog MemAppender : MemoryAppender Properties Methods Box { get; set; } : TextBox Clear() : void CreateLoggers() : void Debug(object o) : void Error(object o) : void Fatal(object o) : void Info(object o) : void RenderLoggingEvent(LoggingEvent loggingevent) : string updatebox() : void Warn(object o) : void Nested Types Figuur 3.19: De statische hulpklasse Log. layout = new PatternLayout(); layout.conversionpattern = " %date{hh:mm:ss} %-5level - %message"; Het statement Log.Info("Found 1 FT232 USB device(s)"); resulteert dan in de volgende boodschap: 14:50:50 INFO - Found 1 FT232 USB device(s). De functie updatebox() schrijft de geheugenbuffer naar een TextBox control. Omdat controls in Windows Forms, de UI laag van.net, gebonden zijn aan een bepaalde thread, moeten voorzorgen genomen worden in ons multithreaded programma. Er geldt dat een thread een control mag benaderen, enkel en alleen als die thread de control heeft aangemaakt. Men zegt dat die thread de control bezit. Wanneer updatebox() opgeroepen wordt, zijn er dus twee gevallen. Stel dat van de threads T 1 en T 2, T 1 de TextBox heeft aangemaakt. 1. T 1 logt een boodschap: er is geen probleem; de TextBox wordt door T 1 aangepast; 2. T 2 logt een boodschap: het updaten van de TextBox wordt uitbesteed aan T 1. In het tweede geval wordt de methode Invoke(textCallBack) van de TextBox opgeroepen. Het argument textcallback is een zg. delegate, objecten die veel gelijkenissen vertonen met

55 Hoofdstuk 3. Software 46 functiepointers in C of C++. Invoke() zorgt er voor dat die delegate dan op de T 1 wordt uitgevoerd. Als we als delegate dezelfde functie updatebox() opgeven, krijgen we de volgende compacte code: delegate void SetTextCallback(); private static SetTextCallback textcallback = new SetTextCallback(updateBox); private static void updatebox() { if (box == null) return; } if (box.invokerequired) { box.invoke(textcallback); } else { LoggingEvent[] events = MemAppender.GetEvents(); box.appendtext(renderloggingevent(events[events.length - 1]) + Environment. NewLine); box.selectionstart = box.text.length; box.scrolltocaret(); } InvokeRequired geeft false terug als de aanroepende thread de control bezit. Het laatste event wordt dan geformatteerd door middel van de functie RenderLoggingEvent() en wordt als laatste lijn toegevoegd aan de TextBox. De klasse Program Deze klasse bevat het entry point van de applicatie: de Main() functie. Daarin wordt de logger aangemaakt en het hoofdvenster getoond. 3.5 Microcontrollercode De microcontroller heeft als taak de basisacties af te handelen: 1. beelden ontvangen van de PC en in het flashgeheugen schrijven;

56 Hoofdstuk 3. Software beelden uit het flashgeheugen halen en terugsturen naar de PC; 3. beelden uit het flashgeheugen halen en naar de FPGA sturen. Deze drie bewerkingen zijn zoals beschreven in als FSM s geïmplementeerd. De communicatie verloopt via de eerste seriële poort (UART0). Door die geïntegreerde logica moet niet op bitniveau gewerkt worden, maar moeten enkel de operatiemode en baudrate ingesteld worden. Eenzelfde special-function register (SFR), SBUF0 wordt beschreven of gelezen om resp. te verzenden of te ontvangen. We werken in mode 1, dit is standaard full-duplex asynchrone communicatie. Per byte worden er 10 bits verstuurd: 1 startbits, 8 databits en 1 stopbit. In deze mode is de baudrate een functie van een timer overflow. Daardoor is de baudrate programmeerbaar. Hier wordt timer 1 gebruikt als baudrategenerator. Door hem in autoreload mode te plaatsen, zal hij bij een overloop (FFh) een klokpuls zenden naar het baudrate circuit en opnieuw vanaf zijn startwaarde beginnen tellen. Een gepaste startwaarde laat toe de baudrate bijna willekeurig te bepalen. Ze wordt in het register TH1 geplaatst en wordt berekend via de volgende formule[13]: TH1 = 256 2SMODx f clk 384 baudrate SMOD x geeft aan of de baudrate verdubbeld moet worden of niet. De initialisatiecode van UART0 void InitUARTTimer1(const word BAUD RATE) heeft als parameter de baudrate. Er kunnen dus eenvoudig andere snelheden getest worden. De rest van de code is standaard en vergt weinig uitleg. Ze kan opgezocht worden op de meegeleverde cdrom. Wanneer er een reset optreedt, springt de microcontroller naar de main() functie: SuperSystemState superstate; void main(void) { /* watchdog timer uitschakelen */ TA = 0xAA; TA = 0x55; EWT = 0; /* init UART0, baudrate 9600, met Timer 1 */ InitUARTTimer1(9600);

57 Hoofdstuk 3. Software 48 /* globale interrupts toelaten */ EA = 1; /* superstate wordt gezet in de UART0 ISR */ superstate = IDLE; while (1) { switch (superstate){ case IDLE: /* idle mode: energie sparen */ PCON = 0x01; break; case START_STORE_UART: ES0 = 0; /* seriële interrupts uitschakelen */ TI = 1; /* verzenden mogelijk maken */ StoreToFlash(); ES0 = 1; /* seriële interrupts inschakelen */ superstate = IDLE; break; case START_GET_UART: ES0 = 0; /* seriële interrupts uitschakelen */ TI = 1; /* verzenden mogelijk maken */ SendToUART(); ES0 = 1; /* seriële interrupts inschakelen */ superstate = IDLE; break; case START_DISPLAY: ES0 = 0; /* seriële interrupts uitschakelen */ TI = 1; /* verzenden mogelijk maken */ Display(); ES0 = 1; /* seriële interrupts inschakelen */ superstate = IDLE; break;

58 Hoofdstuk 3. Software 49 } } } De watchdog wordt uitgeschakeld omdat dit problemen gaf met de communicatie. Na initialisatie van de seriële poort komt de uitvoering in een toestandsmachine terecht. De standaardtoestand is IDLE, waarin de microcontroller zich in een energiezuinige toestand bevindt. De andere toestanden roepen de FSMs die de acties afwerken op. De toestand (bepaald door de variabele superstate) wordt veranderd als een ASCII-commando ontvangen wordt. Dit gebeurt in de interrupt service routine (ISR) van de UART0: bij ontvangen of verzenden van data wordt een interrupt gegenereerd. Om racecondities te vermijden worden de seriële interrupts dan ook uitgeschakeld bij uitvoering van een actie. De ISR ziet er als volgt uit: extern SuperSystemState superstate; void UART_ISR(void) interrupt INTERRUPT_UART /* int 4, adres 0023h */ { char ch; if (RI == 1) { ch = SBUF0; /* seriële buffer */ } switch (ch) { case S : superstate = START_STORE_UART; break; case L : superstate = START_GET_UART; break; case D : superstate = START_DISPLAY; break; default: break; } RI = 0;

59 Hoofdstuk 3. Software 50 } if (TI == 1) { TI = 0; } Het speciale sleutelwoord interrupt geeft aan dat de functie een ISR is. De registers RI en TI zeggen of data ontvangen of verzonden werd; er wordt dan op gepaste wijze gereageerd. Zoals het hoort bij een ISR is deze functie zeer kort. Haar doel is enkel een variabele te veranderen waardoor de acties in normale uitvoering worden afgewerkt. Omdat seriële interrupts dan uitgeschakeld zijn, moeten de functies die data verzenden of ontvangen zelf controleren als de poort vrij is door RI en TI te lezen of te zetten: byte putch_no_ints (const byte c) { while (!TI) ; /* wacht */ TI = 0; return (SBUF0 = c); } byte getch() { byte ch; } while (!RI) ; /* wacht */ RI = 0; return (ch = SBUF0); Implementatie van de acties De toestandsdiagramma van de acties zijn terug te vinden in figuur 3.3, 3.5 en 3.7. Omdat de code meestal triviaal is, wordt ze niet gegeven. Enkel de meest interessante zaken worden hier vermeld.

60 Hoofdstuk 3. Software 51 Schrijven naar het flashgeheugen Bij een opslaan -actie wordt in de toestanden RECEIVE BLOCK en RECEIVE LAST BLOCK geschreven naar het flashgeheugen. Het geheugenmodel van de 8051 is nogal verschillend van dat van een gewone mini- of microcomputer. Daar wordt programmacode en data in dezelfde fysische geheugenruimte geladen. Onze microcontroller gebruikt een adresseerschema dat code en data van elkaar scheidt. Beide zijn 64 KiB groot (0000h tot FFFFh). Ze kunnen echter wel fysisch overlappen. Programmageheugen Dit is alleen-lezen, intern (in de chip zelf) of extern geheugen dat automatisch wordt gelezen bij uitvoering van een programma of door de MOVC-instructie. Datageheugen Dit is lezen/schrijven geheugen, intern of extern. worden door de instructie MOVX. Het kan aangesproken Ons flashgeheugen is duidelijk extern. We moeten niet rechtstreeks met de MOVX werken omdat de C51 compiler een aantal sleutelwoorden heeft die toelaten het soort geheugen te specifiëren: xdata zal een variabele in het extern datageheugen plaatsen, idata in het intern datageheugen. We definiëren dus een pointer naar de beelddata in het flash en een buffer van die data in het intern geheugen: byte volatile xdata * xblock = 0x0000; // extern geheugen byte idata block[128]; // buffer Het sleutelwoord volatile zegt aan de compiler om gelezen data niet in een register te plaatsen, maar opnieuw echt te lezen. Dit is vereist bij het lezen van het flash in een lus. Het adres waar xblock naar wijst wordt aangepast om het correct beeld en blok te schrijven of te lezen. Er wordt sector-gebaseerd naar het flashgeheugen geschreven: als er 128 bytes ingeladen zijn, worden die gelijktijdig geprogrammeerd. De chip zal de adressen en data latchen zodat de adres- en databus vrijkomen voor andere operaties. Het einde van een programmeercylcus kan bepaald worden door DATA-polling: wanneer de laatste ingeladen byte tijdens het programmeren gelezen wordt, zal het complement van de ingeladen data verschijnen op de pin I/O7. Als de programmeercyclus afgelopen is, verschijnt de volledig correct data op de databus. Een en ander wordt verduidelijkt in de volgende code: /*

61 Hoofdstuk 3. Software 52 * CEb is de chip enable poort van het flash (actief laag). * block wijst naar het startadres van een blok */ /* block ontvangen en bufferen */ for (bytenum = 0; bytenum < 128; bytenum++) block[bytenum] = getch(); /* blok wegschrijven */ CEb = 0; for (bytenum = 0; bytenum < 128; bytenum++) *(xblock + bytenum) = block[bytenum]; CEb = 1; /* data polling: laatste byte lezen en vergelijken met versie in het intern geheugen */ while (1) { CEb = 0; if (*(xblock + 127) == block[127]) break; CEb = 1; }; CEb = 1; /* ga nu verder met het volgende blok */ De notaties *(rij + offset) en rij[offset] zijn semantisch gelijk: ze benaderen de data op het adres rij + offset. De array-notatie voor block geeft hier aan dat het om een buffer met vaste grootte aan, terwijl het externe geheugen xblock beschreven wordt op adressen die tijdens de uitvoering berekend worden aan de hand van het beeld- en bloknummer. Lezen uit het flashgeheugen De microcontroller zal een volledige beeld in een keer doorsturen naar de PC, dit gebeurt in de toestand SEND van de FSM: /* length en xblock zijn berekend in een vorige toestand */ case SEND: CEb = 0;

62 Hoofdstuk 3. Software 53 for (bytenum = 0; bytenum < length; bytenum++) CEb = 1; putch_no_ints(*(xblock + bytenum)); Afbeelden van een beeld In deze actie stuurt de microcontroller een beeld naar de FPGA, voor de onderlinge communicatie moeten beide dus een protocol volgen. Er worden 3 signalen gebruikt: sbit RSTb = P3 ^ 2; /* reset, actief laag, bit, pin P3.2 van uc */ sbit DAVb = P3 ^ 3; /* data available, actief laag, bit, pin P3.3 van uc */ sfr DATA = 0x90; /* data, byte, poort P2 = adres 0x90 van uc */ Het tijdsdiagram is te zien in figuur RST DAV DATA ÀÀÀÀ ÄÄ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀ ÄÄ ÀÀÀÀ ÄÄ ÀÀÀÀ ÄÄ ÀÀÀÀ Ä ÍÍÍÍÍÍÍÍÍÍÍ ÎÎÎÎÎÎ ÎÎÎÎÎÎ ÎÎÎÎÎÎ ÎÎÎ Figuur 3.20: Tijdsdiagram van de signalen voor communicatie met de FPGA. Na een reset van de FPGA wordt een byte op de databus gezet en DAV geasserteerd. De FPGA zal nu deze data lezen en cachen. Er moet voor gewaakt worden dat de data lang genoeg op de bus staat. De FPGA werkt namelijk maar met een 4 MHz klok. Daarom wordt een hardwarevertraging Delay() ingevoerd om zeker te zijn dat er minstens één FPGAkloktransitie is wanneer de data geldig is. Tussen de bytes moet ook, maar heel wat korter, gewacht worden. Dat gebeurt dan door aantal NOPs uit te voeren. case DISPLAY: /* puls op RST (actief laag) */ RSTb = 1; Delay(); RSTb = 0; Delay(); RSTb = 1;

63 Hoofdstuk 3. Software 54 /* zend 4 config bytes + 16 rijen van 16 pixels naar de de FPGA */ for (bytenum = 0; bytenum < 16 * ; bytenum++){ /* data op bus plaatsen */ DATA = *(xblock + bytenum); /* deasseerteer DAV */ DAVb = 1; /* beetje wachten */ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); /* asserteer DAV */ DAVb = 0; } /* wacht (FPGA haalt data op) */ Delay(); De hardwarevertraging gebeurt door een timer in te stellen op een goed gekozen waarde. Na overflow wordt dan verder gegaan met de uitvoering Mini DS89C420 programmer De DS89C420 is ontworpen om in-system geprogrammeerd te worden via zijn interne UART. Het bestaande systeem voorziet echter niet in deze functie. Daarom werd een eenvoudige programmer ontwikkeld die gebaseerd is op deze techniek. Om de chip te kunnen programmeren, dient hij naar zijn bootloader te springen. Dit gebeurt door een aantal pinnen een specifieke waarde op te dringen. Na ontvangst van een CR-karakter

64 Hoofdstuk 3. Software 55 zal de microcontroller zijn seriële poort automatisch synchroniseren op de baudrate van de PC. Het programmeren zelf kan dan makkelijkst gebeuren met de gratis Microcontroller Toolkit van Dallas. Een gewone seriële terminal is ook geschikt. In de volgende tabel zijn de vereiste stimuli te zien. RST EA PSEN Tabel 3.1: Inputstimuli voor bootloadermodus. Figuur 3.21 toont het schema van de programmer. Het voedingsgedeelte is standaard: een 7805 spanningsregelaar en een aantal afvlakcondensatoren. De diode beschermt de regelaar tegen spanningspieken die kunnen optreden bij het uitschakelen. Vanaf een ingangsspanning V in van 7 V is de uitgang van dit blok een stabiele 5 V. Het circuit is zo opgezet dat de microcontroller automatisch naar zijn bootloader springt bij het asserteren van de seriële DTR-pin (actief laag). Daartoe is een ingezet. Dit IC bevat 4 niet-inverterende tristate buffers, waarvan er 3 worden gebruikt. De stuuringangen zijn inverterend. Het is duidelijk dat bij assertie van DTR op de pinnen de correcte waarden worden geplaatst. De spanningsomzetting tussen het RS232-domein en CMOS-domein wordt verzorgd door een MAX232. Om de chip zo betrouwbaar mogelijk te programmeren, mogen de baudrates van PC en microcontroller niet meer dan 3 % van elkaar verschillen. Het kristal dat gebruikt wordt voor klokgeneratie moet dan een gepaste trilfrequentie hebben. Er werd gekozen om met de standaardsnelheid van 9600 bps te programmeren. De trilfrequentie van het kristal wordt dan als volgt bepaald: de bootloader gebruikt de seriële poort 0 in mode 1[13]: asynchroon, 1 startbit, 1 stopbit, geen pariteit, full duplex. Daarbij gebeurt de baudrategeneratie door timer 1 in 8 bit autoreload. Dat wil zeggen dat de timer vanaf een bepaalde waarde t naar boven telt en bij FFh automatisch opnieuw begint. In deze mode wordt de baudrate b gegeven door: b = 2SMOD x 32 f clk t Daarbij geldt dat SMOD x = 1. Dat geeft aan dat de baudrate verdubbeld wordt, wat het geval is als de chip zich in de bootloadermode bevindt. De formule wordt:

65 Hoofdstuk 3. Software = f clk 192 (256 t) Oplossen naar gehele waarden van t geeft als oplossing f clk = MHz en t = FAh. De automatische baudratesynchronisatie werkt als volgt: voor t worden achtereenvolgens de waarden uit de set {FFh, FEh, FDh, FCh, FBh, FAh, F8h, F6h, F5h, F4h, F3h, F0h, ECh, EAh, E8h, E6h, E0h, DDh, D8h, D4h, D0h, CCh, C0h, BAh, B0h, A8h, A0h, 98h, 80h, 60h, 40h} geprobeerd totdat een minimale afwijking tussen de interne en externe baudrate gevonden wordt. In ons geval zal dus een optimale waarde voor t van FAh gevonden worden, bij een afwijking 0. Een foto van de programmer opgebouwd op een breadboard is te zien in figuur 3.22.

66 Hoofdstuk 3. Software 57 Figuur 3.21: Het schema van de mini-programmer.

67 Hoofdstuk 3. Software 58 Figuur 3.22: De mini-programmer opgebouwd op een breadboard.

68 Hoofdstuk 4 Semi-automatische vermogenmeting De aanstuurchips die de complexe golfvormen genereren waarmee een beeld wordt opgebouwd, maken gebruik van 6 voedinglijnen: 85 V, 60 V, 55 V, 45 V, 35 V en 5 V. Om het totale vermogen te kennen dat gedissipeerd wordt bij het afbeelden van een beeld, moet de som van het vermogenverbruik in elk van die lijnen gemeten worden. De methode die hier voorgesteld wordt, stelt ons in staat om de dissipatie in 1 lijn te meten. 4.1 Opzet Opmerking vooraf De lengte van een afbeeldcyclus is onder andere afhankelijke van de configuratiedata. In wat volgt wordt uitgegaan van de volgende vaste parameters: Methode lijntijd laag lijntijd hoog CR tijdens reset CR tijdens lijnscan nee nee In [9] wordt een oplossing voorgesteld om het verbruik te meten: voor het (ogenblikkelijk) vermogenverbruik P i in lijn i geldt: P i = V i I i met V i de voedingsspanning van en I i de stroom door de voedingslijn. Het meten van de stroom gebeurt door de spanningsval V di te meten over een kleine shuntweerstand R i. Die weerstand moet klein gehouden worden om de rest van het systeem zo weinig mogelijk te beïnvloeden. We bekomen: P i = V i V di R i 59

69 Hoofdstuk 4. Semi-automatische vermogenmeting 60 In tabel 4.1 zijn eigenschappen van de voedingslijnen samengevat. De index i wordt vanaf nu achterwege gelaten. Voor het meten van de veranderlijke spanningsval V t,d (t) wordt de digitale oscilloscoop THS720A van Tektronix gebruikt[15]. Dit is een 2-kanaalsscoop die programmeerbaar is via een RS- 232 poort. De minimale sampleperiode is 2 ns (500 megasamples per seconde), waarbij per meting 2500 samples genomen worden. Kanaal 1 meet de spanningsval over de shuntweerstand, terwijl op kanaal 2 getriggerd wordt. Het triggersignaal is afkomstig van een rij- of kolomstuursignaal gegenereerd door een driverchip. Het is mogelijk om hierop te triggeren omdat zo n signaal altijd eenzelfde structuur heeft: een aantal resetpulsen gevolgd door een selectiepuls die de rij of kolom selecteert. Door het triggerniveau adequaat in te stellen, en door een vertraagde tijdsbasis te gebruiken kan een arbitraire portie van de spanningsval over de shuntweerstand opgenomen worden. Een vertraagde tijdsbasis van t s wil zeggen dat er, nadat de scoop getriggerd wordt, t s gewacht wordt met opnemen van een golfvorm (figuur 4.1). Figuur 4.1: Illustratie bij een vertraagde tijdsbasis. We kiezen het eerste rijsignaal als triggersignaal voor de metingen (schets in figuur 4.2), met een triggerniveau van 50 V. Het signaal V t,d (t) wordt dus met een sampleperiode T s lijn V i (V) R i (Ω) Tabel 4.1: Voedingslijnen en shuntweerstanden

70 Hoofdstuk 4. Semi-automatische vermogenmeting 61 90,0 80,0 70,0 Spanning (V) 60,0 50,0 40,0 30,0 20,0 10,0 0,0 tijd Figuur 4.2: Het signaal waarop getriggerd wordt. bemonsterd: V d (n) = V t,d (n T s ), n = 1..N T s wordt op een goede waarde ingesteld afhankelijk van de meting. De PC haalt de golfvorm V d (n) op voor verdere verwerking. Het vermogenverbruik tijdens een interval [nt s, (n + 1)T s ] is: P (n) = V R V d(n) De gemiddelde dissipatie en het piekvermogen over het volledig meetinterval worden: P avg = 1 N V R N V d (n) (4.1) n=1 P peak = V R V d,max (4.2) Globale en lokale metingen Er zijn twee soorten metingen: ˆ een globale meting van het vermogen tijdens een volledige afbeeldcyclus; ˆ een lokale meting, met een in te stellen meetvenster. Globale meting Deze meting is bedoeld om een globaal overzicht van de dissipatie in een bepaalde voedingslijn te hebben. Het woord globaal slaat op het feit dat de meting gebeurt

71 Hoofdstuk 4. Semi-automatische vermogenmeting 62 rij tijd (ms) kolom tijd (ms) Tabel 4.2: Eindtijden van de selectiepuls van de stuursignalen. over de volledige afbeeldcyclus. Om de duur van zo n cyclus te bepalen is van elk stuursignaal het tijdstip bepaald van het einde van de selectiepuls ten opzichte van de eerste resetpuls. De langste tijd is de duur van een afbeeldcyclus. Uit tabel 4.2 blijkt dat de cylcustijd 252 ms is. De scoop heeft horizontaal 10 divisies. De tijdsbasisschaal zou dus op 25 ms per divisie moeten ingesteld worden. De THS720A laat echter enkel schaalfactoren toe in een reeks. De schaalfactor wordt dus 20 ms per divisie. Nu moet het signaal in twee keer gemeten worden: de tweede keer met een vertraagde tijdsbasis van 200 ms. V d (n) bestaat dan uit 5000 samples genomen over een tijdspanne van 400 ms. De sampleperiode T s is dan 80 µs. Het is duidelijk dat T s veel te groot is om accurate resultaten te verkrijgen (Nyquistvoorwaarde niet voldaan). Belangrijk is dus op te merken dat een globale meting geen goede indicatie geeft van het vermogengebruik. Het is hoogstens een hulpmiddel om meetvensters te bepalen voor een lokale meting. Lokale meting Een lokale meting is een meting van 2500 samples die gebeurt in een zelf in te stellen interval: het meetvenster. Zo kan men de interessante componenten van de dissipatie afzonderen. De gebruiker geeft een starttijd t en lengte l (uit de sequentie 1-2-5) op. De starttijd t is de vertraging van tijdsbasis. Een voldoende klein venster, en daardoor een voldoende kleine sampleperiode, zal een goede meting opleveren. 4.2 Uitbreiding van BDControl BDControl werd aangepast om te voorzien in de nieuwe functionaliteit. Er werd een nieuwe namespace BD.Power ingevoerd. De visuele component PowerMeasureControl is een nieuw deelvenster voor de vermogenmeting, PowerGraphForm is een simpel venster dat het signaal V d (n) toont en PowerMeasureManager neemt het eigenlijke meetwerk op zich. Een meting

72 Hoofdstuk 4. Semi-automatische vermogenmeting 63 wordt opgeslagen in een PowerMeasurement-object. PowerMeasurement Class Properties XValues YValues Methods GetAveragePower GetPeakPower Figuur 4.3: De klasse PowerMeasurement ˆ BD.Power.PowerMeasurement: deze klasse (figuur 4.3) stelt de eigenlijke meting V d (n) voor. De twee methodes berekenen het piek- en gemiddelde vermogen. PowerMeasureManager Class Properties Methods Events SupplyLines ConformData ExecuteCommands GetWaveformParams InitScope InitSerialPort InvokeCompletionEvent MeasureGlobal MeasureGlobalTask MeasureLocal MeasureLocalTask WaitForBusy MeasurementCompleted Nested Types Figuur 4.4: PowerMeasureManager ˆ BD.Power.PowerMeasureManager: (figuur 4.4) de metingen worden hier ook asynchroon uitgevoerd. Ditmaal is geen gebruik gemaakt van een BackgroundWorker, maar van de.net threadpool. Dit zijn een aantal slapende threads (standaard 25 per logische pro-

73 Hoofdstuk 4. Semi-automatische vermogenmeting 64 cessor). Ze kunnen een taak toegewezen worden met QueueUserWorkItem(). De methoden MeasureGlobal() en MeasureLocal() hebben een corresponderende *Task() die de meting uitvoert. Eerst wordt de oscilloscoop ingesteld, dan wordt het beeld afgebeeld. Daarbij zal de scoop getriggerd worden. Als laatste haalt de PC de golfvorm binnen. Bij een meting zijn er dus drie threads betrokken: één voor de GUI, één voor de scoopsturing en een laatste die de display-actie uitvoert. Uiteraard wordt opnieuw een synchronisatieprimitief (semafoor) gebruikt. Na afloop wordt het event MeasurementCompleted opgeroepen dat de gemeten data kan doorgeven. Het aansturen van de scoop gebeurt met ASCII-commando s[16]. Om bijvoorbeeld in te stellen dat een vertraagde tijdsbasis van 100 ms met een schaal van 2 µs/divisie gebruikt worden, moet de volgende opdrachten gegeven worden: HORIZONTAL:DELAY:TIME:RUNSAFTER 100e-3 HORIZONTAL:MAIN:SCALE 2e-6 HORIZONTAL:MODE DELAYED ExecuteCommand() zal een lijst van commando s naar de oscilloscoop sturen. WaitForBusy bevraagt het apparaat in een lus met BUSY? totdat een 0 geantwoord wordt. Dit is handig om het programma en de scoop de synchroniseren. De get-property SupplyLines geeft een lijst van SupplyLineSettings objecten terug die verschillende voedingslijnen voorstellen (voedingsspanning en shuntweerstand). De data wordt ontvangen in ASCII formaat, waarbij elk datapunt een tekstuele voorstelling is van een 16-bit waarde, dus tussen en De methode ConformData() zal uit deze punten de werkelijke waarden berekenen, samen met de tijdschaal, aan de hand van de instellingen van de oscilloscoop. ˆ BD.GUI.PowerMeasureControl en BD.GUI.PowerGraphForm: een screenshot van het nieuwe interface-element is te zien in figuur 4.5. Dit venster verwacht invoer van de gebruiker: de aansluiting van de oscilloscoop, welke voedingslijn gemeten wordt en het meetvenster. Er zijn knoppen aanwezig om een globale of lokale meting te starten. Een druk op graph toont de golfvorm in een instantie van PowerGraphForm. Daarvoor werd de open-source grafiekbibliotheek NChart gebruikt[10]. De werking van de klassen is uiterst triviaal ze bevatten bijna uitsluitend glue logic en wordt dan ook niet gegeven.

74 Hoofdstuk 4. Semi-automatische vermogenmeting 65 Figuur 4.5: Het nieuwe interface-element voor de vermogenmeting. 4.3 Illustratie van de methode Om correct te meten dient de volgende procedure gevolgd te worden. Hierbij wordt ervan uitgegaan dat het display aangesloten is en dat BDControl draait. Het is belangrijk dat een Tektronix THDS720A oscilloscoop gebruikt wordt. De RS232 snelheid moet baud zijn. 1. Sluit de probe van kanaal 1 aan over de gewenste shuntweerstand. 2. Sluit de probe van kanaal 2 aan op het eerste rijsignaal. 3. Selecteer in BDControl de juiste poorten (zowel van het aanstuurbord als de oscilloscoop). 4. Open indien nodig een beeld met de configuratieparamaters hierboven beschreven en verstuur het naar het display. 5. Selecteer de correcte instelling van de voedingslijn in BDControl. 6. Doe een globale meting. 7. Gebruik de globale meting om een interessant venster te bepalen voor een lokale meting. 4.4 Voorbeeld Er werd een meting gedaan op de 60 V voedingslijn. Figuur 4.6 toont de globale meting en twee lokale metingen met steeds kleiner meetvenster. Enkel bij de laatste meting is de samplefrequentie groot genoeg en zijn de betrouwbare resultaten af te lezen in het resultaatveld (figuur 4.7).

75 Hoofdstuk 4. Semi-automatische vermogenmeting 66 (a) De globale meting. (b) De eerste lokale meting. (c) De tweede lokale meting. Figuur 4.6: Een meetvoorbeeld.

76 Hoofdstuk 4. Semi-automatische vermogenmeting 67 Figuur 4.7: Het vermogenverbruik van de laatste lokale meting.

Prestatiemetingen voor systeemsoftware m.b.v. FPGA

Prestatiemetingen voor systeemsoftware m.b.v. FPGA Prestatiemetingen voor systeemsoftware m.b.v. FPGA Jens Van den Broeck Promotoren: prof. dr. ir. Bjorn De Sutter, prof. dr. ir. Dirk Stroobandt Begeleiders: ir. Niels Penneman, ir. Wim Meeus Masterproef

Nadere informatie

Ontwerp en implementatie van een draadloos communicatieprotocol voor sensor netwerken

Ontwerp en implementatie van een draadloos communicatieprotocol voor sensor netwerken Ontwerp en implementatie van een draadloos communicatieprotocol voor sensor netwerken Bert Vanhoutte Promotor: prof. dr. ir. Jan Doutreloigne Begeleiders: ir. Benoît Huyghe, ir. Thomas Vervust Masterproef

Nadere informatie

Ontwerp van een intelligente EPG voor het MHP-platform

Ontwerp van een intelligente EPG voor het MHP-platform Faculteit Ingenieurswetenschappen Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. Lagasse Onderzoeksgroep Wireless & Cable Directeur: prof. dr. ir. L. Martens Ontwerp van een intelligente EPG

Nadere informatie

Ontwikkeling van een DVB playout manager voor interactieve digitale televisie

Ontwikkeling van een DVB playout manager voor interactieve digitale televisie Faculteit Ingenieurswetenschappen Vakgroep Informatietechnologie Voorzitter: prof. dr. ir. P. Lagasse Onderzoeksgroep Wireless & Cable Directeur: prof. dr. ir. L. Martens Ontwikkeling van een DVB playout

Nadere informatie

Automatische VPN-tunneling tussen OSGi-gateways

Automatische VPN-tunneling tussen OSGi-gateways Faculteit Ingenieurswetenschappen Vakgroep Informatietechnologie Voorzitter: prof. dr. ir. P. LAGASSE Automatische VPN-tunneling tussen OSGi-gateways door Bas BOONE Jelle NELIS Promotor: prof. dr. ir.

Nadere informatie

Auteursrecht. c 2009, Michael Van den Broeck, Cypress Semiconductor

Auteursrecht. c 2009, Michael Van den Broeck, Cypress Semiconductor Auteursrecht c 2009, Michael Van den Broeck, Cypress Semiconductor De auteur geeft de toelating deze scriptie voor consultatie beschikbaar te stellen en delen van de scriptie te kopiëren voor persoonlijk

Nadere informatie

FPGA implementatie van het HOG algoritme

FPGA implementatie van het HOG algoritme FACULTEIT INDUSTRIELE INGENIEURSWETENSCHAPPEN CAMPUS DE NAYER FPGA implementatie van het HOG algoritme Stef VAN WOLPUTTE Promotor: ing. Van Beeck Kristof Masterproef ingediend tot het behalen van de graad

Nadere informatie

Ontwikkeling van een Remote Controlled Alert & Task Agent

Ontwikkeling van een Remote Controlled Alert & Task Agent owered by TCPDF (www.tcpdf.org) Academiejaar 2012 2013 Geassocieerde faculteit Toegepaste Ingenieurswetenschappen Valentin Vaerwyckweg 1 9000 Gent Ontwikkeling van een Remote Controlled Alert & Task Agent

Nadere informatie

RIVM rapport 773401005/2003. Reference Guide Microsoft.NET. M van der Zee, G Verspaij, S Rosbergen

RIVM rapport 773401005/2003. Reference Guide Microsoft.NET. M van der Zee, G Verspaij, S Rosbergen RIVM rapport 773401005/2003 Reference Guide Microsoft.NET M van der Zee, G Verspaij, S Rosbergen Intern rapport Dit onderzoek werd verricht in opdracht en ten laste van LAE-RIS, in het kader van project

Nadere informatie

Visualiseren van de medische beelden op een mobile device

Visualiseren van de medische beelden op een mobile device owered by TCPDF (www.tcpdf.org) Academiejaar 2013 2014 Faculteit Ingenieurswetenschappen en Architectuur Valentin Vaerwyckweg 1 9000 Gent Visualiseren van de medische beelden op een mobile device Masterproef

Nadere informatie

Techno-economische studie voor het uitrollen van interactieve multimedia Thin Client diensten

Techno-economische studie voor het uitrollen van interactieve multimedia Thin Client diensten Techno-economische studie voor het uitrollen van interactieve multimedia Thin Client diensten Maarten De Groote Promotoren: prof. dr. Mario Pickavet, prof. dr. ir. Bart Dhoedt Begeleiders: Pieter Simoens,

Nadere informatie

Dynamische compositie van medische Web services in OWL-S

Dynamische compositie van medische Web services in OWL-S Faculteit Ingenieurswetenschappen Dynamische compositie van medische Web services in OWL-S door Anna HRISTOSKOVA & Dieter MOEYERSOON Promotoren: Prof. Dr. Ir. Filip DE TURCK & Prof. Dr. Johan DECRUYENAERE

Nadere informatie

Masterproef Automatic update and inventory application

Masterproef Automatic update and inventory application Masterproef Automatic update and inventory application Studiegebied Industriële wetenschappen en technologie Opleiding Master in de industriële wetenschappen: Elektronica-ICT Afstudeerrichting Informatie-

Nadere informatie

Grondige performantiestudie van JAVA en.net technologieën voor gedistribueerd software-ontwerp

Grondige performantiestudie van JAVA en.net technologieën voor gedistribueerd software-ontwerp Faculteit Toegepaste Wetenschappen Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. Lagasse Grondige performantiestudie van JAVA en.net technologieën voor gedistribueerd software-ontwerp door

Nadere informatie

Studie van visualisatie-algortimen voor het vinden en selecteren van audiovisuele content

Studie van visualisatie-algortimen voor het vinden en selecteren van audiovisuele content Studie van visualisatie-algortimen voor het vinden en selecteren van audiovisuele content Bart Van Hoecke Promotor: prof. dr. ir. Luc Martens Begeleiders: ir. Tom Deryckere, Toon De Pessemier Scriptie

Nadere informatie

Vb.net planningstool en Scada applicatie

Vb.net planningstool en Scada applicatie Masterproef VB.net planningstool en Scada applicatie Studiegebied Industriële wetenschappen en technologie Opleiding Master of Science in de industriële wetenschappen: elektrotechniek Afstudeerrichting

Nadere informatie

Masterproef Tester Real-Time Software For Weaving Machine

Masterproef Tester Real-Time Software For Weaving Machine Masterproef Tester Real-Time Software For Weaving Machine Studiegebied Industriële wetenschappen en technologie Opleiding Master of Science in de industriële wetenschappen: elektromechanica Academiejaar

Nadere informatie

Localisatie van personen met behulp van WiFi en Smart Cards

Localisatie van personen met behulp van WiFi en Smart Cards Faculteit Ingenieurswetenschappen Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. Lagasse Localisatie van personen met behulp van WiFi en Smart Cards door Pieter Lootens Tim De Bruyn Promotoren:

Nadere informatie

UAV autonoom laten vliegen door een boomgaard

UAV autonoom laten vliegen door een boomgaard Departement Industriële Ingenieurswetenschappen Master in de industriële wetenschappen: Elektronica-ICT afstudeerrichting ICT (Dries Hulens), Elektronica (Maarten Vandersteegen) UAV autonoom laten vliegen

Nadere informatie

Optimaliseren van positiemetingen op basis van randvoorwaarden. Floris De Smedt

Optimaliseren van positiemetingen op basis van randvoorwaarden. Floris De Smedt Optimaliseren van positiemetingen op basis van randvoorwaarden Floris De Smedt 4 mei 2009 ii Voorwoord In 2004 begon ik aan een professionele bachelor opleiding electonica-ict aan het Hoger Instituut der

Nadere informatie

Aflevering van gepersonaliseerde multimediale data in peer-to-peer netwerken

Aflevering van gepersonaliseerde multimediale data in peer-to-peer netwerken Aflevering van gepersonaliseerde multimediale data in peer-to-peer netwerken Birger Anckaert Promotor: prof. dr. ir. Rik Van de Walle Begeleiders: dr. Davy Van Deursen, Erik Mannens Masterproef ingediend

Nadere informatie

Microcontrollers. en de taal C. Wim Dolman. vierde druk

Microcontrollers. en de taal C. Wim Dolman. vierde druk Microcontrollers en de taal C vierde druk Wim Dolman Informatie over dit boek en andere uitgaven kunt u verkrijgen bij: Wim Dolman info@dolman-wim.nl http://mic.dolman-wim.nl/ Microcontrollers en de taal

Nadere informatie

Experimentele studie van een NAT dienst met behulp van netwerkprocessoren

Experimentele studie van een NAT dienst met behulp van netwerkprocessoren Faculteit Toegepaste Wetenschappen Vakgroep Informatietechnologie Voorzitter: Prof. Dr. Ir. P. LAGASSE Experimentele studie van een NAT dienst met behulp van netwerkprocessoren door Wim VAN DE MEERSSCHE

Nadere informatie

Draadloos internet op de trein

Draadloos internet op de trein Faculteit Ingenieurswetenschappen Vakgroep INTEC Voorzitter: Prof. Dr. Ir. P. LAGASSE Draadloos internet op de trein door Wim De Saegher Promotor: prof. dr. ir. I. Moerman scriptiebegeleiders: Ir. B. Jooris

Nadere informatie

Designing a Dynamic Development Environment for Web Design Auteur: Toon G.Y. Macharis

Designing a Dynamic Development Environment for Web Design Auteur: Toon G.Y. Macharis Universiteit Gent Faculteit Ingenieurswetenschappen Vakgroep Electronica en Informatiesystemen Voorzitter: Prof. Dr. Ir. Jan M. Van Campenhout Designing a Dynamic Development Environment for Web Design

Nadere informatie

Shared ios and Android app using Xamarin.Forms with custom controls

Shared ios and Android app using Xamarin.Forms with custom controls Scriptie ingediend tot het behalen van de graad van PROFESSIONELE BACHELOR IN DE ELEKTRONICA-ICT Shared ios and Android app using Xamarin.Forms with custom controls Robin Vercammen Departement Wetenschappen

Nadere informatie

Ontwerp en evaluatie van een OSGi en MHP gebaseerde applicatie voor een thuisomgeving van de toekomst

Ontwerp en evaluatie van een OSGi en MHP gebaseerde applicatie voor een thuisomgeving van de toekomst Faculteit toegepaste wetenschappen Vakgroep Informatie Technologie Voorzitter Prof. Dr. Ir. P. Lagasse Ontwerp en evaluatie van een OSGi en MHP gebaseerde applicatie voor een thuisomgeving van de toekomst

Nadere informatie

Hogeschool Gent Departement Industriële Wetenschappen Vakgroep Elektronica. Academiejaar 2004 2005. FIM for itv. Koen De Voegt

Hogeschool Gent Departement Industriële Wetenschappen Vakgroep Elektronica. Academiejaar 2004 2005. FIM for itv. Koen De Voegt Hogeschool Gent Departement Industriële Wetenschappen Vakgroep Elektronica Academiejaar 2004 2005 FIM for itv Koen De Voegt Promotoren: Ir. K. Handekyn (Alcatel Antwerpen) Ir. L. Colman (Hogeschool Gent)

Nadere informatie

HTML5-gebaseerde monitoring voor digitale toeristische gidsen

HTML5-gebaseerde monitoring voor digitale toeristische gidsen owered by TCPDF (www.tcpdf.org) Academiejaar 2013 2014 Faculteit Ingenieurswetenschappen en Architectuur Valentin Vaerwyckweg 1 9000 Gent HTML5-gebaseerde monitoring voor digitale toeristische gidsen Masterproef

Nadere informatie

Objectgericht ontwerpen

Objectgericht ontwerpen Associatie KULeuven Hogeschool voor Wetenschap & Kunst De Nayer instituut Industrieel ingenieur Opleiding Elektronica-ICT 3e academisch bachelorjaar Objectgericht ontwerpen Deel I Academiejaar 2009-10

Nadere informatie