Projekt od našeho čtenáře Jakuba J. - Arduino ako I2C A/D prevodník:
Samotné Arduino obsahuje 8 kanálový 10 bitový (0-1023) A/D prevodník. Problém nastáva, keď potrebujeme merať viac analógových veličín. Môžeme použiť 16 kanálový analógový multiplexer CD74HC4067, ale tento potrebuje celkom 1 analógový a 4 digitálne piny na Arduine, čo môže byť problém.
K Arduinu tiež môžeme pripojiť neobmedzené množstvo zariadení cez zbernicu I2C. Ako prevodníky môžeme použiť aj 4 kanálový A/D prevodník pre I2C PCF8591, ktorý má ale relatívne nízke rozlíšenie – 8 bitov (0-255), čo môže byť v niektorých prípadoch nepoužiteľné.
Preto sa naskytá toto zaujímavé úsporné riešenie: Ako A/D prevodník použijeme ďalšie Arduino (napríklad malé Nano), komunikujúce s hlavným cez I2C. Po prepojení cez I2C nám zostane ešte 6 voľných analógových pinov, a všetky digitálne. V prípade takéhoto zapojenia môžeme používať až 3 multiplexery CD74HC4067 na každom ďalšom Arduine, čo rozširuje počet analógových pinov až na 48 pre každé ďalšie Arduino.
Zapojenie je jednoduché, obe Arduiná pripojíme k napájaniu, a navzájom prepojíme piny GND, A4 a A5 (pre I2C komunikáciu).
V programoch nie je použitý multiplexer, iba fotorezistor na pine A0.
V programe pre hlavné Arduino – master budeme posielať Arduinu Nano čísla vstupov, z ktorých nám má poslať hodnotu.
//master #include <Wire.h> const int pin = A0; void setup() { Wire.begin(); //spustenie komunikacie I2C Serial.begin(9600); } void loop() { Wire.beginTransmission(4); //spustenie prenosu so zariadenim 4 Wire.write(pin); //odoslanie cisla pinu, z ktoreho chceme citat delay(10); int x = Wire.read(); Serial.print("Namerana analogova hodnota: "); Serial.println(x); Wire.endTransmission(); //ukoncenie prenosu delay(5000); }
V programe pre Arduio slave najprv určíme adresu, pod ktorou bude komunikovať a potom už len čaká na číslo pinu, z ktorého hodnotu má poslať späť.
//prevodnik - slave #include <Wire.h> void setup() { Wire.begin(4); //spustenie I2C komunikacie ako zariadenie 4 } void loop() { Wire.onReceive(prijate); //pri prijate } void prijate(int howMany) { while (1 < Wire.available()) { //citanie dat int pin = Wire.read(); //prijatie cisla analogoveho pinu int x = analogRead(pin); //precitanie hodnoty Wire.write(x); //poslanie analogovej hodnoty } }
Knižnica Wire.h je obsiahnutá v Arduino IDE.