Tartalomjegyzék:

Going Beyond StandardFirmata - Újra megtekintve: 5 lépés
Going Beyond StandardFirmata - Újra megtekintve: 5 lépés

Videó: Going Beyond StandardFirmata - Újra megtekintve: 5 lépés

Videó: Going Beyond StandardFirmata - Újra megtekintve: 5 lépés
Videó: Riden RD6018 Programmable 60V 18A 1080W Buck Converter | WattHour 2024, Július
Anonim
Going Beyond StandardFirmata - Újra megtekintve
Going Beyond StandardFirmata - Újra megtekintve

Röviddel ezelőtt Dr. Martyn Wheeler, a pymata4 felhasználója megkeresett, hogy útmutatást adjak a DHT22 páratartalom/hőmérséklet érzékelő támogatásának hozzáadásához a pymata4 könyvtárhoz. A pymata4 könyvtár az Arduino megfelelőjével, a FirmataExpress -szel együtt lehetővé teszi a felhasználók számára, hogy távolról vezéreljék és felügyeljék Arduino eszközeiket. Az e -mailek cseréjének néhány fordulóján belül Dr. Wheeler sikeresen módosította a pymata4 -et és a FirmataExpress -t. Ennek eredményeképpen a DHT22 és DHT11 érzékelők támogatása a pymata4 és a FirmataExpress szabványos része.

2014 májusában írtam egy cikket a Firmata támogatásának hozzáadásáról további eszközökhöz. Erre a cikkemre gondolva rájöttem, hogy mennyit változott azóta, hogy tollhoz papírt készítettem ehhez a cikkhez. Ezen a cikken kívül Dr. Wheeler dokumentálta erőfeszítéseit, és érdemes ezt is megnézni.

A FirmataExpress a StandardFirmata alapú, és a StandardFirmata könyvtárszerkezet fejlődött. Ezenkívül a pymata4 API is kissé eltér a 2014 -es eredeti PyMata API -tól. Úgy gondoltam, hogy ez a tökéletes alkalom a cikk újbóli megtekintésére és frissítésére. Dr. Wheeler munkáját alapul véve vizsgáljuk meg, hogyan lehet kiterjeszteni a pymata4/FirmataExpress funkciót.

Mielőtt elkezdenénk - Néhány háttérinformáció az Arduino/Firmata -ról

Tehát mi az a Firmata? A Firmata weboldalról idézve: "A Firmata egy általános protokoll a mikrokontrollerekkel való kommunikációhoz a gazdagép számítógépes szoftveréből."

Az Arduino Firmata soros interfészt használ a parancs- és jelentésadatok átviteléhez az Arduino mikrokontroller és a számítógép között, általában 57600 bps sebességű soros/USB -kapcsolat használatával. A hivatkozáson keresztül továbbított adatok binárisak, és a protokoll kliens/szerver modellben valósul meg.

A szerver oldalt feltöltik egy Arduino mikrokontrollerbe Arduino vázlat formájában. Az Arduino IDE -hez mellékelt StandardFirmata vázlat vezérli az Arduino I/O csapokat, az ügyfél utasítása szerint. Ezenkívül a bemeneti érintkezési változásokról és egyéb jelentési információkról is beszámol az ügyfélnek. A FirmataExpress a StandardFirmata kiterjesztett változata. 115200 bps soros kapcsolat sebességgel fut.

A cikkhez használt Arduino kliens a pymata4. Ez egy Python alkalmazás, amelyet PC -n hajtanak végre. Mind parancsokat küld, mind jelentéseket fogad az Arduino szerverről. Mivel a pymata4 a Pythonban van megvalósítva, Windows, Linux (beleértve a Raspberry Pi) és macOS számítógépeken is fut.

Miért használja a Firmata -t?

Az Arduino mikrokontrollerek csodálatos kis eszközök, de a processzor és a memória erőforrásai némileg korlátozottak. Azokban az alkalmazásokban, amelyek processzor- vagy memóriaigényesek, gyakran nincs más választás, mint az erőforrásigényt a számítógépre lerakni, hogy az alkalmazás sikeres legyen.

De nem ez az egyetlen oka a StandardFirmata használatának. Könnyebb súlyú Arduino alkalmazások fejlesztésekor a számítógép olyan eszközöket és hibakeresési lehetőségeket biztosíthat, amelyek közvetlenül nem érhetők el az Arduino mikrovezérlőn. A "rögzített" kliens és szerver használata segít az alkalmazás összetettségének korlátozásában egy PC -vel, amely könnyebben kezelhető. Az alkalmazás tökéletesítése után lefordítható egyéni, önálló Arduino -vázlatra.

Miért érdemes használni a pymata4 -et?

A szerzőjeként természetesen elfogult vagyok. Ennek ellenére ez az egyetlen Python-alapú Firmata kliens, amelyet folyamatosan karbantartottak az elmúlt években. Intuitív és könnyen használható API -t biztosít. A StandardFirmata alapú vázlatok mellett támogatja a Firmata WiFi-n keresztüli használatát az olyan eszközökhöz, mint az ESP-8266, amikor a StandardFirmataWifI vázlatot használja.

Ezenkívül a pymata4 -et úgy tervezték, hogy a felhasználó könnyen kibővítse további érzékelőket és működtetőket, amelyeket a StandardFirmata jelenleg nem támogat.

1. lépés: A Firmata protokoll megértése

A Firmata protokoll megértése
A Firmata protokoll megértése

Az Arduino Firmata kommunikációs protokoll a MIDI protokollból származik, amely egy vagy több 7 bites bájtot használ az adatok megjelenítésére.

A Firmata felhasználó által bővíthető volt. Ezt a kiterjeszthetőséget a System Exclusive (SysEx) üzenetküldő protokoll biztosítja.

A SysEx üzenet formátuma a Firmata protokoll szerint a fenti ábrán látható. Egy START_SYSEX bájttal kezdődik, hexadecimális 0xF0 fix értékkel, majd egyedi SysEx parancsbájt követi. A parancsbájt értékének a hexadecimális 0x00-0x7F tartományban kell lennie. A parancsbájtot ezután egy nem meghatározott számú 7 bites adatbájt követi. Végül az üzenet egy END_SYSEX bájttal fejeződik be, hexadecimális 0xF7 fix értékkel.

Firmata adatkódolás/dekódolás

Mivel a SysEx üzenet felhasználói adatrésze 7 bites bájtsorozatból áll, kíváncsi lehet, hogyan ábrázol egy 128-nál nagyobb értéket (0x7f)? A Firmata ezeket az értékeket kódolja azáltal, hogy szétszereli őket több 7 bites bájtdarabokra, mielőtt az adatokat az adatkapcsolaton keresztül sorba rendezi. Először egy adatelem legkevésbé jelentős bájtja (LSB) kerül elküldésre, majd az adategység egyre jelentősebb összetevői következnek. Az adatelem legjelentősebb bájtja (MSB) az utoljára elküldött adatelem.

Hogy működik ez?

Tegyük fel, hogy 525 értéket szeretnénk beépíteni a SysEx üzenet adatrészébe. Mivel az 525-ös érték nyilvánvalóan nagyobb, mint a 128-as érték, 7 bites bájtos darabokra kell bontani vagy szétszedni.

Íme, hogyan történik ez.

Az 525 érték decimális értékben megegyezik a 0x20D hexadecimális értékével, ami 2 bájt. Az LSB megszerzéséhez maszkoljuk az értéket úgy, hogy 0x7F -el megadjuk. Mind a "C", mind a Python megvalósításai az alábbiakban láthatók:

// "C" megvalósítás az LSB elkülönítésére

int max_distance_LSB = max_távolság & 0x7f; // maszkolja az alsó bájtot # Python implementáció az LSB elkülönítéséhez

A maszkolás után a max_distance_LSB 0x0d értéket tartalmaz. 0x20D és 0x7F = 0x0D.

Ezután el kell különítenünk az MSB-t ehhez a 2 bájtos értékhez. Ehhez a 0x20D értékét jobbra, 7 helyre toljuk el.

// "C" megvalósítás 2 bájtos MSB izolálásához

int max_távolság_MSB = max_táv >> 7; // a magas rendű bájt # Python megvalósításának eltolása 2 bájtos MSB izolálására max_distance_MSB = max_táv >> 7 # shift, hogy megkapja a felső bájtot Az eltolás után a max_distance_MSB 0x04 értéket fog tartalmazni.

Amikor a "csonkított" rendezett adatok érkeznek, azokat újra össze kell állítani egyetlen értékbe. Így állítják össze az adatokat "C" és Python rendszerben

// "C" megvalósítás a 2 bájt összeszereléséhez, // 7 bites értékek egyetlen értékbe int max_distance = argv [0] + (argv [1] << 7); # Python implementáció a 2 bájtos, # 7 bites értékek egyetlen értékbe történő összeszereléséhez max_distance = data [0] + (data [1] << 7)

Az összeszerelés után az érték ismét 525 decimális vagy 0x20D hexadecimális.

Ezt a szétszerelési/összeszerelési folyamatot elvégezheti akár az ügyfél, akár a szerver.

2. lépés: Kezdjük el

Egy új eszköz támogatásához módosítani kell mind az Arduino rezidens szervert, mind a PC rezidens Python klienst. Dr. Wheeler munkáját a szükséges módosítások szemléltetésére használjuk.

Talán a legfontosabb lépés annak eldöntése, hogy egy meglévő támogató eszközkönyvtárat kíván -e integrálni az egyenlet Arduino oldalába, vagy megírja a sajátját. Javasoljuk, hogy ha talál egy meglévő könyvtárat, akkor sokkal egyszerűbb használni, mint saját kezűleg írni.

A DHT eszközök támogatásához Dr. Wheeler a DHTNew könyvtárra alapozta a kiterjesztési kódját. Dr. Wheeler nagyon ügyesen osztotta fel a DHTNew könyvtár funkcióit az egyenlet Arduino és pymata4 oldalán, hogy minimális blokkolást biztosítson az Arduino oldalon.

Ha megnézzük a DHTNew -t, az a következők mindegyikét elvégzi:

  • A kiválasztott tűs digitális kimeneti mód beállítása.
  • Kódolt jelet ad le, hogy lekérje a legújabb páratartalom- és hőmérsékletértékeket.
  • Ellenőrzi és jelenti a hibákat.
  • Kiszámítja az ember által olvasható hőmérséklet és páratartalom értékeket a beolvasott nyers adatokból.

Annak érdekében, hogy a FirmataExpress oldalon a lehető leghatékonyabban működjenek a dolgok, Dr. Wheeler az adatkonverziós rutinokat az Arduino -ról a pymata4 -re töltötte le.

3. lépés: A FirmataExpress módosítása DHT támogatáshoz

A FirmataExpress címtárfa

Az alábbiakban a FirmataExpress adattárat tartalmazó összes fájl található. Ez a fa megegyezik a StandardFiramata fával, csak néhány fájlnév tükrözi a lerakat nevét.

A módosítandó fájlok azok, amelyek mellett csillag (*) található.

FirmataExpress

├── * Táblák.h

├── példák

│ └── FirmataExpress

│ ├── boardx

│ ├── * FirmataExpress.ino

│ ├── LICENSE.txt

│ └── Makefile

├── * FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Nézzük meg az egyes fájlokat és a módosításokat.

Táblák.h

Ez a fájl pin-típusú makró definíciókat tartalmaz a támogatott tábla típusokhoz. Meghatározza a támogatott eszközök maximális számát, ha egynél több eszközt kell támogatni.

A DHT eszköz esetében egyszerre legfeljebb 6 eszköz csatlakoztatható, és ez az érték a következő:

#ifndef MAX_DHTS

#define MAX_DHTS 6 #endif

Ezenkívül az új eszközhöz opcionálisan pin típusú makrókat is definiálhatnak, akár az összes tábla típusra, akár csak azokra, amelyek érdeklik Önt. Ezeket a makrókat többnyire jelentési célokra használják, és nem az eszközök vezérlésére. Ezek a makrók határozzák meg az eszközt támogató csapokat:

#define IS_PIN_DHT (p) (IS_PIN_DIGITAL (p) && (p) - 2 <MAX_DHTS)

Valamint egy makró a pin-szám konverzió meghatározásához.

#define PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataConstants.h

Ez a fájl tartalmazza a firmware verziószámát, amelyet módosíthat, hogy nyomon követhesse, melyik verziót töltötte be az Arduino -ba. Tartalmazza a Firmata üzenet értékeit is, beleértve a Firmata SysEx üzeneteket.

Ebben a fájlban új üzenetet vagy üzenetkészletet kell hozzárendelnie eszközéhez. A DHT -hez két üzenet került hozzáadásra. Az egyik konfigurálja a tűt „DHT” tűként, a másik pedig riporterüzenetként, amikor a legújabb DHT adatokat visszaküldi az ügyfélnek.

static const int DHT_CONFIG = 0x64;

static const int DHT_DATA = 0x65;

Ebben a fájlban a pin módok is megadásra kerülnek. A DHT számára új tűmódot hoztak létre:

static const int PIN_MODE_DHT = 0x0F; // DHT -hez konfigurált pin

Új tűmód hozzáadásakor a TOTAL_PIN_MODES értéket módosítani kell:

static const int TOTAL_PIN_MODES = 17;

FirmataDefines.h

Ezt a fájlt frissíteni kell, hogy tükrözze a FirmataConstants.h fájlhoz hozzáadott új üzeneteket:

#ifdef DHT_CONFIG #undef DHT_CONFIG #endif #define DHT_CONFIG firmata:: DHT_CONFIG // DHT request #ifdef DHT_DATA #undef DHT_DATA #endif #define DHT_DATA firmata:: DHT_DATA // DHT válasz #ifdef PINDFD:: PIN_MODE_DHT

FirmataExpress.ino

Ebben a vitában kitérünk az Arduino-vázlat módosításainak „csúcspontjaira”.

Annak érdekében, hogy a FirmataExpress egyszerre akár hat DHT eszközt is támogathasson, 3 tömböt hoztak létre, amelyek nyomon követik az eszközhöz tartozó PIN -kódot, annak WakeUpDelay értékét és az eszköztípust, azaz DHT22 vagy DHT11:

// DHT érzékelők

int numActiveDHTs = 0; // a csatolt DHT -k száma uint8_t DHT_PinNumbers [MAX_DHTS]; uint8_t DHT_WakeUpDelay [MAX_DHTS]; uint8_t DHT_TYPE [MAX_DHTS];

Mivel mindkét eszköztípus körülbelül 2 másodpercet vesz igénybe az olvasások között, meg kell győződnünk arról, hogy minden DHT-t csak egyszer olvasunk el a 2 másodperces időkeretben. Egyes eszközök, például a DHT-eszközök és a HC-SR04 távolságérzékelők csak időszakosan érhetők el. Ez időt biztosít számukra, hogy kölcsönhatásba lépjenek környezetükkel.

uint8_t nextDHT = 0; // index a dht -ba a következő eszköz olvasásához

uint8_t currentDHT = 0; // Nyomon követi, melyik érzékelő aktív. int dhtNumLoops = 0; // Célszám a b4 cikluson keresztül a DHT eléréséhez int dhtLoopCounter = 0; // Hurok számláló

A DHT eszköz konfigurálása és olvasása

Amikor a FirmataExpress SysEx parancsot kap, hogy konfigurálja a tűt a DHT művelethez, akkor ellenőrzi, hogy nem lépte -e túl a DHT eszközök maximális számát. Ha az új DHT támogatott, a DHT tömbök frissülnek. Ha a DHT típus ismeretlen, akkor SysEx karakterlánc -üzenet jön létre, és visszaküldésre kerül a pymata4 -be

eset DHT_CONFIG: int DHT_Pin = argv [0]; int DHT_type = argv [1]; if (numActiveDHTs <MAX_DHTS) {if (DHT_type == 22) {DHT_WakeUpDelay [numActiveDHTs] = 1; } else if (DHT_type == 11) {DHT_WakeUpDelay [numActiveDHTs] = 18; } else {Firmata.sendString ("HIBA: ISMERETLEN ÉRZÉKELŐ TÍPUS, ÉRVÉNYES ÉRZÉKELŐK 11, 22"); szünet; } // tesztelje az érzékelőt DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = DHT_type; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

A FirmataExpress ezután megpróbál kommunikálni a DHT eszközzel. Ha bármilyen hiba van, SysEx üzenetet képez a hibaadatokkal együtt, és visszaküldi a SysEx üzenetet a pymat4 -nek. A _bits változó tárolja a DHT eszköz által visszaadott adatokat a pymata4 további feldolgozásához, ha szükséges.

Firmata.write (START_SYSEX);

Firmata.write (DHT_DATA); Firmata.write (DHT_Pin); Firmata.write (DHT_type); for (uint8_t i = 0; i> 7 & 0x7f); } Firmata.write (abs (rv)); Firmata.write (1); Firmata.write (END_SYSEX);

Ha érvényes adatokat ad vissza, akkor az aktív DHT -k száma növekszik. Beállítják azt a változót is, amely nyomon követi, hogy hány ciklus -iterációt kell elvégezni a következő DHT -adatok ellenőrzése előtt. Ez a változó biztosítja, hogy függetlenül attól, hogy hány DHT -t adnak hozzá a rendszerhez, mindegyiket 2 másodpercen belül leolvassák.

int rv = readDhtSensor (számActiveDHTs);

if (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHTs; // minden oké}

Ha egy vagy több DHT eszközt konfiguráltak a vázlat hurok funkciójában, akkor a következő DHT eszköz olvasásra kerül. Vagy az érvényes adatokat, vagy a hiba állapotát adja vissza a pymata4 SysEx üzenet formájában:

if (dhtLoopCounter ++> dhtNumLoops) {if (numActiveDHTs) {int rv = readDhtSensor (nextDHT); uint8_t current_pin = DHT_PinNumbers [nextDHT]; uint8_t current_type = DHT_TYPE [nextDHT]; dhtLoopCounter = 0; currentDHT = nextDHT; if (nextDHT ++> = numActiveDHTs - 1) {nextDHT = 0; } if (rv == DHTLIB_OK) {// TESZT -ELLENŐRZÉS Uint8_t összeg = _bit [0] + _bit [1] + _bit [2] + _bit [3]; ha (_bit [4]! = összeg) {rv = -1; }} // küldje vissza az üzenetet hibaállapotban Firmata.write (START_SYSEX); Firmata.write (DHT_DATA); Firmata.write (current_pin); Firmata.write (aktuális_típus); for (uint8_t i = 0; i <sizeof (_bits) - 1; ++ i) {Firmata.write (_bits ); // Firmata.write (_bits ;} Firmata.write (abs (rv)); Firmata.write (0); Firmata.write (END_SYSEX);}}

A DHT eszközzel való kommunikációhoz használt kód közvetlenül a DHTNew könyvtárból származik:

int readDhtSensor (int index) {

// INIT BUFFERVAR AZ ADATOK VÉTELÉHEZ uint8_t mask = 128; uint8_t idx = 0; // EMPTY BUFFER // memset (_bits, 0, sizeof (_bits)); for (uint8_t i = 0; i 5 BYTES for (uint8_t i = 40; i! = 0; i--) {loopCnt = DHTLIB_TIMEOUT; while (digitalRead (pin) == LOW) {if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;} uint32_t t = micros (); loopCnt = DHTLIB_TIMEOUT; while (digitalRead (pin) == HIGH) {if (--loopCnt == 0) return DHTLIB_ERROR_TIMEOUT;} if ((micros ()-t)> 40) {_bits [idx] | = maszk;} maszk >> = 1; if (maszk == 0) // következő bájt? {Maszk = 128; idx ++;}} visszatér DHTLIB_OK;}

4. lépés: A Pymata4 módosítása DHT támogatáshoz

private_constants.h

A DHT támogatásához hozzá kell adnunk az új pin típusú és SysEx üzeneteket is ehhez a fájlhoz:

# pin módok INPUT = 0x00 # pin set in input OUTPUT = 0x01 # pin set output mint ANALOG = 0x02 # analóg pin analóg Bemeneti mód PWM = 0x03 # digitális pin PWM kimeneti módban SERVO = 0x04 # digitális pin Servo kimeneti módban I2C = 0x06 # tű az I2C beállításban STEPPER = 0x08 # bármelyik tű léptető üzemmódban SOROZAT = 0x0a PULLUP = 0x0b # Bármely tű a felhúzás üzemmódban SONAR = 0x0c # Bármely tű SONAR módban TONE = 0x0d # Bármilyen tű hangmódban PIXY = 0x0e # pixikamera módhoz fenntartva DHT = 0x0f # DHT érzékelő IGNORE = 0x7f # DHT SysEx parancsüzenetek DHT_CONFIG = 0x64 # dht config parancs DHT_DATA = 0x65 # dht szenzor válasz

A hozzáadott tűtípusnak és a SysEx parancsoknak meg kell egyezniük a FirmataConstants.h FirmataExpress -hez hozzáadott értékeivel.

pymata4.py

A Pymata4 a Python szótár segítségével gyorsan hozzárendeli a beérkező Firmata üzeneteket az üzenetkezelőhöz. Ennek a szótárnak a neve report_dispatch.

A szótárbejegyzés formátuma a következő:

{Üzenet azonosítója: [üzenet_kezelő, a feldolgozandó adatbájtok száma]}

A bejegyzés bekerült a szótárba a beérkező DHT üzenetek kezelésére:

{PrivateConstants. DHT_DATA: [self._dht_read_response, 7]}

Az üzenetben lévő 7 bájt adat az Arduino digitális pin száma, a DHT eszköz típusa (22 vagy 11) és az 5 bájt nyers adat.

A _dht_read_response módszer ellenőrzi a bejelentett hibákat. Ha nincs bejelentett hiba, a páratartalmat és a hőmérsékletet az Arduino DHTNew könyvtárból átvitt algoritmus segítségével számítják ki.

A számított értékeket a felhasználó által megadott visszahívási módszer jelenti. A belső pin_data adatszerkezetben is tárolódnak. Az utoljára jelentett érték előhívható a pin_data lekérdezésével a dht_read metódussal.

Új DHT eszköz konfigurálása

Új DHT eszköz hozzáadásakor a set_pin_mode_dht metódust hívják meg. Ez a módszer frissíti a pin_data adatokat a digitális csapokhoz. Létrehoz és elküld egy DHT_CONFIG SysEx üzenetet a FirmataExpressnek.

5. lépés: Csomagolás

Amint láttuk, a Firmata támogatás új eszközhöz való hozzáadásához módosítania kell az Arduino FirmataExpress szerverkódot és a Python-alapú pymata4 ügyfélkódot. A FirmataExpress kódot nehéz lehet hibakeresni. A printData nevű módszer hozzáadásra került a FirmataExpresshez a hibakeresés elősegítése érdekében. Ez a módszer lehetővé teszi adatértékek küldését a FirmataExpress szolgáltatásból, és kinyomtatja azokat a pymata4 konzolon.

Ez a funkció mind a karakterláncra mutató mutatót, mind a megtekinteni kívánt értéket igényli. Ha az adatértéket az argc nevű változó tartalmazza, akkor a következő paraméterekkel hívhatja meg a printData -t.

printData ((char*) "argc =", argc);

Ha bármilyen kérdése van, hagyjon megjegyzést, és szívesen válaszolok.

Boldog kódolást!

Ajánlott: