From 8505edd03245bd8c6472a034406726316048ef61 Mon Sep 17 00:00:00 2001 From: Rene Arnhold Date: Mon, 27 Jul 2020 23:14:43 +0200 Subject: [PATCH] first commit --- README.md | 0 include/README | 39 ++++++++++ lib/README | 46 +++++++++++ platformio.ini | 16 ++++ src/main.cpp | 201 +++++++++++++++++++++++++++++++++++++++++++++++++ test/README | 11 +++ 6 files changed, 313 insertions(+) create mode 100644 README.md create mode 100644 include/README create mode 100644 lib/README create mode 100644 platformio.ini create mode 100644 src/main.cpp create mode 100644 test/README diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..931397b --- /dev/null +++ b/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:odroid_esp32] +platform = espressif32 +board = odroid_esp32 +framework = arduino +lib_deps = + ESP32 BLE Arduino \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d3df5bc --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,201 @@ +/* + Video: https://www.youtube.com/watch?v=oCMOYS71NIU + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleNotify.cpp + Ported to Arduino ESP32 by Evandro Copercini + + Create a BLE server that, once we receive a connection, will send periodic notifications. + The service advertises itself as: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E + Has a characteristic of: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E - used for receiving data with "WRITE" + Has a characteristic of: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E - used to send data with "NOTIFY" + + The design of creating the BLE server is: + 1. Create a BLE Server + 2. Create a BLE Service + 3. Create a BLE Characteristic on the Service + 4. Create a BLE Descriptor on the characteristic + 5. Start the service. + 6. Start advertising. + + In this example rxValue is the data received (only accessible inside that function). + And txValue is the data to be sent, in this example just a byte incremented every second. +*/ +#include +#include +#include +#include +#include + +BLEServer *pServer = NULL; +BLECharacteristic * pRTxCharacteristic; +bool deviceConnected = false; +bool oldDeviceConnected = false; +uint8_t txValue = 0; + +// See the following for generating UUIDs: +// https://www.uuidgenerator.net/ + +#define SERVICE_UUID "0000ffe0-0000-1000-8000-00805f9b34fb" // UART service UUID +#define CHARACTERISTIC_UUID_RTX "0000ffe1-0000-1000-8000-00805f9b34fb" + +#define BUTTON_A_PIN 32 +#define BUTTON_B_PIN 33 + +uint8_t params[] = { 0x66, 0x11, 0x20, 0x00, 0x64, 0x30, 0x3C, 0x2A, 0x14, 0xD9, 0x00, 0x32, 0x00, 0x64, 0x00, 0x2D, 0x00, 0xCC, 0x10, 0x64, 0x32, 0xFC, 0x53, 0x98, 0x08, 0x64, 0x00, 0x41, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x78 }; +byte params_request[] = {0x66, 0x11, 0x00, 0x77}; +bool send_params = false; + +uint8_t status[] = { 0x66, 0x41, 0x05, 0x32, 0x32, 0x00, 0x00, 0x02 , 0x02}; +byte status_request[] = {0x66, 0x41, 0x02}; +bool send_status = false; + +void write_status_checksum() { + int suma = 0; + for (int i = 0; i < sizeof(status) - 1; i++) { + suma += status[i]; + } + int tmp_suma = (suma / 256) * 256; + status[8] = suma - tmp_suma; + status[8] = 0; +} + +class MyServerCallbacks: public BLEServerCallbacks { + void onConnect(BLEServer* pServer) { + deviceConnected = true; + }; + + void onDisconnect(BLEServer* pServer) { + deviceConnected = false; + } +}; + +class MyCallbacks: public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *pCharacteristic) { + std::string rxValue = pCharacteristic->getValue(); + if (rxValue.length() > 0) { + if( (rxValue.length() == sizeof(params_request)) && (rxValue[0] == params_request[0]) && (rxValue[1] == params_request[1]) && (rxValue[2] == params_request[2]) && (rxValue[3] == params_request[3]) ) { + send_params = true; + } + else if( (rxValue.length() == (sizeof(status_request) + 3)) && (rxValue[0] == status_request[0]) && (rxValue[1] == status_request[1]) && (rxValue[2] == status_request[2]) ) { + send_status = true; + } + Serial.print(rxValue.length()); + Serial.print(" "); + Serial.print(sizeof(status_request)); + Serial.print(" "); + Serial.print(sizeof(status)); + Serial.println(); + Serial.print("Received Value: "); + for (int i = 0; i < rxValue.length(); i++) { + Serial.print(rxValue[i], HEX); + Serial.print(" "); + } + Serial.println(); + Serial.println("*********"); + } + } +}; + + +void setup() { + Serial.begin(9600); + + pinMode(BUTTON_A_PIN, INPUT_PULLUP); + pinMode(BUTTON_B_PIN, INPUT_PULLUP); + + // Create the BLE Device + BLEDevice::init("RAYVOLT DUMMY"); + + // Create the BLE Server + pServer = BLEDevice::createServer(); + pServer->setCallbacks(new MyServerCallbacks()); + + // Create the BLE Service + BLEService *pService = pServer->createService(SERVICE_UUID); + + // Create a BLE Characteristic + pRTxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_RTX, + BLECharacteristic::PROPERTY_NOTIFY | BLECharacteristic::PROPERTY_WRITE + ); + + pRTxCharacteristic->addDescriptor(new BLE2902()); + pRTxCharacteristic->setCallbacks(new MyCallbacks()); +/* + BLECharacteristic * pRxCharacteristic = pService->createCharacteristic( + CHARACTERISTIC_UUID_RX, + BLECharacteristic::PROPERTY_WRITE + ); + + pRxCharacteristic->setCallbacks(new MyCallbacks()); +*/ + // Start the service + pService->start(); + + // Start advertising + pServer->getAdvertising()->start(); + Serial.println("Waiting a client connection to notify..."); +} + +void loop() { + if (!digitalRead(BUTTON_A_PIN)) { + Serial.println("Button A"); + if (status[3] == 0xFF) { + status[3] = 0x00; + } + else { + status[3] += 1; + } + } + if (!digitalRead(BUTTON_B_PIN)) { + Serial.println("Button B"); + if (status[3] == 0x00) { + status[3] = 0xFF; + } + else { + status[3] -= 1; + } + } + if (deviceConnected) { + if (send_params) { + Serial.print("sending: "); + for (int i = 0; i < sizeof(params); i++) { + Serial.print(params[i], HEX); + pRTxCharacteristic->setValue(¶ms[i], 1); + pRTxCharacteristic->notify(); + } + send_params = false; + Serial.println(""); + } + else if (send_status) { + write_status_checksum(); + Serial.print("sending: "); + for (int i = 0; i < sizeof(status); i++) { + Serial.print(status[i], HEX); + Serial.print(" "); + pRTxCharacteristic->setValue(&status[i], 1); + pRTxCharacteristic->notify(); + } + send_status = false; + Serial.println(""); + } + /* + pTxCharacteristic->setValue(&txValue, 1); + pTxCharacteristic->notify(); + txValue++; + */ + delay(10); // bluetooth stack will go into congestion, if too many packets are sent + } + + // disconnecting + if (!deviceConnected && oldDeviceConnected) { + delay(500); // give the bluetooth stack the chance to get things ready + pServer->startAdvertising(); // restart advertising + Serial.println("start advertising"); + oldDeviceConnected = deviceConnected; + } + // connecting + if (deviceConnected && !oldDeviceConnected) { + // do stuff here on connecting + oldDeviceConnected = deviceConnected; + } +} \ No newline at end of file diff --git a/test/README b/test/README new file mode 100644 index 0000000..df5066e --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html