Tutorial: Working with Bluetooth

We are currently trying to establisch a connection between our PC and our Arduino. For this we are trying to use a bluetooth transiever, the HC 05. In our first attempt, we useing the HC 05 as a receiver, which reads input data from our computer.

Hardware:

  • Arduino Uno R3
  • HC 05 Bluetooth
  • Bluetooth capable PC

First things first, we need to setup our devises.  Here the resistors are 100 Ohm each. This is due to the TX/RX needing 3.3V. Also keep in mind, that the RX goes to TX and vice versa.

Once we’ve got the setup, its time for the software. Herefor we are useing Processing on  PC (Win 10) to send and the Arduino IDE for the recieving arduino. Later on we are going to do it the other way around.

Step two would be pairing with the bluetooth device we just hooked up to the arduino. Under Win10 you can achieve it like follows:

  • Step 1: Open your „Options“ pannel and search for „Bluetooth“.  Once done, you will get a list of all available devices in your current area. Select the device you are trying to pair with and press „Pair“.

  • Step 2: Now the pannel will ask you for a password. If defaul it should be „1234“, if this does not work, you can look up/change the password. (For this you have to enter the AT Command Mode of the device. One can do this as discribed in this post:   AT Command Mode )

  • Step 3: Now that you have paired, all you need to know is on which port. For this click on „Extended Options“. it should list the serial ports of your PC. In our case the „COM5“, because it is outgoing.

Now we have a finnished setup and its time for some code. Since our first objektiv is sending data to our arduino, it needs to be able to recieve it. For this code to work move the TX pin to pin 8 and the RX pin to pin 7!

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8);

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
}

void loop() {
  char to_read;
  
  //while there is a signal from our HC 5
  //print it!
  while (mySerial.available()) {
    to_read = mySerial.read();
    Serial.print(to_read);
  }
}

In the code above, the arduino recieves data via the Serialports und prints it. The counter part would be the PC sending data via Processing. This looks as follows:

import processing.serial.*; 
 
//Serial port object: 
Serial arduino;       
final int  baudRate   = 9600; 
final char delimiter = '\n'; 
 
void setup() { 
  //list all the available serial ports: 
  println("Available Serial Ports:"); 
 
  //Choose your Bluetooth port:
  printArray(Serial.list()); 

  //and enter its position here:        🢃                  
  final String portName = Serial.list()[2]; 
  println("\nOpening Serial Port: " + portName);
  
  //Create instance:  
  arduino = new Serial(this, portName, baudRate); 
 
  size(500, 500); 
  textSize(16); 
} 
 
void draw() { 
  background(0);  //window: black 
  text(str(mousePressed), mouseX, mouseY); 
 
  if (mousePressed) { 
   arduino.write('a');  
  } 
}

This code was provided by Johannes Deich. What it does is open a window which tracks your current mouse position and when you left-click it writes ‚a‘ to the serialport.

All done, we have now established the connection and are sending information from PC to Arduino!

Now its time for the other direction, PC recieves data sent by the Arduino. The setup is exactly the same, only that now we have an incomming port, „COM4“ (See picture „Step 3“). Connect PC to bluetooth device as shown above and keep the current Bluetooth circuit. Again we are going to work with the Arduino IDE and Processing, since it would be nice being capable to merge both communication ways, since the only diffrence is the sofware code aspect. Here the arduino code looks as follows:

//We are only going to print on 
//our Serialport, nothing else

void setup() {
  Serial.begin(9600);
}

void loop() {
  for(int i=0; i<9; i++){
    Serial.print("data ");
    Serial.print(i);
    Serial.print('\n');
  }
  delay(100);
}

On the arduino side of things, we only have to print what we want to send on the Serialport. In Processing it looks a little different:

import processing.serial.*;


Serial arduino;      
final int baudRate   = 9600;
final char delimiter = '\n';

String serialStringFromArduino = null;

void setup() {

  //list all the available serial ports:
  println("Available Serial Ports:"); 
  printArray(Serial.list());

  //look on which port your divice is running
  //and enter it here                   🢃
  final String portName = Serial.list()[2];
  println("\nOpening Serial Port: " + portName); 

  //create instance: 
  arduino = new Serial(this, portName, baudRate);
  arduino.bufferUntil(delimiter);

  size(500, 200);
  textSize(16);
}


void draw() {
  background(0);

  //render String as text in window
  if (serialStringFromArduino != null) {
    text(serialStringFromArduino, 20, 40);
  }
}


void serialEvent(Serial arduino) {
  //read string:
  serialStringFromArduino = arduino.readString();

  //remove amongst other things whitespace and carriage return
  serialStringFromArduino = trim(serialStringFromArduino);
}

Once again we have nearly the exact same code (from Johannes Deich), manly since 95% of it are for the selection of the right port. If one already knows the port on which the Bluetooth device is running, one doesn’t need that part of the code. The rest of the code is just parseing the recieved data String. Vola, all set and done for basic Bluetooth communication.

In contrast to Xbee, WIFI-Feather and NRF technology, the Bluetooth technology makes it easier to connect to the computer(if the computer has Bluetooth). We don’t need a USB-Xbee Shield, a LAN-Router or another NRF-Module+Arduino->connected to the computer.

Tutorial: Connecting Adafruit Feather HUZZAH ESP8266 wireless in real-time to Processing 3.3/Computer

00-Introduction:

The Adafruit Feather HUZZAH ESP8266 is a simple micro controller.  A big point of the Feather is the on board WIFI(no additional Modules+ no Wires needed )! In my case, the motivation is to have a thin and light micro controller to collect data on the costume and send it in real-time wireless to a computer and remote a theater-stage.

In this so called „Tutorial“, I will document my research and steps to establish a real-time server-client-communication(raw data) between the Feather as a WIFI Client and a simple Processing Sketch as a Server. The Feather collects Sensor Data(button press), sends it wireless to the processing server. The Server(Processing Sketch) changes its status and sends feedback to the Feather, which lights a LED after a successful communication.

The research was kind of difficult. There are some tutorials, but unfortunately no real-time communication tutorials. Due to the  fact, that I am new to Web-technology, my solution might be a bit unconventional? (You might leave a comment if that is the case). Anyway here is my solution.

01-Step-by-Step-Tutorial:

I used the following components:

BASIC-Hardware

Adafruit Feather HUZZAH ESP8266

A Network(WLAN-Router, WIFI)

A Computer

BASIC-Software:

Arduino IDE

Processing

a)At first, you should set up everything:

Here, we can stick to Adafruit’s Tutorial, it is very detailed. Here are the steps in short:

  1. solder the feather, to make it easier to plug cables to it
  2. update the Arduino IDE(http://www.arduino.cc/en/Main/Software)  to use the Board Manager
  3. integrate additional Board Manager(http://arduino.esp8266.com/stable/package_esp8266com_index.json)
  4. install the ESP8266 package using the Board-Manager
  5. choose the right board and port in Arduino IDE->Tools(Adafruit HUZZAH ESP8266)
  6. choose in Tools: CPU Frequenzy(„80Mhz“), Flash Size(„4M (3M SPIFFS)“), Upload Speed(115200 baud)

Now everything should be configured and you might want to check a simple sketch(LED Blink?) and a simple WIFI-Connection? At this point we have to build our own application, without the Adafruit-Server, to get the freedom of our own server.

b) Set-Up the Arduino-Client

I use a simple Button-circuit as a sensor.(Button=1 if pressed) And I can control a LED:

You can use any other sensor instead of a button and any other actuator instead of a LED.

My final code will look like this:

CODE-Arduino

 

//programm_specific
#include <string> //to use string
int pin_out_LED; //LED
int pin_in_BUTTON; //Button
int pressing; //remembers if button is pressed
int counter; //message_out counter
String msg; //message_out content
String line; //message_in content

//time_calculation
unsigned long time_a; //start_time
unsigned long time_b; //end_time
bool time_check; //are we interested in time?
bool received;

//Configure WIFI:
#include <ESP8266WiFi.h> //Wifi-li brary


//WLAN-Config
const char* ssid = "YOUR_WIFI_NAME_?"; //Your WIFI Name?
const char* password = "YOUR_WIFI_PASSWORD?"; //Your WIFI Password?

//Host&Client
WiFiClient client; //Feather as a client
const char* host = "192.168....IP_AD.."; //My Server(processing) IP Address(Terminal:"ifconfig -a")
const int httpPort = 12345; //Servers port


void setup() {

 Serial.begin(115200); //baud rate
 pin_out_LED = 14;
 pin_in_BUTTON = 12;
 pressing = 0;
 counter = 0;
 time_a = millis();
 time_b = millis();
 time_check = false;
 received = false;
 pinMode(pin_out_LED, OUTPUT);
 pinMode(pin_in_BUTTON, INPUT);

 // We start by connecting to a WiFi network
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);

 WiFi.begin(ssid, password); //Connect to WIFI
 digitalWrite(pin_out_LED, HIGH);
 while (WiFi.status() != WL_CONNECTED) {

 delay(500);
 Serial.print(".");
 }
 digitalWrite(pin_out_LED, LOW); //We are connected to SSID
 Serial.println("");
 Serial.println("WiFi connected");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());
}

void loop() {

 if (!client.connected())
 {
 if (!client.connect(host, httpPort))
 {
 Serial.println("connection failed");
 delay(500);
 }
 } else {
 //Read Sensor
 if (digitalRead(pin_in_BUTTON)) //if( 1==digitalRead(..)) Button pressed?
 {
 if (pressing == 0)
 {
 counter++;
 if (counter > 100)
 {
 counter = 0;
 }

 msg = String(counter) + ": s \n\r";
 client.print(msg); //SEND to Server

 pressing = 1;
 time_check = true;
 received = false;
 }
 } else {
 pressing = 0;
 }

 while (client.available())
 {
 //READ SERVVVVVVVVVVVVVER
 line = client.readStringUntil('\r'); //READ from Server
 if (line.endsWith("1"))
 {
 digitalWrite(pin_out_LED, HIGH);
 received = true;
 } else if (line.endsWith("0"))
 {
 digitalWrite(pin_out_LED, LOW);
 received = true;
 }
 }

 //To calculate Send_Time
 if (time_check)
 {
 if (received)
 {
 time_b = millis();
 msg = String(time_b - time_a) + "transfer_time";
 Serial.println(msg);
 time_check = false;
 received = false;
 }
 }else
 {
 time_a = millis();
 }
 }
 
}

Whole project code, here.

1.Include, Declare,..

At first, I declare program-specific variables. To control the LED, I declare „pin_out_LED„, in setup I will set it to 14. To use the Button, i declare „pin_in_BUTTON„, in setup I well set it to 12, because of my feather-circuit. Additional I have to set the pin Modes: „pinMode(pin_out_LED, OUTPUT)“ and „pinMode(pin_in_BUTTON, INPUT)„. To remember whether the the button is pressed, I use „pressing„. A „counter“ counts the messages send by the feather. I use „msg“ and „line“ to send and read messages.

Furthermore I want to check the message-transmission-time with „time_a„, „time_b“ and „time_check„. Later more about this.

Now we have to get the WIFI working. In a) point 4, you should have installed the ESP8266, now we want to include it to our code(„#include <ESP8266WiFi.h>“) to make use of it. Manipulate the ssid by entering your WIFI’s name: const char* ssid = „YOUR_SSID_NAME_?“ and do the same with the password: const char* password = „YOUR_PASSWORD_?„. This will work for a simple WIFI connection, not with a special network, for example the university’s eduroam, where you need a username and password. For further information check here( Jan 07, 2017).  For me, a cheap router or my smartphone’s LAN worked fine.. We have to make the Feather as a client: „WiFiClient client“ . You need to know and enter your hosts IP-Address(const char* host = „192.168.1.33“) You need to check it at the computer, where your server(processing sketch) runs. A short research will help to find it. In Ubuntu/Linux, one can simply enter „ifconfig -a“ in Terminal to get it. Later in the processing sketch, we will define a port, through which we will communicate to the server. You can use this one(const int httpPort = 12345).

2.setup()

The setup() part is pretty much straight forward. We begin connecting to the WIFI and the LED is High and we print dots in the Arduino-IDE-Serial-Monitor(Ubuntu: STR+Shift+M), while it is connecting.

It should print: „Wifi connected“.

3.loop()

We always check, whether we are already or still connected to the server. „if (!client.connected())“ . There is a great difference towards the next if request: „if (!client.connect(host, httpPort))“  In contrast to the first, the second one always sends a new server connection request! We only need a new connection if we are not connected yet! Usually Client-Server communication uses client.connect(host, httpPort). A client sends a request and closes the connection, but we do not want to close the connection. We stay connected to save time! We don’t use the common HTTP Get Request, we will simply send RAW-Sensor-Data. That should be efficient and therefore better for real-time communication! At first I was not aware of the difference, I was only using the second one. After sending about 500 messages between server and client I received  „exception 29″ in the Arduino Serial-Monitor, because of memory overflow.  Furthermore processing warned „client got end-of-stream„.

Anyway if we can not connect to the host-server(processing) it will print connection failed. If we are already connected, the procedure can go on!

We only want to send a message, if(if (digitalRead(pin_in_BUTTON))) the Button is newly(if (pressing == 0)) pressed(I press once and hold it pressed, but I only want to send one message!) Whenever that is the case, we send a message(and make counter++, make a time_check,..):

msg = String(counter) + „: s \n\r“;
client.print(msg);

I will always send and receive with a \r at the end of the message, to make it easier to parse! To receive a message, we check whether there is an incoming message with client.available().  

line = client.readStringUntil(‚\r‘);

We read the message until ‚\r‘ and check, whether we received a „1“ or „0“ and according to this, we turn the LED HIGH or LOW.

In between, there is some time_checking. You might want to use or improve it? I get 4ms to 100ms transmission time and in average about 15ms.

c)Set Up the Processing-Server

Now I create a simple server on my computer, using processing .I want to receive a message sent by the feather/client to trigger(on and off) a virtual water faucet(older project of mine):

Whenever there is a change, I want to send feedback to the feather/client(feather lights the LED).

My Full-Code will look like this:

CODE-Processing

import java.util.*;
//#####################Server_stuff:####################################
import processing.net.*;
Server s; 
Client c;
String input;
//######################################################################

//Bilder:
ArrayList<PImage> bilder_a;
ArrayList<PImage> bilder_b;

int phase; //Aktuelle Bild-Nr
int direc; //An oder Aus?
int mode; //Focus
int pic_anzahl; //Anzahl an Bildern

void setup() {
 //Video:
 //fullScreen(); 
 size(600, 300);
 frameRate(25); 
 orientation(LANDSCAPE); //Bug?!

 //Load Pictures:
 bilder_a=new ArrayList(); 
 bilder_b=new ArrayList();
 pic_anzahl=9;

 String pic_name;
 for (int i=0; i<=pic_anzahl; i++)
 {
 pic_name="pic_a"+i+".JPG";
 bilder_a.add(loadImage(pic_name));
 pic_name="pic_b"+i+".JPG";
 bilder_b.add(loadImage(pic_name));
 }

 //Setting_UP:
 phase=0; //Wasser Bild 0
 mode=0; //Focus auf Hebel
 direc=-1; //Wasser auschalten

 //#####################Server_stuff:####################################
 s = new Server(this, 12345); // Start a simple server on a port
 //######################################################################
}

void draw() {
 //#####################Server_stuff:####################################
 c = s.available();
 //println(c);
 if (c != null) 
 {
 input = c.readStringUntil('\r'); 
 //input = input.substring(0, input.indexOf("\n")); // Only up to the newline
 println(input);

 if (input.contains("s"))
 {
 if (phase==0)
 {
 phase=1;
 //#####################Server_stuff:####################################
 s.write("1\r");
 } else {
 s.write("0\r");
 //######################################################################
 }
 direc=direc*-1;
 }
 } 

 //######################################################################

 if (phase>0) //Wasser läuft
 {
 if (phase>8) //Repeat:
 {
 phase=4;
 }
 phase+=direc; //Up or Down
 } 

 //Focus:
 if (mode==0)
 {
 image(bilder_a.get(phase), 0, 0, width, height); //Focus: Hebel
 } else
 {
 image(bilder_b.get(phase), 0, 0, width, height); //Focus: Hahn
 }
}

void mousePressed()
{
 if (mouseX>width/2) //switch foucs: Hebel/Hahn
 {
 mode++;
 mode=mode%2;
 } else //switch Wasser: an/aus
 {

 if (phase==0)
 {
 phase=1;
 //#####################Server_stuff:####################################
 s.write("1\r");
 } else {
 s.write("0\r");
 //######################################################################
 }
 direc=direc*-1;
 }
}

To make the faucet working, you need the whole project with pictures, here.

1.Include, Declare,..

I import processing.net.* to be able to use Server and Client!

2.setup()

I open a Server s = new Server(this, 12345);  at port 12345. You can change the port if you like.

3.draw()

To receive a message send by feather/client, we check whether there is an incoming message with c = s.available().  

If there is a message( if (c != null)), we read the incoming String until ‚\r‘:

 input = c.readStringUntil(‚\r‘); 

We check the input, whether it contains(„s“) and change the faucet’s state and transmit the changes back to the feather/client:

s.write(„1\r“);

The rest of the Code contains only my faucet mechanics.

I hope my tutorial helps people getting their real-time feather to processing application working!

 

02-Some Ideas:

a)Just to answer some study-questions:

  • Yes, one can work without Adafruit’s Server(obviously I am using my own server)
  • no it is not just a close cloud communication system, I guess the feather is open, to work with like any web-application

 

b)Just to give some study-questions:

  • NodeMCU’s Lua or Arduino IDE to configure Feather?
  • How long is the battery lifetime while sending in real-time?
  • One could compare latency(time) and range in different Networks? (I only tried a simple router and my smartphone)
  • Should one preferably use UDP or TCP?
  • Switch roles? Feather as Server and Processing as Client?
  • How does our application work, if there is more traffic on the server?

 

c)Further Ideas:

  • You could secure your connection, because everyone can read it the way it is at the moment. It might be interesting to observe the transmission vie TCP DUMP or Wireshark?
  • If the application stays that way and you only press the button/send a message once in a long while it might be necessary to send a heartbeat from time to time in order to keep the connection.
  • Instead of parsing Strings, we could send simple Bits or Bytes. That would make everything more efficient.
  • At the moment I am only sending when I press the button. It also worked, when I was sending ping pong like all the time.

 

Tutorial: Connecting Arduino-LilyPad wireless via XBee to Processing 3.3/Computer

00-Introduction:

This simple tutorial documents our first Costumes and Environment work. A wireless connection is fundamental to connect a dancer or actor to its environment. The Xbee-Technology is one possibility to send sensor data, collected by the Arduino Lilypad to the computer.

We used the following components:

Hardware:

  • LilyPad
  • LilyPad Xbee
  • Xbee S1   x2
  • Xbee USB Shield

Software:

  • Arduino IDE
  • Processing
  • XCTU

The result looks like this:

Whenever the button is pressed, the Lilypad sends a serial message to the Lilypad-Xbee-Component. That message is transmitted wirelessly to the other Xbee-Component, which is connected via USB to the Computer. In processing, the message can be read like an event. In our case a visual entity, a circle, simply changes destination.

01-Step-by-Step-Tutorial:

a)At first, we should create a simple Lilypad-circuit, to collect sensor-data. For example a pushbutton: https://www.arduino.cc/en/Tutorial/Button Any circuit is fine, as long as we can determine a state(Serial-Monitor: 0, 1 or whatever).

b)Now it is time to configure your XBees. You connect each XBee at a time via USB to the Computer and edit it in XCTU. You want them to communicate in the same channel(For Example C). Furthermore the source of each XBee  should be the destination of the other XBee.

XCTU: Configure Xbee

c)We can integrate the XBees in the circuit. The XBee-Lilypad-Shield should get at least 3.3V(we used a 9V blockbatterie). Furthermore you connect the Arduino Lilypad rx with the Xbee-Lilypad-Shield tx and the other way round, so that ones serial input(rx=receive) can receive messages from the others serial output(tx=transmit). The USB-XBee simply has to be plugged into the PC.  We prefer that modular way of connecting, to keep things replaceable and (de)composable!

We don’t want an LED to blink, when we press the button, so we modify the Arduino Code and communicate with the XBee:

...
void setup() {
  Serial.begin(9600);
  pinMode(11, INPUT);
}

void loop(){
  int button = digitalRead(11);
  
  //Checks if button is pressed
  if (button == 1){ 
    
    //When input availabe, it prints
    if(Serial.available()){
      Serial.println("Button Pushed!");
      delay(1);
    }

    //Onboard LED Blinks if there is no Input to receive  
    digitalWrite(13,HIGH);
    delay(250);
    digitalWrite(13, LOW);
    delay(250);   
  }

  else {

    //Prints Stuff if nothing is received
    if(!Serial.available()){
      print_mh();
      print_pon();
    }
   
    //Prints Input if there is some
    else if(Serial.available()){
      Serial.println(Serial.read());
      delay(100);
    }
  }
}

d)Now we should build a simple processing Sketch. We simply used an older sketch of mine, which looks quite complicated. But any sketch is fine, as long as it works! For example a simple keyboard input-sketch: https://processing.org/examples/keyboard.html

Anyway, that is my sketch:

wechsel.pde is a processing sketch, with simple circles(entities). They interact via reciprocal attraction. Furthermore their behavior is influenced by random noise. Usually I control a special entity with mouse or touch. -Phil

e)Now I want to integrate the XBee to Processing. In the Setup, we have to find the right port. So you check processing’s console for your USB-Port. Than you have to configure your code to fit to your port!

import processing.serial.*; //To work with the serial XBEE
Serial xbee;                //Declare XBEE
...

void setup()
{
 ...
  //FIND PORT
  for (int i=0; i< Serial.list().length; i++)
  {
    //Check console and search for your USB-Port
    println(i+": "+Serial.list()[i]);    
  }

  //SELECT PORT
  //In my case, Serial.list()[38] is the right port..
  //You have to check your console and enter your Port here
  //manually!
  xbee = new Serial(this, Serial.list()[38], 9600);
  //Your Baud-Rate should be the same in Ardunio and
  //Processing, for example 9600!
}
...

See the Console:

Furthermore, we need a Free-Event-Function, that is acivated, whenever the XBee receives something.:

String message;
void serialEvent(Serial xbee) {
   message = xbee.readStringUntil(10); // read incommung String

  if (message != null) {                       
    println(message);                  //Print message to console
    //Do_Something_With_This_message!
  }
}

Now one can simply use the XBee-Input the way you used the keyboard/mouse/touch-input in d).

02-Sources:

In order to build this tutorial, the following sources were helpful:

Tutorial: Simple Wireless Textile Stretch Sensor with XBee and LilyPad

https://forum.processing.org/two/discussion/4943/how-to-connect-xbee-with-processing