konvertálja a 32 bites hosszúságot 4 bájtra és vissza – CAN busz

Tehát 2 nap próbálkozás után nem tudom a fejemet körbejárni.

Tehát CAN buszt használok a gyorsulásmérő és az időadatok átadására (a micros () függvény, ha 71 perc alatt olyan adatokat ad ki, amelyek előjel nélkül is hosszúak lehetnek), azonban az adatokat bájtként kell küldenem. sikerült egy 16 bites int-et 2 bájtra váltani, de gondom van a módszer későbbi hozzáadásával (később hozzáadom) a hosszúságok használatához. Problémáim vannak az unió módszer megértésével, mivel új vagyok a saját funkcióim létrehozásában, szóval hogyan srácok megvalósítanátok ezt? A lehető legegyszerűbben kérem 🙂

Megjegyzések

  • levonja a maximális 3 bájtot az összesből, és hogy kivonja a maximális 2. bájtot a 3. bájt megszerzéséhez. A 4. bájt csak max. 4 bájt mínusz szám mínusz max. 3 bájt +1.

Válasz

A bitshifting és bitenként és operátorok.

Íme egy példa, amely lehetővé teszi a kivonatot long változójának egyes bájtjai. Szerintem egyszerűnek kell lennie, ha kiterjesztjük a különböző hosszúságú változókra:

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); } 

Attól függően, hogy melyik bájtsorrend (várhatóan nagy vagy kis endian) várható, át kell rendezni a bájtokat elküldés előtt vagy a fogadás után.

Megjegyzések

  • Nagyon egyszerű és könnyen érthető az elv, ezért köszönöm, de a " rekonstruálva " csak 5678-at nyomtat?
  • Másolta a kódrészletet a válaszomból? Mert ha a nodemcun futtatom a kódot, akkor a helyes választ kapom.
  • Igen, átmásoltam és beillesztettem a kódot, hozzáadtam a void setup (); és a Serial.begin (9600); hogy a kód futhasson az arduino nano-omon
  • alapértelmezés szerint egy 8 bites AVR-en, az egyenlő jobb oldalán az alapértelmezett érték int armetmetika, amely tizenhat bites előjelű. Tehát a tömböt egy uint32_t-re dobtam a ciklusban. Nem biztos abban, hogy ez a leghatékonyabb módszer, de működik! Köszönöm a segítséget
  • igen. Nem gondoltam ' az arduino vezérlőre, amikor megpróbáltam a nodemcut.

Válasz

A union típus hasonló egy struct típushoz, azzal a különbséggel, hogy az elem minden tagja elfoglalja az ugyanaz az emlék. Ha úgy határoz meg egy struct -t, hogy annak 2 tagja legyen – egy 4 bájtos és egy 4 bájtos tömb egyetlen bájt típusból, akkor könnyen hivatkozhat ugyanazokra az adatokra egész 4 bájtos elemként, vagy bájt szerint, amire vágysz.

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

Ez a típus, ezért a változót deklarálnod kell ez a típus:

packed_long mydata; 

Most a mydata két aleleme van: l és b[].

long értékének mentéséhez írjon a l rész:

mydata.l = myaccel.getY(); 

A 4 bájt eléréséhez:

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

A fogadó végén a 4 bájt mindegyikét elveszi:

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

Amíg a bájtokat ugyanabban a sorrendben kapja meg amelyben elküldte őket, mostantól elérheti long értékét a mydata.l mezőben.

A különböző fájlok tényleges mérete típusok az a fordítótól és az architektúrától függ, ezért érdemes meghatároznia az értékét egy meghatározott méretű változóként is, hogy mindig 32 bittel dolgozzon: int32_t (32 bites egész szám ) vagy uint32_t (aláíratlan 32 bites egész szám).

Válasz

Hosszú küldési módszer az LSB byte (CAN szabvány) eltakarása és elküldése, majd a a következő az LSB pozícióba, 4 bájtért:

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 } // 

Megjegyzések

  • OK, tehát CAN szabványos az LSB az első. Mivel ismeri a CAN-t, abból, amit találok, 8 bájtos csomagot küldenek, ezek közül csak egy vagy kettő az adat? Tehát összesen 16 bájt információhoz 8 csomagra lenne szükség?
  • Elkaptál! Ez ' mindenről tudok, amit a CAN buszról tudok, és ez a Wikipédiából származott . Sok CAN-busz dokumentáció található online; az a cikk ' s bibliográfiája jó kiindulópont.
  • 8 bájt egy szabványos can-frame adat hasznos terhelésének nagysága. tehát két standard képkockára van szükség 16 bájtos információ küldéséhez. az újabb can-fd 64 bájt adat hasznos terhelést támogat képkockánként.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük