This is a general question. I could provide code if needed, but I think it would be better to explain my problem and see if anyone has a solution.
I have been using Arduino successfully for about 6 months now and have written several useful programs. I am a novice programmer, but have written simple programs in several languages, including machine code (years ago!).
I would like to control the position of two different motors simultaneously with one Arduino Uno. It has two interrupt pins, so can keep track of two rotary encoder pulses. However, there is an issue when trying to position both motors at the same time. I would like to call a motor control function that takes a position and a mode input and depending on the mode, will either drive motor 1 (to a specific position), or motor 2, or both at once with one or the other being a master (for position) while the other simply uses the same duration motor pulses.
In order for the motor control function to work as intended, I need to be able to keep track of the position of one of the two motors depending on the 'mode'. In order to do this, I need to be able to have a while loop that stops based on a variable value (the encoder counter) reaching a limit. But I want this to be able to change which encoder counter is used based on the mode. I thought I could use a single variable (say, 'Counter') to hold one or the other encoder value and use a switch statement at the beginning of the function to have Counter equal either Encoder1 or Encoder2. But realized this will only cause them to be equal at the beginning of the function and will not continue to track as the ISR updates the value.
So (finally) here are my questions:
Is there a way to have two variables constantly stay the same value without having a new assignment statement?
OR, is there another way to write the motor control function?
Can you write a program that has a digitial input of a position, say 8 bits? 10 bits? and will servo a motor to that position? Either on the digital pins or through serial of some sort.
If so, just grab a second processor and have one motor "talk" to the other one. Suddenly you can have N motors slaving off the first one.
@AWOL - You lost me. Can you write in C++ on Arduino? I have been using the std Arduino IDE and don't know how to use anything else. Also a reference to the C++ library is a little vague. When I saw you post, I was hoping a 'reference' was a way to refer to another variable.
@jim - this is a very simple DC motor driven by PWM signal to create variable DC voltage. It does not start or stop on a dime and I only know the position by counting encoder pulses.
not sure i fully understand your problem nor why you think you want two variables to have the same value
a common approach for controlling a motor with feedback is to have a target value that is an input to a process that runs continuously to control a motor by comparing the feedback value from the motor to the target. the difference between the target and feedback determines whether a motor is driven forward or reverse and the motor is no longer driven when the different is 0 +/- tolerance
sounds like your "mode" would determine which encoder is used as feedback as well as which or both motors are driven
i doubt that the same drive waveform would result in both motors being a the same position at the same time
You’ve said it is a general question, but it appears very specific to your set up.
Controlling either motor independently should be no problem. Have you already got that far?
I have difficulty visualizing what is supposed to happen when both motors should be controlled simultaneously in a master/slave arrangement. What are these motors driving?
brisguy:
I would like to control the position of two different motors simultaneously with one Arduino Uno. It has two interrupt pins, so can keep track of two rotary encoder pulses. However, there is an issue when trying to position both motors at the same time.
Everything you said after that was more or less nonsense, or at least inadvisable. Just make two independent control procedures, one for each motor, and multitask them. Your attempts to integrate them will only create a mess.
If they interact or the operation of one depends on the other, do it in the higher level code that controls the motor code. Don't try to do it inside the motor code.
Thanks all for the feedback. It may be that I cannot do this with a single processor, which is OK. I was taking it as a challenge. I was hoping that giving some background would help, but it seems to have overshadowed my basic question about variable assignment.
sounds like your "mode" would determine which encoder is used as feedback as well as which or both motors are driven
Correct. The trick is getting the motor drive to stop at the right point for both motors simultaneously.
i doubt that the same drive waveform would result in both motors being a the same position at the same time
That is probably also correct, but they do not have to be at the exact same encoder position. Within +-5 is probably OK. I should also point out that it is not a motor postiion I am trying to control, but a cam being driven by the motor which has 200 or so encoder pulses per revolution.
or at least inadvisable. Just make two independent control procedures
When both motors are active, they have to respond to the same stimulus - an analog voltage that triggers a movement to one of two cam positions. They have to respond immediately and by the time they have reached the target position, there will be another analog trigger almost immediately afterward, so no time to control separately. As you suggest, the hihger level code monitors the analog votage and calls the motor function accordingly. Right now I only have one motor control function but it will not return control to themain program until it is complete i.e. after the cam is in the desired position. It would be too late to call a second one by that time. You have given me an idea of how I might divide up the current functoin into smaller pieces though.
Right now I only have one motor control function but it will not return control to themain program until it is complete i.e. after the cam is in the desired position.
brisguy:
When both motors are active, they have to respond to the same stimulus - an analog voltage that triggers a movement to one of two cam positions.
presumably this analog voltage determines a "target" position value.
presumably there is an encoder on each motor and its two outputs connected to interrupts. the ISRs maintains a "position" value for each motor
loop() calls a single control function to compare the target to one of the motor positions determined by "mode" and mode determines whether the difference drives one/both motors. the control function continues to be called even when the error (target - position[0/1]) is zero +/- tolerance.
brisguy:
You have given me an idea of how I might divide up the current functoin into smaller pieces though.
there's the ISR, the control function and something that determines the target. mode can be changed at any time
once at position, changing target or mode cause the motors to adjust
The basic principle of multitasking is to have one big loop
inside that one loop all details of
-setting up mode
driving the motors
evaluating position
etc.
is done.
Each "iteration" = "run-down" of this loop multiple if-conditions where executed and depending on that if-conditions parts of the code
get executed when if-condition evaluates to true
or
-get not executed when if-condition evaluates to false.
please describe in detail what your camera should do,
what is an acceptable time-difference for both motors to reach a certain position. I guess it don't have to be nano-seconds)
what is the maximum rpm of the motor = what is the maximum pulse-frequency coming from the encoder
If one motor is on full speed and you just switch off the current for the motor how many encoder-pulses does the mechanic overshoot over the number of pulses in the moment of switching off the current?
How much weight has to be moved?
At what speed does this weight has to be moved? A rough estimation is enough less than 0,1 seconds for a 90 degree turn or 5 seconds for a 10 degree turn.
The effort you have to invest to get what you want depends on the details asked above.