I was wondering how can I be able to control multiple actuators simultaneously, and independently using Arduino. I am working on a project that requires me to control the actuators and make it so that it would be able to mimic the knuckle movement of a human hand. I'm new to it, and I am not sure what function would be useful for this matter, and how could I be able to make move independently of one another.
We're going to need more detail.
Or ask a moderator to move this to "Project Guidance".
Or both.
Each actuator would be controlled independently by the Arduino, probably using digital outputs, but that depends on the actuators. The Arduino can be programmed to output to each actuator one after the other thousands of times per second. So, although only one actuator is being controlled at a time it happens so fast that they appear to be controlled simultaneously.
What sort of actuators are you interested in using and how many ?
Thank You! I intend to use actuonix PQ12-P Linear Actuator with Feedback, at this moment I wish to control 4 but at this moment I can only control one. I do that by sending inputs from 0-1023 and the actuator would extend and retract according to the input I sent to it. Now I wish to know how can I be able to set it would be able to determine the required position on its own, and now I wish to know how could I be able to control all 4 of them at the same time independently. Should I create a header file in a library? or is their any function I could be able to use?
UKHeliBob
Hi,
Welcome to the forum.
Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Your existing code and diagram for the single actuator you have will help us help you.
Have you got full control both ways of the servo?
What model Arduino are you using?
Thanks.. Tom...
at this moment I wish to control 4 but at this moment I can only control one
Have you tried to control more than one ? What happened ?
Do you really need to use the feedback of the current actuator position when, after all, you are commanding the actuator to move to a particular position.
What options does your actuator have?
PQ12-GG-VV-C
GG is gear reduction: 30, 63, or 100
VV is motor voltage: 6 or 12
C is controller: P, S, or R
P= Potentiometer feedback
S = Limit switches
R = RC Hobby Servo input (1000 to 2000 microsecond pulses) 6V Only
Since you say "with feedback" I'm guessing you have Type P. That means you need an H-Bridge motor controller for each and an analog input for each to read the feedback. For optimum positioning you would probably want a software PID control loop for each motor controller.
Yes I have the P type 12V. I tried to control multiple ones, but it came up to be a mess on my code, so it wasn't able to run properly. The feedback is so we are able to know its current location before moving it, and also with the H-Bridge read the amount current flowing thought it. On the video it shows the one that I am using, and what I want it to do.
jahb3c:
Yes I have the P type 12V. I tried to control multiple ones, but it came up to be a mess on my code, so it wasn't able to run properly.
It sounds like the sketch that you have not shown is full of mistakes.
Did you want us to guess what your mistakes are without seeing the code or knowing what motor drivers you are using or how they re connected? I don't think that is going to happen.
If you want free help with your sketch, show your hardware and your sketch.
If you want a (paid or volunteer) collaborator to work with you on the sketch then you should post a detailed description of the project and progress so far in the "Gigs and Collaboration" forum.
NOTE: "Wasn't able to work properly" is not a useful problem description. If you want help you have to say exactly what you want the sketch to do and what it is doing that is different from what you want.
If they are to move independently (or, with the illusion of independence), then you'll need to break away from using delay(). As with everyone else: read and understand the "blink without delay" example. It can also be very helpful to use C++ classes to encapsulate the behaviour of each joint.
Hello below is my code. I am using Arduino MEGA 2560, and I am connecting the potentiometer reference of the actuator to an H-Bridge (L298N) which would allow me to connect 2 actuator and also being able to read the current flowing through the actuator.
#include <Servo.h>
#define in1 30
#define in2 31
#define enA 2
const int wiper1 = A0; //Position Potentionmeter Feedback
const int sense1 = A1; //Channel A Current Sense
int wip1 = 0;
int sen1 = 0;
float voltage1 = 0;
float current1 = 0;
int acSpeed = 0;
void setup()
{
// put your setup code here, to run once:
pinMode(enA, OUTPUT); //Sets Enable A pin as OUTPUT for controlling Actuator Speed
pinMode(in1, OUTPUT); //Sets INPUT 1 pin as OUTPUT for Motor Power and Potentiameter Refference
pinMode(in2, OUTPUT); //Sets INPUT 2 pin as OUTPUT for Motor Power and Potentiameter Refference
pinMode(wiper1, INPUT); //Sets Analog Pin 0 as an INPUT Pin
Serial.begin(9600);
}
void gotoPos(uint16_t x)
{
if (x <30) x=30;
if (x> 990) x=990;
uint8_t poof=0;
if (analogRead(wiper1)<x)
{
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
digitalWrite(enA,HIGH);
do{ Serial.print("<");Serial.println(analogRead(wiper1)); delay(100);poof++; if (poof>=40)goto fakeout1;}while (analogRead(wiper1)<x);
digitalWrite(enA,LOW);
}
else
{
digitalWrite(in2,HIGH);
digitalWrite(in1,LOW);
digitalWrite(enA,HIGH);
do { Serial.print(">");Serial.println(analogRead(wiper1)); delay(100);poof++;if (poof>=40)goto fakeout2;}while (analogRead(wiper1)>x);
digitalWrite(enA,LOW);
}
return;
fakeout1:
digitalWrite(in2,HIGH);
digitalWrite(in1,LOW);
delay(250);
digitalWrite(enA,LOW);
return;
fakeout2:
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
delay(250);
digitalWrite(enA,LOW);
return;
}
#define MAXSPEED 255
#define MINSPEED 254
void gotoPos_P(uint16_t x)
{
if (x <30) x=30;
if (x> 990) x=990;
uint8_t poof=0;
uint16_t currPos = analogRead(wiper1);
if (currPos<x)
{
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
//digitalWrite(enA,HIGH);
do{
analogWrite(enA,map(abs(currPos-x),0,1023,MINSPEED,MAXSPEED));
currPos= analogRead(wiper1);
//Serial.print("<");Serial.println(currPos); delay(100);
} while (currPos<x);
digitalWrite(enA,LOW);
}
else
{
digitalWrite(in2,HIGH);
digitalWrite(in1,LOW);
//digitalWrite(enA,HIGH);
//digitalWrite(enA,HIGH);
do{
analogWrite(enA,map(abs(currPos-x),0,1023,MINSPEED,MAXSPEED));
currPos= analogRead(wiper1);
//Serial.print(">");Serial.println(currPos); delay(100);
} while (currPos>x);
digitalWrite(enA,LOW);
}
Serial.print(">");Serial.println(currPos); delay(100);
return;
fakeout1:
digitalWrite(in2,HIGH);
digitalWrite(in1,LOW);
delay(250);
digitalWrite(enA,LOW);
return;
fakeout2:
digitalWrite(in1,HIGH);
digitalWrite(in2,LOW);
delay(250);
digitalWrite(enA,LOW);
return;
}
void loop()
{
uint16_t val=512;
while(1)
{
if (val!=0){
gotoPos(val);
Serial.print("sending:");
Serial.println(val);
}
while(Serial.available()<2);
val=Serial.parseInt();
}
}
The reason why trying to add more actuators to your code makes a mess is because you are using busy-loops for detecting the end of your motion. While one actuator is in a busy-loop none of your other actuators can make any changes (starting, stopping, changing speed...). You will probably have problems with overshoot, too.
Yes I do have the problems you mentioned. This is my first time using Arduino program for a project, that is why I'm looking for better ways of doing this without interfering with other actuator or even make a bigger mess withing the code. I would appreciate if you know a different approach I should take. Thank you for your time.
Look into arrays, and possibly structs.
Driving many devices is virtually no different than driving one.
Start by considering your problem. Mashing and copying code will never work.
This will be a unique problem and solution sculpted to your requirements.
APPROACH:
Each actuator driver has a known 'current' position, and a 'target' position.
This may need to be recalibrated from time to time (e.g. at startup, and may use feedback to detect the limits or thresholds).
Using these primitives, you can arbitrarily set the target position, and the logic of your code will 'chase' the target until it is reached. You may want to add speed ramping - so the motion looks more subtle.
Your motion code actually needs to do very little with a small amount of logic to perform these functions.
You can do other stuff during the idle cycles!
DO NOT use delay() in real-time projects like this!
Hi,
What is the function of "fakeout1"and "fakeout2" ?
"while" and "do" statements are code blockers if not used properly, and "delay" is a code blocker no matter how you use it.
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?
Are you using a L298N shield or breakout board or IC on protoboard?
Thanks.. Tom..
Here is your main loop:
void loop() {
readInputs();
doCalculations();
for(int i=0; i<numMotors; i++) {
moveMotorALittleBit(i);
}
if(itsTimeToOutputToTheHuman()) {
doOutput();
}
}
Just keep that loop running over and over a few hundred times per second by making sure that each function never takes more than a few milliseconds (preferably microseconds) to do a small job.
If your actuators tend to overshoot you should consider switching from Bang-Bang control to PID control. The PID controller will control the speed of the motor so it slows down as it approaches the target position and stops at the right place. There is a library (found via Sketch->Include library->Manage Libraries...) to take care of the math: "PID by Brett Beauregard"
Hi,
When you stop your actuator, does it instantly stop, or run on a little?
If it runs on you may need to get the H-Bridge to BRAKE briefly to ring the motor to a stop.
Tom....
@jahb3c - how are you getting on?
Attached is the schematic of my circuit design. The chip there is not the L298, not exactly the L298N, but the pins are somewhat the same. The design should be able to help you understand a little how it would work. I am yet still trying to figure out a way to simplify the code without having to put everything on the same loop, because as you all have mentioned it would be a big mess on the program.