diff --git a/examples/WiFiWebClientBLELed/WiFiWebClientBLELed.ino b/examples/WiFiWebClientBLELed/WiFiWebClientBLELed.ino new file mode 100644 index 0000000..1ecaca0 --- /dev/null +++ b/examples/WiFiWebClientBLELed/WiFiWebClientBLELed.ino @@ -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 +#include +#include "arduino_secrets.h" + +#include +#include + +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"); +} diff --git a/examples/WiFiWebClientBLELed/arduino_secrets.h b/examples/WiFiWebClientBLELed/arduino_secrets.h new file mode 100644 index 0000000..0c9fdd5 --- /dev/null +++ b/examples/WiFiWebClientBLELed/arduino_secrets.h @@ -0,0 +1,2 @@ +#define SECRET_SSID "" +#define SECRET_PASS "" diff --git a/src/utility/wifi_drv.cpp b/src/utility/wifi_drv.cpp index 6b41e49..a3303bc 100644 --- a/src/utility/wifi_drv.cpp +++ b/src/utility/wifi_drv.cpp @@ -113,7 +113,6 @@ void WiFiDrv::wifiDriverInit() void WiFiDrv::wifiDriverDeinit() { - SpiDrv::end(); } int8_t WiFiDrv::wifiSetNetwork(const char* ssid, uint8_t ssid_len) @@ -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*)¶m, 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*)¶m, 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; diff --git a/src/utility/wifi_drv.h b/src/utility/wifi_drv.h index ecd58a1..ccdceca 100644 --- a/src/utility/wifi_drv.h +++ b/src/utility/wifi_drv.h @@ -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; diff --git a/src/utility/wifi_spi.h b/src/utility/wifi_spi.h index d4d11da..02f7f1f 100644 --- a/src/utility/wifi_spi.h +++ b/src/utility/wifi_spi.h @@ -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,