16bit werte über I2C senden

Gast #4370133
Lesenswert?
• ▲
▼
Hallo,

Ich möchte einen 16bit wert über I2C senden. Meine Sendefunktion lautet 
wie folgt
1
void I2cBigWrite(int bigVal) {  
2
  Wire.write((byte *)&bigVal, sizeof(int));
3
}
Und empfangen wird es wie folgt:
1
uint8_t receivedbyte = Wire.read();
2
    RS422.print("LOW Byte: ");
3
    RS422.println(receivedbyte);
4
    // Read high byte into buffer
5

6
    receivedbyte = Wire.read() ;
7
    RS422.print("HIGH Byte: ");
8
    RS422.println(received byte);

Wenn ich jedoch bspw den Wert 1000 Sende erhalte ich folgendes:

LOW Byte: 232
HIGH Byte: 255


Wie setze ich das nun zusammen um nachher wieder den Wert 1000 zu 
bekommen?

Vielen Dank!

Grüße

Peter
#4370139
Lesenswert?
• ▲
▼
@ Peter (Gast)

>Wenn ich jedoch bspw den Wert 1000 Sende erhalte ich folgendes:

Wer sendet 1000?

>LOW Byte: 232
>HIGH Byte: 255

232*256 + 255 = 59647

Das kann so oder so niemals 1000 sein.

>Wie setze ich das nun zusammen um nachher wieder den Wert 1000 zu
>bekommen?

Highbyte * 256 + Lowbytes
(Firma: Vescomp) #4370152
Lesenswert?
• ▲
▼
Peter schrieb:
> Wenn ich jedoch bspw den Wert 1000 Sende erhalte ich folgendes:
>
> LOW Byte: 232
> HIGH Byte: 255
>
> Wie setze ich das nun zusammen um nachher wieder den Wert 1000 zu
> bekommen?

 1000d = 3E8h
 E8h = 232d

 Also, LowByte ist richtig, ob und wie und was du da als HighByte
 sendest ist fraglich.
 IdleLine ergibt 255, uberprufe nochmal deine Senderoutine.
Gast #4370323
Lesenswert?
• ▲
▼
Okay, habe mal meine Sendefunktion überarbeitet, sie Schluckt jetzt nur 
16bit variablen:
1
void I2cBigNum(int16_t bigNum){
2
    byte myArray[2];
3
    myArray[0] = (bigNum >> 8);
4
    myArray[1] = bigNum ;
5
    Wire.write(myArray, 2);
6
}

Meine Empfängerfunktion ist diese:
1
    
2
uint8_t low = Wire.read();
3
    RS422.print("LOW Byte: ");
4
    RS422.println(low);
5
    // Read high byte into buffer
6

7
   uint8_t high= Wire.read() ;
8
    RS422.print("HIGH Byte: ");
9
    RS422.println(high);
10

11
    RS422.print("Gesamtbyte :");
12
    uint16_t voll= low;
13
    voll = voll << 8 | high;
14
    RS422.println(voll);

Das Ergebnis lautet dann jedoch 1023, anstatt 1000... Teste ich es mit 
1050 anstatt 1000 ist das Ergebnis 1279. Gibt es dazu eine Erklärung?
Gast #4370437
Lesenswert?
• ▲
▼
Peter schrieb:
> Gibt es dazu eine Erklärung?

Die Arduino Help gibt folgendes Besipiel.
1
void loop()
2
{
3
  Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2
4
  while(Wire.available())    // slave may send less than requested
5
  {
6
    char c = Wire.read();    // receive a byte as character
7
    Serial.print(c);         // print the character
8
  }
9
  delay(500);
10
}

Entscheidend ist wohl dass du deinem AVR erst sagen musst wieviel
du empfangen willst.

Deine jetzige Form verschluckt das zweite Byte vermutlich da
Wire.read() erst ausgerufen wird wenn das 2 Byte schon längst
gesendet wurde.
Gast #4370452
Lesenswert?
• ▲
▼
du schickst ein int16_t und möchtest daraus ein uint16_t zusammenbauen. 
Das geht so nicht, weil die int16_t intern als 2er-Komplement 
dargestellt werden. Entweder musst du also wieder ein int16_t als 
Ausgabe verwenden oder das ganze konvertieren.
Gast #4370497
Lesenswert?
• ▲
▼
Karl schrieb:
> du schickst ein int16_t und möchtest daraus ein uint16_t zusammenbauen.
> Das geht so nicht, weil die int16_t intern als 2er-Komplement
> dargestellt werden. Entweder musst du also wieder ein int16_t als
> Ausgabe verwenden oder das ganze konvertieren.

Das ist ein guter Hinweis: Wenn du in C++ auf eine `signed` Variable den 
`>>` Operator anwendest, dann wird daraus ein arithmetischer 
Rechtsshift, also mit Sign Extension.
Um sicher zu sein könntest du deine 16-bit Werte erst einmal in einen 
unsigned casten. Ein einfacher `static_cast<uint16_t>()` belässt die 
bits im Speicher unangetastet.
Dann kannst du die bits beliebig verschieben, die Daten senden, am 
anderen Ende wieder unsigned zusammenbauen und erst ganz am Schluss 
wieder zurueck casten: `static_cast<int16_t>()`.

Wuerde mich interessieren, ob das vielleicht dein Problem loest.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren