Hi everyone.
I'm building a 3 axis router/mill using nema23 steppers.
The parallel breakout board has outputs of step and direction for all axis.
I want to utilize this to build a display unit (7 segs) showing where the axis is in respect to home or zero.
I coded a PIC18F2550 to do this and utilized the MAX7219 display driver to output to the 7 x 7 segment displays using hardware SPI.
I use INT2 interrupt to capture the step pulse and convert to millimeters at 1/1000mm resolution. Each step travels the axis 0.025mm.
THE PROBLEM I HAVE: on the breadboard setup I can use my signal generator to input the pulses (5v square wave 20% duty).
unfortunately anything over ~600Hz the display does not increment any faster, it still displays but not going any faster.
I need to be able to get up to 4kHz and display in real time as the axis can move at 100mm/sec which is 4000 steps/sec
I'm running the uP at 48MHz which at Fosc/4 is 12MHz = 83nS per instruction. 4kHz is 250uS and I feel there is plenty of time to do the calcs and display between interrupts.
Any help and suggestions greatly appreciated.
circuit and code below. I'm using MikroC pro for PIC.
I'm building a 3 axis router/mill using nema23 steppers.
The parallel breakout board has outputs of step and direction for all axis.
I want to utilize this to build a display unit (7 segs) showing where the axis is in respect to home or zero.
I coded a PIC18F2550 to do this and utilized the MAX7219 display driver to output to the 7 x 7 segment displays using hardware SPI.
I use INT2 interrupt to capture the step pulse and convert to millimeters at 1/1000mm resolution. Each step travels the axis 0.025mm.
THE PROBLEM I HAVE: on the breadboard setup I can use my signal generator to input the pulses (5v square wave 20% duty).
unfortunately anything over ~600Hz the display does not increment any faster, it still displays but not going any faster.
I need to be able to get up to 4kHz and display in real time as the axis can move at 100mm/sec which is 4000 steps/sec
I'm running the uP at 48MHz which at Fosc/4 is 12MHz = 83nS per instruction. 4kHz is 250uS and I feel there is plenty of time to do the calcs and display between interrupts.
Any help and suggestions greatly appreciated.
circuit and code below. I'm using MikroC pro for PIC.
Code:
//**************** // CODE FOR X & Y AXIS ******************************
//****************************************************************************
// Stepper motor step counter, converted to millimeter and display
// For PIC 18F2550
// EXT osc @ 20MHz PLL to 48MHz
// Graham Payne commenced 17/7/2015
//****************************************************************************
//Port Declarations
//****************************************************************************
sbit X_Step at RB2_bit; //step input external INT2
sbit X_Dir at RA0_bit; //direction input
sbit X_Step_Direction at TRISB2_bit;
sbit X_Dir_Direction at TRISA0_bit;
// SPI module connections for MAX7912
sbit CS at RC0_bit;
sbit Spi_SDO at RC7_bit;
sbit Spi_CLK at RB1_bit;
sbit Spi_SDI at RB0_bit;
sbit CS_direction at TRISC0_bit;
sbit Spi_SDO_Direction at TRISC7_bit;
sbit Spi_CLK_Direction at TRISB1_bit;
sbit Spi_SDI_Direction at TRISB0_bit;
//****************************************************************************
//Variables
//****************************************************************************
const unsigned long Step_MM = 25; //step amount in millimeters x 1000
unsigned long MM;
unsigned char init_MAX_Flag;
//****************************************************************************
//Send character to the MAX7219
void send_to_max7219(char address, char dat)
{
CS = 0; // LOAD(CS) LINE LOW
SPI1_Write(address);
SPI1_Write(dat);
CS = 1; // LOAD(CS) LINE HIGH
}
//****************************************************************************
//initiallise the MAX7219
void init_MAX7219() {
send_to_max7219(0x09,0xFF); // BCD Mode Code B
send_to_max7219(0x0A,0x09); // INTENSITY 19/32 th's
send_to_max7219(0x0B,0x06); // SCAN 7 DIGITS
send_to_max7219(0x0C,0x01); // TURN ON
send_to_max7219(0x0F,0x00); // TEST OFF
}
//****************************************************************************
void Step()
{
if(init_MAX_Flag == 0){ //have to init MAX7219 here as cannot have 2 threads.
init_MAX7219();
init_MAX_Flag = 1;
delay_ms(1);
}
//check direction, add/subtract a Step amount (*1000, no problems with decimal places & rounding errors)
if(X_Dir == 1) {MM += Step_MM;} else {MM -= Step_MM;}
//if(MM < 0) MM = fabs(MM); //if goes negative
send_to_max7219(0x01, MM/1000000); //extract 1000s
send_to_max7219(0x02, (MM/100000)%10); //extract 100s
send_to_max7219(0x03, (MM/10000)%10); //extract 10s
send_to_max7219(0x04, ((MM/1000)%10)+128); //extract 1s, add decimal point
send_to_max7219(0x05, (MM/100)%10); //extract .1s
send_to_max7219(0x06, (MM/10)%10); //extract .01s
send_to_max7219(0x07, MM%10); //extract .001s
}
//****************************************************************************
void interrupt()
{
if(INT2IF_bit == 1)
{
INT2IF_bit = 0; // clear the flag
Step(); // do a step and calculate output
}
}
//****************************************************************************
void main() {
CMCON = 7; //turn off comparators
ADCON0 = 0b00000000; //turn off A/D converters
ADCON1 = 0b00001111; //all digital
PORTA = 0;
PORTB = 0;
PORTC = 0;
TRISA = 0b00000001; //RA0 dir input
TRISB = 0b00000100; //RB2 int2 for step input
TRISC = 0b00000000;
SPI1_Init(); // Initialize SPI for MAX7912
delay_ms(100);
MM = 0;
init_MAX_Flag = 0;
GIE_bit = 1; // global interrupt enabled
INTEDG2_bit = 1; // rising edge detection on INT2
INT2IF_bit = 0; // clear INT2 flag
INT2IE_bit = 1; // INT2 enabled
do {
} while(1);
}
Attachments
-
20.9 KB Views: 2
Last edited: