Need help coding HID with Pro Micro

Hi all,

I need help with coding my Pro Micro. I have 6 switches that should send a keyboard character/letter/number when pressed.

Here is the challenge;
I have toggle switches and NOT push buttons, so the contact will remain closed all the time once pressed. So what I need; "When the input changes state", send the letter.

Please ignore the resistors right now, they will be used for Debounce when needed.

Here is my Fritzing:


Only the Leonardo (retired) and the Micro can use the Keyboard library to send keystrokes.

So what I need is the code to send the keyboard letter (e.g. "a") just once after the switch is used.

When the input changes state, send the letter.

The resistors are used for Debounce.

Oh? How?

PaulS:
Only the Leonardo (retired) and the Micro can use the Keyboard library to send keystrokes.

Sorry, I meant Pro Micro!

I changed my initial question a bit, sorry for that. My English is not very well.

So yes, I have the Pro Micro and I want to send a letter when the input changes state without causing a loop because its a toggle switch and I don't want a string of letters to be send, just one at every input change.

Thanks for helping in advance, your help will be mentioned on my Hackaday page.

I suggest start with learning about:
-- connecting switches to the Arduino
-- pull up and pull down resistors
-- internal pull up resistors
-- debouncing

All that stuff you can learn here:

There is also a state change detection example. The type of switches does not matter. Pressing and releasing a momentary contact switch causes two state changes. Flipping a toggle switch causes one state change. It is the state changes that are important.

PaulS:
There is also a state change detection example. The type of switches does not matter. Pressing and releasing a momentary contact switch causes two state changes. Flipping a toggle switch causes one state change. It is the state changes that are important.

Thats what I need, good info! Its quite hard for me to find Pro Micro tutorials like UNO has. Can you point me in a direction?

@dmjlambert
Sorry, Thats should have been my first question. I haven't even found out how to wire them.

dmjlambert:
I suggest start with learning about:
-- connecting switches to the Arduino
-- pull up and pull down resistors
-- internal pull up resistors
-- debouncing

All that stuff you can learn here:
Gammon Forum : Electronics : Microprocessors : Switches tutorial

Perfect link, think I found my code:

const byte switchPin = 8;
byte oldSwitchState = HIGH; // assume switch OFF because of pull-up resistor
const unsigned long debounceTime = 10; // milliseconds

void setup ()
{
Serial.begin (115200);
pinMode (switchPin, INPUT_PULLUP);
Keyboard.begin();
} // end of setup

void loop ()
{
// see if switch is OFF or ON
byte switchState = digitalRead (switchPin);

// has it changed since last time?
if (switchState != oldSwitchState)
{
oldSwitchState = switchState; // remember for next time
delay (debounceTime); // debounce
if (switchState == LOW)
{
Serial.println ("Switch ON.");
Keyboard.print("a");
} // end if switchState is LOW
else
{
Serial.println ("Switch OFF.");
Keyboard.print("a");
} // end if switchState is HIGH
} // end of state change

// other code here ...

} // end of loop

The code above works perfect for one switch switch that's send letter "a" when ON and letter "a" again when OFF. That`s just perfect for me, lights are turned ON and OFF with the same letter in my Simulator.

Would you please help me to add another switch to this code for PIN 9? When two switches are in I can manage to add more than two switches for myself I hope.

When you include code in your post or reply, please use the code tags as described in the "How to use this forum - please read" post pinned at the top of the forum. It will make the thread more readable and better.

To add another switch you can add another whole section of code in the loop which deals with the second button. Add it at the bottom of the loop where you currently have

// other code here ...

So, essentially we are talking about repeating everything you currently have in the loop. Use different variable names when dealing with the different switch. Perhaps you can add variables called switchPinB, switchStateB, oldSwitchStateB, etc. You will also have to add those new variable declarations above the Setup section, and add the pinMode statement for the additional switch in the Setup section.

jeroenV1982:
...hard for me to find Pro Micro tutorials like UNO has...

The Pro Micro is not different from Uno when it comes to doing things like attaching buttons, detecting switch states, etc. The Uno does not have the ability to do Keyboard.print like the Pro Micro, but the other general coding should be easily adaptable if you find Uno examples.

I got it! Its working!

Here is the code for PIN 2 till PIN 10 (A to I)

Thank you so much for helping! :slight_smile:

const byte switchPinA = 2;
const byte switchPinB = 3;
const byte switchPinC = 4;
const byte switchPinD = 5;
const byte switchPinE = 6;
const byte switchPinF = 7;
const byte switchPinG = 8;
const byte switchPinH = 9;
const byte switchPinI = 10;
byte oldSwitchStateA = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateB = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateC = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateD = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateE = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateF = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateG = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateH = HIGH;  // assume switch OFF because of pull-up resistor
byte oldSwitchStateI = HIGH;  // assume switch OFF because of pull-up resistor
const unsigned long debounceTime = 10;  // milliseconds

void setup ()
  {
  Serial.begin (115200);
  pinMode (switchPinA, INPUT_PULLUP);
  pinMode (switchPinB, INPUT_PULLUP);
  pinMode (switchPinC, INPUT_PULLUP);
  pinMode (switchPinD, INPUT_PULLUP);
  pinMode (switchPinE, INPUT_PULLUP);
  pinMode (switchPinF, INPUT_PULLUP);
  pinMode (switchPinG, INPUT_PULLUP);
  pinMode (switchPinH, INPUT_PULLUP);
  pinMode (switchPinI, INPUT_PULLUP);
  Keyboard.begin();
  }  // end of setup

void loop ()
  {
  // see if switch A is OFF or ON
  byte switchStateA = digitalRead (switchPinA);
  
  // has it changed since last time?
  if (switchStateA != oldSwitchStateA)
    {
    oldSwitchStateA =  switchStateA;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateA == LOW)
       {
       Serial.println ("Switch A is ON.");
       Keyboard.print("a");
       }  // end if switchStateA is LOW
    else
       {
       Serial.println ("Switch A is OFF.");
       Keyboard.print("a");
       }  // end if switchStateA is HIGH
    }  // end of state change
     
  // see if switch B is OFF or ON
  byte switchStateB = digitalRead (switchPinB);
  
  // has it changed since last time?
  if (switchStateB != oldSwitchStateB)
    {
    oldSwitchStateB =  switchStateB;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateB == LOW)
       {
       Serial.println ("Switch B is ON.");
       Keyboard.print("b");
       }  // end if switchStateA is LOW
    else
       {
       Serial.println ("Switch B is OFF.");
       Keyboard.print("b");
       }  // end if switchStateB is HIGH
    }  // end of state change

    // see if switch C is OFF or ON
  byte switchStateC = digitalRead (switchPinC);
  
  // has it changed since last time?
  if (switchStateC != oldSwitchStateC)
    {
    oldSwitchStateC =  switchStateC;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateC == LOW)
       {
       Serial.println ("Switch C is ON.");
       Keyboard.print("c");
       }  // end if switchStateC is LOW
    else
       {
       Serial.println ("Switch C is OFF.");
       Keyboard.print("c");
       }  // end if switchStateC is HIGH
    }  // end of state change

    // see if switch D is OFF or ON
  byte switchStateD = digitalRead (switchPinD);
  
  // has it changed since last time?
  if (switchStateD != oldSwitchStateD)
    {
    oldSwitchStateD =  switchStateD;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateD == LOW)
       {
       Serial.println ("Switch D is ON.");
       Keyboard.print("d");
       }  // end if switchStateD is LOW
    else
       {
       Serial.println ("Switch D is OFF.");
       Keyboard.print("d");
       }  // end if switchStateD is HIGH
    }  // end of state change

    // see if switch E is OFF or ON
  byte switchStateE = digitalRead (switchPinE);
  
  // has it changed since last time?
  if (switchStateE != oldSwitchStateE)
    {
    oldSwitchStateE =  switchStateE;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateE == LOW)
       {
       Serial.println ("Switch E is ON.");
       Keyboard.print("e");
       }  // end if switchStateE is LOW
    else
       {
       Serial.println ("Switch E is OFF.");
       Keyboard.print("e");
       }  // end if switchStateE is HIGH
    }  // end of state change

    // see if switch F is OFF or ON
  byte switchStateF = digitalRead (switchPinF);
  
  // has it changed since last time?
  if (switchStateF != oldSwitchStateF)
    {
    oldSwitchStateF =  switchStateF;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateF == LOW)
       {
       Serial.println ("Switch F is ON.");
       Keyboard.print("f");
       }  // end if switchStateF is LOW
    else
       {
       Serial.println ("Switch F is OFF.");
       Keyboard.print("f");
       }  // end if switchStateF is HIGH
    }  // end of state change

    // see if switch G is OFF or ON
  byte switchStateG = digitalRead (switchPinG);
  
  // has it changed since last time?
  if (switchStateG != oldSwitchStateG)
    {
    oldSwitchStateG =  switchStateG;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateG == LOW)
       {
       Serial.println ("Switch G is ON.");
       Keyboard.print("g");
       }  // end if switchStateG is LOW
    else
       {
       Serial.println ("Switch G is OFF.");
       Keyboard.print("g");
       }  // end if switchStateG is HIGH
    }  // end of state change

    // see if switch H is OFF or ON
  byte switchStateH = digitalRead (switchPinH);
  
  // has it changed since last time?
  if (switchStateH != oldSwitchStateH)
    {
    oldSwitchStateH =  switchStateH;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateH == LOW)
       {
       Serial.println ("Switch H is ON.");
       Keyboard.print("h");
       }  // end if switchStateH is LOW
    else
       {
       Serial.println ("Switch H is OFF.");
       Keyboard.print("h");
       }  // end if switchStateH is HIGH
    }  // end of state change

    // see if switch I is OFF or ON
  byte switchStateI = digitalRead (switchPinI);
  
  // has it changed since last time?
  if (switchStateI != oldSwitchStateI)
    {
    oldSwitchStateI =  switchStateI;  // remember for next time 
    delay (debounceTime);   // debounce
    if (switchStateI == LOW)
       {
       Serial.println ("Switch I is ON.");
       Keyboard.print("i");
       }  // end if switchStateI is LOW
    else
       {
       Serial.println ("Switch I is OFF.");
       Keyboard.print("i");
       }  // end if switchStateI is HIGH
    }  // end of state change
   
  }  // end of loop

One final question; My code is printing a single letter like "a". Can I also send a key combination like "SHIFT+a"? (hold down shift while pressing "a")?

This would make defining special keys in the simulator way more easy since most of all single press keys are already in use.

I don't know the answer to the question about combination of modifier keys with regular keys, that is where you will probably need to do some googling. The simple ones like shift+a is simply A.

Found it!

Keyboard.press(KEY_LEFT_SHIFT);
       Keyboard.print("a");
       Keyboard.release(KEY_LEFT_SHIFT);

HINT: Don`t forget Keyboard.release like I did the first time or "SHIFT" will be hold for the rest of the day even when the Pro Micro is disconnected from your computer! A PC Reboot fixes the SHIFT pressed issue. After Reboot you can fix the problem in your code and upload it to the Pro Micro. The code I use (see previous comments) wont start anything before you presses your first switch connected to the board.