Kdo si postavil bezdrátové bateriové zařízení Warduxere podle našeho seriálu, jistě netrpělivě čeká na návod, jak ho používat.
Pro práci s Warduxere stačí z Internetu stáhnout Arduino IDE, které obsahuje vše potřebné. Stačí stažený archiv rozbalit, není třeba nic instalovat. Kromě všech potřebných komponent Arduino IDE obsahuje i množství příkladů jak pro samostatné Arduino, tak pro běžně dostupné rozšiřující desky (shieldy).
Warduxere má připraven odpor a pájecí plošky pro sběrnici one-wire, odporový dělič pro měření baterie, odpor a pájecí plošky pro analogové čidlo (např. fotorezistor). Další piny procesoru jsem vyvedl na pájecí plošky, aby se k procesoru dala připojit další zařízení a periferie, například různé typy LCD displejů, Ethernet, GSM moduly.
Konkrétní použití bude záviset hlavně na nápadech každého konstruktéra. Dále popíši vlastnosti, kterými se Warduxere odlišuje od Arduina. Před použitím knihoven zmíněných v následujících odstavcích je potřeba je rozbalit do adresáře arduino/libraries/
.
Připojení
Pro propojení s PC je ideální USB-UART převodník, z kterého je zařízení i napájeno. Já používám převodník s čipem čipem CP2102 nebo FTDI 232RL. Čínský CH340 určitě také dobře poslouží.
Po propojení Warduxere s USB převodníkem již není třeba žádná další elektronika a Warduxere pak lze připojit k PC a používat spolu s Arduino IDE. Propojení je na obrázku, je potřeba správně připojit RX převodníku na TX procesoru.
U počítačů jako je Raspberry Pi a Banana Pi R1 jde Warduxere připojit přímo bez jakékoli další elektroniky, protože tyto počítače mají hardwarové sériové linky pracující s napěťovou úrovní 3,3V.
Pro nahrání programu do procesoru ve vývojovém prostředí slouží tlačítko upload. Po kliknutí na něj IDE nejdříve provede reset procesoru, pomocí vývodu DTR (RTS). Po resetu se jako první spustí zavaděč, který chvíli čeká na nahrání programu.
Dioda
Funkčnost zařízení jde jednoduše vyzkoušet blikáním diody. Obvykle bývá dioda na vývodu CPU 17 (označení dle zvyku Arduina je D13), ale tam je připojen wireless modul. Proto u Warduxere je LED připojena na vývodu procesoru 32 (Arduino D2). Použití je zřejmé ze vzorového programu Blink
.
/* Warduxere - Blink Turns on an LED on for one second, then off for one second, repeatedly. This example code is in the public domain. Author: Bc. Josef Jebavý web: http://www.xeres.cz about project: http://multi.xeres.cz/programovani/wireless-arduino-low-power-consumption */ #define PINLED 3 // the setup function runs once when you press reset or power the board void setup() { // initialize digital pin 3 as an output. pinMode(PINLED, OUTPUT); } // the loop function runs over and over again forever void loop() { digitalWrite(PINLED, HIGH); // turn the LED on (HIGH is the voltage level) delay(1000); // wait for a second digitalWrite(PINLED, LOW); // turn the LED off by making the voltage LOW delay(1000); // wait for a second }
Wireless
Možnosti konfigurace bezdrátové komunikace jsou rozsáhlé. Nejpodstatnější je, že komunikace je paketově orientovaná s bufferem 64 bajtů. Rychlost komunikace může být 0,123 až 256 kbps, modulace: FSK, GFSK a OOK. Je možno provozovat i rozsáhlé MESH sítě.
Pro příklad uvádím jen ten nejzákladnější typ komunikace, s kterým jde ověřit funkčnost zařízení. K vyzkoušení potřebuje dva moduly Warduxere a do každého nahraje jeden z programů. Viz níže uvedené vzorové programy Wireless-client a Wireless-server, které jsou i na GitHubu.
Před vyzkoušením programu je potřeba do Arduino IDE doplnit knihovnu RF22.
Klient
/* Warduxere- Wireless client Example of wireles comunication. Tested on Warduxere: Atmega328 and SI4432 This example code is in the public domain. about Warduxere: http://multi.xeres.cz/programovani/wireless-arduino-low-power-consumption */ #include <SPI.h> #include <RH_RF22.h> // Singleton instance of the radio driver RH_RF22 rf22; void setup() { Serial.begin(9600); if (!rf22.init()) Serial.println("init failed"); // Defaults after init are 434.0MHz, 0.05MHz AFC pull-in, modulation FSK_Rb2_4Fd36 } void loop() { Serial.println("Sending to rf22_server"); // Send a message to rf22_server uint8_t data[] = "Hello World!"; rf22.send(data, sizeof(data)); rf22.waitPacketSent(); // Now wait for a reply uint8_t buf[RH_RF22_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (rf22.waitAvailableTimeout(500)) { // Should be a reply message for us now if (rf22.recv(buf, &len)) { Serial.print("got reply: "); Serial.println((char*)buf); } else { Serial.println("recv failed"); } } else { Serial.println("No reply, is rf22_server running?"); } delay(400); }
Server
/* Warduxere - Wireless server Example of wireles comunication. Tested on Warduxere: Atmega328 and SI4432 This example code is in the public domain. about Warduxere: http://multi.xeres.cz/programovani/wireless-arduino-low-power-consumption */ #include <SPI.h> #include <RH_RF22.h> // Singleton instance of the radio driver RH_RF22 rf22; void setup() { Serial.begin(9600); if (!rf22.init()) Serial.println("init failed"); // Defaults after init are 434.0MHz, 0.05MHz AFC pull-in, modulation FSK_Rb2_4Fd36 } void loop() { if (rf22.available()) { // Should be a message for us now uint8_t buf[RH_RF22_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (rf22.recv(buf, &len)) { // RF22::printBuffer("request: ", buf, len); Serial.print("got request: "); Serial.println((char*)buf); // Serial.print("RSSI: "); // Serial.println(rf22.lastRssi(), DEC); // Send a reply uint8_t data[] = "And hello back to you"; rf22.send(data, sizeof(data)); rf22.waitPacketSent(); Serial.println("Sent a reply"); } else { Serial.println("recv failed"); } } }
Další praktické příklady použití wireless čipu SI4432 s knihovnou RadioHead RF22 čtenář najde v dokumentaci wireless knihovny RF22.
Úsporné režimy
Procesor umí několik úsporných režimů. Neúspornější režim procesoru je spánek, pro větší úsporu je potřeba uspat i jednotlivé částí procesoru jako je A/D převodník a vypnout Brown-out Detector (BOD). Často stačí ponechat běžet pouze watchdog, který vygeneruje přerušení pro probuzení. Periferie je potřeba také uspat, zde se jedná pouze o Wireless modul, který se na žádost umí uspat. Při uspávání zařízení je tedy potřeba uspat jak vlastní procesor, tak wireless část. Jednoduchý příklad s uspáním je v programu Sleep:
/* Warduxere - Sleep Example of sleeping and saving power This example code is in the public domain. Author: Bc. Josef Jebavý web: http://www.xeres.cz about project: http://www.multi.xeres.cz/programovani/wireless-arduino-low-power-consumption */ #include <avr/sleep.h> #include <avr/wdt.h> #include <SPI.h> #include <RH_RF22.h> // Singleton instance of the radio driver RH_RF22 rf22; #define LED 3 // watchdog interrupt ISR(WDT_vect) { wdt_disable(); // disable watchdog } void myWatchdogEnable(const byte interval) { // turn off brown-out enable in software MCUCR = bit (BODS) | bit (BODSE); MCUCR = bit (BODS); int previousADCSRA = ADCSRA; ADCSRA &= ~(1<<ADEN); //Disable ADC ACSR = (1<<ACD); //Disable the analog comparator DIDR0 = 0x3F; //Disable digital input buffers on all ADC0-ADC5 pins DIDR1 = (1<<AIN1D)|(1<<AIN0D); //Disable digital input buffer on AIN1/0 //toto nejde zkompilovat pro atmega8 MCUSR = 0; // reset various flags WDTCSR |= 0b00011000; // see docs, set WDCE, WDE WDTCSR = 0b01000000 | interval; // set WDIE, and appropriate delay wdt_reset(); set_sleep_mode (SLEEP_MODE_PWR_DOWN); sleep_mode(); // now goes to Sleep and waits for the interrupt //zapnuti ADC ADCSRA = previousADCSRA; } void setup() { pinMode (LED, OUTPUT); PRR = bit(PRTIM1); // only keep timer 0 going // ADCSRA &= ~ bit(ADEN); // bitSet(PRR, PRADC); rf22.init(); } void loop() { // awake digitalWrite (LED, HIGH); delay (4000); //not sleeping not lihgt digitalWrite (LED, LOW); delay (4000); //blink before sleep digitalWrite (LED, HIGH); delay (200); digitalWrite (LED, LOW); //sleep wireless module rf22.sleep(); // sleep 8 seconds myWatchdogEnable (0b100001); // sleep bit patterns: // 1 second: 0b000110 // 2 seconds: 0b000111 // 4 seconds: 0b100000 // 8 seconds: 0b100001 }
Kdo nechce řešit nastavení uspávání sám, ten může použít knihovnu Low-Power. Příklad uspání zařízení s použití knihovny Low-Power je ve sketchi Sleep2:
/* Warduxere - Sleep Example of sleeping and saving power This example code is in the public domain. Author: Bc. Josef Jebavý web: http://www.xeres.cz about project: http://www.multi.xeres.cz/wireless-arduino-low-power-consumption */ #include <SPI.h> #include <RH_RF22.h> #include "LowPower.h" // Singleton instance of the radio driver RH_RF22 rf22; #define LED 3 void setup() { pinMode (LED, OUTPUT); rf22.init(); } void loop() { // awake digitalWrite (LED, HIGH); delay (4000); //not sleeping not lihgt digitalWrite (LED, LOW); delay (4000); //blink before sleep digitalWrite (LED, HIGH); delay (200); digitalWrite (LED, LOW); //sleep wireless module rf22.sleep(); // sleep 8 seconds LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART0_OFF, TWI_OFF); // myWatchdogEnable (0b100001); // sleep bit patterns: // 1 second: 0b000110 // 2 seconds: 0b000111 // 4 seconds: 0b100000 // 8 seconds: 0b100001 }
Baterie
Stav baterie je zjišťován měřením napětí na děliči 1:1 pomoci analogově digitálního převodníku, který je v CPU. Takto řešeným zapojením se zjišťuje skutečné napětí na baterii. U jiných řešení, jsem se setkal s problémem, kde se napětí baterie měřilo až za 3V stabilizátorem. Takže se nevědělo, jaké je napětí na baterii, což byl problém, obzvláště při použití Li-Pol/Ion baterií. Díky měření napětí na děliči, na který je přímo připojena baterie, je tak možnost připojit například tři články NiMH nebo jeden článek Li-Pol/Ion nebo i jiné typy baterií a úpravou softwaru lze lehce dosáhnout konkrétních potřeb pro hlídání stavu baterie.
Pro přesné měření baterie je potřeba také mít přesný dělič. Základní řady vyráběných odporů mají toleranci ±5%, ale tyto méně přesné odpory mohou udělat značnou chybu v měření. V nejhorším možném případě až ±10%, což by bylo u 4V baterie 0,4 V, a to je opravdu hodně. Pro vyhodnocení stavu baterií typu Li-Pol/Ion je to nepřijatelné. Proto je potřeba použít přesné odpory s tolerancí ± 0,1 % případně ± 0,5 %. Ale není hned nutné kupovat drahé přesné odpory. Pro výrobu několika wireless modulů dostačuje přeměřit odpory a vybrat do páru odpory o stejné hodnotě.
Měření napětí baterie je ve vzorovém programu Battery.
/* Warduxere - Battery Get battery status This example code is in the public domain. Author: Bc. Josef Jebavý web: http://www.xeres.cz about project: http://multi.xeres.cz/programovani/wireless-arduino-low-power-consumption */ #define PINBAT A1 // the setup routine runs once when you press reset: void setup() { Serial.begin(9600); pinMode(PINBAT, INPUT); } // the loop routine runs over and over again forever: void loop() { //mereni baterie int sensorValue=analogRead(PINBAT); byte bat=0; // na LDO je ubytek napeti 0.178V takze pod 3.478V na baterii uz procesor a ADC bude napajen mene jak 3.3V // pro 3.3V arduino a delic 1:1 bude cislo odpovidat napeti na baterii: // 528 - 3.40V // 539 - 3.478V - hranice pro spravne napajeni // 550 - 3.544 // 559 - 3.60V - hranice pro li-pol/ion baterii if ( sensorValue>558) { bat=1; } Serial.print("battery:"); Serial.print(bat); Serial.print(";value:"); Serial.print(sensorValue); Serial.print(";V:"); double d =3.3/1024*sensorValue*2; Serial.print(d,4); Serial.println(); delay(1000); }
Závěr
Vyzkoušet všechny příklady lze lehce, pokud máte doma Arduino Pro Mini 3,3V 8MHz nebo mikroprocesor Atmega 328P a připojíte Wireless modul DRF4432F20, případně i jiný s čipem SI4432. Vše se dá vyzkoušet s pár součástkami, které zapojíte podle schématu. Jen nesmíte očekávat malou spotřebu zařízení.
Čistokrevní programátoři, kteří si nedokázali poradit s návrhem hardwaru, doposud jen hledali úsporné bateriově napájené bezdrátové zařízení. Nyní mají konečně možnost začít vytvářet programy pro bezdrátové sítě.