Driver for the JY-MCU v1.06 HC-06 Bluetooth module.
Dependents: DISCO-F746NG_rtos_test MbedTableControl
Diff: HC06Bluetooth.h
- 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_ */