BLE with Bluno Beetle

Some time ago my friend Mauro Alfieri showed me an interesting development board produced by DFRobot and called Bluno Beetle (now Beetle Ble). It seemed the perfect board to start “playing” with the Bluetooth Low Energy (BLE) technology; therefore I ordered  one board directly from the DFRobot store.

I expected to receive the usual anonymous parcel with the board inside an antistatic plastic bag; DFRobot instead sends its products in an elegant cardboard box, protecting them with foam:

bluno-011 bluno-012

Bluno Beetle is really small and therefore perfect for wearable projects:

bluno-013 bluno-014

But what is it? Simplifying is a board, Arduino Uno compatible (it hosts the ATmega328P microcontroller) to which has been added the CC2540 chip from Texas Instruments to act as USB and BLE controller. The two chips communicate via a serial interface:

bluno-001

The CC2540 chip is actually a real microcontroller that runs a firmware developed by DFRobot. This firmware can be configured using AT commands. Normally the firmware runs in transparent mode, that is it acts as a “bridge” between the USB/BLE interfaces and the ATmega microcontroller. If you then connect the Bluno to your PC and activate the serial monitor, each character you type is forwarded to the ATmega and viceversa.

To send AT commands, first you have to enter the AT mode of the firmware, sending the + character 3 times (without appending a line ending). The firmware confirms the new mode with the sentence “Enter AT Mode”:

bluno-006

Now you can send the commands, appending the Windows line terminator (CRLF). For example to display the firmware version:

bluno-007

To exit the AT mode and go back to transparent mode, you have to send the AT+EXIT command.

Drivers

It may happen that – if it’s the first time you connect the Bluno Beetle to your Windows PC – it is not correctly recognized:

bluno-003

The correct drivers are shipped with the Arduino IDE. You only need to do a manual installation specifying the path where you installed the IDE:

bluno-004

Windows will identify the new device as an Arduino Uno:

bluno-005

Arduino

As explained above, if the firmware running on the CC2540 chip is in transparent mode, using the USB connection you can talk directly to the ATmega328P microcontroller. This means that you can program the microcontroller using the Arduino IDE without any problems… just choose Arduino Uno as board and select the correct serial port:

bluno-008

BLE and transparent mode

In transparent mode Bluno transmits via BLE each byte it receives from Arduino (the ATmega microcontroller) and – viceversa – it sends to Arduino each byte it receives from BLE.

In this first post let’s explore the demo application DFRobot provides; in a future post I’ll explain how to develop your application to interact with Bluno Beetle via BLE.

If you have an Android smartphone, you can directly install the apk file for the application named BlunoBasicDemo (application of which the source code is also available). In the same Github repository you can also find the source code of the iOS application, you have to compile by yourself.

Compile and upload the following sketch on the board:

unsigned long previous_time = 0;
 
void setup() {
  Serial.begin(115200);
}
 
void loop() {
 
  if (Serial.available() > 0) {
    int incomingByte = Serial.read();
    Serial.print("New byte received: 0x");
    Serial.println(incomingByte, HEX);
  }
  unsigned long actual_time = millis();
  if(actual_time - previous_time > 10000) {
    Serial.println("Hello world!");
    previous_time = actual_time;
  }
}

The sketch reads the incoming bytes (coming from the app) and sends back to the app their hexadecimal value. Every 10 seconds moreover the sketch sends to the app the text Hello world!.

Launch the app. After having clicked on the Scan button, you can choose your Bluno board from the list of detected devices:

bluno-009

Every 10 seconds you should see a new HelloWorld! string appear. You can try to send a character (for example the letter “a”); you’ll receive an answer from Arduino (0x61 is indeed the hex code – in the ASCII table – for the letter “a”):

bluno-010

HID mode

Bluno also supports the HID (Human Interface Device) mode. When running in this mode, Bluno simulates an input peripheral (keyboard, mouse…) connected via BLE.

The AT command that enables this mode is:

  • AT+FSM=FSM_HID_USB_COM_BLE_AT

After having enabled the HID mode, you can send one or more “keys” with:

  • AT+KEY=

you can send up to 3 different keys at a time, concatenating their codes with the + character. The codes to be used, according to the type (page) of the HID device, are listed in the USB specification.

The AT+KEY command notifies the pressure of a key on the keyboard.  It is therefore necessary, after a few moments, to send the AT+KEY=0 command to indicate that the key has been released; otherwise on the PC associated with Bluno you’ll see the character appear repeatedly!

Debug mode

Using two different AT commands you can enable the debug mode of the firmware. This mode allows to receive – via the USB connection – a copy of all the data sent and received through the BLE connection.

The two commands are:

  • AT+BLUNODEBUG=ON (copies the messages sent by the ATmega)
  • AT+USBDEBUG=ON (copies the messages received from BLE)

bluno-002

By default the first debug mode is active, while the second is disabled. You can verify it if you upload the sketch listed above: in the serial monitor you’ll see the Hello World! sentences but not the characters sent by the app.

TWANG, an Arduino-based dungeon crawler

20180111_130909-1-600

Bdring built his own Arduino-based 1D dungeon crawler inspired by Robin Baumgarten’s  Line Wobbler:

I have been a Patron of Robin Baumgarten for a while. He makes experimental hardware for games. His Line Wobbler one dimensional dungeon crawler is my favorite and I have always wanted to play it. It uses a door stop spring as the controller. An accelerometer in the knob allows it to work like a joystick and also detect the wobble used to attack the enemies.

More details at Buildlog.net blog.

Yield function, printable class and mapping arrays: Useful but unknown features from Arduino core

test-printable-arduino-1

Yahya Tawil over at Atadiat wrote a new tip for Arduino developers about three hidden and useful features in Arduino core:

Arduino core, the source code of Arduino API functions and classes, has three useful features that can be used effectively. As the Arduino core documentation doesn’t mention them (at least until the time of publishing this micro-blog), these features are not well-known for arduino developers. Let’s discuss each feature of them one by one.

More details at Atadiat blog.

Via the contact form.

 

Arduino Tutorial: Adding sensors to your data logger

Float configuration deploymnet on new housings

Edward Mallon writes:

This post isn’t another How-To tutorial for a specific sensor because the Arduino community has already produced a considerable number of resources like that.  You’d be hard pressed to find any sensor in the DIY market that doesn’t give you a dozen cookbook recipes to follow after a simple Google search. In fact, you get so many results from “How to use SensorX with Arduino” that beginners are overwhelmed because few of those tutorials help people decide which type of sensor suits their skill level. This post attempts to put the range of different options you can use with a Cave Pearl data logger into a conceptual framework, with links to examples that illustrate the ideas in text.

More details at thecavepearlproject.org.

Arduino controlled Dual Mono AK4490 DAC (part 2)

STM32_MB_1-Small

An update on Arduino controlled Dual Mono AK4490 DAC project we covered previously:

After I was certain that everything related to the software was working the way it should, I designed a “motherboard” that would take care of the following:

  • Accept the STM32F106 board
  • Accept the 3.5″ TFT
  • Accommodate an 24LC256 EEPROM chip, used to store the DAC’s configurable settings
  • Accommodate two sets of I2C signal isolators and I/O expanders
  • Include headers for the encoder, IR receiver, power relay, non-isolated and isolated I2C communication, unused uC pins, etc

See the full post here, Dimdim’s blog.

Weather logger with Losant and Amazon Alexa

losant

Steve documented his experience experimenting with home weather logging:

Like a million other people on the Internet, I’ve been experimenting with home weather logging. I roll my eyes at the phrase “Internet of Things”, but it’s hard to deny the potential of cheap networked sensors and switches, and a weather logging system is like this field’s Hello World application. Back in June I posted about my initial experiments in ESP8266 weather logging. Since then I’ve finalized the hardware setup, installed multiple nodes around the house, organized a nice web page to analyze all the data, and integrated everything with Amazon Alexa. Time for an update.

More details at Big Mess o’ Wires homepage.

Check out the video after the break.

DCC, led accessory decoder

After having designed a shield to interface Arduino with a DCC bus, today I’ll show you how to realize a simple accessory decoder to control a couple of leds.

dccled-101 dccled-100

Accessory decoder

The DCC standard (specifically the document S-9.2.1 DCC Extended Packet Formats) defines different types of decoders, which are devices – connected to the DCC bus – that perform actions based on the command they receive.

An accessory decoder is “intended for control of a number of simple functions such as switch machine control or turning on and off lights“.

dcc2servo2relay

a DIY decoder by Paco

Addressing

Each decoder is assigned one or more addresses. The document S-9.2.1 linked above explains in details the format of a DCC packet sent to an accessory decoder (basic accessory decoder packet format):

dcc-001

9 bits of the packet (AAAAAAAAA) defines the address of the decoder. The address’ most significative bits (MSB) are the ones in the second bytes, while the least significative bits (LSB) are the ones in the first byte. To make things more complicated, the bits in the second byte are in ones’ complement representation.

Let’s understand it with an example:

dcc-003a

Most significative bits are 011. If you ones’ complement them, they become 100.

Least significative bits are 0010011. When you concatenate the two parts, you get 1000010011, therefore the decoder’s address is 267.

2 bit (PP) represents the address of a single port of the decoder. Conventionally, an accessory decoder has 4 ports, each one with a couple of outputs.

Bit O chooses, for the port represented by the PP bits, the output the command is related to. Finally, bit C is the action and defines if that output must be activated (1) or disactivated (0).

dcc-002

Some manufacturers prefert to use a “flat” addressing (not distinguishing between decoder address, port number and output). A good explaination about the different addressing methods (MADAPADA…) is available on the Rocrail wiki.

Arduino

Before developing the sketch for your accessory decoder, you have to install – using the Library Manager – the NmraDcc library in your Arduino IDE:

dcc-acc-001

Then include it in your sketch and create an instance of the NmraDcc object:

#include "NmraDcc.h"
NmraDcc Dcc;

In the setup() you have to configure and initialize the library. First, call the pin() method to tell the library which Arduino pin the DCC signal is connected to (ExtIntPinNum) and the corresponding interrupt number (ExtIntNum). In addition, you can enable or not the internal pullup resistor:

void pin(uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup);

The list of suitable pins for each Arduino board is available in the wiki and you can use the digitalPinToInterrupt() method to get the interrupt number that correspond to each pin.

If you’re using the shield I designed with an Arduino Uno, you can choose pin 2 with the pullup resistor enabled:

#define DCC_PIN 2
[...]
Dcc.pin(digitalPinToInterrupt(DCC_PIN), DCC_PIN, 1);

Let’s now configure the library, with the method:

void init(uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, 
  uint8_t OpsModeAddressBaseCV);

The first two parameters are the manufacturer code and the decoder version; the DCC command station can get those values reading the corresponding CVs (configuration variables). For self-made decoders, the ManufacturedId is set to MAN_ID_DIY.

With the third parameter you can set, in OR, some flags:

dcc-acc-002

For accessory decoder, you have to specify at least the third flag (DCC_ACCESSORY_DECODER).

FLAG_MY_ADDRESS_ONLY

The first flag tells the library to filter the DCC messages it receives and to process only the ones sent to the decoder address. I usually do not set that flag, because I want my sketch to be able to “see” each incoming message. In my code I then decide which messages to process and which not.

When the library is correctly configured, in the loop() you have to call as frequently as possible the process() method to let the library handle the incoming messages:

void loop() {
  Dcc.process();
}

When the library receives a message for an accessory decoder, it can execute different callback functions, depending on what you defined in your sketch:

  • notifyDccAccState()
  • notifyDccAccTurnoutBoard()
  • notifyDccAccTurnoutOutput()
  • notifyDccSigState()

The first 3 methods are called for basic accessory decoder packets, while the last for extended accessory decoder control packets.

For my led decoder, I decided to implement the notifyDccAccState() method:

void notifyDccAccState(uint16_t Addr, uint16_t BoardAddr, 
  uint8_t OutputAddr, uint8_t State)

The method provides some variables. Let’s see their meaning (remember what you learned in the first part of this article about addressing):

  • BoardAddr is the decoder address (9 bits)
  • OutputAddr contains the 3 bits PP and O, that are the address for the port and the output
  • State is the action (1 = activate, 0 = deactivate)
  • Addr is the direct port address (PADA mode)

You can divide the port address (2 bits) from the output address (1 bit) with:

int portAddress = (OutputAddr >> 1) + 1;
int outAddress = OutputAddr & 0x01;

In the code I added 1 to the port address to be able to number the ports from 1 to 4 instead of from 0 to 3.

To keep it simple, the decoder developed for this article has hardcoded in the sketch both the board address and the port address (in a future article I’ll explain how to have the address configurable at runtime):

#define BOARD_ADDRESS   5
#define PORT_ADDRESS    1

In the sketch you can verify that the command received is for your decoder with:

if((BoardAddr == BOARD_ADDRESS) && (portAddress == PORT_ADDRESS)) {

and change the output status of two digital pins (to which I connected the leds) based on the output number and the command:

if(outAddress == 0) {
  digitalWrite(RED_LED_PIN, HIGH);
  digitalWrite(GREEN_LED_PIN, LOW);
   Serial.println("! RED led activated");
} else {
  digitalWrite(RED_LED_PIN, LOW);
  digitalWrite(GREEN_LED_PIN, HIGH);
  Serial.println("! GREEN led activated");      
    }

The source code of the decoder is available in my Github repository, here’s a video that shows how it works:

Arduino controlled Dual Mono AK4490 DAC (part 1)

pDual_Mono_AK4490_05-600

This article is the first of a series detailing the design and build process of an Arduino controlled Dual Mono AK4490 DAC by DimDim:

The design goal was to do a dual mono design so as to maximize SNR and channel separation. A 4-layer PCB design was chosen so as to have a very solid, low impedance ground plane as well as proper power and signal planes. The I2S, audio signals and power after the local LDO regulators are routed on the top layer, the 2 middle layers are ground and power planes, and the bottom layer serves to route I2C signals and some power lines.

See the full post here, Dimdim’s blog.

How to configure I2C sensors with Arduino

sensorpan-600

Edward Mallon writes:

I’ve spent the last year in the ‘uncanny valley’ of the Arduino. That’s the point where you understand the tutorials at Arduino.cc, but still don’t get much from the material on gitHub because trained programmers would never stoop to using the wire.h library when they could just roll their own in native C++ using the avr-g++ compiler.  The problem with establishing sensor communication at the level of the TWI peripheral inside the AVR is that there are so many fiddling details to keep track of that it quickly overruns the 7±2 things this average human can hold in his head at one time: Computers aren’t the only things that crash after a buffer overflow!  So this post is meant to be a chunking exercise for beginner-intermediate level people like myself who want to get a new sensor working using the standard IDE.  I’ve tried to distill it all down to things that I run into frequently, but there’s still a lot of material here:  So pour yourself a cuppa before diving in…

More details at Arduino based underwater sensors blog.

ESP8266 Deep Sleep with Arduino IDE

Deep-sleep-blog-1280-600

Rui Santos has written a great guide shows us what’s Deep Sleep and how to use it with the ESP8266 in the Arduino IDE.

With most of the ESP8266 modules, you can’t change the hardware to save power, but you can write software to do it. If you use the sleep functions with the ESP8266, it will draw less power and your batteries will last longer. In this guide, we’re going to talk about Deep Sleep with the ESP8266.

See the full post on his blog, Random Nerd Tutorials.

Check out the video after the break.