Moto C/C++ Programming Example
Last Modified: 2007-04-18
find:

basket

Acroname Robotics PDF webpage version Moto C/C++ Programming Example PDF

Related
Products

Product image for BrainStem Moto 1.0 Module
BrainStem Moto 1.0 Module
Product image for 3A Back EMF H-Bridge
3A Back EMF H-Bridge

Contents

Overview

BrainStem controllers can be manipulated using a host computer through a serial port with the Acroname C Development Libraries.  This example demonstrates how Moto settings can be changed and actions can be performed by using C function calls.  The example demonstrates how to leverage the Moto's closed loop PID control engine to produce a desired motion. 

Note

This example does not cover how to link, compile or set up your system to run/use C programs, libraries, etc.  It is only intended to demonstrate making function calls using the Acroname C Development libraries. 

Circuit Schematic

The example uses an Acroname H-Bridge, a BrainStem Moto 1.0 and a brushed DC motor with a built in encoder.  Remember, the code executes on a host computer that could range from a laptop, desktop PC, ARM processor, etc.  The following diagram illustrates the connections between each system.  The test setup uses a separate power supply for the motors and the Moto.  Grounds are connected internally on the H-Bridge. 

Wiring diagram showing a motor with encoder, H-Bridge and BrainStem Moto.
Wiring diagram for interfacing a motor with encoder to a Moto and H-Bridge.

Source Code - C Example

The following example demonstrates how C function calls can be used to manipulate the BrainStem Moto 1.0 module.  It assumes that the libraries are built and properly installed on your particular system. 

Many macros are defined that are specific for the Moto.  These macros can be found in the "aMotionDef.tea" file found in the brainstem/aSystem folder. 

This particular example configures the Moto to run in a Encoder/Velocity PID mode.  This mode uses the Moto's built-in PID engine to make the motor spin at a desired encoder rate by adjusting the rotational velocity of the motor.  It may be necessary to adjust the period setting for the control loop to execute depending on your particular motor and encoder setup.  These steps can be skipped if you choose to configure the Moto using the Moto Application utility. 

Initially in the example code, C library functions are used to configure the Moto's settings to be appropriate for the motor and encoder used in this example.  Once the Moto is configured, a loop adjusts the desired encoder velocity setpoint.  After the error from the PID equation becomes adequately small, the setpoint is increased.  As a final stage of this example, the setpoint is decreased back down to zero which stops the motor.  Then the program exits execution returning any aErr codes that may be present. 

Note

Be aware that using Acroname's libraries depends on a global macro define that specifies which operating system you are developing on.  There are a number of ways to do this which can vary from development environments such as compiler flags, prefix headers, or other IDE global system define settings.  Typically for a Windows system, this would be a global define of aWIN; for a MacOS X system, this would be a aMACX and aUNIX; for a Linux system you would need an aUNIX. 

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* file: xxxxxxxx.c */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* description: Simple program to demonstrate using the BrainStem */ /* Moto using the C libraries. */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* Copyright 1994-2007. Acroname Inc. */ /* */ /* This software is the property of Acroname Inc. Any */ /* distribution, sale, transmission, or re-use of this code is */ /* strictly forbidden except with permission from Acroname Inc. */ /* */ /* To the full extent allowed by law, Acroname Inc. also excludes */ /* for itself and its suppliers any liability, wheither based in */ /* contract or tort (including negligence), for direct, */ /* incidental, consequential, indirect, special, or punitive */ /* damages of any kind, or for loss of revenue or profits, loss of */ /* business, loss of information or data, or other financial loss */ /* arising out of or in connection with this software, even if */ /* Acroname Inc. has been advised of the possibility of such */ /* damages. */ /* */ /* Acroname Inc. */ /* www.acroname.com */ /* 720-564-0373 */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include "aStem.h" /* stem library header */ #include "aMotion.h" /* motion control library */ #include "stdlib.h" /* define which BrainStem module and servo we are talking to and * how. In this case, we assume a GP 1.0 module */ #define aMODULE 4 #define aCHANNEL 0 /* the portname below will depend entirely on your computer's */ /* serial port configuration. We use the command */ /* ls /dev/tty.* */ /* to learn what the name of the serial adapter is on our machines */ /* Note: This value will change if you plug the adapter in other */ /* USB ports, depending on your adapter type. */ #define aPORTNAME "tty.usbserial-A1000ivx" #define aPORTSPEED 9600 /* Program specific macros */ #define LOOPDELAY 250 #define SETMAX 200 #define SETINC 10 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* the main (and only) routine */ int main(int argc, char* argv[]) { aErr error = aErrNone; aIOLib ioLib; aStemLib stemLib; aStreamRef linkStream; short setpoint = 0; short pidval = 0; printf("Running the motor example.\n"); /* Get the references to the aIO and aStem library objects. */ if (error == aErrNone) aIO_GetLibRef(&ioLib, &error); if (error == aErrNone) aStem_GetLibRef(&stemLib, &error); /* Build a link stream to communicate serially with the stem. */ if (error == aErrNone) aStream_CreateSerial(ioLib, aPORTNAME, aPORTSPEED, &linkStream, &error); /* Set this new stream as the stem's link stream. This stream * will automatically be destroyed when the stem is destroyed. */ if (error == aErrNone) aStem_SetStream(stemLib, linkStream, kStemModuleStream, &error); /* Configure the Moto settings * These steps can be skipped if you want to manually change the * settings of the Moto through the Moto Application and save the * settings to the EEPROM. The next few commands only demonstrate * ways to manipulate the values using the C libraries. * * See the aMotionDef.tea file found in the aSystem folder for a * list of macros that can be used to define most setting values. * * If there was an error earlier, then we shouldn't even bother * trying to change the settings. */ if (error == aErrNone) { /* We want to try out the pwm only mode */ error = aMotion_SetMode(stemLib, aMODULE, aCHANNEL, aMOTION_MODE_ENCVEL, 0); /* Set the PID P term. The values for this are stored on the Moto * in fixed point notations. The resolution step size for the term * is in increments of 0.031. Therefore, setting the value to 32 * would set the term to 0.031 X 32 = 0.99199 (aka 1.00). */ error = aMotion_SetParam(stemLib, aMODULE, aCHANNEL, aMOTION_PARAM_P, 32); /* Set the PID I term. See the note above about the P term. */ error = aMotion_SetParam(stemLib, aMODULE, aCHANNEL, aMOTION_PARAM_I, 0); /* Set the Period value. The increment value that can be stored is * in 0.1msec increments. Depending on the Moto firmware, the lowest * possible value is 1msec, which is a value of 10. */ printf("Setting the Period Parameter.\n"); error = aMotion_SetParam(stemLib, aMODULE, aCHANNEL, aMOTION_PARAM_PERIOD, 20); } // End of changing the Moto settings /* Begin spinning the motor. * * If there was an error earlier getting started, then there is no * point in trying to spin a motor. */ if (error == aErrNone) { /* Slowly increment the setpoint */ for (setpoint = 0; setpoint < SETMAX; setpoint = setpoint + SETINC) { printf("Setting the Setpoint value to %d\n",setpoint); error = aMotion_SetValue(stemLib, aMODULE, aCHANNEL, setpoint); /* Check to see if the setpoint is zero. We don't want to try and * chase this as a PID error. The motor should be stopped. */ if (setpoint > 0) { do { error = aMotion_GetPIDInput(stemLib, aMODULE, aCHANNEL, &pidval); printf("\tPID Return val is: %d Setpoint: %d\n", pidval, abs((pidval - setpoint))); } while (abs((pidval - setpoint)) > 2); } /* Delay a little bit */ aIO_MSSleep(ioLib, LOOPDELAY, NULL); } /* Slowly bring the setpoint back down to a stop */ for (setpoint = setpoint; setpoint >= 0; setpoint = setpoint - SETINC) { printf("Setting the Setpoint value to %d\n",setpoint); error = aMotion_SetValue(stemLib, aMODULE, aCHANNEL, setpoint); /* Check to see if the setpoint is zero. We don't want to try and * chase this as a PID error. The motor should be stopped. */ if (setpoint > 0) { do { error = aMotion_GetPIDInput(stemLib, aMODULE, aCHANNEL, &pidval); printf("\tPID Return val is: %d Setpoint: %d\n", pidval, abs((pidval - setpoint))); } while (abs((pidval - setpoint)) > 2); } /* Delay a little bit */ aIO_MSSleep(ioLib, LOOPDELAY, NULL); } } /* release the libraries now that we are done whether there * were errors or not */ aStem_ReleaseLibRef(stemLib, NULL); aIO_ReleaseLibRef(ioLib, NULL); return error; } /* main */

Revision History:

  • 2007-04-16: Example Posted
  • 2007-04-17: Included the standard library header "stdlib.h" to the example code. Updated the wiring diagram to illustrate a host computer in this example.
  • 2007-04-18: Added note about the use of global macro defines when using the Acroname development libraries.
 

Related Links:

BrainStem Software: Moto Overview

Related Examples:

Shows a simple program using the C Development Download

voice: 720-564-0373, email: sales@acroname.com, address: 4822 Sterling Dr., Boulder CO, 80301-2350, privacy
© Copyright 1994-2008 Acroname, Inc., Boulder, Colorado. All rights reserved.