Driver for the JY-MCU v1.06 HC-06 Bluetooth module.
Dependents: DISCO-F746NG_rtos_test MbedTableControl
HC06Bluetooth.cpp@21:cce827364df1, 2016-08-08 (annotated)
- Committer:
- Weimen Li
- Date:
- Mon Aug 08 19:48:19 2016 -0400
- Revision:
- 21:cce827364df1
- Parent:
- 20:13283edd1aba
Converted std::queue to RTOS's Queue to pass information from receivedByteISR to receivedByteThread, as std::queue is not ISR-safe.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Electrotiger | 0:3ab5e47dde1e | 1 | /* |
Electrotiger | 0:3ab5e47dde1e | 2 | * HC06Bluetooth.cpp |
Electrotiger | 0:3ab5e47dde1e | 3 | * |
Electrotiger | 0:3ab5e47dde1e | 4 | * Created on: Jun 4, 2016 |
Electrotiger | 0:3ab5e47dde1e | 5 | * Author: Developer |
Electrotiger | 0:3ab5e47dde1e | 6 | */ |
Electrotiger | 0:3ab5e47dde1e | 7 | |
Electrotiger | 10:b0a0a82a9ff5 | 8 | #include <HC06Bluetooth.h> |
Weimen Li |
20:13283edd1aba | 9 | #include "rtos.h" |
Electrotiger | 0:3ab5e47dde1e | 10 | |
Electrotiger | 9:3e23f3f615f2 | 11 | /* Static methods used to help configure the Baudrate. */ |
Electrotiger | 8:14bf9b541f9a | 12 | |
Electrotiger | 9:3e23f3f615f2 | 13 | // WARNING: DO NOT CHANGE THESE VALUES, AS THEY ARE USED TO INDEX INTO AN ARRAY FOR IMPLEMENTATION. |
Electrotiger | 9:3e23f3f615f2 | 14 | 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"}; |
Electrotiger | 9:3e23f3f615f2 | 15 | const int32_t BaudATReplyLength[] = {6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 8, 9}; |
Electrotiger | 9:3e23f3f615f2 | 16 | //const char* BaudATReplyPattern[] = {"OK1200", "OK2400", "OK4800","OK9600","OK19200","OK38400","OK57600","OK115200","OK230400","OK460800","OK921600","OK1382400"}; |
Electrotiger | 9:3e23f3f615f2 | 17 | const int32_t BaudValue[] = {1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600, 1382400}; |
Electrotiger | 8:14bf9b541f9a | 18 | |
Electrotiger | 9:3e23f3f615f2 | 19 | /* HC06 Bluetooth Class Implementation: */ |
Electrotiger | 12:5ba022adbbfb | 20 | HC06Bluetooth::HC06Bluetooth(PinName TX, PinName RX, Baudrate baudrate, void (*lineCallbackFunc) (const char* readString, size_t strlen), void (*charCallbackFunc) (char readChar)) |
Weimen Li |
20:13283edd1aba | 21 | : btSerialObj(TX, RX), baudrate(baudrate), receiveByteThreadObj(osPriorityRealtime), lineCallbackFunc(lineCallbackFunc), charCallbackFunc(charCallbackFunc) |
Weimen Li |
18:85c0f6580cd8 | 22 | { |
Electrotiger | 13:5768b18a1289 | 23 | btSerialObj.baud(BaudValue[baudrate]); |
Electrotiger | 8:14bf9b541f9a | 24 | |
Electrotiger | 8:14bf9b541f9a | 25 | // Set the interrupt to be called when a byte is received. |
Weimen Li |
18:85c0f6580cd8 | 26 | if ((lineCallbackFunc != NULL) || (charCallbackFunc != NULL)) |
Weimen Li |
18:85c0f6580cd8 | 27 | { |
Electrotiger | 8:14bf9b541f9a | 28 | btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR); |
Weimen Li |
20:13283edd1aba | 29 | receiveByteThreadObj.start(this, &HC06Bluetooth::receiveByteThread); |
Electrotiger | 8:14bf9b541f9a | 30 | } |
Electrotiger | 8:14bf9b541f9a | 31 | } |
Electrotiger | 8:14bf9b541f9a | 32 | |
Weimen Li |
18:85c0f6580cd8 | 33 | void HC06Bluetooth::runSetup(std::string deviceName, std::string PIN) |
Weimen Li |
18:85c0f6580cd8 | 34 | { |
Electrotiger | 8:14bf9b541f9a | 35 | int numCharsReceived = 0; |
Electrotiger | 9:3e23f3f615f2 | 36 | // Detatch the interrupt. |
Electrotiger | 9:3e23f3f615f2 | 37 | btSerialObj.attach(NULL); |
Electrotiger | 9:3e23f3f615f2 | 38 | /* Sweep through a list of Baud rates until we find the one that the device has previously been set to. */ |
Electrotiger | 13:5768b18a1289 | 39 | bool baudFound = false; |
Electrotiger | 9:3e23f3f615f2 | 40 | Timer timeOut; |
Electrotiger | 9:3e23f3f615f2 | 41 | timeOut.start(); |
Electrotiger | 9:3e23f3f615f2 | 42 | // For every baud rate in the list: |
Weimen Li |
18:85c0f6580cd8 | 43 | for (volatile int i = 0; (i < END) && (!baudFound); i++) |
Weimen Li |
18:85c0f6580cd8 | 44 | { |
Electrotiger | 9:3e23f3f615f2 | 45 | // Set the communication baud rate to it. |
Electrotiger | 9:3e23f3f615f2 | 46 | btSerialObj.baud(BaudValue[i]); |
Electrotiger | 9:3e23f3f615f2 | 47 | // Send the test command "AT" to the device. |
Electrotiger | 9:3e23f3f615f2 | 48 | btSerialObj.puts("AT"); |
Electrotiger | 9:3e23f3f615f2 | 49 | // While the time out has not been reached: |
Weimen Li |
18:85c0f6580cd8 | 50 | for(timeOut.reset(); timeOut.read_ms() < 1000; ) |
Weimen Li |
18:85c0f6580cd8 | 51 | { |
Electrotiger | 9:3e23f3f615f2 | 52 | // If the serial object is readable, make sure the read character matches the reply string "OK". |
Weimen Li |
18:85c0f6580cd8 | 53 | if (btSerialObj.readable() && !baudFound) |
Weimen Li |
18:85c0f6580cd8 | 54 | { |
Weimen Li |
18:85c0f6580cd8 | 55 | baudFound = true; |
Weimen Li |
18:85c0f6580cd8 | 56 | break; |
Electrotiger | 9:3e23f3f615f2 | 57 | } |
Electrotiger | 9:3e23f3f615f2 | 58 | } |
Electrotiger | 9:3e23f3f615f2 | 59 | } |
Electrotiger | 9:3e23f3f615f2 | 60 | // Flush whatever's in the input buffer. |
Weimen Li |
18:85c0f6580cd8 | 61 | while(btSerialObj.readable()) |
Weimen Li |
18:85c0f6580cd8 | 62 | { |
Electrotiger | 9:3e23f3f615f2 | 63 | btSerialObj.getc(); |
Electrotiger | 9:3e23f3f615f2 | 64 | } |
Electrotiger | 9:3e23f3f615f2 | 65 | //Overwrite the Baud rate to 115200. |
Electrotiger | 12:5ba022adbbfb | 66 | btSerialObj.puts(BaudATString[baudrate]); |
Electrotiger | 12:5ba022adbbfb | 67 | btSerialObj.baud(BaudValue[baudrate]); |
Electrotiger | 8:14bf9b541f9a | 68 | // Wait for the 8 character reply "OK115200" |
Weimen Li |
18:85c0f6580cd8 | 69 | for(numCharsReceived = 0 ; numCharsReceived < BaudATReplyLength[baudrate]; numCharsReceived++) |
Weimen Li |
18:85c0f6580cd8 | 70 | { |
Electrotiger | 9:3e23f3f615f2 | 71 | //while(!btSerialObj.readable()); |
Electrotiger | 12:5ba022adbbfb | 72 | //btSerialObj.getc(); |
Electrotiger | 8:14bf9b541f9a | 73 | } |
Electrotiger | 12:5ba022adbbfb | 74 | wait_ms(1000); |
Electrotiger | 8:14bf9b541f9a | 75 | |
Electrotiger | 0:3ab5e47dde1e | 76 | // Set the name of the device. |
Electrotiger | 8:14bf9b541f9a | 77 | btSerialObj.puts(("AT+NAME" + deviceName.substr(0,20)).c_str()); |
Electrotiger | 8:14bf9b541f9a | 78 | // Wait for the 6 character reply "OKname" |
Weimen Li |
18:85c0f6580cd8 | 79 | for(numCharsReceived = 0 ; numCharsReceived < 6; numCharsReceived++) |
Weimen Li |
18:85c0f6580cd8 | 80 | { |
Electrotiger | 12:5ba022adbbfb | 81 | //while(!btSerialObj.readable()); |
Electrotiger | 12:5ba022adbbfb | 82 | //btSerialObj.getc(); |
Electrotiger | 8:14bf9b541f9a | 83 | } |
Electrotiger | 12:5ba022adbbfb | 84 | wait_ms(1000); |
Electrotiger | 8:14bf9b541f9a | 85 | |
Electrotiger | 8:14bf9b541f9a | 86 | //Set the password of the device. |
Electrotiger | 8:14bf9b541f9a | 87 | btSerialObj.puts(("AT+PIN" + PIN.substr(0, 4)).c_str()); |
Electrotiger | 8:14bf9b541f9a | 88 | // Wait for the 8 character reply "OKsetpin" |
Weimen Li |
18:85c0f6580cd8 | 89 | for(numCharsReceived = 0 ; numCharsReceived < 8; numCharsReceived++) |
Weimen Li |
18:85c0f6580cd8 | 90 | { |
Electrotiger | 12:5ba022adbbfb | 91 | //while(!btSerialObj.readable()); |
Electrotiger | 12:5ba022adbbfb | 92 | //btSerialObj.getc(); |
Electrotiger | 3:ee17212e838e | 93 | } |
Electrotiger | 12:5ba022adbbfb | 94 | wait_ms(1000); |
Electrotiger | 9:3e23f3f615f2 | 95 | // Reattach the interrupt. |
Electrotiger | 9:3e23f3f615f2 | 96 | btSerialObj.attach(this, &HC06Bluetooth::receiveByteISR); |
Electrotiger | 0:3ab5e47dde1e | 97 | } |
Electrotiger | 0:3ab5e47dde1e | 98 | |
Weimen Li |
18:85c0f6580cd8 | 99 | HC06Bluetooth::~HC06Bluetooth() |
Weimen Li |
18:85c0f6580cd8 | 100 | { |
Electrotiger | 0:3ab5e47dde1e | 101 | // TODO Auto-generated destructor stub |
Electrotiger | 0:3ab5e47dde1e | 102 | } |
Electrotiger | 0:3ab5e47dde1e | 103 | |
Weimen Li |
18:85c0f6580cd8 | 104 | void HC06Bluetooth::print(const char* buffer) |
Weimen Li |
18:85c0f6580cd8 | 105 | { |
Weimen Li |
18:85c0f6580cd8 | 106 | // TODO: Code hangs if buffer is too long! Not sure why. |
Electrotiger | 6:5ba0038a7a9a | 107 | btSerialObj.puts(buffer); |
Electrotiger | 6:5ba0038a7a9a | 108 | } |
Electrotiger | 6:5ba0038a7a9a | 109 | |
Weimen Li |
18:85c0f6580cd8 | 110 | void HC06Bluetooth::println(const char* buffer) |
Weimen Li |
18:85c0f6580cd8 | 111 | { |
Electrotiger | 10:b0a0a82a9ff5 | 112 | btSerialObj.puts(buffer); |
Electrotiger | 10:b0a0a82a9ff5 | 113 | btSerialObj.putc('\n'); |
Electrotiger | 10:b0a0a82a9ff5 | 114 | } |
Electrotiger | 10:b0a0a82a9ff5 | 115 | |
Weimen Li |
18:85c0f6580cd8 | 116 | void HC06Bluetooth::print(char c) |
Weimen Li |
18:85c0f6580cd8 | 117 | { |
Electrotiger | 8:14bf9b541f9a | 118 | btSerialObj.putc(c); |
Electrotiger | 8:14bf9b541f9a | 119 | } |
Electrotiger | 8:14bf9b541f9a | 120 | |
Weimen Li |
18:85c0f6580cd8 | 121 | void HC06Bluetooth::receiveByteISR() |
Weimen Li |
18:85c0f6580cd8 | 122 | { |
Weimen Li |
18:85c0f6580cd8 | 123 | // Get all available characters in the input and place them in the buffer. |
Electrotiger | 8:14bf9b541f9a | 124 | |
Weimen Li |
18:85c0f6580cd8 | 125 | while(btSerialObj.readable()) |
Weimen Li |
18:85c0f6580cd8 | 126 | { |
Weimen Li |
21:cce827364df1 | 127 | dataReceivedBuffer.put((char*) btSerialObj.getc()); |
Weimen Li |
18:85c0f6580cd8 | 128 | } |
Weimen Li |
20:13283edd1aba | 129 | } |
Weimen Li |
18:85c0f6580cd8 | 130 | |
Weimen Li |
20:13283edd1aba | 131 | void HC06Bluetooth::receiveByteThread() |
Weimen Li |
20:13283edd1aba | 132 | { |
Weimen Li |
18:85c0f6580cd8 | 133 | // Now that all characters have been read, process them. |
Weimen Li |
21:cce827364df1 | 134 | char receivedChar; |
Weimen Li |
20:13283edd1aba | 135 | while(true) |
Weimen Li |
18:85c0f6580cd8 | 136 | { |
Weimen Li |
21:cce827364df1 | 137 | receivedChar = (uint32_t) dataReceivedBuffer.get().value.p; |
Weimen Li |
21:cce827364df1 | 138 | // Call the character callback function if it is not null. |
Weimen Li |
21:cce827364df1 | 139 | if (charCallbackFunc != NULL) charCallbackFunc(receivedChar); |
Weimen Li |
21:cce827364df1 | 140 | |
Weimen Li |
21:cce827364df1 | 141 | if (lineCallbackFunc != NULL) |
Weimen Li |
20:13283edd1aba | 142 | { |
Weimen Li |
21:cce827364df1 | 143 | // If the character is a newline or carriage return, then call the line callback function. |
Weimen Li |
21:cce827364df1 | 144 | if ((receivedChar == '\n') || (receivedChar == '\r')) |
Weimen Li |
18:85c0f6580cd8 | 145 | { |
Weimen Li |
21:cce827364df1 | 146 | // Clear whatever was in the toClient buffer before. |
Weimen Li |
21:cce827364df1 | 147 | dataReceivedToClient.clear(); |
Weimen Li |
21:cce827364df1 | 148 | // Copy everything from the queue to the client buffer. |
Weimen Li |
21:cce827364df1 | 149 | while(!dataReceivedBufferCopy.empty()) |
Weimen Li |
20:13283edd1aba | 150 | { |
Weimen Li |
21:cce827364df1 | 151 | dataReceivedToClient.push_back(dataReceivedBufferCopy.front()); |
Weimen Li |
21:cce827364df1 | 152 | dataReceivedBufferCopy.pop(); |
Weimen Li |
21:cce827364df1 | 153 | } |
Weimen Li |
21:cce827364df1 | 154 | // Null-terminate the string. |
Weimen Li |
21:cce827364df1 | 155 | dataReceivedToClient.push_back('\0'); |
Weimen Li |
18:85c0f6580cd8 | 156 | |
Weimen Li |
21:cce827364df1 | 157 | // Call the callback function with the toClient buffer. |
Weimen Li |
21:cce827364df1 | 158 | lineCallbackFunc(&dataReceivedToClient[0], dataReceivedToClient.size()); |
Weimen Li |
21:cce827364df1 | 159 | } |
Weimen Li |
18:85c0f6580cd8 | 160 | |
Weimen Li |
21:cce827364df1 | 161 | // Otherwise, enqueue it in the copy. |
Weimen Li |
21:cce827364df1 | 162 | else |
Weimen Li |
21:cce827364df1 | 163 | { |
Weimen Li |
21:cce827364df1 | 164 | dataReceivedBufferCopy.push(receivedChar); |
Electrotiger | 10:b0a0a82a9ff5 | 165 | } |
Electrotiger | 1:026034717620 | 166 | } |
Electrotiger | 1:026034717620 | 167 | } |
Electrotiger | 2:7e0453895727 | 168 | } |
Electrotiger | 0:3ab5e47dde1e | 169 |