Advertisement
joric

Arduino_RN42_KBD_Test.ino

Jun 3rd, 2016
261
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.64 KB | None | 0 0
  1. // http://ww1.microchip.com/downloads/en/DeviceDoc/bluetooth_cr_UG-v1.0r.pdf RN-42 reference
  2. // http://cdn.sparkfun.com/datasheets/Wireless/Bluetooth/RN-HID-User-Guide-v1.0r.pdf keycodes
  3. // pushbutton attached to GND/D2
  4. // HC-06 pins are connected as RXD to TX0, TXD to RX1
  5.  
  6. #define BT Serial1
  7.  
  8. void keyCommand(uint8_t modifiers, uint8_t key1, uint8_t key2 = 0, uint8_t key3 = 0, uint8_t key4 = 0, uint8_t key5 = 0, uint8_t key6 = 0) {
  9.   BT.write(0xFD);       // our command
  10.   BT.write(0x09);       // size
  11.   BT.write(0x01);       // descriptor
  12.   BT.write(modifiers);  // modifier
  13.   BT.write(0x00);       // 0x00  
  14.   BT.write(key1);       // key code 1
  15.   BT.write(key2);       // key code 2
  16.   BT.write(key3);       // key code 3
  17.   BT.write(key4);       // key code 4
  18.   BT.write(key5);       // key code 5
  19.   BT.write(key6);       // key code 6
  20. }
  21.  
  22. void consumerReport(uint16_t code) {
  23.   BT.write(0xFD);
  24.   BT.write(0x03);
  25.   BT.write(0x03);
  26.   BT.write((uint8_t)(code&0xff));
  27.   BT.write((uint8_t)(code>>8));
  28. }
  29.  
  30. void cmd(const char * s, int timeout=100, bool bSendCR=true) {
  31.   Serial.write("> ");
  32.   Serial.write(s);
  33.   Serial.write("\r\n");
  34.  
  35.   BT.write(s);
  36.   if (bSendCR) {
  37.     BT.write("\r");
  38.   }
  39.  
  40.   // rn42 output is tricky, let's use read timeout for now
  41.   long t = millis();
  42.   while(millis() < t + timeout) {
  43.     while (BT.available()) {
  44.       Serial.write(BT.read());
  45.     }
  46.     delay(1);
  47.   }
  48. }
  49.  
  50. void rn42_command_mode() {
  51.   // If the device sees any bytes before or after the $$$ characters in a 1 second window,
  52.   // the device does not enter command mode and these bytes are passed through
  53.   delay(1000);
  54.   cmd("$$$", 100, false);
  55. }
  56.  
  57. void rn42_init() {
  58.   rn42_command_mode();
  59.  
  60.   //cmd("SF,1", 1000); // factory defaults (resets pairing info)  
  61.   cmd("SS,Keyboard/Mouse"); // service name (1-20 chars)
  62.  
  63.   cmd("SW,8000");   // Sniff disable
  64.   cmd("SH,003C");   // combo device, out-report, 4-reconnect
  65.   cmd("SY,FFF4");   // transmit power -12
  66.    
  67.   cmd("S~,6");      // Set HID device
  68.   cmd("SM,5");      // Mode = 5, (any) Auto reconnect (can't use mode 4 because GPIO6 can be unavailable)
  69.   cmd("SC,0000");   // Service COD = 00002540 (Periheral, Keyboard) - Service class (upper 2 bytes) = 0000
  70.   cmd("SD,2540");   // Device Class (2 lower bytes) = 2540
  71.   cmd("SA,2");      // Authentication Mode 2 (SSP, "just works" mode)
  72.   cmd("SN,RN-42");  // Set BT Name (may be non-unique, use "S-,Name" to append MAC-address)
  73.    
  74.   cmd("R,1");       // Reboot!
  75. }
  76.  
  77. void rn42_connect() {
  78.   rn42_command_mode();
  79.   cmd("V");         // show version
  80.   //cmd("X"); Serial.println(); // show settings + line break
  81.   cmd("CFI");       // connect
  82.   cmd("---");       // exit command mode
  83. }
  84.  
  85. void setup() {
  86.   Serial.begin(9600); // This pipes to the serial monitor
  87.   BT.begin(115200); // This is the UART, pipes to sensors attached to board (9600 won't work for RN42)
  88.  
  89.   pinMode(2, INPUT); // input mode for the button pin (D2)
  90.   digitalWrite(2, HIGH); // set button pin to HIGH (software pullup) so it triggers when pulled to GND
  91.  
  92.   BT.write(0);  // disconnect if connected to the host (HID report 0), in case if GPIO6 is unavaliable
  93.   rn42_init();  // can be skipped to speed up connection
  94.   rn42_connect();
  95.  
  96.   // tweak sound volume slider up and down to indicate connection
  97.   delay(2500); consumerReport(0x10); delay(25); consumerReport(0); delay(25); consumerReport(0x20); delay(25); consumerReport(0);
  98. }
  99.  
  100. bool wasPressed = false;
  101.  
  102. void loop() {  
  103.   bool pressed = digitalRead(2)==LOW;  
  104.   if (pressed != wasPressed) {
  105.     keyCommand(pressed ? 0x80 : 0, 0); // winkey
  106.     wasPressed = pressed;
  107.     delay(25);
  108.   }    
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement