├── examples ├── HID_MOUSE_WHEEL │ └── HID_MOUSE_WHEEL.ino ├── HID_MOUSE │ └── HID_MOUSE.ino ├── SPP_SEND_REC_MSG │ └── SPP_SEND_REC_MSG.ino └── HID_KEYBOARD │ └── HID_KEYBOARD.ino ├── README.md ├── BPLib.h └── BPLib.cpp /examples/HID_MOUSE_WHEEL/HID_MOUSE_WHEEL.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Bluetooth Mouse Wheel - Example 3 | 4 | This example illustrated the use of the Bluetooth Mouse Wheel (Scrolling). 5 | 6 | */ 7 | 8 | #include 9 | 10 | BPLib BPMod; 11 | void setup(){ 12 | BPMod.begin(BP_MODE_HID,BP_HID_MOUSE); 13 | } 14 | 15 | void loop(){ 16 | delay(5000); 17 | for(signed int i=-5;i<5;i++){ 18 | BPMod.mouseWheel(i); 19 | delay(100); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /examples/HID_MOUSE/HID_MOUSE.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Bluetooth HID Mouse - Example 3 | 4 | This example illustrated how the library can be used to make mouse movements and clicks. 5 | 6 | */ 7 | 8 | #include 9 | 10 | BPLib BPMod; 11 | void setup(){ 12 | BPMod.begin(BP_MODE_HID,BP_HID_MOUSE); 13 | 14 | } 15 | 16 | void loop(){ 17 | delay(1000); 18 | for(signed int i=-127;i<127;i++){ 19 | BPMod.mouseMove(i,i); 20 | delay(100); 21 | } 22 | BPMod.mouseClick(BP_MOUSE_BTN_LEFT); 23 | } 24 | -------------------------------------------------------------------------------- /examples/SPP_SEND_REC_MSG/SPP_SEND_REC_MSG.ino: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Bluetooth SPP - example 4 | This example illustrates the use of the bluetooth serial protocol. 5 | 6 | */ 7 | 8 | 9 | #include 10 | 11 | BPLib BPMod; 12 | int count = 0; 13 | void setup(){ 14 | BPMod.begin(BP_MODE_SPP,BP_SPP_SPP); //Bluetooth Serial Mode 15 | BPMod.changeName("BlueNar_One"); //Change bluetooth name (appears on devices searching for BT) 16 | while(!BPMod.connected()){}; //BlueNar One only! Check if a connection is made 17 | } 18 | 19 | void loop(){ 20 | if(BPMod.connected()){ //BlueNar One only! if connected then proceed 21 | if(BPMod.available()>0){ //Check if data is available 22 | BPMod.readRaw(); //Read the data (just to empty the buffer) 23 | count++; 24 | BPMod.sendString("Count: "); //Send a string 25 | BPMod.sendInt(count); //Send a integer 26 | BPMod.sendChar('\n'); //Send character 27 | } 28 | } 29 | else{ 30 | while(!BPMod.connected()){}; //BlueNar One only! - If disconnected wait for a new connection 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | BPLib - Bluetooth SPP/HID Library 2 | ===== 3 | 4 | This library simplifies the communication protocol between the RN-42 (HID enabled) device and the atmega32u4. 5 | Some functions won't work on for example (Arduino(R) Leonardo) because there is some hardware mods between the module 6 | and the atmega32u4. One of these functions/statements is the "connected()" statement in the library. 7 | 8 | The library is written with arduino statements (like Serial.begin(), etc) inorder to make the code very 9 | simple/understandable/editable to a Arduino IDE newcomer. 10 | 11 | The library isn't complete, todo list: 12 | 13 | - Add, authorization mode: Toggle between an Open/Pin Locked connection. 14 | - Add, more keyboard scan codes 15 | - Add, software connection check (to support Arduino Uno/Leonardo/Mega) 16 | 17 | Working with following boards: 18 | - BlueNar One 19 | - Arduino(R) Leonardo (One function doesn't work, everything else AOK) 20 | 21 | The library will work with the following BT protocols: 22 | - SPP (Bluetooth Serial) 23 | - HID (Bluetooth Human Interface Device) 24 | - Keyboard 25 | - Mouse 26 | - Combo (Keyboard + Mouse) 27 | - Joystick 28 | - Gamepad 29 | 30 | For example code, see the examples directory 31 | -------------------------------------------------------------------------------- /examples/HID_KEYBOARD/HID_KEYBOARD.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Bluetooth HID Keyboard - example 3 | This example illustrates the different ways you can send keys/keystrokes with the HID keyboard protocol. 4 | This sketch will print the following on the recieving device: lesab (mirrored basel). 5 | */ 6 | 7 | 8 | #include 9 | 10 | BPLib BPMod; 11 | void setup(){ 12 | BPMod.begin(BP_MODE_HID,BP_HID_KEYBOARD); //Begin HID Mode with HID KEYBOARD AS TYPE 13 | 14 | } 15 | 16 | void loop(){ 17 | delay(5000); //Delay 5 seconds between each loop (Not nec.) 18 | BPMod.sendString("b"); //Send a string (will be recieved as keystroke) 19 | BPMod.keyboardPress(BP_KEY_LEFT_ARROW,BP_MOD_NOMOD); //Send Scan code (KEY, MODEFIER key) 20 | BPMod.keyboardReleaseAll(); //Release all keys 21 | BPMod.sendString("a"); 22 | BPMod.keyboardPress(BP_KEY_LEFT_ARROW,BP_MOD_NOMOD); 23 | BPMod.keyboardReleaseAll(); 24 | BPMod.sendString("s"); 25 | BPMod.keyboardPress(BP_KEY_LEFT_ARROW,BP_MOD_NOMOD); 26 | BPMod.keyboardReleaseAll(); 27 | BPMod.sendString("e"); 28 | BPMod.keyboardPress(BP_KEY_LEFT_ARROW,BP_MOD_NOMOD); 29 | BPMod.keyboardReleaseAll(); 30 | BPMod.sendString("l"); 31 | BPMod.keyboardPress(BP_KEY_LEFT_ARROW,BP_MOD_NOMOD); 32 | BPMod.keyboardReleaseAll(); 33 | } 34 | -------------------------------------------------------------------------------- /BPLib.h: -------------------------------------------------------------------------------- 1 | /* 2 | BPLib.h - Library for communication with RN-42 HID Bluetooth module 3 | Created by Basel Al-Rudainy, 6 april 2013. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | */ 15 | #ifndef BPLib_h 16 | #define BPLib_h 17 | 18 | #include "Arduino.h" 19 | 20 | //Bluetooth Modes 21 | #define BP_MODE_COMMAND "$$$" 22 | #define BP_MODE_EXITCOMMAND "---\r\n" 23 | #define BP_MODE_SPP "S~,0\r\n" 24 | #define BP_MODE_HID "S~,6\r\n" 25 | #define BP_MODE_AUTOCONNECT "SM,6\r\n" 26 | #define BP_MODE_MANUCONNECT "SM,4\r\n" 27 | #define BP_MODE_STATUS "SO,/#\r\n" 28 | 29 | //Bluetooth status messages 30 | #define BP_STAT_CMD "CMD\r\n" 31 | #define BP_STAT_END "END\r\n" 32 | #define BP_STAT_ACK "AOK\r\n" 33 | #define BP_STAT_REBOOT "Reboot!\r\n" 34 | //Bluetooth GET commands 35 | #define BP_GET_HID "GH\n" 36 | 37 | //Bluetooth system commands 38 | #define BP_REBOOT "R,1\r\n" 39 | #define BP_RECONNECT "C\r\n" 40 | #define BP_CHANGE_NAME "SN," 41 | //Bluetooth protocol types 42 | #define BP_SPP_SPP "AW\r\n" 43 | #define BP_HID_KEYBOARD "SH,0200\r\n" 44 | #define BP_HID_MOUSE "SH,0220\r\n" 45 | #define BP_HID_GAMEPAD "SH,0210\r\n" 46 | #define BP_HID_JOYSTICK "SH,0240\r\n" 47 | #define BP_HID_COMBO "SH,0230\r\n" 48 | 49 | // KEYBOARD Scan Codes 50 | #define BP_KEY_ENTER 0x28 //Enter 51 | #define BP_KEY_LEFT_ARROW 0x50 //Left arrow 52 | #define BP_KEY_DOWN_ARROW 0x51 //Down arrow 53 | #define BP_KEY_ENTER 0x28 //Enter 54 | #define BP_KEY_UP_ARROW 0x52 //Up arrow 55 | #define BP_KEY_ESCAPE 0x29 //Escape 56 | #define BP_KEY_CAPSLOCK 0x39 //CapsLock 57 | #define BP_KEY_SCROLLLOCK 0x47 //ScrollLock 58 | #define BP_KEY_BREAK_PAUSE 0x48 //Break-pause 59 | #define BP_KEY_NUMLOCK 0x53 //NumLock 60 | #define BP_KEY_TOGGLE_IPHONE_VIRTUAL_KEYBOARD 0x65 //Toggle iPhone Virtual Keyboard 61 | #define BP_KEY_LEFT_CONTROL 0xE0 //Left Control 62 | #define BP_KEY_LEFT_SHIFT 0xE1 //Left Shift 63 | #define BP_KEY_LEFT_ALT 0xE2 //Left Alt 64 | #define BP_KEY_LEFT_GUI 0xE3 //Left GUI 65 | #define BP_KEY_RIGHT_CONTROL 0xE4 //Right Control 66 | #define BP_KEY_RIGHT_SHIFT 0xE5 //Right Shift 67 | #define BP_KEY_RIGHT_ALT 0xE6 //Right Alt 68 | #define BP_KEY_RIGHT_GUI 0xE7 //Right GUI 69 | #define BP_KEY_F1 0x3A //F1 70 | #define BP_KEY_F2 0x3B //F2 71 | #define BP_KEY_F3 0x3C //F3 72 | #define BP_KEY_F4 0x3D //F4 73 | #define BP_KEY_F5 0x3E //F5 74 | #define BP_KEY_F6 0x3F //F6 75 | #define BP_KEY_F7 0x40 //F7 76 | #define BP_KEY_F8 0x41 //F8 77 | #define BP_KEY_F9 0x42 //F9 78 | #define BP_KEY_F10 0x43 //F10 79 | #define BP_KEY_F11 0x44 //F11 80 | #define BP_KEY_F12 0x45 //F12 81 | 82 | 83 | //KEYBOARD MODEFIER CODES 84 | #define BP_MOD_RIGHT_GUI (1<<7) 85 | #define BP_MOD_RIGHT_ALT (1<<6) 86 | #define BP_MOD_RIGHT_SHIFT (1<<5) 87 | #define BP_MOD_RIGHT_CTRL (1<<4) 88 | #define BP_MOD_LEFT_GUI (1<<3) 89 | #define BP_MOD_LEFT_ALT (1<<2) 90 | #define BP_MOD_LEFT_SHIFT (1<<1) 91 | #define BP_MOD_LEFT_CTRL (1<<0) 92 | #define BP_MOD_NOMOD 0x00 93 | 94 | //Mouse Codes 95 | #define BP_MOUSE_BTN_LEFT (1<<0) 96 | #define BP_MOUSE_BTN_RIGHT (1<<1) 97 | #define BP_MOUSE_BTN_MIDDLE (1<<2) 98 | 99 | //GAMEPAD/JOYSTICK BUTTON CODES 100 | //ST == First button combination (BTN0 to BTN7) 101 | #define BP_GAMEJOY_ST_BTN0 (1<<0) 102 | #define BP_GAMEJOY_ST_BTN1 (1<<1) 103 | #define BP_GAMEJOY_ST_BTN2 (1<<2) 104 | #define BP_GAMEJOY_ST_BTN3 (1<<3) 105 | #define BP_GAMEJOY_ST_BTN4 (1<<4) 106 | #define BP_GAMEJOY_ST_BTN5 (1<<5) 107 | #define BP_GAMEJOY_ST_BTN6 (1<<6) 108 | #define BP_GAMEJOY_ST_BTN7 (1<<7) 109 | #define BP_GAMEJOY_ST_NOBTN 0x00 110 | 111 | //ND = Second button combination (BTN0 to BTN7) 112 | #define BP_GAMEJOY_ND_BTN0 (1<<0) 113 | #define BP_GAMEJOY_ND_BTN1 (1<<1) 114 | #define BP_GAMEJOY_ND_BTN2 (1<<2) 115 | #define BP_GAMEJOY_ND_BTN3 (1<<3) 116 | #define BP_GAMEJOY_ND_BTN4 (1<<4) 117 | #define BP_GAMEJOY_ND_BTN5 (1<<5) 118 | #define BP_GAMEJOY_ND_BTN6 (1<<6) 119 | #define BP_GAMEJOY_ND_BTN7 (1<<7) 120 | #define BP_GAMEJOY_ND_NOBTN 0x00 121 | 122 | 123 | class BPLib 124 | { 125 | public: 126 | BPLib(); 127 | byte begin(char BP_Mode[], char BP_Type[]); 128 | byte sendCmd(char BP_CMD[]); 129 | void sendByte(byte rawData); 130 | void sendChar(char rawData); 131 | void sendInt(int rawData); 132 | void sendFloat(float rawData); 133 | void sendLong(long rawData); 134 | void sendString(char rawData[]); 135 | byte readRaw(); 136 | int available(); 137 | void keyboardPrint(char BP_MSG[]); 138 | void keyboardPress(byte BP_KEY,byte BP_MOD); 139 | void keyboardReleaseAll(); 140 | void mouseClick(byte BP_BUTTON); 141 | void mouseMove(signed int BP_X,signed int BP_Y); 142 | void mouseWheel(signed int BP_WHEEL); 143 | void mousePress(byte BP_BUTTON); 144 | void mouseReleaseAll(); 145 | void gameJoyPress(byte BP_ST_BTN, byte BP_ND_BTN); 146 | void gameJoyMove(signed int BP_X1,signed int BP_Y1,signed int BP_X2,signed int BP_Y2); 147 | void gameJoyReleaseAll(); 148 | byte connected(); 149 | byte changeName(char BP_NAME[]); 150 | private: 151 | byte get(char BP_STAT[], byte strlen); 152 | }; 153 | #endif 154 | -------------------------------------------------------------------------------- /BPLib.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | BPLib.cpp - Library for communication with RN-42 HID Bluetooth module 3 | Created by Basel Al-Rudainy, 6 april 2013. 4 | 5 | This library is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU Lesser General Public 7 | License as published by the Free Software Foundation; either 8 | version 2.1 of the License, or (at your option) any later version. 9 | 10 | This library is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | Lesser General Public License for more details. 14 | */ 15 | #include "Arduino.h" 16 | #include "BPLib.h" 17 | 18 | BPLib::BPLib(){ 19 | pinMode(7,INPUT); 20 | digitalWrite(7,LOW); 21 | } 22 | 23 | byte BPLib::begin(char BP_Mode[], char BP_Type[]) 24 | { 25 | Serial1.begin(115200); 26 | Serial1.print(BP_MODE_COMMAND); 27 | if (get(BP_STAT_CMD, (byte)5)!=1) { 28 | return (byte)0; 29 | }//if 30 | 31 | Serial1.print(BP_Mode); 32 | if (get(BP_STAT_ACK, (byte)5)!=1) { 33 | return (byte)0; 34 | }//if 35 | if(strcmp(BP_Type,BP_SPP_SPP)>0){ 36 | Serial1.print(BP_Type); 37 | if (get(BP_STAT_ACK, (byte)5)!=1) { 38 | return (byte)0; 39 | }//if 40 | } 41 | Serial1.print(BP_REBOOT); 42 | if (get(BP_STAT_REBOOT, (byte)9)!=1) { 43 | return (byte)0; 44 | }//if 45 | delay(1000); //Delay (Bluetooth boot-up) 46 | 47 | return (byte)1; 48 | } 49 | 50 | byte BPLib::sendCmd(char BP_CMD[]) 51 | { 52 | Serial1.print(BP_MODE_COMMAND); 53 | if (get(BP_STAT_CMD, (byte)5)!=1) { 54 | return (byte)0; 55 | }//if 56 | Serial1.print(BP_CMD); 57 | if (get(BP_STAT_ACK, (byte)5)!=1) { 58 | return (byte)0; 59 | }//if 60 | Serial1.print(BP_MODE_EXITCOMMAND); 61 | if (get(BP_STAT_END, (byte)5)!=1) { 62 | return (byte)0; 63 | }//if 64 | return (byte)1; 65 | } 66 | 67 | byte BPLib::readRaw(){ 68 | return Serial1.read(); 69 | } 70 | int BPLib::available(){ 71 | return Serial1.available(); 72 | } 73 | 74 | byte BPLib::get(char BP_STAT[],byte strlen) 75 | { 76 | char buffer[strlen + 1]; 77 | while (Serial1.available() <= (strlen-1)) {}; 78 | int count = 0; 79 | while (Serial1.available() > 0) { 80 | buffer[count]=(char)Serial1.read(); 81 | count++; 82 | }//while 83 | buffer[strlen]=0; 84 | //Serial.print(buffer);//DEBUG 85 | if (strcmp(buffer,BP_STAT)==0) { 86 | return (byte)1; 87 | }//if 88 | else { 89 | return (byte)0; 90 | }//else 91 | }//get 92 | 93 | 94 | void BPLib::keyboardPress(byte BP_KEY,byte BP_MOD){ 95 | Serial1.write((byte)0xFD); //Start HID Report 96 | Serial1.write((byte)0x9); //Length byte 97 | Serial1.write((byte)0x1); //Descriptor byte 98 | Serial1.write(BP_MOD); //Modifier byte 99 | Serial1.write((byte)0x00); //- 100 | Serial1.write(BP_KEY); //Send KEY 101 | for(byte i = 0;i<5;i++){ //Send five zero bytes 102 | Serial1.write((byte)0x00); 103 | } 104 | 105 | } 106 | 107 | void BPLib::keyboardReleaseAll(){ 108 | keyboardPress((byte)0x00,BP_MOD_NOMOD); 109 | } 110 | 111 | void BPLib::mouseClick(byte BP_BUTTON){ 112 | mousePress(BP_BUTTON); 113 | mouseReleaseAll(); 114 | } 115 | void BPLib::mouseMove(signed int BP_X,signed int BP_Y){ 116 | Serial1.write((byte)0xFD); //Start HID Report 117 | Serial1.write((byte)0x5); //Length byte 118 | Serial1.write((byte)0x2); //Descriptor byte 119 | Serial1.write((byte)0x00); //Button byte 120 | Serial1.write(BP_X); //(-127 to 127) 121 | Serial1.write(BP_Y); //(-127 to 127) 122 | Serial1.write((byte)0x00); 123 | 124 | } 125 | void BPLib::mousePress(byte BP_BUTTON){ 126 | Serial1.write((byte)0xFD); //Start HID Report 127 | Serial1.write((byte)0x5); //Length byte 128 | Serial1.write((byte)0x2); //Descriptor byte 129 | Serial1.write(BP_BUTTON); //Button byte 130 | for(byte i = 0;i<3;i++){ //Send three zero bytes 131 | Serial1.write((byte)0x00); 132 | } 133 | } 134 | 135 | void BPLib::mouseReleaseAll(){ 136 | Serial1.write((byte)0xFD); //Start HID Report 137 | Serial1.write((byte)0x5); //Length byte 138 | Serial1.write((byte)0x2); //Descriptor byte 139 | for(byte i = 0;i<4;i++){ //Send four zero bytes 140 | Serial1.write((byte)0x00); 141 | } 142 | } 143 | 144 | void BPLib::mouseWheel(signed int BP_WHEEL){ 145 | Serial1.write((byte)0xFD); //Start HID Report 146 | Serial1.write((byte)0x5); //Length byte 147 | Serial1.write((byte)0x2); //Descriptor byte 148 | for(byte i = 0;i<3;i++){ //Send three zero bytes 149 | Serial1.write((byte)0x00); 150 | } 151 | Serial1.write(BP_WHEEL); //Wheel byte (-127 to 127) 152 | } 153 | 154 | byte BPLib::changeName(char BP_NAME[]){ 155 | Serial1.print(BP_MODE_COMMAND); 156 | if (get(BP_STAT_CMD, (byte)5)!=1) { 157 | return (byte)0; 158 | }//if 159 | Serial1.print(BP_CHANGE_NAME); 160 | Serial1.print(BP_NAME); 161 | Serial1.print(F("\r\n")); 162 | if (get(BP_STAT_ACK, (byte)5)!=1) { 163 | return (byte)0; 164 | }//if 165 | Serial1.print(BP_MODE_EXITCOMMAND); 166 | if (get(BP_STAT_END, (byte)5)!=1) { 167 | return (byte)0; 168 | }//if 169 | return (byte)1; 170 | 171 | } 172 | 173 | 174 | void BPLib::sendByte(byte rawData){ 175 | Serial1.print(rawData); 176 | } 177 | void BPLib::sendChar(char rawData){ 178 | Serial1.print(rawData); 179 | } 180 | void BPLib::sendInt(int rawData){ 181 | Serial1.print(rawData); 182 | } 183 | void BPLib::sendFloat(float rawData){ 184 | Serial1.print(rawData); 185 | } 186 | void BPLib::sendLong(long rawData){ 187 | Serial1.print(rawData); 188 | } 189 | void BPLib::sendString(char rawData[]){ 190 | Serial1.print(rawData); 191 | } 192 | 193 | void BPLib::gameJoyPress(byte BP_ST_BTN, byte BP_ND_BTN){ 194 | Serial1.write((byte)0xFD); //Start HID Report 195 | Serial1.write((byte)0x6); //Length byte 196 | Serial1.write((byte)BP_ST_BTN); //First Button byte 197 | Serial1.write((byte)BP_ND_BTN); //Second Button byte 198 | for(byte i = 0;i<4;i++){ //Send four zero bytes 199 | Serial1.write((byte)0x00); 200 | } 201 | } 202 | void BPLib::gameJoyMove(signed int BP_X1,signed int BP_Y1,signed int BP_X2,signed int BP_Y2){ 203 | Serial1.write((byte)0xFD); //Start HID Report 204 | Serial1.write((byte)0x6); //Length byte 205 | Serial1.write((byte)BP_GAMEJOY_ST_NOBTN); //First Button byte 206 | Serial1.write((byte)BP_GAMEJOY_ND_NOBTN); //Second Button byte 207 | Serial1.write(BP_X1 & 0xFF); //First X coordinate 208 | Serial1.write(BP_Y1 & 0xFF); //First Y coordinate 209 | Serial1.write(BP_X2 & 0xFF); //Second X coordinate 210 | Serial1.write(BP_Y2 & 0xFF); //Second Y coordinate 211 | } 212 | void BPLib::gameJoyReleaseAll(){ 213 | gameJoyPress(BP_GAMEJOY_ST_NOBTN, BP_GAMEJOY_ND_NOBTN); 214 | } 215 | 216 | byte BPLib::connected(){ 217 | return digitalRead(7); 218 | } 219 | --------------------------------------------------------------------------------