diff --git a/ConstStepGen.cpp b/ConstStepGen.cpp new file mode 100644 index 0000000..99a7e44 --- /dev/null +++ b/ConstStepGen.cpp @@ -0,0 +1,212 @@ +#include "ConstStepGen.h" +#include + +ConstStepGen::ConstStepGen(uint8_t step_pin , uint8_t dir_pin, uint8_t EepromAddress) { + + _pin[0] = step_pin; // step + _pin[1] = dir_pin; //dir + _currentPos = 0; // + _targetPos = 0; + _speed = 0.0; + _maxSpeed = 1.0; + _stepInterval = 0; + _minPulseWidth = 1; + _lastStepTime = 0; + _direction = DIRECTION_CCW; + _EepromAddress = EepromAddress; + + int i; + for (i = 0; i < 2; i++) + _pinInverted[i] = 0; + + initOutputPin(); + +} + +void ConstStepGen::initOutputPin() { + pinMode(_pin[0], OUTPUT); + pinMode(_pin[1], OUTPUT); +} + +void ConstStepGen::moveTo(long absolute) { + if (_targetPos != absolute) { + _direction = ((absolute - _targetPos) > 0.0) ? DIRECTION_CW : DIRECTION_CCW; + _targetPos = absolute; + } +#if debug + Serial.println("moveTo------ _direction/_targetPos"); + Serial.println(_direction); + Serial.println(_targetPos); + Serial.println("-----"); +#endif +} + +void ConstStepGen::move(long relative) { + moveTo(_currentPos + relative); +} + +void ConstStepGen::setMaxSpeed(float speed) { + + if (_maxSpeed != speed) { + _maxSpeed = speed; + _stepMinInterval = 1000000.0 / speed; + } +#if debug + Serial.println("setMaxSpeed------ _maxSpeed/_stepMinInterval"); + Serial.println(_maxSpeed); + Serial.println(_stepMinInterval); + Serial.println("-----"); +#endif +} + +float ConstStepGen::maxSpeed() { + return _maxSpeed; +} + +void ConstStepGen::setSpeed(float speed) { + if (speed == _speed) + return; + + speed = constrain(speed, -_maxSpeed, _maxSpeed); + if (speed == 0.0) + _stepInterval = 0; + else { + _stepInterval = fabs(1000000.0 / speed); + } + _speed = speed; + +#if debug + Serial.println("setSpeed edildi------_speed/_stepInterval"); + Serial.println(_speed); + Serial.println(_stepInterval); + Serial.println("-----"); +#endif +} + +long ConstStepGen::distanceToGo() +{ + return _targetPos - _currentPos; +} + +boolean ConstStepGen::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); + step(); + +#if debug + Serial.println("STEP"); +#endif + + _lastStepTime = time; + return true; + } + else { + return false; + } +} + +void ConstStepGen::reCalculate() { + long distanceTo = distanceToGo(); + + if (distanceTo == 0) { + _stepInterval = 0; + _speed = 0.0; + return; + } + + _direction = (distanceTo > 0) ? DIRECTION_CW : DIRECTION_CCW; + +#if debug + Serial.println("reCalculate------_direction/distanceTo/"); + Serial.println(_direction); + Serial.println(distanceTo); + Serial.println("-----"); +#endif +} + +boolean ConstStepGen::run() { + + if (runSpeed()) + reCalculate(); + +#if debug + Serial.println("run------distanceToGo()/_targetPos/_currentPos"); + Serial.println(distanceToGo()); + Serial.println(_targetPos); + Serial.println(_currentPos); + Serial.println("-----"); +#endif + + return distanceToGo() != 0; + +} + +void ConstStepGen::step() { + + // _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 + +} + +void ConstStepGen::setOutputPins(uint8_t mask) { + uint8_t numpins = 2; + uint8_t i; + for (i = 0; i < numpins; i++) + digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i])); +} + +void ConstStepGen::setPinsInverted(bool stepInvert, bool directionInvert) { + _pinInverted[0] = stepInvert; + _pinInverted[1] = directionInvert; +} + +void ConstStepGen::stop() { + setSpeed(0); // hız sıfır + _targetPos = _currentPos; + EEPROM_write_CurrentPos(); +} + +void ConstStepGen::EEPROM_write_CurrentPos() +{ + byte* p = (byte*)(void*)&_currentPos; + for (int i = 0; i < sizeof(_currentPos); i++) + EEPROM.write(_EepromAddress++, *p++); +} + +void ConstStepGen::EEPROM_read_CurrentPos() +{ + unsigned long value = 0.0; + byte* p = (byte*)(void*)&value; + for (int i = 0; i < sizeof(value); i++) + *p++ = EEPROM.read(_EepromAddress++); + setCurrentPosition(value); +} + +void ConstStepGen::setCurrentPosition(unsigned long position) { + _targetPos = _currentPos = position; + _stepInterval = 0; + _speed = 0.0; +} + +bool ConstStepGen::isRunning() { + return !(_targetPos == _currentPos); +} diff --git a/ConstStepGen.h b/ConstStepGen.h new file mode 100644 index 0000000..14edfe8 --- /dev/null +++ b/ConstStepGen.h @@ -0,0 +1,73 @@ +#define debug 1 + +#ifndef ConstStepGen_h +#define ConstStepGen_h + +#include +#if ARDUINO >= 100 +#include +#else +#include +#include +#endif + +class ConstStepGen { + public: + ConstStepGen(uint8_t step_pin = 4, uint8_t dir_pin = 5 , uint8_t EepromAddress = 0); + void moveTo(long absolute); + void move(long relative); + boolean run(); + boolean runSpeed(); + void setMaxSpeed(float speed); + float maxSpeed(); + void setSpeed(float speed); + void initOutputPin(); + long distanceToGo(); + void setPinsInverted(bool stepInvert = false, bool directionInvert = false); + void stop(); + void setCurrentPosition(unsigned long position); + void EEPROM_write_CurrentPos(); + void EEPROM_read_CurrentPos(); + bool isRunning(); + + protected: + typedef enum + { + DIRECTION_CCW = 0, + DIRECTION_CW = 1 + } Direction; + + virtual void setOutputPins(uint8_t mask); + void reCalculate(); + void step(); + + private: + /// step motor driverları için step dir pinleri + uint8_t _pin[2]; + + /// eğer pinler invet edilmişse + uint8_t _pinInverted[2]; + + long _currentPos; //Stepler + + long _targetPos;//Stepler + + float _speed; // saniye başına step + + float _maxSpeed;// saniye başına maxSpeed; + + unsigned long _stepInterval;//stepler arası heseplanan zaman + + float _stepMinInterval;// max hızdaki step aralığı + + /// son atılan stepin microsaniye cinsinden değeri + unsigned long _lastStepTime; + + unsigned int _minPulseWidth; //step tick zamanı + + boolean _direction;//yön + + uint8_t _EepromAddress;//acil durumda eeprom yazılacak current pozisyonun başlangıç adresi + +}; +#endif diff --git a/sbt_step_jen.ino b/sbt_step_jen.ino new file mode 100644 index 0000000..7182288 --- /dev/null +++ b/sbt_step_jen.ino @@ -0,0 +1,57 @@ +#include "ConstStepGen.h" + + +String SeriBilgi; +char c; +float negTamSayi; + +ConstStepGen stepper0(A0, A2); + +void setup() { + Serial.begin(115200); + delay(1); + + pinMode(8, OUTPUT); + + stepper0.setMaxSpeed(200); + stepper0.setSpeed(200); + //stepper0.moveTo(-5); + +} + +void loop() { + +// if (digitalRead(8)) +// { +// delay(300); +// stepper0.run(); +// while (digitalRead(8)) {}; +// } + stepper0.run(); + if (Serial.available()) { + char c = Serial.read(); + if (c == '\n') { + parseSeriBilgi(SeriBilgi); + SeriBilgi = ""; + } + else { + SeriBilgi += c; + } + } +} +void parseSeriBilgi(String com) { + signed long pos, speeddd ; + + String Part0, Part1; + Part0 = com.substring(0, com.indexOf(" ")); + + com = com.substring(com.indexOf(" ") + 1); + Part1 = com.substring(0, com.indexOf(" ")); + pos = Part0.toFloat(); + speeddd = Part1.toFloat(); + + stepper0.setSpeed(speeddd); + stepper0.moveTo(pos); + +} +