NEED HELP to move two servo motors simultaneously but in the opposite direction?

I am new at arduino and I'm making a robot that has two servo motors that are opposite of each other. if i program them to move in the same direction it ends up being in the opposite direction because they're opposite of each other on the robot.

this is a non-blocking library I wrote for a similar application, read through it, try it, and see if you have any questions.

you set the destination using the moveTo() function you will see in the .ion example file below this snippet. you will likely use something like:

int destination = 180;
servo1.moveTo(destination);
servo2.moveTo(180 - destination);

ino file:

#include "Sweep.h"

void startMoving(int value);
void stoppedMoving(int value);

Sweep servo1(startMoving, stoppedMoving);

void setup() 
{
  Serial.begin(9600);
  servo1.begin(4);
  pinMode(13, OUTPUT);
  Serial.print("Total Servos: ");
  Serial.println(Sweep::getInstanceCount());
}

void loop() 
{
  Sweep::update();
  static unsigned long lastMillis = 0;
  static bool toggle = true;
  if(millis() - lastMillis > 10000)
  {
    Serial.print("Moving to: ");
    Serial.println(toggle? 180:0);
    servo1.moveTo(toggle? 180:0);
    toggle = !toggle;
    lastMillis = millis();
  }
}

void startMoving(int value)
{
  Serial.print("motion started: ");
  Serial.println(value);
  digitalWrite(13, HIGH);
}

void stoppedMoving(int value)
{
  Serial.print("motion completed: ");
  Serial.println(value);
  digitalWrite(13, LOW);
}

.h file

#ifndef SWEEP_H
#define SWEEP_H

#include <Servo.h>
#include "Arduino.h"

#define MOTION_SPEED_INTERVAL 20  // milliseconds
#define MAX_SERVO_INSTANCES 4


class Sweep : public Servo {

  public:
    Sweep(void(*_startCallback)(int), void(*_endCallback)(int));
    //~Sweep();
    void begin(int servo);
    void moveTo(uint32_t newPosition);
    static void moveAllTo(uint32_t angle);
    static void update();
    static void update(uint32_t now);
    static int getInstanceCount();
    int getPosition (void) const;
    

  private:
    enum MotionState{
      ARM_STANDBY,
      ARM_MOVING,
    };
    void(*startCallback)(int);
    void(*endCallback)(int);
    static Sweep* instanceAddress;
    static int instanceCount;
    int servoPin;
    MotionState motionState = ARM_MOVING;
    uint32_t lastMotionMillis = 0;
    int currentPosition;
    int targetPosition;
    uint32_t sensedChangedMillis;
    static void setTargetPosition(Sweep* instance, int position);
};

#endif

.cpp file

#include "Sweep.h"
#include "Arduino.h"

int Sweep::instanceCount = 0;
Sweep* instances[MAX_SERVO_INSTANCES] = {nullptr};

Sweep::Sweep(void(*_startCallback)(int), void(*_endCallback)(int))
{
  instances[instanceCount++] = this;
  startCallback = _startCallback;
  endCallback = _endCallback;
}

int Sweep::getInstanceCount()
{
  return instanceCount;
}

void Sweep::begin(int servo)
{
  servoPin = servo;
  pinMode(servoPin, OUTPUT);
  attach(servoPin);
  moveTo(0);
  delay(1000);
  detach();
}

void Sweep::setTargetPosition(Sweep* instance, int position)  //flip-flop for the right vs. levt hands.
{
  instance->targetPosition = position;
}

void Sweep::moveTo(uint32_t newPosition)
{
  setTargetPosition(this, newPosition);
}

void Sweep::moveAllTo(uint32_t angle)
{
  for(int i = 0; i < instanceCount; i++)
  {
    setTargetPosition(instances[i], angle);
  }
}

void Sweep::update()
{
  update(millis());
}

void Sweep::update(uint32_t now)
{
  for(int i = 0; i < instanceCount; i++)
  {
    switch (instances[i]->motionState)
    {
      case ARM_MOVING:
        if(now - instances[i]->lastMotionMillis > MOTION_SPEED_INTERVAL)
        {
          if(instances[i]->targetPosition == instances[i]->currentPosition)
          {
            if(instances[i]->attached())
            {
              instances[i]->detach();
              instances[i]->motionState = ARM_STANDBY;
              instances[i]->endCallback(instances[i]->getPosition());
            }
          }
          else
          {
            if(!instances[i]->attached())
            {
              instances[i]->attach(instances[i]->servoPin);
            }
            if(instances[i]->targetPosition > instances[i]->currentPosition)
            {
              instances[i]->currentPosition++;
              instances[i]->write(instances[i]->currentPosition);
            }
            else
            {
              instances[i]->currentPosition--;
              instances[i]->write(instances[i]->currentPosition);
            }
          }
          instances[i]->lastMotionMillis = now;
        }
        break;
      case ARM_STANDBY:
        if(instances[i]->targetPosition != instances[i]->currentPosition)    
        {
          instances[i]->motionState = ARM_MOVING;
          instances[i]->startCallback(instances[i]->getPosition());
        }
      break;
    }
  }
}

int Sweep::getPosition(void) const
{
  return currentPosition;
}

If you are using continuous rotation not-really-servos, you control the speed and direction by writing some value on one side of ~90 degrees. Calculate the difference between that value and 90. Negate the value, and add to 90 to write to the other motor.

If you are using "not really servos" as the traction motors for a robot do not expect them to move at exactly the same speed as one another even when the same value is written to them.