Now, I think I did not yet reveal to you why I chose the particular setup of having an Arduino plus Motorshield v2.0 drive the DC motors of my robot. The answer is surprisingly simple: The Adafruit Motorshield v2 is a pretty awesome piece of hardware that allows you to control up to 4 DC motors, two stepper motors and two servo motors at the same time. Way enough headroom for future ideas. The Motorshield v2.0 is controlled via I2C bus, so I guess in theory I could wire it up to the Raspberry Pi directly. For this first version of my robot, however, I decided to connect it to the Arduino and write a very small piece of Sketch code to run on the ATMega controller. All it will do is to accept motor control commands from its serial interface and pass them on to the motor shield. The Arduino comes with a USB COM port driver chip, so connecting the Arduino to the Raspberry Pi is as simple as plugging in a USB cable and figuring out the device special file to use on the Raspberry Pi side. This is the sketch I put on the Arduino:
/*
Control code for DC motors using Motor Shield 2
This code reads commands in the form of n{+,-}x\n where
n is the motor number and x is the desired speed.
Use '+' to let the motor run forward and '-' to
let it run backwards.
*/
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_PWMServoDriver.h"
const int numMotors = 4;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *motor[numMotors];
void setup() {
// initialize serial:
Serial.begin(115200);
// Initialize motors
AFMS.begin();
for (int i = 0; i < numMotors; ++i) {
motor[i] = AFMS.getMotor(i + 1);
}
}
void loop() {
while (Serial.available()) {
int motoNum = Serial.parseInt();
char sign = Serial.read();
int speed = Serial.parseInt();
if ((Serial.read() == '\n') && (motoNum < numMotors)) {
// and execute command
motor[motoNum]->setSpeed(speed);
motor[motoNum]->run((sign == '+')?FORWARD:BACKWARD);
Serial.print("Set motor ");
Serial.print(motoNum);
Serial.print(" to ");
Serial.print(sign);
Serial.println(speed);
}
}
}
The Raspberry Pi counter part is implemented in Python and looks like this:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# import required modules
import serial
import time
# main function
def main():
comm = serial.Serial("/dev/ttyACM0", 115200)
while True:
for m in range(0,4):
for s in range(0,256):
comm.write(str(m) + "+" + str(s) + "\n")
time.sleep(0.1)
if __name__ == '__main__':
# call main function
main()
This will make the robot turn on its motors, one after another, and gradually bring them to full speed.
Not very useful, but I think it shows the trick.
No comments:
Post a Comment