Skip to content

Changing BLE hci transport #287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions examples/WiFiWebClientBLELed/WiFiWebClientBLELed.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/*
Repeating WiFi Web Client + BLE Led

This sketch connects to a a web server and makes a request
using a WiFi equipped Arduino board.

Additionally this example creates a Bluetooth® Low Energy peripheral with service that contains a
characteristic to control an LED.

You can use a generic Bluetooth® Low Energy central app, like LightBlue (iOS and Android) or
nRF Connect (Android), to interact with the services and characteristics
created in this sketch.

This code is in the public domain.
*/

#include <SPI.h>
#include <WiFiNINA.h>
#include "arduino_secrets.h"

#include <ArduinoBLE.h>
#include <utility/HCI.h>

BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // Bluetooth® Low Energy LED Service

// Bluetooth® Low Energy LED Switch Characteristic - custom 128-bit UUID, read and writable by central
BLEByteCharacteristic switchCharacteristic("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite);
const int ledPin = LED_BUILTIN; // pin to use for the LED

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID; // your network SSID (name)
char pass[] = SECRET_PASS; // your network password (use for WPA, or use as key for WEP)
int keyIndex = 0; // your network key index number (needed only for WEP)

int status = WL_IDLE_STATUS;

// Initialize the WiFi client library
WiFiClient client;

// server address:
char server[] = "example.org";
//IPAddress server(64,131,82,241);

unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
const unsigned long postingInterval = 10L * 1000L; // delay between updates, in milliseconds

void setup() {
//Initialize serial and wait for port to open:
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for native USB port only
}

// set LED pin to output mode
pinMode(ledPin, OUTPUT);

// begin initialization
if (!BLE.begin()) {
Serial.println("starting Bluetooth® Low Energy module failed!");

while (1);
}

// set advertised local name and service UUID:
BLE.setLocalName("LED");
BLE.setAdvertisedService(ledService);

// add the characteristic to the service
ledService.addCharacteristic(switchCharacteristic);

// add service
BLE.addService(ledService);

// set the initial value for the characeristic:
switchCharacteristic.writeValue(0);

// start advertising
BLE.advertise();

Serial.println("BLE LED Peripheral");

// check for the WiFi module:
if (WiFi.status() == WL_NO_MODULE) {
Serial.println("Communication with WiFi module failed!");
// don't continue
while (true);
}

String fv = WiFi.firmwareVersion();
if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
Serial.println("Please upgrade the firmware");
}

// attempt to connect to WiFi network:
while (status != WL_CONNECTED) {
Serial.print("Attempting to connect to SSID: ");
Serial.println(ssid);
// Connect to WPA/WPA2 network. Change this line if using open or WEP network:
status = WiFi.begin(ssid, pass);

// wait 10 seconds for connection:
delay(10000);
}
// you're connected now, so print out the status:
printWifiStatus();
}

void loop() {
// if there's incoming data from the net connection.
// send it out the serial port. This is for debugging
// purposes only:
while (client.available()) {
char c = client.read();
Serial.write(c);
}

// if ten seconds have passed since your last connection,
// then connect again and send data:
if (millis() - lastConnectionTime > postingInterval) {
httpRequest();
}

// listen for Bluetooth® Low Energy peripherals to connect:
BLEDevice central = BLE.central();

// if a central is connected to peripheral:
if (central) {
Serial.print("Connected to central: ");
// print the central's MAC address:
Serial.println(central.address());

// while the central is still connected to peripheral:
while (central.connected()) {
// if the remote device wrote to the characteristic,
// use the value to control the LED:
if (switchCharacteristic.written()) {
if (switchCharacteristic.value()) { // any value other than 0
Serial.println("LED on");
digitalWrite(ledPin, HIGH); // will turn the LED on
} else { // a 0 value
Serial.println(F("LED off"));
digitalWrite(ledPin, LOW); // will turn the LED off
}
}
}

// when the central disconnects, print it out:
Serial.print(F("Disconnected from central: "));
Serial.println(central.address());
}
}

// this method makes a HTTP connection to the server:
void httpRequest() {
// close any connection before send a new request.
// This will free the socket on the NINA module
client.stop();

// if there's a successful connection:
if (client.connect(server, 80)) {
Serial.println("connecting...");
// send the HTTP GET request:
client.println("GET / HTTP/1.1");
client.println("Host: example.org");
client.println("User-Agent: ArduinoWiFi/1.1");
client.println("Connection: close");
client.println();

// note the time that the connection was made:
lastConnectionTime = millis();
} else {
// if you couldn't make a connection:
Serial.println("connection failed");
}
}


void printWifiStatus() {
// print the SSID of the network you're attached to:
Serial.print("SSID: ");
Serial.println(WiFi.SSID());

// print your board's IP address:
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: ");
Serial.println(ip);

// print the received signal strength:
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):");
Serial.print(rssi);
Serial.println(" dBm");
}
2 changes: 2 additions & 0 deletions examples/WiFiWebClientBLELed/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define SECRET_SSID ""
#define SECRET_PASS ""
137 changes: 136 additions & 1 deletion src/utility/wifi_drv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ void WiFiDrv::wifiDriverInit()

void WiFiDrv::wifiDriverDeinit()
{
SpiDrv::end();
}

int8_t WiFiDrv::wifiSetNetwork(const char* ssid, uint8_t ssid_len)
Expand Down Expand Up @@ -1663,5 +1662,141 @@ PreferenceType WiFiDrv::prefGetType(const char * key) {
return type;
}

int WiFiDrv::bleBegin() {
WAIT_FOR_SLAVE_SELECT();

SpiDrv::sendCmd(BLE_BEGIN, PARAM_NUMS_0);

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

uint8_t len = 1;
uint8_t result = 0;
SpiDrv::waitResponseCmd(BLE_BEGIN, PARAM_NUMS_1, (uint8_t*)&result, &len);
SpiDrv::spiSlaveDeselect();

return result == 0;
}

void WiFiDrv::bleEnd() {
WAIT_FOR_SLAVE_SELECT();

SpiDrv::sendCmd(BLE_END, PARAM_NUMS_0);

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

uint8_t len = 1;
uint8_t result = 0;
SpiDrv::waitResponseCmd(BLE_END, PARAM_NUMS_1, (uint8_t*)&result, &len);
SpiDrv::spiSlaveDeselect();
}

int WiFiDrv::bleAvailable() {
WAIT_FOR_SLAVE_SELECT();
uint16_t result = 0;

SpiDrv::sendCmd(BLE_AVAILABLE, PARAM_NUMS_0);

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

uint8_t len = 2;
SpiDrv::waitResponseCmd(BLE_AVAILABLE, PARAM_NUMS_1, (uint8_t*)&result, &len);
SpiDrv::spiSlaveDeselect();

return result;
}

int WiFiDrv::bleRead(uint8_t data[], size_t length) {
WAIT_FOR_SLAVE_SELECT();

SpiDrv::sendCmd(BLE_READ, PARAM_NUMS_1);

int commandSize = 7; // 4 for the normal command length + 3 for the parameter
uint16_t param = length; // TODO check length doesn't exceed 2^16
SpiDrv::sendParam((uint8_t*)&param, sizeof(param), LAST_PARAM);

// pad to multiple of 4
while (commandSize % 4 != 0) {
SpiDrv::readChar();
commandSize++;
}

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

uint16_t res_len = 0;
SpiDrv::waitResponseData16(BLE_READ, data, (uint16_t*)&res_len);

SpiDrv::spiSlaveDeselect();

return res_len;
}

int WiFiDrv::blePeek(uint8_t data[], size_t length) {
WAIT_FOR_SLAVE_SELECT();

SpiDrv::sendCmd(BLE_PEEK, PARAM_NUMS_1);

int commandSize = 7; // 4 for the normal command length + 3 for the parameter
uint16_t param = length; // TODO check length doesn't exceed 2^16
SpiDrv::sendParam((uint8_t*)&param, sizeof(param), LAST_PARAM);

// pad to multiple of 4
while (commandSize % 4 != 0) {
SpiDrv::readChar();
commandSize++;
}

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

uint16_t res_len = 0;
SpiDrv::waitResponseData16(BLE_READ, data, (uint16_t*)&res_len);

SpiDrv::spiSlaveDeselect();

return res_len;
}

size_t WiFiDrv::bleWrite(const uint8_t* data, size_t len) {
WAIT_FOR_SLAVE_SELECT();

int commandSize = 4;
SpiDrv::sendCmd(BLE_WRITE, PARAM_NUMS_1);

SpiDrv::sendBuffer((uint8_t*)data, len, LAST_PARAM);
commandSize += len+2;

// pad to multiple of 4
while (commandSize % 4 != 0) {
SpiDrv::readChar();
commandSize++;
}

SpiDrv::spiSlaveDeselect();
//Wait the reply elaboration
SpiDrv::waitForSlaveReady();
SpiDrv::spiSlaveSelect();

uint8_t res_len = 1;
uint16_t res = 0;
SpiDrv::waitResponseCmd(BLE_WRITE, PARAM_NUMS_1, (uint8_t*)&res, &res_len);
SpiDrv::spiSlaveDeselect();

return res;
}


WiFiDrv wiFiDrv;
7 changes: 7 additions & 0 deletions src/utility/wifi_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,13 @@ class WiFiDrv
static size_t prefGet(const char * key, PreferenceType type, uint8_t value[], size_t len);
static PreferenceType prefGetType(const char * key);

static int bleBegin();
static void bleEnd();
static int bleAvailable();
static int bleRead(uint8_t data[], size_t length);
static int blePeek(uint8_t data[], size_t length);
static size_t bleWrite(const uint8_t* data, size_t length);

static void applyOTA();

friend class WiFiUDP;
Expand Down
7 changes: 7 additions & 0 deletions src/utility/wifi_spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ enum {
GET_DATABUF_TCP_CMD = 0x45,
INSERT_DATABUF_CMD = 0x46,

BLE_BEGIN = 0x4A,
BLE_END = 0x4B,
BLE_AVAILABLE = 0x4C,
BLE_PEEK = 0x4D,
BLE_READ = 0x4E,
BLE_WRITE = 0x4F,

// regular format commands
SET_PIN_MODE = 0x50,
SET_DIGITAL_WRITE = 0x51,
Expand Down