[Android-BLEController] - pwm/analogWrite bug report + solution


#1

I am not sure how many have noticed a major bug in the BLE-Controller application for android devices when trying to transmit pwm values above 127 to the blend micro leads to an error…

In order to visualise this bug, download on an ios from app store the BLEController app, lets say pins 9,10,11 are rgb pwm pins, you can easily turn them on and off using the slider for pin 9…

do the same with the android application from google play, and you will notice you aren’t capable of sending it values above 127 (the maximum is set to 130 on slider, lets assume you remove this non-making sense maximum) ending up not being able to send half of the 8bit field of values…

Currently i fixed it and put a pull request with the bug solved, now in order to understand how deep down it lays and why would it work on IOS and not on Android…

3 classes are effected, the least important is StandardViewFragmentForPinsEx.java where PWM pins are being configured into a maximum value of 130, lets change it to 255 as it is suppose to be.

the other two are

  1. RBLProtocol.java [method effected analogWrite(int pin, int value), write(char[] data)]
  2. RedBearService.java [method writeValue(String address, char[] data)]

In the implementation RedBear are taking as input an int value and casting it into a char(1) and placing it into a char array , after wards this char array being send to the write method and to the RedBearService.writeValue method, there the array will be used to construct a String(2) that will be written to the device.

Now in Java the default charset used when you create a string from char array is UTF-16, meaning every char value is treated as 16 bits, when you create a string from a char array you take the “signature” of the number that represents the digit you are going to place in the string, this digit that has been written by the original value, isn’t the same digit that the ble_read method knows to handle, the reason behind it, is that an Arduino byte is unsigned 8bit, while you sent 16bit value, which explains, why value above 127 would end up with an error or worse as the wrong value…

This is an open door for a lot of bugs along the way that i will not describe here because they can be solved easily, by instead of writing a String with the txCharc.setValue(writeValue method) we will use the overloaded method that receives byte[] array named also setValue(added analogWrite, and write methods that supports writing byte array instead of char array)

Link to fix(pull request): https://github.com/RedBearLab/Android/pull/9


#2

I saw this bug in https://mobile-spy-apps.com mobile recorder on Android.