Toto je starší verze dokumentu!
Navrhnete zařízení pro sběr a záznam environmentálních veličin: teplota okolí, barometrický tlak, vlhkost vzduchu a koncentrace CO2. Tyto údaje zaznamenejte na vhodné paměťové medium. Veličiny vzorkujte s periodou alespoň 1min a zobrazte na grafickém displeji. Vyřešte přenos naměřených údajů do počítače.
Úlohou v tejto práci, je navrhnúť a postaviť zariadenie pre zber údajov environmentálnych veličín. Celý projekt môžeme rozdeliť do niekoľkých podskupín:
Spracovanie údajov zo senzorov, riadenie display-a bude prebiehať na vývojovej doske NXP FRDM-K64. https://www.nxp.com/products/processors-and-microcontrollers/arm-based-processors-and-mcus/kinetis-cortex-m-mcus/k-seriesperformancem4/k2x-usb/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F, ktorú bude potrebné patrične upraviť.
Pre zber údajov o prostredí som navrhol dosku, ktorá obsahuje všetky potrebné senzory. Výber jednotlivých senzorov bol viacmenej priamočiary a výchádzal som z dostupných obvodov, ktoré už boli zakúpené. Pre meranie teploty a tlaku je použítý obvod SHT21 firmy Sensirion. https://www.sensirion.com/en/environmental-sensors/humidity-sensors/humidity-temperature-sensor-sht2x-digital-i2c-accurate/. Ide o obvod, ktorý komunikuje sériovou zbernicou I2C. Obvod vyžaduje len málo externých komponentov, blokovací kondenzátor a štandardné pull-up rezistory na vodičoch zbernice.
Pre meranie tlaku je použitý obvod HOPE RF, HP03M. http://www.hoperf.de/sensor/barometer_16/HP03M.htm. Tento obvod taktiež komunikuje po zbernici I2C s inými adresami zariadenia ako SHT21, preto možu byť bezproblémov zapojené na jednej zbernici. Riadenie je skomplikované tým, že A/D prevodník v senzore nemá vlastný oscilátor a je nutné mu hodinový signál priviesť externe - signál MCLK, ďalej je odporúčané uviesť prevodník do stavu reset, pri čítaní nameraných údajov, k tomu je pripojený ďalší signál XCLR.
Posledným zo senzorov je senzor koncentrácie CO2. Dostupný bol analógový senzor FIGARO TGS4161 https://cdn.sos.sk/productdata/62/d9/f2bb36a6/tgs-4161.pdf. K tomuto bolo nutné navrhnúť obvod, pre spracovanie signálu, ktorý by bolo možné merať A/D prevodníkom. Senzor generuje malé elektromotorické napätie, ktorého veľkosť zmeny exponenciálne závisí od koncentrácie CO2. Výstupná impedancia tohto senzoru je veľmi veľká, z čoho plynie požiadavka pre spracovanie obvodom s veľmi veľkou vstupnou impedanciou. Odporúčaná impedancia je >100G. Tomu vyhovuje obvod TLC271. ďalšie spracovanie je už iba odcítanie a zosilnenie meraného napätia 5x prístrojovým zosilňovačom.
a zmeraná prevodová charakteristika:
. Celý obvod je kompletne dizajnovaný ako jeden modul. Kompletna schema a PCB
Pre zobrazovanie meraných údajov je použitý TFT grafický displej Sainsmart https://www.sainsmart.com/products/3-2-tft-lcd-touch-screen-with-sd-slot s radičom SSD1289, ktorý komunikuje po paralelnej zbernici kompatibilnej s motorola 6800 štandardom. Najlepší spôsob, ako komunikovať po tejto zbernici, je použiť na to určenú perifériu mikrokontroléra K64 Flexbus. SSD1289 vyžaduje 16 dátových signálov, 1 RW, 1 CS, 1 D/S a 1 RST signál. Nie všetky tieto signály sú prístupné na konektoroch vývojovej dosky. Obsahuje ale neobsadené piny na konektoroch, ku ktorým je možné tieto signály priviesť. Pre pripojenie displeju a modulu so senzormi k vývojovej doske som navrhol a vyrobil ďalšiu dosku preto určenú. .
Upravená vývojová doska FRDM-K64 s privedenými chýbajúcimi signálmi zbernice Flexbus:
. Schéma a PCB rozširovacej dosky
Poslednou z nutných periférií pre Datalogger je pamäťové médium. Z výhodou som mohol použiť integrovanú perifériu pre komuniáciu s SDHC kartou. Ďalšie z periférií, ktoré sú prístupné sú LAN, USB a UART pre rozšírenia v budúcnosti. Zostavený dataloger:.
Software je zložený s niekoľkých modulov.
Pre správnu činnosť periférií je dôležité nastavenie konfigurácií pinov. Každý pin procesora obsahuje multiplexor s privedenými signálmi s rôznych periférií.
CLOCK_EnableClock(kCLOCK_PortC); CLOCK_EnableClock(kCLOCK_PortB); CLOCK_EnableClock(kCLOCK_PortE); // Set UART PORT_SetPinMux(PORTC, PIN14_IDX, kPORT_MuxAlt3); /* PORTB16 (pin 62) is configured as UART0_RX */ PORT_SetPinMux(PORTC, PIN15_IDX, kPORT_MuxAlt3); /* PORTB17 (pin 63) is configured as UART0_TX */ SIM->SCGC1 = (SIM->SCGC1 | SIM_SCGC1_UART4_MASK); PORT_SetPinMux(PORTB, PIN20_IDX, kPORT_MuxAsGpio); // GPIO Heater TGS 4146 1->ON PORT_SetPinMux(PORTB, PIN10_IDX, kPORT_MuxAsGpio); //Set SDHC interface const port_pin_config_t porte0_pin1_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_HighDriveStrength, /* High drive strength is configured */ kPORT_MuxAlt4, /* Pin is configured as SDHC0_D1 */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN0_IDX, &porte0_pin1_config); /* PORTE0 (pin 1) is configured as SDHC0_D1 */ const port_pin_config_t porte1_pin2_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_HighDriveStrength, /* High drive strength is configured */ kPORT_MuxAlt4, /* Pin is configured as SDHC0_D0 */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN1_IDX, &porte1_pin2_config); /* PORTE1 (pin 2) is configured as SDHC0_D0 */ const port_pin_config_t porte2_pin3_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_HighDriveStrength, /* High drive strength is configured */ kPORT_MuxAlt4, /* Pin is configured as SDHC0_DCLK */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN2_IDX, &porte2_pin3_config); /* PORTE2 (pin 3) is configured as SDHC0_DCLK */ const port_pin_config_t porte3_pin4_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_HighDriveStrength, /* High drive strength is configured */ kPORT_MuxAlt4, /* Pin is configured as SDHC0_CMD */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN3_IDX, &porte3_pin4_config); /* PORTE3 (pin 4) is configured as SDHC0_CMD */ const port_pin_config_t porte4_pin5_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_HighDriveStrength, /* High drive strength is configured */ kPORT_MuxAlt4, /* Pin is configured as SDHC0_D3 */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN4_IDX, &porte4_pin5_config); /* PORTE4 (pin 5) is configured as SDHC0_D3 */ const port_pin_config_t porte5_pin6_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_HighDriveStrength, /* High drive strength is configured */ kPORT_MuxAlt4, /* Pin is configured as SDHC0_D2 */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN5_IDX, &porte5_pin6_config); /* PORTE5 (pin 6) is configured as SDHC0_D2 */ const port_pin_config_t porte6_pin7_config = { kPORT_PullDown, /* Internal pull-down resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainDisable, /* Open drain is disabled */ kPORT_LowDriveStrength, /* Low drive strength is configured */ kPORT_MuxAsGpio, /* Pin is configured as PTE6 */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN6_IDX, &porte6_pin7_config); /* PORTE6 (pin 7) is configured as PTE6 */ } void BOARD_I2C_ConfigurePins(void) { CLOCK_EnableClock(kCLOCK_PortE); /* Port E Clock Gate Control: Clock enabled */ //Set IIC const port_pin_config_t porte24_pin31_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainEnable, /* Open drain is enabled */ kPORT_LowDriveStrength, /* Low drive strength is configured */ kPORT_MuxAlt5, /* Pin is configured as I2C0_SCL */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN24_IDX, &porte24_pin31_config); /* PORTE24 (pin 31) is configured as I2C0_SCL */ const port_pin_config_t porte25_pin32_config = { kPORT_PullUp, /* Internal pull-up resistor is enabled */ kPORT_FastSlewRate, /* Fast slew rate is configured */ kPORT_PassiveFilterDisable, /* Passive filter is disabled */ kPORT_OpenDrainEnable, /* Open drain is enabled */ kPORT_LowDriveStrength, /* Low drive strength is configured */ kPORT_MuxAlt5, /* Pin is configured as I2C0_SDA */ kPORT_UnlockRegister /* Pin Control Register fields [15:0] are not locked */ }; PORT_SetPinConfig(PORTE, PIN25_IDX, &porte25_pin32_config); /* PORTE25 (pin 32) is configured as I2C0_SDA */ } void BOARD_InitFlexbus(void){ CLOCK_EnableClock(kCLOCK_PortB); /* Port B Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortC); /* Port C Clock Gate Control: Clock enabled */ CLOCK_EnableClock(kCLOCK_PortD); /* Port D Clock Gate Control: Clock enabled */ // Set Flexbus PORT_SetPinMux(PORTD, PIN6_IDX, kPORT_MuxAlt5); /* PORTD6 (pin A2) is configured as FB_AD0 */ PORT_SetPinMux(PORTD, PIN5_IDX, kPORT_MuxAlt5); /* PORTD5 (pin A3) is configured as FB_AD1 */ PORT_SetPinMux(PORTD, PIN4_IDX, kPORT_MuxAlt5); /* PORTD4 (pin A4) is configured as FB_AD2 */ PORT_SetPinMux(PORTD, PIN3_IDX, kPORT_MuxAlt5); /* PORTD3 (pin B4) is configured as FB_AD3 */ PORT_SetPinMux(PORTD, PIN2_IDX, kPORT_MuxAlt5); /* PORTD2 (pin C4) is configured as FB_AD4 */ PORT_SetPinMux(PORTC, PIN10_IDX, kPORT_MuxAlt5); /* PORTC10 (pin C7) is configured as FB_AD5 */ PORT_SetPinMux(PORTC, PIN9_IDX, kPORT_MuxAlt5); /* PORTC9 (pin D7) is configured as FB_AD6 */ PORT_SetPinMux(PORTC, PIN8_IDX, kPORT_MuxAlt5); /* PORTC8 (pin A8) is configured as FB_AD7 */ PORT_SetPinMux(PORTC, PIN7_IDX, kPORT_MuxAlt5); /* PORTC7 (pin B8) is configured as FB_AD8 */ PORT_SetPinMux(PORTC, PIN6_IDX, kPORT_MuxAlt5); /* PORTC6 (pin C8) is configured as FB_AD9 */ PORT_SetPinMux(PORTC, PIN5_IDX, kPORT_MuxAlt5); /* PORTC5 (pin D8) is configured as FB_AD10 */ PORT_SetPinMux(PORTC, PIN4_IDX, kPORT_MuxAlt5); /* PORTC4 (pin A9) is configured as FB_AD11 */ PORT_SetPinMux(PORTC, PIN2_IDX, kPORT_MuxAlt5); /* PORTC2 (pin A12) is configured as FB_AD12 */ PORT_SetPinMux(PORTC, PIN1_IDX, kPORT_MuxAlt5); /* PORTC1 (pin B11) is configured as FB_AD13 */ PORT_SetPinMux(PORTC, PIN0_IDX, kPORT_MuxAlt5); /* PORTC0 (pin B12) is configured as FB_AD14 */ PORT_SetPinMux(PORTB, PIN18_IDX, kPORT_MuxAlt5); /* PORTB18 (pin D12) is configured as FB_AD15 */ PORT_SetPinMux(PORTB, PIN17_IDX, kPORT_MuxAlt5); /* PORTB17 (pin E9) is configured as FB_AD16 */ PORT_SetPinMux(PORTC, PIN11_IDX, kPORT_MuxAlt5); /* PORTC11 (pin B7) is configured as FB_RW_b */ PORT_SetPinMux(PORTB, PIN19_IDX, kPORT_MuxAlt5); /* PORTB19 (pin D11) is configured as FB_OE_b */ PORT_SetPinMux(PORTC, PIN3_IDX, kPORT_MuxAlt5); /* PORTC3 (pin A11) is configured as FB_CLKOUT */ PORT_SetPinMux(PORTD, PIN1_IDX, kPORT_MuxAlt5); /* PORTD1 (pin D4) is configured as FB_CS0_b */ }
Ďalšou z esenciálnych konfigurácií, je nastavenie hodín pre periférie. Hlavným zdrojom je oscilátor v periférii pre fyzickú vrstvu ethernetu 50MHz. Z nej potom PLL blokom generujem hodiny pre jadro 120MHz, pre pamäť 60MHz, Flexbus (Vzhľadom na obmedzenie SSD1289 radiča 25MHz) 15MHz. Zdrojom hodín pre RTC časovač a prevodník snímača tlaku je použitý oscilátor s kryštálom 32,768kHz. Ten funguje aj po vypnutá napájania. Výstup z neho je smerovaný na výstupný pin procesora CLKOUT.