I am making a robot and using H-bridge and regular motors for motion, arms, gripper hands and other things. I am already kind of annoyed at all the digital pin writes and analog PWM writes to make the motors go the direction and speed I want. Code is filling up with groups of 4.
I use 1 digital and 1 PWM pin for each motor and control the speed with PWM. When one side is HIGH, the PWM number needs to be high for slow speed and when I need the motor to go the other direction the HIGH goes to LOW and the PWM number needs to be on the low end.
What's the cleanest way to do this? Am I stuck using 4 pin write commands each time or is it better to use functions and then call ForwardSlow(). Maybe there is some other trick I'm not aware of?
The motors are all low power so I'm using a small MX1508 H-bridge that just uses PWM at the input pins. So there is power, motor out and 2-pin signal in. One or both signal pins can be PWM. https://www.amazon.com/dp/B075S368Y2
I can't see your code. But perhaps it's time to clean things up using arrays, functions, and struts. In fact, I'd go even more OOP by encapsulating functionality into C++ classes.
So yeah, def a function to do a group of four whatever.
If you make it flexible enough, it is possible to have all the motor output manipulation appear only once in your sketch, in this case in a motor control function.
You could make that function a bit more clever one day and use direct port manipulation, but no matter what you ever do, controlling stuff is gonna mean lotsa hands and knees twiddling of output pins.
as already mentioned, create a class "Motor".
design an API of member functions you really need from each motor (setSpeed, setDirection,forward, forwardSlow, reverse... )
let the class handle that "invers" PWM depending on the set direction.
When you have one class, make several objects - one for each motor you need to control.
edit:
just as an idea,
far away from "best",
might be buggy or not fitting to your hardware:
/*
Code for H-Bridge with PWM
https://forum.arduino.cc/t/best-code-method-for-h-bridge-with-pwm/1182039/8
2023-10-25 by noiasca
*/
class Motor {
protected:
const uint8_t pwmPin; // the GPIO for PWM
const uint8_t dirPin; // the GPIO whih sets direction
uint16_t speed = 0; // current speed of motor
int8_t direction = 1; // 1 forward, // -1 reverse
public:
Motor (uint8_t pwmPin, uint8_t dirPin) : pwmPin(pwmPin), dirPin(dirPin) {}
// to be called once in setup
void begin() {
pinMode(pwmPin, OUTPUT);
pinMode(dirPin, OUTPUT);
}
// change speed of motor
void setSpeed(uint16_t newSpeed) {
if (newSpeed > 1023)
speed = 1023;
else
speed = newSpeed;
if (direction == 1)
analogWrite(pwmPin, speed);
else
analogWrite(pwmPin, 1023 - speed); // your logic when motor is in reverse
}
// let the motor move forward
void forward() {
direction = 1;
digitalWrite(dirPin, HIGH);
setSpeed(speed);
}
// let the motor move backwards
void reverse() {
direction = -1;
digitalWrite(dirPin, LOW);
setSpeed(speed);
}
};
// UNO PWM pins are 5,6,9,10,11,3
// pwm dir
Motor motorA(5, 2); // create a motor object and define the PWM pin and the direction pin
Motor motorB(6, 3);
Motor motorC(9, 4);
void setup() {
motorA.begin();
motorB.begin();
motorC.begin();
}
void loop() {
motorA.setSpeed(255);
motorB.setSpeed(512);
motorC.setSpeed(1023);
delay(1000); // dirty delay - just here in the demo
motorA.setSpeed(512);
delay(1000); // dirty delay
motorA.setSpeed(0);
delay(1000); // dirty delay
motorA.reverse();
motorA.setSpeed(128);
delay(1000); // dirty delay
}
//