two arduino boards, one servo

Hello!

I have a situation in which I must control a single servo from two distinct Arduino boards, at different times. The reason is, software is too big for a single Nano/Mini/Micro board and a Mega is too big to fit in my product. So I split the software in two Nanos.

So, I would like to know what would happen(in case someone has any idea, or has actually tried it), if I had for instance two Arduino boards with one of each board's PWM outputs connected together to a single servo.

Of course I would detach() the servo from the software on the first board and signalize the second board (via a digital pin, sending 5v), so it can attach() the servo and operate it. Eventually, I would like to return control of the servo to the first board, so I would drop the voltage on the digital pin to 0v hoping the second board would dettach() the servo and the first board re-attach() it.

Would it work? Are there any risks of frying things? Thanks.

Why not leave the servo under the control of one Nano and have the other Nano send it instructions when it wants the servo moved. Like the skipper on a ship tells the helmsman to turn the wheel.

...R

You mean "bypass" PWM signals from the first board trough the second board, then when I need the last to take over the servos I simply hijack them? How can I accomplish that (using serial between the two Nanos is not an option for this project)?

I do not think that is what Robin means.

Connect the servo to one board. Only that board maintains the position of that servo.
When the software on that first board determines that the servo needs to be in a new position, it writes to that servo to make it so.
The second board does not connect to the servo. It only communicates with the first board. One of the elements of that communication between boards is a request to change the position of the servo. When the software running on the second board determines that the servo needs to be in a new position, it sends a request to the first board.

You say you split the software between 2 boards. How do they interact?

@vinceherman has interpreted me correctly. (Thanks)

...R

vinceherman, I can use a digital pin from the first board as an output, connect it to a digital pin on the second board using it as input over there. If I am sending 0v from the first board, the second board should let the first board control the servo, whereas if I am sending 5v, it is a signal for the second board to operate the servo. Send 0v back from the first board trough that pin and the second board releases the servo back to the control of the first board.

The problem is, I can only use a single pin to exchange information, software serial between the two board is out of the question, as the two of them are already quite busy and tight-packed.

I was asking Robin2 if do a PWM bypass would be a good idea. (like, while the voltage on the flag pin is 0v, the second arduino receives the servo output from the first in a PWM input port, and repeat it exactly as it came trough in a PWM output port where the servo is connected. When the flag pin goes 5v the second board stops copying the signal from the first and printing it to the servo, to take control of the servo for itself).

The problem is, I don't know how to bypass PWM trough an arduino with reliability and performance.
I though of this idea before, but I decided to come here to ask if the original servo.attach() / servo.detach() would work. Either that or PWM bypass, I don't care, as long as it works.

Thanks to both of you guys.

jeferson_lucio:
I was asking Robin2 if do a PWM bypass would be a good idea.

You seem to have missed the point of my Reply #1 and @vinceherman's clarification.

There is no need for anything as complicated as you propose.

Suppose the servo is connected to NanoA. At regular intervals NanoB can send (say) -1 (using Serial) to NanoA. When NanoA receives -1 it knows that it (NanoA) has control of the servo. If NanoB wishes to take control it sends a number (other than -1) representing the required servo angle - say it sends 97. When NanoA receives the 97 it knows to move the servo to 97 degrees.

...R

Yes, I've got it. However, as I said before(quoted bellow), I can't afford using serial, the hardware ones are already in use, as well as one instance of software serial on both boards, that is why I came to this forum.

...that (using serial between the two Nanos is not an option for this project)?....

It sounds like you have a lot going on on both boards.

Do the sketches on the 2 boards interact with each other at all?

Analog mux or 1-of-8 data selector?

Do the sketches on the 2 boards interact with each other at all?

Yes… A little bit… One holds an autopilot that can fly via GPS (Second Board).
(Please do not tell me to go and buy an APM like Arducoter, Flyduino, etc. I want the challenge of building it myself).

The other (First Board) runs a Remote Control Receiver (Yes, instead of buying, I made my own, Arduino in my hands, with a pro joystick, Arduino on the plane and a couple of UHF HC-12 shields between us. Flies over 1km with no problem, no noticeable lag, the responsiveness is impressing).
(Please do not tell me to go and buy a decent pro remote kit for RCs. I enjoyed that much building it myself). (There’s a photo attached to the post.)

This RC project has already been flown dozens of times. It proved itself worthy.

Now I would like to implement my own RTL (“Return To Launch” mode).
The RTL software and sensors live on the Second Board, had to do that, cuz libraries for GPS, Magnetometer, IMU and Barometer, when joint together, plus my own code, have a huge footprint!

The idea is to maintain both boards on the plane. The RC board only turn servo control to the RTL board when a button is pressed on the remote or when radio contact is lost… Hence the idea of using a digital output pin from the RC board to the RTL one. When 5v comes from the RC board in a certain pin of the RTL one, it is a signal that RC board gave up servo control, and the RTL board needs to take over control of servos, until it receives 0v from the RC board again, then it will be time to give up servo control back to the RC Arduino.

Another idea that I considered, consists in “channeling” the servo commands from the RC board to the servos via RTL board. Injecting PWM signal (three servos) to the RTL’s PWM inputs and have them bypassed by software to the servos(connected to the RTL board PWM outputs). When receiving the 5v, the RTL board would ignore its inputs from the RC board and drive the servos by itself.

@jeferson_lucio Just for clarity, although probably not significant to the solution of the problem, using the servo library, servos can run on all digital pins (including the A0-A5 analog pins used as digital pins); they don't have to be on PWM pins.

The servo library's control of a servo is not PWM in the Arduino analogWrite() sense.

jeferson_lucio:
Yes, I've got it. However, as I said before(quoted bellow), I can't afford using serial, the hardware ones are already in use

I think we have a typical xy problem.

You need to tell us all about both Nano programs and post both programs. My suspicion is that the whole thing could be organized better.

...R

So far I'm having success in detaching the servos and re-attaching them without any major incident. Control is re-gained from the first board with no estrange/unexpected behavior. I haven't tried to add the second board to the circuit yet. When I detach the servos I set the pins they are connected to as inputs, so I believe, that when the second board takes over, there will be no risk of frying the pins (where the servos are) on the first board. Of course, when control goes back to the first, I reset the pins as digital outputs, before attach(), and it works.

I just realized that when I wrote Reply #12 I had completely missed Reply #10 - apologies.

It is an interesting problem. What you say in Reply #13 seems reasonable. I will be watching to see how it works out.

...R

Thanks Robin2, I'll keep you guys posted.

Hey lads! It worked!

Board N.1 -->

if(rtl_==1){ /* Received from the remote control, calls Return To Launch point */
  if(servos_attached){
     servo_left.detach(); /* Detach all three servos */
     servo_right.detach();
     servo_elevator.detach();
     pinMode(SERVO_LEFT, INPUT); /* Just for safety, set the servo pins on this board as inputs */
     pinMode(SERVO_RIGHT, INPUT);
     pinMode(SERVO_ELEVATOR, INPUT);
     delay(10); /* Just to be on the safe side, before handing over control to board N.2 */
     digitalWrite(RTL,HIGH); /* Notify board N.2 that the servos have been released */
     servos_attached=false;
  }
} else {
  if(!servos_attached){
     digitalWrite(RTL,LOW); /* Notify board N.2 that board N.1 wants servo control back */
     delay(10); /* Just to be on the safe side, before taking back control from board N.2 */
     pinMode(SERVO_LEFT, OUTPUT); /* Set the servo pins on this board back as outputs */
     pinMode(SERVO_RIGHT, OUTPUT);
     pinMode(SERVO_ELEVATOR, OUTPUT);
     servo_left.attach(SERVO_LEFT,600,2400); /* Re-attach all three servos */
     servo_right.attach(SERVO_RIGHT,600,2400);
     servo_elevator.attach(SERVO_ELEVATOR,600,2400);
     servos_attached=true;
}

Board N.2 -->

void loop() {
  if(digitalRead(TAKE_CONTROL)) { /* input from the pin 'RTL' of the board N.1 */
    attachServos();
  } else {
    dettachServos();
  }
}

void attachServos(){
  if(!servos_attached){
    delay(10); /* Just in case... Lets wait a little before proceeding, shall we? */
    pinMode(SERVO_AILERON_LEFT, OUTPUT); /* Set the servo pins on this board back as outputs */
    pinMode(SERVO_AILERON_RIGHT, OUTPUT);
    pinMode(SERVO_ELEVATOR, OUTPUT);
    servo_aileron_left.attach(SERVO_AILERON_LEFT,600,2400); /* Re-attach all three servos */
    servo_aileron_right.attach(SERVO_AILERON_RIGHT,600,2400);
    servo_elevator.attach(SERVO_ELEVATOR,600,2400);
    servos_attached = true;
  }
}

void dettachServos(){
  if(servos_attached){
    servo_aileron_left.detach(); /* Detach all three servos */
    servo_aileron_right.detach();
    servo_elevator.detach();
    pinMode(SERVO_AILERON_LEFT, INPUT); /* Just for safety, set the servo pins on this board as inputs */
    pinMode(SERVO_AILERON_RIGHT, INPUT);
    pinMode(SERVO_ELEVATOR, INPUT);
    servos_attached = false;
  }
}