Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
| Obě strany předchozí revize Předchozí verze Následující verze | Předchozí verze | ||
|
2017:greenhouse-ctrl [2018/01/14 23:17] Josef Křivský |
2017:greenhouse-ctrl [2018/01/15 07:28] (aktuální) Josef Křivský |
||
|---|---|---|---|
| Řádek 8: | Řádek 8: | ||
| Cílem tohoto projektu je co nejvíce automatizovat obsluhu a udržování běžného zahradního skleníku. Obsahem návrhu je kompletní software řízení a obsluhy, ale také co nejjednodušší hardware pro příslušné periferie. Základní myšlenkou je možnost kontroly a nastavení jednotlivých vlastností skleníku z pohodlí domova, za pomoci ethernetového rozhraní a běžného PC. Pomocí definovaných příkazů je tak možné jak kontrolovat vlhkost půdy, teplotu a osvětlení ve skleníku, tak nastavit jejich limitní hodnoty pro spuštění zavlažování, odvětrávání/vytápění skleníku a přisvětlení zářivkami. | Cílem tohoto projektu je co nejvíce automatizovat obsluhu a udržování běžného zahradního skleníku. Obsahem návrhu je kompletní software řízení a obsluhy, ale také co nejjednodušší hardware pro příslušné periferie. Základní myšlenkou je možnost kontroly a nastavení jednotlivých vlastností skleníku z pohodlí domova, za pomoci ethernetového rozhraní a běžného PC. Pomocí definovaných příkazů je tak možné jak kontrolovat vlhkost půdy, teplotu a osvětlení ve skleníku, tak nastavit jejich limitní hodnoty pro spuštění zavlažování, odvětrávání/vytápění skleníku a přisvětlení zářivkami. | ||
| + | |||
| + | {{ :2017:xkrivs00:img_20180115_063847_7.jpg?400 |}} | ||
| + | |||
| ---- | ---- | ||
| Řádek 15: | Řádek 18: | ||
| + | Key Features | ||
| + | *Microcontroller: | ||
| + | *Kinetis MK64FN1M0VLL12 in 100LQFP microcontroller featuring ARM® Cortex™-M4 32-bit core with DSP instructions and Floating Point Unit (FPU) working @ 120 MHz max CPU frequency | ||
| + | *Memory: | ||
| + | *1024 KB program flash memory, 256 KB RAM, and FlexBus external bus interface | ||
| + | *System peripherals: | ||
| + | *Multiple low-power modes, low-leakage wake-up unit, 16-channel DMA controller | ||
| + | *Clocks: | ||
| + | *3x Internal Reference Clocks: 32KHz, 4MHz and 48MHz, 2x Crystal inputs: 3-32MHz (XTAL0) and 32kHz (XTAL32/RTC), PLL and FL | ||
| + | *Analog modules: | ||
| + | *2x 16-bit SAR ADCs up 800ksps (12-bit mode), 2x 12-bit DACs, 3x Analog comparators, Voltage reference 1.13V | ||
| + | *Communication interfaces: | ||
| + | *1x 10/100 Mbit/s Ethernet MAC controller with MII/RMII interface IEEE1588 capable, 1x USB 2.0 Full-/Low-Speed Device/Host/OTG controller with embedded 3.3V/120mA Vreg, and USB device Crystal-less operation, 1x Controller Area Network (CAN) module, 3x SPI modules, 3x I2C modules. Support for up to 1 Mbit/s, 6x UART modules, 1x Secure Digital Host Controller (SDHC), 1x I2S module | ||
| + | *Timers: | ||
| + | *2x 8-channel Flex-Timers (PWM/Motor control), 2x 2-channel FlexTimers (PWM/Quad decoder), 32-bit PITs and 16 bit low-power timers, Real-Time Clock (RTC), Programmable delay block | ||
| + | *Security and integrity modules: | ||
| + | *Hardware CRC and random-number generator modules, Hardware encryption supporting DES, 3DES, AES, MD5, SHA-1 and SHA-256 algorithms | ||
| + | *Operating characteristics: | ||
| + | *Voltage range: 1.71 to 3.6 V, Flash write voltage range: 1.71 to 3.6 V | ||
| + | ---- | ||
| - | Key Features | + | ====== Vývoj HW ====== |
| - | Microcontroller: | + | |
| - | Kinetis MK64FN1M0VLL12 in 100LQFP microcontroller featuring ARM® Cortex™-M4 32-bit core with DSP instructions | + | Požadavkem na celou konstrukci automatizovaného skleníku byla především jednoduchost implementace/instalace, ale také cena celého systému. Vzhledem k velkému možství některých součástek v inventáři zadavatele, byly proto použity především ony. |
| - | and Floating Point Unit (FPU) working @ 120 MHz max CPU frequency | + | |
| - | Memory: | + | Seznam použitých komponetů: |
| - | 1024 KB program flash memory, 256 KB RAM, and FlexBus external bus interface | + | * Mikrokontrolér FRDM-K64F |
| - | System peripherals: | + | * Servo Hitec HS-485HB |
| - | Multiple low-power modes, low-leakage wake-up unit, 16-channel DMA controller | + | * NTC Termistor Eclipsera 1488979094 |
| - | Clocks: | + | * Arduino modul pro měření intenzity světla BH1750 |
| - | 3x Internal Reference Clocks: 32KHz, 4MHz and 48MHz, 2x Crystal inputs: 3-32MHz (XTAL0) and 32kHz (XTAL32/RTC), | + | * Půdní Vlhkoměr Modul pro Arduino |
| - | PLL and FL | + | |
| - | Analog modules: | + | Odkazy na stránky výrobců/prodejců: |
| - | 2x 16-bit SAR ADCs up 800ksps (12-bit mode), 2x 12-bit DACs, 3x Analog comparators, Voltage reference 1.13V | + | |
| - | Communication interfaces: | + | *http://hitecrcd.com/products/servos/sport-servos/analog-sport-servos/hs-485hb-deluxe-hd-ball-bearing-servo/product |
| - | 1x 10/100 Mbit/s Ethernet MAC controller with MII/RMII interface IEEE1588 capable, 1x USB 2.0 Full-/Low-Speed | + | *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 |
| - | Device/Host/OTG controller with embedded 3.3V/120mA Vreg, and USB device Crystal-less operation, 1x Controller | + | *https://arduino-shop.cz/arduino/1574-ntc-termistor-10k-1-3950-1m-vodotesna-sonda-1488979094.html |
| - | Area Network (CAN) module, 3x SPI modules, 3x I2C modules. Support for up to 1 Mbit/s, 6x UART modules, 1x | + | *https://arduino-shop.cz/arduino/902-arduino-mereni-intenzity-svetla-1420672425.html |
| - | Secure Digital Host Controller (SDHC), 1x I2S module | + | *https://arduino-shop.cz/arduino/1399-pudni-vlhkomer-modul-pro-arduino-1474354607.html |
| - | Timers: | + | |
| - | 2x 8-channel Flex-Timers (PWM/Motor control), 2x 2-channel FlexTimers (PWM/Quad decoder), 32-bit PITs and 16 | + | |
| - | bit low-power timers, Real-Time Clock (RTC), Programmable delay block | + | |
| - | Security and integrity modules: | + | |
| - | Hardware CRC and random-number generator modules, Hardware encryption supporting DES, 3DES, AES, MD5, SHA-1 and | + | |
| - | SHA-256 algorithms | + | |
| - | Operating characteristics: | + | |
| - | Voltage range: 1.71 to 3.6 V, Flash write voltage range: 1.71 to 3.6 V | + | |
| ---- | ---- | ||
| Řádek 48: | Řádek 63: | ||
| ====== Software ====== | ====== Software ====== | ||
| - | V hlavním souboru main.c probíha inicializace ADC převodníku, USB device audio class a audio kodeku pro přehrávání audio výstupu. | + | V hlavním souboru main.cpp probíhá inicializace celého programu pomocí jednotlivých knihoven. Pro celý program byly použity veřejně dostupné knihovny mbed(Rev. 109), mbed-rtos(Rev. 95), EthernetInterface(Rev. 49) a také knihovna BH1750 dostupná na stránce https://os.mbed.com/users/vrabec/code/BH1750/ , kterou však bylo z důvodu jednoduchosti použití třeba značně modifikovat. Pro ostatní periferie byla vytvořena nová c++ knihovna Peripherals, která zahrnuje patřičnou inicializaci periferií (analogové vstupy, digitální a PWM výstupy, ...) a následně práci s nimi. |
| Použité knihovny v soubotu main.c | Použité knihovny v soubotu main.c | ||
| + | * #include "mbed.h" | ||
| + | * #include "rtos.h" | ||
| + | * #include "EthernetInterface.h" | ||
| + | * #include "BH1750.h" | ||
| + | * #include "Peripherals.h" | ||
| + | |||
| + | === Knihovna Peripherals === | ||
| + | Zapouzdřuje do tříd veškeré vlastnosti pro snímání vlhkosti a teploty, a ovládání akčních členů (servomotorem řízené otevírání ventilace a reléově ovládané zavlažování/ventilace/topení). Skládá se z | ||
| + | |||
| + | Peripherals.h: | ||
| + | <code c> | ||
| + | class Humid | ||
| + | { | ||
| + | public: | ||
| + | Humid(PinName AInp = A0, PinName AOut = D0); | ||
| + | uint8_t readHumidity(void); | ||
| + | void setLimit(uint8_t lim); | ||
| + | void setCurrentLimit(void); | ||
| + | uint8_t getLimit(void); | ||
| + | |||
| + | private: | ||
| + | AnalogIn ain; | ||
| + | DigitalOut dop; | ||
| + | uint8_t Limit; | ||
| + | }; | ||
| + | |||
| + | class Temp | ||
| + | { | ||
| + | public: | ||
| + | Temp(PinName AInp = A1); | ||
| + | float readTemperature(void); | ||
| + | void setHighLimit(float lim); | ||
| + | void setLowLimit(float lim); | ||
| + | void setVentLimit(float lim); | ||
| + | void setCurrentHighLimit(void); | ||
| + | void setCurrentLowLimit(void); | ||
| + | void setCurrentVentLimit(void); | ||
| + | float getHighLimit(void); | ||
| + | float getLowLimit(void); | ||
| + | float getVentLimit(void); | ||
| + | |||
| + | private: | ||
| + | AnalogIn ain; | ||
| + | float HLimit, LLimit, VLimit; | ||
| + | }; | ||
| + | |||
| + | class Vent | ||
| + | { | ||
| + | public: | ||
| + | Vent(PinName PWM = D9); | ||
| + | void open(uint8_t percent = 100); | ||
| + | void close(void); | ||
| + | | ||
| + | private: | ||
| + | PwmOut pwm; | ||
| + | uint8_t percentage; | ||
| + | }; | ||
| + | |||
| + | class Fan | ||
| + | { | ||
| + | public: | ||
| + | Fan(PinName DOut = D4); | ||
| + | void Start(void); | ||
| + | void Stop(void); | ||
| + | private: | ||
| + | DigitalOut fan; | ||
| + | }; | ||
| + | |||
| + | class Heat | ||
| + | { | ||
| + | public: | ||
| + | Heat(PinName DOut = D5); | ||
| + | void Start(void); | ||
| + | void Stop(void); | ||
| + | private: | ||
| + | DigitalOut heater; | ||
| + | }; | ||
| + | |||
| + | class Water | ||
| + | { | ||
| + | public: | ||
| + | Water(PinName DOut = D6); | ||
| + | void Start(void); | ||
| + | void Stop(void); | ||
| + | private: | ||
| + | DigitalOut sprinkler; | ||
| + | }; | ||
| + | |||
| + | class Light | ||
| + | { | ||
| + | public: | ||
| + | Light(PinName DOut = D7); | ||
| + | void Start(void); | ||
| + | void Stop(void); | ||
| + | private: | ||
| + | DigitalOut lighting; | ||
| + | }; | ||
| + | </code> | ||
| + | |||
| + | Peripherals.cpp: | ||
| + | |||
| + | <code c> | ||
| + | Humid::Humid(PinName AInp, PinName AOut):ain(AInp),dop(AOut) | ||
| + | { | ||
| + | Limit = 110; | ||
| + | dop = 0; | ||
| + | } | ||
| + | |||
| + | uint8_t Humid::readHumidity(void) | ||
| + | { | ||
| + | dop = 1; | ||
| + | wait_ms(10); | ||
| + | double humidity = 1-ain.read(); | ||
| + | humidity = ((humidity*100)-7)*1.471; | ||
| + | uint8_t hum = humidity; | ||
| + | dop = 0; | ||
| + | return hum; | ||
| + | } | ||
| + | |||
| + | void Humid::setLimit(uint8_t lim) | ||
| + | { | ||
| + | Limit = lim; | ||
| + | } | ||
| + | |||
| + | void Humid::setCurrentLimit(void) | ||
| + | { | ||
| + | uint8_t humidity = readHumidity(); | ||
| + | setLimit(humidity); | ||
| + | } | ||
| + | |||
| + | uint8_t Humid::getLimit(void) | ||
| + | { | ||
| + | return Limit; | ||
| + | } | ||
| + | |||
| + | Temp::Temp(PinName AInp):ain(AInp) | ||
| + | { | ||
| + | LLimit = -30; | ||
| + | HLimit = 125; | ||
| + | VLimit = 125; | ||
| + | } | ||
| + | |||
| + | float Temp::readTemperature(void) | ||
| + | { | ||
| + | double voltage, resistance, temperature; | ||
| + | float temp; | ||
| + | int resistor = 9910; | ||
| + | int thermistor = 10000; | ||
| + | int refTemp = 25; | ||
| + | int beta = 3380; | ||
| + | | ||
| + | voltage = (ain.read())*3.3; | ||
| + | | ||
| + | resistance = (voltage*resistor)/(3.3-voltage); | ||
| + | | ||
| + | temperature = (log(resistance/thermistor))/beta; | ||
| + | temperature += 1.0 / (refTemp + 273.15); | ||
| + | temperature = 1.0 / temperature; | ||
| + | temperature -= 273.15; | ||
| + | | ||
| + | temp = temperature; | ||
| + | | ||
| + | return temp; | ||
| + | } | ||
| + | |||
| + | void Temp::setHighLimit(float lim) | ||
| + | { | ||
| + | HLimit = lim; | ||
| + | } | ||
| + | |||
| + | void Temp::setLowLimit(float lim) | ||
| + | { | ||
| + | LLimit = lim; | ||
| + | } | ||
| + | |||
| + | void Temp::setVentLimit(float lim) | ||
| + | { | ||
| + | LLimit = lim; | ||
| + | } | ||
| + | |||
| + | void Temp::setCurrentHighLimit(void) | ||
| + | { | ||
| + | float temperature = readTemperature(); | ||
| + | setHighLimit(temperature); | ||
| + | } | ||
| + | void Temp::setCurrentLowLimit(void) | ||
| + | { | ||
| + | float temperature = readTemperature(); | ||
| + | setLowLimit(temperature); | ||
| + | } | ||
| + | |||
| + | void Temp::setCurrentVentLimit(void) | ||
| + | { | ||
| + | float temperature = readTemperature(); | ||
| + | setVentLimit(temperature); | ||
| + | } | ||
| + | |||
| + | float Temp::getHighLimit(void) | ||
| + | { | ||
| + | return HLimit; | ||
| + | } | ||
| + | |||
| + | float Temp::getLowLimit(void) | ||
| + | { | ||
| + | return LLimit; | ||
| + | } | ||
| + | |||
| + | float Temp::getVentLimit(void) | ||
| + | { | ||
| + | return VLimit; | ||
| + | } | ||
| + | |||
| + | |||
| + | Vent::Vent(PinName PWM):pwm(PWM) | ||
| + | { | ||
| + | pwm.period(0.020); | ||
| + | pwm.pulsewidth(0.0009); | ||
| + | percentage = 0; | ||
| + | } | ||
| + | |||
| + | void Vent::open(uint8_t percent) | ||
| + | { | ||
| + | |||
| + | uint16_t width = ((6 * percentage)+900); | ||
| + | | ||
| + | while(width != (6*percent)+900) | ||
| + | { | ||
| + | if(percentage>percent) | ||
| + | { | ||
| + | width-=1; | ||
| + | pwm.pulsewidth_us(width); | ||
| + | wait_ms(10); | ||
| + | } | ||
| + | else | ||
| + | { | ||
| + | width+=1; | ||
| + | pwm.pulsewidth_us(width); | ||
| + | wait_ms(10); | ||
| + | } | ||
| + | } | ||
| + | percentage = percent; | ||
| + | } | ||
| + | |||
| + | void Vent::close(void) | ||
| + | { | ||
| + | open(0); | ||
| + | } | ||
| + | |||
| + | |||
| + | Fan::Fan(PinName DOut):fan(DOut) | ||
| + | { | ||
| + | fan = 0; | ||
| + | } | ||
| + | |||
| + | void Fan::Start(void) | ||
| + | { | ||
| + | fan = 1; | ||
| + | } | ||
| + | | ||
| + | void Fan::Stop(void) | ||
| + | { | ||
| + | fan = 0; | ||
| + | } | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | </code> | ||
| + | Za zmínku stojí především třídy Humid a Temp, které nejen zapouzdřují různé proměnné a vstupy, ale také nad nimi provádějí řadu výpočtů. U třídy Humid se jedná pouze o úpravu snímaného napětí ze zesilovače a měření v pulzním režimu (z důvodu elektrolýzy na elektrodách snímače vlhkosti). Třída Temp však již provádí poměrně složité výpočty při převodu snímaného napětí z děliče (tvořen rezistorem a NTC termistorem) na hodnotu okolní teploty. Veškeré další třídy jsou v této knihovně již pouze kopie třídy Fan, které slouží k ovládání reléových výstupů, a které mají jen rozdílné názvy a výstupní piny na desce FRDM-K64F. | ||
| + | |||
| + | |||
| + | === hlavní soubor main.h === | ||
| + | |||
| + | Soubor main.cpp lze rozdělit do několika částí: | ||
| + | * Inicializace (zde probíhá pouze inicializace jednotlivých tříd pro příslušné periferie) | ||
| + | <code c> | ||
| + | #define ECHO_SERVER_PORT 23 | ||
| + | |||
| + | BH1750 light(I2C_SDA, I2C_SCL); // Senzor osvětlení | ||
| + | Humid humidity; // Senzor vlhkosti | ||
| + | Temp temperature; // Snímač teploty | ||
| + | Vent ventilation; // Otevírání ventilace | ||
| + | Fan conditioning; // Ovládání aktivního větrání | ||
| + | Heat heating; // Ovládání topení | ||
| + | Water irrigation; // Spouštění zavlažování | ||
| + | Light illumination; // Ovládání světel | ||
| + | |||
| + | enum STAT // Proměnná pro uložení stavu celého systému | ||
| + | { | ||
| + | READY = 1, SETTINGS, MANUAL, ERROR | ||
| + | }sklenikstav; | ||
| + | </code> | ||
| + | Stav systému sklenikstav je díky třídám pouze pomocnou proměnnou pro rozhodovací stromy uživatelského rozhraní. | ||
| + | |||
| + | * Ovládací vlákna RTOS (zde již probíhá periodická kontrola stavu skleníku, a příslušné reakce periferií) | ||
| + | <code c> | ||
| + | void watering_thread(void) | ||
| + | { | ||
| + | while(true) | ||
| + | { | ||
| + | uint8_t hum = humidity.readHumidity(); | ||
| + | float avghum = 0; | ||
| + | if(hum < humidity.getLimit()) | ||
| + | { | ||
| + | for(int i=0; i<6; i++) | ||
| + | { | ||
| + | avghum += humidity.readHumidity(); | ||
| + | } | ||
| + | | ||
| + | avghum /= 6; | ||
| + | | ||
| + | if(avghum < humidity.getLimit()) | ||
| + | { | ||
| + | irrigation.Start(); | ||
| + | Thread::wait(180000); | ||
| + | irrigation.Stop(); | ||
| + | } | ||
| + | avghum = 0; | ||
| + | } | ||
| + | Thread::wait(900000); | ||
| + | } | ||
| + | } | ||
| - | * #include "stm32f4xx_hal.h" | + | void venting_thread() |
| - | * #include "usb_device.h" | + | { |
| - | * #include "stm32f4xx_hal_adc.h" | + | while(true) |
| - | * #include "cs43l22.h" | + | { |
| - | * #include "stm32f4_discovery_audio.h" | + | uint8_t temp = temperature.readTemperature(); |
| + | float avgtemp = 0; | ||
| + | |||
| + | if(temp > temperature.getVentLimit()) | ||
| + | { | ||
| + | for(int i=0; i<6; i++) | ||
| + | { | ||
| + | avgtemp += temperature.readTemperature(); | ||
| + | } | ||
| + | |||
| + | avgtemp /= 6; | ||
| + | |||
| + | if(avgtemp > temperature.getVentLimit()) | ||
| + | { | ||
| + | ventilation.open(); | ||
| + | conditioning.Start(); | ||
| + | heating.Stop(); | ||
| + | } | ||
| + | avgtemp = 0; | ||
| + | } | ||
| + | |||
| + | else if(temp > temperature.getHighLimit()) | ||
| + | { | ||
| + | for(int i=0; i<6; i++) | ||
| + | { | ||
| + | avgtemp += temperature.readTemperature(); | ||
| + | } | ||
| + | |||
| + | avgtemp /= 6; | ||
| + | |||
| + | if(avgtemp > temperature.getHighLimit()) | ||
| + | { | ||
| + | ventilation.open(); | ||
| + | conditioning.Stop(); | ||
| + | heating.Stop(); | ||
| + | } | ||
| + | avgtemp = 0; | ||
| + | } | ||
| + | |||
| + | else if(temp < temperature.getLowLimit()) | ||
| + | { | ||
| + | for(int i=0; i<6; i++) | ||
| + | { | ||
| + | avgtemp += temperature.readTemperature(); | ||
| + | } | ||
| + | |||
| + | avgtemp /= 6; | ||
| + | |||
| + | if(avgtemp < temperature.getLowLimit()) | ||
| + | { | ||
| + | ventilation.close(); | ||
| + | conditioning.Stop(); | ||
| + | heating.Start(); | ||
| + | } | ||
| + | avgtemp = 0; | ||
| + | } | ||
| + | |||
| + | else | ||
| + | { | ||
| + | ventilation.close(); | ||
| + | conditioning.Stop(); | ||
| + | heating.Stop(); | ||
| + | } | ||
| + | |||
| + | Thread::wait(100000); | ||
| + | } | ||
| + | } | ||
| + | void lighting_thread() | ||
| + | { | ||
| + | uint16_t lx[6]; | ||
| + | for(int i=0; i<6; i++) | ||
| + | { | ||
| + | lx[i] = light.singleMeas(); | ||
| + | } | ||
| + | | ||
| + | while(true) | ||
| + | { | ||
| + | uint16_t avglx = 0; | ||
| + | | ||
| + | for(int i=0; i<5; i++) | ||
| + | { | ||
| + | lx[i] = lx[i+1]; | ||
| + | } | ||
| + | lx[5] = light.singleMeas(); | ||
| + | | ||
| + | for(int i=0; i<6; i++) | ||
| + | { | ||
| + | avglx += lx[i]; | ||
| + | } | ||
| + | avglx /= 6; | ||
| + | | ||
| + | if(avglx<light.getLimit()) | ||
| + | { | ||
| + | illumination.Start(); | ||
| + | } | ||
| + | | ||
| + | else | ||
| + | { | ||
| + | illumination.Stop(); | ||
| + | } | ||
| + | | ||
| + | Thread::wait(300000); | ||
| + | } | ||
| + | } | ||
| + | </code> | ||
| + | Tato vlákna mají zajišťovat plnou automatičnost skleníku po jeho prvotním nastavení. Bohužel se díky problémům s různými verzemi systému MBED a jeho knihoven nepodařilo (díky nedostatku času) najednou zprovoznit vlákna a ovládání skleníku přes ethernetové rozhraní. Ačkoliv RTOS sám o sobě funguje, nebylo by možné nastavovat skleník on-line, čímž bychom přišli o jakoukoliv možnost okamžitého zásahu, a zároveň by nebyla splněna nejdůležitější část zadání. | ||
| - | assert_param(IS_ADC_CHANNEL(sConfig->ADC_CHANNEL_1)); | + | * Funkce rozhodovacího stromu pro Ethernetové rozhraní skleníku (přímé ovládání) |
| - | hadc->Instance->SMPR2 &= ~ADC_SMPR2(ADC_SMPR2_SMP0, sConfig->Channel); | + | <code c> |
| - | hadc->Instance->SMPR2 |= ADC_SMPR2(sConfig->SamplingTime, sConfig->Channel); | + | int evaluate(char *str) |
| - | void ADC_Init(hadc); | + | { |
| - | cs43l22_Init(29, OUTPUT_DEVICE_SPEAKER, 60, AUDIO_FREQUENCY_48K); | + | switch(sklenikstav) |
| + | { | ||
| + | case READY: | ||
| + | if (strcmp(str, "help") == 0) | ||
| + | { | ||
| + | return 1; | ||
| + | } | ||
| + | else if (strcmp(str, "stav") == 0) | ||
| + | { | ||
| + | return 2; | ||
| + | } | ||
| + | else if (strcmp(str, "set") == 0) | ||
| + | { | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | int main(void) | ||
| + | { | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | int x = evaluate(message); | ||
| + | if(sklenikstav == READY) | ||
| + | { | ||
| + | if (x == 0) | ||
| + | { | ||
| + | client.send_all("Neplatny prikaz!\r\n", 18); | ||
| + | client.send_all(commandwait, sizeof(commandwait)); | ||
| + | } | ||
| + | else if (x == 1) | ||
| + | { | ||
| + | char helpmsg[] = "stav\t\t-Zobrazeni aktualnich informaci\r\nset\t\t-Nastaveni skleniku\r\nman\t\t-Ovladani skleniku\r\nexit/quit\t-Konec\r\n"; | ||
| + | client.send_all(helpmsg, sizeof(helpmsg)); | ||
| + | client.send_all(commandwait, sizeof(commandwait)); | ||
| + | number = 0; | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | } | ||
| + | </code> | ||
| + | Jak lze vidět, jedna z těchto funkcí se nachází ve funkci main, a druhá je pouze jako pomoc při určování obdržených řetězců. V závislosti na obdrženém textu pak tyto funkce přepínají jak stavy systému (pouze pro potřeby komunikace s uživatelem), tak výstupy mikrokontroléru. Tyto funkce jsou obdobou absolvovaného cvičení č.5, pouze značně složitější, a proto je tu nebudu uvádět celé. Uvedu pouze stavy systému a jejich akceptované příkazy. | ||
| + | === Celý kód === | ||
| - | Nejprve je inicializován AD převodník a přiřazeným kanálem číslo jedna, který odpovídá převodníku ADC1. Na tento převodník je přivedeno napětí z potenciometru, který ovládá Volume přehrávání audio výstupu. Následně jsou přiřazeny patřičné parametry a vzorkovací frekvence. | + | https://os.mbed.com/users/civava/code/sklenik-2017/ |
| - | Dále je inicializován audio kodek, kde je přižen výstupní pin na Jack 3.5 mm, zvolen typ výstupního zařízení, počáteční hlasitost v procentech a vrozkovací frekvence na 48 kHz. Stejná je vzorkovací frekvence AD převodníku a rychlost přenosu po USB. | ||