Go Down

Topic: Arduino as a HID Keyboard (Read 37 times) previous topic - next topic

A.McD

@ayen:
I was unable to reproduce the problem you're having. I tested the functionality in Winamp, Windows Media Player, and VLC. It works using the sketch below and with the Arduino Keyboard HEX file (in the zip file) reference in my first post.

Code: [Select]
/*

Keyboard sketch
by Andrew McDaniel

Copyright (c) 2010 Andrew McDaniel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
/*
When we send data to the keyboard driver, it has to be
scancodes, not ascii characters. Refer to the AVR keyboard
source code to obtain the scancodes.
Notes:
-Modifiers (Shift, Alt, Ctrl) only modify the next character.
-When sending modifiers, the byte that is sent must be the amount
  of shift (referenced in the source code) plus 0xf0.
-Only one modifier can be used at a time.
-Once a modifier is sent, it will remain on until one of two things
  happen: another byte is sent, or the same modifier is pressed on
  another keyboard connected to the system.
-A delay of at least 25 milliseconds is required after each byte in
  order to gice the keyboard driver time to respond. A function to
  take care of this might be needed.
*/

// meaningful names for constants used in this sketch
const byte SC_SPACE = 0x2c;            const byte MOD_SHIFT = 0xf1;
const byte SC_ENTER = 0x28;            const byte MOD_ALT = 0xf2;
const byte SC_BCKSPC = 0x2a;           const byte MOD_CTRL = 0xf0;
const byte SC_TAB = 0x2b;              const byte SC_PERIOD = 0x37;
const byte SC_ESCAPE = 0x29;           const byte SC_COMMA = 0x36;
const byte SC_ESC = 0x29;              const byte SC_SEMI_AND_COLON = 0x33;
const byte SC_RIGHT_ARROW = 0xef;      const byte SC_SLASH_AND_QUESTION = 0x38;
const byte SC_LEFT_ARROW = 0x50;       const byte SC_VOL_UP = 0x80; //not working
const byte SC_DOWN_ARROW = 0x51;       const byte SC_VOL_DOWN = 0x81; //not working
const byte SC_UP_ARROW = 0x52;         const byte SC_MUTE = 0x7f; //not working
const byte SC_F1 = 0x3a;
const byte SC_F2 = 0x3b;
const byte SC_F3 = 0x3c;
const byte SC_F4 = 0x3d;
const byte SC_F5 = 0x3e;
const byte SC_F6 = 0x3f;
const byte SC_F7 = 0x40;
const byte SC_F8 = 0x41;
const byte SC_F9 = 0x42;
const byte SC_F10 = 0x43;
const byte SC_F11 = 0x44;
const byte SC_F12 = 0x45;


void setup()
{
 delay(6000); //  Give the keyboard driver time to boot
 Serial.begin(9600);
}

void loop()
{
 /*
 sendSCStringLine("This is being sent FROM THE Arduino.");
 sendSCString("This should be a new line. ");
 sendSCString("This should be the same line. ");
 upArrow();
 downArrow();
 */
 
 // windows media player pause play every five seconds
 /*
 sendSCByte(MOD_CTRL);
 sendSCString("p");
 delay(5000);
 */
 
 // winamp play pause every 5
 sendSCString("x");
 delay(5000);
 sendSCString("c");
 delay(5000);
 
 
 // most every other media player pause play every 5
 /*
 sendSCByte(SC_SPACE);
 delay(5000);
 */
 
}



void sendSCByte(byte byteToSend)
{
 // This function sends single scancode bytes.
 // If using this function to send MOD bytes,
 // keep in mind the above notes.
 Serial.print(byteToSend);
 delay(20);
}

void sendSCString(String stringToSend) // send a string of characters with no carriage return
{
 // for everyn character in the string, convert to scancode and send
 for ( int i = 0; i < stringToSend.length(); i++)
 {
   sendSCByte(convertAsciiToScanCode(stringToSend.charAt(i)));
 }
}

void sendSCStringLine(String stringToSend)  // send a string of chars with a carriage return at the end
{
 // concatenate a carraige return onto the end of the string and then send like a normal string
 stringToSend.concat(byte(0x0d));
 sendSCString(stringToSend);
}

byte convertAsciiToScanCode(byte asciiByte)  // self explanatory name
{
 
 if(asciiByte >= 0x61 && asciiByte <= 0x7a) // lower case letters
   return(asciiByte - 0x5d);
 else if(asciiByte >= 0x41 && asciiByte <= 0x5a) // upper case letters
 {
   sendSCByte(MOD_SHIFT);
   return(asciiByte - 0x3d);
 }
 else if(asciiByte >= 0x31 && asciiByte <= 0x39) // numbers 1 to 9
   return(asciiByte - 0x13);  // this actually sends the numbers across the top of the keyboard
 else if(asciiByte == 0x30)  // number 0
   return(0x27);
 else if(asciiByte == 0x20)  // space (duh)
   return(SC_SPACE);
 else if(asciiByte == 0x2e)  // is a comment really necesary for this one?
   return(SC_PERIOD);
 else if(asciiByte == 0x0a || asciiByte == 0x0d)  // line feed/new line and carriage return
   return(SC_ENTER);
 else if(asciiByte == 0x2c)
   return(SC_COMMA);
 else if(asciiByte == 0x3b)
   return(SC_SEMI_AND_COLON);
 else if(asciiByte == 0x3a)
 {
   sendSCByte(MOD_SHIFT);
   return(SC_SEMI_AND_COLON);
 }
 return(0x67);
}

// Arrow key functions shouldn't need axplanations of functionality

void upArrow()
{
 sendSCByte(SC_UP_ARROW);
}

void downArrow()
{
 sendSCByte(SC_DOWN_ARROW);
}

void leftArrow()
{
 sendSCByte(SC_LEFT_ARROW);
}

void rightArrow()
{
 sendSCByte(SC_RIGHT_ARROW);
}

ayen

ok. very sorry, everything is now working fine. at first i used only a few line of your code, and the rest was my solution. If i copy all your code, virtual keyboard works perfect. My bad. respect for your job :)

Go Up