I am currently developing a device that uses a Pro Micro micro-controller, an HM10 ble module (I checked and this isn't a BLE-CC41A), and several Android devices. My issue is the connection between the Android and the HM10. A few days ago the connection between these two worked well and I could send and receive messages between these two. Now the Android can see the HM10 module but for some reason it cannot connect. I have tried several applications such as "nRF Connect", "BLE Scanner", and "MSMBle" all with no results.
All seems fine on the Pro Micro side. With the code I am using I can send AT commands to the HM10. In case you were wondering what code I used for the pro micro:
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(9, 8); //RX|TX
void setup(){
Serial.begin(9600);
bluetooth.begin(9600); // default baud rate
Serial.println("AT commands: ");
}
void loop(){
bluetoothCommunication();
serialCommunication();
}
void serialCommunication() {
if(Serial.available() >0){ //read from the Serial and print to the HM-10
bluetooth.write(Serial.read());
}
}
void bluetoothCommunication(){
String readStr; //expect a string like wer,qwe rty,123 456,hyre kjhg, or like hello world,who are you?,bye!,
while (bluetooth.available() > 0) { //read from the HM-10 and print in the Serial
delay(10); //small delay to allow input buffer to fill
char inChar = bluetooth.read(); //gets one byte from serial buffer
readStr += inChar ; //makes the string readString
}
if (readStr.length() >0) {
Serial.println(readStr); //prints string to serial port out
}
}
About the BLE HM10 module I pretty much use the default settings but changed the name and password. I also want to note that I tested with three HM10 modules and none can connect to an Android device.
Has anyone had the same issue? Did Android make an update that made HM10 modules unusable?
Related
I'am trying to make a android tablet communicate with a USB device (STM32 Nucleo).
I developped a sketch available on github :
the mobile application is developped with Xamarin and VS Studio. It acts as usb host
the STM32 Nucleo application is developped with STMCube and uses it's USB stack to act as a CDC device.
I developped a small master/slave protocol to echange "register" id/value. The device is the slave.
I managed to make it work using the Android.hardware.usb API.
But I must use a native C shared object library for communication as it used on other platform, and that's where I am having trouble now.
I embbeded the library using swig and build it with VS Studio.
I tried two ways to make the library communicate with the device :
From the Android side get permission and fd and pass it to the library that does standard read/write opérations.
From the Android do the same as above, but also pass with fd the endpoints numbers that uses the linux usbdevice_fs API to call bulk transfers; more o less like presented at that question.
Both methods fail and returns an error about the fd that does not exist. I checked the fd and and enpoints values, they're same as the Android.
I launched the android usb device monitor, I can't find the created fd. I can't use any android shell like termux to list the process /proc tree.
But still I can use tehm in the Android side.
From the community I checked that passing fd to the native library is the right method.
I don't know what to do now, is there some more permission to ask ?
Below is how I retrieve the fd :
_devHandle.usbdev = _devHandle.usbManager.DeviceList[name];
// Ask for permission to access the created device
if (!_devHandle.usbManager.HasPermission(_devHandle.usbdev))
{
PendingIntent pi = PendingIntent.GetBroadcast((ContextWrapper)_context, 0, new Intent(ACTION_USB_PERMISSION), 0);
_devHandle.usbManager.RequestPermission(_devHandle.usbdev, pi);
/* We check the permission was given
*/
if (!_devHandle.usbManager.HasPermission(_devHandle.usbdev))
{
// Loose !
Log.Debug("pandavcom", "FAILED : did not have persmission to open device" + _devHandle.usbdev.DeviceName);
return;
}
}
// Now open the port, with the USB Manager : we get the fd/enpoints and pass it to library, no more
_devHandle.connection = _devHandle.usbManager.OpenDevice(_devHandle.usbdev);
if (_devHandle.connection != null)
{
if (OpenInterface(_devHandle.usbdev, _devHandle.connection, ref _devHandle.usbIface, ref _devHandle.ep_in, ref _devHandle.ep_out) == 0)
{
_devHandle.fd = _devHandle.connection.FileDescriptor;
Log.Debug("pandavcom", "opened device endpoint" + _devHandle.usbdev.DeviceName + "with descriptor: " + _devHandle.fd);
}
else
{
Log.Debug("pandavcom", "FAILED : open device endpoint" + _devHandle.usbdev.DeviceName);
}
}
So I made it working, thanks tho the guys of the libusb mailing list.
Actually the mad resistor libusb could only send data to device.
Now with the officiel libusb there's a way to do it, that is still recent.
So the process is :
get with android the device permission and the file descriptor
pass the file descriptor to your native code and execute this step to
initliaze libusb on the fd :
libusb_context *ctx;
enum libusb_error rc;
rc = libusb_set_option(&ctx, LIBUSB_OPTION_WEAK_AUTHORITY, NULL);
if (rc != LIBUSB_SUCCESS) {
__android_log_print(ANDROID_LOG_ERROR, TAG,"libusb_init failed: %d\n", ret);
return -1;
}
ret = libusb_init(&ctx);
if (ret < 0) {
__android_log_print(ANDROID_LOG_INFO, TAG,
"libusb_init failed: %d\n", ret);
return 1;
}
libusb_device_handle *devh = NULL;
ret = libusb_wrap_sys_device(NULL, (intptr_t)FD, &devh);
if (ret < 0) {
__android_log_print(ANDROID_LOG_INFO, TAG,
"libusb_wrap_sys_device failed: %d\n", ret);
return 2;
}
else if (devh == NULL) {
__android_log_print(ANDROID_LOG_INFO, TAG,
"libusb_wrap_sys_device returned invalid handle\n");
return 3;
}
(FD = FileDescriptor from Android.USBManager)
The code above was sent over the mailing.
An example of integration is available on my github project.
I'm still validating this solution on more Android tablet.
I have connected hc-05 bluetooth module and Esp8266 wifi module to my arduino uno. This is my code
#include <SoftwareSerial.h>// import the serial library
SoftwareSerial BluetoothModule(10, 11); // RX, TX
int ledpin=13; // led on D13 will show blink on / off
int BluetoothData; // the data given from Computer
void setup() {
// put your setup code here, to run once:
BluetoothModule.begin(9600);
BluetoothModule.println("Bluetooth On please press 1 or 0 blink LED ..");
pinMode(ledpin,OUTPUT);
}
void loop() {
// put your main code here, to run repeatedly:
if (BluetoothModule.available()){
BluetoothData=BluetoothModule.read();
if(BluetoothData=='1') { // if number 1 pressed ....
digitalWrite(ledpin,1);
BluetoothModule.println("LED On D13 ON ! ");
}
if (BluetoothData=='0'){// if number 0 pressed ....
digitalWrite(ledpin,0);
BluetoothModule.println("LED On D13 Off ! ");
}
}
delay(100);// prepare for next data ...
}
As you can see the code is fairly simple ( taken from instructables.com )
And it works fine .I am able to send "0" and "1" from my app and the LED goes on/off.
I have also added ESP8266 wifi module to my arduino and I am able to send
AT commands .
Here is what I do :
1) Open Serial Monitor
2) Set Baud Rate as 115200
3) Switch to CL and NL
4) Start sending AT commands from Serial Monitor and it works fine.
=======
Now my next approach is to receive single character like "a", "b" and then forward this command to ESP8266.
I tried creating a software serial on 8,9 (RX,TX) and tried forwarding "a" as "AT" to the module and receive data from ESP8266 to bluetooth module
but that did not work.
if( data == "a" ) {
ESPserial.write( "AT");
Bluetooth.println( ESPserial.readString() );
}
How can I share data between hc-05/esp8266 wifi module ?
my project has 2 steps:
Establish a connection between my phone and the arduino board
Use accelerometer sensor to move the car
The motion part i can handle it, but i can't find a way to use bluetooth. I just can't figure how to work with this Api.
What should i do to connect to the arduino and start sending signals to it?
Check this link out, its a Guide on Connecting Android Device with Arduino and Bluetooth
I'll just paste the Steps here, in case the link expires someday.
At the top of your source code, include these libs.
#include "SoftwareSerial.h"
#include "Bluetooth.h"
To start using it, at the top of your source declare a public variable to access it:
Bluetooth *blue = new Bluetooth(2, 3);
With Bluetooth(RX_Pin, TX_Pin)
The default pin is 1234, name is “PNGFramework” and baudrate is 9600
Now, on your Setup(), add the follow line:
void setup(){
Serial.begin(9600);
blue->setupBluetooth();
}
Send a message when we receive some data from Serial.
void loop(){
String msg = blue->Read();
if(msg.length() > 1){
Serial.print("Received: ");
Serial.println(msg);
}
if(Serial.available()){
blue->Send("Example message#");
}
}
In Android
First, create a bluetooth object, use the following code, make sure to use the same RobotName that you used in the Arduino project. (default is “PNGFramework”).
BluetoothArduino mBlue = BluetoothArduino.getInstance("PNGFramework");
To connect with the Arduino, add the command bellow:
mBlue.Connect();
Now, to read a message, run the command:
String msg = mBlue.getLastMessage();
I am writing an open source framework to use BLE Mini module with Android and iOS mobile devices using Unity engine.
This framework should allow to establish a connection between the mobile device and the BLE Mini module, and to send/receive data using it. The framework can be theoretically adapted to work with any BLE module.
The idea is to make the existing BLE Mini frameworks (available for iOS and Android) work in Unity engine, hence I am writing native plugins for iOS and Android that will allow Unity apps use the native frameworks.
The iOS plugin is working as expected, while I am having problems writing the Android plugin.
Everything works as expected except the fact that I cannot send data to my characteristic. If I send the data the BLE Mini module does not receive it.
The code controlling the BLE Mini data reception is correct because it works when iOS sends the data. So I am pretty sure the problem is in the Android plugin.
The Android plugin is composed by Android native code that can be found here:
https://github.com/giomurru/ble-framework/tree/master/AndroidPlugin/src/com/gmurru/bleframework
and by Unity c# code that can call the public java methods: https://github.com/giomurru/ble-framework/blob/master/Unity/Assets/BLE/BLEController.cs
The code contained in RBLGattAttributes.java and RBLService.java is correct because it is the framework provided by RedBearLab and I tested it and it works correctly with native Android apps.
The code in which I need help and that probably contains the bug is the one in BleFramework.java
The BleFramework class contains a series of functions that can be called by the Unity engine. The functions are called following this order:
Call the get static method BleFramework.getInstance() to get a singleton instance of the class BleFramework. This method returns one and only one instance of the BleFramework class.
After I have the instance of the class I can call the BleFramework methods using this instance (which is always the same instance).
The methods are called following this order:
1) Call the function _InitBLEFramework from Unity. The function should initialize the BLE framework. When the initialization is finished the Android plugin answer to Unity with a OnBleDidInitialize "Success" message.
2) If Unity receives the OnBleDidInitialize "Success" message, I can call the function _ScanForPeripherals from Unity. The function scans for available BLE modules peripherals. When the available peripherals are found the plugin answer to Unity with a OnBleDidCompletePeripheralScan "Success" message.
3) If Unity receives the OnBleDidCompletePeripheralScan "Success" message, I can call the function _GetListOfDevices to get the list of found devices.
4) Once I have the list of BLE module devices I found, I can try to connect to one of them using the function _ConnectPeripheralAtIndex(int peripheralIndex). When the _mGattUpdateReceiver receives RBLService.ACTION_GATT_SERVICES_DISCOVERED I can say the connection is established and I can let Unity know I am ready to send/receive data by sending a OnBleDidConnect "Success" message.
Up to here the plugin works as expected, and the connection is established.
The problem is when I try to send data in step 5.
5) When Unity receives the OnBleDidConnect "Success" message it is ready to send data through the established connection. Hence I try to send the data by using _SendData function in the plugin. Unfortunately it does not work.
This is the code:
public void _SendData(byte[] data)
{
Log.d(TAG,"_SendData: ");
BluetoothGattCharacteristic characteristic = _map.get(RBLService.UUID_BLE_SHIELD_TX);
Log.d(TAG, "Set data in the _characteristicTx");
byte[] tx = hexStringToByteArray("fefefe");
characteristic.setValue(tx);
Log.d(TAG, "Write _characteristicTx in the _mBluetoothLeService: " + tx[0] + " " + tx[1] + " " + tx[2]);
if (_mBluetoothLeService==null)
{
Log.d(TAG, "_mBluetoothLeService is null");
}
_mBluetoothLeService.writeCharacteristic(characteristic);
}
public static byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
Just for the purpose of testing I ignored byte[] data parameter and I try to send byte[] tx data that I create inside the _SendData function using hexStringToByteArray function (that I found in this StackOverflow post: Convert a string representation of a hex dump to a byte array using Java?)
I also tried to create the tx data as:
byte tx[] = new byte[] { (byte) 0xfe, (byte) 0xfe, (byte) 0xfe };
or to send the data directly like this:
public void _SendData(byte[] data)
{
Log.d(TAG,"_SendData: ");
BluetoothGattCharacteristic characteristic = _map.get(RBLService.UUID_BLE_SHIELD_TX);
Log.d(TAG, "Set data in the _characteristicTx");
characteristic.setValue(data);
Log.d(TAG, "Write _characteristicTx in the _mBluetoothLeService: " + data[0] + " " + data[1] + " " + data[2]);
if (_mBluetoothLeService==null)
{
Log.d(TAG, "_mBluetoothLeService is null");
}
_mBluetoothLeService.writeCharacteristic(characteristic);
}
In all the cases I failed to send the data.
I really can't understand why this is happening. The code I am using to search ble devices, establish connection, send receive data is very similar to the Android native samples available in ReadBearLab github page: https://github.com/RedBearLab/Android/tree/master/Examples
The only difference is that I am not extending Activity.
I tried to make BleFramework class an extension of Activity but it didn't work. The problem I had was that while BleFramework activity was running I was not able to send messages back to Unity using the UnityPlayer.UnitySendMessage function.
I answer my own question just for reference if anybody is interested in the solution I found.
I fixed the bug by updating the code to the latest Android APIs. Please check out the commits from June 15th 2019 to June 22nd 2019 in the repository if you are interested in the modifications. In particular the commit named "Android tx/rx works"
https://github.com/giomurru/ble-framework
I am trying to connect my laptop(as client) to my android phone(as listener) using python-bluez on the laptop and android-bluetooth API on the phone.
I use the following code for my phone:
BluetoothServerSocket tmp = badapter.listenUsingRfcommWithServiceRecord(
badapter.getName(), MY_UUID);
BluetoothServerSocket bserversocket = tmp;
if(bserversocket != null)
{
BluetoothSocket acceptsocket = bserversocket.accept(timeout);
}
//timeout is set to about 15 sec
if(acceptsocket != null)
{
out.append("got the connection...\n");
}
and the following in python for my laptop client:
from bluetooth import *
btooth_addr = "38:EC:E4:57:1F:1B"
sock = BluetoothSocket(RFCOMM)
sock.connect((btooth_addr, 2))
print "Connected"
sock.close()
the listener time-outs without acknowledging any connections from the laptop, while the sender moves on to print 'Connected' on all attempts on different ports.
the problem is that I don't know and can't set the port/channel the android phone is listening on, and also that I am required to fill in a port number as second argument of 'connect'(2 in this snippet).
please help me out - my sole goal at this time is to get the connection attempt acknowledged by the phone.
Have a look at the pybluez documentation(source code) for establishing client connections.
You can get the correct port for the supplied Bluetooth address and UUID using find_service.
Then connect your socket just as you do in your code, replacing hardcoded port value with the correct one.
Don't forget to vote up!