Location: Asia Pacific, Cyberspace, in the Dark Dystopia
Posts: 19,118
Thanks Given: 2,351
Thanked 3,359 Times in 1,878 Posts
Basic Arduino UNO Bluetooth Testing with the BLE 4.0 (CC2541, MLT-BT04 IC)
Here is a sketch to do basic testing for the Arduino UNO and the MLT-BT04.
This BLE module works with IOS (iPhone) and I'll add some details on my IOS testing with an iPhone in a follow-up post.
For now, here is the basic BLE (HM-10) sketch for the Arduino UNO:
Code:
/*
Arduino test-code fir BLE MLT-BT04 to the Arduino board.
BLE Version 4.0 Module chipset: CC2541
Schematic: Arduino D7 to MLT-BT04 TX
Schematic: Arduino D8 to MLT-BT04 RX
Schematic: Arduino GRD to MLT-BT04 GRD
Schematic: Arduino 3.3v to MLT-BT04 ACC
Prints Help Menu for the CC2541 and some other sample AT commands.
Neo: www.unix.com version 0.1 January 2020
Modified version of an unattributed CC2541 firmware example sketch.
Use as you wish, with or without attribution.
*/
#include <SoftwareSerial.h>
SoftwareSerial ble_device(7, 8); // RX, TX
String str_ii = "";
int ii_0 = 0;
bool debug = false;
void setup() {
Serial.begin(9600);
delay(1000);
ble_device.begin(9600);
delay(1000);
// First, get all available functions from CC2541 firmware
ble_cmdhelp();
ble_cmdln("AT+LADDR");
ble_cmdln("AT+NAME");
ble_cmdln("AT+CHAR");
ble_cmdln("AT+UUID");
if (debug) Serial.print("\nEND BLE SKETCH\n");
}
void loop() {
}
void ble_cmdhelp() {
ble_device.println("AT+HELP"); // list all AT+ commands
while (true) { // loop to print all AT+ commands
char in_char = ble_device.read();
if (int(in_char) == -1 or int(in_char) == 42) {
continue;
}
str_ii += in_char;
if (in_char == '\n') {
if (str_ii == String('\r') + String('\n')) {
if (ii_0 == 0) {
ii_0 = 1;
continue;
}
break; // break after more than 1 empty carriage return and newline
}
Serial.print(str_ii);
str_ii = "";
}
}
}
void ble_cmdln(String cmd) {
if (debug) Serial.print("\nSTART " + cmd + "\n");
ble_device.println(cmd); // get basic AT+ command
delay(1000);
while (ble_device.available() > 0) {
char in_char = ble_device.read();
if (in_char) {
str_ii += in_char;
}
else {
break;
}
}
Serial.println(str_ii);
if (debug) Serial.print("END " + cmd + "\n");
str_ii = "";
}
Sample serial monitor output:
Code:
20:44:41.624 ->
20:44:41.624 -> Command Description
20:44:41.846 -> ----------------------------------------------------------------
20:44:42.061 -> AT Check if the command terminal work normally
20:44:42.247 -> AT+DEFAULT Restore factory default
20:44:42.431 -> AT+BAUD Get/Set baud rate
20:44:42.612 -> AT+RESET Software reboot
20:44:42.836 -> AT+ROLE Get/Set current role.
20:44:43.059 -> AT+DISC Disconnect connection
20:44:43.244 -> AT+ADVEN Broadcast switch
20:44:43.423 -> AT+ADVI Broadcast interval
20:44:43.633 -> AT+NINTERVAL Connection interval
20:44:43.851 -> AT+POWE Get/Set RF transmit power
20:44:44.061 -> AT+NAME Get/Set local device name
20:44:44.250 -> AT+LADDR Get local bluetooth address
20:44:44.432 -> AT+VERSION Get firmware, bluetooth, HCI and LMP version
20:44:44.653 -> AT+TYPE Binding and pairing settings
20:44:44.864 -> AT+PIN Get/Set pin code for pairing
20:44:45.046 -> AT+UUID Get/Set system SERVER_UUID .
20:44:45.231 -> AT+CHAR Get/Set system CHAR_UUID .
20:44:45.447 -> AT+INQ Search from device
20:44:45.632 -> AT+RSLV Read the scan list MAC address
20:44:45.817 -> AT+CONN Connected scan list device
20:44:46.040 -> AT+CONA Connection specified MAC
20:44:46.222 -> AT+BAND Binding from device
20:44:46.443 -> AT+CLRBAND Cancel binding
20:44:46.632 -> AT+GETDCN Number of scanned list devices
20:44:46.852 -> AT+SLEEP Sleep mode
20:44:47.036 -> AT+HELP List all the commands
20:44:47.467 -> ---------------------------------------------------------------
20:44:48.680 ->
20:44:48.680 -> +LADDR=20:C3:8F:8A:54:4A
20:44:48.680 ->
20:44:49.694 -> +NAME=MLT-BT05
20:44:49.694 ->
20:44:50.713 -> +CHAR:FFE1
20:44:50.713 ->
20:44:51.698 -> +UUID:FFE0
20:44:51.698 ->
Location: Asia Pacific, Cyberspace, in the Dark Dystopia
Posts: 19,118
Thanks Given: 2,351
Thanked 3,359 Times in 1,878 Posts
Here is the chip.... as I find these kind of details matter and are often omitted on these kinds of Internet tutorials and discussions. I will replace this photo (taken quickly with my iPhone) with a screen shot from my computer when I find the USB cable to my little microscope.
In fact, the way I got this test to work (finding a starting point sketch) was to use my microscope to read the model number on the chip: the CC2541
A number of times recently, I received some modules with the model number of the chip "burned off" with a laser, which is really annoying.
Update: Here is the same chip shot using the USB interface to my Mac Pro :
Both "chip shots" were taken though the plastic wrapper around the BLE module... that is why the image is a bit blurry)
For example, in their basic sketch, with PIN setup as follows (TX, RX pins reversed from the first sketch above, FYI - which I changed to match the ArdunioBlue defaults):
Code:
/*
ArduinoBlue example code to demonstrate the features of the app.
*/
#include <SoftwareSerial.h>
#include <ArduinoBlue.h>
const unsigned long BAUD_RATE = 9600;
// The bluetooth tx and rx pins must be supported by software serial.
// Visit https://www.arduino.cc/en/Reference/SoftwareSerial for unsupported pins.
// Bluetooth TX -> Arduino D8
const int BLUETOOTH_TX = 8;
// Bluetooth RX -> Arduino D7
const int BLUETOOTH_RX = 7;
int prevThrottle = 49;
int prevSteering = 49;
int throttle, steering, sliderVal, button, sliderId;
SoftwareSerial bluetooth(BLUETOOTH_TX, BLUETOOTH_RX);
ArduinoBlue phone(bluetooth); // pass reference of bluetooth object to ArduinoBlue constructor
// Setup code runs once after program starts.
void setup() {
// Start serial communications.
// The baud rate must be the same for both the serial and the bluetooth.
Serial.begin(BAUD_RATE);
bluetooth.begin(BAUD_RATE);
delay(100);
Serial.println("setup complete");
}
// Put your main code here, to run repeatedly:
void loop() {
// ID of the button pressed pressed.
button = phone.getButton();
// Returns the text data sent from the phone.
// After it returns the latest data, empty string "" is sent in subsequent.
// calls until text data is sent again.
String str = phone.getText();
// Throttle and steering values go from 0 to 99.
// When throttle and steering values are at 99/2 = 49, the joystick is at center.
throttle = phone.getThrottle();
steering = phone.getSteering();
// ID of the slider moved.
sliderId = phone.getSliderId();
// Slider value goes from 0 to 200.
sliderVal = phone.getSliderVal();
// Display button data whenever its pressed.
if (button != -1) {
Serial.print("Button: ");
Serial.println(button);
}
// Display slider data when slider moves
if (sliderId != -1) {
Serial.print("Slider ID: ");
Serial.print(sliderId);
Serial.print("\tValue: ");
Serial.println(sliderVal);
}
// Display throttle and steering data if steering or throttle value is changed
if (prevThrottle != throttle || prevSteering != steering) {
Serial.print("Throttle: "); Serial.print(throttle); Serial.print("\tSteering: "); Serial.println(steering);
prevThrottle = throttle;
prevSteering = steering;
}
// If a text from the phone was sent print it to the serial monitor
if (str != "") {
Serial.println(str);
}
// Send string from serial command line to the phone. This will alert the user.
if (Serial.available()) {
Serial.write("send: ");
String str = Serial.readString();
phone.sendMessage(str); // phone.sendMessage(str) sends the text to the phone.
Serial.print(str);
Serial.write('\n');
}
}
I set up two buttons and two sliders just like in the instructions, and everything worked "out of the box" (much better than all the other IOS BLE Arduino apps I tested). For example, here is the Arduino serial monitor output:
Side Note: I'm starting too like all these cheap Chinese shields from AliExpress
This is the ArduinoBlue test setup on the iPhone:
With the basics out of the way on the iPhone (for now), next I think I will look for / find / modify or write a Python app so I can play Arduino BLE from my desktop MacPro. Also, in that search, I'll also check to see what kinds of macOS apps are good for this caper (so far, I've not found any suitable BLE app for macOS, so my guess is I'll end up writing or modifying a Python project for BLE on the Mac).
Location: Asia Pacific, Cyberspace, in the Dark Dystopia
Posts: 19,118
Thanks Given: 2,351
Thanked 3,359 Times in 1,878 Posts
Update and Issues:
Having some problems with the ArdunioBlue IOS app because I cannot find any method / sketch to send data from the Arduino BLE module to IOS. However, sending data to the Arduino BLE module from IOS works fine. Unless I am missing something huge, the ArduinoBlue IOS app is "one way communications" only, as far as the user is concerned. I sent an email to the developer, but it bounced as "undeliverable". I would prefer to have BLE comms bidirectional, obviously.
Edit(Update): I found more docs on ArdunioBlue and then found a method (which I have tested and it works) to send messages from the Arduino back to IOS:
Code:
void sendMessage(String text) - Sends the text to the phone as a popup
/*************************************************************
Download latest Blynk library here:
https://github.com/blynkkk/blynk-library/releases/latest
Blynk is a platform with iOS and Android apps to control
Arduino, Raspberry Pi and the likes over the Internet.
You can easily build graphic interfaces for all your
projects by simply dragging and dropping widgets.
Downloads, docs, tutorials: http://www.blynk.cc
Sketch generator: http://examples.blynk.cc
Blynk community: http://community.blynk.cc
Follow us: http://www.fb.com/blynkapp
http://twitter.com/blynk_app
Blynk library is licensed under MIT license
This example code is in public domain.
*************************************************************
Warning: Bluetooth support is in beta!
You can send/receive any data using WidgetTerminal object.
App project setup:
Terminal widget attached to Virtual Pin V1
*************************************************************/
/* Comment this out to disable prints and save space */
#define BLYNK_PRINT Serial
#include <SoftwareSerial.h>
SoftwareSerial SwSerial(10, 11); // RX, TX
#include <BlynkSimpleSerialBLE.h>
#include <SoftwareSerial.h>
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "YourAuthToken";
SoftwareSerial SerialBLE(10, 11); // RX, TX
// Attach virtual serial terminal to Virtual Pin V1
WidgetTerminal terminal(V1);
// You can send commands from Terminal to your hardware. Just use
// the same Virtual Pin as your Terminal Widget
BLYNK_WRITE(V1)
{
// if you type "Marco" into Terminal Widget - it will respond: "Polo:"
if (String("Marco") == param.asStr()) {
terminal.println("You said: 'Marco'") ;
terminal.println("I said: 'Polo'") ;
} else {
// Send it back
terminal.print("You said:");
terminal.write(param.getBuffer(), param.getLength());
terminal.println();
}
// Ensure everything is sent
terminal.flush();
}
void setup()
{
// Debug console
Serial.begin(9600);
SerialBLE.begin(9600);
Blynk.begin(SerialBLE, auth);
Serial.println("Waiting for connections...");
// This will print Blynk Software version to the Terminal Widget when
// your hardware gets connected to Blynk Server
terminal.println(F("Blynk v" BLYNK_VERSION ": Device started"));
terminal.println(F("-------------"));
terminal.println(F("Type 'Marco' and get a reply, or type"));
terminal.println(F("anything else and get it printed back."));
terminal.flush();
}
void loop()
{
Blynk.run();
}
But after many tries, I cannot get the Blynk IOS app to connect to the Arduino BLE module, even thought it works fine with other IOS BLE apps, so I posted a question on this in the Blynk Community:
Location: Asia Pacific, Cyberspace, in the Dark Dystopia
Posts: 19,118
Thanks Given: 2,351
Thanked 3,359 Times in 1,878 Posts
Update:
Well, I seem to have been wrong. I thought Blynk was a BLE app, but it's not. From the website:
Quote:
Blynk is a hardware-agnostic IoT platform with white-label mobile apps, private clouds, device management, data analytics, and machine learning.
My experience is that apps which try to be "all things to all platforms" often end of "nothing special for most platforms", so I think I will probably drop the Blynk line of investigation for BLE.
In fact, I may put the HM-10 BLE module back in my "module drawer" and move on to a new Arduino module soon. I have too many Arduino modules to test and my attention span is not very high for module testing, LOL
Location: Asia Pacific, Cyberspace, in the Dark Dystopia
Posts: 19,118
Thanks Given: 2,351
Thanked 3,359 Times in 1,878 Posts
Update:
Have downloaded, installed and tried a number of python git repos for BLE and macOS. Could not get any of around four python BLE repos to work as I had expected or hoped "out of the box" (for example, no discovery or device listing worked) so I'm going to move this little HM-10 BLE module into temporary storage for now and move on to testing a different Arduino module / shield.
I may return to the HM-10 BLE module if I want to build a BLE app to control some relays with my iPhone, since I was happy with how ArduinoBlue worked OOTB. Unfortunately, ArduinoBlue development seems to be "dead" at the moment and the original developer's email bounces back "account deleted" .
Caveat, I deleted xcode off my mac months ago, so you may have better luck of you use a python wrapper over the xcode BLE libs.
My attention span is now very low with many Arduino modules and shields waiting, in dark, unopened, static resistant packages, to be freed from the drawer, wired up and coded.
ArduinoBlue class
phone(Stream obj) - Constructor pass SoftwareSerial object. Alternatively, you can pass any Serial. For example, on the Arduino Mega you can pass phone(Serial2) instead. Note if you use Serial, you won't be able to use serial communication through USB.
int getButton() - Returns once the ID of the button that was pressed. Returns -1 otherwise.
int getSliderId() - Returns once the slider ID of the slider that was moved. Returns -1 otherwise.
int getSliderVal() - Returns the value of the slider of the slider that was moved.
int getThrottle() - Returns the throttle value of the joystick.
int getSteering() - Returns the steering value of the joystick.
void sendMessage(String text) - Sends the text to the phone as a popup.
String getText() - Returns the text that was sent from the app's text box.
So, I was able to easily send test messages (using BLE) from the Arduino UNO back to the iPhone ArdunioBlue app using the sendMessage() method.
Basically, from all the testing I did so far, I'm quite happy with ArduinoBlue for IOS.
I think next I may combine this BLE app with NB-IoT to send command and control (C2) messages via BLE from my iPhone to a server on the Internet using an NB-IoT network and get C2 status messages and alerts back from the remote server to my iPhone the same way.
This post describes a "work in progress" project I started today. Here is the High Level Overview:
Currently, this project sits on my desk as an Arduino UNO (on the bottom), an NB-IoT Shield (sandwiched in the middle), a Sensor Shield (on top) with a HM-10 BLE Module (in the little... (13 Replies)
Just finished a quick Python script to send the current unix time over to the Arduino from macOS, so in the absence of GPS or some other way to get the unix timestamp (epoch time) to the Arduino, I can get my macOS and Arduino UNO synced to within a second.
Normally, when the Arduino starts... (9 Replies)
Waiting for more fun Ardunio parts from AliExpress, I decided to test two cheap Chinese Arduino UNO clones.
The Arduino UNO R3 (CH340G) MEGA328P
The Wavgat UNO R3 (CH340G) MEGA328P
Both of these Chinese Ardunio clones sell for about $3 USD, delivered to your door.
The bottom line is... (0 Replies)
HI all...
(Apologies for any typos.)
To add to Neo's Arduino subject matter I have decided to upload this in ".zip" format.
Ignore "*.info" files these are AMIGA icons only and also the "HAM" drawer as these are photos in ancient AMIGA HAM modes.
I have noticed that there are current... (6 Replies)
In my further exploration of Arduino, today I decided to install the arduino-cli on my mac today.
https://github.com/arduino/arduino-cli
I followed the instructions for macOS but when I got to this part:
arduino-cli board list
I got the dreaded "Unknown" Fully Qualified Board Name... (1 Reply)
A very simple Arduino board test... LOL
Here is some very easy code to test a cheap Arduino board I just got from China via Aliexpress. I am still waiting on a about 30 more orders from Aliexpress for more Arduino stuff. This was the first order which made it here.
/*
Arduino test-code... (18 Replies)
I am working on a semi-auto detection idea for Arduino for the Scope project.
It does require a little user intervention but minimal.
It works by just responding to two on screen prompts to unplug and plug Arduino
into a USB port.
There are two versions and both work perfectly well and give... (3 Replies)