Muunna 32-bittinen pituus 4 tavuksi ja takaisin – CAN-väylä

Joten kahden päivän yrityksen jälkeen en pääse pääni sen ympärille.

Joten käytän CAN-väylää kiihtyvyysmittarin ja aikatietojen siirtämiseen (mikros () -toiminto, jos alle 71 minuuttia tuottaa tietoja, jotka voivat olla allekirjoittamattomia pitkiä), mutta minun on lähetettävä tiedot tavuina. onnistui siirtämään 16-bittisen intin 2 tavuun, mutta minulla on vaikeuksia menetelmän ekstrapoloinnissa (lisätään myöhemmin) pitkien käyttämiseen. Minulla on vaikeuksia ymmärtää unionimenetelmää, koska olen uusi omien toimintojeni luomisessa, joten miten Voisitko saavuttaa tämän? Mahdollisimman yksinkertainen 🙂

Kommentit

  • vähennät enimmäistavun 3 kokonaismäärästä ja joka vähentää enimmäistavun 2, voi olla tavun 3 saaminen. tavu 4 on vain suurin tavu 4 miinus numero vähennettynä suurin tavu 3 +1.

vastaus

Voit saavuttaa haluamasi käyttämällä bitshifting ja bittiä ja operaattoreita.

Tässä on esimerkki, jonka avulla voit purkaa muuttujan long yksittäiset tavut. Mielestäni sen on oltava suoraviivaista laajentaa se eripituisiin muuttujiin:

void loop() { long a=0x12345678, c=0; byte b[4]; Serial.println("Original:"); Serial.println(a,HEX); delay(1000); Serial.println("Individual bytes:"); for (int i=0; i<4; i++) { b[i]=((a>>(i*8)) & 0xff); //extract the right-most byte of the shifted variable Serial.println(b[i],HEX); delay(1000); } for (int i=0; i<4; i++) { c+=b[i]<<(i*8); } Serial.println("Reconstructed:"); Serial.println(c,HEX); delay(1000); } 

Riippuen tavujärjestyksestä (iso tai pieni endiaani), saatat ehkä täytyy tavut järjestää uudelleen ennen lähettämistä tai vastaanottamisen jälkeen.

Kommentit

  • Erittäin suoraviivainen ja helppo ymmärtää periaate, joten kiitos, kuitenkin kohdassa " rekonstruoitu " se tulostaa vain 5678?
  • Kopioitko koodinpätkän vastauksestani? Koska jos suoritan koodin nodemcussa, saan oikean vastauksen.
  • Kyllä, kopioin ja liitin koodin, lisäsin tyhjät asetukset (); ja Serial.begin (9600); saada koodi toimimaan arduino nanossa
  • oletusarvoisesti 8-bittisellä AVR: llä, yhtälön oikealla puolella on oletusarvo int aritmeettinen, joka on allekirjoitettu kuusitoista bittiä. Joten heitin matriisin silmukan uint32_t: lle. Etkö ole varma, onko se tehokkain tapa, mutta se toimii! Kiitos avustasi
  • kyllä oikein. En ajatellut ' ajatellut arduino-ohjainta, kun yritin nodemcua.

Vastaa

union -tyyppi on samanlainen kuin struct, paitsi että kukin elementin jäsenistä miehittää sama muisti. Jos määrität struct siten, että siinä on 2 jäsentä – yksi 4-tavuinen tyyppi ja yksi 4-elementtinen matriisi yhden tavun tyypistä, voit helposti viitata samoihin tietoihin kokonaisuutena 4-tavuisena elementtinä tai tavuina haluamallasi tavalla.

union packed_long { long l; byte b[4]; }; 

Tämä on tyyppi, joten sinun on ilmoitettava muuttujan olevan kyseinen tyyppi:

packed_long mydata; 

Sinulla on nyt kaksi div-osaa: mydata: l ja b[].

Jos haluat tallentaa long -arvosi, kirjoita l osa:

mydata.l = myaccel.getY(); 

Pääset kaikkiin 4 tavuun seuraavasti:

byte1 = mydata.b[0]; byte2 = mydata.b[1]; byte3 = mydata.b[2]; byte4 = mydata.b[3]; 

Vastaanottopäässä otat kaikki 4 tavua:

mydata.b[0] = canbus.read(); mydata.b[1] = canbus.read(); mydata.b[2] = canbus.read(); mydata.b[4] = canbus.read(); 

Niin kauan kuin saat tavut samassa järjestyksessä jossa lähetit heidät, voit nyt käyttää long -arvoa kohdassa mydata.l.

Erilaisten todellinen koko tyypit on riippuu kääntäjästä ja arkkitehtuurista, joten voit myös halutessasi määrittää arvon tietyn kokoiseksi muuttujaksi varmistaaksesi, että työskentelet aina 32 bitillä: int32_t (allekirjoitettu 32-bittinen kokonaisluku ) tai uint32_t (allekirjoittamaton 32-bittinen kokonaisluku).

vastaus

Tapa lähettää pitkä on peittää ja lähettää LSB-tavu (CAN-standardi), siirtää sitten seuraava LSB-asentoon, 4 tavua:

uint32_t data; // Send to CAN bus LSB-first // This method is destructive; data should be a temp if the // Arduino is to retain the data after sending it. for( uint8_t b = 4; b > 0; --b ){ sendByte(data & 0xFF); // send curr byte data >>= 8; // shift that byte away } // Read from CAN bus for( uint8_t b = 4; b > 0; --b ){ data >>= 8; // make room for byte data |= (readByte() << 8); // read next higher byte } // 

Kommentit

  • OK, joten VOI standardi on ensin LSB. Koska tiedät CAN: n, mistä löydän ne lähettävät 8 tavun paketin, onko vain yksi tai kaksi näistä tiedoista? Tarvitsisiko siis 8 pakettia yhteensä 16 tavua varten tietoja?
  • Sait minut kiinni! Se ' s kaikesta, mitä tiedän CAN-väylästä, ja se oli peräisin Wikipediasta . Verkossa on paljon CAN-väyläasiakirjoja; kyseisen artikkelin ' bibliografia on hyvä alku.
  • 8 tavua on tavallisen can-frame-tiedon hyötykuorman koko. joten tarvitset kaksi vakiokehystä 16 tavun tiedon lähettämiseen. uudempi can-fd tukee 64 tavun datan hyötykuormaa kehystä kohti.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *