Pololu Orangutan X2 User Manual

Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation
Orangutan X2 Command
Documentation v1.01
Page 1 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation
1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. ATmega644 SPI Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3. Low-Level SPI Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.a. Motor Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.a.01. Command 214: Set Motor Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.a.02. Command 128: Independent Motor Brake (inB = inA) . . . . . . . . . . . . . . . . . . . 7
3.a.03. Command 136: Independent Motor Drive (inB = ~inA) . . . . . . . . . . . . . . . . . . 7
3.a.04. Command 232: Independent Motor Drive with Acceleration (inB = ~inA) . . . . . . . . . 7
3.a.05. Command 144: Joint Motor Operation (inA1 = inB1 = in1; inA2 = inB2 = in2) . . . . . . 8
3.a.06. Command 228: Joint Motor Drive with Acceleration (in2 = ~in1) . . . . . . . . . . . . . 8
3.a.07. Command 208: Set Acceleration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.a.08. Command 188: Set Brake Duration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.a.09. Command 212: Set Number of Current Sense Samples in Averages . . . . . . . . . . . . 9
3.a.10. Command 192: Set Current Limit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.a.11. Command 210: Set Motor PWM Frequencies . . . . . . . . . . . . . . . . . . . . . . . . 10
3.a.12. Command 216: Get Average Motor Current . . . . . . . . . . . . . . . . . . . . . . . . 11
3.b. Buzzer Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.b.1. Command 152: Play Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.b.2. Command 160: Play Frequency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.b.3. Command 176: Play Melody . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.b.4. Command 168: Store Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.b.5. Command 224: End Melody . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.b.6. Command 186: Erase Melodies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.b.7. Command 226: Set Volume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.b.8. Command 187: Set Note Gap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.b.9. Command 225: Buzzer Off . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.c. UART Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.c.01. Command 200: Set Serial Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.c.02. Command 219: Read UART Byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.c.03. Command 220: Send UART Byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.c.04. Command 222: Get Free Space in Send Buffer . . . . . . . . . . . . . . . . . . . . . . . 18
3.c.05. Command 223: Get Number of Bytes in Read Buffer . . . . . . . . . . . . . . . . . . . . 18
3.c.06. Command 227: Set Read Ready Size . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.c.07. Command 252: Get UART Error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.d. Miscellaneous Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.d.01. Command 218: Get Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.d.02. Command 240: Write to EEPROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.d.03. Command 248: Read from EEPROM . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.d.04. Command 254: Check If EEPROM Is Busy . . . . . . . . . . . . . . . . . . . . . . . . . 21
3.d.05. Command 253: Get Firmware version (version = major byte . minor byte) . . . . . . . . 21
3.d.06. Command 255: NULL Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4. Attention and SPI Pins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.a. ATmega168’s Attention Line . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4.b. ATmega168’s Slave Select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5. ATmega168’s EEPROM Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Page 2 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation

1. Overview

microcontroller is now an ATmega328P instead of an ATmega168. The ATmega1284P has 128 KB of program memory, 16 KB of RAM, and 4 KB of EEPROM, and it offers an additional 16-bit timer (TIMER3). If you have a new Orangutan X2, treat all “mega644” references in this document as “mega1284” references.
The Orangutan X2 [http://www.pololu.com/catalog/product/738] motor drivers, buzzer, and USB-to-serial interface are controlled by the auxiliary ATmega168 microcontroller, which is connected to the ATmega644 user controller via the Serial Peripheral Interface (SPI), a synchronous serial protocol for which the mega644 has a dedicated hardware module. Once the SPI module is configured correctly, the mega644 can invoke mega168 functions by sending command packets consisting of one command byte followed by zero or more data bytes. Command bytes always have an MSB of one while data bytes always have an MSB of zero.
This document explains in great detail the low-level SPI commands used to communicate with the auxiliary mega168. If you want to get started quickly with your Orangutan X2, you can bypass this detailed documentation and instead use our high-level C wrapper functions [http://www.pololu.com/file/download/
ox2_spi_wrappers_v1_01.zip?file_id=0J20] (12k zip) of these low-level commands. The file SPI.h contains the function
prototypes of the wrappers, along with some convenient #defines; the file SPI.c contains the commented implementations of the wrappers. By including SPI.h in your project, you will be able to get up and running quickly with your Orangutan X2. We encourage you to modify these high-level wrapper functions to fit your specific needs.
Note: Before you can call any of the wrapper functions in SPI.c, you must initialize the mega644’s SPI hardware module by calling SPIInit(). For examples of how to use these wrapper functions in your Orangutan X2 projects, please see the sample AVR Studio project files linked from the various Orangutan X2
pages [http://www.pololu.com/catalog/category/37].
1. Overview Page 3 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation

2. ATmega644 SPI Configuration

The mega644 SPI module should be configured as follows:
• SPI enabled
• MSB first
• master mode
• clock polarity 0 (clock line low when idle)
• clock phase 0 (sample on leading ege)
• Maximum frequency: 2.5 MHz (clock/8)
If you have the latest WinAVR [http://winavr.sourceforge.net/] installed (version 20070525 at the time this was written), the following C code will set up the SPI module, assuming you have your device set as atmega644. If you are using an older version of WinAVR, you will need to add zeroes to the ends of all of the SPI register/bit names (e.g. change SPCR to SPCR0, SPSR to SPSR0, SPE to SPE0, etc).
#include <avr/io.h>
// global flag used to help us track when an SPI transmission is in progress unsigned char SPITransmitting;
void SPIInit() {
// make the MOSI, SCK, and SS pins outputs DDRB |= ( 1 << PB5 ) | ( 1 << PB7 ) | ( 1 << PB4 );
// make sure the MISO pin is input DDRB &= ~( 1 << PB6 );
// set up the SPI module: SPI enabled, MSB first, master mode, // clock polarity and phase = 0, F_osc/8 SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR0 ); SPSR = 1; // set double SPI speed for F_osc/8
// the previous settings clear the SPIF bit of SPCR, so we use our global // flag to indicate that this does not mean we are currently transmitting SPITransmitting = 0;
}
Most commands require data flow in only one direction: from the mega644 to the mega168. This can be achieved with an SPI transmit command.
void SPITransmit( unsigned char data ) {
if ( SPITransmitting ) // if we really are transmitting
while ( ! ( SPSR & ( 1 << SPIF ))) // wait for completion of
SPDR = data; // begin transmission SPITransmitting = 1; // flag transmission in progress
}
; // previous transmission
Reading data back from the mega168 is only slightly more complicated since we need to give the mega168 time (~3us) to prepare the data byte we’re requesting. Once it’s ready we then need to transmit an extra byte since every SPI transaction has data flow in both directions. As our byte is being sent to the mega168, the data we’re interested is being sent to us. At the end of the transmission, the value from the mega168 will be in the mega644’s SPI data register, SPDR. We need an extra function to perform our 3 microsecond delay, so we’ll include an example here:
static inline void delay_us(unsigned int microseconds) __attribute__((always_inline)); void delay_us(unsigned int microseconds)
2. ATmega644 SPI Configuration Page 4 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation
{
__asm__ volatile (
"1: push r22" "\n\t" " ldi r22, 4" "\n\t" "2: dec r22" "\n\t" " brne 2b" "\n\t" " pop r22" "\n\t" " sbiw %0, 1" "\n\t" " brne 1b" : "=w" ( microseconds ) : "0" ( microseconds )
);
}
unsigned char SPIReceive( unsigned char data ) // data is often a junk byte (e.g. 0) {
if ( SPITransmitting )
while ( ! ( SPSR & ( 1 << SPIF ))) // wait for completion of
delay_us( 3 ); // give the mega168 time to prepare
SPDR = data; // start bidirectional transfer while ( ! ( SPSR & ( 1 << SPIF ))) // wait for completion of
// reading SPCR and SPDR will clear SPIF, so we will use our global flag // to indicate that this does not mean we are currently transmitting SPITransmitting = 0; return SPDR;
}
; // previous transmission
// return data
; // transaction
We can now put wrapper functions around these low-level SPI commands to communicate with the mega168. For instance, here is a command for setting motor 1:
void setMotor1( int speed ) {
// first, we'll prepare our command byte
unsigned char command;
if ( speed > 255 )
speed = 255;
if ( speed < -255 )
speed = -255;
if ( speed >= 0 )
command = 136; // motor 1, forward else {
command = 138; // motor 1, reverse
speed = -speed; }
// the MSB of the speed gets tacked onto the command byte command |= ( (unsigned char) speed & 0x80 ) >> 7;
// now, send the command SPITransmit( command ); SPITransmit( (unsigned char) speed & 0x7F );
}
2. ATmega644 SPI Configuration Page 5 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation

3. Low-Level SPI Commands

We will now elaborate on the low-level SPI commands.
Some commands produce immediate results (e.g. non-acceleration motor commands, all the read commands, buzzer off) independent of the state of the mega168’s main loop. Others queue up actions to be carried out by the appropriate handler in the mega168’s main loop (e.g. UART transmit, most buzzer commands, acceleration motor commands).
The SPI clock can run at up to 2.5 MHz, which corresponds to SPI byte rate of approximately 312 kHz. The mega168 is designed to be able to accept these bytes as quickly as you are able to send them without losing data or ignoring commands. However there are a few exceptions:
• If you are sending a command that will cause the mega168 to write to its EEPROM, you will be tying up the mega168’s main loop for approximately 3.4 ms per EEPROM write. You should not send another command that will cause an EEPROM write until after the previous write has finished. For example, do not stream “Store Note” commands to the mega168 any faster than one packet per 10.2 ms. You can send a command packet that does not cause an EEPROM write immediately following one that does, but realize that the various handlers in the mega168’s main loop will not get around to that command until after the EEPROM writes are finished. As such, we recommend that, if possible, you have the mega168 perform any necessary EEPROM writes during the initialization phase of your program rather than in the middle of some crucial, time-sensitive phase.
• If you are sending a read command, you must give the mega168 time to load the desired value into its SPI data register before initiating the SPI transmission that will transfer it to the mega644. The recommended protocol is to transmit the byte that will tell the mega168 what value is desired (usually this is just the command byte), wait for the transmission to complete, then wait for an additional 3us before transmitting another byte (usually this will be a junk data byte or a NULL command). As this last byte is transmitted over the SPI to the mega168, the desired value is transmitted over the SPI to the mega644. When transmission of this last byte is complete, the mega644’s SPI data register, SPDR, holds the requested value.
• It doesn’t make sense to stream some commands as quickly as possible to the mega168. For example, you can send PWM updates to the mega168 at 143 kHz, but given that the fastest PWM frequency you can use is ~20 kHz, such an update rate would be pointless.
In general, you rarely need to worry about having to insert delays between the bytes you’re transmitting over the SPI; it is up to you to decide what update rate makes the most sense for your particular application.
Note: “motor 1” corresponds to motor bit 0 and “motor 2” corresponds to motor bit 1.

3.a. Motor Commands

3.a.01. Command 214: Set Motor Mode

Effect: This setting determines whether the X2 is running in independent motor mode (i.e. controlling two PWM-
driven motors independently) or in joint motor mode (wired to control only one motor using both drivers operating in unison). Independent-motor commands are not accepted when running in joint motor mode and joint-motor commands are not accepted when running in independent motor mode. Setting the mode to joint operation will synchronize the timers for the two PWMs and set them both based on the settings for motor 1. In general, joint­motor mode uses motor 1 settings only. The X2 defaults to independent motor mode (motor mode bit = 0) after each hardware reset, so this command really only needs to be sent at the beginning of your program if you wish to run in joint motor mode (motor mode bit = 1). This setting cannot be stored in EEPROM and hence to operate in joint mode the mega644 must always send this command after a hardware reset.
3. Low-Level SPI Commands Page 6 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation
If you want to run your X2 in joint motor mode, you should connect one terminal of your motor to the two M1 outputs and the other terminal of your motor to the two M2 outputs.
It is important to note that current sensing is not possible in joint motor mode. The Set Current Limits command (192—Section 3.a.10) will have no effect in joint motor mode and the Get Average Motor Current command (216—Section 3.a.12) will not return anything meaningful.
Values sent: motor mode (1 bit)
command byte = 214 | motor mode bit

3.a.02. Command 128: Independent Motor Brake (inB = inA)

Effect: Causes the specified motor to immediately brake high (inA bit = 1) or low (inA bit = 0) with the desired
PWM
Values sent: motor (1 bit), inA (1 bit), PWM (8 bits)
command byte = 128 | (motor bit << 2) | (inA bit << 1) | MSB of PWM
data byte = 7 lower bits of PWM byte

3.a.03. Command 136: Independent Motor Drive (inB = ~inA)

Effect: Causes the specified motor to immediately drive forward (inA bit = 0) or reverse (inA bit = 1) with the
desired PWM
Values sent: motor (1 bit), inA (1 bit), PWM (8 bits)
command byte = 136 | (motor bit << 2) | (inA bit << 1) | MSB of PWM
data byte = 7 lower bits of PWM byte

3.a.04. Command 232: Independent Motor Drive with Acceleration (inB = ~inA)

Effect: Causes the specified motor to transition from its current direction and PWM to the desired direction PWM
at a rate determined by its corresponding acceleration setting. If the desired motor direction (forward for inA = 0 and reverse for inA = 1) is the same as the current direction and the desired PWM is less than the current PWM, the PWM will be set directly to the desired value during the next PWM-update phase of the mega168 main loop (sometime in the next 10ms). In short, this command will not produce artifical deceleration to slow a motor. The only time the acceleration comes into play is when the PWM is increasing in a specific direction. If this command results in a change of direction, the motor is first stopped by braking low at 100% duty cycle for a duration that can be set using command 188 (Section 3.a.08). The PWM is then linearly incremented from zero to the desired PWM in the desired direction based on the acceleration setting, which can be set using command 208 (Section
3.a.07). Acceleration updates to the PWM are performed 100 times per second if possible. It is important to note
that acceleration timing is done using the motor 1 PWM timer, so decreasing motor 1’s PWM frequency below 100Hz will decrease the acceleration update rate.
Values sent: motor (1 bit), inA (1 bit), PWM (8 bits)
command byte = 232 | (motor bit << 2) | (inA bit << 1) | MSB of PWM
data byte = 7 lower bits of PWM byte
3. Low-Level SPI Commands Page 7 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation

3.a.05. Command 144: Joint Motor Operation (inA1 = inB1 = in1; inA2 = inB2 = in2)

Effect: Use dual motor drivers together as a single, more powerful motor driver. The settings of in1 and in2
determine if the effect is brake low, forward, or reverse at thedesired PWM. This command sets motor to the specified state immediately. It is not possible to brake high in joint motor mode. It is also not possible to take advantage of current-sensing while in joint motor mode. Joint motor control works by PWMing the low output side while holding the other side constantly high. Here is how it performs the following actions:
• Joint brake (in1 = in2): both H-bridges alternate between high impedance and driving low at the same synchronized duty cycle.
• Joint “forward” (in1 = 0, in2 = 1): H-bridge 1 alternates between high impedance and driving low while H-bridge 2 drives high.
• Joint “reverse” (in1 = 1, in2 = 0): H-bridge 2 alternates between high impedance and driving low while H-bridge 1 drives high.
The red/green LEDs on the daughter motor-driver board will not function in joint motor mode, nor will current­sensing. To run your X2 in joint motor mode, you should connect one side of your motor to the two M1 outputs and the other side of your motor to the two M2 outputs.
Values sent: in1 (1 bit), in2 (1 bit), PWM (8 bits)
command byte = 144 | (in1 bit << 2) | (in2 bit << 1) | MSB of PWM
data byte = 7 lower bits of PWM byte

3.a.06. Command 228: Joint Motor Drive with Acceleration (in2 = ~in1)

Effect: See “Independent Motor Drive with Acceleration” (Section 3.a.04) command. Joint Motor Drive uses the
dual motor drivers together as a single, more powerful motor driver. When operating in joint motor mode, settings for operation are determined by “motor 1” (motor bit = 0) settings while “motor 2” settings are ignored.
Values sent: in1 (1 bit), PWM (8 bits)
command byte = 228 + (in1 bit << 1) + MSB of PWM
data byte = 7 lower bits of PWM byte

3.a.07. Command 208: Set Acceleration

Effect: Sets for the specified motor the acceleration used by the motor acceleration commands 228 (Section
3.a.06) and 232 (Section 3.a.04). While accelerating, the net effect is that the PWM is incremented by the
acceleration value every 100 ms. In reality, the updates will usually be increments of the one tenth the acceleration value applied every 10 ms. The acceleration value for each motor is specified by a seven-bit number and will change the duty cycle twice as quickly in seven-bit PWM mode as in eight-bit PWM mode. An acceleration value of zero is treated as infinite acceleration and will simply set the PWM equal to the target PWM when the motor­handling portion of the mega168’s main loop is executed sometime in the next 10ms.
This command does not save the acceleration values to EEPROM, however they can be saved by issuing separate EEPROM-write commands (240—Section 3.d.02) that store the values at the appropriate addresses (9 for motor 1, 10 for motor 2). It is possible to safely store 8-bit values at these location if you need even higher accelerations than 127.
Values sent: motor acceleration (7 bits), motor (1 bit)
3. Low-Level SPI Commands Page 8 of 27
Orangutan X2 Command Documentation v1.01 © 2001–2010 Pololu Corporation
command byte = 208 | motor bit
data byte = 7-bit acceleration (MSB always zero)

3.a.08. Command 188: Set Brake Duration

Effect: Sets the duration the specified motor spends braking low at 100% duty cycle when issued an acceleration
command (228—Section 3.a.06 or 232—Section 3.a.04) that results in a change of direction. The brake duration value is in tens of milliseconds, so a value of 1 will result in a brake duration of 10 ms and a value of 127 will result in a brake duration of 1.27 seconds. A brake duration value of 0 causes the motor to switch direction with no braking in between. Brake duration is a seven-bit value.
This command does not save the brake duration value to EEPROM, however it can be saved by issuing a separate EEPROM-write command (240—Section 3.d.02) that stores the value at the appropriate address (11 for motor 1, 12 for motor 2). It is possible to safely store 8-bit values at these location if you need longer brake durations than
1.27 seconds.
Note: this command is bugged in firmware version 1.00 and has no effect, but it has been fixed in version 1.01.
Values sent: motor (1 bit), brake duration (7 bits)
command byte = 188 | (motor bit << 1)
data byte = 7-bit brake duration (MSB always zero)

3.a.09. Command 212: Set Number of Current Sense Samples in Averages

Effect: This setting determines how many current sense samples will be in each motor’s current average. These
averages are what the Get Currents command (216—Section 3.a.12)) returns. Each motor’s current average is a running average that is updated every other ADC conversion. The ADC can perform conversions at approximately 10 kHz, which means each motor’s current average is updated at approximately 5 kHz. The previous X samples are stored in memory, and the average returned is the average of those X most recent samples. This setting determines the value of X. The values are sent as three-bit, base-two exponents, meaning that the largest sample size allowed per average is 27(128) while the smallest is 20(1).
It is important to note that current sensing is not possible in joint motor mode. As such, this command has no effect when running in joint motor mode. It is also important to note that current sensing is only possible when using a motor driver daughter board that has VNH2SP30s (the VNH3SP30 does not provide current sense feedback).
This command does not save this setting to EEPROM, however it can be saved by issuing separate EEPROM­write commands (240—Section 3.d.02) that store the values at the appropriate addresses (3 for motor 1, 4 for motor 2). The values stored in EEPROM should be the actual number of samples to average, not the exponents. For example, if you are sending an exponent of 5 for motor 1 to the mega168 via this command, you should send a value of 25(32) to be stored in byte 3 of the mega168’s EEPROM. The value you store must be a power of two.
Values sent: motor 1 current sense samples exponent (3 bits), motor 2 current sense samples exponent (3 bits)
command byte = 212
data byte = (motor 2 current sense samples exponent << 3) | motor 1 current sense samples exponent
3. Low-Level SPI Commands Page 9 of 27
Loading...
+ 18 hidden pages