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.