Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- jimESS
- Date:
- 2017-01-16
- Revision:
- 0:ac34ca83efb9
File content as of revision 0:ac34ca83efb9:
#include "mbed.h"
//Libraries needed
#include "mbed.h"
#include "USBHID.h"
// We declare a USBHID device.
// HID In/Out Reports are 64 Bytes long
// Vendor ID (VID): 0x15A2
// Product ID (PID): 0x0138
// Serial Number: 0x0001
USBHID hid(64, 64, 0x15A2, 0x0138, 0x0001, true);
//storage for send and receive data
HID_REPORT send_report;
HID_REPORT recv_report;
//Stepper Motor States
#define STATE1 1
#define STATE2 2
#define STATE3 3
#define STATE4 4
#define STATE5 5
#define STATE6 6
#define STATE7 7
#define STATE8 8
// USB COMMANDS
// These are sent from the PC
#define WRITE_LED 0x20
#define WRITE_OUTPUT_EN 0x30
#define WRITE_STEPS_PER_SEC 0x40
#define WRITE_RUN_STOP 0x70
#define WRITE_DIRECTION 0x71
#define WRITE_ACCEL 0x80
#define WRITE_RESET 0xA0
#define WRITE_STEPMODE 0xB0
// MOTOR STATES
#define STOP 0x00
#define RUN 0x02
#define RAMP 0x03
#define RESET 0x05
// LED CONSTANTS
#define LEDS_OFF 0x00
#define RED 0x01
#define GREEN 0x02
#define BLUE 0x03
#define READY_LED 0x04
// LOGICAL CONSTANTS
#define OFF 0x00
#define ON 0x01
//step modes
#define QTR 0x01
#define HALF 0x02
//FRDM-KL25Z LEDs
//DigitalOut red_led(LED1);
//DigitalOut green_led(LED2);
//DigitalOut blue_led(LED3);
//Input pins on Eval Board
DigitalOut IN1A(PTA5); // Pin IN1A input to EVAL board (FRDM PIN Name)
DigitalOut IN1B(PTC8); // Pin IN1B input to EVAL board (FRDM PIN Name)
DigitalOut IN2A(PTA13); // Pin IN2A input to EVAL board (FRDM PIN Name)
DigitalOut IN2B(PTD5); // Pin IN2B input to EVAL board (FRDM PIN Name)
//Green LED on Eval Board
//DigitalOut READY(PTC5); // Pin READY input to EVAL board (FRDM PIN Name)
//These pins are defined differntly on different parts
//OE for FRDM-17529 and FRDM-17533 Eval Boards
//and PSAVE for FRDM-17C724 and FRDM-17531 Eval Boards
//FRDM-34933 Eval Board does not have either of these pins
DigitalOut OE(PTA2); // Pin OE input to MPC17533, MPC17529 (FRDM PIN Name)
//variables
static int stepState = 1; //holds current step state of the step being applied to the stepper
static int stepMode = 0; //This is either 1/2 or 1/4 step
static int dir = 0; //rotational direction of stepper
static int rampCount = 0; //counter value used during acceleration ramp-up
static int initflag = 0; //used upon first entry into main at startup
static int runstop = 0; //holds value of running or stopped of commanded value from PC
static int motorState = 0; //holds state of stepper motor state machine (RUN, STOP, RESET, or RAMP)
static int accel = 0; //holds the value of accceleration enabled from PC
static float numRampSteps = 0; //calculated value that is based on the stepper speed after acceleration
static float stepRate = 10;
static int stepMultiplier = 1;
static float next_interval_us = 1200;
static float stepInterval_us = 1200;
static bool acceleration_start = 0;
static bool runStopChange = 0;
static bool accel_wait_flag = 0;
//static int mode = 0;
void test_state_mach(void);
void adv_state_mach_half(void);
void adv_state_mach_full(void);
void set_speed(float stepRate);
void acceleration_a(void);
void acceleration_b(void);
void set_speed_with_ramp(void);
void null_function(void);
void clear_accel_wait_flag(void);
//
//Create a Timeout function. Used for ramping up the speed at startup
Timeout accel_ramp;
//Create a Ticker function. Called during normal runtime to advance the stepper motor
Ticker advance_state;
int main()
{
//set up storage for incoming/outgoing
send_report.length = 64;
recv_report.length = 64;
//red_led = 1; // Red LED = OFF
//green_led = 1; // Green LED = OFF
//blue_led = 0; // Blue LED = ON
//READY = 0;
motorState = RESET;
while(1)
{
//try to read a msg
if(hid.readNB(&recv_report))
{
if(initflag == true)
{
initflag = false;
///blue_led = 1; //turn off blue LED
//READY = 0;
}
switch(recv_report.data[0]) //byte 0 of recv_report.data is command
{
//-----------------------------------------------------------------------------------------------------------------
// COMMAND PARSER
//-----------------------------------------------------------------------------------------------------------------
////////
case WRITE_LED:
switch(recv_report.data[1])
{
case LEDS_OFF:
//red_led = 1;
// green_led = 1;
// blue_led = 1;
break;
case RED:
//if(recv_report.data[2] == 1){red_led = 0;} else {red_led = 1;}
break;
case GREEN:
//if(recv_report.data[2] == 1){green_led = 0;} else {green_led = 1;}
break;
case BLUE:
//if(recv_report.data[2] == 1){blue_led = 0;} else {blue_led = 1;}
break;
default:
break;
}// End recv report data[1]
break;
////////end case WRITE_LED
////////
case WRITE_STEPS_PER_SEC:
stepRate = recv_report.data[1];
set_speed(stepRate);
break;
////////
case WRITE_RUN_STOP:
if(recv_report.data[1] == 1)
{
if(runstop != 1)
{
//red_led = 1;
//blue_led = 1;
//green_led = 0;
runstop = 1;
runStopChange = 1;
if(accel == 1)
{
motorState = RAMP;
next_interval_us = stepMultiplier;
acceleration_start = 1;
}
else
{
motorState = RUN;
set_speed(stepRate);
}
}
}
else
{
if(runstop != 0)
{
runstop = 0;
runStopChange = 1;
motorState = STOP;
//red_led = 0;
//green_led = 1;
//blue_led = 1;
}
}//end if(recv_report.data[1] == 1)
break;
////////
case WRITE_DIRECTION:
if(recv_report.data[1] == 1)
{
dir = 1;
}
else
{
dir = 0;
}
break;
////////
case WRITE_ACCEL:
if(recv_report.data[1] == 1)
{
accel = 1;
}
else
{
accel = 0;
}
break;
////////
case WRITE_STEPMODE:
if(recv_report.data[1] == QTR)
{
stepMode = QTR;
stepMultiplier = 8;
}
else
{
stepMode = HALF;
stepMultiplier = 4;
}
break;
////////
default:
break;
}// End Switch recv report data[0]
//-----------------------------------------------------------------------------------------------------------------
// end command parser
//-----------------------------------------------------------------------------------------------------------------
send_report.data[0] = recv_report.data[0]; // Echo Command
send_report.data[1] = recv_report.data[1]; // Echo Subcommand 1
send_report.data[2] = recv_report.data[2]; // Echo Subcommand 2
send_report.data[3] = 0x00;
send_report.data[4] = 0x00;
send_report.data[5] = 0x00;
send_report.data[6] = 0x00;
send_report.data[7] = 0x00;
//Send the report
hid.send(&send_report);
}// End If(hid.readNB(&recv_report))
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//End of USB message handling
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/************************************************************************************************************************
// This is handling of Speed, Acceleration, Direction, and Start/Stop
***********************************************************************************************************************/
switch (motorState)
{
case STOP:
if(runStopChange == 1)
{
runStopChange = 0;
OE = 1;
advance_state.detach();
}
else
{
OE = 1;
}
break;
case RUN:
if(runStopChange != 0)
{
OE = 0;
runStopChange = 0;
}
break;
case RESET:
OE = 1;
runStopChange = false;
motorState = STOP;
break;
case RAMP:
if(acceleration_start == 1)
{
OE = 0;
acceleration_a();
acceleration_start = 0;
}
if(accel_wait_flag == 0)
{
acceleration_a();
accel_wait_flag = 1;
accel_ramp.attach_us(&clear_accel_wait_flag, next_interval_us);
}
break;
}// end switch motorState
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}//end while
}//end main
//state machine to advance to next step
//called each time
void adv_state_mach_half()
{
//READY = 1;
if(OE == 0)
{
if(dir == 1)
{
switch(stepState)
{
case STATE1:
IN1A = 1; //coil A +, coil B +
IN1B = 0;
IN2A = 1;
IN2B = 0;
stepState = 2;
break;
case STATE2:
IN1A = 0; //coil A 0, coil B +
IN1B = 0;
IN2A = 1;
IN2B = 0;
stepState = 3;
break;
case STATE3:
IN1A = 0; //coil A -, coil B +
IN1B = 1;
IN2A = 1;
IN2B = 0;
stepState = 4;
break;
case STATE4:
IN1A = 0; //coil A -, coil B 0
IN1B = 1;
IN2A = 0;
IN2B = 0;
stepState = 5;
break;
case STATE5:
IN1A = 0; //coil A -, coil B -
IN1B = 1;
IN2A = 0;
IN2B = 1;
stepState = 6;
break;
case STATE6:
IN1A = 0; //coil A 0, coil B -
IN1B = 0;
IN2A = 0;
IN2B = 1;
stepState = 7;
break;
case STATE7:
IN1A = 1; //coil A +, coil B -
IN1B = 0;
IN2A = 0;
IN2B = 1;
stepState = 8;
break;
case STATE8:
IN1A = 1; //coil A +, coil B 0
IN1B = 0;
IN2A = 0;
IN2B = 0;
stepState = 1;
break;
default:
IN1A = 0;
IN1B = 0;
IN2A = 0;
IN2B = 0;
stepState = 1;
break;
}
}
else
{
switch(stepState)
{
case STATE1:
IN1A = 1; //coil A +, coil B 0
IN1B = 0;
IN2A = 0;
IN2B = 0;
stepState = 2;
break;
case STATE2:
IN1A = 1; //coil A +, coil B -
IN1B = 0;
IN2A = 0;
IN2B = 1;
stepState = 3;
break;
case STATE3:
IN1A = 0; //coil A 0 , coil B -
IN1B = 0;
IN2A = 0;
IN2B = 1;
stepState = 4;
break;
case STATE4:
IN1A = 0; //coil A -, coil B -
IN1B = 1;
IN2A = 0;
IN2B = 1;
stepState = 5;
break;
case STATE5:
IN1A = 0; //coil A -, coil B 0
IN1B = 1;
IN2A = 0;
IN2B = 0;
stepState = 6;
break;
case STATE6:
IN1A = 0; //coil A -, coil B +
IN1B = 1;
IN2A = 1;
IN2B = 0;
stepState = 7;
break;
case STATE7:
IN1A = 0; //coil A 0, coil B +
IN1B = 0;
IN2A = 1;
IN2B = 0;
stepState = 8;
break;
case STATE8:
IN1A = 1; //coil A +, coil B +
IN1B = 0;
IN2A = 1;
IN2B = 0;
stepState = 1;
break;
default:
IN1A = 0;
IN1B = 0;
IN2A = 0;
IN2B = 0;
stepState = 1;
break;
}
}
}
}
void adv_state_mach_full()
{
if(OE == 0)
{
if(dir == 1)
{
switch(stepState)
{
case STATE1:
IN1A = 1; //coil A +, coil B +
IN1B = 0;
IN2A = 1;
IN2B = 0;
stepState = 2;
break;
case STATE2:
IN1A = 1; //coil A +, coil B -
IN1B = 0;
IN2A = 0;
IN2B = 1;
stepState = 3;
break;
case STATE3:
IN1A = 0; //coil A -, coil B -
IN1B = 1;
IN2A = 0;
IN2B = 1;
stepState = 4;
break;
case STATE4:
IN1A = 0; //coil A -, coil B +
IN1B = 1;
IN2A = 1;
IN2B = 0;
stepState = 1;
break;
default:
IN1A = 0;
IN1B = 0;
IN2A = 0;
IN2B = 0;
stepState = 1;
break;
}
}
else
{
switch(stepState)
{
case STATE1:
IN1A = 0; //coil A -, coil B +
IN1B = 1;
IN2A = 1;
IN2B = 0;
stepState = 2;
break;
case STATE2:
IN1A = 0; //coil A -, coil B -
IN1B = 1;
IN2A = 0;
IN2B = 1;
stepState = 3;
break;
case STATE3:
IN1A = 1; //coil A +, coil B -
IN1B = 0;
IN2A = 0;
IN2B = 1;
stepState = 4;
break;
case STATE4:
IN1A = 1; //coil A +, coil B +
IN1B = 0;
IN2A = 1;
IN2B = 0;
stepState = 1;
break;
default:
IN1A = 0;
IN1B = 0;
IN2A = 0;
IN2B = 0;
stepState = 1;
break;
} //end switch
} //end else
}
}
/////////////////////////////////////////////////////////////////////////////////
void clear_accel_wait_flag(void)
{
accel_wait_flag = 0;
}
void acceleration_a(void)
{
rampCount ++;
if(rampCount <= numRampSteps)
{
test_state_mach();
next_interval_us = 1000000 * (1/float(rampCount * stepMultiplier));
// accel_ramp.attach_us(&acceleration_b, next_interval_us);//speed);
}
else
{
rampCount = 0;
motorState = RUN;
advance_state.attach_us(&test_state_mach, stepInterval_us);
}
}
/////////////////////////////////////////////////////////////////////////////////
void acceleration_b(void)
{
//READY = 1;
rampCount ++;
if(rampCount <= 5000) //numRampSteps)
{
test_state_mach();
next_interval_us = 1000000 * (1/(rampCount)); // * stepMultiplier));
accel_ramp.attach_us(&acceleration_a, next_interval_us);
}
else
{
//READY = 0;
rampCount = 0;
motorState = RUN;
advance_state.attach_us(&test_state_mach, stepInterval_us);
}
}
/////////////////////////////////////////////////////////////////////////////////
void test_state_mach(void)
{
if(stepMode == QTR)
{
adv_state_mach_half();
}
else
{
adv_state_mach_full();
}
}
///////////////////////////////////////////////////////////////////////////////////
void set_speed(float speed)
{
if(motorState == RUN)
{
if(stepMode == QTR)
{
numRampSteps = speed;
stepInterval_us = 1000000*(1.0/(speed * 8));
advance_state.attach_us(&test_state_mach, stepInterval_us);
}
else
{
numRampSteps = speed;
stepInterval_us = 1000000*(1.0/(speed * 4));
advance_state.attach_us(&test_state_mach, stepInterval_us);
}
}
else //not in run mode, save the change
{
if(stepMode == QTR)
{
numRampSteps = speed;
stepInterval_us = 1000000*(1.0/(speed * 8));
}
else
{
stepInterval_us = 1000000*(1.0/(speed * 4));
numRampSteps = speed;
}
}
}