Obsah:

Going Beyond StandardFirmata - Revisited: 5 Steps
Going Beyond StandardFirmata - Revisited: 5 Steps

Video: Going Beyond StandardFirmata - Revisited: 5 Steps

Video: Going Beyond StandardFirmata - Revisited: 5 Steps
Video: Firmata and Java:Installation & Test on Windows 11 2024, Červenec
Anonim
Going Beyond StandardFirmata - Revisited
Going Beyond StandardFirmata - Revisited

Před malou chvílí mě kontaktoval Dr. Martyn Wheeler, uživatel pymata4, s žádostí o pomoc při přidávání podpory snímače vlhkosti/teploty DHT22 do knihovny pymata4. Knihovna pymata4 ve spojení se svým protějškem Arduino, FirmataExpress, umožňuje uživatelům vzdáleně ovládat a monitorovat svá zařízení Arduino. Během několika kol výměny e -mailů byl Dr. Wheeler úspěšný v úpravě pymata4 i FirmataExpress. Díky tomu je podpora senzorů DHT22 a DHT11 nyní standardní součástí programů pymata4 a FirmataExpress.

V květnu 2014 jsem napsal článek o přidání podpory do Firmaty pro další zařízení. Když jsem se zamyslel nad tímto článkem, uvědomil jsem si, jak moc se toho změnilo od doby, kdy jsem pro tento článek vzal pero na papír. Kromě tohoto článku doktor Wheeler zdokumentoval své úsilí a možná byste si to také chtěli ověřit.

FirmataExpress je založen na StandardFirmata a adresářová struktura StandardFirmata se vyvinula. Kromě toho se API pymata4 API také trochu liší od původního API PyMata z roku 2014. Myslel jsem si, že to bude ideální čas na revizi a aktualizaci tohoto článku. Na základě práce Dr. Wheelera pojďme prozkoumat, jak rozšířit funkce pymata4/FirmataExpress.

Než začneme - pár základních informací o Arduinu/Firmata

Co je tedy Firmata? Citujeme z webové stránky Firmata: „Firmata je obecný protokol pro komunikaci s mikrokontroléry ze softwaru na hostitelském počítači.“

Arduino Firmata používá sériové rozhraní k přenosu informací o povelech a zprávách mezi mikrokontrolérem Arduino a počítačem, obvykle pomocí sériového/USB propojení nastaveného na 57 600 bps. Data přenesená přes tento odkaz jsou binární a protokol je implementován v modelu klient/server.

Strana serveru je nahrána do mikrokontroléru Arduino ve formě skici Arduino. Skica StandardFirmata, která je součástí IDE Arduino, ovládá I/O piny Arduino podle příkazu klienta. Rovněž hlásí změny vstupních pinů a další informace o zprávách zpět klientovi. FirmataExpress je rozšířená verze StandardFirmata. Běží na rychlosti sériového propojení 115200 bps.

Klient Arduino použitý pro tento článek je pymata4. Je to aplikace Python, která se spouští na PC. Posílá příkazy na server Arduino a přijímá zprávy ze serveru. Protože je pymata4 implementován v Pythonu, běží na počítačích Windows, Linux (včetně Raspberry Pi) a macOS.

Proč používat Firmata?

Mikrokontroléry Arduino jsou nádherná malá zařízení, ale prostředky procesoru a paměti jsou poněkud omezené. U aplikací, které jsou náročné na procesor nebo paměť, často nezbývá nic jiného, než přenést požadavek na zdroje na počítač, aby byla aplikace úspěšná.

Ale to není jediný důvod, proč používat StandardFirmata. Při vývoji lehčích aplikací Arduino může počítač poskytovat nástroje a možnosti ladění, které nejsou přímo dostupné na mikrokontroléru Arduino. Použití „pevného“klienta a serveru pomáhá omezit složitost aplikace na počítač, který se snadněji spravuje. Jakmile je aplikace zdokonalená, lze ji přeložit do vlastní, samostatné skici Arduino.

Proč používat pymata4?

Jako jeho autor jsem samozřejmě zaujatý. Jak již bylo řečeno, je to jediný klient Firmata založený na Pythonu, který byl v posledních několika letech nepřetržitě udržován. Poskytuje intuitivní a snadno použitelné API. Kromě skic založených na StandardFirmata podporuje Firmata přes WiFi pro zařízení jako ESP-8266 při použití skici StandardFirmataWifI.

Také pymata4 byl navržen tak, aby jej uživatel snadno rozšířil o podporu dalších senzorů a akčních členů, které v současné době StandardFirmata nepodporuje.

Krok 1: Porozumění protokolu Firmata

Pochopení protokolu Firmata
Pochopení protokolu Firmata

Komunikační protokol Arduino Firmata je odvozen z protokolu MIDI, který k zobrazení dat používá jeden nebo více 7bitových bytů.

Firmata byla navržena tak, aby byla uživatelsky rozšiřitelná. Mechanismus, který poskytuje tuto rozšiřitelnost, je protokol pro zasílání zpráv System Exclusive (SysEx).

Formát zprávy SysEx, definovaný protokolem Firmata, je zobrazen na obrázku výše. Začíná bajtem START_SYSEX s pevnou hodnotou šestnáctkové 0xF0 a za ním následuje jedinečný bajt příkazu SysEx. Hodnota příkazového bajtu musí být v rozsahu hexadecimálních 0x00-0x7F. Za příkazovým bajtem pak následuje neurčený počet 7bitových datových bytů. Nakonec je zpráva ukončena bajtem END_SYSEX s pevnou hodnotou hexadecimální 0xF7.

Kódování/dekódování dat firmy

Protože část uživatelských dat zprávy SysEx se skládá ze série 7bitových bajtů, můžete se divit, jak jeden představuje hodnotu větší než 128 (0x7f)? Firmata tyto hodnoty zakóduje tak, že je rozloží na více 7bitových bajtových bloků, než budou data zařazena přes datové spojení. Nejprve se odešle nejméně významný bajt (LSB) datové položky a poté podle konvence stále významnější komponenty datové položky. Nejvýznamnějším bajtem (MSB) datové položky je poslední odeslaná datová položka.

Jak to funguje?

Řekněme, že chceme začlenit hodnotu 525 do datové části zprávy SysEx. Protože hodnota 525 je zjevně větší než hodnota 128, musíme ji rozdělit nebo rozebrat na 7bitové bajtové „bloky“.

Zde je návod, jak se to dělá.

Hodnota 525 v desítkové soustavě odpovídá hexadecimální hodnotě 0x20D, což je 2bajtová hodnota. Chcete -li získat LSB, maskujeme hodnotu pomocí AND'ing s 0x7F. Implementace „C“a Python jsou uvedeny níže:

// Implementace "C" k izolaci LSB

int max_distance_LSB = max_distance & 0x7f; // maskování spodního bajtu # Implementace Pythonu k izolování LSB max_distance_LSB = max_distance & 0x7F # maskování dolního bajtu

Po maskování bude max_distance_LSB obsahovat 0x0d. 0x20D & 0x7F = 0x0D.

Dále musíme izolovat MSB pro tuto 2bajtovou hodnotu. Za tímto účelem posuneme hodnotu 0x20D doprava, 7 míst.

// Implementace "C" k izolaci MSB o hodnotě 2 bajtů

int max_distance_MSB = max_distance >> 7; // posunutí bajtu vysokého řádu # implementace Pythonu k izolování MSB o hodnotě 2 bajtů max_distance_MSB = max_distance >> 7 # shift k získání horního bajtu Po posunu bude max_distance_MSB obsahovat hodnotu 0x04.

Když jsou přijata zařazená data „chunkified“, je třeba je znovu sestavit do jedné hodnoty. Zde je návod, jak jsou data znovu sestavena v „C“i v Pythonu

// Implementace "C" pro opětovné sestavení 2bajtu, // 7 bitových hodnot do jedné hodnoty int max_distance = argv [0] + (argv [1] << 7); # Implementace Pythonu k opětovnému sestavení 2 bajtů, # 7 bitových hodnot do jediné hodnoty max_distance = data [0] + (data [1] << 7)

Po opětovném sestavení se hodnota opět rovná 525 desítkové nebo 0x20D šestnáctkové.

Tento proces demontáže/opětovné montáže může provádět buď klient, nebo server.

Krok 2: Začněme

Podpora nového zařízení vyžaduje změny jak na rezidentním serveru Arduino, tak na klientském Pythonu v PC. K ilustraci nezbytných úprav bude použito dílo Dr. Wheelera.

Asi nejdůležitějším krokem je rozhodnout se, zda chcete integrovat existující knihovnu podpůrných zařízení do strany rovnice Arduino, nebo napsat vlastní. Doporučuje se, že pokud najdete existující knihovnu, je mnohem jednodušší ji použít, než psát vlastní od začátku.

Dr. Wheeler pro podporu zařízení DHT založil svůj rozšiřující kód na knihovně DHTNew. Dr. Wheeler velmi chytře rozdělil funkce knihovny DHTNew napříč rovnicemi Arduino a pymata4, aby poskytoval minimální blokování na straně Arduino.

Pokud se podíváme na DHTNew, provede všechny následující:

  • Nastaví vybraný režim digitálního výstupu pinů.
  • Zakóduje zakódovaný signál pro získání nejnovějších hodnot vlhkosti a teploty.
  • Zkontroluje a nahlásí všechny chyby.
  • Ze získaných surových dat vypočítá hodnoty teploty a vlhkosti čitelné pro člověka.

Aby byly věci na straně FirmataExpress co nejefektivnější, Dr. Wheeler uvolnil rutiny převodu dat z Arduina na pymata4.

Krok 3: Úprava FirmataExpress pro podporu DHT

Strom adresářů FirmataExpress

Níže jsou uvedeny všechny soubory, které tvoří úložiště FirmataExpress. Tento strom je identický se stromem StandardFiramata, jen některé názvy souborů odrážejí název úložiště.

Soubory, které vyžadují úpravu, jsou ty, které mají vedle sebe hvězdičku (*).

FirmataExpress

├── * Boards.h

├── příklady

│ └── FirmataExpress

│ ├── boardx

│ ├── * FirmataExpress.ino

│ ├── LICENCE.txt

│ └── Makefile

├── * FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Podívejme se na každý ze souborů a změny, které byly provedeny.

Boards.h

Tento soubor obsahuje definice makra typu pin pro každý z podporovaných typů desek. Definuje maximální počet podporovaných zařízení, když je potřeba podporovat více než jedno zařízení.

U zařízení DHT může být současně připojeno až 6 zařízení a tato hodnota je definována jako:

#ifndef MAX_DHTS

#define MAX_DHTS 6 #endif

Pro nové zařízení mohou být volitelně definována také makra typu pin, a to buď pro všechny typy desek, nebo jen pro ta, která vás zajímají. Tato makra se používají většinou pro účely hlášení a nepoužívají se k ovládání zařízení. Tato makra definují oba piny, které podporují zařízení:

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

Stejně jako makro pro definování převodu pin-number.

#define PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataConstants.h

Tento soubor obsahuje číslo verze firmwaru, které můžete upravit, aby bylo možné sledovat, jakou verzi jste nahráli do svého Arduina. Obsahuje také hodnoty zpráv Firmata, včetně zpráv Firmata SysEx.

V tomto souboru budete muset svému zařízení přiřadit novou zprávu nebo sadu zpráv. Pro DHT byly přidány dvě zprávy. Jeden konfiguruje pin jako pin „DHT“a druhý jako zprávu reportéra při odesílání nejnovějších dat DHT zpět klientovi.

static const int DHT_CONFIG = 0x64;

static const int DHT_DATA = 0x65;

V tomto souboru jsou také specifikovány režimy připnutí. Pro DHT byl vytvořen nový režim pinů:

static const int PIN_MODE_DHT = 0x0F; // pin nakonfigurovaný pro DHT

Při přidávání nového režimu pinů je třeba upravit TOTAL_PIN_MODES:

static const int TOTAL_PIN_MODES = 17;

FirmataDefines.h

Tento soubor musí být aktualizován, aby odrážel nové zprávy přidané do FirmataConstants.h:

#ifdef DHT_CONFIG #undef DHT_CONFIG #endf #define:: PIN_MODE_DHT

FirmataExpress.ino

V této diskusi se budeme zabývat „vysokými body“změn provedených v této skici Arduino.

Aby mohla společnost FirmataExpress podporovat až šest zařízení DHT současně, byla vytvořena 3 pole, která sledují každé přiřazené číslo PIN zařízení, jeho hodnotu WakeUpDelay a typ zařízení, tj. DHT22 nebo DHT11:

// Senzory DHT

int numActiveDHTs = 0; // počet připojených DHT uint8_t DHT_PinNumbers [MAX_DHTS]; uint8_t DHT_WakeUpDelay [MAX_DHTS]; uint8_t DHT_TYPE [MAX_DHTS];

Protože oba typy zařízení vyžadují mezi čteními přibližně 2 sekundy, musíme zajistit, abychom každý DHT přečetli pouze jednou v časovém rámci 2 sekund. Některá zařízení, například zařízení DHT a snímače vzdálenosti HC-SR04, jsou přístupná pouze periodicky. To jim umožňuje čas na interakci se svým prostředím.

uint8_t nextDHT = 0; // index do dht pro čtení dalšího zařízení

uint8_t aktuálníDHT = 0; // Sleduje, který senzor je aktivní. int dhtNumLoops = 0; // Cílový počet opakování prostřednictvím smyčky b4 s přístupem k DHT int dhtLoopCounter = 0; // Počitadlo smyček

Konfigurace a čtení zařízení DHT

Když FirmataExpress obdrží příkaz SysEx ke konfiguraci pinu pro provoz DHT, ověří, zda nebyl překročen maximální počet zařízení DHT. Pokud lze nový DHT podporovat, pole DHT se aktualizují. Pokud je typ DHT neznámý, vytvoří se řetězcová zpráva SysEx a odešle se zpět do pymata4

případ 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 ("CHYBA: NEZNÁMÝ TYP SNÍMAČE, PLATNÉ SENZORY JSOU 11, 22"); přestávka; } // test senzoru DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = typ DHT; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

FirmataExpress se poté pokusí komunikovat se zařízením DHT. Pokud se vyskytnou nějaké chyby, vytvoří zprávu SysEx s chybovými daty a odešle zprávu SysEx zpět na pymat4. Proměnná _bits uchovává data vrácená zařízením DHT pro další zpracování pymata4, pokud je to požadováno.

Firmata.write (START_SYSEX);

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

Pokud jsou vrácena platná data, počet aktivních DHT se zvýší. Upraví se také proměnná, která sleduje, kolik iterací smyčky je třeba dokončit před kontrolou dat další DHT. Tato proměnná zajišťuje, že bez ohledu na to, kolik DHT je přidáno do systému, budou všechny přečteny během 2 sekund.

int rv = readDhtSensor (numActiveDHTs);

if (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHTs; // vše v pořádku}

Pokud bylo ve smyčkové funkci náčrtu nakonfigurováno jedno nebo více zařízení DHT, načte se další zařízení DHT. Buď jsou platná data nebo jejich chybový stav vráceny do pymata4 ve formě zprávy SysEx:

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) {// TEST CHECKSUM uint8_t sum = _bits [0] + _bits [1] + _bits [2] + _bits [3]; if (_bits [4]! = sum) {rv = -1; }} // odeslat zprávu zpět s chybovým stavem Firmata.write (START_SYSEX); Firmata.write (DHT_DATA); Firmata.write (current_pin); Firmata.write (current_type); 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);}}

Kód používaný ke komunikaci se zařízením DHT je odvozen přímo z knihovny DHTNew:

int readDhtSensor (int index) {

// INIT BUFFERVAR K PŘIJÍMÁNÍ DAT uint8_t maska = 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) {_bitů [idx] | = maska;} maska >> = 1; if (maska == 0) // další byte? {Maska = 128; idx ++;}} návrat DHTLIB_OK;}

Krok 4: Úprava Pymata4 pro podporu DHT

private_constants.h

Abychom podporovali DHT, musíme do tohoto souboru přidat nové zprávy typu pin a SysEx:

# režimy PIN INPUT = 0x00 # pin nastaven jako vstup OUTPUT = 0x01 # pin nastaven jako výstup ANALOG = 0x02 # analogový pin v analogovém Vstupní režim PWM = 0x03 # digitální pin ve výstupním režimu PWM SERVO = 0x04 # digitální pin v režimu Servo výstup I2C = 0x06 # pin zahrnut v nastavení I2C STEPPER = 0x08 # libovolný pin v režimu steper SERIAL = 0x0a PULLUP = 0x0b # jakýkoli pin v režimu pullup SONAR = 0x0c # jakýkoli pin v režimu SONAR TONE = 0x0d # jakýkoli pin v režimu tónu PIXY = 0x0e # vyhrazeno pro režim pixy kamery DHT = 0x0f # snímač DHT IGNORE = 0x7f # DHT zprávy příkazu SysEx DHT_CONFIG = 0x64 # dht konfigurační příkaz DHT_DATA = 0x65 # dht odpověď snímače

Přidaný typ pinů a příkazy SysEx se musí shodovat s hodnotami ve FirmataConstants.h přidanými do FirmataExpress.

pymata4.py

Pymata4 používá slovník Pythonu k rychlému přiřazení příchozí zprávy Firmata k obsluze zpráv. Název tohoto slovníku je report_dispatch.

Formát záznamu ve slovníku je:

{MessageID: [message_handler, number of data bytes to be processing]}

Do slovníku byla přidána položka pro zpracování příchozích zpráv DHT:

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

7 bajtů dat ve zprávě je číslo digitálního pinu Arduino, typ zařízení DHT (22 nebo 11) a 5 bajtů nezpracovaných dat.

Metoda _dht_read_response kontroluje všechny hlášené chyby. Pokud nejsou hlášeny žádné chyby, vlhkost a teplota se vypočítají pomocí algoritmu přeneseného z knihovny Arduino DHTNew.

Vypočítané hodnoty jsou hlášeny pomocí metody zpětného volání dodané uživatelem. Jsou také uloženy v interní datové struktuře pin_data. Poslední hlášenou hodnotu lze vyvolat dotazováním pin_data pomocí metody dht_read.

Konfigurace nového zařízení DHT

Při přidávání nového zařízení DHT se zavolá metoda set_pin_mode_dht. Tato metoda aktualizuje pin_data pro digitální piny. Také vytvoří a odešle zprávu DHT_CONFIG SysEx do FirmataExpress.

Krok 5: Zabalení

Jak jsme viděli, přidání podpory Firmata pro nové zařízení vyžaduje úpravu kódu serveru Arduino FirmataExpress a klientského kódu pymata4 založeného na Pythonu. Ladění kódu FirmataExpress může být náročné. Na podporu ladění byla do FirmataExpress přidána metoda s názvem printData. Tato metoda vám umožňuje odesílat datové hodnoty z FirmataExpress a vytiskne je na konzole pymata4.

Tato funkce vyžaduje jak ukazatel na řetězec znaků, tak hodnotu, kterou chcete zobrazit. Pokud je hodnota dat obsažena v proměnné zvané argc, můžete zavolat printData s následujícími parametry.

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

Pokud máte nějaké dotazy, zanechte komentář a já vám rád odpovím.

Šťastné kódování!

Doporučuje: