75 volatile int32_t *p __attribute__((used));
130 asm volatile(
"push r16 \n\t");
131 asm volatile(
"in r16,0x3F \n\t");
132 asm volatile(
"push r16 \n\t");
133 asm volatile(
"push r30 \n\t");
134 asm volatile(
"push r31 \n\t");
135 asm volatile(
"lds r30,p \n\t");
136 asm volatile(
"lds r31,p+1 \n\t");
138 asm volatile(
"ldd r16,z+24 \n\t");
139 asm volatile(
"cpi r16,0x01 \n\t");
140 asm volatile(
"breq _pid \n\t");
142 asm volatile(
"ldd r16,z+0 \n\t");
143 asm volatile(
"cpi r16,0x00 \n\t");
144 asm volatile(
"brne _pid \n\t");
146 asm volatile(
"ldd r16,z+1 \n\t");
147 asm volatile(
"cpi r16,0x00 \n\t");
148 asm volatile(
"brne _pid \n\t");
150 asm volatile(
"ldd r16,z+2 \n\t");
151 asm volatile(
"cpi r16,0x00 \n\t");
152 asm volatile(
"brne _pid \n\t");
154 asm volatile(
"ldd r16,z+3 \n\t");
155 asm volatile(
"cpi r16,0x00 \n\t");
156 asm volatile(
"brne _pid \n\t");
158 asm volatile(
"subi r30,83 \n\t");
159 asm volatile(
"sbci r31,0 \n\t");
161 asm volatile(
"jmp _AccelerationAlgorithm \n\t");
163 asm volatile(
"_pid: \n\t");
164 asm volatile(
"push r0 \n\t");
165 asm volatile(
"push r1 \n\t");
166 asm volatile(
"push r2 \n\t");
167 asm volatile(
"push r3 \n\t");
168 asm volatile(
"push r4 \n\t");
169 asm volatile(
"push r5 \n\t");
170 asm volatile(
"push r6 \n\t");
171 asm volatile(
"push r7 \n\t");
172 asm volatile(
"push r8 \n\t");
173 asm volatile(
"push r9 \n\t");
174 asm volatile(
"push r10 \n\t");
175 asm volatile(
"push r11 \n\t");
176 asm volatile(
"push r12 \n\t");
177 asm volatile(
"push r13 \n\t");
178 asm volatile(
"push r14 \n\t");
179 asm volatile(
"push r15 \n\t");
180 asm volatile(
"push r17 \n\t");
181 asm volatile(
"push r18 \n\t");
182 asm volatile(
"push r19 \n\t");
183 asm volatile(
"push r20 \n\t");
184 asm volatile(
"push r21 \n\t");
185 asm volatile(
"push r22 \n\t");
186 asm volatile(
"push r23 \n\t");
187 asm volatile(
"push r24 \n\t");
188 asm volatile(
"push r25 \n\t");
189 asm volatile(
"push r26 \n\t");
190 asm volatile(
"push r27 \n\t");
191 asm volatile(
"push r28 \n\t");
192 asm volatile(
"push r29 \n\t");
201 asm volatile(
"nop \n\t");
202 asm volatile(
"nop \n\t");
203 asm volatile(
"nop \n\t");
204 asm volatile(
"nop \n\t");
205 asm volatile(
"nop \n\t");
206 asm volatile(
"nop \n\t");
207 asm volatile(
"nop \n\t");
208 asm volatile(
"nop \n\t");
209 asm volatile(
"nop \n\t");
210 asm volatile(
"nop \n\t");
211 asm volatile(
"nop \n\t");
212 asm volatile(
"nop \n\t");
213 asm volatile(
"nop \n\t");
214 asm volatile(
"nop \n\t");
215 asm volatile(
"nop \n\t");
216 asm volatile(
"nop \n\t");
217 asm volatile(
"nop \n\t");
234 asm volatile(
"pop r29 \n\t");
235 asm volatile(
"pop r28 \n\t");
236 asm volatile(
"pop r27 \n\t");
237 asm volatile(
"pop r26 \n\t");
238 asm volatile(
"pop r25 \n\t");
239 asm volatile(
"pop r24 \n\t");
240 asm volatile(
"pop r23 \n\t");
241 asm volatile(
"pop r22 \n\t");
242 asm volatile(
"pop r21 \n\t");
243 asm volatile(
"pop r20 \n\t");
244 asm volatile(
"pop r19 \n\t");
245 asm volatile(
"pop r18 \n\t");
246 asm volatile(
"pop r17 \n\t");
247 asm volatile(
"pop r15 \n\t");
248 asm volatile(
"pop r14 \n\t");
249 asm volatile(
"pop r13 \n\t");
250 asm volatile(
"pop r12 \n\t");
251 asm volatile(
"pop r11 \n\t");
252 asm volatile(
"pop r10 \n\t");
253 asm volatile(
"pop r9 \n\t");
254 asm volatile(
"pop r8 \n\t");
255 asm volatile(
"pop r7 \n\t");
256 asm volatile(
"pop r6 \n\t");
257 asm volatile(
"pop r5 \n\t");
258 asm volatile(
"pop r4 \n\t");
259 asm volatile(
"pop r3 \n\t");
260 asm volatile(
"pop r2 \n\t");
261 asm volatile(
"pop r1 \n\t");
262 asm volatile(
"pop r0 \n\t");
263 asm volatile(
"pop r31 \n\t");
264 asm volatile(
"pop r30 \n\t");
265 asm volatile(
"pop r16 \n\t");
266 asm volatile(
"out 0x3F,r16 \n\t");
267 asm volatile(
"pop r16 \n\t");
268 asm volatile(
"reti \n\t");
277 static float deltaSpeedAngle = 0.0;
278 static uint8_t loops = 0;
299 curAngle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
309 if(deltaAngle < -2047)
315 else if(deltaAngle > 2047)
324 deltaSpeedAngle += (float)deltaAngle;
335 deltaSpeedAngle = 0.0;
348 float float2::getFloatValue(
void)
356 a.i = (uint32_t)(this->value >> 25);
361 uint64_t float2::getRawValue(
void)
366 void float2::setValue(
float val)
376 this->value = ((uint64_t)a.i) << 25;
379 bool float2::operator<=(
const float &value)
381 if(this->getFloatValue() > value)
386 if(this->getFloatValue() == value)
388 if((this->value & 0x0000000000007FFF) > 0)
397 bool float2::operator<=(
const float2 &value)
399 if((this->value >> 56) > (value.value >> 56))
404 if((this->value >> 56) == (value.value >> 56))
406 if( (this->value >> 48) < (value.value >> 48) )
411 if( (this->value >> 48) == (value.value >> 48) )
413 if((this->value & 0x0000FFFFFFFFFFFF) <= (value.value & 0x0000FFFFFFFFFFFF))
423 float2 & float2::operator=(
const float &value)
425 this->setValue(value);
430 float2 & float2::operator+=(
const float &value)
438 uint64_t tempMant, tempExp;
441 if((this->value >> 56) == (temp.value >> 56))
445 cnt = (temp.value >> 48) - (this->value >> 48);
448 tempExp = (temp.value >> 48);
450 this->value &= 0x0000FFFFFFFFFFFF;
451 this->value |= 0x0001000000000000;
454 tempMant = (temp.value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
455 tempMant += this->value;
457 while(tempMant > 0x2000000000000)
463 tempMant &= 0x0000FFFFFFFFFFFF;
464 this->value = (tempExp << 48) | tempMant;
468 this->value = temp.value;
474 cnt = (this->value >> 48) - (temp.value >> 48);
478 tempExp = (this->value >> 48);
480 temp.value &= 0x0000FFFFFFFFFFFF;
481 temp.value |= 0x0001000000000000;
484 tempMant = (this->value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
485 tempMant += temp.value;
487 while(tempMant > 0x2000000000000)
493 tempMant &= 0x0000FFFFFFFFFFFF;
494 this->value = (tempExp << 48) | tempMant;
499 else if((this->value >> 56) == 1)
501 this->value &= 0x00FFFFFFFFFFFFFF;
505 cnt = (temp.value >> 48) - (this->value >> 48);
509 tempExp = (temp.value >> 48);
511 this->value &= 0x0000FFFFFFFFFFFF;
512 this->value |= 0x0001000000000000;
515 tempMant = (temp.value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
517 tempMant -= this->value;
519 if(tempMant > 0x8000000000000000)
522 tempMant &= 0x0000FFFFFFFFFFFF;
526 while(tempMant < 0x1000000000000)
532 tempMant &= 0x0000FFFFFFFFFFFF;
534 this->value = (tempExp << 48) | tempMant;
539 this->value = temp.value;
545 cnt = (this->value >> 48) - (temp.value >> 48);
548 tempExp = (this->value >> 48);
550 temp.value &= 0x0000FFFFFFFFFFFF;
551 temp.value |= 0x0001000000000000;
554 tempMant = (this->value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
556 tempMant -= temp.value;
558 if(tempMant > 0x8000000000000000)
560 tempMant &= 0x0000FFFFFFFFFFFF;
564 while(tempMant < 0x1000000000000)
570 tempMant &= 0x0000FFFFFFFFFFFF;
572 this->value = (tempExp << 48) | tempMant;
573 this->value |= 0x0100000000000000;
580 temp.value &= 0x00FFFFFFFFFFFFFF;
584 cnt = (this->value >> 48) - (temp.value >> 48);
587 tempExp = (this->value >> 48);
589 temp.value &= 0x0000FFFFFFFFFFFF;
590 temp.value |= 0x0001000000000000;
593 tempMant = (this->value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
595 tempMant -= temp.value;
597 if(tempMant > 0x8000000000000000)
599 tempMant &= 0x0000FFFFFFFFFFFF;
603 while(tempMant < 0x1000000000000)
609 tempMant &= 0x0000FFFFFFFFFFFF;
611 this->value = (tempExp << 48) | tempMant;
617 cnt = (temp.value >> 48) - (this->value >> 48);
620 tempExp = (temp.value >> 48);
622 this->value &= 0x0000FFFFFFFFFFFF;
623 this->value |= 0x0001000000000000;
626 tempMant = (temp.value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
628 tempMant -= this->value;
630 if(tempMant > 0x8000000000000000)
632 tempMant &= 0x0000FFFFFFFFFFFF;
636 while(tempMant < 0x1000000000000)
642 tempMant &= 0x0000FFFFFFFFFFFF;
644 this->value = (tempExp << 48) | tempMant;
645 this->value |= 0x0100000000000000;
650 this->value = temp.value;
651 this->value |= 0x0100000000000000;
671 Vout = analogRead(TEMP)*0.0048828125;
672 NTC = ((
R*5.0)/Vout)-
R;
674 T =
A +
B*NTC +
C*NTC*NTC*NTC;
687 return (
float)this->angleMoved*0.087890625;
692 return this->curSpeed;
710 TIMSK1 = (1 << OCIE1A);
711 TCCR1A = (1 << WGM11);
712 TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS10);
722 this->encoderOffset = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
727 this->angleMoved = 0;
728 this->revolutions = 0;
734 return (
float)this->angle*0.087890625;
743 return (((uint16_t)data[0]) << 8 )| (uint16_t)data[1];
768 else if(data == 0x10)
773 else if(data == 0x20)
786 this->setMaxAcceleration(1000.0);
787 this->setMaxVelocity(1000.0);
789 p = &(this->control);
801 this->setMaxVelocity(vel);
802 this->setMaxAcceleration(accel);
804 p = &(this->control);
814 this->acceleration = accel;
817 this->multiplier.setValue((this->acceleration/(
INTFREQ*
INTFREQ)));
819 if(this->state !=
STOP)
821 if(this->continous == 1)
823 this->runContinous(this->direction);
827 this->moveSteps(this->totalSteps - this->currentStep + 1, this->direction, this->hold);
834 return this->acceleration;
841 this->velocity = 0.5005;
844 else if(vel > 28000.0)
846 this->velocity = 28000.0;
851 this->velocity = vel;
855 this->cruiseDelay = (uint16_t)((
INTFREQ/this->velocity) - 0.5);
857 if(this->state !=
STOP)
859 if(this->continous == 1)
861 this->runContinous(this->direction);
865 this->moveSteps(this->totalSteps - this->currentStep + 1, this->direction, this->hold);
872 return this->velocity;
889 curVel =
INTFREQ/this->exactDelay.getFloatValue();
890 if(dir != digitalRead(DIR))
892 this->direction = dir;
894 this->initialDecelSteps = (uint32_t)(((curVel*curVel))/(2.0*this->acceleration));
895 this->accelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->acceleration));
897 this->exactDelay.setValue(
INTFREQ/sqrt((curVel*curVel) + 2.0*this->acceleration));
899 if(this->exactDelay.getFloatValue() >= 65535.5)
901 this->delay = 0xFFFF;
905 this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5);
910 if(curVel > this->velocity)
913 this->initialDecelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(-2.0*this->acceleration));
914 this->accelSteps = 0;
917 else if(curVel < this->velocity)
920 this->accelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(2.0*this->acceleration));
932 this->direction = dir;
942 this->accelSteps = (velocity*velocity)/(2.0*acceleration);
944 this->exactDelay.setValue(
INTFREQ/sqrt(2.0*this->acceleration));
946 if(this->exactDelay.getFloatValue() > 65535.0)
948 this->delay = 0xFFFF;
952 this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5);
975 else if(holdMode ==
SOFT)
977 this->disableMotor();
995 this->hold = holdMode;
996 this->totalSteps = steps;
1001 curVel =
INTFREQ/this->exactDelay.getFloatValue();
1003 if(dir != digitalRead(DIR))
1006 this->initialDecelSteps = (uint32_t)((curVel*curVel)/(2.0*this->acceleration));
1007 this->accelSteps = (uint32_t)((this->velocity * this->velocity)/(2.0*this->acceleration));
1008 this->totalSteps += this->initialDecelSteps;
1010 if(this->accelSteps > (this->totalSteps >> 1))
1012 this->accelSteps = this->decelSteps = (this->totalSteps >> 1);
1013 this->accelSteps += this->totalSteps - this->accelSteps - this->decelSteps;
1017 this->decelSteps = this->accelSteps;
1018 this->cruiseSteps = this->totalSteps - this->accelSteps - this->decelSteps;
1021 this->exactDelay.setValue(
INTFREQ/sqrt((curVel*curVel) + 2.0*this->acceleration));
1023 if(this->exactDelay.getFloatValue() >= 65535.5)
1025 this->delay = 0xFFFF;
1029 this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5);
1034 if(curVel > this->velocity)
1037 this->initialDecelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(-2.0*this->acceleration));
1038 this->accelSteps = 0;
1039 this->decelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->acceleration));
1040 this->exactDelay.setValue((
INTFREQ/sqrt((curVel*curVel) + 2*this->acceleration)));
1042 if(this->totalSteps <= (this->initialDecelSteps + this->decelSteps))
1044 this->cruiseSteps = 0;
1048 this->cruiseSteps = steps - this->initialDecelSteps - this->decelSteps;
1054 else if(curVel < this->velocity)
1056 this->state =
ACCEL;
1057 this->accelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(2.0*this->acceleration));
1059 if(this->accelSteps > (this->totalSteps >> 1))
1061 this->accelSteps = this->decelSteps = (this->totalSteps >> 1);
1062 this->accelSteps += this->totalSteps - this->accelSteps - this->decelSteps;
1063 this->cruiseSteps = 0;
1067 this->decelSteps = this->accelSteps;
1068 this->cruiseSteps = this->totalSteps - this->accelSteps - this->decelSteps;
1071 this->cruiseSteps = steps - this->accelSteps - this->decelSteps;
1072 this->initialDecelSteps = 0;
1078 this->decelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->acceleration));
1079 this->accelSteps = 0;
1080 this->initialDecelSteps = 0;
1082 if(this->decelSteps >= this->totalSteps)
1084 this->cruiseSteps = 0;
1088 this->cruiseSteps = steps - this->decelSteps;
1104 this->state =
ACCEL;
1105 this->accelSteps = (uint32_t)((this->velocity * this->velocity)/(2.0*this->acceleration));
1106 this->initialDecelSteps = 0;
1108 if(this->accelSteps > (steps >> 1))
1110 this->cruiseSteps = 0;
1111 this->accelSteps = this->decelSteps = (steps >> 1);
1112 this->accelSteps += steps - this->accelSteps - this->decelSteps;
1117 this->decelSteps = this->accelSteps;
1118 this->cruiseSteps = steps - this->accelSteps - this->decelSteps;
1120 this->exactDelay.setValue(
INTFREQ/sqrt(2.0*this->acceleration));
1122 if(this->exactDelay.getFloatValue() > 65535.0)
1124 this->delay = 0xFFFF;
1128 this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5);
1133 this->enableMotor();
1143 this->stepsSinceReset = (int32_t)(this->encoder.getAngleMoved()*this->angleToStep);
1147 this->hold = holdMode;
1156 if(holdMode ==
SOFT)
1158 this->disableMotor();
1161 else if (holdMode ==
HARD)
1163 this->enableMotor();
1177 if(this->mode ==
PID && this->control)
1179 this->hardStop(holdMode);
1184 this->hold = holdMode;
1188 curVel =
INTFREQ/this->exactDelay.getFloatValue();
1190 this->decelSteps = (uint32_t)((curVel*curVel)/(2.0*this->acceleration));
1191 this->accelSteps = this->initialDecelSteps = this->cruiseSteps = 0;
1192 this->state =
DECEL;
1194 this->exactDelay.setValue(
INTFREQ/sqrt(2.0*this->acceleration));
1196 if(this->exactDelay.getFloatValue() > 65535.0)
1198 this->delay = 0xFFFF;
1202 this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5);
1210 if(holdMode ==
SOFT)
1212 this->disableMotor();
1215 else if (holdMode ==
HARD)
1217 this->enableMotor();
1223 uint8_t microStepping,
1224 float faultTolerance,
1225 float faultHysteresis,
1233 this->encoder.setup(mode);
1237 this->encoder.setHome();
1241 pointer->
stepsSinceReset = ((float)this->encoder.angleMoved * this->stepConversion) + 0.5;
1255 digitalWrite(2,HIGH);
1256 digitalWrite(3,HIGH);
1257 digitalWrite(4,HIGH);
1258 attachInterrupt(digitalPinToInterrupt(2),
interrupt0, CHANGE);
1259 attachInterrupt(digitalPinToInterrupt(3),
interrupt1, FALLING);
1261 this->tolerance = faultTolerance;
1262 this->hysteresis = faultHysteresis;
1265 this->pTerm = pTerm/10000.0;
1266 this->iTerm = iTerm/(10000.0*500.0);
1267 this->dTerm = dTerm/(10000.0/500.0);
1270 this->stepConversion = ((float)(200*microStepping))/4096.0;
1271 this->angleToStep = ((float)(200*microStepping))/360.0;
1272 TCCR2B &= ~((1 << CS20) | (1 << CS21) | (1 << CS22) | (1 << WGM22));
1273 TCCR2A &= ~((1 << WGM20) | (1 << WGM21));
1274 TCCR2B |= (1 << CS21)| (1 << WGM22);
1275 TCCR2A |= (1 << WGM21) | (1 << WGM20);
1297 TIFR2 |= (1 << OCF2A);
1298 TIMSK2 |= (1 << OCIE2A);
1305 TIMSK2 &= ~(1 << OCIE2A);
1320 return this->direction;
1325 if(this->mode ==
PID)
1331 else if(this->state !=
STOP)
1339 if(this->state !=
STOP)
1350 if(this->direction ==
CW)
1352 return this->stepsSinceReset;
1356 return this->stepsSinceReset;
1362 this->pwmD8(current);
1367 if(!(TCCR1A & (1 << COM1B1)))
1370 TCCR1A |= (1 << COM1B1);
1384 OCR1B = (uint16_t)(duty + 0.5);
1391 if(!(TCCR1A & (1 << COM1B1)))
1394 TCCR1A |= (1 << COM1B1);
1400 TCCR1A &= ~(1 << COM1B1);
1406 if(!(TCCR2A & (1 << COM2B1)))
1409 TCCR2A |= (1 << COM2B1);
1423 OCR2B = (uint16_t)(duty + 0.5);
1430 if(!(TCCR2A & (1 << COM2B1)))
1433 TCCR2A |= (1 << COM2B1);
1439 TCCR2A &= ~(1 << COM2B1);
1450 this->stepCnt = (int32_t)(setPoint*this->angleToStep);
1459 lengthMoved = this->encoder.getAngleMoved();
1461 this->hardStop(
HARD);
1463 this->runContinous(dir);
1466 pos = abs(this->encoder.getAngleMoved() - (this->getStepsSinceReset()*0.1125));
1467 Serial.println(pos);
1478 this->hardStop(
SOFT);
1480 this->moveSteps(20, !dir,
SOFT);
1481 while(this->getMotorState())
1488 lengthMoved = this->encoder.getAngleMoved() - lengthMoved();
1492 lengthMoved -= this->encoder.getAngleMoved();
1494 this->encoder.setHome();
1504 diff = angle - this->encoder.getAngleMoved();
1505 steps = (uint32_t)((abs(diff)*angleToStep) + 0.5);
1509 this->moveSteps(steps,
CCW, holdMode);
1513 this->moveSteps(steps,
CW, holdMode);
1524 steps = -(int32_t)((angle*angleToStep) - 0.5);
1525 this->moveSteps(steps,
CCW, holdMode);
1529 steps = (int32_t)((angle*angleToStep) + 0.5);
1530 this->moveSteps(steps,
CW, holdMode);
1536 static float oldError = 0.0;
1539 static float accumError = 0.0;
1544 static uint32_t speed = 10000;
1545 static uint32_t oldMicros = 0;
1551 error = (float)this->stepCnt;
1552 if(this->speedValue[0] == oldMicros)
1562 speed = this->speedValue[0] - this->speedValue[1];
1566 curAngle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
1567 this->encoder.angle = curAngle;
1568 curAngle -= this->encoder.encoderOffset;
1574 deltaAngle = (int16_t)this->encoder.oldAngle - (int16_t)curAngle;
1576 if(deltaAngle < -2047)
1578 this->encoder.revolutions--;
1582 else if(deltaAngle > 2047)
1584 this->encoder.revolutions++;
1588 this->encoder.angleMoved = (int32_t)curAngle + (4096*(int32_t)this->encoder.revolutions);
1589 this->encoder.oldAngle = curAngle;
1591 error = (((float)this->encoder.angleMoved * this->stepConversion) - error);
1593 if(error < -this->tolerance)
1596 this->control = (int32_t)error;
1601 integral = error*this->iTerm;
1602 accumError += integral;
1608 output -= this->pTerm*error;
1609 output -= accumError;
1610 output -= this->dTerm*(error - oldError);
1616 output *= (float)speed;
1621 accumError -= integral;
1632 else if(error > this->tolerance)
1635 this->control = (int32_t)error;
1638 integral = error*this->iTerm;
1639 accumError += integral;
1641 output -= this->pTerm*error;
1642 output -= accumError;
1643 output -= this->dTerm*(error - oldError);
1649 output *= (float)speed;
1654 accumError -= integral;
1667 if(error >= -this->hysteresis && error <= this->hysteresis)
1669 PORTB |= (PIND & 0x04) >> 2;
1681 static float oldError = 0.0;
1684 static float accumError = 0.0;
1690 static uint32_t speed = 10000;
1691 static uint32_t oldMicros = 0;
1692 static uint8_t stallCounter = 0;
1693 static bool running = 0;
1703 error = (float)this->stepsSinceReset;
1704 if(this->exactDelay.getFloatValue() >= 1.0)
1706 speed = (uint32_t)((this->exactDelay.getFloatValue() *
INTPERIOD));
1719 curAngle = (((uint16_t)data[0]) << 8 ) | (uint16_t)data[1];
1720 this->encoder.angle = curAngle;
1721 curAngle -= this->encoder.encoderOffset;
1727 deltaAngle = (int16_t)this->encoder.oldAngle - (int16_t)curAngle;
1729 if(deltaAngle < -2047)
1731 this->encoder.revolutions--;
1735 else if(deltaAngle > 2047)
1737 this->encoder.revolutions++;
1741 this->encoder.angleMoved = (int32_t)curAngle + (4096*(int32_t)this->encoder.revolutions);
1742 this->encoder.oldAngle = curAngle;
1744 error = (((float)this->encoder.angleMoved * this->stepConversion) - error);
1748 if(this->state !=
STOP)
1758 detectStall((
float)deltaAngle, running);
1760 if(error < -this->tolerance)
1763 this->control = (int32_t)error;
1768 integral = error*this->iTerm;
1769 accumError += integral;
1775 output -= this->pTerm*error;
1776 output -= accumError;
1777 oldError = error - oldError;
1778 output -= this->dTerm*oldError;
1784 output *= (float)speed;
1788 accumError -= integral;
1804 else if(error > this->tolerance)
1807 this->control = (int32_t)error;
1810 integral = error*this->iTerm;
1811 accumError += integral;
1813 output -= this->pTerm*error;
1814 output -= accumError;
1815 oldError = error - oldError;
1816 output -= this->dTerm*(error - oldError);
1822 output *= (float)speed;
1826 accumError -= integral;
1845 if(error >= -this->hysteresis && error <= this->hysteresis)
1848 if(this->hold || this->state!=
STOP)
1881 bool uStepper::detectStall(
float diff,
bool running)
1883 static uint16_t accumDiff = 0;
1884 static uint8_t checks = 0;
1885 static float oldDiff = 0.0;
1886 static float temp = 0.0;
1897 if(temp < 10.0 && temp > -10.0)
1928 while (!(TWCR & (1 << TWINT)))
1938 status = TWSR & 0xF8;
1943 bool i2cMaster::read(uint8_t slaveAddr, uint8_t regAddr, uint8_t numOfBytes, uint8_t *data)
1945 uint8_t i, buff[numOfBytes];
1947 TIMSK1 &= ~(1 << OCIE1A);
1967 for(i = 0; i < (numOfBytes - 1); i++)
1984 TIMSK1 |= (1 << OCIE1A);
1993 TIMSK1 &= ~(1 << OCIE1A);
2007 for(i = 0; i < numOfBytes; i++)
2017 TIMSK1 |= (1 << OCIE1A);
2026 if(this->cmd((1 << TWINT) | (1 << TWEN) | (1 << TWEA)) ==
false)
2035 if(this->cmd((1 << TWINT) | (1 << TWEN)) ==
false)
2049 this->cmd((1<<TWINT) | (1<<TWSTA) | (1<<TWEN));
2051 if (this->getStatus() !=
START && this->getStatus() !=
REPSTART)
2057 TWDR = (addr << 1) | RW;
2058 this->cmd((1 << TWINT) | (1 << TWEN));
2074 return this->start(addr, RW);
2081 this->cmd((1 << TWINT) | (1 << TWEN));
2090 TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
2093 while (TWCR & (1 << TWSTO));
uStepper(void)
Constructor of uStepper class.
uStepperEncoder(void)
Constructor.
void interrupt0(void)
Used by dropin feature to take in step pulses.
void TIMER1_COMPA_vect(void) __attribute__((signal
Measures angle and speed of motor.
uint16_t getStrength(void)
Measure the strength of the magnet.
void setCurrent(double current)
Set motor output current.
float getSpeed(void)
Measure the current speed of the motor.
volatile uint16_t counter
bool write(uint8_t slaveAddr, uint8_t regAddr, uint8_t numOfBytes, uint8_t *data)
sets up I2C connection to device, writes a number of data bytes and closes the connection ...
bool getMotorState(void)
Get the current state of the motor.
Prototype of class for accessing all features of the uStepper in a single object. ...
void pid(void)
This method handles the actual PID controller calculations, if enabled.
void TIMER2_COMPA_vect(void) __attribute__((signal
Used to apply step pulses to the motor.
void enableMotor(void)
Enables the stepper driver output stage.
float getMaxAcceleration(void)
Get the value of the maximum motor acceleration.
float getTemp(void)
Request a reading of current temperature.
#define INTPIDDELAYCONSTANT
void updateSetPoint(float setPoint)
Updates setpoint for the motor.
bool getCurrentDirection(void)
Returns the direction the motor is currently configured to rotate.
void pidDropIn(void)
This method handles the actual PID controller calculations for drop-in feature, if enabled...
float getAngleMoved(void)
Measure the angle moved from reference position.
void setup(uint8_t mode=NORMAL, uint8_t microStepping=SIXTEEN, float faultTolerance=10.0, float faultHysteresis=5.0, float pTerm=1.0, float iTerm=0.02, float dterm=0.006, bool setHome=true)
Initializes the different parts of the uStepper object.
void hardStop(bool holdMode)
Stop the motor without deceleration.
void setMaxAcceleration(float accel)
Set the maximum acceleration of the stepper motor.
void startTimer(void)
Starts timer for stepper algorithm.
bool isStalled(void)
This method returns a bool variable indicating wether the motor is stalled or not.
bool cmd(uint8_t cmd)
Sends commands over the I2C bus.
void setMaxVelocity(float vel)
Sets the maximum rotational velocity of the motor.
float getMaxVelocity(void)
Returns the maximum rotational velocity of the motor.
bool writeByte(uint8_t data)
Writes a byte to a device on the I2C bus.
i2cMaster(void)
Constructor.
void softStop(bool holdMode)
Stop the motor with deceleration.
uint8_t detectMagnet(void)
Detect if magnet is present and within range.
volatile int32_t stepsSinceReset
uint8_t getStatus(void)
Get current I2C status.
void pwmD8(double duty)
Generate PWM signal on digital output 8.
volatile int32_t angleMoved
bool restart(uint8_t addr, bool RW)
Restarts connection between arduino and I2C device.
bool readByte(bool ack, uint8_t *data)
Reads a byte from the I2C bus.
volatile uint32_t speedValue[2]
volatile uint16_t oldAngle
void stopTimer(void)
Stops the timer for the stepper algorithm.
uint8_t getAgc(void)
Read the current AGC value of the encoder chip.
bool start(uint8_t addr, bool RW)
sets up connection between arduino and I2C device.
void runContinous(bool dir)
Make the motor rotate continuously.
#define ENCODERSPEEDCONSTANT
Prototype of class for accessing the TWI (I2C) interface of the AVR (master mode only).
void setHome(void)
Define new reference(home) position.
volatile int16_t revolutions
float getAngle(void)
Measure the current shaft angle.
void moveToAngle(float angle, bool holdMode)
Moves the motor to an absolute angle.
float moveToEnd(bool dir)
Moves the motor to its physical limit, without limit switch.
bool stop(void)
Closes the I2C connection.
void moveAngle(float angle, bool holdMode)
Moves the motor to a relative angle.
void begin(void)
Setup TWI (I2C) interface.
void interrupt1(void)
Used by dropin feature to take in enable signal.
Function prototypes and definitions for the uStepper library.
int32_t getStepsSinceReset(void)
Get the number of steps applied since reset.
void setup(uint8_t mode)
Setup the encoder.
void moveSteps(int32_t steps, bool dir, bool holdMode)
Make the motor perform a predefined number of steps.
void pwmD3(double duty)
Generate PWM signal on digital output 3.
uStepperTemp(void)
Constructor.
bool read(uint8_t slaveAddr, uint8_t regAddr, uint8_t numOfBytes, uint8_t *data)
sets up I2C connection to device, reads a number of data bytes and closes the connection ...
void disableMotor(void)
Disables the stepper driver output stage.