I'm in a quandary. I have one of those feed back electric actuators that I am trying to control. It has a pot inside the actuator to give position information. The value from the pot ranges 0 to 1026 with the analogRead function.
I am using a 3 amp H-Bridge, a TLE5206 motor driver to control the actuator. It uses two digital inputs for motor control, motA and motB. The motor controller works like this, pin1 and pint 2 high, it freezes the motor. If pin 1 is high and pin 2 is low, motor turns clockwise. If pin 1 is low and pin 2 is high, motor turns counterclockwise.
Variables are "actpos", for actuator position from the pot; and "command" from another pot I'm trying to use to control the position that also has a value from 0 to 1026.
Movement code:
if (command > actpos) {
while (command > actpos) {digitalWrite(motA,HIGH); digitalWrite(motB,LOW);}}
if (command < actpos) {
while (command < actpos) {digitalWrite(motB,HIGH); digitalWrite(motA,LOW);}}
My problem is that it either goes all the way one way (there is a limit switch built into the actuator), or all the way the other. It won't just move a hair. At the top of the loop there is a high high command for the motor pins to stop it, so I thought that once the condition of the "while" loop was met, the motor would stop. It's like the Arduino is too slow or something.
if (command > actpos) {
while (command > actpos) {digitalWrite(motA,HIGH); digitalWrite(motB,LOW);}}
So, once the relationshi9p between command and actpos is established, keep running the motor in one direction forever. Doesn't seem all that useful. Something should be happening to change command or actpos in the while loop, or in an interrupt handler.
How can I loop the motor on until the value of the reference is met? Can you loop inside a loop? That's what I was trying to do with the "while" function.
But in the while loop you weren't looking at the pot output at all. The variable
doesn't change unless you change it explicitly. You need to call analogRead()
No, because you've just declared a different "actpos" inside the while loop
that is unconnected with the one outside the loop,
while (command > actpos) // loop forever as this actpos never changes
{int actpos = analogRead (potpin) ; // declare a new actpos variable
digitalWrite (motA, command >= actpos) ; // use the new actpos variable
digitalWrite (motB, command <= actpos) ;}
What would work is
while (command > actpos) // loop forever as this actpos never changes
{
digitalWrite (motA, command >= actpos) ;
digitalWrite (motB, command <= actpos) ;
actpos = digitalRead (potpin) ; // update the one and only actpos variable
}
If you do wait for a change in state you don't need to use those comparisons in
the digitalWrites, you know the state:
while (command > digitalRead (potpin)) // no need for an actpos variable at all
{
digitalWrite (motA, HIGH) ;
digitalWrite (motB, LOW) ;
}
If you wait like this no other code in loop() will run, however, so anything else you
are controlling will become unresponsive - its better to handle everything without
waiting or delaying in the body of loop - this means keeping track of state with
state variables.
Okay, I'm still confused. Thanks for all the input everyone.
The way the program works is :
Read input reference pot position to create a command to destination.
Read position of the actuator (pot inside actuator).
Compare the two-
If command is > actuator position, extend actuator to match command
If command is < actuator position, retract actuator to match command
Basically, it's turning the actuator into a servo. I've tried the above suggestions, but it just moves all the way out or all the way in depending on where the command pot is. I want it to move to a location. How do I loop inside the main loop? I'm so confused..
c131frdave:
it just moves all the way out or all the way in depending on where the command pot is. I want it to move to a location.
If you had implemented the algorithm you described then it would do what you say you want, so clearly you haven't implemented it correctly. It should be simple:
Read the required position.
Read the actual position.
Command the actuator to move towards the required position.
Do that repeatedly, and you have reproduced the functionality of a standard cheap RC servo.
Maybe in a couple of days I can see if I can adapt some servo code to the TLE5206 chip setup. I've several of the chips but never used them. I think they would be ideal for driving the 12v linear actuators.
I'd appreciate that. Is there servo code available that I can look at? I've done searches, but it just shows how to move a hobby servo with pulses.
Peter, that's what I'm trying to do. I understand completely what I need to do. I just don't understand how to do it. I don't now how to loop the movement from one spot to another inside the main program loop.
The following is the current state of the code. It doesn't work:
Another thing I don't understand is why does the communications drop out? I uploaded the program fine, but when I change it, it loses the serial port (COM7). The computer sees COM7, and lists the Arduino UNO in the devices screen. Drives me crazy. I have to unplug the USB about ten times before the program sees it again. Is it because I'm using the Serial monitor to display the values? Do I need to exit out of that before sending code?
if (command < actpos) {
while (command < analogRead(A3)) {digitalWrite(motB,HIGH); digitalWrite(motA,LOW);
actpos = analogRead (A3);
}}
So what it does now is move the actuator one way, but then it gets stuck because the motor overshoots (I guess), and stays locked in the loop. I have the serial monitor on, and you can see when it tells it to retract, but then it overshoots, and won't come back out... Frustrating...
Pick a specific scenario that causes the problem. Which loop is it getting stuck in? Are the actions taken in that loop expected to cause the loop condition to become false? If so, and if they aren't actually becoming false then check whether the output action is correct and whether it's having the effect you intended. (For example, you move one of two different motors based on an input comparison; it'd be more intuitive to move the same motor in different directions - I don't know whether that is what you intended.)
Also, given the way you check the position it seems to me that unless you manage to hit on the command being exactly equal to the input value (pretty unlikely in the real world) that the code would always try to move one way or the other. Depending how this bit of code is called, that might give the impression that it's stuck in the loop when it actually isn't.
It seems to be getting stuck more often in the second loop. I inserted serial prints into the while loop to show the command value and the value of the actuator position pot, and it is just sits there.
I know my syntax sucks, but that's because I'm making changes on the fly. I'll try to make it more pretty and organized for you all going forward.
PeterH:
Also, given the way you check the position it seems to me that unless you manage to hit on the command being exactly equal to the input value (pretty unlikely in the real world) that the code would always try to move one way or the other. Depending how this bit of code is called, that might give the impression that it's stuck in the loop when it actually isn't.