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

Dependents:   DISCO-F746NG_rtos_test MbedTableControl

Revision:
18:85c0f6580cd8
Parent:
17:63261635b153
Child:
20:13283edd1aba
--- a/HC06Bluetooth.cpp	Wed Aug 03 19:27:59 2016 +0000
+++ b/HC06Bluetooth.cpp	Fri Aug 05 12:04:08 2016 -0400
@@ -18,16 +18,19 @@
 
 /* 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(TX, RX), baudrate(baudrate), lineCallbackFunc(lineCallbackFunc), charCallbackFunc(charCallbackFunc)
+{
     btSerialObj.baud(BaudValue[baudrate]);
 
     // Set the interrupt to be called when a byte is received.
-    if ((lineCallbackFunc != NULL) || (charCallbackFunc != NULL)) {
+    if ((lineCallbackFunc != NULL) || (charCallbackFunc != NULL))
+    {
         btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR);
     }
 }
 
-void HC06Bluetooth::runSetup(std::string deviceName, std::string PIN) {
+void HC06Bluetooth::runSetup(std::string deviceName, std::string PIN)
+{
     int numCharsReceived = 0;
     // Detatch the interrupt.
     btSerialObj.attach(NULL);
@@ -36,29 +39,34 @@
     Timer timeOut;
     timeOut.start();
     // For every baud rate in the list:
-    for (volatile int i = 0; (i < END) && (!baudFound); i++) {
+    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; ) {
+        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;
+            if (btSerialObj.readable() && !baudFound)
+            {
+                baudFound = true;
+                break;
             }
         }
     }
     // Flush whatever's in the input buffer.
-    while(btSerialObj.readable()) {
+    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++) {
+    for(numCharsReceived = 0 ; numCharsReceived < BaudATReplyLength[baudrate]; numCharsReceived++)
+    {
         //while(!btSerialObj.readable());
         //btSerialObj.getc();
     }
@@ -67,7 +75,8 @@
     // 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++) {
+    for(numCharsReceived = 0 ; numCharsReceived < 6; numCharsReceived++)
+    {
         //while(!btSerialObj.readable());
         //btSerialObj.getc();
     }
@@ -76,7 +85,8 @@
     //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++) {
+    for(numCharsReceived = 0 ; numCharsReceived < 8; numCharsReceived++)
+    {
         //while(!btSerialObj.readable());
         //btSerialObj.getc();
     }
@@ -85,56 +95,67 @@
     btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR);
 }
 
-HC06Bluetooth::~HC06Bluetooth() {
+HC06Bluetooth::~HC06Bluetooth()
+{
     // TODO Auto-generated destructor stub
 }
 
-void HC06Bluetooth::print(const char* buffer) {
-   // TODO: Code hangs if buffer is too long! Not sure why.
+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) {
+void HC06Bluetooth::println(const char* buffer)
+{
     btSerialObj.puts(buffer);
     btSerialObj.putc('\n');
 }
 
-void HC06Bluetooth::print(char c) {
+void HC06Bluetooth::print(char c)
+{
     btSerialObj.putc(c);
 }
 
-void HC06Bluetooth::receiveByteISR() {
-    while(btSerialObj.readable()) {
-        // Get the character from the input.
-        char receivedChar = btSerialObj.getc();
+void HC06Bluetooth::receiveByteISR()
+{
+    // Get all available characters in the input and place them in the buffer.
 
+    while(btSerialObj.readable())
+    {
+        dataReceivedBuffer.push(btSerialObj.getc());
+    }
+
+    // Now that all characters have been read, process them.
+    while(!dataReceivedBuffer.empty())
+    {
+       char receivedChar = dataReceivedBuffer.front();
+       dataReceivedBuffer.pop();
         // Call the character callback function if it is not null.
-        if (charCallbackFunc != NULL) {
-            charCallbackFunc(receivedChar);
-        }
+        if (charCallbackFunc != NULL) charCallbackFunc(receivedChar);
 
-        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;
+        if (lineCallbackFunc != NULL)
+        {
+           // If the character is a newline or carriage return, then call the line callback function.
+           if ((receivedChar == '\n') || (receivedChar == '\r'))
+            {
+               // Clear whatever was in the toClient buffer before.
+               dataReceivedToClient.clear();
+               // Copy everything from the queue to the client buffer.
+               while(!dataReceivedBufferCopy.empty()) {
+                  dataReceivedToClient.push_back(dataReceivedBufferCopy.front());
+                  dataReceivedBufferCopy.pop();
+               }
+               // Null-terminate the string.
+               dataReceivedToClient.push_back('\0');
+
+               // Call the callback function with the toClient buffer.
+               lineCallbackFunc(&dataReceivedToClient[0], dataReceivedToClient.size());
             }
-            // Otherwise, just place it in the buffer and move on.
+
+            // Otherwise, enqueue it in the copy.
             else {
-                if (dataReceivedBufferPos < dataBufferSize) {
-                    dataReceivedBuffer[dataReceivedBufferPos] = receivedChar;
-                    dataReceivedBufferPos++;
-                }
+               dataReceivedBufferCopy.push(receivedChar);
             }
         }
     }