using usb keyboard led as softserial?

Hi, once more, i'm here with an unusual question:

I know that the USB-Keyboard leds (capslock, numlock...) can be used to programm an AVR.

But is there a way to use them as Softserial?

What i mean is: on pc an application sends the data by blinking the capslock led instead of using an com port, and on the arduino, i can receive the capslock changes and somehow feed thet into the softserial!

(btw, i'm not mad!? maybe a little, but this came up as the com ports on the pc's for my project are locked and i can only interface by USB-HID (Keyboard).

Many thanks for advice

I know that the USB-Keyboard leds (capslock, numlock...) can be used to programm an AVR.

Can you please start by explaining this part to me ?

UKHeliBob: Can you please start by explaining this part to me ?

I am glad I am not the only scratching my head on this.

LEDs being able to program an AVR would be quite an feat.

I have 64 of them in a 4 * 4 * 4 cube attached to an Arduino. Just think what they could do.

Hey, it's alway fun to see, how many people in this forum react on questions, that are not 10000 times done before. Your think, everyone else must be an idiot, instead of thinking about first! I've done many project (vbscript/wscript/other scripts), where i've heard "it can't be done, you silly one", and they run like charm. So maybe some of you may use his power to help solving a problem, than lynch someone!!!!!!!!!

What i've seen (in the posted project and in one project on tindied (sadly i can't find it right now) is:

Keyboard ATtiny direction Num lock SCL out Caps lock MOSI out Scroll lock Reset out row/column of right shift key MISO (through optocoupler) in

have a look here: https://wiki.steve-m.de/hidkey_gpio

Ok, so we cleared this: it can be done. Now lets face the primary question:

Can this be done by "bending" something like softserial? Or maybe you've an other solution??

And, as you can see, one can be friendly too...

MANY thanks for any (serious) HELP and ADVICE!

infantilo: MANY thanks for any (serious) HELP and ADVICE!

How about posting a question with the correct technical information ?

You had no clue what you are writing [ I know that the USB-Keyboard leds (capslock, numlock...) can be used to programm an AVR and using usb keyboard led as softserial? ] and you accuse people of being naysayers and unfriendly? You have some nerve.

Maybe i've troubles writing in english???? YOU thought, the light of an led could programm something!! Get a towel, wype your tears and HELP!

Ok, but now that we've done basting... could we go on a bit more productive? Others may profit from new thoughts, too!!!!!!

Found where i've seen it before:

http://matrixstorm.com/avr/tinyusbboard/oldindex.html

I also provided here (keyboardasp_v2.zip) some software (windows and linux) to build your ISP from a keyboard. You can call "tinyUSBboard.exe" to get an AVR (your board) programmed. Therefore you even do not need MISO (board-->PC). NUMLOCK will be CLK, CAPSLOCK will be MOSI and SCROLLOCK connects to RESET.

Num lock SCL out Caps lock MOSI out Scroll lock Reset out row/column of right shift key MISO

Where does SoftwareSerial come into the equation ? What you are describing looks like an SPI interface for which there is an Arduino library and several dedicated pins.

What i was thinking off is to use these bits for communication between pc and arduino and generate something similar to an serial terminal.
As i mentioned, com ports are disabled on the pc’s, so i can’t use an serial terminal to send data to the arduino leonardo beetle / CLMCU, that acts as HID Keyboard.
So it came in my mind to use caps-lock and num-lock as RX and TX.
Softserial was only an idea, lack of further knowledge :blush: (and i already use serial commands… and i have to keep memory in mind (currently i use 61% pgm memory)…)

infantilo: Maybe i've troubles writing in english???? YOU thought, the light of an led could programm something!! Get a towel, wype your tears and HELP!

Ok, but now that we've done basting... could we go on a bit more productive? Others may profit from new thoughts, too!!!!!!

That's what you wrote. If it sounds stupid, then it is your fault, not ours.

If you want to write something different, then I suggest that you write it [u]correctly[/u] in English.

MANY THX UKHeliBob!!!! SPI seems to be what i've been looking for. Now i've got plenty to read (and learn) about SPI ;-)

Once more, SORRY for my bad english! It's hard to verbalize many things correctly.

I'll post any (hopefully working) results here, but it may take awhile ;-)

So, as promised, here is an solution, that at least works for my needs:

All credits goes to Thanasis Georgiou!
He posted an pseudo-code that exactly describes, what needed.
https://thgeorgiou.com/posts/2016-02-23-Communicating-using-keyboard-status-LEDs/

An commandline c++ exe sends test to the arduino by toggling the keyboard leds (capslock, numlock, scrollock).
Yes, it is an slow way of communication, and yes, there could (or schould) be added an ACK message, BUT it works!

I had to tweak with GetKeyState(0) a lot, to enshure, i’m always getting the updated key values (this is an windows issue, and calling GetKeyState(0) is forcing the system to refresh the keystates)

PC (Dev-C++):

#include <iostream>
#include <string>
#include <bitset>
#include <Windows.h>

const int ClockSpeed = 10;
const int Delay = 1000 / ClockSpeed;


void SetCapsLock(BOOL bState)
{
 GetKeyState(0);
 Sleep(8);
 GetKeyState(0);
 Sleep(8);
 BYTE keyState[256];
 GetKeyboardState((LPBYTE)&keyState);
 if((bState&&!(keyState[VK_CAPITAL]&1)) || (!bState && (keyState[VK_CAPITAL]&1)))
 {
 keybd_event(VK_CAPITAL,
 0,
 KEYEVENTF_EXTENDEDKEY | 0,
 0);

 keybd_event(VK_CAPITAL,
 0,
 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
 0);
 }
}

void SetNumLock(BOOL bState)
{
 GetKeyState(0);
 Sleep(8);
 GetKeyState(0);
 Sleep(8);
 BYTE keyState[256];
 
 GetKeyboardState((LPBYTE)&keyState);
 if((bState&&!(keyState[VK_NUMLOCK]&1)) || (!bState && (keyState[VK_NUMLOCK]&1)))
 {
 keybd_event(VK_NUMLOCK,
 0,
 KEYEVENTF_EXTENDEDKEY | 0,
 0);
 
 keybd_event(VK_NUMLOCK,
 0,
 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
 0);
 }
}

void SetScrollLock(BOOL bState)
{
 GetKeyState(0);
 Sleep(8);
 GetKeyState(0);
 Sleep(8);
 BYTE keyState[256];
 
 GetKeyboardState((LPBYTE)&keyState);
 if((bState&&!(keyState[VK_SCROLL]&1)) || (!bState && (keyState[VK_SCROLL]&1)))
 {
 keybd_event(VK_SCROLL,
 0,
 KEYEVENTF_EXTENDEDKEY | 0,
 0);
 
 keybd_event(VK_SCROLL,
 0,
 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
 0);
 }
}




std::bitset<8> ToBits(unsigned char byte)
{
 return std::bitset<8>(byte);
}




int main(int argc, char** argv) 
{
 bool loopflag = true;
 
 while(loopflag) {

 SetCapsLock(false);
 SetNumLock(false);
 SetScrollLock(false);
 
 std::cout << "Enter string:";
 std::string s;
 std::getline(std::cin, s);
 
 s = s + '\n';
 
 if (s=="-q") {
 loopflag=false;
 break;
 }
 
 
 
 
 for (std::size_t i=0; i< s.size(); i++)
 {
 std::bitset<8> v8 = std::bitset<8>(s.c_str()[i]);
 for (int j=0; j<8; j+= 2)
 {
 //Set data lines
 SetNumLock(v8[j]);
 SetCapsLock(v8[j+1]);
 
 //Cycle Clock
 Sleep(Delay/3);
 SetScrollLock(true);
 Sleep(Delay/3);
 SetScrollLock(false);
 Sleep(Delay/3);
 
 //std::cout << v8[j];
 //std::cout << v8[j+1];
 }
 
 //std::cout << std::bitset<8>(s.c_str()[i]) << std::endl;
 } 
 //std::cout << "" << std::endl;
 
 SetCapsLock(false);
 SetNumLock(false);
 SetScrollLock(false);

 }


}

Arduino (this code shoud be used with Nicehood’s HID library (e.g. BootKeyboard):
(GitHub - NicoHood/HID: Bring enhanced HID functions to your Arduino!)

//#################################################
// Read from Status-HID-Keyboard-Leds
// call this function each time a new Led-State has receives, or - as i do - in your main loop as often as possible
//#################################################

char yourIncommingChar;
// which byte are we receiving
unsigned char byteIndex = 0;
// which bit of the byte above we are receiving right now
unsigned char bitIndex = 0;
// was the last cycle a clock?
unsigned char lastClock = 0;

uint8_t myLeds;


void ReadKeyboardLedCommunication(void) {
  if(BootKeyboard.getLeds() == myLeds) {
    return;
  } else {
    myLeds = BootKeyboard.getLeds();
  }

  
  if ((myLeds & LED_SCROLL_LOCK)!=0) { // if numlock is enabled HIGH
    if (lastClock == 0) {
      lastClock = 1;
      //store numlock
      if((myLeds & LED_NUM_LOCK) != 0) {
        yourIncommingChar |= 1 << (bitIndex);
      }
      // advance the bit index since we stored one bit
      bitIndex++;
      
      //store capslock
      if((myLeds & LED_CAPS_LOCK) != 0) {
        yourIncommingChar |= 1 << (bitIndex);
      }
      bitIndex++; // another bit

      //if this byte is received, move to next one
      if (bitIndex == 8) {
        byteIndex++;
        bitIndex = 0;
      }


    }
  } else if ((myLeds & LED_SCROLL_LOCK)==0) { // scroll lock off
    // clock cycle finished
    if (lastClock == 1) {
      lastClock = 0;
      if (byteIndex == 1) {

          Serial.print(yourIncommingChar);

          yourIncommingChar = 0;
          bitIndex = 0;
          byteIndex = 0;
      }
    }
  }
}

For my needs, i modded the dynamic serial command parser, so it can read the yourIncommingChar, too (this way i don’t waste programm space, and as i’ll use this whenever serial is not available, i don’t need to care about it).

There’s a lot to do, an maybe someone would like to participate and help to improve the communication.

I’m an simple hobby programmer, so there will be a lot that could be done better.

However, this is wat works for me.
I’d be happy for ANY advice to do things better!!!