From db459b35f181ba9386c647d0924e88981ead353a Mon Sep 17 00:00:00 2001 From: Fenoglio Date: Mon, 3 Dec 2018 16:14:49 +0100 Subject: [PATCH] Updated coderacer lib - supports now Bluetooth --- Arduino/libraries/CodeRacer/CodeRacer.cpp | 143 ++++++++++++++++++ Arduino/libraries/CodeRacer/CodeRacer.h | 31 +++- .../SimpleBTCoderacer/SimpleBTCoderacer.ino | 56 +++++++ .../esp32_coderacer_beispiel.ino | 18 --- Arduino/libraries/CodeRacer/keywords.txt | 15 ++ 5 files changed, 244 insertions(+), 19 deletions(-) create mode 100644 Arduino/libraries/CodeRacer/examples/SimpleBTCoderacer/SimpleBTCoderacer.ino create mode 100644 Arduino/libraries/CodeRacer/keywords.txt diff --git a/Arduino/libraries/CodeRacer/CodeRacer.cpp b/Arduino/libraries/CodeRacer/CodeRacer.cpp index c4dc5fe..5871950 100644 --- a/Arduino/libraries/CodeRacer/CodeRacer.cpp +++ b/Arduino/libraries/CodeRacer/CodeRacer.cpp @@ -1,6 +1,8 @@ // the compiler switch for an ESP8266 is looking like this: #elif defined(ARDUINO_ARCH_ESP8266) #include "CodeRacer.h" +using namespace std; + /** @brief CodeRace constructor without pins. All pins settings taken from the coderacer header file * @return nothing */ @@ -68,6 +70,11 @@ CodeRacer::CodeRacer(uint8_t button_pin , uint8_t servo_pin, void CodeRacer::begin() { // init of variables and objects + _bluetoothcreated = false; + _bt_stopOnLostConnection_timeout_ms = 0; + _bt_lastmessagereceived = millis(); + _bt_ignoremsgs.clear(); + _bt_onlymsgs.clear(); _servo_dummy = new Servo(); // the dummy is needed so far to avoid conflicts with analog write _servo = new Servo(); @@ -490,6 +497,142 @@ void CodeRacer::kitt() /** @} */ // end of group lowerlevelfun + +//************************************** +//*** Bluetooth *** +//************************************** +/** @defgroup lowerlevelbluetooth Lower level bluetooth methods +* @{ +*/ +/** @brief starting the bluetooth service for the coderacer if not already started +* @param name the device will be listed by that name in your bluetooth device lists +* @return nothing +*/ +void CodeRacer::bt_start(String name) +{ + if (false == _bluetoothcreated) { + _BTSerial = new BluetoothSerial(); + _BTSerial->begin(name); + _bluetoothcreated = true; + } +} + +/** @brief enables the code to stop if there was no incoming message for the specified time. This will be checked everytime bt_getXXX or bt_msgavailable is called. +* @param timeout after that duration of milliseconds without an incoming bluetooth message the coderacer will be stopped. 0 means this stoppinf is disabled. +* @return nothing +*/ +void CodeRacer::bt_enable_stopOnLostConnection(unsigned long timeout) +{ + _bt_stopOnLostConnection_timeout_ms = timeout; +} + +/** @brief enables the code to stop if there was no incoming message for 1 second. This will be checked everytime bt_getXXX or bt_msgavailable is called. +* @return nothing +*/ +void CodeRacer::bt_enable_stopOnLostConnection() +{ + _bt_stopOnLostConnection_timeout_ms = 1000; +} + +/** @brief Disables the code to stop if there was no incoming message for a certain duration of time. +* @return nothing +*/ +void CodeRacer::bt_disable_stopOnLostConnection() +{ + _bt_stopOnLostConnection_timeout_ms = 0; +} + +/** @brief gets the bluetooth message string until a delimiter of 0 +* @return will return the string. If nothing is availbale or the service is not started it will return an empty string. +*/ +String CodeRacer::bt_getString() +{ + return bt_getString(0); +} + +/** @brief gets the bluetooth message string until a specified delimiter +* @return will return the string. If nothing is availbale or the service is not started it will return an empty string. +*/ +String CodeRacer::bt_getString(uint8_t delimiterbyte) +{ + String readstring = ""; + if (bt_msgavailable()) + { + readstring = _BTSerial->readStringUntil(delimiterbyte); + if (find(_bt_ignoremsgs.begin(), _bt_ignoremsgs.end(), readstring) != _bt_ignoremsgs.end()) + { + readstring = ""; + } + } + return(readstring); +} + +/** @brief add a String to a list of Strings that will be ignored if this is received via blue tooth. Ignores means - it will be read from the pipe but not returned to user code. But it will reset the message timeout counter. +* @param stringtoignore the String that has to be ignored. Will be added to the internal list if not already there. +*/ +void CodeRacer::bt_addStringToIgnoreList(String stringtoignore) +{ + std::vector::iterator it; + if (stringtoignore.length() > 0) + { + it = find(_bt_ignoremsgs.begin(), _bt_ignoremsgs.end() ,stringtoignore); + if (it == _bt_ignoremsgs.end()) + { + _bt_ignoremsgs.push_back(stringtoignore); + } + } +} + +/** @brief removes a String from the list of Strings that will be ignored if this is received via blue tooth. Ignores means - it will be read from the pipe but not returned to user code. But it will reset the message timeout counter. +* @param stringtoignore the String that has to be removed from the ignore list. +*/ +void CodeRacer::bt_removeStringFromIgnoreList(String stringtoignore) +{ + std::vector::iterator it; + if (stringtoignore.length() > 0) + { + it = find(_bt_ignoremsgs.begin(), _bt_ignoremsgs.end(), stringtoignore); + if (it != _bt_ignoremsgs.end()) + { + _bt_ignoremsgs.erase(it); + } + } +} + +/** @brief Clears the list of Strings that will be ignored if this is received via blue tooth. All elements of the list will be deleted from the list. +*/ +void CodeRacer::bt_clearIgnoreList() +{ + _bt_ignoremsgs.clear(); +} + + +/** @brief checks if a bluetooth is available. Will also stop the coderacer if there was nor message received for a certain time - and if stopping was enabled . +* @return true if a message is available , false if not message is available or the service was not started +*/ +bool CodeRacer::bt_msgavailable() +{ + bool rc = false; + if (true == _bluetoothcreated) { + if(_BTSerial->available()) + { + rc = true; + _bt_lastmessagereceived = millis(); + } + if (_bt_stopOnLostConnection_timeout_ms > 0) + { + if ((millis() - _bt_lastmessagereceived) > _bt_stopOnLostConnection_timeout_ms) + { + stop_driving(); + } + } + + } + return rc; +} + +/** @} */ // end of group lowerlevelbluetooth + //************************************** //*** Servo drive lower level control *** //************************************** diff --git a/Arduino/libraries/CodeRacer/CodeRacer.h b/Arduino/libraries/CodeRacer/CodeRacer.h index a690f08..26c93b8 100644 --- a/Arduino/libraries/CodeRacer/CodeRacer.h +++ b/Arduino/libraries/CodeRacer/CodeRacer.h @@ -2,6 +2,13 @@ #include // std::swap #include // Servo drive support for ESP32 #include "esp32-hal-ledc.h" // Part of ESP32 board files - Analog output +#include "BluetoothSerial.h" // Bluetooth enablement - part of ESP or standart Arduino lib +#include // support for vectors +#include + +#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED) +#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it +#endif #ifndef __CodeRacer_H__ #define __CodeRacer_H__ @@ -56,6 +63,9 @@ #define H_LED_LEFT_PIN 33 #define H_LED_RIGHT_PIN 27 + +using namespace std; + static volatile bool coderracer_activ = false;; static volatile unsigned long button_last_pressed_at_ms = millis(); @@ -75,6 +85,14 @@ class CodeRacer { private: + //bluetooth + std::vector _bt_ignoremsgs; + std::vector _bt_onlymsgs; + bool _bluetoothcreated; + unsigned long _bt_stopOnLostConnection_timeout_ms; + unsigned long _bt_lastmessagereceived; + BluetoothSerial* _BTSerial; + //pins uint8_t _button_pin; uint8_t _servo_pin; @@ -131,7 +149,7 @@ class CodeRacer { static void _set_button_state(); void _analog_write(uint8_t pin, uint8_t speed); unsigned long _servo_set_position(uint8_t position); - + public: //properties bool coderacer_fun_enabled; @@ -187,6 +205,17 @@ class CodeRacer { void start_stop_at_min_distance(unsigned long min_distance_cm); void stop_stop_at_min_distance(); + // Bluetooth + void bt_enable_stopOnLostConnection(); + void bt_enable_stopOnLostConnection(unsigned long timeout); + void bt_disable_stopOnLostConnection(); + void bt_start(String name); + String bt_getString(); + String bt_getString(uint8_t delimiterbyte); + bool bt_msgavailable(); + void bt_addStringToIgnoreList(String stringtoignore); + void bt_clearIgnoreList(); + void bt_removeStringFromIgnoreList(String stringtoignore); // LEDs void set_leds_left_stop_frwd_right(ledstate leftled, ledstate stopled, ledstate frwdled, ledstate rightled); diff --git a/Arduino/libraries/CodeRacer/examples/SimpleBTCoderacer/SimpleBTCoderacer.ino b/Arduino/libraries/CodeRacer/examples/SimpleBTCoderacer/SimpleBTCoderacer.ino new file mode 100644 index 0000000..47ca307 --- /dev/null +++ b/Arduino/libraries/CodeRacer/examples/SimpleBTCoderacer/SimpleBTCoderacer.ino @@ -0,0 +1,56 @@ + +// Full API description of the coderacer.h can be found here: https://fenoglio.pages.itsblue.de/coderacer/ +// Repository with all needed data and users guide is here: https://git.itsblue.de/Fenoglio/coderacer/tree/master +// An example for a application to control the coderacer via bluetooth can be found here: +// - this app was developed with MIT App Inventor and can be uploaded to your account to rework it. + +#include + +CodeRacer coderacer; +String recvddata = ""; //Variable in der der Bluetooth Befehl gespeichert wird + +void setup() { + Serial.begin(115200); + coderacer.begin(); + coderacer.bt_start("CodeRacer"); //Bluetooth für den Coderacer anschalten + coderacer.bt_enable_stopOnLostConnection(); //Coderacer anhalten, wenn 1 Sekunde nichts per Bluetooth empfangen wurde + coderacer.bt_addStringToIgnoreList("."); //das "." Zeichen wird beim empfangen ignoriert +} + +void loop() { + // Prüfen ob Bluetooth Nachrichten angekommen sind und die gleich abholen ... + recvddata = coderacer.bt_getString(); //die Nachtricht merken (sie steht jetzt in recvdata und kann später benutzt werden) + if (recvddata != "") //wenn eine Nachricht empfangen wurde, in der was drin steht ... + { + Serial.println(recvddata); + + if(recvddata == "stop") + { + coderacer.stop_driving(); + } + + if(recvddata == "vor") + { + coderacer.drive_forward(255,255); + } + + if(recvddata.startsWith("rueck")) + { + coderacer.drive_backward(255,255); + } + + if(recvddata.startsWith("links")) + { + coderacer.turn_left(); + } + + if(recvddata.startsWith("rechts")) + { + coderacer.turn_right(); + } + } + + delay(20); +} + + diff --git a/Arduino/libraries/CodeRacer/examples/esp32_coderacer_beispiel/esp32_coderacer_beispiel.ino b/Arduino/libraries/CodeRacer/examples/esp32_coderacer_beispiel/esp32_coderacer_beispiel.ino index c16a436..ec20405 100644 --- a/Arduino/libraries/CodeRacer/examples/esp32_coderacer_beispiel/esp32_coderacer_beispiel.ino +++ b/Arduino/libraries/CodeRacer/examples/esp32_coderacer_beispiel/esp32_coderacer_beispiel.ino @@ -3,24 +3,6 @@ //----- settings for the ultrasonic sensor ----- #define US_STOP_ABSTAND_CM 20 // if distance goes below that - stop the racer -//----- {CODES}RACER API -> online: https://doc.itsblue.de/Fenoglio/coderacer/Doku/Doxygen/html/ -//-- Some main higher level methods listed below -// void CodeRacer::stop_driving () Stops the racer and sets status LEDs -// void CodeRacer::drive_forward () Sets the speed and the directions of both drives so that it will move forward. -// void CodeRacer::drive_backward () Sets the speed and the directions of both drives so that it will move backward. -// void CodeRacer::turn_left () Will turn the racer to the left for the internally stored time in ms and with the internally stored speed. -// void CodeRacer::turn_right () Will turn the racer to the right for the internally stored time in ms and with the internally stored speed. -// void CodeRacer::start_stop_at_min_distance () Enables to stopp the racer if during a distance measurement the measured distance is smaller then the internally stored minimal distance. -// void CodeRacer::stop_stop_at_min_distance () Disables to stopp the racer if during a distance measurement the measured distance is smaller then the specified minimal distance. -// bool CodeRacer::start_stop () This will return if the codracer is in active mode or not. -// void CodeRacer::servo_set_to_right () Drives the servo to the postion that is defined by #servo_right_pos. -// void CodeRacer::servo_set_to_left () Drives the servo to the postion that is defined by #servo_left_pos. -// void CodeRacer::servo_set_to_center () Drives the servo to the postion that is defined by #servo_center_pos. -// uint8_t CodeRacer::servo_position () Get the actual position of the servo. -// unsigned long CodeRacer::usonic_measure_cm () Measures the distance to the next object in front of the ultra sonic sensor in cm. -// -// ... there are much more ... read the online API for more details. - //----- variables we need unsigned long distance_cm = 0; diff --git a/Arduino/libraries/CodeRacer/keywords.txt b/Arduino/libraries/CodeRacer/keywords.txt new file mode 100644 index 0000000..f498ec9 --- /dev/null +++ b/Arduino/libraries/CodeRacer/keywords.txt @@ -0,0 +1,15 @@ +CodeRacer KEYWORD1 +begin KEYWORD2 +servo_einstellungen KEYWORD2 +motor_einstellungen KEYWORD2 +anhalten KEYWORD2 +normal_tempo KEYWORD2 +vorwaerts KEYWORD2 +links KEYWORD2 +rechts KEYWORD2 +servo_rechts KEYWORD2 +servo_links KEYWORD2 +servo_mitte KEYWORD2 +abstand_messen KEYWORD2 +servo_schwenk KEYWORD2 +start_stop KEYWORD2 \ No newline at end of file