Connecting an Arduino Nano 33 IoT to an Android app through Bluetooth - android
I am working on connecting an Arduino nano 33 iot to an android app via the Bluetooth capabilities of the iot device. I have seen many resources referring to the use of a Bluetooth module, but no resources about using the nano 33 iot Bluetooth capabilities.
I am wanting to receive data from the Arduino via Bluetooth connection and display it in an android app. I had developed an app that can see the Arduino in a list of Bluetooth devices but am unable to connect to the Arduino due to it not being able to be paired with the phone.
Thanks
Did you found a solution? I think you need to be sure, that you are connect with Bluetooth Low Energy with the Nano Board from Arduino. The way, which is descripted in your posted Tutorial, is not Low Energy. Because of that, you cannot pair.
To connect the Arduino nano 33 IoT via BLE you can use the Demo by Bernardo Giovanni as a template code for your project.
https://www.settorezero.com
*/
// Voltage divider definitions.
// Here I've reported my precise values for R1 (47K) and R2 (33K)
// remember: you cannot apply more than 3.3V on analog input.
// Having a voltage divider with those values (47K and 33K)
// consent to apply on the voltage divider input a maximum of:
// 3.3/VDK = 3.3/0.4125 = 8V
#define R1 46.2F
#define R2 32.86F
#define VDK (R2/(R1+R2))
// since I'm using a 4xAA battery holder and you cannot apply
// less than 5V on Vin pin, I define my "battery full" value as 6V
// and "battery low" value as 5V
#define BAT_FUL 6
#define BAT_LOW 5
// analog pin connected to the voltage divider for battery
// voltage reading
#define AN_BAT A7
#include <ArduinoBLE.h> // Arduino BLE library
#include <Arduino_LSM6DS3.h> // Use Arduino library for the IMU on the Nano 33 IOT
// UUid for Service
const char* UUID_serv = "84582cd0-3df0-4e73-9496-29010d7445dd";
// UUids for accelerometer characteristics (I separated x, y and z values)
const char* UUID_ax = "84582cd1-3df0-4e73-9496-29010d7445dd";
const char* UUID_ay = "84582cd2-3df0-4e73-9496-29010d7445dd";
const char* UUID_az = "84582cd3-3df0-4e73-9496-29010d7445dd";
// UUids for gyroscope characteristics (as above)
const char* UUID_gx = "84582cd4-3df0-4e73-9496-29010d7445dd";
const char* UUID_gy = "84582cd5-3df0-4e73-9496-29010d7445dd";
const char* UUID_gz = "84582cd6-3df0-4e73-9496-29010d7445dd";
// UUid for battery values (bap=percent, ba=voltage)
const char* UUID_bap = "84582cd7-3df0-4e73-9496-29010d7445dd";
const char* UUID_ba = "84582cd8-3df0-4e73-9496-29010d7445dd";
// BLE Service
BLEService myService(UUID_serv);
// BLE Characteristics
BLEFloatCharacteristic chAX(UUID_ax, BLERead|BLENotify);
BLEFloatCharacteristic chAY(UUID_ay, BLERead|BLENotify);
BLEFloatCharacteristic chAZ(UUID_az, BLERead|BLENotify);
BLEFloatCharacteristic chGX(UUID_gx, BLERead|BLENotify);
BLEFloatCharacteristic chGY(UUID_gy, BLERead|BLENotify);
BLEFloatCharacteristic chGZ(UUID_gz, BLERead|BLENotify);
BLEFloatCharacteristic chBAP(UUID_bap, BLERead|BLENotify);
BLEFloatCharacteristic chBA(UUID_ba, BLERead|BLENotify);
void setup()
{
Serial.begin(115200);
uint32_t t=millis();
while (!Serial) // wait 5 seconds for serial connection
{
if ((millis()-t) > 5000) break;
}
bool err=false;
pinMode(LED_BUILTIN, OUTPUT); // onboard led
digitalWrite(LED_BUILTIN, LOW); // led off
// init IMU
if (!IMU.begin())
{
Serial.println("IMU: failed");
err=true;
}
Serial.println("IMU: ok");
// init BLE
if (!BLE.begin())
{
Serial.println("BLE: failed");
err=true;
}
Serial.println("BLE: ok");
// error: flash led forever
if (err)
{
Serial.println("Init error. System halted");
while(1)
{
digitalWrite(LED_BUILTIN, HIGH); // led on
delay(500);
digitalWrite(LED_BUILTIN, LOW); // led off
delay(500);
}
}
// BLE service
// correct sequence:
// set BLE name > advertised service > add characteristics > add service > set initial values > advertise
// Set BLE name
BLE.setLocalName("Settorezero_IMU");
BLE.setDeviceName("Arduino"); // Arduino is the default value on this module
// Set advertised Service
BLE.setAdvertisedService(myService);
// Add characteristics to the Service
myService.addCharacteristic(chAX);
myService.addCharacteristic(chAY);
myService.addCharacteristic(chAZ);
myService.addCharacteristic(chGX);
myService.addCharacteristic(chGY);
myService.addCharacteristic(chGZ);
myService.addCharacteristic(chBAP);
myService.addCharacteristic(chBA);
// add service to BLE
BLE.addService(myService);
// characteristics initial values
chAX.writeValue(0);
chAY.writeValue(0);
chAZ.writeValue(0);
chGX.writeValue(0);
chGY.writeValue(0);
chGZ.writeValue(0);
chBAP.writeValue(0);
chBA.writeValue(0);
// start advertising
BLE.advertise();
Serial.println("Advertising started");
}
void loop()
{
static long preMillis = 0;
// listen for BLE centrals devices
BLEDevice central = BLE.central();
// central device connected?
if (central)
{
digitalWrite(LED_BUILTIN, HIGH); // turn on the onboard led
Serial.print("Connected to central: ");
Serial.println(central.address()); // central device MAC address
// while the central is still connected to peripheral:
while (central.connected())
{
// additional placeholder for writing command from central
// to this device. "myCharacteristic" is a characteristic initialized
// in write mode (BLEwrite) with his own UUid
/*
if (myCharacteristic.written())
{
command = myCharacteristic.value(); // retrieve value sent from central
Serial.print(F("commmand value: "));
Serial.println(command);
}
*/
long curMillis = millis();
if (preMillis>curMillis) preMillis=0; // millis() rollover?
if (curMillis - preMillis >= 10) // check values every 10mS
{
preMillis = curMillis;
updateValues(); // call function for updating value to send to central
}
} // still here while central connected
// central disconnected:
digitalWrite(LED_BUILTIN, LOW);
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
} // no central
}
void updateValues()
{
uint8_t averages=10; // average on this values count (accelerometer and gyroscope)
uint16_t b_averages=500; // average for battery
// accelerometer averaged values/actual values
static float ax=0;
static float ay=0;
static float az=0;
float ax1, ay1, az1;
// gyroscope averaged values/actual values
static float gx=0;
static float gy=0;
static float gz=0;
float gx1, gy1, gz1;
// battery averaged value/actual value
static float anBa=0;
float anBa1;
static uint8_t i_a=0; // accelerometer readings counter
static uint8_t i_g=0; // gyroscope readings counter
static uint16_t i_b=0; // battery readings counter
// read accelerometer values if available
if (IMU.accelerationAvailable())
{
i_a++;
IMU.readAcceleration(ax1, ay1, az1);
ax+=ax1;
ay+=ay1;
az+=az1;
if (i_a==averages) // send average over BLE
{
ax/=averages;
ay/=averages;
az/=averages;
//Serial.println("Accelerometer: "+String(ax)+","+String(ay)+","+String(az));
chAX.writeValue(ax);
chAY.writeValue(ay);
chAZ.writeValue(az);
ax=0;
ay=0;
az=0;
i_a=0;
}
}
// read gyroscope values if available
if (IMU.gyroscopeAvailable())
{
i_g++;
IMU.readGyroscope(gx1, gy1, gz1);
gx+=gx1;
gy+=gy1;
gz+=gz1;
if (i_g==averages) // send average over BLE
{
gx/=averages;
gy/=averages;
gz/=averages;
//Serial.println("Gyroscope: "+String(gx)+","+String(gy)+","+String(gz));
chGX.writeValue(gx);
chGY.writeValue(gy);
chGZ.writeValue(gz);
gx=0;
gy=0;
gz=0;
i_g=0;
}
}
// read battery value
anBa1=analogRead(AN_BAT);
anBa+=anBa1;
i_b++;
if (i_b==b_averages)
{
anBa/=b_averages; // averaged analog value
float voltage=anBa*(3.3/1023); // voltage on pin (if 3.3V => ADC gives 1023)
voltage=voltage/VDK; // real voltage on the voltage divider input = battery voltage
// send voltage in V to BLE
chBA.writeValue(voltage);
/*
Serial.print("Battery: ");
Serial.print(voltage,2);
Serial.print("V (");
*/
// calculate percentual battery
// we must consider BAT_FUL=100% and BAT_LO=0%
// report voltage to range having 0 as lower limit and (BAT_FUL-BAT_LO) as higher limit
// for having percent value
voltage-=BAT_LOW;
voltage/=(BAT_FUL-BAT_LOW);
anBa=voltage*100;
// keep percent value in the range 0-100
if (anBa<0) anBa=0;
else if (anBa>100) anBa=100;
// send % value to BLE
chBAP.writeValue(anBa); // percent voltage
/*
Serial.print(anBa,1);
Serial.println("%)");
*/
i_b=0;
anBa=0;
}
}
There is also a good tutorial about BLE on the Arduino website
https://docs.arduino.cc/tutorials/nano-33-iot/Bluetooth
and an excellent ultimate Android to BLE guide here:
https://punchthrough.com/android-ble-guide/
other really useful guides, tutorials and OS code can be found on the links below:
https://github.com/nenovmy/arduino
https://www.thinker-talk.com/post/bluecard-part-6-controlling-the-arduino-nano-bluetooth-module-from-android-device
Related
How to detect if a device get my phone bluetooth name?
I'm using a bluetooth modul (HC-05) to detect if an android phone is in the modul's range. I tried to connect with HC-05 (as master) and a PIC16f887 to the phone, but I can't. Searched many pages on net how to use HC-05 as master, but no solution. So, finally I could do this by modul get my phone's BT name. If it could, my phone is in range. But now I want my phone to detect this "remote name query" and play some sound then. Sorry for my poor english :)
Im guessing you want something like this: VIDEO Lets start with the basics: The typical default factory settings for a new Bluetooth HC-05 module are: Default Bluetooth Name: “HC-05” Default Password: 1234 or 0000 Default Communication: Slave Device Default Mode: Data Mode Default Data Mode Baud Rate: 9600, 8, N, 1 Default Command Mode Baud Rate: 38400, 8, N, 1 Default firmware: LINVOR 1. To TEST Bluetooth connections from your android device use id suggest you use this APK 2. Connect the HC-05 BT module as shown in the diagram 3. Initialize the UART receiver at the microcontroller end (side) (code includes 2 leds for pin 33 and pin 34) /* * LAB Number: 17 * LAB Name: Bluetooth Module HC-05 Interfacing (Smartphone -> MCU) * Author: Khaled Magdy * For More Information Visit My Website # DeepBlueMbedded.com * */ #include <xc.h> #include <stdint.h> #include "config.h" #define _XTAL_FREQ 4000000 //--[ Control Data ]-- #define Blue_LED_ON 49 #define Blue_LED_OFF 50 #define Yellow_Toggle 51 //-------------------------------- // Functions Declarations void UART_RX_Init(void); // Globals uint8_t UART_Buffer = 0; //-------------------------------- // Main Routine void main(void) { //--[ Peripherals & IO Configurations ]-- UART_RX_Init(); // Initialize The UART in Master Mode # 9600bps TRISB0 = 0; // Blue LED (Switch) TRISB1 = 0; // Yellow LED (Toggle) RB0 = 0; // Initially OFF RB1 = 0; // Initially OFF //--------------------------- while(1) { } return; } //-------------------------------- // Functions Definitions void UART_RX_Init() { BRGH = 1; // Set For High-Speed Baud Rate SPBRG = 25; // Set The Baud Rate To Be 9600 bps // Enable The Ascynchronous Serial Port SYNC = 0; SPEN = 1; // Set The RX-TX Pins to be in UART mode (not io) TRISC6 = 1; // As stated in the datasheet TRISC7 = 1; // As stated in the datasheet //--[ Enable UART Receiving Interrupts ]-- RCIE = 1; // UART Receving Interrupt Enable Bit PEIE = 1; // Peripherals Interrupt Enable Bit GIE = 1; // Global Interrupt Enable Bit //------------------ CREN = 1; // Enable Data Continous Reception } void interrupt ISR (void) { if (RCIF == 1) { UART_Buffer = RCREG; // Read The Received Data Buffer // This could have been done within the main loop. Since it's not // Excessive processing, so it's OK to do it here below if(UART_Buffer == Blue_LED_ON) RB0 = 1; // Blue LED ON if(UART_Buffer == Blue_LED_OFF) RB0 = 0; // Blue LED OFF if(UART_Buffer == Yellow_Toggle) RB1 = ~RB1; // Toggle Yellow LED RCIF = 0; // Clear The Interrupt Flag } } NOTE The Data Bytes (49, 50, and 51) are the ASCII equivalents for the numeric characters (1, 2, and 3 respectively). 4. Download this apk to send commands to your HC05: APK For more info follow Reference: LINK
HC-06 Bluetooth to Android - Receiving Random Symbols
I wanted to send values from a light sensor, using an HC-06. I have everything connected properly. I used MIT App Inventor and the image shows how I connect to the Bluetooth module, and how do I show the data. Arduino Code int analogInPin = A0; int sensorValue = 0; void setup() { Serial.begin(9600); } void loop() { sensorValue = analogRead(analogInPin); Serial.println(sensorValue); delay(100); } Phone I already searched for several solutions but none worked. I have the baud rate at 9600 (the same as the Bluetooth module).
How to exit void loop in Arduino if there is no serial data available?
I am building an internet controlled robot that uses 2 android phones for controlling. The first phone is connected to Arduino Uno via USB and serves as a 3G shield The second phone is used to control the whole thing. It sends unassigned byte to the first phone which sends it to Arduino. The apps I uses on the phones have one problem. The joystick in the app doesn't send a specific command when its in rest. For example when I move it up it sends "1" to the phone connected to the Arduino which drives the motors forward but when I release the joystick it stops sending data however the motors on my robot still spin until I move the joystick down which sends "2" motor.run(RELEASE); How can I stop the motors if there is no Serial Data available? This is the code i wrote. #include <AFMotor.h> AF_DCMotor motor_left(2, MOTOR12_1KHZ); AF_DCMotor motor_right(3, MOTOR12_1KHZ); int ledPin = 13; int speed_min = 100; //the minimum "speed" the motors will turn - take it lower and motors don't turn int speed_max = 1000; //the maximum "speed" the motors will turn – you can’t put in higher int speed_left = speed_max; // set both motors to maximum speed int speed_right = speed_max; int command = 0; void setup () { Serial.begin(9600); pinMode(ledPin, OUTPUT); motor_left.setSpeed(255); motor_left.run(RELEASE); motor_right.setSpeed(255); motor_right.run(RELEASE); motor_left.setSpeed(speed_left); // minimum speed 135 max speed 255 motor_right.setSpeed(speed_right); // minimum speed 135 max speed 255 } void loop() { if (Serial.available() > 0); byte command = Serial.read(); if (command == 1) { Serial.println("Move Forward"); digitalWrite(ledPin, HIGH); motor_left.run(FORWARD); } if (command == 2) { Serial.println("Stop"); digitalWrite(ledPin, LOW); motor_left.run(RELEASE); } } So basically it should do nothing if there is no data available.
Use your code like this, it will help void loop() { if (Serial.available() > 0) { byte command = Serial.read(); if (command == 1) { Serial.println("Move Forward"); digitalWrite(ledPin, HIGH); motor_left.run(FORWARD); } else if (command == 2) { Serial.println("Stop"); digitalWrite(ledPin, LOW); motor_left.run(RELEASE); } else { //put your code to stop Motor } } }
control a servo with android and arduino
I'm trying to control a servo with an android phone and an arduino via bluetooth but the data in the arduino is received as a char, and the arduino doesn't know when all the data is received and the servo don't move properly. The arduino code is this: #include Servo myservo; char val; // variable to receive data from the serial port int ledpin = 13; // LED connected to pin 48 (on-board LED) void setup() { pinMode(ledpin, OUTPUT); // pin 48 (on-board LED) as OUTPUT Serial.begin(9600); // start serial communication at 9600bps myservo.attach(9); } void loop() { if( Serial.available() ) // if data is available to read { val = Serial.read(); // read it and store it in 'val' } if( val - 0 >= 0 && val - 0 <= 180){ } // Serial.print("Recibido"); delay(100); // wait 100ms for next reading } What can I do to get the correct value from "val" to control the servo?
You can send multiple chars if you need them. Simple store each new char into an array and program your android program to send a specific byte that indicates the ending of the val reading. Checking this "ending" byte each time you perform a read from serial will tell you if this char is to store or to convert the previous stored chars into an integer or whatever data type you need it. Than simply converting that array will tell you the correct val.
Arduino: using Serial and Software Serial with bluetooth module
My purpose is to use Arduino to set up communication between a PC and an Android device using an HC-05 bluetooth module. I use the USB communication between the PC and the Arduino (Serial Monitor) and a SoftwareSerial to connect to the HC-05. My problem is that the communication works well from BT to the PC, but doesn't work as expected in the other way. When sending from the PC to BT all the characters sent are received by the BT device only when I close the Serial Monitor on the PC or when I reset the Arduino. I've excluded a problem with the BT Module or the Android application because if in Arduino I implement an "ECHO" code (write in Android and the send in Android) everything works fine. With the Arduino code posted below the expected behaviour is: Arduino reset-> Hello word sent, Serial monitor opened-> nothing happens, character written on serial monitor-> character received on BT, character written on BT-> character received on Serial Monitor, Serial monitor closed-> nothing happens. The real behaviour is: Arduino reset-> Hello word sent, Serial monitor opened-> 2 Hello word on BT and 1 ("goodnight") on PC, character written on serial monitor-> nothing, character written on BT-> character received on Serial Monitor, Serial monitor closed-> previous written character(s) in serial monitor received + Hello Word. How can I fix this problem? Code: #include <SoftwareSerial.h> SoftwareSerial mySerial(2, 3); // RX, TX int a=0; char c; char d; void setup() { Serial.begin(9600); Serial.println("Goodnight moon!"); mySerial.begin(9600); mySerial.println("Hello, world?"); } void loop() { delay(10); if (Serial.available()) { c=Serial.read(); delay(10); Serial.write(c); } delay(10); if (mySerial.available()) { d=mySerial.read(); delay(10); mySerial.write(d); } }
This code is working for me on an Arduino Mini Pro (should be the same as UNO) with an HC-05. I have the HC-05 paired with my laptop. Using HyperTerminal on the COM port associated with the HC-05 and the Arduino serial console, I can send messages bidirectionally. The Serial.println statements show up in the Hyperterminal window like they should. #include <SoftwareSerial.h> #define rxPin 8 #define txPin 7 SoftwareSerial mySerial(rxPin, txPin); // RX, TX char myChar ; void setup() { Serial.begin(9600); Serial.println("Goodnight moon!"); mySerial.begin(9600); mySerial.println("Hello, world?"); } void loop(){ while(mySerial.available()){ myChar = mySerial.read(); Serial.print(myChar); } while(Serial.available()){ myChar = Serial.read(); mySerial.print(myChar); } }
I have implemented a serial communication between Arduino Uno and PC and this was my code, hope it can help: int data; char character; int start_flag = 0; void setup() { Serial.begin(921600); pinMode(2, OUTPUT); } void loop() { if(Serial.available() > 0){ character = (char) Serial.read(); if(character == 's') { start_flag = 1; } if(character == 't') { start_flag = 0; } } if (start_flag == 1) { Serial.print(data); //data that was acquired by internal ADC } }
You could try this. It's about the simplest code you can use when testing Arduino bluetooth <-> C# communication. Note: the code was tested by connecting PIN1(TX) <-> MODULE RX, PIN2(RX) <-> MODULE TX and dividing the PIN1(TX) 5V to 2,5V before feeding it to the module. Hope this helps all that are trying this!
Use this serial setup. With this code I can receive and send date to bluetooth from Serial Monitor void setup(){ Serial.begin(9600); // Begin the serial monitor at 9600bps bluetooth.begin(115200); // The Bluetooth Mate defaults to 115200bps bluetooth.print("$"); // Print three times individually bluetooth.print("$"); bluetooth.print("$"); // Enter command mode delay(100); // Short delay, wait for the Mate to send back CMD bluetooth.println("U,9600,N"); // Temporarily Change the baudrate to 9600, no parity // 115200 can be too fast at times for NewSoftSerial to relay the data reliably bluetooth.begin(9600); // Start bluetooth serial at 9600 pinMode(led, OUTPUT); pinMode(buttonPin1, INPUT); pinMode(buttonPin2, INPUT); } For more information, visit http://www.circuitmagic.com/arduino/arduino-and-bluetooth-hc-06-to-control-the-led-with-android-device/
I recommend to use this app for testing: https://play.google.com/store/apps/details?id=com.vagoscorp.virtualterminal It let you see and send bytes as bytes(number from 0b00000000 to 0b11111111 (0 to 255 in decimal)) so you can make a simple echo firmware to test if your baudrate is correct and with that working, begin sending commands to turn on/off some LEDs this is an echo code example: char dato = 0; void setup() { Serial.begin(9600);//9600 is the default baudrate of the HC-05 (you can change it by AT commands, google it if you want) //pinMode(13, OUTPUT); //enable this pin if you want to use de LED idea //digitalWrite(13, HIGH); } ////////////////////////////////////////////////////////////////////////// void serialEvent() { //if you have received serial data while (Serial.available() > 0) { char dato = (byte)Serial.read();//save the byte Serial.write(dato);//send the just received byte (echo) } } /////////////////////////////////////////////////////////////////////////// void loop() { } I hope it helps you
Had the same problem, you have to view the BT module as 2 different baud rates on the wired side and the radio side. The radio side is set by whatever you connect at through putty, the wired side is programmed via AT commands. HC-05 defaults at 38400.