Arduino as a Keyboard



ARDUINO AS A KEYBOARD

ABSTRACT

In this activity I’ve made a little circuit with Arduino that simulates to be a keyboard. At the beginning I was looking for a way to send data between Arduino and the tablet without using the USB host module. Then, I realized that this task would be very straightforward if I cheated the tablet or the PC simulating as Arduino were a Human Interface Device.

The aim of this circuit is to send the information of temperature and humidity to the tablet through a USB cable. Searching a solution in Internet, I found this web [1]. This web is extremely useful if you are an Arduino fan.

As you can see in the Figure 1, the design is like an Arduino shield. It has temperature and humidity sensors, one led, four small buttons and the rest of the components for send the data through the USB cable.

The circuit sends a little message when you push one of button. One message is the temperature and other message is the humidity. Basically the led does not do anything, it is collocated there only for debugging. The other device can be a tablet or a PC. It does not work with iPad because they are fascists and force you to buy expensive stuff for everything.

Figure 1: The circuit developed as a shield above the Arduino board.


     
MATERIALS

1 x Arduino board
2 x USB cable AM/BM
1 x Humidity sensor
1 x Temperature sensor
4 x Res. 10KΩ
2 x Res. 68 Ω
1 x Res. 2K2Ω
1 x Res. 330 Ω
2 x Diode Zener 3V6, 0.50W
4 x Small buttons
1 x 4 pins connector or   Usb female type B
1 x proto-board
Wires, pins, solder lead, etc…

DEVELOPMENT

The schematic of the hardware is in the following picture:
Figure 2: Schematic of the circuit.
Before starting to program the Arduino it is necessary to download the USBkeyboard library from [3], that it is a link of the web of the project [2]. In my case I modified the file “usbconfig.h” for using other digital pins. I changed the lines 33 and 68. The example used the digital outputs 5 and 4 but I’ve used the pins 6 and 7.


#define USB_CFG_DMINUS_BIT      7  // Before: 4

#define USB_CFG_PULLUP_BIT      6  // Before: 5

The Arduino code is in the Appendix 1. The functions for getting the temperature and the humidity are in the file “Sensors.h” that are in the Appendix 2.

RESULTS

The results can be watched in the next video:


Sorry for the quality of the video.

REFERENCE

[1] http://www.practicalarduino.com/projects/virtual-usb-keyboard
[2] http://code.rancidbacon.com/ProjectLogArduinoUSB
[3] http://www.obdev.at/products/vusb/download.html


PROPOSALS OF IMPROVEMENT

Use Arduino as a HID mouse.
Develop HID pedals.

APPENDIX 1

Arduino main code:

#include
#include "UsbKeyboard.h"
#include "Sensors.h"

#define BUTTON_A 8
#define BUTTON_B 9
#define BUTTON_C 10
#define BUTTON_D 11

// Use the on-board LED as an activity display
int ledPin = 13;

// If the timer isr is corrected
// to not take so long change this to 0.
#define BYPASS_TIMER_ISR 1

int humidity=0,temperature=0;

void setup()
{
  Serial.begin(9600);
  // Set the button pins to inputs
  pinMode (BUTTON_A, INPUT);
  pinMode (BUTTON_B, INPUT);
  pinMode (BUTTON_C, INPUT);
  pinMode (BUTTON_D, INPUT);

  // Enable the CPU's internal 20k pull-up resistors on the button
  // inputs so they default to a "high" state
  digitalWrite (BUTTON_A, HIGH);
  digitalWrite (BUTTON_B, HIGH);
  digitalWrite (BUTTON_C, HIGH);
  digitalWrite (BUTTON_D, HIGH);

#if BYPASS_TIMER_ISR
  // disable timer 0 overflow interrupt (used for millis)
  TIMSK0&=!(1<
#endif
}

#if BYPASS_TIMER_ISR
void delayMs(unsigned int ms) {
  /*
  */
  for (int i = 0; i < ms; i++) {
    delayMicroseconds(1000);
  }
}
#endif

void loop()
{
  int val=0;
 
  UsbKeyboard.update();

  if (digitalRead(BUTTON_A) == LOW)
  {   
    UsbKeyboard.sendKeyStroke(KEY_H);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_O);

    UsbKeyboard.sendKeyStroke(KEY_SPACE);

    UsbKeyboard.sendKeyStroke(KEY_W);
    UsbKeyboard.sendKeyStroke(KEY_O);
    UsbKeyboard.sendKeyStroke(KEY_R);
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_D);

    UsbKeyboard.sendKeyStroke(KEY_ENTER);
#if BYPASS_TIMER_ISR  // check if timer isr fixed.
    delayMs(20);
#else
    delay(20);
#endif  
  }

  if (digitalRead(BUTTON_B) == LOW)
  {
    temperature=Temperatura();
   
    UsbKeyboard.sendKeyStroke(KEY_T);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_M);
    UsbKeyboard.sendKeyStroke(KEY_P);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_R);
    UsbKeyboard.sendKeyStroke(KEY_A);
    UsbKeyboard.sendKeyStroke(KEY_T);
    UsbKeyboard.sendKeyStroke(KEY_U);
    UsbKeyboard.sendKeyStroke(KEY_R);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_SPACE);

    val= 29 + temperature/10;  
    if(val!=0) UsbKeyboard.sendKeyStroke(val);
    val= 29 + temperature%10;
    if(val==29) UsbKeyboard.sendKeyStroke(39);
    else UsbKeyboard.sendKeyStroke(val);
    //UsbKeyboard.sendKeyStroke(KEY_ENTER);
#if BYPASS_TIMER_ISR  // check if timer isr fixed.
    delayMs(20);
#else
    delay(20);
#endif  
  }
  if (digitalRead(BUTTON_C) == LOW)
  {
    humidity=Humedad();
   
    UsbKeyboard.sendKeyStroke(KEY_H);
    UsbKeyboard.sendKeyStroke(KEY_U);
    UsbKeyboard.sendKeyStroke(KEY_M);
    UsbKeyboard.sendKeyStroke(KEY_I);
    UsbKeyboard.sendKeyStroke(KEY_D);
    UsbKeyboard.sendKeyStroke(KEY_I);
    UsbKeyboard.sendKeyStroke(KEY_T);
    UsbKeyboard.sendKeyStroke(KEY_Y);

    UsbKeyboard.sendKeyStroke(KEY_SPACE);

    val= 29 + humidity/10;  
    if(val!=0) UsbKeyboard.sendKeyStroke(val);
    val= 29 + humidity%10;
    if(val==29) UsbKeyboard.sendKeyStroke(39);
    else UsbKeyboard.sendKeyStroke(val);
    //UsbKeyboard.sendKeyStroke(KEY_ENTER);
#if BYPASS_TIMER_ISR  // check if timer isr fixed.
    delayMs(50);
#else
    delay(50);
#endif  
  }

  if (digitalRead(BUTTON_D) == LOW)
  {
    UsbKeyboard.sendKeyStroke(KEY_L);
    UsbKeyboard.sendKeyStroke(KEY_E);
    UsbKeyboard.sendKeyStroke(KEY_D);

#if BYPASS_TIMER_ISR  // check if timer isr fixed.
    delayMs(100);
#else
    delay(100);
#endif 

    digitalWrite(ledPin, HIGH); // Toggle status LED
    delay(1000);
    digitalWrite(ledPin, LOW); // Toggle status LED
  }

}


APPENDIX 2

Sensors.h code:

static int temperaturePin = 5;//14 Analog input 0
static int humidityPin=4;//15 Analog input 1static int moisturePin=2;//Analog input 2


int Temperatura(void)
{
 //the analog pin the TMP36's Vout (sense) pin is connected to the resolution is 10 mV / degree centigrade.
 //(500 mV offset) to make negative temperatures an option
 float temperature=analogRead(temperaturePin) * .004882814;//converting from a 0 to 1023 digital range
 // to 0 to 5 volts (each 1 reading equals ~ 5 millivolts.Example: 5:1024=0.004882814
 temperature = (temperature - .5) * 100;//0 degree begins in 500mV
 Serial.print("Temperature: ");
 Serial.print(temperature,0);
 Serial.println("\260C");
 return(int(temperature));                                                
}

int Humedad (void)
{
 //5V=1024;5000mV/1024=4.882814mv por unidad
 float humidity=analogRead(humidityPin)* 4.882814;
 humidity=(humidity-800)/31;//Conversion of milivolts to humidity
 Serial.print("Air humidity: ");
 Serial.print(humidity,0);
 Serial.println("%");
 return(int(humidity));
}