Robotic Hand

I have built a robotic hand which is controlled by 5 motors. It is operated using either Automatic Control (Pressure Pad) or Manual Control (5 toggle switches).

I am having problems writing the code i need, as i need to set a variable equal to a certain time, eg. 3 seconds, which is the time taken for a finger to open and close. If a toggle switch is flicked down, a finger closes. If it is flicked up, the finger opens. But if the toggle sitch is flicked back, halfway between the finger opening and closing, the motor will turn for too long and push the finger back to much.

I need to figure out away of setting it to be between a certain time, for up and down movement.

If you already have some code that controls the motor it might help to quote that here for people to comment on - its probably less work than writing something from scratch and we will be using the same variable names as you...

as i need to set a variable equal to a certain time, eg. 3 seconds

unsigned long timeToFlipOff = 3000;

But if the toggle sitch is

The what?

I need to figure out away of setting it to be between a certain time, for up and down movement.

What is “it”?

You can note what time the switch was first pressed, and when it is pressed again. If the difference is less than the required time, you can ignore the second press, or you can run the motor in reverse for less time.

PaulS: What is "it"?

It's a weakness ...

http://en.wikipedia.org/wiki/Knights_who_say_Ni

Stop hating on me guys, or I'll squash you with my gigantic foot! I'm sorry I didnt explain very well, I was in a rush.

Okay, I have 5 motors, and each motor controls one finger ( that makes 5 fingers in total :/) if the motor turns clockwise, the finger opens. If the motor turns anticlockwise, the finger closes.

In which direction I want it to turn, is controlled by a toggle switch, one for each finger.

I am able, and have written the code to do this using a simple "if-else" command and setting the time for it to run to be 3 sec, (example time delay, may have to be altered (only slightly)) and it works.

However, if for example, I flick the toggle switch controlling the index finger, causing it to close, wait 1.5 sec ( so it's halfway between open and close position) and then flick the toggle switch back the other way, to open the finger again, it will tell the motor to then turn the other direction for 3 seconds! the motor turns 1.5 sec longer than it takes to return the finger to open position.

So, i need to write the code saying the total time the motor is turned on, is equal to the time it moved last, and total time in full in either direction to be 3 sec.

I hope I've made myself clear this time, and I would greatly appreciate help I'm solving this problem.

I think it would be easier to provide suggestions if you posted what your code is now. The actual logic of doing this isn't all that hard, but it really depends on exactly how you implemented what you have now.

read about the millis() function on the arduino reference... also look at this, http://www.cmiyc.com/blog/2011/01/06/millis-tutorial/. Use those instead of delays. that will also allow you to move more than one finger at a time. Then all you have to do is figure out when you need to stop (Timer in the example), subtract it from how far into the 3 seconds you are now(Timer - millis()),which is used in the next line... and set that as your new temporary timer limit. (temp = Timer - millis(); ) you also need some code to only set the beginning time once. not loop every clock cycle... ex:

boolean setTimer;
unsigned long Timer;
unsigned long targetTime = 3000;
unsigned long temp;

if (!setTimer) {
        Timer = millis();
        setTimer = true;
      }
      if (millis() - Timer >= targetTime) {
        setTimer = false;
        //do your code

Thank you for the information abot the millis function. I have uploaded the code i have at the moment, and as you can see its quite crude.
I am not really sure how to incorporate the millis fuction, or any other function for that matter which will help solve my problem.
Any suggestions?

int analogPin = A0;
int sensorValue = 0;
int threshold = 500;               //amount of pressure needed to turn motor

const int togglebetweenPin = 30;    //To switch between automatic(pressure pad) and manual(toggle switches one to five)
int togglebetween = 0;

const int toggleonePin = 31;       
int toggleoneState = 0;            

const int toggletwoPin = 32;
int toggletwoState = 0; 

const int togglethreePin = 33;
int togglethreeState = 0; 

const int togglefourPin = 34;
int togglefourState = 0; 

const int togglefivePin = 35;
int togglefiveState = 0; 



void setup() {                
  pinMode(44, OUTPUT);     //thumb motor
  pinMode(45, OUTPUT); 
  
  pinMode(46, OUTPUT);     //index motor
  pinMode(47, OUTPUT); 
  
  pinMode(48, OUTPUT);     //middle motor
  pinMode(49, OUTPUT); 
  
  pinMode(50, OUTPUT);     //ring motor
  pinMode(51, OUTPUT); 
  
  pinMode(52, OUTPUT);     //pinky motor
  pinMode(53, OUTPUT); 
  
  pinMode(2, OUTPUT);       //led showing automatic control active
  pinMode(3, OUTPUT);       //led showing manual control active
  
  pinMode(togglebetweenPin, INPUT);
  pinMode(toggleonePin, INPUT);         //controls thumb  44,45
  pinMode(toggletwoPin, INPUT);         //controls index  46,47
  pinMode(togglethreePin, INPUT);       //controls middle 48,49
  pinMode(togglefourPin, INPUT);        //controls ring   50,51
  pinMode(togglefivePin, INPUT);        //controls pinky  52,53
}

void loop() {
 
  togglebetween = digitalRead(togglebetweenPin);
  
  if (togglebetween ==HIGH) {                               //automatic part
  
  int analogValue = analogRead(analogPin);
  
  if(analogValue > threshold) {
  digitalWrite(44, LOW);  
  digitalWrite(45, HIGH); 
  digitalWrite(46, LOW);  
  digitalWrite(47, HIGH);
  digitalWrite(48, LOW);  
  digitalWrite(49, HIGH);
  digitalWrite(50, LOW);  
  digitalWrite(51, HIGH);
  delay(3000);            
}

  if(analogValue < threshold) {
  digitalWrite(45, LOW);  
  digitalWrite(44, HIGH); 
  digitalWrite(47, LOW);  
  digitalWrite(46, HIGH);
  digitalWrite(49, LOW);  
  digitalWrite(48, HIGH);
  digitalWrite(51, LOW);  
  digitalWrite(50, HIGH);
  delay(3000);               
              
}
}

  if (togglebetween == LOW) {                                        //manual part

  toggleoneState = digitalRead(toggleonePin);
  toggletwoState = digitalRead(toggletwoPin);
  togglethreeState = digitalRead(togglethreePin);
  togglefourState = digitalRead(togglefourPin);
  togglefiveState = digitalRead(togglefivePin);
  
  if (toggleoneState == HIGH) {
    digitalWrite(44, LOW);  
    digitalWrite(45, HIGH);
    delay(3000);              }
    
  if (toggletwoState == HIGH) {
    digitalWrite(46, LOW);  
    digitalWrite(47, HIGH);
    delay(3000);              }
    
  if (togglethreeState == HIGH) {
    digitalWrite(48, LOW);  
    digitalWrite(49, HIGH);
    delay(3000);              }
   
  if (togglefourState == HIGH) {
    digitalWrite(50, LOW);  
    digitalWrite(51, HIGH);
    delay(3000);              }
   
  if (togglefiveState == HIGH) {
    digitalWrite(52, LOW);  
    digitalWrite(53, HIGH);
    delay(3000);              } 
 }
}

All these: delay(3000); make what you're trying to do impossible. When the Arduino delays for 3 seconds, it will do absolutely nothing else. It won't respond to any of your toggles until that 3 second delay is finished, which also means the behavior you described (toggling a switch after 1.5 seconds) also is not happening. At least, not with the code you posted.

Think of delay() as basically meaning 'do absolutely nothing for the specified period of time'.

Look at the Blink without Delay example sketch for code that performs time based actions without blocking via delay().

I understand that, they're just for show. HOW do i change it to make it do what i want? :blush:

First things first. Change:

  digitalWrite(44, LOW);  
  digitalWrite(45, HIGH); 
  digitalWrite(46, LOW);  
  digitalWrite(47, HIGH);
  digitalWrite(48, LOW);  
  digitalWrite(49, HIGH);
  digitalWrite(50, LOW);  
  digitalWrite(51, HIGH);

to:

    for (byte i = 44; i <= 51; i += 2)
      {
      digitalWrite (i, LOW);  
      digitalWrite (i + 1, HIGH);  
      }

As for the delay, you need to remember the time, eg.

  if(analogValue > threshold && millis() - lastTime > 3000) 
    {
    lastTime = millis ();
    for (byte i = 44; i <= 51; i += 2)
      {
      digitalWrite (i, LOW);  
      digitalWrite (i + 1, HIGH);  
      }
    }

… where lastTime is an unsigned long used to remember when you last did whatever. I don’t know exactly what you are trying to achieve here, but that is a way of knowing when 3 seconds elapsed without actually delaying.

I understand that, they're just for show.

No, that is an absolutely ludicrous statement. The blink without delay example shows how to do something at a defined time, without the need to delay until that time has arrived. That the example merely turns a pin on and off, to which an LED is attached, and the resulting behavior appears to only show a blinking light, is completely irrelevant.

In which direction I want it to turn, is controlled by a toggle switch, one for each finger.

I suggest you switch from toggle switch operated motors to servos for your robot hand actuators.