Skip to content

Commit e7a2c30

Browse files
add support for BLEPeripheral library
1 parent 6ce3fbe commit e7a2c30

File tree

6 files changed

+233
-72
lines changed

6 files changed

+233
-72
lines changed

Boards.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,22 @@ writePort(port, value, bitmask): Write an 8 bit port.
449449
#define PIN_TO_SERVO(p) ((p) - 2)
450450

451451

452+
// RedBearLab BLE Nano with factory switch settings (S1 - S10)
453+
#elif defined(BLE_NANO)
454+
#define TOTAL_ANALOG_PINS 6
455+
#define TOTAL_PINS 15 // 9 digital + 3 analog
456+
#define IS_PIN_DIGITAL(p) ((p) >= 2 && (p) <= 14)
457+
#define IS_PIN_ANALOG(p) ((p) == 8 || (p) == 9 || (p) == 10 || (p) == 11 || (p) == 12 || (p) == 14) //A0~A5
458+
#define IS_PIN_PWM(p) ((p) == 3 || (p) == 5 || (p) == 6)
459+
#define IS_PIN_SERVO(p) ((p) >= 2 && (p) <= 7)
460+
#define IS_PIN_I2C(p) ((p) == SDA || (p) == SCL)
461+
#define IS_PIN_SPI(p) ((p) == CS || (p) == MOSI || (p) == MISO || (p) == SCK)
462+
#define PIN_TO_DIGITAL(p) (p)
463+
#define PIN_TO_ANALOG(p) ((p) - 8)
464+
#define PIN_TO_PWM(p) PIN_TO_DIGITAL(p)
465+
#define PIN_TO_SERVO(p) (p)
466+
467+
452468
// Sanguino
453469
#elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__)
454470
#define TOTAL_ANALOG_PINS 8

Firmata.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ extern "C" {
3333
*/
3434
void FirmataClass::sendValueAsTwo7bitBytes(int value)
3535
{
36-
FirmataStream->write(value & B01111111); // LSB
37-
FirmataStream->write(value >> 7 & B01111111); // MSB
36+
FirmataStream->write(value & 0x7F); // LSB
37+
FirmataStream->write(value >> 7 & 0x7F); // MSB
3838
}
3939

4040
/**

examples/StandardFirmataBLE/StandardFirmataBLE.ino

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,25 @@
2020
2121
See file LICENSE.txt for further informations on licensing terms.
2222
23-
Last updated by Jeff Hoefs: January 3rd, 2015
23+
Last updated by Jeff Hoefs: February 20th, 2016
2424
*/
2525

2626
#include <Servo.h>
2727
#include <Wire.h>
2828
#include <Firmata.h>
2929

30-
#include <CurieBle.h>
31-
#include "utility/BLEStream.h"
30+
#include "bleConfig.h"
3231

3332
//#define SERIAL_DEBUG
3433
#include "utility/firmataDebug.h"
3534

36-
#define I2C_WRITE B00000000
37-
#define I2C_READ B00001000
38-
#define I2C_READ_CONTINUOUSLY B00010000
39-
#define I2C_STOP_READING B00011000
40-
#define I2C_READ_WRITE_MODE_MASK B00011000
41-
#define I2C_10BIT_ADDRESS_MODE_MASK B00100000
42-
#define I2C_END_TX_MASK B01000000
35+
#define I2C_WRITE 0x00 //B00000000
36+
#define I2C_READ 0x08 //B00001000
37+
#define I2C_READ_CONTINUOUSLY 0x10 //B00010000
38+
#define I2C_STOP_READING 0x18 //B00011000
39+
#define I2C_READ_WRITE_MODE_MASK 0x18 //B00011000
40+
#define I2C_10BIT_ADDRESS_MODE_MASK 0x20 //B00100000
41+
#define I2C_END_TX_MASK 0x40 //B01000000
4342
#define I2C_STOP_TX 1
4443
#define I2C_RESTART_TX 0
4544
#define I2C_MAX_QUERIES 8
@@ -95,8 +94,6 @@ byte servoCount = 0;
9594

9695
boolean isResetting = false;
9796

98-
BLEStream stream(0);
99-
10097
/* utility functions */
10198
void wireWrite(byte data)
10299
{
@@ -736,6 +733,14 @@ void setup()
736733

737734
stream.setLocalName("FIRMATA");
738735

736+
#ifdef BLE_REQ
737+
for (byte i = 0; i < TOTAL_PINS; i++) {
738+
if (IS_IGNORE_BLE_PINS(i)) {
739+
Firmata.setPinMode(i, PIN_MODE_IGNORE);
740+
}
741+
}
742+
#endif
743+
739744
stream.begin();
740745
Firmata.begin(stream);
741746

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*===================================================================================
2+
* BLE CONFIGURATION
3+
*
4+
* If you are using an Arduino 101, you do not need to make any changes to this
5+
* file. If you are using another supported BLE board or shield, follow the
6+
* instructions for the specific board or shield below.
7+
*
8+
* Supported boards and shields:
9+
* - Arduino 101 (recommended)
10+
* - RedBearLab BLE Shield (v2) ** to be verified **
11+
*
12+
*==================================================================================*/
13+
14+
/*
15+
* RedBearLab BLE Shield
16+
*
17+
* If you are using a RedBearLab BLE shield, uncomment the define below.
18+
* Also, change the define for BLE_RST if you have the jumper set to pin 7 rather than pin 4.
19+
*
20+
* You will need to use the shield with an Arduino Mega, Due or other board with sufficient
21+
* Flash and RAM. Arduino Uno, Leonardo and other ATmega328p and Atmega32u4 boards to not have
22+
* enough memory to run StandardFirmataBLE.
23+
*
24+
* TODO: verify if this works and with which boards it works.
25+
*
26+
* Test script: https://gist.github.com/soundanalogous/927360b797574ed50e27
27+
* (may need to skip capabilities - see https://gist.github.com/soundanalogous/d39bb3eb36333a0906df)
28+
*/
29+
//#define REDBEAR_BLE_SHIELD
30+
31+
#ifdef REDBEAR_BLE_SHIELD
32+
#include <SPI.h>
33+
#include <BLEPeripheral.h>
34+
#include "utility/BLEStream.h"
35+
36+
#define BLE_REQ 9
37+
#define BLE_RDY 8
38+
#define BLE_RST 4 // 4 or 7 via jumper on shield
39+
40+
BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST);
41+
#endif
42+
43+
44+
/*===================================================================================
45+
* END BLE CONFIGURATION - you should not need to change anything below this line
46+
*==================================================================================*/
47+
48+
/*
49+
* Arduino 101
50+
*
51+
* Test script: https://gist.github.com/soundanalogous/927360b797574ed50e27
52+
*/
53+
#ifdef _VARIANT_ARDUINO_101_X_
54+
#include <CurieBle.h>
55+
//#include <CurieBLE.h> // switch to this once new Arduino 101 board package is available
56+
#include "utility/BLEStream.h"
57+
BLEStream stream;
58+
#endif
59+
60+
61+
/*
62+
* RedBearLab BLE Nano
63+
* Blocked on this issue: https://github.com/RedBearLab/nRF51822-Arduino/issues/46
64+
* Also, need to skip Capability Query (see example in test script)
65+
*
66+
* Test script: https://gist.github.com/soundanalogous/d39bb3eb36333a0906df
67+
*/
68+
// #ifdef BLE_NANO
69+
// #include <BLEPeripheral.h>
70+
// #include "utility/BLEStream.h"
71+
// BLEStream stream;
72+
// #endif
73+
74+
75+
/*
76+
* RedBearLab Blend and Blend Micro
77+
* StandardFirmataBLE is requires too much Flash and RAM to run on Blend Micro
78+
* may work with ConfigurableFirmata selecting only analog and digital I/O
79+
*/
80+
// #if defined(BLEND_MICRO) || defined(BLEND)
81+
// #include <SPI.h>
82+
// #include <BLEPeripheral.h>
83+
// #include "utility/BLEStream.h"
84+
85+
// #define BLE_REQ 6
86+
// #define BLE_RDY 7
87+
// #define BLE_RST 4
88+
89+
// BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST);
90+
// #endif
91+
92+
93+
#if defined(BLE_REQ) && defined(BLE_RDY) && defined(BLE_RST)
94+
#define IS_IGNORE_BLE_PINS(p) ((p) == BLE_REQ || (p) == BLE_RDY || (p) == BLE_RST)
95+
#endif

utility/BLEStream.cpp

Lines changed: 87 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22
BLEStream.cpp
33
44
Based on BLESerial.cpp by Voita Molda
5-
https://github.com/vojtamolda/BLEPeripheral/blob/master/examples/uart/BLESerial.cpp
5+
https://github.com/sandeepmistry/arduino-BLEPeripheral/blob/master/examples/serial/BLESerial.cpp
66
*/
77

88
#include "BLEStream.h"
99

10-
//#define BLE_SERIAL_DEBUG
10+
// #define BLE_SERIAL_DEBUG
1111

1212
BLEStream* BLEStream::_instance = NULL;
1313

14-
BLEStream::BLEStream(unsigned char) :
14+
BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) :
15+
#if defined(_VARIANT_ARDUINO_101_X_)
1516
BLEPeripheral()
17+
#else
18+
BLEPeripheral(req, rdy, rst)
19+
#endif
1620
{
1721
this->_txCount = 0;
1822
this->_rxHead = this->_rxTail = 0;
@@ -29,100 +33,130 @@ BLEStream::BLEStream(unsigned char) :
2933
addAttribute(this->_txNameDescriptor);
3034
}
3135

32-
void BLEStream::begin(...) {
36+
void BLEStream::begin(...)
37+
{
3338
BLEPeripheral::begin();
34-
#ifdef BLE_SERIAL_DEBUG
35-
Serial.println(F("BLEStream::begin()"));
36-
#endif
39+
#ifdef BLE_SERIAL_DEBUG
40+
Serial.println(F("BLEStream::begin()"));
41+
#endif
3742
}
3843

39-
bool BLEStream::poll() {
44+
bool BLEStream::poll()
45+
{
46+
// BLEPeripheral::poll is called each time connected() is called
4047
this->_connected = BLEPeripheral::connected();
41-
if (millis() > this->_flushed + BLESTREAM_TXBUFFER_FLUSH_INTERVAL) flush();
48+
if (millis() > this->_flushed + BLESTREAM_TXBUFFER_FLUSH_INTERVAL) {
49+
flush();
50+
}
4251
return this->_connected;
4352
}
4453

45-
void BLEStream::end() {
54+
void BLEStream::end()
55+
{
4656
this->_rxCharacteristic.setEventHandler(BLEWritten, NULL);
4757
this->_rxHead = this->_rxTail = 0;
4858
flush();
4959
BLEPeripheral::disconnect();
5060
}
5161

52-
int BLEStream::available(void) {
62+
int BLEStream::available(void)
63+
{
64+
// BLEPeripheral::poll only calls delay(1) in CurieBLE so skipping it here to avoid the delay
65+
#ifndef _VARIANT_ARDUINO_101_X_
66+
// TODO Need to do more testing to determine if all of these calls to BLEPeripheral::poll are
67+
// actually necessary. Seems to run fine without them, but only minimal testing so far.
68+
BLEPeripheral::poll();
69+
#endif
5370
int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer);
54-
#ifdef BLE_SERIAL_DEBUG
55-
if (retval > 0) {
56-
Serial.print(F("BLEStream::available() = "));
57-
Serial.println(retval);
58-
}
59-
#endif
71+
#ifdef BLE_SERIAL_DEBUG
72+
if (retval > 0) {
73+
Serial.print(F("BLEStream::available() = "));
74+
Serial.println(retval);
75+
}
76+
#endif
6077
return retval;
6178
}
6279

63-
int BLEStream::peek(void) {
80+
int BLEStream::peek(void)
81+
{
82+
#ifndef _VARIANT_ARDUINO_101_X_
83+
BLEPeripheral::poll();
84+
#endif
6485
if (this->_rxTail == this->_rxHead) return -1;
65-
unsigned char byte = this->_rxBuffer[this->_rxTail];
66-
#ifdef BLE_SERIAL_DEBUG
67-
Serial.print(F("BLEStream::peek() = 0x"));
68-
Serial.println(byte, HEX);
69-
#endif
86+
uint8_t byte = this->_rxBuffer[this->_rxTail];
87+
#ifdef BLE_SERIAL_DEBUG
88+
Serial.print(F("BLEStream::peek() = 0x"));
89+
Serial.println(byte, HEX);
90+
#endif
7091
return byte;
7192
}
7293

73-
int BLEStream::read(void) {
94+
int BLEStream::read(void)
95+
{
96+
#ifndef _VARIANT_ARDUINO_101_X_
97+
BLEPeripheral::poll();
98+
#endif
7499
if (this->_rxTail == this->_rxHead) return -1;
75100
this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer);
76-
unsigned char byte = this->_rxBuffer[this->_rxTail];
77-
#ifdef BLE_SERIAL_DEBUG
78-
Serial.print(F("BLEStream::read() = 0x"));
79-
Serial.println(byte, HEX);
80-
#endif
101+
uint8_t byte = this->_rxBuffer[this->_rxTail];
102+
#ifdef BLE_SERIAL_DEBUG
103+
Serial.print(F("BLEStream::read() = 0x"));
104+
Serial.println(byte, HEX);
105+
#endif
81106
return byte;
82107
}
83108

84-
void BLEStream::flush(void) {
109+
void BLEStream::flush(void)
110+
{
85111
if (this->_txCount == 0) return;
86-
if (this->_connected) this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount);
112+
this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount);
87113
this->_flushed = millis();
88114
this->_txCount = 0;
89-
#ifdef BLE_SERIAL_DEBUG
90-
Serial.println(F("BLEStream::flush()"));
91-
#endif
115+
#ifdef BLE_SERIAL_DEBUG
116+
Serial.println(F("BLEStream::flush()"));
117+
#endif
92118
}
93119

94-
size_t BLEStream::write(uint8_t byte) {
120+
size_t BLEStream::write(uint8_t byte)
121+
{
122+
#ifndef _VARIANT_ARDUINO_101_X_
123+
BLEPeripheral::poll();
124+
#endif
125+
if (this->_txCharacteristic.subscribed() == false) return 0;
95126
this->_txBuffer[this->_txCount++] = byte;
96127
if (this->_txCount == sizeof(this->_txBuffer)) flush();
97-
#ifdef BLE_SERIAL_DEBUG
98-
Serial.print(F("BLEStream::write( 0x"));
99-
Serial.print(byte, HEX);
100-
Serial.println(F(") = 1"));
101-
#endif
128+
#ifdef BLE_SERIAL_DEBUG
129+
Serial.print(F("BLEStream::write( 0x"));
130+
Serial.print(byte, HEX);
131+
Serial.println(F(") = 1"));
132+
#endif
102133
return 1;
103134
}
104135

105-
BLEStream::operator bool() {
136+
BLEStream::operator bool()
137+
{
106138
bool retval = this->_connected = BLEPeripheral::connected();
107-
#ifdef BLE_SERIAL_DEBUG
108-
Serial.print(F("BLEStream::operator bool() = "));
109-
Serial.println(retval);
110-
#endif
139+
#ifdef BLE_SERIAL_DEBUG
140+
Serial.print(F("BLEStream::operator bool() = "));
141+
Serial.println(retval);
142+
#endif
111143
return retval;
112144
}
113145

114-
void BLEStream::_received(const unsigned char* data, size_t size) {
115-
for (int i = 0; i < size; i++) {
146+
void BLEStream::_received(const unsigned char* data, size_t size)
147+
{
148+
for (size_t i = 0; i < size; i++) {
116149
this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer);
117150
this->_rxBuffer[this->_rxHead] = data[i];
118151
}
119-
#ifdef BLE_SERIAL_DEBUG
120-
Serial.print(F("BLEStream::received("));
121-
for (int i = 0; i < size; i++) Serial.print(data[i], HEX);
122-
Serial.println(F(")"));
123-
#endif
152+
#ifdef BLE_SERIAL_DEBUG
153+
Serial.print(F("BLEStream::received("));
154+
for (int i = 0; i < size; i++) Serial.print(data[i], HEX);
155+
Serial.println(F(")"));
156+
#endif
124157
}
125158

126-
void BLEStream::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic) {
159+
void BLEStream::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic)
160+
{
127161
BLEStream::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength());
128162
}

0 commit comments

Comments
 (0)