Arduino Uno as a HID Keyboard PROBLEM

Hi.

So I have made a little code on my arduino Uno.
The goal is to use one button to cicle through some numbers and send the number to computer over USB as a keyboard.
The purpose is to trigger some movie clips in previously mapped software.

So you click the button once, nr 1 is sent to PC and the first clip is played. You press the button second time nr 2 is sent to PC and the second clip is played.

The code is here and if I use Serial monitor, it works correct symbols are shown. But if I convert the devise into HID, Windows shows some random CTRL+ALT stuff and controls. I don't really understand what is wrong. Could anyone help me?
My PC winXP recognises the Arduino as a HID. So there should not be a problem.
USB table is here. http://www.usb.org/developers/devclass_docs/Hut1_11.pdf

uint8_t buf[8] = { 
  0 }; 	/* Keyboard report buffer */

const byte switchPin = A0;
                  // switch is connected to pin A0
byte ledPin = 13;                      // led on pin 13
byte buttonPresses = 0;                // how many times the button has been pressed 
byte lastPressCount = 0;               // to keep track of last press count

void setup() {
  pinMode(switchPin, INPUT);          // Set the switch pin as input
  digitalWrite(switchPin, HIGH);      // set pullup resistor
  Serial.begin(9600);                 // Set up serial communication at 9600bps
 
  delay(200);
}



void loop(){
  if (digitalRead(switchPin) == LOW)  // check if button was pressed
  {
    buttonPresses++;                  // increment buttonPresses count
    delay(600);                       // debounce switch
  }
  if (buttonPresses == 10) buttonPresses = 0;         // rollover every 10th press
  if (lastPressCount != buttonPresses)              // only do output if the count has changed
  {
    Serial.print ("Button press count = ");          // out to serial
    Serial.println(buttonPresses, DEC);
    
     if(buttonPresses == 0)
    {
      buf[0] = 39;	  // 0
    Serial.write(buf, 8);	// Send keypress
    releaseKey();     
    }
    
    else if(buttonPresses == 1)    
    { 
     buf[0] = 30;	  // 1
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 2)    
    { 
     buf[0] = 31;	  // 2
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 3)    
    { 
     buf[0] = 32;	  // 3
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 4)    
    { 
     buf[0] = 0;
     buf[2] = 0x21;	  // 4
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 5)    
    { 
     buf[0] = 34;	  // 5
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 6)    
    { 
     buf[0] = 35;	  // 6
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 7)    
    { 
     buf[0] = 36;	  // 7
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 8)    
    { 
     buf[0] = 37;	  // 8
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    else if(buttonPresses == 9)    
    { 
     buf[0] = 38;	  // 9
    Serial.write(buf, 8);	// Send keypress
    releaseKey();  
    }
    
    
    lastPressCount = buttonPresses;    // track last press count
  }
}

    void releaseKey() 
{
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);	// Release key  
  delay(200);
}

It actually looks like Windows doesn't understand at all what I am trying to send.

Some presses are not doing anything. Mostly I can write ½½^4§½½^4§½½^4§½½^4
Caps lock gets on also.
And this happenes with in 10 clicks.

Nothing more is happening.

I assume that you have all the tools to do this project. You have both .hex files, the one for HID and the one for serial converter. I also assume you have the programming software to switch between the two fuctions so you can easily go back and forth between Serial converter and HID.

After up update the firmware on the serial interface controller, does it appear as an HID device on your computer?

In HID mode, what is the interface baud rate? Are you sure that it is 9600 and not something higher?

You know that you can do

pinMode(switchPin, INPUT_PULLUP);

instead of

pinMode(switchPin, INPUT);          // Set the switch pin as input
digitalWrite(switchPin, HIGH);      // set pullup resistor

You might want to try something VERY simple like:
Press the button - say "Hello World"
Release the button - say "Goodbye World"

Then work up from there.

Hi.

yes Arduino is reprogrammed by Flip with
Arduino-usbserial-uno.hex to program it and
Arduino-keyboard-0.3.hex to act as a keyboard.

I am also thinking that maybe the rates are different. How can I change it? I dont have full understandig of what I am doing.

  if (digitalRead(switchPin) == LOW)  // check if button was pressed
  {
    buttonPresses++;                  // increment buttonPresses count
    delay(600);                       // debounce switch
  }

You do NOT want to increment the counter when the pin IS low. You want to increment when the pin BECOMES low. Look at the state change detection example.

A 600 millisecond delay is not debouncing.

PaulS:

  if (digitalRead(switchPin) == LOW)  // check if button was pressed

{
   buttonPresses++;                  // increment buttonPresses count
   delay(600);                       // debounce switch
 }



You do NOT want to increment the counter when the pin IS low. You want to increment when the pin BECOMES low. Look at the state change detection example.

A 600 millisecond delay is not debouncing.

But I have the Pin set high if the button is not pressed. so Why it should not be counted when its low?
600ms is because I don't want to allow the button being pressed that frequently.

I will try to send text to confirm if the connection works.

Oh I tried this code. Its a random Key/ Random Delay. And this worked.

/* Arduino USB HID Keyboard Demo
 * Random Key/Random Delay
 */
 
uint8_t buf[8] = { 
  0 }; 	/* Keyboard report buffer */
 
void setup() 
{
  Serial.begin(9600);
  randomSeed(analogRead(0));
  delay(200);
}
 
void loop() 
{
  int randomChar = random(4, 130);
  long randomDelay = random(1000, 10000);
 
  delay(randomDelay);
 
  buf[2] = randomChar;	  // Random character
  Serial.write(buf, 8);	// Send keypress
  releaseKey();
}
 
void releaseKey() 
{
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);	// Release key  
}

But if I convert the devise into HID,

How do you do this (convert the arduino into an HID ) ?

But I have the Pin set high if the button is not pressed. so Why it should not be counted when its low?
600ms is because I don’t want to allow the button being pressed that frequently.

It seems to me like you want to count once for each switch press, regardless of how long the switch is held down. If that isn’t what you want, forget I said anything.

Still, the 600 millisecond delay is not for debouncing, so your comment is wrong.

raschemmel:

But if I convert the devise into HID,

How do you do this (convert the arduino into an HID ) ?

Have a look at this one

About the subject.

I managed to make it send only one letter after each button press.
Now I think it might be that the counter is messing something up. Dont understand.

Hi.

I still have not figured out what is going on.

Once I add counter to the code it will start to send random keys to the PC:
If I use one button to send one Symbol it works.

Is there another way to send numbers from 0 to 9 (or some other keys) without using Counter?
I have tried that random key press works fine.

Anyideas how to use it?

/* Arduino USB HID Keyboard Demo
 * Random Key/Random Delay
 */
 
uint8_t buf[8] = { 
  0 }; 	/* Keyboard report buffer */
 
void setup() 
{
  Serial.begin(9600);
  randomSeed(analogRead(0));
  delay(200);
}
 
void loop() 
{
  int randomChar = random(4, 130);
  long randomDelay = random(1000, 10000);
 
  delay(randomDelay);
 
  buf[2] = randomChar;	  // Random character
  Serial.write(buf, 8);	// Send keypress
  releaseKey();
}
 
void releaseKey() 
{
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);	// Release key  
}

Once I add counter to the code

To what code?

But I have the Pin set high if the button is not pressed. so Why it should not be counted when its low?
600ms is because I don't want to allow the button being pressed that frequently.

That means you're debouncing the user, not the switch. If you use the state change detection approach you only act when the state of the switch changes. The user could hold it down for minutes and it will only count once. When you simply check the state of the switch you increment the counter every time it checks, if the switch is pressed. Your work around is the long delay giving the user time to release the switch. This is debouncing the user. I used to do that until I figured it out.

Good point.
I will get to it once I have some hope to get the counter thing working.

So here is a code that works.
It sends a R each time I press the button. A0 is pulled low with resistor and goes high once the button is pressed.

/* 
 * 
 */ 
 //9.Aprill, 2000
 
uint8_t buf[8] = { 
  0 }; 	/* Keyboard report buffer */
 const int button = A0; // Button input pin
 int ButtonState = LOW; // 
 int val = 0;           // button value
void setup() 
{
  Serial.begin(9600);
  pinMode(button, INPUT);
  delay(200);
}
 
void loop() 
{
 val = digitalRead(button);   // read the button
 delay(300);                  // wait, to reduce noise (debouncing stuff)
 
 if (val == HIGH)              // continue if the button is pressed
 {
 
  buf[2] = 0x15;	  // Letter R
  Serial.write(buf, 8);	// Send keypress
  releaseKey();
  }
}
 
void releaseKey() 
{
  buf[0] = 0;
  buf[2] = 0;
  Serial.write(buf, 8);	// Release key  
}

The next step would be to get the thing sending other letters or numbers (I actually need nubers from 0 to 9)
I was first thinking to program a counter. And use If/else if functions to send different numbers to PC.

I also found out that if I use Serial.print in the code and switch to Arduino keyboard, the thing will go nuts.

Hi.

So I did something like this. There is something wrong. The program is stuck somewhere.

/* 
 * 
 */ 
 //9.Aprill, 2000
 
  uint8_t buf[8] = { 
    0 }; 	/* Keyboard report buffer */
     const int button = A0; // Button input pin
     int ButtonState = 0; // Current button value
     int lastbuttonState = 0;  //previous state
     int counter = 0;        // counter
     
  void setup() 
    {
    Serial.begin(9600);
    pinMode(button, INPUT);
    delay(200);
    }
 
  void loop() 
   {
     ButtonState = digitalRead(button);   // read the button
    
     if (counter == 4) ButtonState = 0; 
     if (ButtonState != lastbuttonState)
        {
        if (ButtonState == HIGH)
           {
             counter++;
              
           }
         }
         
     if (counter == 2)              // continue if counter value 2
     {
 
      buf[2] = 0x15;	  // Letter R
      Serial.write(buf, 8);	// Send keypress
      releaseKey();
      }
      
     lastbuttonState = ButtonState; 
    }
 
  void releaseKey() 
    {
      buf[0] = 0;
      buf[2] = 0;
      Serial.write(buf, 8);	// Release key  
     }

PaulS:
You do NOT want to increment the counter when the pin IS low. You want to increment when the pin BECOMES low. Look at the state change detection example.

served:
so Why it should not be counted when its low?

PaulS was drawing your attention to the difference between a transition from HIGH to LOW vs. a LOW state.

Do I really need to solder a 10k resistor to the board to get this thing to laod some keyboard usbserial hex files?

Seems a touch much!

I have the Uno R3 board.