Haptic Glove: Difference between revisions
Jump to navigation
Jump to search
| Line 59: | Line 59: | ||
F09F09F09F09F09 |
F09F09F09F09F09 |
||
F01F03F05F07F09 |
F01F03F05F07F09 |
||
F51F53F55F57F59 // continue vib after duration |
|||
000000000000000 // stop all vibrations |
|||
*/ |
*/ |
||
| Line 70: | Line 73: | ||
byte durationVib[NUMVIB]; // Duration for vibration |
byte durationVib[NUMVIB]; // Duration for vibration |
||
byte pinVib[NUMVIB] = {3, 5, 6, 10, 11 }; // Analog output pins that the vibration motors are attached to |
byte pinVib[NUMVIB] = {3, 5, 6, 10, 11 }; // Analog output pins that the vibration motors are attached to |
||
const byte FLEX_SENSOR_PIN=A0; // pin number of the flex sensor |
|||
const int NUMCONTACTPOINTS=4; // number of electric contacts points (contacts are made with conductive textiles and conductive threads) |
|||
byte pinContactPoints[NUMCONTACTPOINTS] = {2, 4, 7, 8 }; // Digital input pins that the contacts are attached to (the thumb finger is on the Vin). Use pull-up. |
|||
void setup() { |
void setup() { |
||
// initialize serial communications at 9600 bps: |
// initialize serial communications at 9600 bps: |
||
Serial.begin(9600); |
Serial.begin(9600); |
||
| ⚫ | |||
for (int i=0; i<NUMVIB; i++) { |
|||
pinMode(pinVib[i], OUTPUT); |
|||
} |
|||
for (int i=0; i<NUMCONTACTPOINTS; i++) { |
|||
pinMode(pinContactPoints[i], INPUT); |
|||
} |
|||
} |
} |
||
void loop() { |
void loop() { |
||
sendInputs(); |
|||
// TODO eliminate LF and CR |
// TODO eliminate LF and CR |
||
if (Serial.available() >=(NUMVIB*3)) { |
if (Serial.available() >=(NUMVIB*3)) { |
||
| Line 94: | Line 112: | ||
} |
} |
||
} |
} |
||
| ⚫ | |||
for (int j=0; j<NUMVIB; j++) { |
for (int j=0; j<NUMVIB; j++) { |
||
// calculate next duration |
// calculate next duration |
||
| Line 111: | Line 129: | ||
if(j==0){ |
if(j==0){ |
||
for (int i=0; i<NUMVIB; i++) { |
for (int i=0; i<NUMVIB; i++) { |
||
if |
// if levelVib[i]==0, the vibration is stopped |
||
analogWrite(pinVib[i], levelVib[i]); |
|||
| ⚫ | |||
} |
} |
||
} |
} |
||
// sendInputs(); |
|||
delay(minDuration*COEF); |
delay(minDuration*COEF); |
||
| Line 127: | Line 145: | ||
} |
} |
||
} |
} |
||
| ⚫ | |||
} |
|||
} |
|||
void sendInputs(){ |
|||
// send the flex sensor value on TX |
|||
Serial.print(map(analogRead(FLEX_SENSOR_PIN), 0, 1023, 0, 255)); |
|||
// send the contacts states flags on TX |
|||
for (int i=0; i<NUMCONTACTPOINTS; i++) { |
|||
if (digitalRead(pinContactPoints[i]) == HIGH) { |
|||
Serial.print("1"); |
|||
} else { |
|||
Serial.print("0"); |
|||
} |
} |
||
} |
} |
||
| Line 146: | Line 177: | ||
return parse(b)<<4; |
return parse(b)<<4; |
||
} |
} |
||
</pre> |
</pre> |
||
Revision as of 08:00, 28 September 2011
- UE/Module: Projet IHM Avancé de RICM5
- Enseignant: Didier Donsez
- Elèves RICM5: Christophe Havard (chef de projet), Renaud Collin
Introduction
La perception haptique est désormais présente dans les applications mobiles, ...
Ce projet vise à réaliser un gant à perception haptique pour des applications tactiles (écrans larges, ...)
Objectifs
Matériel
- 1 glove (cotton, leather)
- Arduino Uno or Lilypad or Arduino Fio
- 1 XBee module or Bluetooth module for wireless communication
- 5 Vibration motors
- 1 Flex sensor
For finger contacts
- Conductive textiles
- Conductive threads
Source code
/*
Haptic Glove
Reads 15 bytes that encode the level and the duration of the 5 vibration motors connected to the Arduino' PWM pins
Vibration Motor, sku: ROB-08449
http://www.sparkfun.com/products/8449
http://www.sparkfun.com/products/8468
"With a 2-3.6V operating range, these units shake crazily at 3V"
Septembre 18, 2011 by Didier Donsez
This example code is in the public domain.
Input format is 5 groups of 3 hexadecimal characters
one group per motor
first char is the vibration level (F is Max)
second char is the vibration level setted after the duration (0 to stop vibration)
third char is the duration of the vibration (value is char * 16 * COEF milliseconds)
Test by sending the following inputs with the serial monitor
F09000000000000
000F09000000000
000000F09000000
000000000F09000
000000000000F09
F09F09F09F09F09
F01F03F05F07F09
F51F53F55F57F59 // continue vib after duration
000000000000000 // stop all vibrations
*/
const int MAXVIB=180; // 180 is 3.6V if Vin is 5V (Arduino Uno)
const int COEF=10; // Coeficient for duration (Max duration is 256 * COEF milliseconds
const int NUMVIB=5; // Number of vibration motors (one per finger)
byte levelVib[NUMVIB]; // Level for vibration
byte levelEndVib[NUMVIB]; // Level for vibration after the delay
byte durationVib[NUMVIB]; // Duration for vibration
byte pinVib[NUMVIB] = {3, 5, 6, 10, 11 }; // Analog output pins that the vibration motors are attached to
const byte FLEX_SENSOR_PIN=A0; // pin number of the flex sensor
const int NUMCONTACTPOINTS=4; // number of electric contacts points (contacts are made with conductive textiles and conductive threads)
byte pinContactPoints[NUMCONTACTPOINTS] = {2, 4, 7, 8 }; // Digital input pins that the contacts are attached to (the thumb finger is on the Vin). Use pull-up.
void setup() {
// initialize serial communications at 9600 bps:
Serial.begin(9600);
for (int i=0; i<NUMVIB; i++) {
pinMode(pinVib[i], OUTPUT);
}
for (int i=0; i<NUMCONTACTPOINTS; i++) {
pinMode(pinContactPoints[i], INPUT);
}
}
void loop() {
sendInputs();
// TODO eliminate LF and CR
if (Serial.available() >=(NUMVIB*3)) {
for (int i=0; i<NUMVIB; i++) {
levelVib[i]=convertLevel(Serial.read());
if(levelVib[i]>MAXVIB) {
levelVib[i]=MAXVIB; // protect the motor
}
levelEndVib[i]=convertLevel(Serial.read());
if(levelEndVib[i]>MAXVIB) {
levelEndVib[i]=MAXVIB; // protect the motor
}
durationVib[i]= convertDuration(Serial.read());
if(durationVib[i]==0) {
durationVib[i]=0;
}
}
for (int j=0; j<NUMVIB; j++) {
// calculate next duration
byte minDuration=0xFF;
byte cpt=0;
for (int i=0; i<NUMVIB; i++) {
if(durationVib[i]>0 && durationVib[i]<minDuration) {
minDuration=durationVib[i];
cpt++;
}
}
if(cpt==0) {
return;
}
if(j==0){
for (int i=0; i<NUMVIB; i++) {
// if levelVib[i]==0, the vibration is stopped
analogWrite(pinVib[i], levelVib[i]);
}
}
// sendInputs();
delay(minDuration*COEF);
for (int i=0; i<NUMVIB; i++) {
if(durationVib[i]!=0) {
durationVib[i]-=minDuration;
}
if(durationVib[i]==0 && levelVib[i]>0) {
analogWrite(pinVib[i], levelEndVib[i]);
}
}
}
}
}
void sendInputs(){
// send the flex sensor value on TX
Serial.print(map(analogRead(FLEX_SENSOR_PIN), 0, 1023, 0, 255));
// send the contacts states flags on TX
for (int i=0; i<NUMCONTACTPOINTS; i++) {
if (digitalRead(pinContactPoints[i]) == HIGH) {
Serial.print("1");
} else {
Serial.print("0");
}
}
}
byte parse(byte b) {
if(b>='0' && b<='9') {
return (b-'0');
} else if(b>='A' && b<='F') {
return (b-'A'+10);
} else return 0;
}
byte convertLevel(byte b) {
return map(parse(b), 0, 0x0F, 0, MAXVIB);
}
byte convertDuration(byte b) {
return parse(b)<<4;
}