Arduino + IPad

Introduction
Il est visiblement assez facile de connecter un IPad sur un Arduino.
A la base, il suffit de mettre un adaptateur USB pour son IPad, ce qui permet de raccorder l'IPad par l'intermédiaire d'un Cable USB identique à celui d'Arduino.

De son côté, Arduino utilise la librairie UsbKeyboard, ce qui lui permet de se faire passer pour un clavier USB.

C'est vraiment une approche très intéressant! 

Librairie UsbKeyboard
En temps normal, si l'on désire utiliser un Arduino couplé avec un logiciel, il faut utilisé le canal de communication série (qui passe par le port USB d'Arduino).
Cela réclame que le programme soit adapté pour traiter le flux d'information provenant du port série.

Permettre à Arduino de se faire passer pour un Clavier USB peu présenter de nombreux avantages.
Par exemple, il peut automatiser la saisie de donnée, piloter une application Web, activer des raccourcis claviers, etc.
Cela offre l'opportunité à Arduino d'intéragir avec un logiciel sans devoir modifier le logiciel!
C'est un avantage indéniable.

Pour en savoir plus sur ce point, je vous invite à lire l'article "Virtual USB Keyboard" (du livre Practical Arduino)

A terme, vous aurez besoin de la librairie VUSB-for-Arduino (Virtual USB).
Voir le projet VUSB-for-Arduino sur Google Code.

Plan de montage

Selon l'article source, les diodes Zener doivent êtres à 3.6V (pour une puissance de 0.5w ou moins, les diodes de 1W ne fonctionnent pas).

Code Arduino
Pour compiler ce code vous aurez besoin de VUSB-for-Arduino disponible sur Google Code. 

#include "UsbKeyboard.h"

#define BUTTON_PIN 7

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

void setup() {
  pinMode(BUTTON_PIN, INPUT);
  digitalWrite(BUTTON_PIN, HIGH);
  
#if BYPASS_TIMER_ISR
  // disable timer 0 overflow interrupt (used for millis)
  TIMSK0&=!(1<<TOIE0); // ++
#endif
}

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

int value = 0;
boolean started = false;

void loop() {
  UsbKeyboard.update();
  if (digitalRead(BUTTON_PIN) == 0) {
    started = true;
  }
  if (started) {
    value = (int)(10*analogRead(0)/1023.0);
    switch (value) {
      case 0: UsbKeyboard.sendKeyStroke(KEY_0); break;
      case 1: UsbKeyboard.sendKeyStroke(KEY_1); break;
      case 2: UsbKeyboard.sendKeyStroke(KEY_2); break;
      case 3: UsbKeyboard.sendKeyStroke(KEY_3); break;
      case 4: UsbKeyboard.sendKeyStroke(KEY_4); break;
      case 5: UsbKeyboard.sendKeyStroke(KEY_5); break;
      case 6: UsbKeyboard.sendKeyStroke(KEY_6); break;
      case 7: UsbKeyboard.sendKeyStroke(KEY_7); break;
      case 8: UsbKeyboard.sendKeyStroke(KEY_8); break;
      case 9: UsbKeyboard.sendKeyStroke(KEY_9); break;
      default: break;
    }
    delay(300);
    
#if BYPASS_TIMER_ISR  // check if timer isr fixed.
    delayMs(20);
#else
    delay(20);
#endif
   }
}

Code sur IPad 
Côté IPad, notre développeur en herbe à utilisé Processing.js, ce qui permet d'exécuté un code plus évolué depuis une page html.
Processing.JS peut être obtenu sur processingjs.org

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<!-- TITLE -->
<title>iPad + USB-keyboard + Processing.js</title>

<!-- Processing.js -->
<script type="text/javascript" src="excanvas.js"></script>
<script type="text/javascript" src="processing.js"></script>

<!-- Object for Keyboard Input -->
<style type="text/css">
form.keyinput input {
    position: absolute;
    padding-left: 0px;
    padding-top: 0px;
    border: 5px;
    top: 0px;
    left: 0px;
    width: 50px;
    height: 50px;
    background: #FFC000;//yellow;
    color: #646464;//black;
}
form.keyinput input:focus {
    background-color: transparent;
}
</style>

<!-- Update by keyinput -->
<script type="text/javascript">
var key_value ='';
function keyinput_update(){
    key_value = document.form_key.input_field.value;
    document.form_key.input_field.value = "";
}
</script>

<!-- JavaScript for Processing -->
<script type="text/javascript">
window.onload = function() {
    var canvas = document.getElementsByTagName('canvas')[0];
    var codeElm = document.getElementById('processing-code');
    var code = codeElm.textContent || codeElm.innerText || codeElm.text;
    Processing(canvas, code);
};
</script>

<!-- for Debug -->
<script type="text/javascript">
function msg(text) {
    document.getElementById('message').innerHTML = text;
}
</script>

<!-- Processing Code -->
<script id="processing-code" type="application/processing">
void setup(){
  size(768, 902);
  background(0);
  noStroke();
}

int count = 0;

void draw(){
  if ( key_value>=0 && key_value<=9 ) {
    count = key_value;
  } else {
    count = 0;
  }
  background(100);
  for (int i=0; i<count; i++) {
    fill(255,192,0);
    rect(100,760-80*i, 0.7*width,50);
  }
}
</script>

</head>
<body>
    <canvas style="position: absolute; top: 0px; left: 0px;"></canvas>
    <form action="#" class="keyinput" name="form_key" onkeyup="keyinput_update()">
        <input name="input_field">
    </form>
    <div id="message"></div>
</body>
</html>

Exemple en vidéo

Références