Sample code for PCA9629 operation

Dependencies:   mbed PCA9629

What is "PCA9629" ?

Information

The stepper motor controller PCA9629A is available now!
This "A-version (PCA9629A)" is a feature extended version on "non-A (PCA9629)".
If you are thinking new design, the PCA9629A can be a good option.

The PCA9629A has several new features like on-the-fly speed change, extended ramp controls, filter settings for GPIO port inputs, braking and releasing by timeout.. and more.

Please find detail information here. The "A-version" chip is pin-compatible to "non-A". So it can be replaced easily.
The register mapping and bit fields are re-defined. Those should be cared by software.
A sample code and a class library are available for mbed.

Import programPCA9629A_Hello

Hello program for PCA9629A. Demonstrates basic operations of PCA9629A component library.

Import libraryPCA9629A

PCA9629A component library

A Stepper motor controller

/media/uploads/nxp_ip/9629x5-bd-s.jpg
PCA9629 (x5) demo board: PCA9629, 4x FETs and stepper motor

The PCA9629 is an I2C-bus controlled low-power CMOS device that provides all the logic and control required to drive a four phase stepper motor. PCA9629 is intended to be used with external high current drivers to drive the motor coils. The PCA9629 supports three stepper motor drive formats: one-phase (wave drive), two-phase, and half-step. In addition, when used as inputs, four General Purpose Input/Outputs (GPIOs) allow sensing of logic level output from optical interrupter modules and generate active LOW interrupt signal on the INT pin of PCA9629. This is a useful feature in sensing home position of motor shaft or reference for step pulses. Upon interrupt, the PCA9629 can be programmed to automatically stop the motor or reverse the direction of rotation of motor.

/media/uploads/nxp_ip/block-diagram0.png
Communicate with mbed through I2C. The motor can be operated by register settings

Output wave train is programmable using control registers. The control registers are programmed via the I2C-bus. Features built into the PCA9629 provide highly flexible control of stepper motor, off-load bus master/micro and significantly reduce I2C-bus traffic. These include control of step size, number of steps per single command, number of full rotations and direction of rotation. A ramp-up on start and/or ramp-down on stop is also provided.

/media/uploads/nxp_ip/pca9629_16steps_w_ramp_control.png
Waveforms: Lower 2 lines are I2C bus. Upper 4 lines are output for motor driver stage
Motor moving 16 steps with acceleration and deceleration after register setting via I2C

The PCA9629 is available in a 16-pin TSSOP package and is specified over the -40 deg-C to +85 deg-C industrial temperature range.

/media/uploads/nxp_ip/dsc_0103_-1-.jpg
TSSOP16 package

Datasheet is available at next URL.
http://www.nxp.com/documents/data_sheet/PCA9629.pdf

Hardware

A sample schematic diagram is shown in next picture.

/media/uploads/nxp_ip/sample-sch.png

This schematic diagram shows a sample of the PF35T-48C stepper motor. It is using 12V supply voltage for motor and driving by SI3812DV FETs.
Pull-up resisters: For /RESET and /INT pins : 4.7K-ohms, for I2C signals (SDA and SCL) : >1.3k-ohms.

NOTE

For the correct operation of the "auto interrupt" demo, the GPIO port P0(pin1) and P1(pin2) must be connected to sensor input. signal edge of those pins are treated as the interrupt.

Sample code

This sample code operates the PCA9629 using its class library.
For the details of the library, please find information in library page.

Import libraryPCA9629

PCA9629 a stepper motor controller class library

API details are available in here

This program targets PCA9629 which has I2C address of 0x42 on I2C bus on pin28 and pin27 of mbed. 4 types motor actions are demonstrated in sequence (following 1..4 steps in loop).

  1. Simple motor turn demo
    • Motor moved 96 steps with 100pps (pulse persecond) speed
    • Then the motor turn reversed, move 48 steps by 50pps.
  2. Ramp control demo
    • total operation time = 2 seconds, initial speed = 40.69pps, rotations = 5turns+0steps, ramp-up enable = enable, ramp-down enable = enable, rotate direction = CW
    • The ramp control can be done with several register settings. The setting value calculation can be done by register setting tool (an Excel worksheet) from NXP.
  3. Auto interrupt demo
    • The GPIO inputs can be used as interrupt for PCA9629. The operation can be stopped or change the direction of turn.
    • This is turn direction auto reversing demo. Motor will switch the direction 12 steps after interrupt signal assertion.
    • The register setting of interrupt operation can be done by register setting tool also.
    • This demo works correctly only when sensor signals available on P0(pin1) and P1(pin2) input pins.
  4. Speed change demo
    • Changing motor speed in 5 steps from 55pps to 275pps.
Committer:
nxp_ip
Date:
Mon Jul 23 05:05:01 2012 +0000
Revision:
2:2e75cedf6565
Parent:
1:cab53217fcc1
version 1.1 release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nxp_ip 2:2e75cedf6565 1 /** A sample code for PCA9629
nxp_ip 0:4f93f6ecf23c 2 *
nxp_ip 1:cab53217fcc1 3 * @author Akifumi (Tedd) OKANO, NXP Semiconductors
nxp_ip 2:2e75cedf6565 4 * @version 1.1
nxp_ip 2:2e75cedf6565 5 * @date 23-Jul-2012
nxp_ip 2:2e75cedf6565 6 *
nxp_ip 2:2e75cedf6565 7 * revision history
nxp_ip 2:2e75cedf6565 8 * version 1.0 (24-Apr-2011) : Initial version
nxp_ip 2:2e75cedf6565 9 * version 1.1 (23-Jul-2012) : API modification
nxp_ip 2:2e75cedf6565 10 * Correction for comments
nxp_ip 0:4f93f6ecf23c 11 *
nxp_ip 0:4f93f6ecf23c 12 * Released under the MIT License: http://mbed.org/license/mit
nxp_ip 0:4f93f6ecf23c 13 *
nxp_ip 2:2e75cedf6565 14 * An operation sample of PCU9629 stepper motor controller.
nxp_ip 2:2e75cedf6565 15 * The mbed accesses the PCU9629 registers through I2C.
nxp_ip 0:4f93f6ecf23c 16 *
nxp_ip 0:4f93f6ecf23c 17 * This sample code demonstrates 4 type of PCA9629 operation
nxp_ip 2:2e75cedf6565 18 *
nxp_ip 2:2e75cedf6565 19 * About PCA9629:
nxp_ip 2:2e75cedf6565 20 * http://www.nxp.com/products/interface_and_connectivity/i2c/i2c_bus_controller_and_bridge_ics/PCA9629PW.html
nxp_ip 0:4f93f6ecf23c 21 */
nxp_ip 0:4f93f6ecf23c 22
nxp_ip 0:4f93f6ecf23c 23 #include "mbed.h"
nxp_ip 0:4f93f6ecf23c 24 #include "PCA9629.h"
nxp_ip 0:4f93f6ecf23c 25
nxp_ip 0:4f93f6ecf23c 26 BusOut leds( LED4, LED3, LED2, LED1 );
nxp_ip 2:2e75cedf6565 27 PCA9629 motor_controller( p28, p27, 48 ); // SDA, SCL, Steps/rotation, I2C_address (option)
nxp_ip 0:4f93f6ecf23c 28
nxp_ip 0:4f93f6ecf23c 29 void motor_action_0( void );
nxp_ip 0:4f93f6ecf23c 30 void motor_action_1( void );
nxp_ip 0:4f93f6ecf23c 31 void motor_action_2( void );
nxp_ip 0:4f93f6ecf23c 32 void motor_action_3( void );
nxp_ip 0:4f93f6ecf23c 33 void motor_action_CDE( void );
nxp_ip 0:4f93f6ecf23c 34
nxp_ip 0:4f93f6ecf23c 35 int main() {
nxp_ip 0:4f93f6ecf23c 36 printf( "PCA9629 simple sample program\r\n" );
nxp_ip 0:4f93f6ecf23c 37
nxp_ip 0:4f93f6ecf23c 38 while ( 1 ) {
nxp_ip 0:4f93f6ecf23c 39 leds = 0x1;
nxp_ip 2:2e75cedf6565 40 motor_action_0(); // demo 0
nxp_ip 0:4f93f6ecf23c 41
nxp_ip 0:4f93f6ecf23c 42 leds = 0x3;
nxp_ip 2:2e75cedf6565 43 motor_action_1(); // demo 1
nxp_ip 0:4f93f6ecf23c 44
nxp_ip 0:4f93f6ecf23c 45 leds = 0x7;
nxp_ip 2:2e75cedf6565 46 motor_action_2(); // demo 2
nxp_ip 0:4f93f6ecf23c 47
nxp_ip 0:4f93f6ecf23c 48 leds = 0xF;
nxp_ip 2:2e75cedf6565 49 motor_action_3(); // demo 3
nxp_ip 0:4f93f6ecf23c 50 }
nxp_ip 0:4f93f6ecf23c 51 }
nxp_ip 0:4f93f6ecf23c 52
nxp_ip 0:4f93f6ecf23c 53 void motor_action_0( void ) {
nxp_ip 0:4f93f6ecf23c 54
nxp_ip 0:4f93f6ecf23c 55 // simple motor operation
nxp_ip 2:2e75cedf6565 56 // the motor spins 2 times (200pps) for clockwise (CW), 1 time (100pps) for counter-clockwise.
nxp_ip 0:4f93f6ecf23c 57
nxp_ip 0:4f93f6ecf23c 58 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 59 motor_controller.init_registers();
nxp_ip 0:4f93f6ecf23c 60
nxp_ip 2:2e75cedf6565 61 motor_controller.pps( PCA9629::CW, 200 );
nxp_ip 2:2e75cedf6565 62 motor_controller.rotations_and_steps( PCA9629::CW, 0, 96 );
nxp_ip 0:4f93f6ecf23c 63
nxp_ip 2:2e75cedf6565 64 motor_controller.pps( PCA9629::CCW, 100 );
nxp_ip 2:2e75cedf6565 65 motor_controller.rotations_and_steps( PCA9629::CCW, 0, 48 );
nxp_ip 0:4f93f6ecf23c 66
nxp_ip 0:4f93f6ecf23c 67 for ( int i = 0; i < 2; i++ ) {
nxp_ip 0:4f93f6ecf23c 68 motor_controller.start( PCA9629::CW );
nxp_ip 0:4f93f6ecf23c 69 wait( 2.0 );
nxp_ip 0:4f93f6ecf23c 70
nxp_ip 0:4f93f6ecf23c 71 motor_controller.start( PCA9629::CCW );
nxp_ip 0:4f93f6ecf23c 72 wait( 2.0 );
nxp_ip 0:4f93f6ecf23c 73 }
nxp_ip 0:4f93f6ecf23c 74 }
nxp_ip 0:4f93f6ecf23c 75
nxp_ip 0:4f93f6ecf23c 76 void motor_action_1( void ) {
nxp_ip 0:4f93f6ecf23c 77
nxp_ip 0:4f93f6ecf23c 78 // ramp control demo
nxp_ip 0:4f93f6ecf23c 79
nxp_ip 0:4f93f6ecf23c 80 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 81 motor_controller.init_registers();
nxp_ip 0:4f93f6ecf23c 82
nxp_ip 0:4f93f6ecf23c 83 // auto generated example code for PCA9629 on mbed
nxp_ip 0:4f93f6ecf23c 84 // setting: total operation time = 2, initial speed = 40.69, rotations = 5, steps = 0, ramp-up enable = enable, ramp-down enable = enable, rotate direction = CW
nxp_ip 0:4f93f6ecf23c 85
nxp_ip 0:4f93f6ecf23c 86 // motor_controller.write( PCA9629::STEPS_PER_ROATION, 48 );
nxp_ip 0:4f93f6ecf23c 87 motor_controller.write( PCA9629::CW__STEP_WIDTH, 1175 );
nxp_ip 0:4f93f6ecf23c 88 motor_controller.write( PCA9629::CW__STEP_COUNT, 35 );
nxp_ip 0:4f93f6ecf23c 89 motor_controller.write( PCA9629::CW__ROTATION_COUNT, 2 );
nxp_ip 0:4f93f6ecf23c 90 motor_controller.write( PCA9629::RAMPCNTL, 0x37 );
nxp_ip 0:4f93f6ecf23c 91
nxp_ip 0:4f93f6ecf23c 92 for ( int i = 0; i < 2; i++ ) {
nxp_ip 0:4f93f6ecf23c 93 motor_controller.write( PCA9629::MCNTL, 0xA8 ); // start
nxp_ip 0:4f93f6ecf23c 94 wait( 2.5 );
nxp_ip 0:4f93f6ecf23c 95 }
nxp_ip 0:4f93f6ecf23c 96 }
nxp_ip 0:4f93f6ecf23c 97
nxp_ip 0:4f93f6ecf23c 98 void motor_action_2( void ) {
nxp_ip 0:4f93f6ecf23c 99
nxp_ip 0:4f93f6ecf23c 100 // interrupt operation demo
nxp_ip 0:4f93f6ecf23c 101
nxp_ip 0:4f93f6ecf23c 102 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 103
nxp_ip 0:4f93f6ecf23c 104 // this array is a sample for PCA9629 local interrupt operation
nxp_ip 0:4f93f6ecf23c 105 // the P0 and P1 inputs enabled for interrupt in.
nxp_ip 0:4f93f6ecf23c 106 // motor rotation will be reversed by interrupt signals.
nxp_ip 0:4f93f6ecf23c 107 // the motor direction will be changed 12 steps after when the interrupt happened
nxp_ip 0:4f93f6ecf23c 108 //
nxp_ip 0:4f93f6ecf23c 109 // CW = 40.69pps, CCW = 81.38pps
nxp_ip 0:4f93f6ecf23c 110
nxp_ip 0:4f93f6ecf23c 111 char init_array2[] = { 0x80,
nxp_ip 0:4f93f6ecf23c 112 0x20, 0xE2, 0xE4, 0xE6, 0xE0, 0xFF, 0x10, // for registers MODE - WDCNTL (0x00 - 0x06
nxp_ip 0:4f93f6ecf23c 113 0x00, 0x00, // for registers IP and INTSTAT (0x07, 0x08)
nxp_ip 0:4f93f6ecf23c 114 0x0F, 0x03, 0x0C, 0x0F, 0x03, 0x01, 0x03, 0x03, 0x01, // for registers OP - INT_AUTO_CLR (0x09 - 0x11)
nxp_ip 0:4f93f6ecf23c 115 0x00, 0x00, 0x30, 0x00, 0xFF, 0x1F, 0xFF, 0x0F, // for registers SETMODE - CCWPWH (0x12 - 0x19)
nxp_ip 0:4f93f6ecf23c 116 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x00, 0x0A, 0x00, // for registers CWSCOUNTL - CCWRCOUNTH (0x1A - 0x21)
nxp_ip 0:4f93f6ecf23c 117 0x0C, 0x0C, // for registers EXTRASTEPS0 and EXTRASTEPS1 (0x22, 0x23)
nxp_ip 0:4f93f6ecf23c 118 0x00, 0x00, 0xA8 // for registers RMPCNTL - MCNTL (0x24 - 0x26)
nxp_ip 0:4f93f6ecf23c 119 };
nxp_ip 0:4f93f6ecf23c 120
nxp_ip 0:4f93f6ecf23c 121 motor_controller.set_all_registers( init_array2, sizeof( init_array2 ));
nxp_ip 0:4f93f6ecf23c 122 wait( 5.0 );
nxp_ip 0:4f93f6ecf23c 123
nxp_ip 0:4f93f6ecf23c 124 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 125 wait( 0.5 );
nxp_ip 0:4f93f6ecf23c 126
nxp_ip 0:4f93f6ecf23c 127 }
nxp_ip 0:4f93f6ecf23c 128
nxp_ip 0:4f93f6ecf23c 129 void motor_action_3( void ) {
nxp_ip 0:4f93f6ecf23c 130
nxp_ip 0:4f93f6ecf23c 131 // speed change sample while the motor is running
nxp_ip 0:4f93f6ecf23c 132
nxp_ip 0:4f93f6ecf23c 133 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 134 motor_controller.init_registers();
nxp_ip 0:4f93f6ecf23c 135
nxp_ip 0:4f93f6ecf23c 136 motor_controller.rotations( PCA9629::CCW, 0xFFFF );
nxp_ip 0:4f93f6ecf23c 137
nxp_ip 0:4f93f6ecf23c 138 for ( int i = 0; i < 2; i++ ) {
nxp_ip 0:4f93f6ecf23c 139 for ( int s = 1; s <= 5; s++ ) {
nxp_ip 2:2e75cedf6565 140 motor_controller.pps( PCA9629::CCW, 55 * s );
nxp_ip 0:4f93f6ecf23c 141 motor_controller.start( PCA9629::CCW );
nxp_ip 0:4f93f6ecf23c 142 wait( 1.0 );
nxp_ip 0:4f93f6ecf23c 143 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 144 }
nxp_ip 0:4f93f6ecf23c 145 }
nxp_ip 0:4f93f6ecf23c 146 }
nxp_ip 0:4f93f6ecf23c 147
nxp_ip 0:4f93f6ecf23c 148 void motor_action_CDE( void ) {
nxp_ip 2:2e75cedf6565 149 char scale[ 8 ] = { 4, 6, 8, 9, 11, 13, 15, 16 }; // CDEFGABC (A=0)
nxp_ip 0:4f93f6ecf23c 150 float freq[ 8 ];
nxp_ip 0:4f93f6ecf23c 151
nxp_ip 0:4f93f6ecf23c 152 for ( int i = 0; i < 8; i++ )
nxp_ip 2:2e75cedf6565 153 freq[ i ] = (440.0 / 8.0) * pow( 2.0, (float)(scale[ i ]) / 12.0 );
nxp_ip 0:4f93f6ecf23c 154
nxp_ip 0:4f93f6ecf23c 155 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 156 motor_controller.init_registers();
nxp_ip 0:4f93f6ecf23c 157 motor_controller.rotations( PCA9629::CCW, 0xFFFF );
nxp_ip 2:2e75cedf6565 158 motor_controller.write( PCA9629::PHCNTL, 0x1 );
nxp_ip 0:4f93f6ecf23c 159
nxp_ip 0:4f93f6ecf23c 160 for ( int i = 0; i < 2; i++ ) {
nxp_ip 0:4f93f6ecf23c 161 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 162 for ( int s = 0; s < 8; s++ ) {
nxp_ip 2:2e75cedf6565 163 motor_controller.pps( PCA9629::CCW, freq[ s ] );
nxp_ip 0:4f93f6ecf23c 164 motor_controller.start( PCA9629::CCW );
nxp_ip 0:4f93f6ecf23c 165 wait( 1 );
nxp_ip 0:4f93f6ecf23c 166
nxp_ip 0:4f93f6ecf23c 167 motor_controller.stop();
nxp_ip 0:4f93f6ecf23c 168 }
nxp_ip 0:4f93f6ecf23c 169 }
nxp_ip 0:4f93f6ecf23c 170 }
nxp_ip 0:4f93f6ecf23c 171