PIC16F877A + Stepper + mikroC
PIC16F877A + Stepper + mikroC
Hi all,
Well I’m new here, I got my easypic5 from a while, I start to modify some examples for learning.
I have a control board from a photocopy machine that can control 3 Stepper motor + Diagram.
I was wondering if somebody can help to start, looking to use 3 buttons for each motor, to do one step Fw/rev and one turn.
And I was looking to start with MikroC or MikroC Pro, just a small brief and then to start to change code and do some test... later on i can upgrade like adding memory for all the step that i did manually...
For the stepper I have an idea how it's work, but I’m newbie in mikroC...
Regards,
Sam
Well I’m new here, I got my easypic5 from a while, I start to modify some examples for learning.
I have a control board from a photocopy machine that can control 3 Stepper motor + Diagram.
I was wondering if somebody can help to start, looking to use 3 buttons for each motor, to do one step Fw/rev and one turn.
And I was looking to start with MikroC or MikroC Pro, just a small brief and then to start to change code and do some test... later on i can upgrade like adding memory for all the step that i did manually...
For the stepper I have an idea how it's work, but I’m newbie in mikroC...
Regards,
Sam
-
- Posts: 619
- Joined: 05 Jul 2008 06:05
- Location: Thailand
Hi,
Thanks Sobrietytest for your reply, well my board based on 3 MTD2001 - Stepping Motor Driver ICs, all what i'm trying to do as begining is to control 1 bipolar stepper motor with this board, i found some example for Uni-polar with mikroC, but nothing for bipolar.
Hope to get some assistance.
Regards,
Sam
Thanks Sobrietytest for your reply, well my board based on 3 MTD2001 - Stepping Motor Driver ICs, all what i'm trying to do as begining is to control 1 bipolar stepper motor with this board, i found some example for Uni-polar with mikroC, but nothing for bipolar.
Hope to get some assistance.
Regards,
Sam
Hi again,
Can someone help me with explanation if there's a smaller method to write the same code, and how i can use port A as input i mean if Buton A0 pressed it will start this routine, and A1 to start the second routine i know it seems a dumb question, but i want to start like a stepper (step by step)
PS, this for a unipolar stepper.
later on A2 to start the same routine but one time only.
Part of this code i ripped from the net can i get explanation for this part:
Regards,
Sam
Can someone help me with explanation if there's a smaller method to write the same code, and how i can use port A as input i mean if Buton A0 pressed it will start this routine, and A1 to start the second routine i know it seems a dumb question, but i want to start like a stepper (step by step)
PS, this for a unipolar stepper.
later on A2 to start the same routine but one time only.
Part of this code i ripped from the net can i get explanation for this part:
Code: Select all
//routine to move in one direction
for (i=0;i<50;i++)// increse i=50 to i=100 to cover double the distance
Code: Select all
char i;
char oldstate = 0;
void main()
{
TRISB = 0X00;
PORTB = 0X00;
TRISA.F1 = 0;
TRISA.F2 = 0;
do {
if (Button(&PORTA, 1, 1, 1))
oldstate = 1;
if (oldstate && Button(&PORTA, 1, 1, 0)) {
//routine to move in one direction
for (i=0;i<50;i++)// increse i=50 to i=100 to cover double the distance
{
PORTB.F1=0X80;
delay_ms(20);
PORTB.F2=0X40;
delay_ms(20);
PORTB.F3=0X20;
delay_ms(20);
PORTB.F4=0X10;
delay_ms(20);
}
oldstate = 0;
}
} while(1); // endless loop
//routine to move in the other direction
do {
if (Button(&PORTA, 2, 1, 1))
oldstate = 1;
if (oldstate && Button(&PORTA, 1, 1, 0)) {
//routine to move in one direction
for (i=0;i<50;i++)// increse i=50 to i=100 to cover double the distance
{
PORTB.F4=0X10;
delay_ms(20);
PORTB.F3=0X20;
delay_ms(20);
PORTB.F2=0X40;
delay_ms(20);
PORTB.F1=0X80;
delay_ms(20);
}
oldstate = 0;
}
} while(1); // endless loop
}
Sam
Hi MD5,
(By the way, I like your nick name), if that referes to hashing, then take a look at this code that I wrote: http://www.vbforums.com/showthread.php?t=232284
Anyways... I am a beginner at electronics, but I consider myself expert at programming.
And I see several things wrong with the code that you posted.
First, and the most important is: WHY ???? do you use delays !
You should use interrupts instead. Using interrupts you are not "hanging" your application, wich means that while you process commands that you give to your stepper motors, you can do something else, like talking to the computer that gives the commands on how to move the motors and how fast, etc.
Second:
When you have a line like this "PORTB.F1=0X80;", this means that you are acessing ONE bit, therefore, passing anything other than 1 and 0 does not make any sence.
So it should be:
PORTB.F1 = 1;
delay_ms(20);
PORTB.F2 = 1;
delay_ms(20);
PORTB.F3 = 1;
delay_ms(20);
PORTB.F4 = 1;
delay_ms(20);
BUT, that is wrong also... because there is nothing to turn the other bits OFF. So when you assign 1 to PORTB.F2, nothing turned off bit PORTB.F1... so at the last line PORTB.F4, ALL bits are set, and the second pass in the loop, all bits are ALREDY ON, and they will stay ON forever, because I don't see anywhere in the code where you turn the bits off...
What I think you should have is this:
PORTB = 0X01;
delay_ms(20);
PORTB = 0X02;
delay_ms(20);
PORTB = 0X04;
delay_ms(20);
PORTB = 0X08;
delay_ms(20);
This will assign values to the ENTIRE PORT, all 8 bits, and it will turn OFF all bits exept 1 of the bits.
The only problem with that, is that if you have anything on bits 4,5,6,7 (last 4 bits), then those bits will be off, but it looks like you don't use them anyways.
So, in short, I think you should search for a better example for controlling stepper motors using interrupts.
And third problem: I'm no expert in electronics (as I said before), but you said you are using a unipolar stepper, but when I look at the schematic, it looks like it is a bipolar stepper controller (I could be wrong though)
(By the way, I like your nick name), if that referes to hashing, then take a look at this code that I wrote: http://www.vbforums.com/showthread.php?t=232284
Anyways... I am a beginner at electronics, but I consider myself expert at programming.
And I see several things wrong with the code that you posted.
First, and the most important is: WHY ???? do you use delays !
You should use interrupts instead. Using interrupts you are not "hanging" your application, wich means that while you process commands that you give to your stepper motors, you can do something else, like talking to the computer that gives the commands on how to move the motors and how fast, etc.
Second:
When you have a line like this "PORTB.F1=0X80;", this means that you are acessing ONE bit, therefore, passing anything other than 1 and 0 does not make any sence.
So it should be:
PORTB.F1 = 1;
delay_ms(20);
PORTB.F2 = 1;
delay_ms(20);
PORTB.F3 = 1;
delay_ms(20);
PORTB.F4 = 1;
delay_ms(20);
BUT, that is wrong also... because there is nothing to turn the other bits OFF. So when you assign 1 to PORTB.F2, nothing turned off bit PORTB.F1... so at the last line PORTB.F4, ALL bits are set, and the second pass in the loop, all bits are ALREDY ON, and they will stay ON forever, because I don't see anywhere in the code where you turn the bits off...
What I think you should have is this:
PORTB = 0X01;
delay_ms(20);
PORTB = 0X02;
delay_ms(20);
PORTB = 0X04;
delay_ms(20);
PORTB = 0X08;
delay_ms(20);
This will assign values to the ENTIRE PORT, all 8 bits, and it will turn OFF all bits exept 1 of the bits.
The only problem with that, is that if you have anything on bits 4,5,6,7 (last 4 bits), then those bits will be off, but it looks like you don't use them anyways.
So, in short, I think you should search for a better example for controlling stepper motors using interrupts.
And third problem: I'm no expert in electronics (as I said before), but you said you are using a unipolar stepper, but when I look at the schematic, it looks like it is a bipolar stepper controller (I could be wrong though)
I wrote this code for you to give you an idea what you should do:
This is for 20MHz osscilator
NOTE: I just wrote this code without testing (I did not even compile it), so there probably are some errors.
First thing you should do is configure the ports (on top), right now it's set up to have the motors on port D, port A is by default for analog input.
Also, you might have to change the speed setting from 30 to a higher value, and that will make the motor slower.
Even your buttons should not be on port A, it should be on one of the digital ports (B, C, D), and set that port (or specific pins) as input.
This is for 20MHz osscilator
Code: Select all
// Configure pins for each motor
#define motora_pin1 PORTD.F0
#define motora_pin2 PORTD.F1
#define motora_pin3 PORTD.F2
#define motora_pin4 PORTD.F3
#define motorb_pin1 PORTD.F4
#define motorb_pin2 PORTD.F5
#define motorb_pin3 PORTD.F6
#define motorb_pin4 PORTD.F7
int motor_a_enable = 0;
int motor_a_speed = 30; // default speed for this motor
int motor_a_direction = 0;
int motor_a_step = 0;
int motor_a_interrupt_count = 0
int motor_b_enable = 0;
int motor_b_speed = 30; // default speed for this motor
int motor_b_direction = 0;
int motor_b_step = 0;
int motor_b_interrupt_count = 0
void interrupt () {
if (INTCON.T0IF == 1) { // Timer interrupt, 10000 / second
// do something only if motor flag is enabled
if(motor_a_enable) {
motor_a_interrupt_count++; // increment the interrupt count for motor
// move to the next step when interrupts count equal to the speed
// so this means that the lower the value of motor speed,
// the faster the motor will turn
if(motor_a_interrupt_count >= motor_a_speed) {
motora_pin1 = (motor_a_step == 0) ? 1:0;
motora_pin2 = (motor_a_step == 1) ? 1:0;
motora_pin3 = (motor_a_step == 2) ? 1:0;
motora_pin4 = (motor_a_step == 3) ? 1:0;
if(motor_a_direction)
motor_a_step = (++motor_a_step) % 4; // increment motor step
else { // decrement motor step
if (motor_a_step == 0) motor_a_step = 3;
else motor_a_step--;
}
motor_a_interrupt_count = 0; // reset interrupt count for this motor
}
} else {
// if not enabled, turn off all bits for this motor
motora_pin1 = motora_pin2 = motora_pin3 = motora_pin4 = 0;
}
if(motor_b_enable) {
motor_b_interrupt_count++; // increment the interrupt count for motor
if(motor_b_interrupt_count >= motor_b_speed) {
motorb_pin1 = (motor_b_step == 0) ? 1:0;
motorb_pin2 = (motor_b_step == 1) ? 1:0;
motorb_pin3 = (motor_b_step == 2) ? 1:0;
motorb_pin4 = (motor_b_step == 3) ? 1:0;
if(motor_b_direction)
motor_b_step = (++motor_b_step) % 4; // increment motor step
else { // decrement motor step
if (motor_b_step == 0) motor_b_step = 3;
else motor_b_step--;
}
motor_b_interrupt_count = 0; // reset interrupt count for this motor
}
} else {
motorb_pin1 = motorb_pin2 = motorb_pin3 = motorb_pin4 = 0;
}
TMR0 = 131;
INTCON.T0IF = 0; // reset interrupt overflow flag
}
}
void main(){
OPTION_REG = 0b10000001; // Assign prescaler to TMR0
TMR0 = 131; // Timer0 initial value
INTCON = 0b10100000; // Enable TMRO interrupt
ADCON0 = 0b10000000; // Configure analog inputs and Vref
TRISA = 0b11111111; // PORTA is input
PORTB = 0;
TRISB = 0b00000000; // Configure PORTB as output
// 76543210
PORTC = 0;
TRISC = 0b00000000; // Configure PORTC as output
// 76543210
PORTD = 0;
TRISD = 0b00000000; // Configure PORTD as output
do {
if (Button(&PORTA, 1, 1, 1)) motor_a_enable = 1;
if (Button(&PORTA, 1, 1, 1)) motor_a_enable = 0;
} while(1);
}
First thing you should do is configure the ports (on top), right now it's set up to have the motors on port D, port A is by default for analog input.
Also, you might have to change the speed setting from 30 to a higher value, and that will make the motor slower.
Even your buttons should not be on port A, it should be on one of the digital ports (B, C, D), and set that port (or specific pins) as input.
Hi CVMichael,
First I would like to thank you a lot, for your example and for all the explanation you mentioned in Both reply.
As I said I’m new in C, better in Electronics, that’s right the Diagram is for a bipolar stepper, but since I found that it's more complicated to do that, I said I will start with a small example with one unipolar stepper, to understand exactly how stuff work.
Then during searching I found that it will be better to use a small chip like UCN5804B, or similar that include almost everything, and all what you need to send command instead of complete routine, will save PIC pins.
I will test your example this weekend, and hope that there's no problem to ask if there's anything I didn't get...
MD5 refer to hash, I will check you link for encryption example.
Best regards,
Sam
First I would like to thank you a lot, for your example and for all the explanation you mentioned in Both reply.
As I said I’m new in C, better in Electronics, that’s right the Diagram is for a bipolar stepper, but since I found that it's more complicated to do that, I said I will start with a small example with one unipolar stepper, to understand exactly how stuff work.
Then during searching I found that it will be better to use a small chip like UCN5804B, or similar that include almost everything, and all what you need to send command instead of complete routine, will save PIC pins.
I will test your example this weekend, and hope that there's no problem to ask if there's anything I didn't get...
MD5 refer to hash, I will check you link for encryption example.
Best regards,
Sam
I'm using L297 and L298 for my bipolar steppers.
I also have code that I can give you using stepper motors with L297 and L298 for PIC16F877.
But the code is for the CNC I'm making, see this:
http://www.youtube.com/watch?v=izudmpqHE74
The code might be too complicated for you, but I guess you can try....
I am at work right now, I will send you another message with the code when I get home (in ~6 hours) (if you want)
I also have code that I can give you using stepper motors with L297 and L298 for PIC16F877.
But the code is for the CNC I'm making, see this:
http://www.youtube.com/watch?v=izudmpqHE74
The code might be too complicated for you, but I guess you can try....
I am at work right now, I will send you another message with the code when I get home (in ~6 hours) (if you want)
Actually, the reason is because I did not have (and did not want to use) a belt to connect the 2 threaded rods. So I used 2 motors connected to the same output on the microcontroller, so they move at the same time.MD5 wrote:I like your CNC, are you using 2 motor for X, to get higher torque from a small Stepper.
And by the way, that axis is Z. Y is up/down, X is left/right.
Yesterday, I was gonna post the code, but then I realized; how will it be useful if I don't also post the code that talks with the microcontroller (i.e. the VB6 code on the PC), and also, I will have to post the schematic of the CNC.MD5 wrote: it will be a good idea to post your Code, other members will appreciate that as I do.
Regards,
Sam
The thing is, I don't have any of those finished... I did not finish the MikroC code, I only have the schematic of the stepper motor drivers (everything else is in my mind only), and the VB6 code is only for testing, it does not even have a proper interface, only 3 buttons.
Also, I don't see anywhere on this page where I can post attachments ?
-
- Posts: 2780
- Joined: 25 Dec 2008 15:22
- Location: Scotland
Just some stuff to think aboutCVMichael wrote: Actually, the reason is because I did not have (and did not want to use) a belt to connect the 2 threaded rods. So I used 2 motors connected to the same output on the microcontroller, so they move at the same time.
Using 2 motors on the same axis is going to be really tough to truly get precision between both sides (obviously worse the greater the distance between both sides and the further the tool [pen] is from the centre of the table). Of course it really depends on what you want in terms of resolution and i have no idea what your motors are individually capable of but i can say with certainty that the movement of both sides will not be exactly the same and i am 100% sure you have the capability to see this in your own mind. I have worked with SMT placement machines costing in excess of 1M bucks (capable of pick and place 23,500 x 0201 components per hour) and even these only use one stepper for each axis and its not cost related.
Without even getting deeply into it, you should consider that different cable lengths (in fact before you leave the controller board even right down to different PCB track topology from pic to driver fet) will result in different stepper start/stop times. This is without considering all the components and their individual tolerances, then onto the mechanical properties including inertia (not such an issue at the demo speed)...
Z is Up/Down hmmm...
Well, when I made the CNC I assigned the axis based on MY logic, I did not actually check to see how real CNCs have the axis assigned. Also, my father's job is working with professional CNCs, and he did not comment about the axis when I showed him my CNC... I will double check next time I will have chat with him.