int16_t in PHP

Hallo Leute,

ich kämpfe ja noch mit der „Übersetzung“ des BME680 Drivers.

Dort gibt es Byteoperationen die ich mit (msb << 8) | lsb) versucht habe in PHP abzubilden, doch scheint nicht immer zu funktionieren, die Ergebnisse passen nicht ganz… Hier ist mir aufgefallen, dass dabei offensichtlich auch teilweise negative Werte herauskommen!:confused:

Im Original sind bei der mathematischen Operation tatsächlich einige mit uint16_t definiert, das „u“ steht dabei offensichtlich für „unsigned“, also vorzeichenlos.
Teilweise sind sie aber auch als int16_t definiert, was dann auch zu negativen Werten führen kann…

Wie kann ich das in PHP nachbilden?

Joachim

Zeigt doch mal was du hast, und was du brauchst. Bei dem Link habe ich dein Problem jetzt nicht auf anhieb gefunden.
Grundsätzlich gehen Bit Operationen in PHP genauso.
PHP: Bit-Operatoren - Manual
Sehe ich das richtig, das du im Endeffekt die ganze Lib hier nachbauen musst, weil du I2C sprechen willst; nur über PHP?

Viel Spaß :wink: :smiley:

Michael

Hallo Michael,

ich vermute nun, das es bei es sich den „int16_t“ um Bitfolgen im „2’s complement“ handelt, da gibt das höchste Bit (bei der Definition wahrscheinlich das 16.) Auskunft darüber ob es eine positive oder negative Zahl ist. Wenn das so stimmt muss ich wohl prüfen, ob der Wert größer 32.768 (2 hoch 15) ist und dann denn „negativen Wert“ herausfinden…
Gibt da bestimmt etwas.

Ja, ich habe für alle meine Devices die Vorlagen - manchmal gab es ja auch welche in PHP - für die Module angepasst oder mich tapfer durch das Datenblatt gearbeitet. Andere machen Kreuzworträtsel oder Sodoku!:smiley:

Joachim

Du kannst mit unpack 2Byte in eine vorzeichenbehaftete Zahl wandeln.
Selber prüfen ob das höchste Bit gesetzt ist muss man also nicht.
Deswegen sagte ich ja, das Beispiele gut wären :wink:
Michael

…habe etwas gefunden und angepasst:

private function bin16dec($dec) 
	{
	    	// converts 16bit binary number string to integer using two's complement
	    	$BinString = decbin($dec);
		$DecNumber = bindec($BinString) & 0xFFFF; // only use bottom 16 bits
	    	If (0x8000 & $DecNumber) {
			$DecNumber = - (0x010000 - $DecNumber);
	    	}
	return $DecNumber;
	}  
	    
	private function bin8dec($dec) 
	{
	    	// converts 16bit binary number string to integer using two's complement
	    	$BinString = decbin($dec);
		$DecNumber = bindec($BinString) & 0xFF; // only use bottom 16 bits
	    	If (0x80 & $DecNumber) {
			$DecNumber = - (0x0100 - $DecNumber);
	    	}
	return $DecNumber;
	}    

…und jetzt passt das Ergebnis schon deutlich besser!!:smiley:

Vielen Dank für den „Tritt“ in die richtige Richtung!

Joachim

Also statt bin16dec müsste auch unpack(‚s‘,$value) funktionieren.
Diesen hin und her wandeln nach einem String aus Nullen und Einsen kann man sich glaube ich sparen.
Und klein s für 8 Bit.
Michael