PIC16F877A + Stepper + mikroC

General discussion on mikroC.
Author
Message
MD5
Posts: 21
Joined: 25 Apr 2009 23:12

PIC16F877A + Stepper + mikroC

#1 Post by MD5 » 28 Apr 2009 23:17

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

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

#2 Post by Sobrietytest » 29 Apr 2009 02:17

This is almost impossible to answer without seeing your control board diagram, can you post it? Bear in mind that there might be copyright issues involoved! Perhaps you could PM the diagram to anyone that's interested.

MD5
Posts: 21
Joined: 25 Apr 2009 23:12

#3 Post by MD5 » 30 Apr 2009 00:04

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.
Image

Regards,
Sam

MD5
Posts: 21
Joined: 25 Apr 2009 23:12

#4 Post by MD5 » 01 May 2009 17:43

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:

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
}
Regards,
Sam

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

#5 Post by CVMichael » 03 May 2009 19:55

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)

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

#6 Post by CVMichael » 03 May 2009 21:48

I wrote this code for you to give you an idea what you should do:
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);
}
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.

MD5
Posts: 21
Joined: 25 Apr 2009 23:12

#7 Post by MD5 » 04 May 2009 18:09

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

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

#8 Post by CVMichael » 04 May 2009 18:48

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)

MD5
Posts: 21
Joined: 25 Apr 2009 23:12

#9 Post by MD5 » 04 May 2009 20:23

I like your CNC, are you using 2 motor for X, to get higher torque from a small Stepper.

it will be a good idea to post your Code, other members will appreciate that as I do.

Regards,
Sam

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

#10 Post by CVMichael » 05 May 2009 19:44

MD5 wrote:I like your CNC, are you using 2 motor for X, to get higher torque from a small Stepper.
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.

And by the way, that axis is Z. Y is up/down, X is left/right.
MD5 wrote: it will be a good idea to post your Code, other members will appreciate that as I do.

Regards,
Sam
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.
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 ? :?

Mince-n-Tatties
Posts: 2780
Joined: 25 Dec 2008 15:22
Location: Scotland

#11 Post by Mince-n-Tatties » 05 May 2009 21:55

CVMichael 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.
Just some stuff to think about

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)...

MD5
Posts: 21
Joined: 25 Apr 2009 23:12

#12 Post by MD5 » 06 May 2009 16:06

CVMichael wrote:
And by the way, that axis is Z. Y is up/down, X is left/right.

Image

Now i'm confused this X no?

Regards,

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

#13 Post by CVMichael » 06 May 2009 17:32

MD5 wrote: Image

Now i'm confused this X no?

Regards,
Z is Up/Down :o 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.

MD5
Posts: 21
Joined: 25 Apr 2009 23:12

#14 Post by MD5 » 06 May 2009 21:28

Hi Michael,

Could you please post the computer interface board that you're using.

Regards.

CVMichael
Posts: 239
Joined: 30 Apr 2009 02:36
Location: Canada, Toronto

#15 Post by CVMichael » 06 May 2009 21:41

I'm not sure what you mean by that ?

You mean the Visual Basic program that I made that communicates with the microcontroller ?

Post Reply

Return to “mikroC General”