Using the AT-09 BLE module with the Arduino

This article shows how to get a rookie (like me 😀) started with using the AT-09 with an Arduino.

The AT-09 module

Introduction

The AT-09 is a module that contains a BLE chip (a CC2540/CC2541). This module allows to perform serial communication with the BLE chip thanks to an Rx and a Tx pin. This module is also very similar to the HM-10 module and is also compatible with it. So if you have some experience with the latter, you will get started quickly with the AT-09.

Rear view of the AT-09 module

Let’s start by turning on the module.

Connecting the Arduino with the module

Let’s start by connecting the Arduino with the AT09 module in order to turn it on. To achieve that, we only need these two pins

AT-09 GND <-> Any Arduino GND Pin

AT-09 VCC <-> Any Arduino 5V Pin or 3.3V Pin

Turn on you Arduino, you should see the AT-09 led blink.

If you have a BLE smartphone, you can also open a BLE scanning app to scan for the AT-09. In my case, I used BlueCap on iPhone. The module was detected as device named ?. You can have a different result.

? is our AT-09

If you do not happen to detect the module in this step, it may be simply a problem with the configuration of the module. So keep reading to learn how to configure it.

In the next section, we will see how we can send commands to the module with the Arduino.

Sending our first command from the Arduino to the module

To allow the Arduino to communicate with the AT-09 BLE module, we use the serial interface (the TXD and RXD pins). Hopefully, Arduino allows to turn any pair of digital pins into a serial interface using the SoftwareSerial library.

After establishing the serial connection, We can start transmitting data to the AT-09 module. The module understands certain data as commands. These commands are the HM-10 AT commands. We will see some examples in this article. Additionally, you can download the reference here https://github.com/yostane/arduino-at-09/blob/master/hm-10-datasheet.pdf or by searching the internet.

Thus, in order to send command to the module we need to:

  • Connect the TXD and RXD pins of the module to any pair of Arduino pins other than 1 and 2.
  • Ask the Arduino to convert that pair of pins into a serial interface.
  • Send AT commands to the module and receive their responses.

Let’s connect the TXD and RXD pins with the Arduino like this:

AT-09 RXD <-> Arduino PIN 3

AT-09 TXD <-> Arduino PIN 2

Connecting the AT-09 with the Arduino

Of course, you can connect the RXD and TXD pins to any Arduino digital Pin (other than 0 and 1).

Next, we declare the serial interface like this: SoftwareSerial mySerial(2, 3). This means that the arduino will use pin2 will be used for reception and pin 3 for transmission.

After that, we can begin the serial communication by calling mySerial.begin(9600) and send the first command mySerial.println(“AT”).

The AT command allows to verify that we are correctly connected and return “OK” in that case. It acts like a ping command.

In order to display the response in the Arduino serial monitor, we do this little while loop:

After running this loop, you should see an “OK” appear on the serial monitor.

We have an OK Huston !

The difficulty here is distinguishing between the Serial object and the mySerial object. The first one is the serial interface between the Arduino and the PC (thourgh USB and pin 0 and 1) while the latter is the serial interface between the Arduino and AT-09.

PC_USB ←(Serial)→ USB_Arduino_PINS 2, 3 ←(mySerial)→ TDX, RXD_AT-09

If we add the bluetooth central, we get this outline:

PC_USB ←(Serial)→ USB_Arduino_PINS 2, 3 ←(mySerial)→ TDX, RXD_AT-09_BLE chip (CC254x) ← Characteristic → BLE central

The full sketch is available here: https://github.com/yostane/arduino-at-09/blob/master/at09/at09.ino

Congratulations, we sent our first command to the AT-09 module through the Arduino. In the next section, we will configure the module as a BLE peripheral using commands.

Configuring the AT-09 as a BLE peripheral

Let’s tackle more AT commands. The goal of this section is to call the commands that allow to:

  • Set the module as peripheral
  • Set the service UUID
  • Set the characteristic UUID
  • Set a nice name to the peripheral

An important detail to note here is that the AT-09 allows only one service that contains only one characteristic when it is configured as a peripheral.

The HM-10 datasheet contains a section that lists AT commands. After some research, we find the commands that we are going to use:

  • Set the module as peripheral if not set yet: AT+ROLE0 where 0 is for peripheral and 1 is for central.
  • Set the service UUID: AT+UUIDuuid where uuid is the UUID of the service. It ranges from 0x0001~0xFFFE and defaults to 0xFFE0
  • Set the characteristic UUID: AT+CHARuuid where uuid is the UUID of the characteristic. It ranges from 0x0001~0xFFFE and defaults to 0xFFE1
  • Set a nice name to the peripheral: AT+NAMEnew_name where new_name is the new name that we want to set

Suppose we want this configuration

  • Role: peripheral
  • Name: bluino
  • Service UUID: 0xFFE0
  • Characteristic UUID: 0xFFE1

By consolidating all this information, we conclude to these commands:

  • AT+ROLE0
  • AT+UUID0xFFE0
  • AT+CHAR0xFFE1
  • AT+NAMEbluino

On the Arduino sketch, we will send these commands during the setup() step since we will do it once when the board it boots up. In order to send them easily, let’s define a function. It will take the command as a parameter, sends it, and displays its result.

Note that I force a delay between sending a command and reading its reply. I did it because I noted in my tests that there is a lag between these two steps. So, better keep the delay :).

Here is the code of the setup() function:

When you run the sketch, you should see the following output on the serial monitor:

Configuration output

On the iOS side, the name of peripheral gets updated. I used LightBlue on iOS to perform the verification.

The name of the peripheral was changed after the configuration step

We can also verify the UUIDs of the services and characteristics.

The UUIDs of the service and the characteristic

The full sketch is available here: https://github.com/yostane/arduino-at-09/blob/master/at-09-conf-periph/at-09-conf-periph.ino

We are making good progress. The next step consists in reading and writing data on the characteristic using the Arduino. The next section first focuses on reading the data available in that characteristic.

Reading the data on the AT-09’s characteristic

After configuring the AT-09 module as a peripheral, our Arduino can easily read the data sent to its characteristic by reading TXD pin. Any connected central can inject data into the characteristic. The communication looks like this:

Central_BLE chip — (BLE) → BLE chip(CC2541)_AT-09_ TXD — (mySerial) → Pin 2_Arduino

Please note that the only available characteristic can store up to 20 bytes of random data.

Here is a function that puts the characteristic data into a buffer and then writes it to the serial monitor:

The loop() function does simply a call to the readSerial() function.

I use LightBlue on iOS to write data to the characteristic. Note that the AT-09 led will remain red when a central is connected. The video below illustrates what we have done.

he full sketch is available here: https://github.com/yostane/arduino-at-09/blob/master/at-09-read-periph/at-09-read-periph.ino

Next, we will see how to write data to the characteristic on the Arduino side and how to receive on the central side.

Writing data on the AT-09 characteristic

You can now guess how to write data to the module. The answer is of course, by using mySerial.write(). The communication can be illustrated like this:

Pin 2_Arduino — (mySerial) → RXD_AT-09_BLE chip(CC2541) — BLE notification → Central BLE Chip

Just remember that the characteristic is limited to 20 characters.

Here is a helper function for writing a char to the characteristic:

The loop() method will print a value that gets incremented after each write.

This sketch will write these values one by one: 1, 2, 3, 4, 5, etc.

After each write, the AT-09 module will update the characteristic and also send a notification. On our central app, we will receive notifications following this order: 1, 2, 3, 4, 5, etc.

In this video, I use LightBlue to subscribe and receive the notifications.

The full sketch is available here: https://github.com/yostane/arduino-at-09/blob/master/at-09-notif-periph/at-09-notif-periph.ino

Let’s finish this article with a small cool temperature application :).

Application; sending temperature to the smartphone through BLE

For this section, we will need a temperature sensor. I am using the LM35 sensor here.

We will connect the sensor to the Arduino following this article:

After establishing the connections, we will need to read the temperature from the analogue pin. Here is a helper function that allows to read the temperature in Celsius.

Since the result is a float, I decided to convert it to a string before sending it to the AT09 module. This is possible thanks to the dtostrf function. Its synopsis is dtostrf(float, minimum width, precision, character array). When the conversion is done, we just need to send the string to the serial port of the AT09 module.

Our writeToBLE function now sends a string to the AT-09:

Our sketch is now completed. This video illustrates the iPhone receiving the notification in real time.

Unfortunately, I couldn’t get my temperature sensor to work correctly. But you get the idea :)

The full sketch is available here: https://github.com/yostane/arduino-at-09/blob/master/at-09-temp/at-09-temp.ino

It is time to conclude now.

Conclusion:

This article guided you through the necessary steps to connect, configure, and communicate with the AT09 BLE module. We finally made a small temperature application that sends up to date temperature data through BLE.

The sketches are available on github: https://github.com/yostane/arduino-at-09

Happy coding :)

References: