I am showcasing this set up of a Pololu Simple Motor Controller and 9v battery with the brains of the SBC called the BeagleY-AI.
I am using termios in C/C++ to handle motor movement of a DC Motor from the motor controller.
The wires are from the 9v battery to the headers on the Motor Controller. Then, from the Motor Controller to the inner workings of the driver to the headers which go to the DC Motor.
The revolutions turn left and right or backwards and forwards, i.e. depending on if things are attached to your DC Motor(s).
There is a Simple Motor Controller Center package of source you can get from Pololu to set up your Motor Controller.
Note: This motor controller is deprecated. 18v7.
The Pololu people are requesting that newer users and older users exchange out their deprecated controllers for updated controllers/motor drivers.
I have not made the jump yet. I still have this 18v7 and I would like to explain how to use it:
// From Pololu and their website for the 18v7 motor driver
// Uses POSIX functions to send and receive data from the virtual serial
// port of a Pololu Simple Motor Controller.
// NOTE: The Simple Motor Controller's Input Mode must be set to Serial/USB.
// NOTE: You must change the 'const char * device' line below.
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#ifdef _WIN32
#define O_NOCTTY 0
#else
#include <termios.h>
#endif
#define SERIAL_ERROR -9999
// Reads a variable from the SMC and returns it as number between 0 and 65535.
// Returns SERIAL_ERROR if there was an error.
// The 'variableId' argument must be one of IDs listed in the
// "Controller Variables" section of the user's guide.
// For variables that are actually signed, additional processing is required
// (see smcGetTargetSpeed for an example).
int smcGetVariable(int fd, unsigned char variableId)
{
unsigned char command[] = {0xA1, variableId};
if(write(fd, &command, sizeof(command)) == -1)
{
perror("error writing");
return SERIAL_ERROR;
}
unsigned char response[2];
if(read(fd,response,2) != 2)
{
perror("error reading");
return SERIAL_ERROR;
}
return response[0] + 256 * response[1];
}
// Returns the target speed (-3200 to 3200).
// Returns SERIAL_ERROR if there is an error.
int smcGetTargetSpeed(int fd)
{
int val = smcGetVariable(fd, 20);
return val == SERIAL_ERROR ? SERIAL_ERROR : (signed short)val;
}
// Returns a number where each bit represents a different error, and the
// bit is 1 if the error is currently active.
// See the user's guide for definitions of the different error bits.
// Returns SERIAL_ERROR if there is an error.
int smcGetErrorStatus(int fd)
{
return smcGetVariable(fd, 0);
}
// Sends the Exit Safe Start command, which is required to drive the motor.
// Returns 0 if successful, SERIAL_ERROR if there was an error sending.
int smcExitSafeStart(int fd)
{
const unsigned char command = 0x83;
if (write(fd, &command, 1) == -1)
{
perror("error writing");
return SERIAL_ERROR;
}
return 0;
}
// Sets the SMC's target speed (-3200 to 3200).
// Returns 0 if successful, SERIAL_ERROR if there was an error sending.
int smcSetTargetSpeed(int fd, int speed)
{
unsigned char command[3];
if (speed < 0)
{
command[0] = 0x86; // Motor Reverse
speed = -speed;
}
else
{
command[0] = 0x85; // Motor Forward
}
command[1] = speed & 0x1F;
command[2] = speed >> 5 & 0x7F;
if (write(fd, command, sizeof(command)) == -1)
{
perror("error writing");
return SERIAL_ERROR;
}
return 0;
}
int main()
{
// Open the Simple Motor Controller's virtual COM port.
const char * device = "/dev/ttyACM0"; // Linux
int fd = open(device, O_RDWR | O_NOCTTY);
if (fd == -1)
{
perror(device);
return 1;
}
#ifdef _WIN32
_setmode(fd, _O_BINARY);
#else
struct termios options;
tcgetattr(fd, &options);
options.c_iflag &= ~(INLCR | IGNCR | ICRNL | IXON | IXOFF);
options.c_oflag &= ~(ONLCR | OCRNL);
options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tcsetattr(fd, TCSANOW, &options);
#endif
smcExitSafeStart(fd);
printf("Error status: 0x%04x\n", smcGetErrorStatus(fd));
int speed = smcGetTargetSpeed(fd);
printf("Current Target Speed is %d.\n", speed);
usleep(900000);
int newSpeed = (speed <= 0) ? 3200 : -3200;
printf("Setting Target Speed to %d.\n", newSpeed);
smcSetTargetSpeed(fd, newSpeed);
usleep(900000);
smcSetTargetSpeed(fd, newSpeed = 0);
close(fd);
return 0;
}
This source code will promote revolutions of your DC Motor. The revolution happens once the file is compiled and ran on the command line. Then, the revolution direction changes before stopping and then we close the file descriptor.
I will make a short video on the production in effect to showcase the single board computer, the motor driver, and the motor movement.
Here are some photos of the hardware used in this short on what can be used to handle DC Motors.
The first photo is the power source and the motor driver. Since the Pololu team has deprecated this motor driver, I am looking to attain a new driver from their company to handle small bots for movement. I see their RC (Radio Controlled) devices of this driver seem to be why they were so popular.
Please stay tuned for a video and RC ideas with separate types of batteries, i.e. LiPo and/or NICD or lithium.
Hopefully, this short has been somewhat informative on the motor driver and the ways to initialize motors via the C/C++ language and POSIX functions alongside in Linux. Oh, here is the first page view of the Simple Motor Controller Center from Pololu:
Now, we can attempt Radio Control via the Motor Driver:
- Plug in the Pololu motor driver to you development desktop
- Start the Simple Motor Controller Center application
- Once connected to your first 18v7, change the Input Settings to RC
- Then try the Quick Input Set Up
- Follow the instructions on the Quick Input Set Up under Input Settings
- You will sample your RC controller and RC receiver connections
- The action will basically be you turning your wheel or switch to the furthest extent once in one direction and then once in the opposite direction
Once it cycles its test, you can now use your Receiver and Controller. Repeat for the second Motor Driver from Pololu.
One should be throttle and/or mixed, i.e. depending on your set up. Another from of control may be your Throttle and the other controller is Steering. I am making a short video to describe things:
Next, I will configure things to work on the BeagleY-AI outside of just development desktop use cases...
Comments