Sadržaj:

Iznad standardnih firmi - ponovno pregledavanje: 5 koraka
Iznad standardnih firmi - ponovno pregledavanje: 5 koraka

Video: Iznad standardnih firmi - ponovno pregledavanje: 5 koraka

Video: Iznad standardnih firmi - ponovno pregledavanje: 5 koraka
Video: Моя работа наблюдать за лесом и здесь происходит что-то странное 2024, Srpanj
Anonim
Ići dalje od standardnih firmi - ponovno posjetiti
Ići dalje od standardnih firmi - ponovno posjetiti

Nedavno me kontaktirao dr. Martyn Wheeler, korisnik pymata4, radi smjernica u dodavanju podrške za DHT22 osjetnik vlažnosti/temperature u biblioteku pymata4. Knjižnica pymata4, zajedno sa svojim kolegom iz Arduina, FirmataExpress, omogućuje korisnicima daljinsko upravljanje i nadziranje svojih Arduino uređaja. U nekoliko rundi razmjene e -pošte, dr. Wheeler je uspio izmijeniti pymata4 i FirmataExpress. Zbog toga je podrška za senzore DHT22 i DHT11 sada standardni dio pymata4 i FirmataExpress.

U svibnju 2014. napisao sam članak o dodavanju podrške Firmati za dodatne uređaje. Razmišljajući o tom članku, shvatio sam koliko se promijenilo otkad sam uzeo olovku za papir za taj članak. Uz ovaj članak, dr. Wheeler je dokumentirao svoje napore, a možda biste htjeli provjeriti i to.

FirmataExpress temelji se na StandardFirmata, a struktura direktorija StandardFirmata se razvila. Osim toga, pymata4 API također se prilično razlikuje od izvornog PyMata API -a iz 2014. Mislio sam da bi ovo bilo savršeno vrijeme za ponovni posjet i ažuriranje tog članka. Koristeći rad dr. Wheelera kao osnovu, istražimo kako proširiti funkcionalnost pymata4/FirmataExpress.

Prije nego počnemo - neke osnovne informacije o Arduinu/Firmati

Što je dakle Firmata? Citirajući s web stranice Firmata, "Firmata je generički protokol za komunikaciju s mikrokontrolerima iz softvera na računalu domaćinu."

Arduino Firmata koristi serijsko sučelje za prijenos podataka o naredbama i izvješćima između Arduino mikrokontrolera i računala, obično koristeći serijsku/USB vezu postavljenu na 57600 bps. Podaci koji se prenose preko ove veze su binarni, a protokol je implementiran u klijent/poslužiteljski model.

Strana poslužitelja učitana je na Arduino mikrokontroler u obliku Arduino skice. Skica StandardFirmata, uključena u Arduino IDE, kontrolira Arduino I/O pinove, prema nalogu klijenta. Također izvješćuje klijenta o promjenama ulaznog pina i drugim informacijama o izvješću. FirmataExpress je proširena verzija StandardFirmata. Radi brzinom serijske veze od 115200 bps.

Arduino klijent koji se koristi za ovaj članak je pymata4. To je Python aplikacija koja se izvršava na računalu. Oba šalje naredbe i prima izvješća s Arduino poslužitelja. Budući da je pymata4 implementiran u Python, radi na Windows, Linux (uključujući Raspberry Pi) i macOS računalima.

Zašto koristiti Firmatu?

Arduino mikrokontroleri izvrsni su mali uređaji, ali procesorski i memorijski resursi donekle su ograničeni. Za aplikacije koje zahtijevaju procesore ili memoriju često nema drugog izbora nego prenijeti zahtjev za resursima na računalo kako bi aplikacija bila uspješna.

No, to nije jedini razlog korištenja StandardFirmata. Prilikom razvoja lakših Arduino aplikacija, računalo može pružiti alate i mogućnosti otklanjanja pogrešaka koji nisu izravno dostupni na Arduino mikrokontroleru. Korištenje "fiksnog" klijenta i poslužitelja pomaže ograničiti složenost aplikacije na računalo, kojim se lakše upravlja. Nakon što se aplikacija usavrši, može se prevesti u prilagođenu, samostalnu Arduino skicu.

Zašto koristiti pymata4?

Budući da sam njezin autor, naravno, pristran sam. S obzirom na to, to je jedini klijent Firmata sa Python-om koji se kontinuirano održava posljednjih nekoliko godina. Pruža intuitivan i jednostavan za korištenje API. Osim skica temeljenih na StandardFirmata, podržava Firmata preko WiFi-a za uređaje poput ESP-8266 kada se koristi skica StandardFirmataWifI.

Također, pymata4 je dizajniran tako da ga korisnik može lako proširiti za podršku dodatnih senzora i aktuatora koje trenutno ne podržava StandardFirmata.

Korak 1: Razumijevanje Firmata protokola

Razumijevanje Firmata protokola
Razumijevanje Firmata protokola

Komunikacijski protokol Arduino Firmata izveden je iz MIDI protokola, koji koristi jedan ili više 7-bitnih bajtova za predstavljanje podataka.

Firmata je osmišljena tako da je proširiva za korisnike. Mehanizam koji omogućuje ovu proširivost je protokol za razmjenu poruka System Exclusive (SysEx).

Format poruke SysEx, definiran protokolom Firmata, prikazan je na gornjoj ilustraciji. Započinje s START_SYSEX bajtom s fiksnom vrijednošću heksadecimalnog 0xF0, a nakon njega slijedi jedinstveni bajt naredbe SysEx. Vrijednost naredbenog bajta mora biti u rasponu heksadecimalnog 0x00-0x7F. Nakon naredbenog bajta slijedi neodređen broj 7-bitnih podatkovnih bajtova. Konačno, poruka se završava s END_SYSEX bajtom, s fiksnom vrijednošću heksadecimalnog 0xF7.

Firmata kodiranje/dekodiranje podataka

Budući da se dio korisničkih podataka SysEx poruke sastoji od niza 7-bitnih bajtova, možda ćete se zapitati kako jedan predstavlja vrijednost veću od 128 (0x7f)? Firmata kodira te vrijednosti rastavljajući ih na više 7-bitnih dijelova bajtova prije nego što se podaci razmjeste preko podatkovne veze. Najprije se šalje najmanje značajan bajt (LSB) stavke podataka, a zatim slijede sve značajnije komponente stavke podataka prema dogovoru. Najvažniji bajt (MSB) podatkovne stavke je posljednja poslana stavka podataka.

Kako ovo radi?

Recimo da želimo unijeti vrijednost 525 u podatkovni dio poruke SysEx. Budući da je vrijednost 525 očito veća od vrijednosti 128, moramo je podijeliti ili rastaviti u 7-bitne "komade" bajtova.

Evo kako se to radi.

Vrijednost 525 u decimalu ekvivalentna je heksadecimalnoj vrijednosti 0x20D, vrijednosti od 2 bajta. Da bismo dobili LSB, maskiramo vrijednost AND pomoću "0x7F". I "C" i Python implementacije prikazane su u nastavku:

// "C" implementacija za izolaciju LSB -a

int max_distance_LSB = max_distanca & 0x7f; // maskiranje donjeg bajta # Python implementacija za izolaciju LSB max_distance_LSB = max_distance & 0x7F # maska donjeg bajta

Nakon maskiranja, max_distance_LSB sadržavat će 0x0d. 0x20D & 0x7F = 0x0D.

Zatim moramo izolirati MSB za ovu 2-bajtnu vrijednost. Da bismo to učinili, pomaknut ćemo vrijednost 0x20D udesno, 7 mjesta.

// "C" implementacija za izolaciju MSB -a od 2 bajta

int max_distance_MSB = max_distanca >> 7; // pomak bajta visokog reda # Python implementacija za izolaciju MSB -a od 2 bajta max_distance_MSB = max_distance >> 7 # shift za dobivanje gornjeg bajta Nakon premještanja, max_distance_MSB će sadržavati vrijednost 0x04.

Kad se dobiju "zrnasti" raspoređeni podaci, potrebno ih je ponovno sastaviti u jednu vrijednost. Evo kako se podaci ponovno sastavljaju u "C" i Pythonu

// implementacija "C" za ponovno sastavljanje 2 bajta, // 7 bitnih vrijednosti u jednu vrijednost int max_distance = argv [0] + (argv [1] << 7); # Python implementacija za ponovno okupljanje 2 -bajtnih, # 7 -bitnih vrijednosti u jednu vrijednost max_distance = data [0] + (data [1] << 7)

Nakon ponovnog sastavljanja, vrijednost ponovno iznosi 525 decimalnih ili 0x20D heksadecimalnih.

Ovaj postupak rastavljanja/ponovnog sastavljanja može izvesti klijent ili poslužitelj.

Korak 2: Počnimo

Podržavanje novog uređaja zahtijeva promjene i na Arduino rezidentnom poslužitelju i na rezidentnom Python klijentu. Rad dr. Wheelera će se koristiti za ilustraciju potrebnih izmjena.

Možda je najvažniji korak odlučiti želite li integrirati postojeću knjižnicu podržanih uređaja u Arduino stranu jednadžbe ili napisati vlastitu. Preporučuje se da je, ako pronađete postojeću knjižnicu, daleko jednostavnije koristiti nego pisati vlastitu od nule.

Za podršku DHT uređaja, dr. Wheeler je svoj kod proširenja zasnovao na knjižnici DHTNew. Vrlo pametno, dr. Wheeler je podijelio funkcionalnost DHTNew knjižnice na Arduino i pymata4 strane jednadžbe kako bi osigurao minimalno blokiranje na Arduino strani.

Ako pogledamo DHTNew, on izvodi sve sljedeće:

  • Postavlja odabrani način digitalnog izlaza s pin -om.
  • Sat kodira signal za dohvaćanje najnovijih vrijednosti vlažnosti i temperature.
  • Provjerava i prijavljuje sve pogreške.
  • Izračunava vrijednosti temperature i vlažnosti koje čitaju ljudi iz preuzetih sirovih podataka.

Kako bi stvari bile što učinkovitije na strani FirmataExpressa, dr. Wheeler je iskrcao rutine pretvorbe podataka s Arduina na pymata4.

Korak 3: Izmjena FirmataExpress -a za DHT podršku

Stablo direktorija FirmataExpress

Ispod su sve datoteke koje sadrže spremište FirmataExpress. Ovo stablo je identično onom u StandardFiramata, samo što neki od naziva datoteka odražavaju naziv spremišta.

Datoteke koje je potrebno promijeniti su one koje imaju zvjezdicu (*) pored sebe.

FirmataExpress

├── * Ploče.h

├── primjeri

│ └── FirmataExpress

│ ├── boardx

│ ├── * FirmataExpress.ino

│ ├── LICENSE.txt

│ └── Makefile

├── * FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Pogledajmo svaku datoteku i promjene koje su napravljene.

Ploče.h

Ova datoteka sadrži pin definicije makroa za svaku od podržanih vrsta ploča. Definira najveći mogući broj podržanih uređaja kada je potrebno podržati više uređaja.

Za DHT uređaj, do 6 uređaja može biti spojeno odjednom, a ova vrijednost je definirana kao:

#ifndef MAX_DHTS

#define MAX_DHTS 6 #endif

Također, makronaredbe tipa pin mogu se po izboru definirati za novi uređaj, bilo za sve vrste ploča ili samo za one koje vas zanimaju. Ovi se makronaredbe uglavnom koriste za potrebe izvješćivanja i ne koriste se za kontrolu uređaja. Ove makronaredbe definiraju oba pina koji podržavaju uređaj:

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

Kao i makronaredbu za definiranje pretvorbe pin-broja.

#define PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataKonstante.h

Ova datoteka sadrži broj verzije firmvera, koji biste možda htjeli izmijeniti kako biste pratili koju ste verziju učitali na svoj Arduino. Također sadrži vrijednosti poruka Firmata, uključujući poruke Firmata SysEx.

Morate dodijeliti novu poruku ili skup poruka za svoj uređaj u ovoj datoteci. Za DHT su dodane dvije poruke. Jedan konfigurira pin kao "DHT" pin, a drugi, kao reportersku poruku, kada šalje najnovije DHT podatke natrag klijentu.

static const int DHT_CONFIG = 0x64;

static const int DHT_DATA = 0x65;

Načini pričvršćivanja također su navedeni u ovoj datoteci. Za DHT je stvoren novi pin način:

static const int PIN_MODE_DHT = 0x0F; // pin konfiguriran za DHT

Prilikom dodavanja novog načina pribadače, TOTAL_PIN_MODES se mora prilagoditi:

static const int TOTAL_PIN_MODES = 17;

FirmataDefines.h

Ova se datoteka mora ažurirati kako bi odražavala nove poruke dodane na FirmataConstants.h:

#ifdef DHT_CONFIG #undef DHT_CONFIG #endif #define DHT_CONFIG firmata:: DHT_CONFIG // DHT zahtjev #ifdef DHT_DATA #undef DHT_DATA #endif #define DHT_DATA firmata: DHT_DATA // DHT odgovor #ifDM_DH_DODODRIM:: PIN_MODE_DHT

FirmataExpress.ino

U ovoj raspravi pokriti ćemo "vrhunce" promjena napravljenih na ovoj Arduino skici.

Kako bi FirmataExpress istodobno podržavao do šest DHT uređaja, stvorena su 3 niza za praćenje svakog PIN -a povezanog uređaja, njegove WakeUpDelay vrijednosti i vrste uređaja, to jest DHT22 ili DHT11:

// DHT senzori

int numActiveDHTs = 0; // broj priloženih DHT -ova uint8_t DHT_PinNumbers [MAX_DHTS]; uint8_t DHT_WakeUpDelay [MAX_DHTS]; uint8_t DHT_TIP [MAX_DHTS];

Budući da obje vrste uređaja zahtijevaju približno 2 sekunde između čitanja, moramo se pobrinuti da svaki DHT očitamo samo jednom u vremenskom okviru od 2 sekunde. Nekim uređajima, poput DHT uređaja i senzora udaljenosti HC-SR04, pristupa se samo povremeno. To im daje vremena za interakciju sa svojim okruženjem.

uint8_t sljedećiDHT = 0; // indeksira u dht za sljedeći uređaj za čitanje

uint8_t trenutnaDHT = 0; // Prati koji je senzor aktivan. int dhtNumLoops = 0; // Ciljani broj puta kroz petlju b4 koji pristupa DHT -u int dhtLoopCounter = 0; // Brojač petlji

Konfiguriranje i čitanje DHT uređaja

Kada FirmataExpress primi naredbu SysEx za konfiguriranje pina za rad DHT -a, provjerava se da nije premašen maksimalni broj DHT uređaja. Ako se može podržati novi DHT, DHT nizovi se ažuriraju. Ako je tip DHT nepoznat, kreira se poruka s nizom SysEx i šalje natrag na pymata4

slučaj 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 ("GREŠKA: NEPOZNATI TIP SENZORA, VRIJEDNI SENZORI SU 11, 22"); pauza; } // testiranje senzora DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = DHT_tip; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

FirmataExpress zatim pokušava komunicirati s DHT uređajem. Ako ima grešaka, formira SysEx poruku s podacima o pogrešci i šalje poruku SysEx natrag na pymat4. Varijabla _bits sadrži podatke koje vraća DHT uređaj za dodatnu obradu od strane pymata4 ako to želi.

Firmata.write (START_SYSEX);

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

Ako se vrate valjani podaci, broj aktivnih DHT -ova se povećava. Također se prilagođava varijabla koja prati koliko iteracija petlje treba dovršiti prije provjere podataka sljedećeg DHT -a. Ova varijabla osigurava da će se, bez obzira na to koliko DHT -ova dodano u sustav, svi oni biti pročitani u razdoblju od 2 sekunde.

int rv = readDhtSensor (numActiveDHTs);

if (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHT; // sve u redu}

Ako je jedan ili više DHT uređaja konfigurirano u funkciji petlje skice, tada se čita sljedeći DHT uređaj. Ili važeći podaci ili njihov status pogreške vraćaju se pymata4 u obliku poruke SysEx:

if (dhtLoopCounter ++> dhtNumLoops) {if (numActiveDHTs) {int rv = readDhtSensor (nextDHT); uint8_t current_pin = DHT_Broj brojeva [nextDHT]; uint8_t trenutni_tip = DHT_TIP [sljedećiDHT]; 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 (_bit [4]! = zbroj) {rv = -1; }} // pošaljite poruku natrag sa statusom pogreške Firmata.write (START_SYSEX); Firmata.write (DHT_DATA); Firmata.write (current_pin); Firmata.write (trenutni_tip); 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 koji se koristi za komunikaciju s DHT uređajem izveden je izravno iz knjižnice DHTNew:

int readDhtSensor (int indeks) {

// INIT BUFFERVAR ZA PRIMANJE PODATAKA uint8_t mask = 128; uint8_t idx = 0; // PRAZNI BUFER // memset (_bit, 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) vrati DHTLIB_ERROR_TIMEOUT;} if ((micros ()-t)> 40) {_bits [idx] | = mask;} mask >> = 1; if (mask == 0) // sljedeći bajt? {Mask = 128; idx ++;}} vrati DHTLIB_OK;}

Korak 4: Izmjena Pymata4 za DHT podršku

private_constants.h

Da bismo podržali DHT, ovoj datoteci moramo dodati i nove pin-type i SysEx poruke:

# pin načina INPUT = 0x00 # pin je postavljen kao ulaz OUTPUT = 0x01 # pin je postavljen kao izlaz ANALOG = 0x02 # analogni pin u analognom načinu ulaza PWM = 0x03 # digitalni pin u načinu rada PWM izlaza SERVO = 0x04 # digitalni pin u načinu Servo izlaza I2C = 0x06 # pin uključen u postavljanje I2C STEPPER = 0x08 # bilo koji pin u stepper modu SERIAL = 0x0a PULLUP = 0x0b # Bilo koji pin u modu pullup SONAR = 0x0c # Bilo koji pin u SONAR načinu TONE = 0x0d # Bilo koji pin u ton načinu PIXY = 0x0e # rezervirano za način rada pixy kamere DHT = 0x0f # DHT senzor IGNORE = 0x7f # Poruke naredbe DHT SysEx DHT_CONFIG = 0x64 # dht konfiguracijska naredba DHT_DATA = 0x65 # dht odgovor senzora

Dodani tip pina i naredbe SysEx moraju odgovarati vrijednostima u FirmataConstants.h dodane u FirmataExpress.

pymata4.py

Pymata4 koristi rječnik Python za brzo povezivanje dolazne poruke Firmata s rukovateljem porukama. Naziv ovog rječnika je report_dispatch.

Format unosa u rječnik je:

{MessageID: [message_handler, broj bajtova podataka za obradu]}

U rječnik je dodan unos za obradu dolaznih DHT poruka:

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

7 bajta podataka u poruci su broj digitalnog PIN -a Arduino, vrsta DHT uređaja (22 ili 11) i 5 bajtova neobrađenih podataka.

Metoda _dht_read_response provjerava ima li prijavljenih pogrešaka. Ako nema prijavljenih pogrešaka, vlažnost i temperatura se izračunavaju pomoću algoritma prenesenog iz Arduino DHTNew knjižnice.

Izračunate vrijednosti se prijavljuju putem metode povratnog poziva koju je dobavio korisnik. Također su pohranjeni u internoj strukturi podataka pin_data. Posljednja prijavljena vrijednost može se pozvati anketiranjem pin_data metodom dht_read.

Konfiguriranje novog DHT uređaja

Prilikom dodavanja novog DHT uređaja poziva se metoda set_pin_mode_dht. Ova metoda ažurira pin_data za digitalne pinove. Također stvara i šalje DHT_CONFIG SysEx poruku na FirmataExpress.

Korak 5: Zaključak

Kao što smo vidjeli, dodavanje Firmata podrške za novi uređaj zahtijeva od vas da promijenite kod poslužitelja Arduino FirmataExpress i klijentski kod Pymata4 temeljen na Pythonu. Otklanjanje pogrešaka u kodu FirmataExpress može biti izazovno. Metoda zvana printData dodana je FirmataExpressu radi lakšeg otklanjanja pogrešaka. Ova vam metoda omogućuje slanje podatkovnih vrijednosti s FirmataExpress -a i ispisat će ih na konzoli pymata4.

Ova funkcija zahtijeva i pokazivač na niz znakova i vrijednost koju želite vidjeti. Ako je vrijednost podataka sadržana u varijabli koja se zove argc, možete pozvati printData sa sljedećim parametrima.

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

Ako imate pitanja, ostavite komentar, a ja ću vam rado odgovoriti.

Sretno kodiranje!

Preporučeni: