Obsah:

Going Beyond StandardFirmata - Revidited: 5 Steps
Going Beyond StandardFirmata - Revidited: 5 Steps

Video: Going Beyond StandardFirmata - Revidited: 5 Steps

Video: Going Beyond StandardFirmata - Revidited: 5 Steps
Video: 6 ways to heal trauma without medication | Bessel van der Kolk | Big Think 2024, Júl
Anonim
Going Beyond StandardFirmata - Revisited
Going Beyond StandardFirmata - Revisited

Pred malou chvíľou ma kontaktoval doktor Martyn Wheeler, používateľ pymata4, so žiadosťou o pomoc pri pridávaní podpory pre snímač vlhkosti a teploty DHT22 do knižnice pymata4. Knižnica pymata4 v spojení s jej náprotivkom Arduino, FirmataExpress, umožňuje používateľom ovládať a monitorovať ich zariadenia Arduino na diaľku. V priebehu niekoľkých kôl výmeny e -mailov bol Dr. Wheeler úspešný v úprave pymata4 aj FirmataExpress. Výsledkom je, že podpora pre snímače DHT22 a DHT11 je teraz štandardnou súčasťou programov pymata4 a FirmataExpress.

V máji 2014 som napísal článok o pridaní podpory pre ďalšie zariadenia do Firmaty. Keď som sa zamyslel nad týmto článkom, uvedomil som si, ako veľmi sa to zmenilo, pretože som k tomuto článku vzal pero a papier. Okrem tohto článku doktor Wheeler zdokumentoval svoje úsilie a možno by ste si to chceli pozrieť aj vy.

FirmataExpress je založený na štandarde StandardFirmata a menila sa štruktúra adresárov StandardFirmata. Okrem toho sa API pymata4 API celkom líši od pôvodného rozhrania API PyMata z roku 2014. Myslel som si, že teraz bude ideálny čas na opätovné prezeranie a aktualizáciu tohto článku. Na základe práce Dr. Wheelera sa pozrime, ako rozšíriť funkcie pymata4/FirmataExpress.

Skôr než začneme - niekoľko základných informácií o Arduino/Firmata

Čo je teda Firmata? Citujeme z webovej stránky Firmata: „Firmata je generický protokol pre komunikáciu s mikrokontrolérmi zo softvéru na hostiteľskom počítači.“

Arduino Firmata používa sériové rozhranie na prenos informácií o príkazoch a správach medzi mikrokontrolérom Arduino a počítačom, spravidla pomocou sériového/USB prepojenia nastaveného na 57 600 bps. Údaje prenášané cez toto prepojenie sú binárne a protokol je implementovaný v modeli klient/server.

Strana servera je nahraná do mikrokontroléra Arduino vo forme náčrtu Arduino. Skica StandardFirmata, ktorá je súčasťou IDE Arduino, riadi I/O piny Arduino podľa príkazu klienta. Tiež hlási klientovi zmeny vstupných pinov a ďalšie informácie o správach. FirmataExpress je rozšírená verzia StandardFirmata. Beží na rýchlosti sériového spojenia 115200 bps.

Klient Arduino použitý v tomto článku je pymata4. Je to aplikácia Python, ktorá sa vykonáva na počítači. Oba odosielajú príkazy na server Arduino a prijíma správy z neho. Pretože je pymata4 implementovaný v Pythone, beží na počítačoch Windows, Linux (vrátane Raspberry Pi) a macOS.

Prečo používať Firmata?

Mikrokontroléry Arduino sú úžasné malé zariadenia, ale zdroje procesora a pamäte sú do určitej miery obmedzené. V prípade aplikácií, ktoré sú náročné na procesor alebo pamäť, často nie je veľa možností, ako presunúť dopyt po zdrojoch do počítača, aby bola aplikácia úspešná.

Ale to nie je jediný dôvod, prečo používať StandardFirmata. Pri vývoji ľahších aplikácií Arduino môže počítač poskytovať nástroje a možnosti ladenia, ktoré nie sú priamo k dispozícii v mikrokontroléri Arduino. Použitie „pevného“klienta a servera pomáha obmedziť zložitosť aplikácie na počítač, ktorý je jednoduchšie spravovateľný. Akonáhle je aplikácia zdokonalená, môže byť preložená do vlastného, samostatného náčrtu Arduino.

Prečo používať pymata4?

Keďže som jeho autorom, som samozrejme zaujatý. Ako už bolo povedané, je to jediný klient Firmata založený na Pythone, ktorý bol počas posledných niekoľkých rokov nepretržite udržiavaný. Poskytuje intuitívne a ľahko použiteľné API. Okrem skíc založených na StandardFirmata podporuje Firmata cez WiFi pre zariadenia ako ESP-8266 pri použití skici StandardFirmataWifI.

Systém pymata4 bol tiež navrhnutý tak, aby ho užívateľ ľahko rozšíril o podporu ďalších senzorov a aktuátorov, ktoré v súčasnosti StandardFirmata nepodporuje.

Krok 1: Pochopenie protokolu Firmata

Pochopenie protokolu Firmata
Pochopenie protokolu Firmata

Komunikačný protokol Arduino Firmata je odvodený od protokolu MIDI, ktorý na reprezentáciu údajov používa jeden alebo viac 7-bitových bajtov.

Firmata bola navrhnutá tak, aby bola užívateľsky rozšíriteľná. Mechanizmus, ktorý poskytuje túto rozšíriteľnosť, je protokol na odosielanie správ System Exclusive (SysEx).

Formát správy SysEx, definovaný protokolom Firmata, je zobrazený na obrázku vyššie. Začína sa bajtom START_SYSEX s pevnou hodnotou hexadecimálnej 0xF0 a za ním nasleduje jedinečný príkazový bajt SysEx. Hodnota príkazového bajtu musí byť v rozsahu hexadecimálnych 0x00-0x7F. Za príkazovým bajtom potom nasleduje nešpecifikovaný počet 7-bitových dátových bajtov. Nakoniec je správa ukončená bajtom END_SYSEX s pevnou hodnotou hexadecimálnej 0xF7.

Kódovanie/dekódovanie údajov firmy

Pretože časť užívateľských údajov v správe SysEx pozostáva zo série 7-bitových bajtov, môžete sa čudovať, ako jeden predstavuje hodnotu väčšiu ako 128 (0x7f)? Firmata tieto hodnoty zakóduje tak, že ich rozloží na viacero 7-bitových bajtových blokov predtým, ako budú údaje zaradené cez dátové spojenie. Najmenej významný bajt (LSB) dátovej položky sa odošle ako prvý a potom podľa konvencie stále významnejšie súčasti dátovej položky. Najvýznamnejším bajtom (MSB) dátovej položky je posledná odoslaná dátová položka.

Ako to funguje?

Povedzme, že chceme do dátovej časti správy SysEx začleniť hodnotu 525. Pretože hodnota 525 je zreteľne väčšia ako hodnota 128, musíme ju rozdeliť alebo rozobrať na 7-bitové bajtové „kúsky“.

Tu je návod, ako sa to robí.

Hodnota 525 v desatinnom čísle je ekvivalentom hexadecimálnej hodnoty 0x20D, 2-bajtovej hodnoty. Aby sme získali LSB, hodnotu zamaskujeme tak, že ju spojíme s 0x7F. Implementácie „C“a Python sú uvedené nižšie:

// Implementácia "C" na izoláciu LSB

int max_distance_LSB = max_distance & 0x7f; // maskovanie dolného bajtu # Implementácia Pythonu na izoláciu LSB max_distance_LSB = max_distance & 0x7F # maskovanie dolného bajtu

Po maskovaní bude max_distance_LSB obsahovať 0x0d. 0x20D & 0x7F = 0x0D.

Ďalej musíme izolovať MSB pre túto 2-bajtovú hodnotu. Aby sme to urobili, posunieme hodnotu 0x20D doprava, 7 miest.

// Implementácia "C" na izoláciu MSB s hodnotou 2 bajtov

int max_distance_MSB = max_distance >> 7; // posunutie bajtu vysokého rádu # implementácia Pythonu na izoláciu MSB s hodnotou 2 bajtov max_distance_MSB = max_distance >> 7 # shift na získanie horného bajtu Po posunutí bude max_distance_MSB obsahovať hodnotu 0x04.

Keď sú prijaté „chunkifikované“zoradené údaje, je potrebné ich znova zostaviť do jednej hodnoty. Tu je návod, ako sú údaje znova zostavené v jazyku „C“aj v Pythone

// Implementácia „C“na opätovné zostavenie 2 bajtov, // 7 bitových hodnôt do jednej hodnoty int max_distance = argv [0] + (argv [1] << 7); # Implementácia Pythonu na opätovné zostavenie 2 bajtov, # 7 bitových hodnôt do jednej hodnoty max_distance = data [0] + (data [1] << 7)

Po opätovnom zostavení sa hodnota opäť rovná 525 desatinných miest alebo 0x20D hexadecimálnych hodnôt.

Tento proces demontáže/montáže môže vykonať buď klient, alebo server.

Krok 2: Začnime

Podpora nového zariadenia vyžaduje zmeny na rezidentnom serveri Arduino aj na klientskom počítači Python rezidentnom v počítači. Na ilustráciu potrebných úprav poslúži práca doktora Wheelera.

Asi najdôležitejším krokom je rozhodnúť sa, či chcete integrovať existujúcu podpornú knižnicu zariadení do strany rovnice Arduino, alebo napísať vlastnú. Odporúča sa, že ak nájdete existujúcu knižnicu, je oveľa jednoduchšie ju použiť, ako písať vlastnú od začiatku.

Pokiaľ ide o podporu zariadení DHT, Dr. Wheeler založil svoj rozširovací kód na knižnici DHTNew. Dr. Wheeler veľmi šikovne rozdelil funkčnosť knižnice DHTNew na strany rovnice Arduino a pymata4, aby poskytoval minimálne blokovanie na strane Arduino.

Ak sa pozrieme na DHTNew, vykonáva všetky tieto činnosti:

  • Nastaví zvolený režim digitálneho výstupu pinov.
  • Zakóduje zakódovaný signál na získanie najnovších hodnôt vlhkosti a teploty.
  • Skontroluje a nahlási všetky chyby.
  • Zo získaných surových údajov vypočítava hodnoty teploty a vlhkosti čitateľné pre človeka.

Aby boli veci na strane FirmataExpress čo najefektívnejšie, Dr. Wheeler vyložil rutiny konverzie údajov z Arduina na pymata4.

Krok 3: Úprava FirmataExpress pre podporu DHT

Strom adresárov FirmataExpress

Nasledujú všetky súbory, ktoré obsahujú úložisko FirmataExpress. Tento strom je identický so stromom StandardFiramata, akurát, že niektoré názvy súborov odrážajú názov úložiska.

Súbory, ktoré vyžadujú úpravu, sú tie, ktoré sú vedľa nich označené hviezdičkou (*).

FirmataExpress

├── * Boards.h

├── príklady

│ └── FirmataExpress

│ ├── boardx

│ ├── * FirmataExpress.ino

│ ├── LICENCIA.txt

│ └── Makefile

├── * FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Pozrime sa na každý zo súborov a zmeny, ktoré boli vykonané.

Rady.h

Tento súbor obsahuje definície makier typu pin pre každý z podporovaných typov dosiek. Definuje maximálny počet podporovaných zariadení, keď je potrebné podporovať viac ako jedno zariadenie.

Pre zariadenie DHT môže byť súčasne pripojených až 6 zariadení a táto hodnota je definovaná ako:

#ifndef MAX_DHTS

#define MAX_DHTS 6 #endif

Pre nové zariadenie môžu byť voliteľne definované aj makrá typu pin, a to buď pre všetky typy dosiek, alebo len pre tie, ktoré vás zaujímajú. Tieto makrá sa používajú väčšinou na účely hlásenia a nepoužívajú sa na ovládanie zariadení. Tieto makrá definujú oba piny, ktoré podporujú zariadenie:

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

Rovnako ako makro na definovanie prevodu pin-number.

#define PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataConstants.h

Tento súbor obsahuje číslo verzie firmvéru, ktoré môžete upraviť tak, aby sledovalo, ktorú verziu ste nahrali do svojho Arduina. Obsahuje tiež hodnoty správ Firmata vrátane správ Firmata SysEx.

V tomto súbore budete musieť svojmu zariadeniu priradiť novú správu alebo skupinu správ. Pre DHT boli pridané dve správy. Jeden konfiguruje pin ako pin „DHT“a druhý ako správu reportéra pri odosielaní najnovších údajov DHT späť klientovi.

static const int DHT_CONFIG = 0x64;

static const int DHT_DATA = 0x65;

V tomto súbore sú tiež určené režimy pripnutia. Pre DHT bol vytvorený nový režim pinov:

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

Pri pridávaní nového režimu pinov je potrebné upraviť TOTAL_PIN_MODES:

static const int TOTAL_PIN_MODES = 17;

FirmataDefines.h

Tento súbor je potrebné aktualizovať, aby odrážal nové správy pridané do súboru FirmataConstants.h:

#ifdef DHT_CONFIG #undef DHT_CONFIG:: PIN_MODE_DHT

FirmataExpress.ino

V tejto diskusii sa budeme zaoberať „vrcholmi“zmien vykonaných v tomto náčrte Arduino.

Aby FirmataExpress podporoval až šesť zariadení DHT súčasne, boli vytvorené 3 polia na sledovanie každého z priradených čísel PIN zariadenia, jeho hodnoty WakeUpDelay a typu zariadenia, ktorým je DHT22 alebo DHT11:

// Senzory DHT

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

Pretože oba typy zariadení vyžadujú medzi čítaniami približne 2 sekundy, musíme sa uistiť, že každý DHT prečítame iba raz v 2-sekundovom časovom rámci. K niektorým zariadeniam, ako sú zariadenia DHT a snímače vzdialenosti HC-SR04, sa pristupuje iba pravidelne. To im dáva čas na interakciu so svojim prostredím.

uint8_t nextDHT = 0; // index do dht pre čítanie ďalšieho zariadenia

uint8_t currentDHT = 0; // Sleduje, ktorý snímač je aktívny. int dhtNumLoops = 0; // Cieľový počet opakovaní prístupu slučky b4 k DHT int dhtLoopCounter = 0; // Počítadlo slučiek

Konfigurácia a čítanie zariadenia DHT

Keď spoločnosť FirmataExpress dostane príkaz SysEx na konfiguráciu kolíka pre operáciu DHT, overí, či nebol prekročený maximálny počet zariadení DHT. Ak je možné podporovať nový DHT, polia DHT sa aktualizujú. Ak je typ DHT neznámy, vytvorí sa reťazcová správa SysEx a prenesie sa späť do pymata4

prí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ÁMY TYP SNÍMAČA, PLATNÉ SENZORY SÚ 11, 22"); prestávka; } // test senzora DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = DHT_type; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

FirmataExpress sa potom pokúsi komunikovať so zariadením DHT. Ak sa vyskytnú chyby, vytvorí správu SysEx s chybovými údajmi a odošle správu SysEx späť na pymat4. Premenná _bits uchováva údaje vrátené zariadením DHT na ďalšie spracovanie pymata4, ak je to potrebné.

Firmata.write (START_SYSEX);

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

Ak sa vrátia platné údaje, počet aktívnych DHT sa zvýši. Upraví sa aj premenná, ktorá sleduje, koľko iterácií slučky treba dokončiť pred kontrolou údajov ďalšej DHT. Táto premenná zaisťuje, že bez ohľadu na to, koľko DHT je pridaných do systému, všetky budú prečítané do 2 sekundovej periódy.

int rv = readDhtSensor (numActiveDHTs);

if (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHTs; // všetko v poriadku}

Ak bolo v slučkovej funkcii náčrtu nakonfigurované jedno alebo viac zariadení DHT, potom sa načíta ďalšie zariadenie DHT. Buď sa platné údaje alebo ich chybový stav vrátia na server pymata4 vo forme sprá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) {// TESTOVACÍ KONTROLNÝ súčet uint8_t súčet = _bitov [0] + _bitov [1] + _bitov [2] + _bitov [3]; if (_bits [4]! = suma) {rv = -1; }} // odoslať správu späť s chybovým stavom 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ý na komunikáciu so zariadením DHT je odvodený priamo z knižnice DHTNew:

int readDhtSensor (int index) {

// INIT BUFFERVAR NA PRÍJEM ÚDAJOV 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) {_bits [idx] | = maska;} maska >> = 1; if (maska == 0) // ďalší bajt? {Maska = 128; idx ++;}} vrátiť DHTLIB_OK;}

Krok 4: Úprava Pymata4 pre podporu DHT

private_constants.h

Na podporu DHT musíme do tohto súboru pridať nové správy typu pin a SysEx:

# režimy pinov INPUT = 0x00 # pin nastavený ako vstup OUTPUT = 0x01 # pin nastavený ako výstup ANALOG = 0x02 # analógový pin v analógovom Vstupný režim PWM = 0x03 # digitálny pin v režime výstupu PWM SERVO = 0x04 # digitálny pin v režime servo výstupu I2C = 0x06 # pin zahrnutý v nastavení I2C STEPPER = 0x08 # ľubovoľný pin v krokovom režime SÉRIOVÉ = 0x0a PULLUP = 0x0b # Akýkoľvek pin v režime sťahovania SONAR = 0x0c # Akýkoľvek pin v režime SONAR TONE = 0x0d # Akýkoľvek pin v tónovom režime PIXY = 0x0e # vyhradené pre režim pixy kamery DHT = 0x0f # senzor DHT IGNORE = 0x7f # DHT správy príkazu SysEx DHT_CONFIG = 0x64 # dht konfiguračný príkaz DHT_DATA = 0x65 # dht odpoveď snímača

Pridaný typ pinov a príkazy SysEx sa musia zhodovať s hodnotami vo FirmataConstants.h pridaných do FirmataExpress.

pymata4.py

Pymata4 používa slovník Pythonu na rýchle priradenie prichádzajúcej správy Firmata k obsluhe správ. Názov tohto slovníka je report_dispatch.

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

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

Do slovníka bol pridaný záznam na spracovanie prichádzajúcich správ DHT:

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

7 bajtov údajov v správe je číslo digitálneho pinu Arduino, typ zariadenia DHT (22 alebo 11) a 5 bajtov nespracovaných údajov.

Metóda _dht_read_response kontroluje všetky nahlásené chyby. Ak nie sú hlásené žiadne chyby, vlhkosť a teplota sa vypočítajú pomocou algoritmu preneseného z knižnice Arduino DHTNew.

Vypočítané hodnoty sú hlásené prostredníctvom metódy spätného volania dodanej používateľom. Sú tiež uložené v internej dátovej štruktúre pin_data. Poslednú hlásenú hodnotu je možné vyvolať pomocou polling_data pomocou metódy dht_read.

Konfigurácia nového zariadenia DHT

Pri pridávaní nového zariadenia DHT sa nazýva metóda set_pin_mode_dht. Táto metóda aktualizuje údaje pin_data pre digitálne piny. Tiež vytvorí a odošle správu DHT_CONFIG SysEx na server FirmataExpress.

Krok 5: Zbaliť sa

Ako sme videli, pridanie podpory Firmata k novému zariadeniu vyžaduje úpravu kódu servera Arduino FirmataExpress a kódu klienta pymata4 založeného na Pythone. Ladenie kódu FirmataExpress môže byť náročné. Na pomoc pri ladení bola do FirmataExpress pridaná metóda s názvom printData. Táto metóda vám umožňuje odosielať hodnoty údajov z FirmataExpress a vytlačiť ich na konzole pymata4.

Táto funkcia vyžaduje ukazovateľ na reťazec znakov aj hodnotu, ktorú chcete zobraziť. Ak je údajová hodnota obsiahnutá v premennej nazývanej argc, môžete zavolať printData s nasledujúcimi parametrami.

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

Ak máte akékoľvek otázky, zanechajte komentár a ja vám rád odpoviem.

Šťastné kódovanie!

Odporúča: