Driver for the JY-MCU v1.06 HC-06 Bluetooth module.

Dependents:   DISCO-F746NG_rtos_test MbedTableControl

Revision:
16:1030b80a28f4
Parent:
15:6a0aeaa39291
Child:
18:85c0f6580cd8
--- a/HC06Bluetooth.h	Wed Aug 03 18:18:05 2016 +0000
+++ b/HC06Bluetooth.h	Wed Aug 03 18:49:53 2016 +0000
@@ -1,142 +1,74 @@
-/*
- * HC06Bluetooth.cpp
- *
- *  Created on: Jun 4, 2016
- *      Author: Developer
+/**
+ * @file HC06Bluetooth.hpp
+ * @date June 4th, 2016
+ * @author Weimen Li
+ * @class HC06Bluetooth
+ * @brief This class creates an object representing the HC06 Bluetooth Module
+ * The baud rate for the device is configured to be 115200.
  */
 
-#include <HC06Bluetooth.h>
-#include <algorithm>
-
-/* Static methods used to help configure the Baudrate. */
-
-// WARNING: DO NOT CHANGE THESE VALUES, AS THEY ARE USED TO INDEX INTO AN ARRAY FOR IMPLEMENTATION.
-const char* BaudATString[] = {"AT+BAUD1", "AT+BAUD2", "AT+BAUD3", "AT+BAUD4", "AT+BAUD5", "AT+BAUD6", "AT+BAUD7", "AT+BAUD8", "AT+BAUD9", "AT+BAUDA", "AT+BAUDB", "AT+BAUDC"};
-const int32_t BaudATReplyLength[] = {6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9};
-//const char* BaudATReplyPattern[] = {"OK1200", "OK2400", "OK4800","OK9600","OK19200","OK38400","OK57600","OK115200","OK230400","OK460800","OK921600","OK1382400"};
-const int32_t BaudValue[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1382400};
-
-/* HC06 Bluetooth Class Implementation: */
-HC06Bluetooth::HC06Bluetooth(PinName TX, PinName RX, Baudrate baudrate, void (*lineCallbackFunc) (const char* readString, size_t strlen), void (*charCallbackFunc) (char readChar))
-: btSerialObj(TX, RX), baudrate(baudrate), lineCallbackFunc(lineCallbackFunc), charCallbackFunc(charCallbackFunc), dataReceivedBufferPos(0) {
-    btSerialObj.baud(BaudValue[baudrate]);
-
-    // Set the interrupt to be called when a byte is received.
-    if ((lineCallbackFunc != NULL) || (charCallbackFunc != NULL)) {
-        btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR);
-    }
-}
 
-void HC06Bluetooth::runSetup(std::string deviceName, std::string PIN) {
-    int numCharsReceived = 0;
-    // Detatch the interrupt.
-    btSerialObj.attach(NULL);
-    /* Sweep through a list of Baud rates until we find the one that the device has previously been set to. */
-    bool baudFound = false;
-    Timer timeOut;
-    timeOut.start();
-    // For every baud rate in the list:
-    for (volatile int i = 0; (i < END) && (!baudFound); i++) {
-        // Set the communication baud rate to it.
-        btSerialObj.baud(BaudValue[i]);
-        // Send the test command "AT" to the device.
-        btSerialObj.puts("AT");
-        // While the time out has not been reached:
-        for(timeOut.reset(); timeOut.read_ms() < 1000; ) {
-            // If the serial object is readable, make sure the read character matches the reply string "OK".
-            if (btSerialObj.readable() && !baudFound) {
-                    baudFound = true;
-                    break;
-            }
-        }
-    }
-    // Flush whatever's in the input buffer.
-    while(btSerialObj.readable()) {
-        btSerialObj.getc();
-    }
-    //Overwrite the Baud rate to 115200.
-    btSerialObj.puts(BaudATString[baudrate]);
-    btSerialObj.baud(BaudValue[baudrate]);
-    // Wait for the 8 character reply "OK115200"
-    for(numCharsReceived = 0 ; numCharsReceived < BaudATReplyLength[baudrate]; numCharsReceived++) {
-        //while(!btSerialObj.readable());
-        //btSerialObj.getc();
-    }
-    wait_ms(1000);
+#ifndef HC06BLUETOOTH_H_
+#define HC06BLUETOOTH_H_
+#include "mbed.h"
+#include <string>
 
-    // Set the name of the device.
-    btSerialObj.puts(("AT+NAME" + deviceName.substr(0,20)).c_str());
-    // Wait for the 6 character reply "OKname"
-    for(numCharsReceived = 0 ; numCharsReceived < 6; numCharsReceived++) {
-        //while(!btSerialObj.readable());
-        //btSerialObj.getc();
-    }
-    wait_ms(1000);
+const int dataBufferSize = 256;
+// WARNING: DO NOT CHANGE THESE VALUES, AS THEY ARE USED TO INDEX INTO AN ARRAY FOR IMPLEMENTATION.
+enum Baudrate {B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B921600, B1382400, END};
 
-    //Set the password of the device.
-    btSerialObj.puts(("AT+PIN" + PIN.substr(0, 4)).c_str());
-    // Wait for the 8 character reply "OKsetpin"
-    for(numCharsReceived = 0 ; numCharsReceived < 8; numCharsReceived++) {
-        //while(!btSerialObj.readable());
-        //btSerialObj.getc();
-    }
-    wait_ms(1000);
-    // Reattach the interrupt.
-    btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR);
-}
-
-HC06Bluetooth::~HC06Bluetooth() {
-    // TODO Auto-generated destructor stub
-}
-
-void HC06Bluetooth::print(const char* buffer) {
-   // TODO: Code hangs if buffer is too long! Not sure why.
-    btSerialObj.puts(buffer);
-}
-
-void HC06Bluetooth::println(const char* buffer) {
-    btSerialObj.puts(buffer);
-    btSerialObj.putc('\n');
-}
-
-void HC06Bluetooth::print(char c) {
-    btSerialObj.putc(c);
-}
+class HC06Bluetooth {
+public: // Public methods.
+    /**
+     * @brief Constructor for the HC06_Bluetooth class.
+     * @param TX The pin that the TX line is attached to.
+     * @param RX The pin that the RX line is attached to.
+     * @param deviceName The name that you want your system to be identified as when you connect to it i.e. "Weimen's MAE433Robot"
+     * @param password A 4-digit numeric PIN that you want your device to connect with. It defaults to "1234".
+     * @param lineCallbackFunc The callback function that will be called once a newline character is encountered on the receiving data.
+     * The callback function takes as an argument a string containing the line that has been read.
+     * @remark The callback function is run within within an interrupt service routine, so it should be written to be safe for ISRs.
+     * @param charCallbackFunc A function that will be called once a new character has been read. It should return void and take as an argument
+     * the character that has been read.
+     * @remark The callback function is run within within an interrupt service routine, so it should be written to be safe for ISRs.
+     */
+    HC06Bluetooth(PinName TX, PinName RX, Baudrate baudrate = B115200, void (*lineCallbackFunc) (const char* readString, size_t strlen) = NULL, void (*charCallbackFunc) (char readChar) = NULL);
+    virtual ~HC06Bluetooth();
+    /**
+     * @brief Run the setup routine to configure the device name and the device pin.
+     * @remark: You only need to run this once during the entire time you have the module, since the device name and PIN are saved
+     * by the module itself! However, you may run the function again if you would like to change the deviceName or PIN.
+     * @param deviceName The name of the device, as a string. It must only contain alphanumeric characters - no spaces allowed.
+     * @param PIN The device PIN.
+     */
+    void runSetup(std::string deviceName, std::string PIN = "1234");
+    /**
+     * @brief Print information in buffer to the output.
+     * @param buffer A null-terminated buffer containing the data you want to send.
+     */
+    void print(const char *buffer);
+    /**
+     * @brief Print information in buffer to the output followed by a newline
+     * @param buffer A null-terminated buffer containing the data you want to send.
+     */
+    void println(const char *buffer);
+    /**
+     * @brief Print a character to output.
+     * @param char The character you want to print to output.
+     */
+    void print(char c);
 
-void HC06Bluetooth::receiveByteISR() {
-    while(btSerialObj.readable()) {
-        // Get the character from the input.
-        char receivedChar = btSerialObj.getc();
-
-        // Call the character callback function if it is not null.
-        if (charCallbackFunc != NULL) {
-            charCallbackFunc(receivedChar);
-        }
+private:
+    RawSerial btSerialObj;
+    Baudrate baudrate;
+    void receiveByteISR();
+    /// Pointer to a callback function the client provides when a line is received.
+    void (*lineCallbackFunc) (const char*, size_t strlen);
+    /// Pointer to a callback function the client provides when a character is received.
+    void (*charCallbackFunc) (char);
+    char dataReceivedBuffer[dataBufferSize];
+    int32_t dataReceivedBufferPos;
+    char dataReceivedBufferCopy[dataBufferSize];
+};
 
-        if (lineCallbackFunc != NULL) {
-            // If the character is a newline or carriage return, then call the line callback function.
-            if ((receivedChar == '\n') || (receivedChar == '\r')) {
-                // Terminate the buffer with a null character, since that is what strings end with.
-                receivedChar = '\0';
-                dataReceivedBuffer[dataReceivedBufferPos] = receivedChar;
-                dataReceivedBufferPos++;
-                // Copy data from the buffer to a copy.
-                std::copy(dataReceivedBuffer, dataReceivedBuffer + dataReceivedBufferPos, dataReceivedBufferCopy);
-                // Call the callback function.
-                if (lineCallbackFunc != NULL) {
-                    lineCallbackFunc((const char*)dataReceivedBuffer, dataReceivedBufferPos);
-                }
-                // Reset the buffer position.
-                dataReceivedBufferPos = 0;
-            }
-            // Otherwise, just place it in the buffer and move on.
-            else {
-                if (dataReceivedBufferPos < dataBufferSize) {
-                    dataReceivedBuffer[dataReceivedBufferPos] = receivedChar;
-                    dataReceivedBufferPos++;
-                }
-            }
-        }
-    }
-}
-
+#endif /* HC06BLUETOOTH_H_ */