Need help properly concatenating data

Hello,

I am trying to make a Bluetooth enabled keyboard. So far the keyboard works but I'm having trouble properly sending the key press values to the Bluetooth module. I'm using the Arduino Keyboard library as well as the Adafruit BLE library for the nRF51 module.

Inside the Keybaord.h there is a struct called KeyReport as shown below:

typedef struct
{
  uint8_t modifiers;
  uint8_t reserved;
  uint8_t keys[6];
} KeyReport;

The above struct holds the key press values and is updated in my main program. In my main program, I have to send these values using a ble.print() command to the bluetooth module. The ble.print() command is from the aforementioned ble library from adafruit but appears to behave like regular Serial.print().

Below is code that currently works with the BLE module - all is well but the BLE module is SLOW when responding to keypresses. I believe it is due to performing all of these ble.print() commands separately instead of one ble.print() command.

                          ble.print("AT+BLEKEYBOARDCODE=");
                          ble.print(Keyboard._keyReport.modifiers,HEX);
                          ble.print("-");
                          ble.print(Keyboard._keyReport.reserved,HEX);
                          ble.print("-");
                          ble.print((Keyboard._keyReport.keys[0]), HEX);
                          ble.print("-");
                          ble.print((Keyboard._keyReport.keys[1]), HEX);
                          ble.print("-");
                          ble.print((Keyboard._keyReport.keys[2]), HEX);
                          ble.print("-");
                          ble.print((Keyboard._keyReport.keys[3]), HEX);
                          ble.print("-");
                          ble.print((Keyboard._keyReport.keys[4]), HEX);
                          ble.print("-");
                          ble.print((Keyboard._keyReport.keys[5]), HEX);
                          ble.println();

How can I do the above but with ONE ble.println() statement? I have tried a ton of things... making a char buffer, using strcat, etc... with no luck. I don't think I understand the types I'm working with well enough. Any guidance would be great!

Thanks!

I don't think it would make any difference if you put the entire message in one Serial.print(). The preparation of the data is very much faster than the serial output.

Have you the option of using a higher baud rate?

if you need more help please post your complete program.

...R

Have you ever considered a for loop?

The BLE module is run over SPI so I'm not sure if I can increase the speed. Do you think that the BLE module itself is the limiting factor on speed here?

Here is my entire code:

Warning - This code is long but most of it is just commented sections where I was trying to do what I posted about. Also, the if else statements for a few values are because half of my keyboard uses a shift register to scan the matrix because I ran out of I/O on the micro. The micro I'm using is an Adafruit Feather M0 with the nRF51 module onboard and connected via SPI.

The code is here: https://pastebin.com/embed_js/nnJisfyP

Also, with regard to for loop... yes i tried that but I don't think it solves my problem. I still need to print all these values with separate print statements. I'm trying to do it with just one complete print statement.

iamatesla:
Also, the if else statements for a few values are because half of my keyboard uses a shift register to scan the matrix because I ran out of I/O on the micro.

Assuming I have understood your code correctly, you could probably make things a little clearer like this (untested) example:

char outputs[] = {1, 0, 5, 21, 20, 14, 9, -1, -2, 19, 18, -4, -8, -16}; // negative indicates shift register q

void setup() {
  for (unsigned i = 0; i < sizeof(outputs); i++)
  {
    const char output = outputs[i];
    if (output >= 0) {
      pinMode(output, OUTPUT);
      digitalWrite(output, LOW);
    }
  }
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, 0);
  digitalWrite(latchPin, HIGH);
}

void loop() {
  for (unsigned i = 0; i < sizeof(outputs); i++)
  {
    const char output = outputs[i];
    
    if (output >= 0) {
      digitalWrite(output, HIGH);
    } else {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, -output);
      digitalWrite(latchPin, HIGH);
    }


    if (output >= 0) {
      digitalWrite(output, LOW);
    } else {
      digitalWrite(latchPin, LOW);
      shiftOut(dataPin, clockPin, MSBFIRST, 0);
      digitalWrite(latchPin, HIGH);
    }
  }
}

Some of it could go into a function, but you may not gain much.

You could also consider flashing a LED when a keypress is detected but before anything is sent over BT. That way you could see if the delay is in detecting the keypresses or sending them.

@arduarn Thanks for the comment, but I think you lost me with this. The code to detect key presses works fine. The keyboard is working with USB HID perfectly...just slow on bluetooth.

I actually believe I fixed the issue. Turns out the problem was the factory firmware in the nRF51 BLE module. I updated the firmware from adafruit and that appears to have fixed the latency problem. Thanks for all the recommendations guys!