INHOUDSOPGAWE:

Going Beyond Standard Firmata - hersien: 5 stappe
Going Beyond Standard Firmata - hersien: 5 stappe

Video: Going Beyond Standard Firmata - hersien: 5 stappe

Video: Going Beyond Standard Firmata - hersien: 5 stappe
Video: Тонкости работы с монтажной пеной. То, что ты не знал! Секреты мастеров 2024, Julie
Anonim
Going Beyond Standard Firmata - hersien
Going Beyond Standard Firmata - hersien

'N Kort rukkie gelede is ek deur dr Martyn Wheeler, 'n pymata4 -gebruiker, gekontak vir leiding oor die toevoeging van ondersteuning vir die DHT22 humiditeits-/temperatuursensor by die pymata4 -biblioteek. Met die pymata4 -biblioteek, in samewerking met sy Arduino -eweknie, FirmataExpress, kan gebruikers hul Arduino -toestelle op afstand beheer en monitor. Binne 'n paar rondes e -posuitruilings was dr Wheeler suksesvol in die aanpassing van beide pymata4 en FirmataExpress. As gevolg hiervan is ondersteuning vir die DHT22- en DHT11 -sensors nou 'n standaardonderdeel van pymata4 en FirmataExpress.

In Mei 2014 het ek 'n artikel geskryf oor die toevoeging van ondersteuning by Firmata vir ekstra toestelle. As ek nadink oor die eerste artikel, het ek besef hoeveel daar verander het sedert ek die papier op papier geneem het. Benewens hierdie artikel, het dr Wheeler sy pogings gedokumenteer, en u sou dit ook wou ondersoek.

FirmataExpress is gebaseer op StandardFirmata, en die StandardFirmata -gidsstruktuur het ontwikkel. Boonop is die pymata4 API ook heelwat anders as die oorspronklike PyMata API van 2014. Ek het gedink dit sou die perfekte tyd wees om die artikel weer te besoek en by te werk. Met die werk van Dr. Wheeler as 'n basis, laat ons ondersoek hoe ons die funksie van pymata4/FirmataExpress kan uitbrei.

Voordat ons begin - 'n bietjie agtergrondinligting oor Arduino/Firmata

So, wat is Firmata? Op die Firmata -webblad, "Firmata is 'n generiese protokol vir kommunikasie met mikrobeheerders vanaf sagteware op 'n gasheerrekenaar."

Arduino Firmata gebruik 'n seriële koppelvlak om beide opdrag- en verslaginligting tussen 'n Arduino -mikrobeheerder en 'n rekenaar te vervoer, gewoonlik met 'n seriële/USB -skakel op 57600 bps. Die data wat oor hierdie skakel oorgedra word, is binêre, en die protokol word geïmplementeer in 'n kliënt/bedienermodel.

Die bedienerkant word in die vorm van 'n Arduino -skets na 'n Arduino -mikrobeheerder gelaai. Die StandardFirmata -skets, wat by die Arduino IDE ingesluit is, beheer die Arduino I/O -penne, soos beveel deur die kliënt. Dit rapporteer ook veranderings in die invoerpen en ander verslaginligting aan die kliënt. FirmataExpress is 'n uitgebreide weergawe van StandardFirmata. Dit werk teen 'n seriële skakelsnelheid van 115200 bps.

Die Arduino -kliënt wat vir hierdie artikel gebruik is, is pymata4. Dit is 'n Python -toepassing wat op 'n rekenaar uitgevoer word. Dit stuur beide opdragte na en ontvang verslae van die Arduino -bediener. Omdat pymata4 in Python geïmplementeer is, werk dit op Windows, Linux (insluitend Raspberry Pi) en macOS -rekenaars.

Waarom Firmata gebruik?

Arduino -mikrobeheerders is wonderlike klein toestelle, maar verwerker- en geheuehulpbronne is ietwat beperk. Vir toepassings wat verwerker of geheueintensief is, is daar dikwels weinig ander keuse as om die hulpbronvraag op 'n rekenaar af te laai sodat die toepassing suksesvol kan wees.

Maar dit is nie die enigste rede waarom u StandardFirmata gebruik nie. By die ontwikkeling van ligter gewig Arduino -toepassings, kan 'n rekenaar gereedskap en ontfoutingsfunksies bied wat nie direk op 'n Arduino -mikrobeheerder beskikbaar is nie. Die gebruik van 'n 'vaste' kliënt en bediener help om die kompleksiteit van die toepassing te beperk tot 'n rekenaar wat makliker bestuur kan word. Sodra die toepassing vervolmaak is, kan dit vertaal word in 'n persoonlike, selfstandige Arduino -skets.

Waarom Pymata4 gebruik?

As skrywer daarvan is ek natuurlik bevooroordeeld. Dit gesê, dit is die enigste Python-gebaseerde Firmata-kliënt wat die afgelope paar jaar voortdurend onderhou is. Dit bied 'n intuïtiewe en maklik om te gebruik API. Benewens StandardFirmata-gebaseerde sketse, ondersteun dit Firmata via WiFi vir toestelle soos die ESP-8266 by die gebruik van die StandardFirmataWifI-skets.

Pymata4 is ook ontwerp om maklik deur 'n gebruiker uitgebrei te word om addisionele sensors en aandrywers wat tans nie deur StandardFirmata ondersteun word nie, te ondersteun.

Stap 1: Verstaan die Firmata -protokol

Verstaan die Firmata -protokol
Verstaan die Firmata -protokol

Die Arduino Firmata-kommunikasieprotokol is afgelei van die MIDI-protokol, wat een of meer 7-bis grepe gebruik om data voor te stel.

Firmata is ontwerp om deur gebruikers uitbreidbaar te wees. Die meganisme wat hierdie uitbreidbaarheid bied, is die System Exclusive (SysEx) boodskapprotokol.

Die formaat van 'n SysEx -boodskap, soos gedefinieer deur die Firmata -protokol, word in die bostaande illustrasie getoon. Dit begin met 'n START_SYSEX -byte met 'n vaste waarde van heksadesimale 0xF0, en word gevolg deur 'n unieke SysEx -opdragbyte. Die waarde van die opdragbyte moet binne die heksadesimale reeks 0x00-0x7F wees. Die opdragbyte word dan gevolg deur 'n ongespesifiseerde aantal 7-bis data-grepe. Laastens word die boodskap beëindig met 'n END_SYSEX -greep, met 'n vaste waarde van heksadesimale 0xF7.

Firmata Data Encoding/Decoding

Aangesien die gebruikersdata-gedeelte van 'n SysEx-boodskap uit 'n reeks 7-bis grepe bestaan, wonder u miskien hoe 'n waarde groter is as 128 (0x7f)? Firmata kodeer hierdie waardes deur dit in meer as 7-bis byte te demonteer voordat die data oor die dataskakel versprei word. Die minste belangrike byte (LSB) van 'n data -item word eers gestuur, gevolg deur toenemend belangrike komponente van die data -item volgens konvensie. Die belangrikste byte (MSB) van die data -item is die laaste data -item wat gestuur is.

Hoe werk dit?

Gestel ons wil 'n waarde 525 in die datagedeelte van 'n SysEx -boodskap opneem. Aangesien 'n waarde van 525 duidelik groter is as 'n waarde van 128, moet ons dit in 7-byte "stukke" verdeel of uitmekaar haal.

Hier is hoe dit gedoen word.

Die waarde van 525 in desimale is gelykstaande aan die heksadesimale waarde van 0x20D, 'n 2-byte waarde. Om die LSB te kry, masker ons die waarde deur dit met 0x7F te bedek. Beide "C" en Python implementasies word hieronder getoon:

// "C" implementering om LSB te isoleer

int max_distance_LSB = max_distance & 0x7f; // masker die onderste byte # Python -implementering om LSB max_distance_LSB = max_distance & 0x7F # te masker die onderste byte

Na maskering bevat max_distance_LSB 0x0d. 0x20D & 0x7F = 0x0D.

Vervolgens moet ons die MSB isoleer vir hierdie 2-byte waarde. Om dit te doen, skuif ons die waarde van 0x20D na regs, 7 plekke.

// "C" implementering om MSB van 2 byte waarde te isoleer

int max_distance_MSB = max_distance >> 7; // skuif die groot orde byte # Python implementering om MSB van 2 byte waarde max_distance_MSB = max_distance >> 7 # shift te isoleer om die boonste byte te kry Na die verskuiwing sal max_distance_MSB 'n waarde van 0x04 bevat.

As die 'ingedrukte' ingewikkelde data ontvang word, moet dit weer in 'n enkele waarde saamgestel word. Hier is hoe die data in beide 'C' en Python weer saamgestel word

// "C" implementering om die 2 byte weer aanmekaar te sit, // 7 biswaardes in 'n enkele waarde int max_distance = argv [0] + (argv [1] << 7); # Python -implementering om die 2 -byte, # 7 -bitwaardes weer in 'n enkele waarde te plaas max_distance = data [0] + (data [1] << 7)

Na die samestelling is die waarde weer gelyk aan 525 desimale of 0x20D heksadesimale.

Hierdie demontage-/hermonteringsproses kan deur die kliënt of die bediener uitgevoer word.

Stap 2: Kom ons begin

Om 'n nuwe toestel te ondersteun, is veranderinge aan beide die Arduino resident -bediener en die PC -resident Python -kliënt nodig. Dr. Wheeler se werk sal gebruik word om die nodige wysigings toe te lig.

Die belangrikste stap is miskien om te besluit of u 'n bestaande biblioteek vir ondersteunende toestelle wil integreer in die Arduino -kant van die vergelyking of u eie wil skryf. Dit word aanbeveel dat as u 'n bestaande biblioteek kan vind, dit baie makliker is om dit te gebruik as om u eie van nuuts af te skryf.

Vir ondersteuning van DHT -toestelle, het Dr. Wheeler sy uitbreidingskode gebaseer op die DHTNew -biblioteek. Heel slim verdeel Dr. Wheeler die funksionaliteit van die DHTNew -biblioteek oor die Arduino- en pymata4 -kante van die vergelyking om minimale blokkering aan die Arduino -kant te verseker.

As ons na DHTNew kyk, voer dit al die volgende uit:

  • Stel die geselekteerde pin digitale uitsetmodus in.
  • Skakel 'n gekodeerde sein uit om die nuutste humiditeits- en temperatuurwaardes op te haal.
  • Kontroleer of daar foute is en rapporteer dit.
  • Bereken menslike temperatuur- en humiditeitswaardes uit die rou data wat verkry is.

Om dinge so doeltreffend moontlik aan die FirmataExpress -kant te hou, het dr Wheeler die data -omskakelingsroetines van die Arduino na pymata4 afgelaai.

Stap 3: Verander FirmataExpress vir DHT -ondersteuning

Die FirmataExpress -gidsboom

Hieronder is al die lêers wat die FirmataExpress -bewaarplek bevat. Hierdie boom is identies aan dié van StandardFiramata, net dat sommige van die lêernaam die naam van die bewaarplek weerspieël.

Die lêers wat gewysig moet word, is die lêers wat 'n asterisk (*) langs hulle het.

FirmataExpress

├── * Boards.h

├── voorbeelde

│ └── FirmataExpress

│ ├── boardx

│ ├── * FirmataExpress.ino

│ ├── LISENSIE.txt

│ └── Makefile

├── * FirmataConstants.h

├── * FirmataDefines.h

├── FirmataExpress.cpp

├── FirmataExpress.h

├── FirmataMarshaller.cpp

├── FirmataMarshaller.h

├── FirmataParser.cpp

└── FirmataParser.h

Kom ons kyk na elk van die lêers en die veranderinge wat aangebring is.

Rade.h

Hierdie lêer bevat makro-definisies van pen-tipe vir elk van die ondersteunde bordtipes. Dit definieer die maksimum aantal toestelle wat ondersteun word wanneer meer as een toestel ondersteun moet word.

Vir die DHT -toestel kan tot 6 toestelle tegelyk gekoppel word en hierdie waarde word gedefinieer as:

#ifndef MAX_DHTS

#definieer MAX_DHTS 6 #endif

Daarbenewens kan pin-tipe makro's opsioneel vir die nuwe toestel gedefinieer word, óf vir alle bordtipes óf net vir diegene wat vir u interessant is. Hierdie makros word meestal vir rapporteringsdoeleindes gebruik en word nie gebruik om die toestelle te beheer nie. Hierdie makros definieer albei die penne wat die toestel ondersteun:

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

Sowel as 'n makro om 'n speldgetalomskakeling te definieer.

#definieer PIN_TO_DHT (p) PIN_TO_DIGITAL (p)

FirmataConstants.h

Hierdie lêer bevat die weergawe nommer van die firmware, wat u dalk wil verander om tred te hou met die weergawe wat u op u Arduino gelaai het. Dit bevat ook die Firmata -boodskapwaardes, insluitend die Firmata SysEx -boodskappe.

U moet 'n nuwe boodskap of stel boodskappe vir u toestel in hierdie lêer toewys. Vir die DHT is twee boodskappe bygevoeg. Die een stel 'n speld as 'n 'DHT' -speld op, en die ander as 'n verslaggewerboodskap wanneer die nuutste DHT -data na die kliënt teruggestuur word.

statiese const int DHT_CONFIG = 0x64;

statiese const int DHT_DATA = 0x65;

Speldmodusse word ook in hierdie lêer gespesifiseer. Vir die DHT is 'n nuwe pin -modus geskep:

statiese const int PIN_MODE_DHT = 0x0F; // pin opgestel vir DHT

As 'n nuwe speldmodus bygevoeg word, moet die TOTAL_PIN_MODES aangepas word:

statiese konst int TOTAL_PIN_MODES = 17;

FirmataDefines.h

Hierdie lêer moet opgedateer word om die nuwe boodskappe wat by FirmataConstants.h gevoeg is, weer te gee:

#ifdef DHT_CONFIG #undef DHT_CONFIG #endif #define DHT_CONFIG firmata:: DHT_CONFIG // DHT versoek #ifdef DHT_DATA #undef DHT_DATA #endif #define DHT_DATA firmata:: DHT_DATA // DHT_DE_DODE_DDE_DE_DODE_DE_DODDM_DDE_DE_DE_DODE_DDE_DE_DODDM_DDE_DE_DODE_DODE_DE_DE_DODE_DDE_DODE_DODE_DODE_DODE_DE_DODE_DODE_DE_DE:: PIN_MODE_DHT

FirmataExpress.ino

In hierdie bespreking behandel ons die 'hoogtepunte' van die veranderinge wat aan hierdie Arduino-skets aangebring is.

Vir FirmataExpress om tot ses DHT -toestelle gelyktydig te ondersteun, is 3 skikkings geskep om die geassosieerde speldnommer van die toestel, die WakeUpDelay -waarde en die tipe toestel, dit wil sê DHT22 of DHT11, by te hou:

// DHT -sensors

int numActiveDHTs = 0; // aantal DHT's aangeheg uint8_t DHT_PinNumbers [MAX_DHTS]; uint8_t DHT_WakeUpDelay [MAX_DHTS]; uint8_t DHT_TYPE [MAX_DHTS];

Omdat beide toesteltipes ongeveer 2 sekondes tussen lesings benodig, moet ons seker maak dat ons elke DHT slegs een keer in die 2-sekonde tydraamwerk lees. Sommige toestelle, soos die DHT-toestelle en HC-SR04 afstandsensors, word slegs periodiek verkry. Dit gee hulle die tyd om met hul omgewing om te gaan.

uint8_t nextDHT = 0; // indeks in dht vir die volgende toestel om te lees

uint8_t currentDHT = 0; // Hou by watter sensor aktief is. int dhtNumLoops = 0; // Doel hoeveel kere deur lus b4 toegang tot 'n DHT int dhtLoopCounter = 0; // Lus toonbank

Die DHT -toestel instel en lees

As FirmataExpress 'n SysEx -opdrag ontvang om 'n speld vir DHT -operasie op te stel, bevestig dit dat die maksimum aantal DHT -toestelle nie oorskry is nie. As die nuwe DHT ondersteun kan word, word die DHT -skikkings opgedateer. As die DHT -tipe onbekend is, word 'n SysEx -stringboodskap geskep en teruggestuur na pymata4

saak DHT_CONFIG: int DHT_Pin = argv [0]; int DHT_type = argv [1]; if (numActiveDHTs <MAX_DHTS) {if (DHT_type == 22) {DHT_WakeUpDelay [numActiveDHTs] = 1; } anders as (DHT_type == 11) {DHT_WakeUpDelay [numActiveDHTs] = 18; } anders {Firmata.sendString ("ERROR: UNKNOWN SENSOR TYPE, GELDIGE SENSORS IS 11, 22"); breek; } // toets die sensor DHT_PinNumbers [numActiveDHTs] = DHT_Pin; DHT_TYPE [numActiveDHTs] = DHT_tipe; setPinModeCallback (DHT_Pin, PIN_MODE_DHT);

FirmataExpress probeer dan om met die DHT -toestel te kommunikeer. As daar foute is, vorm dit 'n SysEx -boodskap met die foutdata en stuur die SysEx -boodskap terug na pymat4. Die veranderlike _bits bevat die data wat deur die DHT -toestel teruggestuur word vir addisionele verwerking deur pymata4 indien verkies.

Firmata.write (START_SYSEX);

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

As geldige data teruggestuur word, word die aantal aktiewe DHT's toegeneem. 'N Veranderlike wat byhou hoeveel lus -herhalings moet voltooi word voordat die volgende DHT vir data nagegaan word, word ook aangepas. Hierdie veranderlike verseker dat ongeag hoeveel DHT's by die stelsel gevoeg word, dit alles binne 'n tydperk van 2 sekondes gelees sal word.

int rv = readDhtSensor (numActiveDHTs);

as (rv == DHTLIB_OK) {numActiveDHTs ++; dhtNumLoops = dhtNumLoops / numActiveDHTs; // alles in orde}

As een of meer DHT -toestelle in die lusfunksie van die skets opgestel is, word die volgende DHT -toestel gelees. Óf die geldige data óf die foutstatus daarvan word teruggestuur na pymata4 in die vorm van 'n SysEx -boodskap:

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 = volgendeDHT; as (nextDHT ++> = numActiveDHTs - 1) {nextDHT = 0; } if (rv == DHTLIB_OK) {// TEST CHECKSUM uint8_t som = _bits [0] + _bits [1] + _bits [2] + _bits [3]; as (_bits [4]! = som) {rv = -1; }}} // stuur die boodskap terug met 'n foutstatus Firmata.write (START_SYSEX); Firmata.write (DHT_DATA); Firmata.write (huidige_pen); Firmata.write (huidige tipe); vir (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);}}

Die kode wat gebruik word om met die DHT -toestel te kommunikeer, is direk afgelei van die DHTNew -biblioteek:

int readDhtSensor (int indeks) {

// INIT BUFFERVAR OM DATA TE ONTVANG uint8_t mask = 128; uint8_t idx = 0; // LEë BUFFER // memset (_bits, 0, sizeof (_bits)); vir (uint8_t i = 0; i 5 BYTES vir (uint8_t i = 40; i! = 0; i--) {loopCnt = DHTLIB_TIMEOUT; terwyl (digitalRead (pin) == LOW) {if (--loopCnt == 0) gee DHTLIB_ERROR_TIMEOUT terug;} uint32_t t = micros (); loopCnt = DHTLIB_TIMEOUT; terwyl (digitalRead (pin) == HOOG) {if (--loopCnt == 0) gee DHTLIB_ERROR_TIMEOUT;} as ((micros ()-t)> 40) {_bits [idx] | = masker;} masker >> = 1; as (masker == 0) // volgende greep? {Mask = 128; idx ++;}} gee DHTLIB_OK;}

Stap 4: Pas Pymata4 aan vir DHT -ondersteuning

private_konstante.h

Om die DHT te ondersteun, moet ons beide die nuwe pin-tipe en SysEx-boodskappe by hierdie lêer voeg:

# penmodusse INPUT = 0x00 # pen ingestel as invoer UITGANG = 0x01 # pen ingestel as uitset ANALOG = 0x02 # analoog pen in analoog Invoermodus PWM = 0x03 # digitale pen in PWM -afvoermodus SERVO = 0x04 # digitale pen in Servo -uitvoermodus I2C = 0x06 # pen ingesluit in I2C -opstelling STEPPER = 0x08 # enige pen in stepper -modus SERIEEL = 0x0a PULLUP = 0x0b # Enige pen in pullup -modus SONAR = 0x0c # Enige pen in SONAR -modus TONE = 0x0d # Enige pen in toon -modus PIXY = 0x0e # voorbehou vir pixy -kamera -modus DHT = 0x0f # DHT -sensor IGNORE = 0x7f # DHT SysEx -opdragboodskappe DHT_CONFIG = 0x64 # dht config -opdrag DHT_DATA = 0x65 # dht sensor antwoord

Die bygevoegde pin -tipe en SysEx -opdragte moet ooreenstem met die waardes in FirmataConstants.h wat by FirmataExpress gevoeg is.

pymata4.py

Pymata4 gebruik 'n Python -woordeboek om vinnig 'n inkomende Firmata -boodskap met 'n boodskaphanteerder te assosieer. Die naam van hierdie woordeboek is report_dispatch.

Die formaat vir 'n woordeboekinskrywing is:

{MessageID: [message_handler, aantal data grepe wat verwerk moet word]}

'N Inskrywing is by die woordeboek gevoeg om inkomende DHT -boodskappe te hanteer:

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

Die 7 grepe data in die boodskap is die Arduino digitale speldnommer, die tipe DHT -toestel (22 of 11) en die 5 grepe rou data.

Die _dht_read_response metode kyk na enige gerapporteerde foute. As daar geen foute aangemeld word nie, word die humiditeit en temperatuur bereken met behulp van die algoritme wat uit die Arduino DHTNew -biblioteek oorgedra word.

Die berekende waardes word aangemeld via 'n terugbelmetode wat deur die gebruiker verskaf word. Hulle word ook in die interne pin_data -datastruktuur gestoor. Die laaste waarde wat gerapporteer word, kan herroep word deur pin_data te peil deur die dht_read -metode te gebruik.

Stel 'n nuwe DHT -toestel op

As u 'n nuwe DHT -toestel byvoeg, word die set_pin_mode_dht -metode genoem. Hierdie metode werk die pin_data vir digitale penne op. Dit skep en stuur ook 'n DHT_CONFIG SysEx -boodskap na FirmataExpress.

Stap 5: Inpak

Soos ons gesien het, moet u die byvoeging van Firmata-ondersteuning vir 'n nuwe toestel, die Arduino FirmataExpress-bedienerkode en die Python-gebaseerde pymata4-kliëntkode verander. FirmataExpress -kode kan 'n uitdaging wees om te ontfout. 'N Metode genaamd printData is by FirmataExpress gevoeg om te ontfout. Met hierdie metode kan u datawaardes vanaf FirmataExpress stuur en dit op die pymata4 -konsole druk.

Hierdie funksie vereis beide 'n wyser na 'n tekenreeks en die waarde wat u wil sien. As die datawaarde in 'n veranderlike met die naam argc voorkom, kan u printData met die volgende parameters noem.

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

As u enige vrae het, laat dan net 'n opmerking, en ek beantwoord dit graag.

Gelukkige kodering!

Aanbeveel: