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

Dependents:   DISCO-F746NG_rtos_test MbedTableControl

HC06Bluetooth.cpp

Committer:
Electrotiger
Date:
2016-08-02
Revision:
11:aeb8c5c27111
Parent:
10:b0a0a82a9ff5
Child:
12:5ba022adbbfb

File content as of revision 11:aeb8c5c27111:

/*
 * HC06Bluetooth.cpp
 *
 *  Created on: Jun 4, 2016
 *      Author: Developer
 */

#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.
enum Baudrate {B1200, B2400, B4800, B9600, B19200, B38400, B57600, B115200, B230400, B460800, B921600, B1382400, END};
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, void (*lineCallbackFunc) (const char* readString, size_t strlen), void (*charCallbackFunc) (char readChar))
: btSerialObj(TX, RX), lineCallbackFunc(lineCallbackFunc), charCallbackFunc(charCallbackFunc) {
    btSerialObj.baud(115200);

    // 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 (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[B115200]);
    btSerialObj.baud(BaudValue[B115200]);
    // Wait for the 8 character reply "OK115200"
    for(numCharsReceived = 0 ; numCharsReceived < BaudATReplyLength[B115200]; numCharsReceived++) {
        //while(!btSerialObj.readable());
        btSerialObj.getc();
    }

    // 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();
    }

    //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();
    }
    // Reattach the interrupt.
    btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR);
}

HC06Bluetooth::~HC06Bluetooth() {
    // TODO Auto-generated destructor stub
}

void HC06Bluetooth::print(const char* buffer) {
    btSerialObj.puts(buffer);
}

void HC06Bluetooth::println(const char* buffer) {
    btSerialObj.puts(buffer);
    btSerialObj.putc('\n');
}

void HC06Bluetooth::print(char c) {
    btSerialObj.putc(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);
        }

        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;
                // 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++;
                }
            }
        }
    }
}