ByteArray requestWrite

Hi,

I am trying to send location information to a ble peripheral. Hence must convert the Float (Double) location and altitude to a ByteArray to pass the the requestWrite.
I have tried various stuff but keep getting exceptions....

	function notifyLocationChange( lati, longi, elev ){
		var ba = new[12]b;
		var latiArray = new[4]b;
		var longiArray = new[4]b;
		var elevArray = new[4]b;
		if( _characteristic != null ){
			latiArray.addAll( ByteArray.encodeNumber(52.95, Lang.NUMBER_FORMAT_FLOAT, null ));
			longiArray.addAll( ByteArray.encodeNumber( 1.16, Lang.NUMBER_FORMAT_FLOAT, null ));
			elevArray.addAll( ByteArray.encodeNumber( 400.0, Lang.NUMBER_FORMAT_FLOAT, null ));
			//ba = ByteArray.encodeNumber(lati, Lang.NUMBER_FORMAT_FLOAT, null );
			//ba.addAll( ByteArray.encodeNumber( longi, Lang.NUMBER_FORMAT_FLOAT, null ));
			//ba.addAll( ByteArray.encodeNumber( elev, Lang.NUMBER_FORMAT_FLOAT, null ));
			_characteristic.requestWrite( ba, {:writeType => Ble.WRITE_TYPE_DEFAULT} );
		}
	}

and whatever I seem to try I get....

Error: Unhandled Exception
Exception: UnexpectedTypeException: Expected ByteArray, given Object
Stack: 
  - notifyLocationChange() at C:\NordicSemi
RF5_SDK_15.3.0_59ac345\examples\Incus_Performance\garmin\NovaThingy\source\EnvironmentProfileModel.mc:40 0x1000108c 
  - onPosition() at C:\NordicSemi
RF5_SDK_15.3.0_59ac345\examples\Incus_Performance\garmin\NovaThingy\source\PositionSampleView.mc:66 0x10000e87 

Have tried various combinations?
I am also confused by Float; is this a base type of an object?
What is the difference between...

var x = new [12]b; and a ByteArray? Are they synonymous?

Regards,

Owain

  • OK applied Jims answer....

    https://forums.garmin.com/developer/connect-iq/f/discussion/210596/bytearray-encodenumber-example

    	function notifyLocationChange( lati, longi, elev ){
    		var locArray = new[12]b;
    		var latiArray = new[4]b;
    		var longiArray = new[4]b;
    		var elevArray = new[4]b;
    		if( _characteristic != null ){
    			latiArray.encodeNumber(lati, Lang.NUMBER_FORMAT_FLOAT, null );
    			longiArray.encodeNumber(longi, Lang.NUMBER_FORMAT_FLOAT, null );
    			elevArray.encodeNumber(elev, Lang.NUMBER_FORMAT_FLOAT, null );
    			locArray.addAll( latiArray );
    			locArray.addAll( longiArray );
    			locArray.addAll( elevArray );
    			_characteristic.requestWrite( locArray, {:writeType => Ble.WRITE_TYPE_DEFAULT} );
    		}
    	}

    but the hit log write exception????

    Error: Unhandled Exception
    Exception: Long Writes are not supported
    Stack: 
      - notifyLocationChange() at C:\NordicSemi
    RF5_SDK_15.3.0_59ac345\examples\Incus_Performance\garmin\NovaThingy\source\EnvironmentProfileModel.mc:46 0x10001108 
      - onPosition() at C:\NordicSemi
    RF5_SDK_15.3.0_59ac345\examples\Incus_Performance\garmin\NovaThingy\source\PositionSampleView.mc:66 0x10000e87 

  • locArray is too large. You're creating a 12 byte array, then appending another 12 bytes to the end of it with the addAll() calls. The maximum size is 20 bytes but you're trying to send 24.

    From the documentation for addAll():

    "When adding an Array of Objects, the Array is expanded by the size of the provided Array, and all of the new elements are inserted starting at the new index."

    So addAll is expanding to fit the contents of the new array, and sticking them at the end.

    Initialize locArray to an empty array instead of a 12 byte array. 

  • Also, the documentation for ByteArray says the same thing. addAll() is really more of an "appendAll" operation.

    locArray = new[0]b;

    .....

    locArray.addAll(latiArray);

    locArray.addAll(longiArray);

    locArray.addAll(elevArray);

    ..... 

  • Another option would be to create a byte array that's large enough and then use an :offset in encodeNumber

  • Super; used :offset option for the requestWrite; eureeka.....hit breakpoint in  peripheral; has received some location data.
    I just now need to throttle the writeRequest; do one is finished before the next is requested.

    It would also be good to limit the rate of location data arriving in the app.

  • Yes, you meed to do queueing.  The nordic sample does that, and I do it in the raspberry pi samples I posted:

    https://forums.garmin.com/developer/connect-iq/b/news-announcements/posts/would-you-like-some-raspberry-pi-with-your-connect-iq

    CommQueue.mc in the CIQ apps is the main code, and in the view I add to the queue, in the bledelegat, run the queue, etc..

    I also have logic for time outs, so in the event you don't hear back, things reset.