The Animatronic Robotic Hand

A new way to pursue the "Rubber Hand Illusion"

Programming : Tasks

  1. Communication with the user: LCD screen and buttons
  2. Read signals from 5 Flex Sensors and write it on Servo
  3. Implementation of a certain delay

I. Communication with the user

We use the libraries:
      #include < Wire.h >
      #include < LiquidCrystal_I2C.h >
With simple functions as:
      lcd.clear();
      lcd.print();

Four buttons are used: OK, +, -, CHANGE
The buttons are set as entries with pull-up resistances;
      pinMode(buttonOK, INPUT_PULLUP);
Settings are asked at the beginning. We also made an initialization of the maximum and minimum values of resistance for each sensor (to map the value and fit the movement at its best). Each result is memorized in a vector high[] and low[]. High[0] is the maximum resistance for the analogic potpin 0.
CHANGE generates an interrupt when the program is running.

The user choose the delay and the program
Program 1 : standard mode (no delay)
Program 2 : only the index moves
Program 3: random mode, the fingers on the real hand actuate random fingers on the robotic hand

II. Read signals from 5 Flex Sensors and write it on Servo

We use the library:
      #include < Servo.h >
With simple function:
      servo.write(tmp);
We implement two functions:
      void write_position_from_finger(int number_of_servo, int potpin_finger)
      -number_of_servo: where to put result in the matrix named position[]
      -potpin_finger: on which analogic we must read. If this value is 9, we don't read the flex and set the value at 30 (to disable the servo).
      void write_position_on_servo(int number_of_servo, Servo servo)
      -number_of_servo: where to read in the matrix position[]
      -servo : which servomotor we work on

Each 10ms, we made a data acquisition. The resistance measurement is converted into degrees with the function map(). Then, the values are memorized in the matrix.
      Timer0 => use in delay()
      Timer1 =>use in servo()
We choose Timer2 (8 bits timer) with overflow interrupt and prescaler of 1024; and we set the count at 99.
Timer will count until 28-1=255 before interruption. Speed of timer = 16mHz/1024= 15, 625Hz Period to make 255-99(=156) steps is equivalent to 0,010016s = 10ms

void Timer2init()
{
TCCR2B = 0x00;         // Disable Timer2 while we set it up
TCNT2 = 99;         // Reset Timer Count (255-99) = execute ev 125-th T/C clock
TIFR2 = 0x00;         // Timer2 INT Flag Reg: Clear Timer Overflow Flag
TIMSK2 = 0x01;         // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
TCCR2A = 0x00;         // Timer2 Control Reg A: Wave Gen Mode normal
TCCR2B = 0x07;         // Timer2 Control Reg B: Timer Prescaler set to 1024
};

III. Implementation of a certain delay

We chose a static implementation with a circular vector:
Vector with a number of cases equal to the ratio between delay max/period of acquisition (here 1000ms/10ms = 100)
        in = position in vector for stocking reading value on finger
        out= position in vector to read value and set servo with it
When the value designed by out is set on servo, we can erase it => increment out.
When in or out is > 100, set it at 0 (circular vector)
Condition in interrupt to enable movement of servo => delay/10 cases between the two values.

Program Scheme

Program Scheme

Click the link on the side to display the entire program: Program

Program Parameters

const int buttonOK=8;
const int buttonPLUS=7;        // the number of the pushbutton pin
const int buttonMINUS=4;
const int buttonINTERRUPT=2;
volatile int a;         // flag to start a function
boolean changeData;        //disable timer2 interrupt if false
int choiceProgram;         //number of program
Servo servo0;         // create servo object to control a servo, 0 is for the thumb
Servo servo1;         // 1 is for the index
Servo servo2;         // 2 is for the middle finger
Servo servo3;         // 3 is for the ring
Servo servo4;        // 4 is for the pinky
int potpin_servo[5]         // analogic entry pin connected to the flex sensor
int tmp;         // working variable
int time;        //wanted delay in ms
int in[5];         // memorize the position in vector positions where we write the measured value for each servo
int out[5];         // memorize the position in vector positions where we read the measured value for each servo
int high[7];         // memorize for each finger the highest value of resistance (when hand is closed)
int low[7];         // memorize for each finger the lowest value of resistance (when hand is open)
int positions[5][100];         // delay max = 1000ms and interrupt occur every 10ms => 100 positions max

Examples of Parameters:

Functions

void setup()
void ServoInit()
        Puts servo in a fixed position, called just before the Init_data in the setup which wait a long time for response of the user.
void Timer2init()
        Initialization of the timer
ISR(TIMER2_OVF_vect)
        Interruption every 10ms that call write_position_on_servo and write_position_from_finger
void Init_data ()
        Function that writes on LCD and communicates with the user via buttons
void Change_data ()
        Function that writes on LCD and communicates with user via buttons while the CHANGE button is pressed.         The initialization of open and closed hand is not done anymore.
void InterruptChange ()
        Interrupt linked to the button to change the data when the program is running
void Program()
        Function that sets parameters of potpin_servo according to the chosen program. Called at the end of setup() and Change_data()
void write_position_on_servo(int number_of_servo, Servo servo)
        Puts the appropriate signal corresponding to the line number "number_of_servo" in position matrix
void write_position_from_finger(int number_of_servo, int potpin_finger)
        Reads the potpin_finger and writes value on line number_of_servo of position matrix.