71 #include <uStepperSLite.h>
74 volatile int32_t *p __attribute__((used));
125 void TIMER3_COMPA_vect(
void)
127 asm volatile(
"push r16 \n\t");
128 asm volatile(
"in r16,0x3F \n\t");
129 asm volatile(
"push r16 \n\t");
130 asm volatile(
"push r30 \n\t");
131 asm volatile(
"push r31 \n\t");
132 asm volatile(
"lds r30,p \n\t");
133 asm volatile(
"lds r31,p+1 \n\t");
135 asm volatile(
"jmp _stepGenerator \n\t");
139 void TIMER1_COMPA_vect(
void)
144 float posError = 0.0;
145 static float posEst = 0.0;
146 static float velIntegrator = 0.0;
147 static float velEst = 0.0;
150 int32_t pidTargetPositionTruncated;
151 int32_t *stepsSinceResetPointer;
160 I2C.
read(ENCODERADDR, ANGLE, 2, data);
162 curAngle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
173 if(deltaAngle < -2047)
178 else if(deltaAngle > 2047)
190 if(pointer->
mode == DROPIN)
193 stepCntTemp = pointer->
stepCnt;
197 posEst += velEst * ENCODERINTSAMPLETIME;
198 posError = (float)stepCntTemp - posEst;
199 velIntegrator += posError * PULSEFILTERKI;
200 velEst = (posError * PULSEFILTERKP) + velIntegrator;
248 if(pointer->
mode == PID)
251 stepsSinceResetPointer = &pidTargetPositionTruncated;
281 if(pointer->
state == INITDECEL)
288 pointer->
state = ACCEL;
294 if(*stepsSinceResetPointer <= pointer->decelToAccelThreshold)
296 pointer->
state = ACCEL;
301 else if(pointer->
state == ACCEL)
305 if(*stepsSinceResetPointer <= pointer->accelToCruiseThreshold)
307 pointer->
state = CRUISE;
315 pointer->
state = CRUISE;
320 else if(pointer->
state == CRUISE)
324 pointer->
state = CRUISE;
330 if(*stepsSinceResetPointer <= pointer->cruiseToDecelThreshold)
332 pointer->
state = DECEL;
339 pointer->
state = DECEL;
347 else if(pointer->
state == DECEL)
353 pointer->
state = STOP;
359 if(*stepsSinceResetPointer <= pointer->decelToStopThreshold)
361 pointer->
state = STOP;
366 else if(pointer->
state == STOP)
370 TCCR3B &= ~(1 << CS30);
371 if(pointer->
mode == NORMAL)
373 if(pointer->
brake == BRAKEON)
394 temp = (uint32_t)((STEPGENERATORFREQUENCY/(pointer->
currentPidSpeed)) + 0.5);
401 temp = (uint32_t)((STEPGENERATORFREQUENCY/(-pointer->
currentPidSpeed)) + 0.5);
446 TIMSK1 = (1 << OCIE1A);
447 TCCR1A = (1 << WGM11);
448 TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS10);
455 TIMSK1 &= ~(1 << OCIE1A);
456 I2C.
read(ENCODERADDR, ANGLE, 2, data);
457 TIMSK1 |= (1 << OCIE1A);
458 this->
encoderOffset = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
471 return (
float)this->
angle*0.087890625;
478 TIMSK1 &= ~(1 << OCIE1A);
479 I2C.
read(ENCODERADDR, MAGNITUDE, 2, data);
480 TIMSK1 |= (1 << OCIE1A);
482 return (((uint16_t)data[0]) << 8 )| (uint16_t)data[1];
488 TIMSK1 &= ~(1 << OCIE1A);
489 I2C.
read(ENCODERADDR, AGC, 1, &data);
490 TIMSK1 |= (1 << OCIE1A);
497 TIMSK1 &= ~(1 << OCIE1A);
498 I2C.
read(ENCODERADDR, STATUS, 1, &data);
499 TIMSK1 |= (1 << OCIE1A);
507 else if(data == 0x10)
512 else if(data == 0x20)
538 if(this->
state != STOP)
560 else if(vel > 100000.0)
570 if(this->
state != STOP)
586 float curVel, startVelocity = 0;
589 uint32_t initialDecelSteps;
591 if(this->
mode == DROPIN)
598 if(this->
state == STOP)
600 initialDecelSteps = 0;
606 else if((dir == CW && curVel < 0) || (dir == CCW && curVel > 0))
608 tempState = INITDECEL;
609 initialDecelSteps = (uint32_t)((curVel*curVel)/(2.0*this->
acceleration));
612 startVelocity = curVel;
614 else if((dir == CW && curVel > 0) || (dir == CCW && curVel < 0))
618 tempState = INITDECEL;
623 else if(abs(curVel) < this->
velocity)
627 initialDecelSteps = 0;
632 initialDecelSteps = 0;
639 initialDecelSteps = 0;
675 this->
state = tempState;
679 TCCR3B |= (1 << CS30);
684 float curVel, startVelocity = 0;
689 uint32_t initialDecelSteps;
690 uint32_t cruiseSteps = 0;
692 if(this->
mode == DROPIN)
708 initialDecelSteps = 0;
710 if(this->state == STOP)
716 if(accelSteps > (totalSteps >> 1))
719 accelSteps = decelSteps = (totalSteps >> 1);
720 accelSteps += totalSteps - accelSteps - decelSteps;
725 decelSteps = accelSteps;
726 cruiseSteps = totalSteps - accelSteps - decelSteps;
730 else if((dir == CW && curVel < 0) || (dir == CCW && curVel > 0))
733 initialDecelSteps = (uint32_t)((curVel*curVel)/(2.0*this->
acceleration));
735 totalSteps += initialDecelSteps;
737 if(accelSteps > (totalSteps >> 1))
739 accelSteps = decelSteps = (totalSteps >> 1);
740 accelSteps += totalSteps - accelSteps - decelSteps;
745 decelSteps = accelSteps;
746 cruiseSteps = totalSteps - accelSteps - decelSteps;
748 startVelocity = curVel;
750 else if((dir == CW && curVel > 0) || (dir == CCW && curVel < 0))
757 decelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->
acceleration));
758 startVelocity = curVel;
759 if(totalSteps <= (initialDecelSteps + decelSteps))
765 cruiseSteps = steps - initialDecelSteps - decelSteps;
769 else if(abs(curVel) < this->
velocity)
774 if(accelSteps > (totalSteps >> 1))
776 accelSteps = decelSteps = (totalSteps >> 1);
777 accelSteps += totalSteps - accelSteps - decelSteps;
782 decelSteps = accelSteps;
783 cruiseSteps = totalSteps - accelSteps - decelSteps;
786 cruiseSteps = totalSteps - accelSteps - decelSteps;
787 initialDecelSteps = 0;
795 initialDecelSteps = 0;
797 if(decelSteps >= totalSteps)
800 decelSteps = totalSteps;
804 cruiseSteps = totalSteps - decelSteps;
807 startVelocity = curVel;
815 if(accelSteps > (totalSteps >> 1))
818 accelSteps = decelSteps = (totalSteps >> 1);
819 accelSteps += totalSteps - accelSteps - decelSteps;
824 decelSteps = accelSteps;
825 cruiseSteps = totalSteps - accelSteps - decelSteps;
866 this->
brake = holdMode;
870 TCCR3B |= (1 << CS30);
875 if(this->
mode == DROPIN)
888 this->
brake = holdMode;
895 TCCR3B |= (1 << CS30);
905 uint32_t decelSteps = 0;
908 if(this->
mode == DROPIN)
915 decelSteps = (uint32_t)((curVel*curVel)/(2.0*this->
acceleration));
928 this->
brake = holdMode;
946 TCCR3B |= (1 << CS30);
953 int16_t angleDiff[3];
955 I2C.
read(ENCODERADDR, ANGLE, 2, data);
956 angle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
960 for(i = 0; i < 50; i++)
963 delayMicroseconds(1);
968 angleDiff[0] = (int16_t)
angle;
970 I2C.
read(ENCODERADDR, ANGLE, 2, data);
971 angle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
973 angleDiff[0] -= (int16_t)
angle;
977 for(i = 0; i < 50; i++)
980 delayMicroseconds(1);
985 angleDiff[1] = (int16_t)
angle;
987 I2C.
read(ENCODERADDR, ANGLE, 2, data);
988 angle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
990 angleDiff[1] -= (int16_t)
angle;
992 for(i = 0; i < 2; i++)
994 if(angleDiff[i] > 2048)
996 angleDiff[i] -= 4096;
998 else if(angleDiff[i] < -2048)
1000 angleDiff[i] += 4096;
1004 if((angleDiff[0] > 2 && angleDiff[1] < -2))
1021 float stepsPerRevolution = 3200.0,
1025 bool setHome =
true,
1028 uint8_t holdCurrent)
1042 if((uint16_t)stepsPerRevolution == FULL)
1044 stepsPerRevolution = 200.0;
1046 else if((uint16_t)stepsPerRevolution == HALF)
1048 stepsPerRevolution = 400.0;
1050 else if((uint16_t)stepsPerRevolution == QUARTER)
1052 stepsPerRevolution = 800.0;
1054 else if((uint16_t)stepsPerRevolution == EIGHT)
1056 stepsPerRevolution = 1600.0;
1058 else if((uint16_t)stepsPerRevolution == SIXTEEN)
1060 stepsPerRevolution = 3200.0;
1064 this->
angleToStep = ((float)(stepsPerRevolution))/360.0;
1065 this->
stepToAngle = 360.0/((float)(stepsPerRevolution));
1073 if(this->
mode == DROPIN)
1080 digitalWrite(2,HIGH);
1081 digitalWrite(3,HIGH);
1082 digitalWrite(4,HIGH);
1091 tempSettings.
invert = invert;
1132 TIMSK3 = (1 << OCIE3A);
1133 TCCR3A = (1 << WGM31);
1134 TCCR3B = (1 << WGM32) | (1 << WGM33);
1155 if(this->
state != STOP)
1190 if(this->
mode == DROPIN)
1201 while(!this->
isStalled(stallSensitivity));
1229 steps = (uint32_t)((abs(diff)*
angleToStep) + 0.5);
1259 float u, uSat, temp;
1261 static float integral;
1262 static bool integralReset = 0;
1269 if(this->
state == STOP)
1271 if(this->
brake == BRAKEON)
1288 u = error*this->
pTerm;
1305 integral += error*this->
iTerm;
1307 if(integral > 10000.0)
1311 else if(integral < -10000.0)
1313 integral = -10000.0;
1318 if(u > 100000 || u < -100000)
1321 uSat = ((u > 0) - (u < 0)) * uSat;
1328 if(error < -2.0 || error > 2.0)
1352 TCCR3B |= (1 << CS30);
1357 if(this->
state == STOP)
1359 TCCR3B &= ~(1 << CS30);
1366 temp = (uint32_t)((STEPGENERATORFREQUENCY/uSat) + 0.5);
1373 else if(uSat < -5.0)
1377 temp = (uint32_t)((STEPGENERATORFREQUENCY/-uSat) + 0.5);
1431 static float integral;
1432 static bool integralReset = 0;
1438 u = error*this->
pTerm;
1455 integral += error*this->
iTerm;
1457 if(integral > 10000.0)
1461 else if(integral < -10000.0)
1463 integral = -10000.0;
1466 if(error > -10 && error < 10)
1487 static float oldTargetPosition;
1488 static float oldEncoderPosition;
1489 static float encoderPositionChange;
1490 static float targetPositionChange;
1492 static float internalStall = 0.0;
1494 encoderPositionChange *= 0.99;
1495 encoderPositionChange += 0.01*(oldEncoderPosition - encoderPosition);
1496 oldEncoderPosition = encoderPosition;
1498 targetPositionChange *= 0.99;
1502 if(abs(encoderPositionChange) < abs(targetPositionChange)*0.5)
1512 if(internalStall >= 0.95)
1524 if(this->stallSensitivity > 1.0)
1526 this->stallSensitivity = 1.0;
1528 else if(this->stallSensitivity < 0.0)
1530 this->stallSensitivity = 0.0;
1546 this->
iTerm = I * ENCODERINTSAMPLETIME;
1551 this->
dTerm = D * ENCODERINTFREQ;
1564 if(cmd->charAt(2) ==
';')
1566 Serial.println(
"COMMAND NOT ACCEPTED");
1575 if(cmd->substring(0,2) == String(
"P="))
1579 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1581 value.concat(cmd->charAt(i));
1583 else if(cmd->charAt(i) ==
'.')
1585 value.concat(cmd->charAt(i));
1589 else if(cmd->charAt(i) ==
';')
1595 Serial.println(
"COMMAND NOT ACCEPTED");
1602 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1604 value.concat(cmd->charAt(i));
1606 else if(cmd->charAt(i) ==
';')
1608 Serial.print(
"COMMAND ACCEPTED. P = ");
1609 Serial.println(value.toFloat(),4);
1617 Serial.println(
"COMMAND NOT ACCEPTED");
1627 else if(cmd->substring(0,2) == String(
"I="))
1631 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1633 value.concat(cmd->charAt(i));
1635 else if(cmd->charAt(i) ==
'.')
1637 value.concat(cmd->charAt(i));
1641 else if(cmd->charAt(i) ==
';')
1647 Serial.println(
"COMMAND NOT ACCEPTED");
1654 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1656 value.concat(cmd->charAt(i));
1658 else if(cmd->charAt(i) ==
';')
1660 Serial.print(
"COMMAND ACCEPTED. I = ");
1661 Serial.println(value.toFloat(),4);
1670 Serial.println(
"COMMAND NOT ACCEPTED");
1680 else if(cmd->substring(0,2) == String(
"D="))
1684 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1686 value.concat(cmd->charAt(i));
1688 else if(cmd->charAt(i) ==
'.')
1690 value.concat(cmd->charAt(i));
1694 else if(cmd->charAt(i) ==
';')
1700 Serial.println(
"COMMAND NOT ACCEPTED");
1707 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1709 value.concat(cmd->charAt(i));
1711 else if(cmd->charAt(i) ==
';')
1713 Serial.print(
"COMMAND ACCEPTED. D = ");
1714 Serial.println(value.toFloat(),4);
1722 Serial.println(
"COMMAND NOT ACCEPTED");
1732 else if(cmd->substring(0,6) == String(
"invert"))
1734 if(cmd->charAt(6) !=
';')
1736 Serial.println(
"COMMAND NOT ACCEPTED");
1741 Serial.println(F(
"Direction normal!"));
1749 Serial.println(F(
"Direction inverted!"));
1761 else if(cmd->substring(0,5) == String(
"error"))
1763 if(cmd->charAt(5) !=
';')
1765 Serial.println(
"COMMAND NOT ACCEPTED");
1768 Serial.print(F(
"Current Error: "));
1770 Serial.println(F(
" Steps"));
1777 else if(cmd->substring(0,7) == String(
"current"))
1779 if(cmd->charAt(7) !=
';')
1781 Serial.println(
"COMMAND NOT ACCEPTED");
1784 Serial.print(F(
"Run Current: "));
1785 Serial.print(this->
driver.getRunCurrent());
1786 Serial.println(F(
" %"));
1787 Serial.print(F(
"Hold Current: "));
1788 Serial.print(this->
driver.getHoldCurrent());
1789 Serial.println(F(
" %"));
1796 else if(cmd->substring(0,10) == String(
"parameters"))
1798 if(cmd->charAt(10) !=
';')
1800 Serial.println(
"COMMAND NOT ACCEPTED");
1803 Serial.print(F(
"P: "));
1805 Serial.print(F(
", "));
1806 Serial.print(F(
"I: "));
1808 Serial.print(F(
", "));
1809 Serial.print(F(
"D: "));
1817 else if(cmd->substring(0,4) == String(
"help"))
1819 if(cmd->charAt(4) !=
';')
1821 Serial.println(
"COMMAND NOT ACCEPTED");
1831 else if(cmd->substring(0,11) == String(
"runCurrent="))
1835 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1837 value.concat(cmd->charAt(i));
1839 else if(cmd->charAt(i) ==
'.')
1841 value.concat(cmd->charAt(i));
1845 else if(cmd->charAt(i) ==
';')
1851 Serial.println(
"COMMAND NOT ACCEPTED");
1858 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1860 value.concat(cmd->charAt(i));
1862 else if(cmd->charAt(i) ==
';')
1864 if(value.toFloat() >= 0.0 && value.toFloat() <= 100.0)
1866 i = (uint8_t)value.toFloat();
1871 Serial.println(
"COMMAND NOT ACCEPTED");
1877 Serial.println(
"COMMAND NOT ACCEPTED");
1882 Serial.print(
"COMMAND ACCEPTED. runCurrent = ");
1884 Serial.println(F(
" %"));
1894 else if(cmd->substring(0,12) == String(
"holdCurrent="))
1898 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1900 value.concat(cmd->charAt(i));
1902 else if(cmd->charAt(i) ==
'.')
1904 value.concat(cmd->charAt(i));
1908 else if(cmd->charAt(i) ==
';')
1914 Serial.println(F(
"COMMAND NOT ACCEPTED"));
1921 if(cmd->charAt(i) >=
'0' && cmd->charAt(i) <=
'9')
1923 value.concat(cmd->charAt(i));
1925 else if(cmd->charAt(i) ==
';')
1927 if(value.toFloat() >= 0.0 && value.toFloat() <= 100.0)
1929 i = (uint8_t)value.toFloat();
1934 Serial.println(F(
"COMMAND NOT ACCEPTED"));
1940 Serial.println(F(
"COMMAND NOT ACCEPTED"));
1945 Serial.print(F(
"COMMAND ACCEPTED. holdCurrent = "));
1947 Serial.println(F(
" %"));
1959 Serial.println(F(
"COMMAND NOT ACCEPTED"));
1967 static String stringInput;
1968 static uint32_t t = millis();
1972 while(!Serial.available())
1975 if((millis() - t) >= 500)
1977 stringInput.remove(0);
1982 stringInput += (char)Serial.read();
1983 if(stringInput.lastIndexOf(
';') > -1)
1986 stringInput.remove(0);
1993 Serial.println(F(
"uStepper S-lite Dropin !"));
1994 Serial.println(F(
""));
1995 Serial.println(F(
"Usage:"));
1996 Serial.println(F(
"Show this command list: 'help;'"));
1997 Serial.println(F(
"Get PID Parameters: 'parameters;'"));
1998 Serial.println(F(
"Set Proportional constant: 'P=10.002;'"));
1999 Serial.println(F(
"Set Integral constant: 'I=10.002;'"));
2000 Serial.println(F(
"Set Differential constant: 'D=10.002;'"));
2001 Serial.println(F(
"Invert Direction: 'invert;'"));
2002 Serial.println(F(
"Get Current PID Error: 'error;'"));
2003 Serial.println(F(
"Get Run/Hold Current Settings: 'current;'"));
2004 Serial.println(F(
"Set Run Current (percent): 'runCurrent=50.0;'"));
2005 Serial.println(F(
"Set Hold Current (percent): 'holdCurrent=50.0;'"));
2006 Serial.println(F(
""));
2007 Serial.println(F(
""));
2014 EEPROM.get(0,tempSettings);
2040 uint8_t checksum = 0xAA;
2041 uint8_t *p = (uint8_t*)settings;
2043 for(i=0; i < 15; i++)