Double DC motor control issues on ATmega1284p

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Everyone,

 

This time case study is a development platform for robot (2 DC motors, caterpillars combines together), and after developing the motor control and directions of movement, I decided that next would be to get a feedback from Hall sensors on both motors.

 

But here I faced serious issues in this.sfF

 

I wrote ISR() to check the S1R and S1L, Hall sensors via PCINT18 and PCINT20 pin change interrupts. Inside a function I check up which of the both interrupts. As soon as on of them fires, then the control checks up on other 2 Hall sensors (S2R and S2L), which I am using to know the direction of the rotation and speed.

 

Please see the schematics below.

 

So far I have coded two function for each motor. That said I have telemetryRight() and telemetryLeft(), and they work perfectly. In case S1R ISR() fires then the telemetryRight() is invoked and it gives me data on direction and rotation amount. In case the S1L ISR() fires, then the telemetryLeft() is invoked and same happens there. Everything cool.

 

But as you read it tells me only if my motor moves forward or backward, so I would like to know whether it turns left or turns right I need to combined them into ISR(). But here the issues come in. The function inside ISR() becomes very big which involves adding those to functions into it. Would it be something I should consider or, there are other better ways to do that?

 

- Also what I measured that one motor is always slower that the other about 20 Hz, any ideas why? especially at slower  speeds(pwm values). If so than I can't implement a logic to get the information about the directions, du to the fact that the conditions in function will change on the fly. This becomes a long post, but all this is not as simple as it might be, if the motor speed difference comes into play.

 

 

Separate versions of the both functions.

 

move_knob_R = S1R, move_knob_L = S1L 

 

move_dir_R = S2R, move_dir_L = S2L

 

void telemetryRightMotor(void){

    move_knob_R = (HALL_PIN & (1 << HALL_S1R));
    if(move_knob_R == 0){
            move_dir_R = (HALL_PIN & (1 << HALL_S2R));
            if(move_dir_R == 0){
                    hall_S2R_pulse ++;
                    printString("Right motor = forward/Hall sensor feedback = ");
                    printWord(hall_S2R_pulse);
                    printString("\r\n");
            }

            else{
                    hall_S2R_pulse --;
                    printString("Right motor = backwards/Hall sensor feedback = ");
                    printWord(hall_S2R_pulse);
                    printString("\r\n");
        }
   }
}

void telemetryLeftMotor(void){

    move_knob_L = (HALL_PIN & (1 << HALL_S1L));
    if(move_knob_L == 0){
            move_dir_L = (HALL_PIN & (1 << HALL_S2L));
            if(move_dir_L == 0){
                    hall_S2L_pulse ++;
                    printString("Left motor = forward/Hall sensor feedback = ");
                    printWord(hall_S2L_pulse);
                    printString("\r\n");
            }

            else{
                    hall_S2L_pulse --;
                    printString("Left motor = backwards/Hall sensor feedback = ");
                    printWord(hall_S2L_pulse);
                    printString("\r\n");
        }
   }
}

 

work in progress...

Last Edited: Sun. Oct 6, 2019 - 11:32 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the speeds involved are slow, why use interrupts? You would be better off using a timer in ctc mode interrupting at a constant rate, say, 10ms. Maybe faster depending on the rate of the input signals. In the timer isr you can read the sensor states and process the changes. reading at a constant rate also means you can filter the inputs to remove noise and transients.

 

 

Note that having print statements in your isr code will slow it down significantly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If so than I can't implement a logic to get the information about the directions, du to the fact that the conditions in function will change on the fly. 

What?  Say something that is understandable.  Not the of what it and means!

Use your ISR to grab the states of all the sensors (or use a timer as suggested)....do everything else in your main routine. 

 

 that one motor is always slower that the other about 20 Hz,

Do you mean RPM? 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yes, the RPM of one motor is always slower than the other, about 20Hz. It is more pronounced when at slower speeds.
At some value that slow motor stops spinning, but the left does. Any ideas what can cause that, and where to look for solution.

 

work in progress...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 RPM of one motor is always slower than the other, about 20Hz.

 

What are you talking about ? The units of RPM are revolutions per minute (like 25 RPM).    Hz is cycles per second.....so why are you mixing them together?

 

Why do you neglect to provide both motor speeds you are measuring?

     

In any case, the PWM just sets the generic no-load motor speed, which depends on a fairly loose voltage coefficient ....RPM=Kv * Volts.

 

Under loading, there will be even more variation.    Torque is proportional to current.  Each of your motors having a coefficient due to the actual winding, the magnetics, etc.

At low speeds you can get cogging, but you neglect to mention what speeds you are using.

  

 

Determining left/right probably belongs in main, not your IRQ...just use the IRQ to grab the corresponding motor measurements. 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The comment about print statements in your code slowing it down "significantly" is an understatement. It will kill it!