Monday, August 17, 2015

Internet of things - Rasberry Pi - Alamode Arduino Shield - Bluetooth Mate RN41/RN42 - SPP - MAX31855 Thermocouple

Now that we have a running aRest App running on Alamode we can add MAX31855 breakout board to connect a Thermocouple K cable and query the temperature from a Windows laptop by sending aRest API command over SPP

Friday, August 14, 2015

Internet of things - Rasberry Pi2


Hook up your board

  1. Insert the micro SD card you prepared (the slot is on the opposite side of the board shown below).
  2. Connect a network cable from your local network to the Ethernet port on the board. Make sure your development PC is on the same network.

  3. Connect an HDMI monitor to the HDMI port on the board.
  4. Connect the power supply to the micro USB port on the board.

Install the Rasbian 20XX-XX-XX-raspbian-wheezy.img or Ubuntu Mate image Windows


  1. Download the IMG for the Raspberry Pi 2 from raspberrypi.org or from https://ubuntu-mate.org/raspberry-pi/ for Ubuntu Mate.  For Ubuntu mate mouse over on one of the country icon and use wget if you want to download inside a Window shell
eg: wget http://can.ubuntu-mate.net/raspberry-pi/ubuntu-mate-15.04-desktop-armhf-raspberry-pi-2.img.bz2

Put the Image on your SD card


Using the Win32DiskImager program

1.   Download the distribution from the raspberrypi.org downloads page or from a mirror or torrent. Make sure the distribution is for the Raspberry Pi, as others will not work. Usually these are zipped (compressed) files ending in .zip or .gz (something like "distribution-name.zip").
2.   Extract the image file from the downloaded .zip file, so you now have "distribution-name.img".
3.   Insert the SD card into your SD card reader and check what drive letter it was assigned. You can easily see the drive letter (for example G:) by looking in the left column of Windows Explorer. You can use the SD Card slot (if you have one) or a cheap Adapter in a USB slot.
4.   Download the Win32DiskImager utility (it is also a zip file). You can run this from a USB drive.


5.   Extract the executable from the zip file and run the Win32DiskImager utility; you may need to run the utility as Administrator! Right-click on the file, and select 'Run as Administrator'
6.   Select the image file you extracted above.
7.   Select the drive letter of the SD card in the device box. Be careful to select the correct drive; if you get the wrong one you can destroy your data on the computer's hard disk! If you are using an SD Card slot in your computer (if you have one) and can't see the drive in the Win32DiskImager window, try using a cheap Adapter in a USB slot.
8.   Click Write and wait for the write to complete.
9.   Exit the imager and eject the SD card.
10. You are now ready to plug the card into your Raspberry Pi

Raspbian


if you plan to use an apple keyboard (the white one) connect the Mouse directly on the Pi which now has 4 external USB! Sweet! Else the keyboard won't be recognize

User management in Raspbian is done on the command line. The default user is pi with the password raspberry. You can add users and change each user's password.

CHANGE YOUR PASSWORD

When logged in as the pi user you can change your password with the passwd command.

Enter passwd on the command line and hit Enter. You'll be prompted to enter your current password to authenticate, and then asked for a new password. Hit Enter on completion and you'll be asked to confirm it. Note that no characters will be displayed while entering your password. Once you've correctly confirmed, you'll be shown a success message (passwd: password updated successfully) and the new password will be in effect immediately.

If your user has sudo permissions, you can change another user's password with passwd proceeded by the user's username, e.g. sudo passwd bob will allow you to set the user bob's password, and then some additional optional values for the user such as their name. Just hit Enter to skip each of these options.

Keyboard

sudo dpkg-reconfigure keyboard-configuration

Reload the keymap

invoke-rc.d keyboard-setup start









AlaMode works on the Pi 2


ICoutesy Element 14
the new Pi 2 is quite snappy, even the web browser is quite useable. It should be a marvelous platform for your IOT projects! Especially with AlaMode.
It has the same form factor as the B+ so you have to plug the AlaMode’s shorter GPIO connector into one end of the header, and the board overlaps the connector end of the Pi by a few millimeters. I recommend putting some electrical tape over the metal cans of the connectors to keep from shorting AlaMode’s headers.
Because the Pi 2 has a new processor, the GPIO base addressed changed, which makes us update our patched version of avrdude. (needed because standard Arduinos use serial ports handshaking to toggle the reset line, we use a GPIO pin)
Get the new setup here:
wget https://github.com/wyolum/alamode/blob/master/bundles/alamode-setup.tar.gz?raw=true
tar -xvzf alamode-setup.tar.gz
cd alamode-setup
sudo ./setup
Note if you haven’t already, you’ll need a new version of Raspbian that supports the Pi2, plus installing Arduino 
pi@raspberrypi ~ $ sudo apt-get update
pi@raspberrypi ~ $ sudo apt-get install arduino
before running the setup above.

      Ubuntu Mate


Re-size file system (Wheezy)

There are no utilities included for automatic file system re-sizing. However, it's not hard to do manually. Once booted:
$sudo fdisk /dev/mmcblk0
Delete the second partition (d, 2), then re-create it using the defaults (n, p, 2, enter, enter), then write and exit (w). Reboot the system, then:
$sudo resize2fs /dev/mmcblk0p2

$ sudo parted /dev/mmcblk0p2
(parted) print

In my case using a 16GB sdcard
Model: Unknown (unknown)
Disk: /dev/mmcblk0p2: 15.9 GB
Sector size (logical/physical): 512B/512B
Partition Table: loop
Disk FLags:

Number Start End Size File systen Flags
1      0.00B 15.9GB   ext4
(parted) quit
$pi@pi-desktop:~$

Hardware accelerated video

To play videos using hardware accelerated decoding you will need MPEG-2 and/or VC-1 licenses from the Raspberry Pi Store. You can then use omxplayer, which uses the Raspberry Pi VideoCore libraries, to provide hardware accelerated video playback.

Redirecting audio output

You can select which audio device omxplayer should output audio to.
For HDMI
omxplayer -o hdmi video.mp4
For 3.5mm audio jack
omxplayer -o local video.mp4
The sound will output to HDMI by default if both HDMI and the 3.5mm audio jack are connected. You can, however, force the system to output to a particular device using amixer.
For HDMI
sudo amixer cset numid=3 2
For 3.5mm audio jack
sudo amixer cset numid=3 1
 

Wifi dongle

I purchased Netis WF2120 worked out of the box!! 

Microsoft Wireless All In one keyboard 

work out of the box with Raspbian Jessie 

Apple Wireless Keyboard and Apple Magic Mouse

 
I managed to get an "Apple Wireless Keyboard" and "Apple Magic Mouse" 
working.  The is a lot of crap out there on how to do it.  This is what 
worked here (blueman did NOT work).
The advantage of doing it this way is that the keyboard and mouse are available without X.
Here they work at boot.

Buy BLE USB dongle : Cirago BTA8000 worked out of the box!!

Get root
sudo -i

apt-get install bluetooth bluez-tools
Wait a long time....

check bluetooth status:
/etc/init.d/bluetooth status

You may need to start bluetooth, if its not running:
/etc/init.d/bluetooth start

hciconfig -a
You should see a line with "UP RUNNING PSCAN" probably on hci0

If its down you it may come up with:
hciconfig hci0 up

Once hci0 is up, find the address of the device you want to pair:
hcitool scan
and copy the bluetooth address to use in the following commands

pair the keyboard (here an old apple wireless keyboard):
bluez-simple-agent hci0 68:D9:3C:ED:47:15

it will prompt you for a pin, enter a 4 digit number for the keyboard, then type in on the keyboard and press enter on it.
For the mouse try 0000 or 1234. If you need to pair
again you may get and error. If so append repair after the and the old
pairing is deleted.


You want your Pi to remember that your keyboard’s paired with it so it will connect to that keyboard when it boots. You can tell your Pi to trust your keyboard with the bluez-test-device command.trust the device:
bluez-test-device trusted yes

and connect it:
bluez-test-input connect


Once you’ve got your Apple keyboard paired, trusted, and conneted, you can unplug your USB keyboard and reboot your Pi. If your Pi doesn’t immediately pick up your Apple keyboard on boot, you can prompt it to connect my pressing any key. The LED will flash once, and then you can type normally.repeat the pairing, trusting, connects for each device. I have only tested this with input
devices (eg keyboard and mouse).


If you need a GUI tool for Bluetooth install Blueman

sudo apt-get install blueman

For Cambridge Silicon Radio Bluetooth Dongle

make following change:
add line "blacklist hci_usb" into /etc/modprobe.d/alsa-base-blacklist.conf
and line "hci_usb reset=1" into /etc/modules. After reboot dongle should work


PS3 DualShick controller on PI

install dependencies first

sudo apt-get install bluez-utils bluez-compat bluez-hcidump checkinstall libusb-dev  libbluetooth-dev joystick

It takes a while.

After all type "hciconfig" in console, you should see something like this.

pi@raspberrypi ~ $ hciconfig
hci0: Type: BR/EDR Bus: USB
 BD Address: 00:1F:81:00:06:20 ACL MTU: 1021:4 SCO MTU: 180:1
UP RUNNING PSCAN
RX bytes:1260 acl:0 sco:0 events:46 errors:0
TX bytes:452 acl:0 sco:0 commands:45 errors:0


if not, your dongle seems not to be recognized by system.

So now, we need to pairing the dongle with the gamepad using this tool.

download and compile it.

wget http://www.pabr.org/sixlinux/sixpair.c
gcc -o sixpair sixpair.c -lusb

After this you should have a executable file "sixpair".
Now connect your  Dualshock via a USB cable for PS3 to Raspberry Pi and launch this file with sudo.

sudo ./sixpair

Current Bluetooth master: DE:AD:BE:EF:00:00
Setting master bd_addr to: 00:1F:81:00:06:20
 

If you see this, it was successful.

Install a Sixaxis Joystick Manager. Download a last archive and compile only important for us part.

wgethttp://sourceforge.net/projects/qtsixa/files/QtSixA%201.5.1/QtSixA-1.5.1-src.tar.gz
tar xfvz QtSixA-1.5.1-src.tar.gz
cd QtSixA-1.5.1/sixad
make
sudo mkdir -p /var/lib/sixad/profiles
sudo checkinstall

the last command make automatically a package for you, so you can later simple uninstall it, if you won't it or use a different system, type  "sudo make install" instead of "sudo checkinstall"

Now test it, for this launch temporary a sixad daemon.

sudo sixad --start

Then press a "PS" button on Dualshock gamepad, if you feel a vibration, it works, congratulations!

After all you can make "sixad" daemon starting at boot time.

sudo update-rc.d sixad defaults
reboot


If you have any trouble with recognition, you can debug your Dualshock controller with "jstest".

sudo jstest /dev/input/js0

Finally you will need to purchase a charher for the PS3 controller if you don't have a PS3.
I got the Energizer one and I like it a lot http://www.bhphotovideo.com/c/product/1056118-REG/energizer_pl6328_ps3_energizer_charging_system.html
 

Friday, August 07, 2015

Internet of things - Rasberry Pi - Alamode Arduino Shield - Cool projects

Adafruit-MAX31855-library https://github.com/adafruit/Adafruit-MAX31855-library
https://learn.adafruit.com/thermocouple

GreenEgg Heatermeter Pit Probe
http://www.instructables.com/id/HeaterMeter-Pit-Probe/

CmdMessenger
https://github.com/thijse/Arduino-Libraries/tree/master/CmdMessenger


Automated Cooling fan for Pi
http://m.instructables.com/id/Automated-cooling-fan-for-Pi/
http://m.instructables.com/id/Temperature-Controlled-Fan/?ALLSTEPS

Multi Camera ir control
http://sebastian.setz.name/arduino/my-libraries/multi-camera-ir-control/

Multi Color Lamp using Amarino Android and arduino
http://www.buildcircuit.com/multi-color-lamp-using-amarino-android-and-arduino/
https://code.google.com/p/amarino/
https://github.com/arduino/BTSerial

Arduino Pool Management System
https://blog.adafruit.com/2012/08/27/ridercool-an-arduinoadafruit-pool-management-system/

Reverse engineering a bluetooth low energy light bulb
https://learn.adafruit.com/reverse-engineering-a-bluetooth-low-energy-light-bulb/sniff-protocol

Setting up the arduino pro mini and bluetooth mate on mac
http://www.rioleo.org/setting-up-the-arduino-pro-mini-and-bluetooth-mate-on-mac.php

Thursday, August 06, 2015

Internet of things - Rasberry Pi - Alamode Arduino Shield - Bluetooth Mate RN41/RN42 - SPP

re you ready to hit the airwaves and add Bluetooth to your project? With the BlueSMiRF and Bluetooth Mate line of products, you’re much closer than you think to replacing those pesky, tangled RX and TX wires with 2.4GHz wireless communication.
Bluetooth Mate Gold and Silvers
Each of these modules has a Bluetooth transceiver on it, meaning they’re capable of both sending and receiving data. They’re perfect for directly replacing a wired asynchronous serial interface. Free of wires, your devices can be up to 100 meters away (RN41 Gold) from each other. On top of those benefits, these modules are also very easy to use. There’s no messing with Bluetooth protocols or the stack, just send data over a serial interface, and it’s piped through to whatever Bluetooth module to which it’s connected.

Materials and Tools

For starters, you’ll need one of the four Bluetooth modems we’ll be covering in this tutorial: the Bluetooth Mate Silver,BlueSMiRF SilverBluetooth Mate Gold, or BlueSMiRF Gold. The modules all function in the same way, so this tutorial is applicable to all four.
Wireless communication won’t do you any good unless you have two devices that can talk to each other! These Bluetooth modems can talk to any other Bluetooth device that supports SPP. That (long) list includes other BlueSMiRFs or Bluetooth Mates, or Bluetooth modules embedded into your computer, or even your smartphone. If your computer doesn’t already have a Bluetooth module in it, you can plug a Bluetooth USB Module into an available USB slot.
We’ll also need something to talk to the Bluetooth modem on the serial end. This will usually be a microcontroller of some sort. In this tutorial we’ll be using the Alamode Arduino Shield seating on top of the Rasberry pi

SMiRF? Mate? Silver? Gold? What’s the Difference?

The “Silver” and “Gold” designations of these modules indicates whether they use an RN-42 Bluetooth module or an RN-41. The Silvers use the RN-42, and the Gold uses an RN-41. The difference between those two modules? Range and transmit power. The RN-41 is a class 1 Bluetooth module, so it can communicate at up to 100 meters, but it also transmits at a higher power (meaning shorter battery life). The RN-42 is class 2, which limits the transmit range to about 10 meters.
The difference between Mate and SMiRF all comes down to the pin-out of the six-pin header. If you flip each of the boards over, and look at the pin labels, this is what you’ll see:
Pinout of BlueSMiRF and Bluetooth Mate

Design Overview

The RN-42 and RN-41 are pin-for-pin compatible, so the schematic for each of these boards is the same. The only difference exists at the connector pin-out for the Mate and SMiRF. Click the image below to see a bigger view of the schematic (or click here to see it in PDF form).
Bluetooth Mate Silver Schematic
Key to the design are level shifting circuits between the RN-41/42’s serial pins, and the output header. The maximum operating voltage of the Roving Networks modules is 3.3V, so these enable a device operating at 5V (like an Arduino) to safely communicate with the Bluetooth modems. There is also a linear 3.3V regulator on the board, so a voltage from 3.3V to 6V can be used to supply power to the module.
The boards also include two LEDs. There’s a red “Stat” LED, and a green “Connect” LED. These can be used to determine what state the Bluetooth module is in.
Annotated Board
Finally, be aware of where the antenna is – give it some room to breathe. Don’t place it near any big chunks of metal or enclose it in a Faraday cage, and you should be just fine.

The Pinouts

Each of the four Bluetooth boards breaks out six pins. Four pins are devoted to the serial interface, and the other two are for power.
Pin LabelPin FunctionInput, Output, Power?Description
RTS-ORequest to sendOutputRTS is used for hardware flow control in some serial interfaces. This output is not critical for simple serial communication.
RX-ISerial receiveInputThis pin receives serial data from another device. It should be connected to the TX of the other device.
TX-OSerial transmitOutputThis pin sends serial data to another device. It should be connected to the RX of the other device.
VCCVoltage supplyPower InThis voltage supply signal is routed through a 3.3V regulator, then routed to the Bluetooth module. It should range from 3.3V to 6V.
CTS-IClear to sendInputCTS is another serial flow control signal. Like RTS, it's not required for most, simple serial interfaces.
GNDGroundPower InThe 0V reference voltage, common to any other device connected to the Bluetooth modem.

Powering the Modules

These Bluetooth devices are designed to work seamlessly in both 3.3V and 5V systems. The voltage supplied to the VCC/GND pins can be anywhere between 3.3V and 6V. Voltages on the input serial and control signals (RX-I and CTS-I) can be anywhere between 3.3V and 5V. The output signals (TX-O and RTS-O) will range from 0V for a LOW logic level, and VCC for a HIGH. That means if you power them at 6V, the TX and RTS signals will output up to 6V.
The current consumption of a modem depends on what it’s doing at the time. It can be as low as 0.026mA when the device is asleep, and as high as 50mA when data is being transmitted. This table from the datasheet provides some good estimates:
Current consumption characteristics

Connecting a device up to the Bluetooth modems is as easy as applying power and wiring up the serial RX and TX pins. What do we send over that serial interface, though? That’s where we need to look at the the firmware and the Bluetooth module’s operation modes.

Hardware Hookup

Assembly

Happily, most of the assembly on these modules is done for you; you don’t need to learn how to solder SMD components just yet. However, before you can begin using these Bluetooth modules, you’ll need to solder somethinginto the six plated-through-holes to form a solid electrical connection.
What you solder into the holes depends mostly on what you’re going to connect the device to. If you’ve got a Bluetooth Mate, and want to connect it directly to an Arduino Pro, you may want to throw a right-angle female header on there. Another good option, which makes the board breadboard-compatible, is male-headers. A third, ever-reliable option is to solder wires directly to the holes.

Connecting Everything Together

We need to connect the Bluetooth modems to devices that can send and receive serial signals. These are TTL-levelserial signals, make sure you don’t confuse that with RS-232! Voltages should be between 3.3V and 5V. There are loads of options here, for this tutorial we’ll use an Arduino.
Instead of connecting the Bluetooth modem to the Arduino’s lone hardware UART, we’ll use SoftwareSerial and connect the modem’s RX and TX pins to any of the Arduino’s free digital pins. This will help to avoid bus contention and will make sure the Bluetooth modem doesn’t receive any spurious data during a sketch upload. Here’s the connections we’ll make for the example code later in this tutorial:
Fritzing diagram

Note that this is a Bluetooth Mate shown in the Fritzing diagram, the BlueSMiRF will have a different pinout.

For Alamode


TX-O is connected to D2 of the Alamode (blue), RX-I is connected to D3 (white), GND goes to GND, and VCC goes to 5V. The CTS-I and RTS-O pins are left floating. The TX-O and RX-I pins could really be connected to any digital pin (besides 0 and 1), so if you need 2 and 3 for something else, feel free to move those around.

Half of the hardware hookup is done. We still need to create a wireless connection to another Bluetooth device. Before we can delve further into that, though, we need to understand more about the Bluetooth modem’s firmware.

Firmware Overview

serial interface is all it takes to control these Bluetooth modules and send data through them. They act, essentially, like a data pipeline. Serial data that goes into the module (from the RX-I pin), is passed out the Bluetooth connection. Data coming in from the Bluetooth side is passed out the serial side (out the TX-O pin).
How data passes through modem
Establishing this data pipeline is a two step process. First, we need to connect something capable of sending and receiving serial data to the header of the Bluetooth modem. We achieved this in the Hardware Hookup phase by connecting an Arduino to the serial header, but any microcontroller with a UART could work. With the device connected we need to configure the serial port to work at the same baud rate the the modem is configured to – they default to 115200 bps (8-N-1).
Secondly, on the Bluetooth end of things, we need to establish a wireless connection between the modem and another Bluetooth device. The only stipulation here is the other Bluetooth device must support SPP (which most do). This connection involves a pairing process similar to connecting any other Bluetooth devices together. More on that later. Let’s talk a bit more about the serial interface.

Data and Command Modes

Controlling the Bluetooth module and sending data through it are two very separate operations, but they’re both done via the serial interface. To differentiate between these two forms of data, the Bluetooth modules implement two different communication modes.
Command mode is used to configure the Bluetooth module. Characteristics like the device name, baud rate, PIN code, and data rate can be adjusted in command mode. This is also where action commands are sent to the module, which can tell it to connect to a device or scan for other modules.
In data mode, the Bluetooth module acts as a transparent data gateway. Any data received over the Bluetooth connection is routed out the module’s TX pin. And data sent to the module’s RX pin is piped out over the Bluetooth connection.
Data and command mode examples
To enter command mode from data mode, the host controller needs to send a string of three $ symbols ($$$).

Configuration Timer

The configuration timer is the one obstacle to watch out for when entering command mode. The config timer begins counting as soon as the Bluetooth modem is turned on, and once it’s done counting, you’ll be unable to enter config mode unless you cycle power. By default the config timer is set to 60 seconds, however this can be adjusted, or even turned off (that’s the ticket!).

Deciphering the LEDs

There are two LEDs on the Bluetooth modems: a red one labeled “Stat”, and a green one labeled “Connect”. These help to indicate the status of the module. Never forget the importance of blinkies! The green LED will illuminate when a wireless connection is formed. The “Stat” LED can indicate that the module is in one of three states, depending on how fast it blinks:
ModeStat Blink RateNotes
Configuration10 per secondModule is in config mode.
Startup/Config Timer2 per secondModule is not in config mode, but the configuration timer is still counting.
Discoverable/Inquiring/Idle1 per secondNot in config mode, and the config timer has run out.

If you’re having trouble getting the module to enter configuration mode, make sure the timer hasn’t run out by checking for a very slow blink rate.

Bridge Mode 

 In bridge mode the BT is used to foward packet received over BT to Serial port and then the data is send over debug serial port of Alamode which is connected to the Rasberry PI serial port. This means that app running on the Rasberry pi will also receive the data transiting  through the running Arduino Sketch on the ATMEL MCU. pretty Sweet!

/*
  Example Bluetooth Serial Passthrough Sketch
 by: Jim Lindblom
 SparkFun Electronics
 date: February 26, 2013
 license: Public domain

 This example sketch converts an RN-42 bluetooth module to
 communicate at 9600 bps (from 115200), and passes any serial
 data between Serial Monitor and bluetooth module.
 */
#include   

int bluetoothTx = 2;  // TX-O pin of bluetooth mate, Arduino D2
int bluetoothRx = 3;  // RX-I pin of bluetooth mate, Arduino D3

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

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
}

void loop()
{
  if(bluetooth.available())  // If the bluetooth sent any characters
  {
    // Send any characters the bluetooth prints to the serial monitor
    Serial.print((char)bluetooth.read());  
  }
  if(Serial.available())  // If stuff was typed in the serial monitor
  {
    // Send any characters the Serial monitor prints to the bluetooth
    bluetooth.print((char)Serial.read());
  }
  // and loop forever and ever!
}


Now you are good to use aRest.io with BluetoothMate !!

This sketch makes use of the SoftwareSerial library, which should be included with most of the recent versions of Arduino.
At the beginning of the sketch, the Arduino enters the command mode string and temporarily changes the Bluetooth modem’s baud rate to 9600 bps (using the U,9600,N command). Remember this is temporary, so when power is cycled, the modem will default back to 115200 bps.
The loop of the sketch simply checks to see if either the Bluetooth modem or the Serial Monitor have sent any data to the Arduino. If so, it’ll relay the data sent from one device to the other.

Using the Passthrough Sketch

With the code uploaded, and everything hooked up accordingly, open up the Serial Monitor. Make sure the baud rate is set to 9600. Throughout this process you’ll have to fudge around with the dropdown menu to the left of the baud rate selection. It should initially be set to “No line ending”.
First, let’s enter command mode by typing $$$, and click “Send”. You should see the Bluetooth modem respond with CMD, and you’ll notice the red Stat LED blinking much faster, this all indicates that the device is in command mode.
Once you’re in command mode, you’ll need to change the line ending dropdown to “Newline”. The basis of all this is that the RN-42 module expects a newline character after every command except for the command mode string. Annoying, but we’ll deal.

Using GET Commands

The GET commands are a good place to start using command mode, they’ll display settings, status, or other information that might be helpful. Try sending the “Display Basic Settings” command by typing “D”, and pressing “Send”. This will trigger a response from the Bluetooth modem that details, among other things, the baud rate settings, the name, and the address (BTA) of the device. The address is something you should take note of, it can either be identified from this command, or by taking a gander at the module’s label, next to the “MAC NO”. Each Bluetooth moule has a unique address which can’t be changed. Try sending the other get commands, and see what information you can retrieve from the modem.
Displaying Settings from Command Mode

Using SET Commands

After sending the “D” command, you may have noticed your Bluetooth modem has it’s own name, in addition to the address. Unlike the address, this name can be changed to whatever you’d like. By default it’ll be RN42-XXXX, where XXXX is the last four digits of the address. Let’s give a SET command a whirl. The SN, command is used to set the name, where is any collection of up to 20 characters. Think up a unique name, and assign it to your device. After sending the SN command, the modem should respond with an “AOK”. Now if you send the D command, you should see your new name listed next to the “BTName” setting.
Using the SET name command
Be careful with the SET commands, only change something if you’re sure it won’t negatively affect the modem, or your ability to communicate with it. If you change something you don’t think you should have, send the SF, 1 command to reset everything back to its factory default value. Another handy command, if you’re lazy like me, is ST,0, which turns the config timer off. Remember that any setting you modify will be saved to the Bluetooth modem’s memory, and will be retained upon loss of power.

ACTION Commands

Finally, it’s time for some action. Among other things the Bluetooth modem’s ACTION commands can be used to find other Bluetooth devices, connect to them, and disconnect from them.
Begin by sending the inquiry scan command – I, – to search for other Bluetooth modules in range. The parameter defines the number of seconds the modem will take to look for other modules. It’ll default to 10 if not defined. If you just type “I” and click send, the device should respond with a “Inquiry, COD=0”, and then after ten seconds it’ll respond with any Bluetooth modules it found. It will print their information as “BT address, BT name, COD” (COD is class of device).
Connecting via command mode
If the modem finds any modules, you can try sending the connect command – C,
 – to connect to one of them. The modem in the example above found two devices in range, by sending the C,000666421B01 command, we can attempt to connect to one of them.
After sending the connect command, the device will respond with “TRYING”, which will be followed by either “CONNECT failed” (the meaning of which should be pretty apparent) or the connection will be successful! After a successful connection we immediately enter data mode, and the modem becomes a pipeline. Any characters sent from one Bluetooth device will be sent to the other, and vice-versa. To disconnect, you’ll need to re-enter command mode (don’t forget to set to “No new line”), and send the “K,” command (with Newline selected, bleh).

There are a lot of other commands to explore! Thumb through the User’s Manual and familiarize yourself with all of the power at your Bluetooth modems’s fingertips!

Connecting From Another Device

In the example code section we attempted to connect to a device from the Bluetooth modem, but what if you wanted to initiate the connection from another Bluetooth device? This process varies by operating system and device, but most of the steps involved are pretty similar.
If your device (computer, phone, etc.) doesn’t already have an Bluetooth modem, you’ll need to connect an external module to it. The Bluetooth USB Module works for any computer with an available USB slot.

Connecting to the Modem in Windows

Go to the Control Panel and navigate to the Devices and Printers window. In the top-left section of that window, there should be an Add a device button. Click that.
Add a device window
When the Add a device window opens your computer’s Bluetooth module should automatically search for any in-range, available Bluetooth devices. Those it finds should show up in the window (give the window a few seconds to search).
If you see your device in this window, double-click it to initiate a connection. You’ll then be presented with the Select a pairing option window. Since the modems don’t have an attached keypad, select the Enter the device’s pairing code option.
Pairing options menu
On the next window, enter 1234 as the PIN code. This is the default PIN value for every RN-42 and RN-41.
Entering the PIN code
Windows will take a few moments to install drivers for your device. Once it’s done, it’ll pop up a notification to let you know that your device is ready to use!
But how do you actually use it? You’ll need to open up a terminal emulator (check out our Serial Terminal Basics tutorial for help!). When Windows installed drivers for your new Bluetooth device, it created a new COM port for it. Opening up your device manager, and looking in the “Ports (COM & LPT)” tree, you’ll find a new port named “Standard Serial over Bluetooth link (COM##)” (there may be two of them).
Device manager
To open up a connection between the Bluetooth devices, open up a terminal to that COM port at 9600 bps (8-N-1). (If you see two ports, try the lower number first). When the terminal opens up, your Bluetooth modem’s green connect LED should light up. Connection successful!
If you have the sketch from the last example (the serial passthrough) still loaded up on your Arduino, you can open up a second terminal window to communicate between devices.
Bluetooth communication example
If you’re within the config timer window (cycle power on the modem if you’re not), you can even remotely enter command mode by sending the “$$$” string. Now you can remotely alter the settings of your Bluetooth modem. Nifty!

If your using a Mac, Linux, or even a smartphone, pairing and connecting should involve a similar process. If authentication is required, you’ll want to use the PIN-code option, and enter the default PIN of “1234”. Open up a serial terminal emulator – Terminal or CoolTerm on Mac OSX, a variety of apps are available for smartphones – to initiate the connection and start passing data.

aRest API Mode 




The aREST framework was created to give RESTful interface to several embedded boards & platforms. In a nutshell, the library allows you to send commands to a given board running aREST, provoke an action (or just get some data), and send data back in a JSON container.

For example, to set the state of pin 6 to HIGH on an Arduino board running aREST, connected to your local network via Ethernet, and with the IP address 192.168.1.101, you would send the command:

192.168.1.101/digital/6/1
It’s that simple. As an answer, the board will then send:

{“message”: “Pin D6 set to 1?, “id”: “1”, “name”: “arduino”, “connected”: true}
This makes aREST really easy to use for your connected project. You don’t have to change the code on your embedded boards anymore: set it once, and then interact with your boards using a RESTful interface.

let's modify aRest to support SoftwareSerial

edit aREST.h and merge with following version
/* 
  aREST Library for Arduino
  See the README file for more details.
 
  Written in 2014 by Marco Schwartz under a GPL license. 
  Version 1.9.8
  Changelog:
  
  Version 1.9.8: Added support for ESP8266 chip
  Version 1.9.7: Added support for Arduino 1.6.2
  Version 1.9.6: Added support for float variables for Arduino Mega
  Version 1.9.5: Added compatibility with Arduino IDE 1.5.8
  Version 1.9.4: Bug fixes & added support for configuring analog pints as digital outputs
  Version 1.9.3: Added description of available variables for the /id and / routes
  Version 1.9.2: Added compatibility with the Arduino WiFi library
  Version 1.9.1: Added compatibility with CORS
  Version 1.9: New speedup of the library (answers 2x faster in HTTP compared to version 1.8)
  Version 1.8: Speedup of the library (answers 2.5x faster with the CC3000 WiFi chip)
  Version 1.7.5: Reduced memory footprint of the library
  Version 1.7.4: Added a function to read all analog & digital inputs at once
  Version 1.7.3: Added LIGHTWEIGHT mode to only send limited data back
  Version 1.7.2: Added possibility to assign a status pin connected to a LED
  Version 1.7.1: Added possibility to change number of exposed variables & functions
  Version 1.7: Added compatibility with the Arduino Due & Teensy 3.x
  Version 1.6: Added compatibility with the Arduino Yun
  
  Version 1.5: Size reduction, and added compatibility with Adafruit BLE
  
  Version 1.4: Added authentification with API key
  
  Version 1.3: Added support for the Ethernet shield
  
  Version 1.2: Added support of Serial communications
  
  Version 1.1: Added variables & functions support
  
  Version 1.0: First working version of the library
*/

#ifndef aRest_h
#define aRest_h

// Include Arduino header
#include "Arduino.h"


#include 

// Using ESP8266 ?
#if defined(ESP8266)
#include "stdlib_noniso.h"
#endif

// Which board?
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(CORE_WILDFIRE) || defined(ESP8266)
#define NUMBER_ANALOG_PINS 16
#define NUMBER_DIGITAL_PINS 54
#define OUTPUT_BUFFER_SIZE 2000
#elif defined(__AVR_ATmega328P__) && !defined(ADAFRUIT_CC3000_H)
#define NUMBER_ANALOG_PINS 6
#define NUMBER_DIGITAL_PINS 14
#define OUTPUT_BUFFER_SIZE 350
#elif defined(ADAFRUIT_CC3000_H)
#define NUMBER_ANALOG_PINS 6
#define NUMBER_DIGITAL_PINS 14
#define OUTPUT_BUFFER_SIZE 275  
#else
#define NUMBER_ANALOG_PINS 6
#define NUMBER_DIGITAL_PINS 14
#define OUTPUT_BUFFER_SIZE 350
#endif

// Size of name & ID
#define NAME_SIZE 20
#define ID_SIZE 10

// Debug mode
#ifndef DEBUG_MODE
#define DEBUG_MODE 0
#endif

// Use light answer mode
#ifndef LIGHTWEIGHT
#define LIGHTWEIGHT 0
#endif

// Default number of max. exposed variables
#ifndef NUMBER_VARIABLES
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(CORE_WILDFIRE) || defined(ESP8266)
  #define NUMBER_VARIABLES 10
  #else
  #define NUMBER_VARIABLES 5
  #endif
#endif

// Default number of max. exposed functions
#ifndef NUMBER_FUNCTIONS
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(CORE_WILDFIRE) || defined(ESP8266)
  #define NUMBER_FUNCTIONS 10
  #else
  #define NUMBER_FUNCTIONS 5
  #endif
#endif

class aREST {

public:

aREST() {
  
  command = 'u';
  pin_selected = false;
 
  status_led_pin = 255;
  state = 'u';

}

// Set status LED
void set_status_led(uint8_t pin){
  
  // Set variables
  status_led_pin = pin;
  
  // Set pin as output
  pinMode(status_led_pin,OUTPUT);
}

// Glow status LED
void glow_led() {

  if(status_led_pin != 255){
    unsigned long i = millis();
    int j = i % 4096;
    if (j > 2048) { j = 4096 - j;}
      analogWrite(status_led_pin,j/8);
    }
}

// Send HTTP headers for Ethernet & WiFi
void send_http_headers(){

  addToBuffer(F("HTTP/1.1 200 OK\r\nAccess-Control-Allow-Origin: *\r\nAccess-Control-Allow-Methods: POST, GET, PUT, OPTIONS\r\nContent-Type: application/json\r\nConnection: close\r\n\r\n"));
}

// Reset variables after a request
void reset_status() {
  answer = "";
  command = 'u';
  pin_selected = false;
  state = 'u';
  arguments = "";

  index = 0;
  //memset(&buffer[0], 0, sizeof(buffer));

}

// Handle request with the Adafruit CC3000 WiFi library
#ifdef ADAFRUIT_CC3000_H
void handle(Adafruit_CC3000_ClientRef& client) {
  
  if (client.available()) {

    // Handle request
    handle_proto(client,true,0);
        
    // Answer
    sendBuffer(client,32,20);
    client.stop();  

    // Reset variables for the next command
    reset_status();
  } 
}

// Handle request with the Arduino Yun
#elif defined(_YUN_CLIENT_H_) 
void handle(YunClient& client) {
  
  if (client.available()) {

    // Handle request
    handle_proto(client,false,0);
    
    // Answer
    sendBuffer(client,25,10);
    client.stop();
   
    // Reset variables for the next command
    reset_status();
  } 
}

// Handle request with the Adafruit BLE board
#elif defined(_ADAFRUIT_BLE_UART_H_)
void handle(Adafruit_BLE_UART& serial) {
  
  if (serial.available()) {

    // Handle request
    handle_proto(serial,false,0);
    
    // Answer
    sendBuffer(serial,100,1);

    // Reset variables for the next command
    reset_status();
  } 
}

// Handle request for the Arduino Ethernet shield
#elif defined(ethernet_h)
void handle(EthernetClient& client){

  if (client.available()) {

    // Handle request
    handle_proto(client,true,0);

    // Answer
    sendBuffer(client,50,0);
    client.stop();  
   
    // Reset variables for the next command
    reset_status();   
  }
}

// Handle request for the ESP8266 chip
#elif defined(ESP8266)
void handle(WiFiClient& client){

  if (client.available()) {

    if (DEBUG_MODE) {Serial.println("Request received");}

    // Handle request
    handle_proto(client,true,0);

    // Answer
    sendBuffer(client,0,0);
    client.stop();  
   
    // Reset variables for the next command
    reset_status();   
  }
}

// Handle request for the Arduino WiFi shield
#elif defined(WiFi_h)
void handle(WiFiClient& client){

  if (client.available()) {

    if (DEBUG_MODE) {Serial.println("Request received");}

    // Handle request
    handle_proto(client,true,0);

    // Answer
    sendBuffer(client,50,1);
    client.stop();  
   
    // Reset variables for the next command
    reset_status();   
  }
}

#elif defined(CORE_TEENSY)
// Handle request on the Serial port
void handle(usb_serial_class& serial){

  if (serial.available()) {

    // Handle request
    handle_proto(serial,false,1);

    // Answer
    sendBuffer(serial,25,1);

    // Reset variables for the next command
    reset_status();     
  }
}

#elif defined(__AVR_ATmega32U4__)
// Handle request on the Serial port
void handle(Serial_& serial){

  if (serial.available()) {

    // Handle request
    handle_proto(serial,false,1);

    // Answer
    sendBuffer(serial,25,1);

    // Reset variables for the next command
    reset_status();     
  }
}

#elif defined(__RN41__)

// Handle request on the SoftwareSerial port
void handle(SoftwareSerial & client){

  if (client.available()) {

    // Handle request
    handle_proto(client,false,1);

    // Answer
    sendBuffer(client,25,1);

    // Reset variables for the next command
    reset_status();     
  }
}
#else
// Handle request on the Serial port
void handle(HardwareSerial& serial){

  if (serial.available()) {

    // Handle request
    handle_proto(serial,false,1);

    // Answer
    sendBuffer(serial,25,1);

    // Reset variables for the next command
    reset_status();     
  }
}
#endif

void handle(char * string) {

  // Process String
  handle_proto(string);

  // Reset variables for the next command
  reset_status();     
}

void handle_proto(char * string) {
  // Check if there is data available to read
  for (int i = 0; i < strlen(string); i++){

    char c = string[i];
    answer = answer + c;

    // Process data
    process(c);
    
  }

  // Send command
  send_command(false);
}

template <typename T>
void handle_proto(T& serial, bool headers, uint8_t read_delay) 
{

  // Check if there is data available to read
  while (serial.available()) {
       
    // Get the server answer
    char c = serial.read();
    delay(read_delay);
    answer = answer + c;
    //if (DEBUG_MODE) {Serial.print(c);}

    // Process data
    process(c);
    
   }

   // Send command
   send_command(headers);  
}

void process(char c){

  // Check if we are receveing useful data and process it
  if ((c == '/' || c == '\r') && state == 'u') {

      if (DEBUG_MODE) {Serial.println(answer);}

      // If the command is mode, and the pin is already selected    
      if (command == 'm' && pin_selected && state == 'u') {
        
        // Get state
        state = answer[0];
            
     }
     
     // If a digital command has been received, process the data accordingly     
     if (command == 'd' && pin_selected && state == 'u') {
                
       // If it's a read command, read from the pin and send data back
       if (answer[0] == 'r') {state = 'r';}
       
       // If not, get value we want to apply to the pin        
       else {value = answer.toInt(); state = 'w';}
     }
     
     // If analog command has been selected, process the data accordingly     
     if (command == 'a' && pin_selected && state == 'u') {
                
       // If it's a read, read from the correct pin
       if (answer[0] == 'r') {state = 'r';}
       
       // Else, write analog value        
       else {value = answer.toInt(); state = 'w';}
     }
     
     // If the command is already selected, get the pin     
     if (command != 'u' && pin_selected == false) {
       
       // Get pin
       if (answer[0] == 'A') {
         pin = 14 + answer[1] - '0';  
       }
       else {
         pin = answer.toInt();
       }
       if (DEBUG_MODE) {
        Serial.print("Selected pin: ");
        Serial.println(pin);
       }
       pin_selected = true;

       // Nothing more ?
       if ((answer[1] != '/' && answer[2] != '/') 
        || (answer[1] == ' ' && answer[2] == '/')
        || (answer[2] == ' ' && answer[3] == '/')) {
     
        // Nothing more & digital ?
        if (command == 'd') {

          // Read all digital ?
          if (answer[0] == 'a') {state = 'a';}

          // Save state & end there
          else {state = 'r';}
        }

       // Nothing more & analog ?
       if (command == 'a') {

         // Read all analog ?
         if (answer[0] == 'a') {state = 'a';}
        
         // Save state & end there
         else {state = 'r';}
       }
     }  

   }
     
     // Digital command received ?    
     if (answer.startsWith("digital")) {command = 'd';}
          
     // Mode command received ?
     if (answer.startsWith("mode")) {command = 'm';}
          
     // Analog command received ?
     if (answer.startsWith("analog")) {command = 'a';}

     // Variable or function request received ?
     if (command == 'u') {
       
       // Check if variable name is in int array
       for (uint8_t i = 0; i < variables_index; i++){
         if(answer.startsWith(int_variables_names[i])) {
           
           // End here
           pin_selected = true;
           state = 'x';

           // Set state
           command = 'v';
           value = i;
         }
       }

       // Check if variable name is in float array (Mega & ESP8266 only)
       #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
       for (uint8_t i = 0; i < float_variables_index; i++){
         if(answer.startsWith(float_variables_names[i])) {
           
           // End here
           pin_selected = true;
           state = 'x';

           // Set state
           command = 'l';
           value = i;
         }
       }
       #endif

       // Check if variable name is in float array (Mega & ESP8266 only)
       #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
       for (uint8_t i = 0; i < string_variables_index; i++){
         if(answer.startsWith(string_variables_names[i])) {
           
           // End here
           pin_selected = true;
           state = 'x';

           // Set state
           command = 's';
           value = i;
         }
       }
       #endif

       // Check if function name is in array
       for (uint8_t i = 0; i < functions_index; i++){
         if(answer.startsWith(functions_names[i])) {
           
           // End here
           pin_selected = true;
           state = 'x';

           // Set state
           command = 'f';
           value = i;

           // Get command
           arguments = "";
           uint8_t header_length = strlen(functions_names[i]);
           if (answer.substring(header_length, header_length + 1) == "?") {
             uint8_t footer_start = answer.length();
             if (answer.endsWith(" HTTP/"))
               footer_start -= 6; // length of " HTTP/"
             arguments = answer.substring(header_length + 8, footer_start);
           }
         }
       }

       // If the command is "id", return device id, name and status
       if ( (answer[0] == 'i' && answer[1] == 'd') ){

           // Set state
           command = 'i';

           // End here
           pin_selected = true;
           state = 'x';
       }

       if (answer[0] == ' '){

           // Set state
           command = 'r';

           // End here
           pin_selected = true;
           state = 'x';
       }

       // Check the type of HTTP request
       // if (answer.startsWith("GET")) {method = "GET";}
       // if (answer.startsWith("POST")) {method = "POST";}
       // if (answer.startsWith("PUT")) {method = "PUT";}
       // if (answer.startsWith("DELETE")) {method = "DELETE";}
       
       // if (DEBUG_MODE && method != "") {
       //  Serial.print("Selected method: ");
       //  Serial.println(method);
       // }

     }

     answer = "";
    }
}

bool send_command(bool headers) {

   if (DEBUG_MODE) {
     Serial.println(F("Sending command"));
     Serial.print(F("Command: "));
     Serial.println(command);
     Serial.print(F("State: "));
     Serial.println(state);
     Serial.print(F("State of buffer at the start: "));
     Serial.println(buffer);
   }

   // Start of message
   if (headers && command != 'r') {send_http_headers();}

   // Mode selected
   if (command == 'm'){

     // Send feedback to client 
     if (!LIGHTWEIGHT){
       addToBuffer(F("{\"message\": \"Pin D"));
       addToBuffer(pin); 
     } 
     
     // Input
     if (state == 'i'){
      
      // Set pin to Input     
      pinMode(pin,INPUT);
          
      // Send feedback to client
      if (!LIGHTWEIGHT){addToBuffer(F(" set to input\", "));}
     }

     // Output
     if (state == 'o'){

       // Set to Output  
       pinMode(pin,OUTPUT);
          
       // Send feedback to client
       if (!LIGHTWEIGHT){addToBuffer(F(" set to output\", "));}
     }

   }

   // Digital selected
   if (command == 'd') {
     if (state == 'r'){

       // Read from pin
       value = digitalRead(pin);

       // Send answer
       if (LIGHTWEIGHT){addToBuffer(value);}
       else {
        addToBuffer(F("{\"return_value\": "));
        addToBuffer(value);
        addToBuffer(F(", "));
      }
     }
     
     #if !defined(__AVR_ATmega32U4__) || !defined(ADAFRUIT_CC3000_H)
     if (state == 'a') {
       if (!LIGHTWEIGHT) {addToBuffer(F("{"));}
       
       for (uint8_t i = 0; i < NUMBER_DIGITAL_PINS; i++) {       
         
         // Read analog value
         value = digitalRead(i);
      
         // Send feedback to client
         if (LIGHTWEIGHT){
           addToBuffer(value);
           addToBuffer(F(","));
         }
         else {
           addToBuffer(F("\"D"));
           addToBuffer(i);
           addToBuffer(F("\": "));
           addToBuffer(value);
           addToBuffer(F(", "));
         } 
     }
    }
    #endif

     if (state == 'w') {

       // Apply on the pin      
       digitalWrite(pin,value);

       // Send feedback to client
       if (!LIGHTWEIGHT){
        addToBuffer(F("{\"message\": \"Pin D"));
        addToBuffer(pin);
        addToBuffer(F(" set to "));
        addToBuffer(value);
        addToBuffer(F("\", "));
       }
     }
   }

   // Analog selected
   if (command == 'a') {
     if (state == 'r'){
       
       // Read analog value
       value = analogRead(pin);
      
       // Send feedback to client
       if (LIGHTWEIGHT){addToBuffer(value);}
       else {
        addToBuffer(F("{\"return_value\": "));
        addToBuffer(value);
        addToBuffer(F(", "));
       }
     }
     #if !defined(__AVR_ATmega32U4__)
     if (state == 'a') {
       if (!LIGHTWEIGHT) {addToBuffer(F("{"));}
       
       for (uint8_t i = 0; i < NUMBER_ANALOG_PINS; i++) {       
         
         // Read analog value
         value = analogRead(i);
      
         // Send feedback to client
         if (LIGHTWEIGHT){
           addToBuffer(value);
           addToBuffer(F(","));
         }
         else {
           addToBuffer(F("\"A"));
           addToBuffer(i);
           addToBuffer(F("\": "));
           addToBuffer(value);
           addToBuffer(F(", "));
         } 
     }
   }
   #endif
   if (state == 'w') {

     // Write output value
     analogWrite(pin,value);

     // Send feedback to client
     addToBuffer(F("{\"message\": \"Pin D"));
     addToBuffer(pin);
     addToBuffer(F(" set to "));
     addToBuffer(value);
     addToBuffer(F("\", "));

   }
  }

  // Variable selected
  if (command == 'v') {          

       // Send feedback to client
       if (LIGHTWEIGHT){addToBuffer(*int_variables[value]);}
       else {
        addToBuffer(F("{\""));
        addToBuffer(int_variables_names[value]);
        addToBuffer(F("\": "));
        addToBuffer(*int_variables[value]);
        addToBuffer(F(", ")); 
       }
  }

  // Float ariable selected (Mega only)
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
  if (command == 'l') {          

       // Send feedback to client
       if (LIGHTWEIGHT){addToBuffer(*float_variables[value]);}
       else {
        addToBuffer(F("{\""));
        addToBuffer(float_variables_names[value]);
        addToBuffer(F("\": "));
        addToBuffer(*float_variables[value]);
        addToBuffer(F(", ")); 
       }
  }
  #endif

  // String variable selected (Mega & ESP8266 only)
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
  if (command == 's') {          

       // Send feedback to client
       if (LIGHTWEIGHT){addToBuffer(*string_variables[value]);}
       else {
        addToBuffer(F("{\""));
        addToBuffer(string_variables_names[value]);
        addToBuffer(F("\": \""));
        addToBuffer(*string_variables[value]);
        addToBuffer(F("\", ")); 
       }
  }
  #endif

  // Function selected
  if (command == 'f') {

    // Execute function
    uint8_t result = functions[value](arguments);

    // Send feedback to client
    if (!LIGHTWEIGHT) {
     addToBuffer(F("{\"return_value\": "));
     addToBuffer(result);
     addToBuffer(F(", "));
     //addToBuffer(F(", \"message\": \""));
     //addToBuffer(functions_names[value]);
     //addToBuffer(F(" executed\", "));
    }
  }

  if (command == 'r') {
    root_answer();
  }

  if (command == 'i') {
    if (LIGHTWEIGHT) {addToBuffer(id);}
    else {
      addToBuffer(F("{"));
    }
  }

   // End of message
   if (LIGHTWEIGHT){
     addToBuffer(F("\r\n"));
   }

   else {

     if (command != 'r') {
      addToBuffer(F("\"id\": \""));
       addToBuffer(id);
       addToBuffer(F("\", \"name\": \""));
       addToBuffer(name);
       addToBuffer(F("\", \"connected\": true}\r\n"));
     }
   }

   if (DEBUG_MODE) {
     Serial.print(F("State of buffer at the end: "));
     Serial.println(buffer);
   }
   
   // End here
   return true;
}

virtual void root_answer() {
  if (LIGHTWEIGHT) {addToBuffer(id);}
    else {
      addToBuffer(F("{\"variables\": {"));

      // Int variables
      if (variables_index > 0){
        
        for (uint8_t i = 0; i < variables_index-1; i++){
          addToBuffer(F("\""));
          addToBuffer(int_variables_names[i]);
          addToBuffer(F("\": "));
          addToBuffer(*int_variables[i]);
          addToBuffer(F(", "));
        }
        addToBuffer(F("\""));
        addToBuffer(int_variables_names[variables_index-1]);
        addToBuffer(F("\": "));
        addToBuffer(*int_variables[variables_index-1]);
        addToBuffer(F("}, "));
      }
      else {
        addToBuffer(F(" }, "));
      }
      
    }
}

void variable(char * variable_name, int *variable){

  int_variables[variables_index] = variable;
  int_variables_names[variables_index] = variable_name;
  variables_index++;

}

// Float variables (Mega & ESP only)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
void variable(char * variable_name, float *variable){

  float_variables[float_variables_index] = variable;
  float_variables_names[float_variables_index] = variable_name;
  float_variables_index++;

}
#endif

// String variables (Mega & ESP only)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
void variable(char * variable_name, String *variable){

  string_variables[string_variables_index] = variable;
  string_variables_names[string_variables_index] = variable_name;
  string_variables_index++;

}
#endif

void function(char * function_name, int (*f)(String)){

  functions_names[functions_index] = function_name;
  functions[functions_index] = f;
  functions_index++;
}

// Set device ID
void set_id(char *device_id){

  strcpy(id,device_id);
}

// Set device name
void set_name(char *device_name){
  
  strcpy(name, device_name);
}

// Set device name
void set_name(String device_name){

  device_name.toCharArray(name, NAME_SIZE);
}

// Set device ID
void set_id(String device_id){

  device_id.toCharArray(id, NAME_SIZE);
}

// Add to output buffer
void addToBuffer(char * toAdd){

  if (DEBUG_MODE) {
    Serial.print(F("Added to buffer: "));
    Serial.println(toAdd);
  }
  
  for (int i = 0; i < strlen(toAdd); i++){
    buffer[index+i] = toAdd[i];  
  }
  index = index + strlen(toAdd);
}

// Add to output buffer
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
void addToBuffer(String toAdd){

  if (DEBUG_MODE) {
    Serial.print(F("Added to buffer: "));
    Serial.println(toAdd);
  }
  
  for (int i = 0; i < toAdd.length(); i++){
    buffer[index+i] = toAdd[i];  
  }
  index = index + toAdd.length();
}
#endif

// Add to output buffer
void addToBuffer(uint16_t toAdd){

  char number[10];
  itoa(toAdd,number,10);
  
  addToBuffer(number);
}

// Add to output buffer
void addToBuffer(int toAdd){

  char number[10];
  itoa(toAdd,number,10);
  
  addToBuffer(number);
}

// Add to output buffer (Mega & ESP only)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
void addToBuffer(float toAdd){

  char number[10];
  dtostrf(toAdd, 5, 2, number);
  
  addToBuffer(number);
}
#endif

// Add to output buffer
void addToBuffer(const __FlashStringHelper *toAdd){

  // if (DEBUG_MODE) {
  //   Serial.print(F("Added to buffer: "));
  //   Serial.println(toAdd);
  // }

  uint8_t idx = 0;

  PGM_P p = reinterpret_cast<PGM_P>(toAdd);

  while (1) {
    unsigned char c = pgm_read_byte(p++);
    if (c == 0) break;
    buffer[index + idx] = c;
    idx++;
  }
  index = index + idx;
}

template <typename T>
void sendBuffer(T& client, uint8_t chunkSize, uint8_t wait_time) {

  if (DEBUG_MODE) {
    Serial.print(F("Buffer size: "));
    Serial.println(index);
  }  

  // Send all of it
  if (chunkSize == 0) {
    client.print(buffer);
  }

  // Send chunk by chunk
  else {
    
    // Max iteration
    uint8_t max_iteration = (int)(index/chunkSize) + 1;

    // Send data
    for (uint8_t i = 0; i < max_iteration; i++) {
      char intermediate_buffer[chunkSize+1];
      memcpy(intermediate_buffer, buffer + i*chunkSize, chunkSize);
      intermediate_buffer[chunkSize] = '\0';

      // Send intermediate buffer
      #ifdef ADAFRUIT_CC3000_H
      client.fastrprint(intermediate_buffer);
      #else
      client.print(intermediate_buffer);
      #endif

      // Wait for client to get data
      delay(wait_time);

      if (DEBUG_MODE) {
        Serial.print(F("Sent buffer: "));
        Serial.println(intermediate_buffer);
      }
    }
  }
    
    // Reset the buffer
    resetBuffer();
}

char * getBuffer() {
  return buffer;
}

void resetBuffer(){
  memset(&buffer[0], 0, sizeof(buffer));
}


private:
  String answer;
  char command;
  uint8_t pin;
  char state;
  uint16_t value;
  boolean pin_selected;

  //char * method;

  char name[NAME_SIZE];
  char id[ID_SIZE];
  String arguments;

  // Output uffer
  char buffer[OUTPUT_BUFFER_SIZE];
  uint16_t index;

  // Status LED
  uint8_t status_led_pin;

  // Int variables arrays
  uint8_t variables_index;
  int * int_variables[NUMBER_VARIABLES];
  char * int_variables_names[NUMBER_VARIABLES];

  // Float variables arrays (Mega & ESP8266 only)
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
  uint8_t float_variables_index;
  float * float_variables[NUMBER_VARIABLES];
  char * float_variables_names[NUMBER_VARIABLES];
  #endif

  // String variables arrays (Mega & ESP8266 only)
  #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ESP8266) || defined(CORE_WILDFIRE)
  uint8_t string_variables_index;
  String * string_variables[NUMBER_VARIABLES];
  char * string_variables_names[NUMBER_VARIABLES];
  #endif

  // Functions array
  uint8_t functions_index;
  int (*functions[NUMBER_FUNCTIONS])(String);
  char * functions_names[NUMBER_FUNCTIONS];

};

#endif

/*
  Example Bluetooth Serial aRest Sketch
 by: Thomas Younsi
 date: August 7, 2015
 license: Public domain

 This example sketch converts an RN-42 bluetooth module to
 communicate at 9600 bps (from 115200), and Handle REST calls 
 send over bluetooth.
 */
#define __RN41__ 1

#include <SoftwareSerial.h> 
// Create aREST instance
aREST rest = aREST();
// Variables to be exposed to the API
int temperature;
int humidity;
int led = 13;


#include  
int bluetoothTx = 2;  // TX-O pin of bluetooth mate, Arduino D2
int bluetoothRx = 3;  // RX-I pin of bluetooth mate, Arduino D3

SoftwareSerial bluetooth(bluetoothTx, bluetoothRx);

void setup()
{
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);

  // Start Serial
#ifdef BRIDGE
  Serial.begin(9600);  // Begin the serial monitor at 9600bps
#else
  Serial.begin(115200);
#endif

  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

  // Init variables and expose them to REST API
  temperature = 24;
  humidity = 40;
  rest.variable("temperature",&temperature);
  rest.variable("humidity",&humidity);
  // Function to be exposed
  rest.function("led",ledControl);
  // Give name and ID to device
  rest.set_id("008");
  rest.set_name("ble_drake");
}

void loop()
{
  if(bluetooth.available())  // If the bluetooth sent any characters
  {
    // Handle REST calls send over bluetooth
    rest.handle(bluetooth);

    // Send any characters the bluetooth prints to the serial monitor
    //Serial.print((char)bluetooth.read());
  }
#ifdef BRIDGE
  if(Serial.available())  // If stuff was typed in the serial monitor
  {
    // Send any characters the Serial monitor prints to the bluetooth
    bluetooth.print((char)Serial.read());
  }
#endif
  // and loop forever and ever!
}


// Custom function accessible by the REST API
int ledControl(String command) 
{
  // Get state from command
  int state = command.toInt();

  digitalWrite(led,state);
  return 1;
}

Android Client TODO


iOS Client TODO


Resources and Going Further

Hopefully this tutorial has prepared you for an exciting foray into the world of wireless communication. Now that you have a good idea of how to command these Bluetooth modems, and connect them to other devices, the rest is up to you. How are you going to make use of your pleasant lack of wire? Go hit the airwaves!

Resources