Gamoto PID to BrainStem Example
Last Modified: 2006-11-02
find:

basket

Acroname Robotics PDF webpage version Gamoto PID to BrainStem Example PDF

Related
Products

Product image for Brainstem GP 1.0 Module
Brainstem GP 1.0 Module

Contents

Introduction

The Gamatronix company produces a PID controller for DC Motors with quadrature encoders called the "Gamoto".  It has a built-in h-bridge that provides up to 3A for a 12-55 volt motor.  It also has an I2C bus interface which makes it compatible with a variety of devices including the BrainStem GP 1.0 controller.  This example illustrates the use of a library for communicating with the Gamoto controller via the I2C bus. 

Modifying the BrianStem I2C Rate

The Gamoto supports a maximum I2C baud rate of 100KHz.  The Stem's default I2C baud rate is 1MHz.  A cmdVAL_SET and cmdVAL_SAV command is necessary to configure the Stem for a 100KHz I2C baud rate. 

2 18 3 0 /* cmdVAL_SET, I2C baudrate, value=100kHz */ 2 19 /* cmdVAL_SAV */

Communicating with the Gamoto

A full description of the operation of the Gamoto controller or PID control is beyond the scope of this example.  This example only shows how to communicate with the Gamoto.  There are two important issues for the Gamoto interface.  The first is byte-ordering.  With multiple-byte values, such as 16-bit integers, the BrainStem stores the most significant bytes first in memory.  The Gamoto stores the least significant bytes first in memory.  The BrainStem's I2C routines must do a byte reversal in order to keep the values identical after a data transfer.  The second issue is integer size.  The Gamoto uses some 24-bit, 3-byte integers.  BrainStem modules do not support 3-byte integers.  To transmit a 3-byte integer from a Stem, it must be broken up into a 1-byte char and 2-byte int type.  Then it must be byte-reversed and sent across the I2C bus.  To retrieve a 3-byte intger, the Stem must do separate reads of a char and int.  Fortunately, reading 3-byte integers is not usually necessary because the Gamoto mainly acts as a slave controller that receives I2C data and commands. 

Source Code - TEA Library for Communicating with Gamoto

The "aGamoto.tea" file conforms to TEA library standards.  It contains I2C data transfer routines along with defined constants for the various register addresses in the Gamoto controller.  The "aGamoto_SetChar" and "aGamoto_GetChar" routines are just macros of standard I2C routines since byte reversal is not an issue for 1-byte char types.  The "aGamoto_SetInt" and "aGamoto_GetInt" routines handle 16-bit integer transfers and byte-swapping.  The "aGamoto_Set3ByteInt" routine takes a char and int and transfers their 3 bytes in reversed order across the I2C bus in order to write a 24-bit integer in the Gamoto controller.  An additional "aGamoto_ByteSwap" routine is provided as a utility for reversing bytes in a 16-bit integer. 

/* filname: aGamoto.tea */ #ifndef _aGamoto_T_ #define _aGamoto_T_ #include <aI2C.tea> #define aGamoto_GetChar(addr, x) aI2C_ReadChar(addr, x) #define aGamoto_SetChar(addr, x, c) aI2C_WriteChar(addr, x, c) #define aGamoto_FactoryRst 0x00 #define aGamoto_SaveParms 0x01 #define aGamoto_Kp 0x22 #define aGamoto_Ki 0x24 #define aGamoto_Kd 0x26 #define aGamoto_iLimit 0x28 #define aGamoto_dS 0x2A #define aGamoto_Mode 0x2B #define aGamoto_pwrLimit 0x2C #define aGamoto_setPosition 0x2F #define aGamoto_mPosition 0x33 #define aGamoto_setVelocity 0x36 #define aGamoto_mVelocity 0x39 #define aGamoto_trajectory 0x3B #define aGamoto_mPower 0x3C #define aGamoto_u0 0x61 #define aGamoto_Analog0 0xA0 #define aGamoto_Analog1 0xA2 #define aGamoto_Analog2 0xA4 #define aGamoto_Analog3 0xA6 #define aGamoto_Analog4 0xA8 #define aGamoto_version 0xB2 #define aGamoto_X0 0xB4 #define aGamoto_V0 0xB6 #define aGamoto_A0 0xB8 #define aGamoto_X1 0xBA #define aGamoto_V1 0xBC #define aGamoto_A1 0xBE #define aGamoto_X2 0xC0 #define aGamoto_V2 0xC2 #define aGamoto_A2 0xC4 #define aGamoto_X3 0xC6 #define aGamoto_V3 0xC8 #define aGamoto_A3 0xCA #define aGamoto_X4 0xCC #define aGamoto_V4 0xCE #define aGamoto_A4 0xD0 #define aGamoto_X5 0xD2 #define aGamoto_V5 0xD4 #define aGamoto_A5 0xD6 #define aGamoto_X6 0xD8 #define aGamoto_V6 0xDA #define aGamoto_A6 0xDC #define aGamoto_X7 0xDE #define aGamoto_V7 0xE0 #define aGamoto_A7 0xE2 int aGamoto_ByteSwap(int a) { asm { pushsb 3 pushsb 5 popss 4 } return a; } int aGamoto_GetInt(char addr, char reg) { int val=0; asm { /* write address */ pushsb 6 /* IIC address */ pushlb 1 /* data size */ pushsb 7 /* push reg */ pushlb 3 /* cmd size */ popcmd /* read byte from device */ pushsb 6 /* IIC address */ pushlb 1 /* set read bit */ orb pushlb 2 /* bytes to read */ popsm aPortIICRead popbs 3 /* store as byte-swapped int */ popbs 1 } return val; } void aGamoto_SetInt(char addr, char reg, int data) { asm { pushsb 6 /* IIC address */ pushlb 3 /* data size */ pushsb 7 /* push reg */ pushsb 6 /* push data (low) */ pushsb 8 /* push data (high) */ pushlb 5 /* cmd size */ popcmd } } /* writes 1-byte char and 2-byte int */ /* into a 3-byte little-endian Gamoto register */ /* (On Stem, b1 is MSB, b2 is middle byte, and b3 is LSB) */ void aGamoto_Set3ByteInt(char addr, char reg, char b1, int b2b3) { asm { pushsb 7 /* IIC address */ pushlb 4 /* data size */ pushsb 8 /* push reg */ pushsb 6 /* push b2b3 (low) */ pushsb 8 /* push b2b3 (high) */ pushsb 10 /* push b1 */ pushlb 6 /* cmd size */ popcmd } } #endif /* _aGamoto_T_ */

Source Code - Gamoto TEA Test

The following file tests some I2C read and write functions.  For testing this example, the "aGamoto.tea" is stored in the aUser folder so the filename is surrounded by quotes instead of angle brackets. 

/* filename: gamoto_test.tea */ #include <aCore.tea> #include <aPrint.tea> #include "aGamoto.tea" #define aGAMOTO_ADDR (char)0x90 void main() { int i; char b1; int b2b3; /* do read-write test of a 3-byte register */ aGamoto_Set3ByteInt(aGAMOTO_ADDR, aGamoto_setPosition, 0x01, 0x2345); b2b3 = aGamoto_GetInt(aGAMOTO_ADDR, aGamoto_setPosition); b1 = aGamoto_GetChar(aGAMOTO_ADDR, aGamoto_setPosition + 2); aPrint_String("setPosition = 0x"); aPrint_CharHex(b1); aPrint_IntHex(b2b3); aPrint_Char('\\n'); aCore_Sleep(1000); /* do read-write test of a 2-byte register */ aGamoto_SetInt(aGAMOTO_ADDR, aGamoto_setVelocity, -4000); i = aGamoto_GetInt(aGAMOTO_ADDR, aGamoto_setVelocity); aPrint_String("setVelocity = "); aPrint_IntDec(i); aPrint_Char('\\n'); aCore_Sleep(1000); /* get some readings from A2D channel 1 */ for (i = 0; i < 5; i++) { aPrint_String("Analog1 = "); aPrint_IntDec(aGamoto_GetInt(aGAMOTO_ADDR, (char)aGamoto_Analog1)); aPrint_Char('\\n'); aCore_Sleep(5000); } }

Revision History:

  • 2004-05-27: Example Created.
 

Related Links:

Articles: PID Motion Control Basics

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.