Make 4 different motors turn a certain amount of degrees

Hello I am trying to make motors turn a certain amount of degrees,

I have some questions regarding how to make this happen:

  1. Is it absolutely necessary to use PID, because I have almost 0 programming experience.

  2. I managed to find some code and adjust it to where I can get a single motor to display how much it turned based on encoder ticks, where: my motors has 48CPR and 34 Gear ratio, so it's ~4.5 tics/degree.

  3. Could I specify a degree range to make the motor stop where I could simply do something like:
    --->Motor 1 speed =100%,
    if motor is at {pulses' equivalence of 1.5-1.6 turns},
    then stop/decelerate?
    3.1. If that is possible, how would that command look?

  4. Is it possible to use a single MEGA board to count the turns of 4 different motors so they can move independently?

This is the code I have so far, not my code, I just found and changed it a bit so it isn't limited to 360 degree turns and is based on my encoder and motor.
Also my motor driver has only 1 direction pin, when it's high motor will go say CW and low it'l go CCW

int pulses;
int deg = 0;
int encoderA = 2;
int encoderB = 3;

int pulsesChanged = 0;

void setup(){
  Serial.begin(115200);
  Serial.println("Degrees turned");
  pinMode(encoderA, INPUT);
  pinMode(encoderB, INPUT);  
  
  attachInterrupt(0, A_CHANGE, CHANGE);
  attachInterrupt(1, B_CHANGE, CHANGE);

}//setup

void loop(){
  if (pulsesChanged != 0) {
    pulsesChanged = 0;
    Serial.println(pulses*0.22059);
  }
}

void A_CHANGE(){
  if( digitalRead(encoderB) == 0 ) {
    if ( digitalRead(encoderA) == 0 ) {
      // A fell, B is low
      pulses--; // moving reverse
    } else {
      // A rose, B is low
      pulses++; // moving forward
    }
 } else {
    if ( digitalRead(encoderA) == 0 ) {
      // A fell, B is high
      pulses++; // moving forward
    } else {
      // A rose, B is high
      pulses--; // moving reverse
    }
  }
  // Make sure the pulses are between 0 and 359
  //if (pulses > 359) {
 //   pulses = pulses - 360;
 // } else if (pulses < 0) {
  //  pulses = pulses + 360;
  //}
 
  // tell the loop that the pulses have changed
  pulsesChanged = 1;
}

void B_CHANGE(){
  if ( digitalRead(encoderA) == 0 ) {
    if ( digitalRead(encoderB) == 0 ) {
      // B fell, A is low
      pulses++; // moving forward
    } else {
      // B rose, A is low
      pulses--; // moving reverse
    }
 } else {
    if ( digitalRead(encoderB) == 0 ) {
      // B fell, A is high
      pulses--; // moving reverse
    } else {
      // B rose, A is high
      pulses++; // moving forward
    }
  }
  // Make sure the pulses are between 0 and 359
  //if (pulses > 359) {
   // pulses = pulses - 360;
 // } else if (pulses < 0) {
  //  pulses = pulses + 360;
 // }

  // tell the loop that the pulses have changed
  pulsesChanged = 1;
}

What range of "degrees" are you thinking of using?

Servo would be one.

Stepper another.

Motor gearbox probably not so good as you get overrun.

I'm creating a 4 wheel vehicle that has to basically go forward about 1m, stop , turn left 90deg, go forward 1m, turn right 90 deg,then reverse 2m.

Considered steppers, but they provide very little torque for their weight compared to DC motors, not to mention the cost lol.

Servos are ok, but they are also too slow,and so require really big wheels to achieve comparable speeds to a DC motor.

I can address the overshoot by tweaking when the motors begin to decelerate.

Basically, all I need now is a command that allows me to instruct a motor to stop based on a certain amount of encoder tics, or degrees of rotation.

So the range of degrees would vary from position to position, but I just need an accuracy within ~40 degrees of a turn, so I would make a motor run until it has reached 1.5-1.6 rotations (540-576 degrees), then decelerate over half a rotation and stop a 2.5 rotations (900) degrees, and with some tweaking I can make it so it's almost at a complete stop when I want to be, that should eliminate any considerable degree of overshoot.

I tested the motors with simple PWM value commands too, and they seem to be good quality, I slo-mo recorded them going full speed 1 direction, then snap changing to the other in full speed, and the overshoot was very small.

If worse comes to worse, I would just have to forget about using the encoders, and tweak the speed and delay until I get desired results, the problem is that it would be too unreliable since battery fluctuations would come into play and create over and undershoots :frowning:

I've had quite good results doing this with a simple 2-wheeled robot and encoders on the wheels, about 20 ticks per rotation. Not much at least. I was doubling the resolution by counting both the rising and falling edges. To make the 90° turn I'd just run one of the two motors for the desired number of ticks, the overshoot will be roughly the same every time, so set your ticks accordingly. Switch off the motor when the motion is complete.

This is of course anything but accurate, but definitely good enough for a toy. The turn ends up somewhere between 85 and 95 degrees, which is good enough to have a robot turn away from an obstacle.

To keep the thing move straight I'm looking at the encoders, the moment one encoder gets ahead of the other the wheel on the one side gets one PWM point extra power, reset the encoder counts, and continue that way. Keeps it moving pretty straight. Running at 60-70%, that's fast enough and keeps the motors from burning (I think they're designed for ~6V so 2x LiPo is a bit much of a voltage).

A 5 deg difference is a bit too much for my liking :disappointed_relieved: , I have 1632 counts per rotation, so it should be somewhat easy to control.
If I ever find some code that I can use to direct a wheel to move a certain amount of rotations, the only thing that can cause over/under shooting will be slippage, but that likelihood can be reduced by adding more weight where the motor wheels are located, and I can just add more wheels making them concentric and flush with the current wheels to increase surface contact to the ground.
Yeah I have an alternative plan using 2 wheels, but for now I want to try 4 wheels.