CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Stepper motor step/dir lib for drivers like A4988.. [SOLVED]
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mednas



Joined: 09 May 2020
Posts: 7
Location: Algeria

View user's profile Send private message Send e-mail

Stepper motor step/dir lib for drivers like A4988.. [SOLVED]
PostPosted: Sat May 09, 2020 11:24 am     Reply with quote

I want to use stepper motor with (step/dir) driver like A4988 or DRV8825, so i need library for this kind of driver that uses step/dir command. I found one but it's for Arduino AccelStepper. I can't use it for PIC16F or 18F. If someone can translate the code for CCS, or have a library or any help, i will really thank you and I will be grateful.
The code of this driver for Arduino is:
Code:

#include "AccelStepper.h"

#if 0
// Some debugging assistance
void dump(uint8_t* p, int l)
{
    int i;

    for (i = 0; i < l; i++)
    {
   Serial.print(p[i], HEX);
   Serial.print(" ");
    }
    Serial.println("");
}
#endif

void AccelStepper::moveTo(long absolute)
{
    if (_targetPos != absolute)
    {
   _targetPos = absolute;
   computeNewSpeed();
   // compute new n?
    }
}

void AccelStepper::move(long relative)
{
    moveTo(_currentPos + relative);
}

// Implements steps according to the current step interval
// You must call this at least once per step
// returns true if a step occurred
boolean AccelStepper::runSpeed()
{
    // Dont do anything unless we actually have a step interval
    if (!_stepInterval)
   return false;

    unsigned long time = micros();   
    if (time - _lastStepTime >= _stepInterval)
    {
   if (_direction == DIRECTION_CW)
   {
       // Clockwise
       _currentPos += 1;
   }
   else
   {
       // Anticlockwise 
       _currentPos -= 1;
   }
   step(_currentPos);

   _lastStepTime = time; // Caution: does not account for costs in step()

   return true;
    }
    else
    {
   return false;
    }
}

long AccelStepper::distanceToGo()
{
    return _targetPos - _currentPos;
}

long AccelStepper::targetPosition()
{
    return _targetPos;
}

long AccelStepper::currentPosition()
{
    return _currentPos;
}

// Useful during initialisations or after initial positioning
// Sets speed to 0
void AccelStepper::setCurrentPosition(long position)
{
    _targetPos = _currentPos = position;
    _n = 0;
    _stepInterval = 0;
    _speed = 0.0;
}

void AccelStepper::computeNewSpeed()
{
    long distanceTo = distanceToGo(); // +ve is clockwise from curent location

    long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16

    if (distanceTo == 0 && stepsToStop <= 1)
    {
   // We are at the target and its time to stop
   _stepInterval = 0;
   _speed = 0.0;
   _n = 0;
   return;
    }

    if (distanceTo > 0)
    {
   // We are anticlockwise from the target
   // Need to go clockwise from here, maybe decelerate now
   if (_n > 0)
   {
       // Currently accelerating, need to decel now? Or maybe going the wrong way?
       if ((stepsToStop >= distanceTo) || _direction == DIRECTION_CCW)
      _n = -stepsToStop; // Start deceleration
   }
   else if (_n < 0)
   {
       // Currently decelerating, need to accel again?
       if ((stepsToStop < distanceTo) && _direction == DIRECTION_CW)
      _n = -_n; // Start accceleration
   }
    }
    else if (distanceTo < 0)
    {
   // We are clockwise from the target
   // Need to go anticlockwise from here, maybe decelerate
   if (_n > 0)
   {
       // Currently accelerating, need to decel now? Or maybe going the wrong way?
       if ((stepsToStop >= -distanceTo) || _direction == DIRECTION_CW)
      _n = -stepsToStop; // Start deceleration
   }
   else if (_n < 0)
   {
       // Currently decelerating, need to accel again?
       if ((stepsToStop < -distanceTo) && _direction == DIRECTION_CCW)
      _n = -_n; // Start accceleration
   }
    }

    // Need to accelerate or decelerate
    if (_n == 0)
    {
   // First step from stopped
   _cn = _c0;
   _direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW;
    }
    else
    {
   // Subsequent step. Works for accel (n is +_ve) and decel (n is -ve).
   _cn = _cn - ((2.0 * _cn) / ((4.0 * _n) + 1)); // Equation 13
   _cn = max(_cn, _cmin);
    }
    _n++;
    _stepInterval = _cn;
    _speed = 1000000.0 / _cn;
    if (_direction == DIRECTION_CCW)
   _speed = -_speed;

#if 0
    Serial.println(_speed);
    Serial.println(_acceleration);
    Serial.println(_cn);
    Serial.println(_c0);
    Serial.println(_n);
    Serial.println(_stepInterval);
    Serial.println(distanceTo);
    Serial.println(stepsToStop);
    Serial.println("-----");
#endif
}

// Run the motor to implement speed and acceleration in order to proceed to the target position
// You must call this at least once per step, preferably in your main loop
// If the motor is in the desired position, the cost is very small
// returns true if the motor is still running to the target position.
boolean AccelStepper::run()
{
    if (runSpeed())
   computeNewSpeed();
    return _speed != 0.0 || distanceToGo() != 0;
}

AccelStepper::AccelStepper(uint8_t interface, uint8_t pin1, uint8_t pin2, uint8_t pin3, uint8_t pin4, bool enable)
{
    _interface = interface;
    _currentPos = 0;
    _targetPos = 0;
    _speed = 0.0;
    _maxSpeed = 1.0;
    _acceleration = 0.0;
    _sqrt_twoa = 1.0;
    _stepInterval = 0;
    _minPulseWidth = 1;
    _enablePin = 0xff;
    _lastStepTime = 0;
    _pin[0] = pin1;
    _pin[1] = pin2;
    _pin[2] = pin3;
    _pin[3] = pin4;
    _enableInverted = false;
   
    // NEW
    _n = 0;
    _c0 = 0.0;
    _cn = 0.0;
    _cmin = 1.0;
    _direction = DIRECTION_CCW;

    int i;
    for (i = 0; i < 4; i++)
   _pinInverted[i] = 0;
    if (enable)
   enableOutputs();
    // Some reasonable default
    setAcceleration(1);
}

AccelStepper::AccelStepper(void (*forward)(), void (*backward)())
{
    _interface = 0;
    _currentPos = 0;
    _targetPos = 0;
    _speed = 0.0;
    _maxSpeed = 1.0;
    _acceleration = 0.0;
    _sqrt_twoa = 1.0;
    _stepInterval = 0;
    _minPulseWidth = 1;
    _enablePin = 0xff;
    _lastStepTime = 0;
    _pin[0] = 0;
    _pin[1] = 0;
    _pin[2] = 0;
    _pin[3] = 0;
    _forward = forward;
    _backward = backward;

    // NEW
    _n = 0;
    _c0 = 0.0;
    _cn = 0.0;
    _cmin = 1.0;
    _direction = DIRECTION_CCW;

    int i;
    for (i = 0; i < 4; i++)
   _pinInverted[i] = 0;
    // Some reasonable default
    setAcceleration(1);
}

void AccelStepper::setMaxSpeed(float speed)
{
    if (speed < 0.0)
       speed = -speed;
    if (_maxSpeed != speed)
    {
   _maxSpeed = speed;
   _cmin = 1000000.0 / speed;
   // Recompute _n from current speed and adjust speed if accelerating or cruising
   if (_n > 0)
   {
       _n = (long)((_speed * _speed) / (2.0 * _acceleration)); // Equation 16
       computeNewSpeed();
   }
    }
}

float   AccelStepper::maxSpeed()
{
    return _maxSpeed;
}

void AccelStepper::setAcceleration(float acceleration)
{
    if (acceleration == 0.0)
   return;
    if (acceleration < 0.0)
      acceleration = -acceleration;
    if (_acceleration != acceleration)
    {
   // Recompute _n per Equation 17
   _n = _n * (_acceleration / acceleration);
   // New c0 per Equation 7, with correction per Equation 15
   _c0 = 0.676 * sqrt(2.0 / acceleration) * 1000000.0; // Equation 15
   _acceleration = acceleration;
   computeNewSpeed();
    }
}

void AccelStepper::setSpeed(float speed)
{
    if (speed == _speed)
        return;
    speed = constrain(speed, -_maxSpeed, _maxSpeed);
    if (speed == 0.0)
   _stepInterval = 0;
    else
    {
   _stepInterval = fabs(1000000.0 / speed);
   _direction = (speed > 0.0) ? DIRECTION_CW : DIRECTION_CCW;
    }
    _speed = speed;
}

float AccelStepper::speed()
{
    return _speed;
}

// Subclasses can override
void AccelStepper::step(long step)
{
    switch (_interface)
    {
        case FUNCTION:
            step0(step);
            break;

   case DRIVER:
       step1(step);
       break;
   
   case FULL2WIRE:
       step2(step);
       break;
   
   case FULL3WIRE:
       step3(step);
       break; 

   case FULL4WIRE:
       step4(step);
       break; 

   case HALF3WIRE:
       step6(step);
       break; 
      
   case HALF4WIRE:
       step8(step);
       break; 
    }
}

// You might want to override this to implement eg serial output
// bit 0 of the mask corresponds to _pin[0]
// bit 1 of the mask corresponds to _pin[1]
// ....
void AccelStepper::setOutputPins(uint8_t mask)
{
    uint8_t numpins = 2;
    if (_interface == FULL4WIRE || _interface == HALF4WIRE)
   numpins = 4;
    else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
   numpins = 3;
    uint8_t i;
    for (i = 0; i < numpins; i++)
   digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
}

// 0 pin step function (ie for functional usage)
void AccelStepper::step0(long step)
{
    (void)(step); // Unused
    if (_speed > 0)
   _forward();
    else
   _backward();
}

// 1 pin step function (ie for stepper drivers)
// This is passed the current step number (0 to 7)
// Subclasses can override
void AccelStepper::step1(long step)
{
    (void)(step); // Unused

    // _pin[0] is step, _pin[1] is direction
    setOutputPins(_direction ? 0b10 : 0b00); // Set direction first else get rogue pulses
    setOutputPins(_direction ? 0b11 : 0b01); // step HIGH
    // Caution 200ns setup time
    // Delay the minimum allowed pulse width
    delayMicroseconds(_minPulseWidth);
    setOutputPins(_direction ? 0b10 : 0b00); // step LOW
}


// 2 pin step function
// This is passed the current step number (0 to 7)
// Subclasses can override
void AccelStepper::step2(long step)
{
    switch (step & 0x3)
    {
   case 0: /* 01 */
       setOutputPins(0b10);
       break;

   case 1: /* 11 */
       setOutputPins(0b11);
       break;

   case 2: /* 10 */
       setOutputPins(0b01);
       break;

   case 3: /* 00 */
       setOutputPins(0b00);
       break;
    }
}
// 3 pin step function
// This is passed the current step number (0 to 7)
// Subclasses can override
void AccelStepper::step3(long step)
{
    switch (step % 3)
    {
   case 0:    // 100
       setOutputPins(0b100);
       break;

   case 1:    // 001
       setOutputPins(0b001);
       break;

   case 2:    //010
       setOutputPins(0b010);
       break;
      
    }
}

// 4 pin step function for half stepper
// This is passed the current step number (0 to 7)
// Subclasses can override
void AccelStepper::step4(long step)
{
    switch (step & 0x3)
    {
   case 0:    // 1010
       setOutputPins(0b0101);
       break;

   case 1:    // 0110
       setOutputPins(0b0110);
       break;

   case 2:    //0101
       setOutputPins(0b1010);
       break;

   case 3:    //1001
       setOutputPins(0b1001);
       break;
    }
}

// 3 pin half step function
// This is passed the current step number (0 to 7)
// Subclasses can override
void AccelStepper::step6(long step)
{
    switch (step % 6)
    {
   case 0:    // 100
       setOutputPins(0b100);
            break;
      
        case 1:    // 101
       setOutputPins(0b101);
            break;
      
   case 2:    // 001
       setOutputPins(0b001);
            break;
      
        case 3:    // 011
       setOutputPins(0b011);
            break;
      
   case 4:    // 010
       setOutputPins(0b010);
            break;
      
   case 5:    // 011
       setOutputPins(0b110);
            break;
      
    }
}

// 4 pin half step function
// This is passed the current step number (0 to 7)
// Subclasses can override
void AccelStepper::step8(long step)
{
    switch (step & 0x7)
    {
   case 0:    // 1000
       setOutputPins(0b0001);
            break;
      
        case 1:    // 1010
       setOutputPins(0b0101);
            break;
      
   case 2:    // 0010
       setOutputPins(0b0100);
            break;
      
        case 3:    // 0110
       setOutputPins(0b0110);
            break;
      
   case 4:    // 0100
       setOutputPins(0b0010);
            break;
      
        case 5:    //0101
       setOutputPins(0b1010);
            break;
      
   case 6:    // 0001
       setOutputPins(0b1000);
            break;
      
        case 7:    //1001
       setOutputPins(0b1001);
            break;
    }
}
   
// Prevents power consumption on the outputs
void    AccelStepper::disableOutputs()
{   
    if (! _interface) return;

    setOutputPins(0); // Handles inversion automatically
    if (_enablePin != 0xff)
    {
        pinMode(_enablePin, OUTPUT);
        digitalWrite(_enablePin, LOW ^ _enableInverted);
    }
}

void    AccelStepper::enableOutputs()
{
    if (! _interface)
   return;

    pinMode(_pin[0], OUTPUT);
    pinMode(_pin[1], OUTPUT);
    if (_interface == FULL4WIRE || _interface == HALF4WIRE)
    {
        pinMode(_pin[2], OUTPUT);
        pinMode(_pin[3], OUTPUT);
    }
    else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
    {
        pinMode(_pin[2], OUTPUT);
    }

    if (_enablePin != 0xff)
    {
        pinMode(_enablePin, OUTPUT);
        digitalWrite(_enablePin, HIGH ^ _enableInverted);
    }
}

void AccelStepper::setMinPulseWidth(unsigned int minWidth)
{
    _minPulseWidth = minWidth;
}

void AccelStepper::setEnablePin(uint8_t enablePin)
{
    _enablePin = enablePin;

    // This happens after construction, so init pin now.
    if (_enablePin != 0xff)
    {
        pinMode(_enablePin, OUTPUT);
        digitalWrite(_enablePin, HIGH ^ _enableInverted);
    }
}

void AccelStepper::setPinsInverted(bool directionInvert, bool stepInvert, bool enableInvert)
{
    _pinInverted[0] = stepInvert;
    _pinInverted[1] = directionInvert;
    _enableInverted = enableInvert;
}

void AccelStepper::setPinsInverted(bool pin1Invert, bool pin2Invert, bool pin3Invert, bool pin4Invert, bool enableInvert)
{   
    _pinInverted[0] = pin1Invert;
    _pinInverted[1] = pin2Invert;
    _pinInverted[2] = pin3Invert;
    _pinInverted[3] = pin4Invert;
    _enableInverted = enableInvert;
}

// Blocks until the target position is reached and stopped
void AccelStepper::runToPosition()
{
    while (run())
   ;
}

boolean AccelStepper::runSpeedToPosition()
{
    if (_targetPos == _currentPos)
   return false;
    if (_targetPos >_currentPos)
   _direction = DIRECTION_CW;
    else
   _direction = DIRECTION_CCW;
    return runSpeed();
}

// Blocks until the new target position is reached
void AccelStepper::runToNewPosition(long position)
{
    moveTo(position);
    runToPosition();
}

void AccelStepper::stop()
{
    if (_speed != 0.0)
    {   
   long stepsToStop = (long)((_speed * _speed) / (2.0 * _acceleration)) + 1; // Equation 16 (+integer rounding)
   if (_speed > 0)
       move(stepsToStop);
   else
       move(-stepsToStop);
    }
}

bool AccelStepper::isRunning()
{
    return !(_speed == 0.0 && _targetPos == _currentPos);
}



Thanks
_________________
''I never lose, I either win or learn!" Nelson Mandela


Last edited by mednas on Thu May 14, 2020 2:34 am; edited 3 times in total
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

Stepper Driver
PostPosted: Sat May 09, 2020 2:32 pm     Reply with quote

Did you search the CCS Code Library?
There are several there including one I posted a while back.

Go here to find the site index and the Code Library:
http://www.ccsinfo.com/forum/index.php

Then use the search option at the top of the page to search for the word stepper

BTW, I like your tag line!
''I never loose, I either win or learn!" Nelson Mandela
_________________
Google and Forum Search are some of your best tools!!!!


Last edited by dyeatman on Sun May 10, 2020 6:43 am; edited 6 times in total
mednas



Joined: 09 May 2020
Posts: 7
Location: Algeria

View user's profile Send private message Send e-mail

PostPosted: Sun May 10, 2020 2:43 am     Reply with quote

Hi Dyeatman. Yes i want a CCS Code Library to control a stepper motor with driver like drv8825 using step/dir pins for more precision (microstepping) and there are many stepper motor driver that work with step/dir commands. i appreciate any help. If you can give me link or posting a code please. Thank you
Sorry for my bad english
_________________
''I never lose, I either win or learn!" Nelson Mandela
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun May 10, 2020 4:56 am     Reply with quote

At the top of this post, you can goto the blue ccs index, choose 'code library'. It's another 'forum' that will have LOTS of working code for dozens of peripherals and tasks.
You can use the 'search' option (upper right area), just enter 'keywords' to narrow your search results.

I'm always amazed at the Worldwide appeal of PICs, and forget that English is not everyone's 1st language. I still haven't mastered it after 67 years.... Very Happy
mednas



Joined: 09 May 2020
Posts: 7
Location: Algeria

View user's profile Send private message Send e-mail

PostPosted: Sun May 10, 2020 10:12 am     Reply with quote

Thanks for your help, i Know how to do a search in the general CCS discussion. I found nothing about step/dir driver Library for stepper motor.
There are Library for stepper motor but direct connection like l293d or H bridge not step/dir driver library with acceleration and deceleration, speed and control for multiple stepper motor...
_________________
''I never lose, I either win or learn!" Nelson Mandela
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun May 10, 2020 10:26 am     Reply with quote

There's two hits for DRV8825, your question and another. Perhaps it has what you need ??
dyeatman



Joined: 06 Sep 2003
Posts: 1933
Location: Norman, OK

View user's profile Send private message

PostPosted: Sun May 10, 2020 11:18 am     Reply with quote

There is also a YouTube that controller and CCS.

https://www.youtube.com/watch?v=QmTxgDOOLdE
_________________
Google and Forum Search are some of your best tools!!!!
mednas



Joined: 09 May 2020
Posts: 7
Location: Algeria

View user's profile Send private message Send e-mail

PostPosted: Sun May 10, 2020 2:00 pm     Reply with quote

Yes i see the video this what i want dyeatman. But he don't share any information about code or library Crying or Very sad
temtronic i check the code of the second one who post the question about drv8825 but he use a code with PWM to control steps of the driver this make a motor speed without acceleration and deceleration its not good for stepper motor and can't control exact number of steps. Thank you.
Thanks for all who want to help me.
_________________
''I never lose, I either win or learn!" Nelson Mandela
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun May 10, 2020 2:38 pm     Reply with quote

if, IF, the Ardunio driver will do what you need, roll up your sleeves and convert into CCS C code.
What you've shown isn't the complete driver. If you eliminate all the //// comments, there's just a LOT of functions, no real code.
If you're already familiar with Ardunio style C, then conversion to CCS is pretty easy. even easier if you have the hardware (stepper PCB, motor, PSU).
mednas



Joined: 09 May 2020
Posts: 7
Location: Algeria

View user's profile Send private message Send e-mail

PostPosted: Sun May 10, 2020 4:53 pm     Reply with quote

yes temtronic, the code is not complete you are right, there are other .ccp files who have all functions i will change it, no chance i will roll up my sleeves as you said and i will take the functions i need. Confused
_________________
''I never lose, I either win or learn!" Nelson Mandela
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue May 12, 2020 12:39 am     Reply with quote

I have to make the comment here, that all stepper libraries can be
modified from being direct drive to being step/direction.
If you look at the posted library, it has different drive functions
for the motor. step1, is the step/direction drive. then step2, step3, step4
and step8, are the functions to output bit patterns to directly drive the
motor, in single step & half step modes.
Just as with this every existing library can be used with step/direction
drive. If you pull (for example), the basic ex_step code. All you need to
do is where the code advances forwards/back through phase patterns,
substitute a single step pulse, with the direction set for either forwards
or back. This example is very basic with no acceleration or deceleration,
but makes the point of how easy this change is.
Step/direction, is so simple compared to phase drive, that separate
libraries for it rarely exist.
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue May 12, 2020 5:17 am     Reply with quote

A comment.
I was curious about the A4988 so I downloaded the datasheet. I assume the driver uses the microstepping pins to do accel/decel . This would give it 5 'steps' during accel or decel.
The problem with any 'driver' is that it doesn't know what motor, drivetrain, load, etc. that it's controlling. You'll need to do a lot of bench testing to get the numbers right for smooth operation of whatever you're controlling. The last big stepper I coded for was a 2HP unit that ran a carousel,useingan LSI-11 and assembler.
Start with a basic 'bit control' driver. Get the PIC to actually move the motor and direction. Then add microstepping functions. After that it's just bench testing to get the timing of transitions 'right' for whatever you're controlling.
Also
be very careful about PCB layout, PSU design, wiring, etc. and protect all PIC pins from EMI spikes !
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Tue May 12, 2020 7:50 am     Reply with quote

Just FYI, there is a 'move steps' library here:

<http://www.buildlog.net/pic/pic_basic_motion.html>

It has the classic 'SPI_SS_DISABLED' error created by the old wizard,
so change this line to setup_spi(FALSE); which is the correct syntax.

(edited, forgot the closing bracket...)


Last edited by Ttelmah on Tue May 12, 2020 9:35 am; edited 1 time in total
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Tue May 12, 2020 8:38 am     Reply with quote

Hello mednas,

Sorry, nothing to add regarding your original question, but I will point out that there is an error in your signature line! I realize that you are probably not a native English speaker, so it's quite understandable!

You use the word 'loose' in your signature line which is an adjective meaning 'not tight'. You really want to use the word 'lose' which is a verb meaning 'fail to win'.

BTW, the sentiment of the what you are trying to say is very admirable, and I agree with it 100%!
_________________
John

If it's worth doing, it's worth doing in real hardware!
mednas



Joined: 09 May 2020
Posts: 7
Location: Algeria

View user's profile Send private message Send e-mail

PostPosted: Wed May 13, 2020 5:32 am     Reply with quote

thanks for all, i tried this code its work for full step with a4988 and drv8825 but so slowly for microstepping its logic, i will work on that,this is the code:
Code:

// this code work fine with step/dir drivers ( full step ) but slowly for microstepping
#include <16f876a.h>
#device adc=10
#fuses HS,NOWDT,NOPUT,NOPROTECT,NODEBUG,BROWNOUT,NOLVP,NOCPD,NOWRT
#USE DELAY(clock = 16000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,bits=8, parity=N)
#INCLUDE <stdlib.h>
#include <flex_lcd.c>

#define BUFFER_SIZE 15
BYTE buffer[BUFFER_SIZE];
BYTE string[BUFFER_SIZE];
BYTE P1[7];
BYTE P2[7];
BYTE next_in = 0;
BYTE next_out = 0;

#define Dir_M1  PIN_C0         // dir pin for driver of motor 1
#define Dir_M2  PIN_C2         // dir pin for driver of motor 2
#define Step_M1  PIN_C1         // step pin for driver of motor 1
#define Step_M2  PIN_C3         // step pin for driver of motor 2
#define en_dr  PIN_C4         // enable drivers pin

unsigned int8 i=0,t,k;
int1 have_string=FALSE;
unsigned int8 max_sp=2;       //max speed 2 ms per step thats for full drive its so slowly for microsteps
unsigned int8 acc = 30;    //accelleration deceleration example : 30 steps for acceleration
signed int32 pos1,pos2,j;

#int_rda
void serial_isr() {
   int t;

   buffer[next_in]=getc();
   t=next_in;
   next_in=(next_in+1) % BUFFER_SIZE;
   if(next_in==next_out)
     next_in=t;           // Buffer full !!
}

#define bkbhit (next_in!=next_out)

BYTE bgetc() {
   BYTE c;
   while(!bkbhit) ;
   c=buffer[next_out];
   next_out=(next_out+1) % BUFFER_SIZE;
   return(c);
}

//-----------------------------------------------------------------------------------
void step_move(unsigned int a,signed int32 y){
switch (a) {
     
            case 1:{ if (y<0) {output_low(Dir_M1);y=-y;} else output_high (Dir_M1);
            for (j=0;j<y;j++)
            {
            if (j<acc)
               {
               i=(acc+max_sp-1-j);
               output_high(Step_M1);delay_ms(i);output_low(Step_M1);delay_ms(i);
               }
            if ((j>=acc)&&(j<=(y-acc)))
               {
               output_high(Step_M1);delay_ms(i);output_low(Step_M1);delay_ms(i);
               }
            if (j>(y-acc))
               {
               i=j-(y-(acc+max_sp-1));
               output_high(Step_M1);delay_ms(i);output_low(Step_M1);delay_ms(i);
               }
            }}break;
            case 2:{  if (y<0) {output_low(Dir_M2);y=-y;} else output_high(Dir_M2);
            for (j=0;j<y;j++)
            {
            if (j<acc)
               {
               i=(acc+max_sp-1-j);
               output_high(Step_M2);delay_ms(i);output_low(Step_M2);delay_ms(i);
               }
            if ((j>=acc)&&(j<=(y-acc)))
               {
               output_high(Step_M2);delay_ms(i);output_low(Step_M2);delay_ms(i);
               }
            if (j>(y-acc))
               {
               i=j-(y-(acc+max_sp-1));
               output_high(Step_M2);delay_ms(i);output_low(Step_M2);delay_ms(i);
               }
            }}break;
           
}
}
//-----------------------------------------------------------------------------------
void main()
{
   set_tris_a(0xff);
   set_tris_b(0x00);
   //port_a_pullups(TRUE);           
   
   lcd_init() ;
   printf(lcd_putc,"Salam alikoum");      //hello
         
   delay_ms(300); //many LCD's require longer to wake
   output_high(en_dr); //initialise driver
   enable_interrupts(GLOBAL);               
   enable_interrupts(INT_RDA);      //enable_interrupts

    do {
       delay_ms(100);
       k=0;
       string="";
   
       while(bkbhit){
        string[k] = bgetc();
        k++;
        have_string=true;
       }
       
       if ( have_string){
       
       disable_interrupts(GLOBAL);
       have_string=false;
       printf("RX=>OK\n");
       
       for (k=0;k<7;k++){P1[k]=string[k];}
       for (k=7;k<15;k++){P2[k-7]=string[k];}
       pos1=atoi32(P1);
       pos2=atoi32(P2);
       printf("pos1=%ld>>>pos2=%ld\n",pos1,pos2);
     
       output_low(en_dr);        //enable driver
       step_move(1,pos1);     //move motor1 to pos 1
       printf("Pos1>>%ld end\r\n",pos1);
       delay_ms(1000);
       step_move(1,pos2); //move motor1 to pos 2
       printf("Pos2>>%ld end\r\n",pos2);
       delay_ms(1000);
       output_high(en_dr);    //disable driver
       
       enable_interrupts(GLOBAL);
                     
       }
        if (!input(PIN_a1) )
       {
       output_low(en_dr);      //enable driver
       pos1=pos1*(-1);
       step_move(1,pos1);
       printf("Pos1>>%ld end\r\n",pos1);
       delay_ms(1000);
       pos2=pos2*(-1);
       step_move(1,pos2);
       printf("Pos2>>%ld end\r\n",pos2);
       delay_ms(1000);
       output_high(en_dr);    //disable driver
       }
       
         
                 
       
                     
   } while (TRUE); 
}
////////////////////////////////////////////////////////////////////////////////

thank you Ttelmah i will try with the library of the link
ezflyr yes i'm not native english speaker (arabic and french) but i try to speak and to search in english, thank you for explanation
_________________
''I never lose, I either win or learn!" Nelson Mandela
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group