uStepper
 All Classes Files Functions Variables Macros Pages
uStepper.cpp
Go to the documentation of this file.
1 /********************************************************************************************
2 * File: uStepper.cpp *
3 * Version: 0.4.4 *
4 * date: August 8th, 2016 *
5 * Author: Thomas Hørring Olsen *
6 * *
7 *********************************************************************************************
8 * uStepper class *
9 * *
10 * This file contains the implementation of the class methods, incorporated in the *
11 * uStepper arduino library. The library is used by instantiating an uStepper object *
12 * by calling either of the two overloaded constructors: *
13 * *
14 * example: *
15 * *
16 * uStepper stepper; *
17 * *
18 * OR *
19 * *
20 * uStepper stepper(500, 2000); *
21 * *
22 * The first instantiation above creates a uStepper object with default acceleration *
23 * and maximum speed (1000 steps/s^2 and 1000steps/s respectively). *
24 * The second instantiation overwrites the default settings of acceleration and *
25 * maximum speed (in this case 500 steps/s^2 and 2000 steps/s, respectively); *
26 * *
27 * after instantiation of the object, the object setup function should be called within *
28 * arduino's setup function: *
29 * *
30 * example: *
31 * *
32 * uStepper stepper; *
33 * *
34 * void setup() *
35 * { *
36 * stepper.setup(); *
37 * } *
38 * *
39 * void loop() *
40 * { *
41 * *
42 * } *
43 * *
44 * After this, the library is ready to control the motor! *
45 * *
46 *********************************************************************************************
47 * (C) 2016 *
48 * *
49 * ON Development IVS *
50 * www.on-development.com *
51 * administration@on-development.com *
52 * *
53 * The code contained in this file is released under the following open source license: *
54 * *
55 * Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International *
56 * *
57 * The code in this file is provided without warranty of any kind - use at own risk! *
58 * neither ON Development IVS nor the author, can be held responsible for any damage *
59 * caused by the use of the code contained in this file ! *
60 * *
61 ********************************************************************************************/
69 #include <uStepper.h>
70 #include <math.h>
71 
72 uStepper *pointer;
74 
75 volatile uint16_t i = 0;
76 volatile int32_t stepCnt = 0, control = 0;
77 
78 extern "C" {
79 
80  void INT1_vect(void)
81  {
82  if((PIND & (0x20))) //CCW
83  {
84  if(control == 0)
85  {
86  PORTD |= (1 << 7); //Set dir to CCW
87 
88  }
89  stepCnt--; //DIR is set to CCW, therefore we subtract 1 step from step count (negative values = number of steps in CCW direction from initial postion)
90  }
91  else //CW
92  {
93  if(control == 0)
94  {
95 
96  PORTD &= ~(1 << 7); //Set dir to CW
97  }
98 
99  stepCnt++; //DIR is set to CW, therefore we add 1 step to step count (positive values = number of steps in CW direction from initial postion)
100  }
101 
102  if(control == 0) //If no steps are lost, redirect step pulses
103  {
104  PORTD |= (1 << 4); //generate step pulse
105  delayMicroseconds(1); //wait a small time
106  PORTD &= ~(1 << 4); //pull step pin low again
107  }
108  }
109 
110  void INT0_vect(void)
111  {
112 
113  if(PIND & 0x04)
114  {
115 
116  PORTB |= (1 << 0);
117  }
118  else
119  {
120 
121  PORTB &= ~(1 << 0);
122  }
123  }
124 
125  void TIMER2_COMPA_vect(void)
126  {
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,pointer \n\t");
133  asm volatile("lds r31,pointer+1 \n\t");
134  asm volatile("ldd r16,z+56 \n\t");
135  asm volatile("sbrs r16,0 \n\t");
136  asm volatile("jmp _AccelerationAlgorithm \n\t"); //Execute the acceleration profile algorithm
137 
138  asm volatile("push r0 \n\t");
139  asm volatile("push r1 \n\t");
140  asm volatile("push r2 \n\t");
141  asm volatile("push r3 \n\t");
142  asm volatile("push r4 \n\t");
143  asm volatile("push r5 \n\t");
144  asm volatile("push r6 \n\t");
145  asm volatile("push r7 \n\t");
146  asm volatile("push r8 \n\t");
147  asm volatile("push r9 \n\t");
148  asm volatile("push r10 \n\t");
149  asm volatile("push r11 \n\t");
150  asm volatile("push r12 \n\t");
151  asm volatile("push r13 \n\t");
152  asm volatile("push r14 \n\t");
153  asm volatile("push r15 \n\t");
154  asm volatile("push r17 \n\t");
155  asm volatile("push r18 \n\t");
156  asm volatile("push r19 \n\t");
157  asm volatile("push r20 \n\t");
158  asm volatile("push r21 \n\t");
159  asm volatile("push r22 \n\t");
160  asm volatile("push r23 \n\t");
161  asm volatile("push r24 \n\t");
162  asm volatile("push r25 \n\t");
163  asm volatile("push r26 \n\t");
164  asm volatile("push r27 \n\t");
165  asm volatile("push r28 \n\t");
166  asm volatile("push r29 \n\t");
167 
168  if(i < pointer->faultStepDelay) //This value defines the speed at which the motor rotates when compensating for lost steps. This value should be tweaked to the application
169  {
170 
171  i++;
172  }
173  else
174  {
175  PORTD |= (1 << 4);
176  delayMicroseconds(1);
177  PORTD &= ~(1 << 4);
178  if(control < 0)
179  {
180  control += 1;
181  }
182 
183  else if(control > 0)
184  {
185  control -= 1;
186  }
187  i = 0;
188  }
189 
190  asm volatile("pop r29 \n\t");
191  asm volatile("pop r28 \n\t");
192  asm volatile("pop r27 \n\t");
193  asm volatile("pop r26 \n\t");
194  asm volatile("pop r25 \n\t");
195  asm volatile("pop r24 \n\t");
196  asm volatile("pop r23 \n\t");
197  asm volatile("pop r22 \n\t");
198  asm volatile("pop r21 \n\t");
199  asm volatile("pop r20 \n\t");
200  asm volatile("pop r19 \n\t");
201  asm volatile("pop r18 \n\t");
202  asm volatile("pop r17 \n\t");
203  asm volatile("pop r15 \n\t");
204  asm volatile("pop r14 \n\t");
205  asm volatile("pop r13 \n\t");
206  asm volatile("pop r12 \n\t");
207  asm volatile("pop r11 \n\t");
208  asm volatile("pop r10 \n\t");
209  asm volatile("pop r9 \n\t");
210  asm volatile("pop r8 \n\t");
211  asm volatile("pop r7 \n\t");
212  asm volatile("pop r6 \n\t");
213  asm volatile("pop r5 \n\t");
214  asm volatile("pop r4 \n\t");
215  asm volatile("pop r3 \n\t");
216  asm volatile("pop r2 \n\t");
217  asm volatile("pop r1 \n\t");
218  asm volatile("pop r0 \n\t");
219  asm volatile("pop r31 \n\t");
220  asm volatile("pop r30 \n\t");
221  asm volatile("pop r16 \n\t");
222  asm volatile("out 0x3F,r16 \n\t");
223  asm volatile("pop r16 \n\t");
224  asm volatile("reti \n\t");
225  }
226 
227  void TIMER1_COMPA_vect(void)
228  {
229  float error;
230  float deltaAngle, newSpeed;
231  static float curAngle, oldAngle = 0.0, deltaSpeedAngle = 0.0, oldSpeed = 0.0;
232  static uint8_t loops = 0;
233  static float revolutions = 0.0;
234  uint8_t data[2];
235 
236  sei();
237  if(I2C.getStatus() != I2CFREE)
238  {
239  return;
240  }
241 
242  I2C.read(ENCODERADDR, ANGLE, 2, data);
243  curAngle = (float)((((uint16_t)data[0]) << 8 ) | (uint16_t)data[1])*0.087890625;
244  pointer->encoder.angle = curAngle;
245  curAngle -= pointer->encoder.encoderOffset;
246 
247  curAngle = fmod(curAngle + 360.0, 360.0);
248 
249  deltaAngle = (oldAngle - curAngle);
250  //count number of revolutions, on angle overflow
251  if(deltaAngle < -180.0)
252  {
253  revolutions -= 1.0;
254  deltaAngle += 360;
255  }
256 
257  else if(deltaAngle > 180.0)
258  {
259  revolutions += 1.0;
260  deltaAngle -= 360.0;
261  }
262 
263  if( loops < 10)
264  {
265  loops++;
266  deltaSpeedAngle += deltaAngle;
267  }
268  else
269  {
270  newSpeed = (deltaSpeedAngle*ENCODERSPEEDCONSTANT);
271  newSpeed = oldSpeed*ALPHA + newSpeed*BETA; //Filter
272  oldSpeed = newSpeed;
273  pointer->encoder.curSpeed = newSpeed;
274  loops = 0;
275  deltaSpeedAngle = 0.0;
276  }
277 
278  pointer->encoder.angleMoved = curAngle + (360.0*revolutions);
279  oldAngle = curAngle;
280  pointer->encoder.oldAngle = curAngle;
281 
282  if(pointer->dropIn)
283  {
284  cli();
285  error = (float)stepCnt; //atomic read to ensure no fuckups happen from the external interrupt routine
286  sei();
287  error *= pointer->stepResolution;
288  error -= pointer->encoder.angleMoved;
289  if(error > pointer->tolerance)
290  {
291  PORTB &= ~(1 << 0);
292  control = (int32_t)(error/pointer->stepResolution);
293 
294  PORTD |= (1 << 7);
295  pointer->startTimer();
296  }
297  else if(error < -pointer->tolerance)
298  {
299  PORTB &= ~(1 << 0);
300  control = (int32_t)(error/pointer->stepResolution);
301  PORTD &= ~(1 << 7);
302 
303  pointer->startTimer();
304  }
305  else
306  {
307  PORTB |= (PIND & 0x04) >> 2;
308  control = 0;
309  pointer->stopTimer();
310  }
311  }
312  }
313 }
314 
315 float2::float2(void)
316 {
317 
318 }
319 
320 float float2::getFloatValue(void)
321 {
322  union
323  {
324  float f;
325  uint32_t i;
326  } a;
327 
328  a.i = (uint32_t)(this->value >> 25);
329 
330  return a.f;
331 }
332 
333 uint64_t float2::getRawValue(void)
334 {
335  return this->value;
336 }
337 
338 void float2::setValue(float val)
339 {
340  union
341  {
342  float f;
343  uint32_t i;
344  } a;
345 
346  a.f = val;
347 
348  this->value = ((uint64_t)a.i) << 25;
349 }
350 
351 bool float2::operator<=(const float &value)
352 {
353  if(this->getFloatValue() > value)
354  {
355  return 0;
356  }
357 
358  if(this->getFloatValue() == value)
359  {
360  if((this->value & 0x0000000000007FFF) > 0)
361  {
362  return 0;
363  }
364  }
365 
366  return 1;
367 }
368 
369 bool float2::operator<=(const float2 &value)
370 {
371  if((this->value >> 56) > (value.value >> 56)) // sign bit of "this" bigger than sign bit of "value"?
372  {
373  return 1; //"This" is negative while "value" is not. ==> "this" < "value"
374  }
375 
376  if((this->value >> 56) == (value.value >> 56)) //Sign bit of "this" == sign bit of "value"?
377  {
378  if( (this->value >> 48) < (value.value >> 48) ) //Exponent of "this" < exponent of "value"?
379  {
380  return 1; //==> "this" is smaller than "value"
381  }
382 
383  if( (this->value >> 48) == (value.value >> 48) ) //Exponent of "this" == exponent of "value"?
384  {
385  if((this->value & 0x0000FFFFFFFFFFFF) <= (value.value & 0x0000FFFFFFFFFFFF)) //mantissa of "this" <= mantissa of "value"?
386  {
387  return 1; //==> "this" <= "value"
388  }
389  }
390  }
391 
392  return 0; //"this" > "value"
393 }
394 
395 float2 & float2::operator=(const float &value)
396 {
397  this->setValue(value);
398 
399  return *this;
400 }
401 
402 float2 & float2::operator+=(const float &value)
403 {
404 
405 }
406 
407 float2 & float2::operator+=(const float2 &value)
408 {
409  float2 temp = value;
410  uint64_t tempMant, tempExp;
411  uint8_t cnt; //how many times should we shift the mantissa of the smallest number to add the two mantissa's
412 
413  if((this->value >> 56) == (temp.value >> 56))
414  {
415  if(*this <= temp)
416  {
417  cnt = (temp.value >> 48) - (this->value >> 48);
418  if(cnt < 48)
419  {
420  tempExp = (temp.value >> 48);
421 
422  this->value &= 0x0000FFFFFFFFFFFF;
423  this->value |= 0x0001000000000000;
424  this->value >>= cnt;
425 
426  tempMant = (temp.value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
427  tempMant += this->value;
428 
429  while(tempMant > 0x2000000000000)
430  {
431  tempMant >>= 1;
432  tempExp++;
433  }
434 
435  tempMant &= 0x0000FFFFFFFFFFFF;
436  this->value = (tempExp << 48) | tempMant;
437  }
438  else
439  {
440  this->value = temp.value;
441  }
442  }
443 
444  else
445  {
446  cnt = (this->value >> 48) - (temp.value >> 48);
447 
448  if(cnt < 48)
449  {
450  tempExp = (this->value >> 48);
451 
452  temp.value &= 0x0000FFFFFFFFFFFF;
453  temp.value |= 0x0001000000000000;
454  temp.value >>= cnt;
455 
456  tempMant = (this->value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
457  tempMant += temp.value;
458 
459  while(tempMant > 0x2000000000000)
460  {
461  tempMant >>= 1;
462  tempExp++;
463  }
464 
465  tempMant &= 0x0000FFFFFFFFFFFF;
466  this->value = (tempExp << 48) | tempMant;
467  }
468  }
469  }
470 
471  else if((this->value >> 56) == 1)
472  {
473  this->value &= 0x00FFFFFFFFFFFFFF; //clear sign bit, to consider absolute value
474 
475  if(*this <= temp)
476  {
477  cnt = (temp.value >> 48) - (this->value >> 48);
478 
479  if(cnt < 48)
480  {
481  tempExp = (temp.value >> 48);
482 
483  this->value &= 0x0000FFFFFFFFFFFF;
484  this->value |= 0x0001000000000000;
485  this->value >>= cnt;
486 
487  tempMant = (temp.value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
488 
489  tempMant -= this->value;
490 
491  if(tempMant > 0x8000000000000000)
492  {
493 
494  tempMant &= 0x0000FFFFFFFFFFFF;
495  tempExp--;
496  }
497 
498  while(tempMant < 0x1000000000000)
499  {
500  tempMant <<= 1;
501  tempExp--;
502  }
503 
504  tempMant &= 0x0000FFFFFFFFFFFF;
505 
506  this->value = (tempExp << 48) | tempMant;
507  }
508 
509  else
510  {
511  this->value = temp.value;
512  }
513  }
514 
515  else
516  {
517  cnt = (this->value >> 48) - (temp.value >> 48);
518  if(cnt < 48)
519  {
520  tempExp = (this->value >> 48);
521 
522  temp.value &= 0x0000FFFFFFFFFFFF;
523  temp.value |= 0x0001000000000000;
524  temp.value >>= cnt;
525 
526  tempMant = (this->value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
527 
528  tempMant -= temp.value;
529 
530  if(tempMant > 0x8000000000000000)
531  {
532  tempMant &= 0x0000FFFFFFFFFFFF;
533  tempExp--;
534  }
535 
536  while(tempMant < 0x1000000000000)
537  {
538  tempMant <<= 1;
539  tempExp--;
540  }
541 
542  tempMant &= 0x0000FFFFFFFFFFFF;
543 
544  this->value = (tempExp << 48) | tempMant;
545  this->value |= 0x0100000000000000;
546  }
547  }
548  }
549 
550  else
551  {
552  temp.value &= 0x00FFFFFFFFFFFFFF; //clear sign bit, to consider absolute value
553 
554  if(temp <= *this)
555  {
556  cnt = (this->value >> 48) - (temp.value >> 48);
557  if(cnt < 48)
558  {
559  tempExp = (this->value >> 48);
560 
561  temp.value &= 0x0000FFFFFFFFFFFF;
562  temp.value |= 0x0001000000000000;
563  temp.value >>= cnt;
564 
565  tempMant = (this->value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
566 
567  tempMant -= temp.value;
568 
569  if(tempMant > 0x8000000000000000)
570  {
571  tempMant &= 0x0000FFFFFFFFFFFF;
572  tempExp--;
573  }
574 
575  while(tempMant < 0x1000000000000)
576  {
577  tempMant <<= 1;
578  tempExp--;
579  }
580 
581  tempMant &= 0x0000FFFFFFFFFFFF;
582 
583  this->value = (tempExp << 48) | tempMant;
584  }
585  }
586 
587  else
588  {
589  cnt = (temp.value >> 48) - (this->value >> 48);
590  if(cnt < 48)
591  {
592  tempExp = (temp.value >> 48);
593 
594  this->value &= 0x0000FFFFFFFFFFFF;
595  this->value |= 0x0001000000000000;
596  this->value >>= cnt;
597 
598  tempMant = (temp.value & 0x0000FFFFFFFFFFFF) | 0x0001000000000000;
599 
600  tempMant -= this->value;
601 
602  if(tempMant > 0x8000000000000000)
603  {
604  tempMant &= 0x0000FFFFFFFFFFFF;
605  tempExp--;
606  }
607 
608  while(tempMant < 0x1000000000000)
609  {
610  tempMant <<= 1;
611  tempExp--;
612  }
613 
614  tempMant &= 0x0000FFFFFFFFFFFF;
615 
616  this->value = (tempExp << 48) | tempMant;
617  this->value |= 0x0100000000000000;
618  }
619 
620  else
621  {
622  this->value = temp.value;
623  this->value |= 0x0100000000000000;
624  }
625  }
626  }
627 
628  return *this;
629 
630 }
631 
633 {
634 
635 }
636 
638 {
639  float T = 0.0;
640  float Vout = 0.0;
641  float NTC = 0.0;
642 
643  Vout = analogRead(TEMP)*0.0048828125; //0.0048828125 = 5V/1024
644  NTC = ((R*5.0)/Vout)-R; //the current NTC resistance
645  NTC = log(NTC);
646  T = A + B*NTC + C*NTC*NTC*NTC; //Steinhart-Hart equation
647  T = 1.0/T;
648 
649  return T - 273.15;
650 }
651 
653 {
654  I2C.begin();
655 }
656 
658 {/*
659  float deltaAngle, angle;
660 
661  TIMSK1 &= ~(1 << OCIE1A);
662 
663  angle = this->getAngle() - this->encoderOffset;
664 
665 
666  if(angle < 0.0)
667  {
668  angle += 360.0;
669  }
670 
671  deltaAngle = this->oldAngle - angle;
672 
673  if(deltaAngle < -180.0)
674  {
675  pointer->encoder.angleMoved += (deltaAngle + 360.0);
676  }
677 
678  else if(deltaAngle > 180.0)
679  {
680  pointer->encoder.angleMoved -= (360.0 - deltaAngle);
681  }
682 
683  else
684  {
685  this->angleMoved += deltaAngle;
686  }
687 
688  this->oldAngle = angle;
689 
690  TIMSK1 |= (1 << OCIE1A);*/
691 
692  return this->angleMoved;
693 }
694 
696 {
697  return this->curSpeed;
698 }
699 
701 {
702  uint8_t data[2];
703  TCCR1A = 0;
704  TCNT1 = 0;
705  OCR1A = 16000;
706  TIFR1 = 0;
707  TIMSK1 = (1 << OCIE1A);
708  TCCR1B = (1 << WGM12) | (1 << CS10);
709  I2C.read(ENCODERADDR, ANGLE, 2, data);
710  this->encoderOffset = (float)((((uint16_t)data[0]) << 8 ) | (uint16_t)data[1])*0.087890625;
711 
712  this->oldAngle = 0.0;
713  this->angleMoved = 0.0;
714 
715  sei();
716 
717 }
718 
720 {
721  cli();
722  uint8_t data[2];
723  I2C.read(ENCODERADDR, ANGLE, 2, data);
724  this->encoderOffset = (float)((((uint16_t)data[0]) << 8 ) | (uint16_t)data[1])*0.087890625;
725 
726  this->angle = 0.0;
727  this->oldAngle = 0.0;
728  this->angleMoved = 0.0;
729  sei();
730 }
731 
733 {
734  return this->angle;
735 }
736 
738 {
739  uint8_t data[2];
740 
741  I2C.read(ENCODERADDR, MAGNITUDE, 2, data);
742 
743  return (((uint16_t)data[0]) << 8 )| (uint16_t)data[1];
744 }
745 
747 {
748  uint8_t data;
749 
750  I2C.read(ENCODERADDR, MAGNITUDE, 1, &data);
751 
752  return data;
753 }
754 
756 {
757  uint8_t data;
758 
759  I2C.read(ENCODERADDR, AGC, 1, &data);
760 
761  data &= 0x38; //For some reason the encoder returns random values on reserved bits. Therefore we make sure reserved bits are cleared before checking the reply !
762 
763  if(data == 0x08)
764  {
765  return 1; //magnet too strong
766  }
767 
768  else if(data == 0x10)
769  {
770  return 2; //magnet too weak
771  }
772 
773  else if(data == 0x20)
774  {
775  return 0; //magnet detected and within limits
776  }
777 
778  return 3; //Something went horribly wrong !
779 }
780 
782 {
783 
784  this->state = STOP;
785 
786  this->setMaxAcceleration(1000.0);
787  this->setMaxVelocity(1000.0);
788 
789  pointer = this;
790 
791  DDRD |= (1 << 7); //set direction pin to output
792  DDRD |= (1 << 4); //set step pin to output
793  DDRB |= (1 << 0); //set enable pin to output
794 }
795 
796 uStepper::uStepper(float accel, float vel)
797 {
798  this->state = STOP;
799 
800  this->setMaxVelocity(vel);
801  this->setMaxAcceleration(accel);
802 
803  pointer = this;
804 
805  DDRD |= (1 << 7); //set direction pin to output
806  DDRD |= (1 << 4); //set step pin to output
807  DDRB |= (1 << 0); //set enable pin to output
808 }
809 
811 {
812  this->acceleration = accel;
813 
814  this->stopTimer(); //Stop timer so we dont fuck up stuff !
815  this->multiplier.setValue((this->acceleration/(INTFREQ*INTFREQ))); //Recalculate multiplier variable, used by the acceleration algorithm since acceleration has changed!
816 
817  if(this->state != STOP)
818  {
819  if(this->continous == 1) //If motor was running continously
820  {
821  this->runContinous(this->direction); //We should make it run continously again
822  }
823  else //If motor still needs to perform some steps
824  {
825  this->moveSteps(this->totalSteps - this->currentStep + 1, this->direction, this->hold); //we should make sure the motor gets to execute the remaining steps
826  }
827  }
828 }
829 
831 {
832  /*Serial.print(this->exactDelay.getFloatValue(),15);
833  Serial.print("\t");
834  Serial.println(this->delay);
835  Serial.print("\t");
836  Serial.print((uint8_t)((this->exactDelay.value >> 48) & 0x00000000000000FF),HEX);
837  Serial.print(" ");
838  Serial.print((uint8_t)((this->exactDelay.value >> 40) & 0x00000000000000FF),HEX);
839  Serial.print(" ");
840  Serial.print((uint8_t)((this->exactDelay.value >> 32) & 0x00000000000000FF),HEX);
841  Serial.print(" ");
842  Serial.print((uint8_t)((this->exactDelay.value >> 24) & 0x00000000000000FF),HEX);
843  Serial.print(" ");
844  Serial.print((uint8_t)((this->exactDelay.value >> 16) & 0x00000000000000FF),HEX);
845  Serial.print(" ");
846  Serial.print((uint8_t)((this->exactDelay.value >> 8) & 0x00000000000000FF),HEX);
847  Serial.print(" ");
848  Serial.print((uint8_t)((this->exactDelay.value) & 0x00000000000000FF),HEX);
849  Serial.print("\t");
850  Serial.print(this->delay);
851  Serial.print("\t");
852  Serial.println(this->totalSteps);*/
853  /*cli();
854  float tmp=this->exactDelay.getFloatValue();
855  sei();
856  return tmp;*/
857  return this->acceleration;
858 }
859 
861 {
862  if(vel < 0.5005)
863  {
864  this->velocity = 0.5005; //Limit velocity in order to not overflow delay variable
865  }
866 
867  else if(vel > 32000.0)
868  {
869  this->velocity = 32000.0; //limit velocity in order to not underflow delay variable
870  }
871 
872  else
873  {
874  this->velocity = vel;
875  }
876 
877  this->stopTimer(); //Stop timer so we dont fuck up stuff !
878  this->cruiseDelay = (uint16_t)((INTFREQ/this->velocity) - 0.5); //Calculate cruise delay, so we dont have to recalculate this in the interrupt routine
879 
880  if(this->state != STOP) //If motor was running, we should make sure it runs again
881  {
882  if(this->continous == 1) //If motor was running continously
883  {
884  this->runContinous(this->direction); //We should make it run continously again
885  }
886  else //If motor still needs to perform some steps
887  {
888  this->moveSteps(this->totalSteps - this->currentStep + 1, this->direction, this->hold); //we should make sure it gets to execute these steps
889  }
890  }
891 }
892 
894 {
895  return this->velocity;
896 }
897 
899 {
900  float curVel;
901 
902  if(this->dropIn)
903  {
904  return; //Drop in feature is activated. just return since this function makes no sense with drop in activated!
905  }
906 
907  this->stopTimer(); //Stop interrupt timer, so we don't fuck up stuff !
908  this->continous = 1; //Set continous variable to 1, in order to let the interrupt routine now, that the motor should run continously
909 
910 
911 
912  if(state != STOP) //if the motor is currently running and we want to move the opposite direction, we need to decelerate in order to change direction.
913  {
914  curVel = INTFREQ/this->exactDelay.getFloatValue(); //Use this to calculate current velocity
915  if(dir != digitalRead(DIR)) //If motor is currently running the opposite direction as desired
916  {
917  this->direction = dir;
918  this->state = INITDECEL; //We should decelerate the motor to full stop before accelerating the speed in the opposite direction
919  this->initialDecelSteps = (uint32_t)(((curVel*curVel))/(2.0*this->acceleration)); //the amount of steps needed to bring the motor to full stop. (S = (V^2 - V0^2)/(2*-a)))
920  this->accelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->acceleration)); //Number of steps to bring the motor to max speed (S = (V^2 - V0^2)/(2*a)))
921 
922  this->exactDelay.setValue(INTFREQ/sqrt((curVel*curVel) + 2.0*this->acceleration)); //number of interrupts before the first step should be performed.
923 
924  if(this->exactDelay.getFloatValue() >= 65535.5)
925  {
926  this->delay = 0xFFFF;
927  }
928  else
929  {
930  this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5); //Truncate the exactDelay variable, since we cant perform fractional steps
931  }
932  }
933  else //If the motor is currently rotating the same direction as the desired direction
934  {
935  if(curVel > this->velocity) //If current velocity is greater than desired velocity
936  {
937  this->state = INITDECEL; //We need to decelerate the motor to desired velocity
938  this->initialDecelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(-2.0*this->acceleration)); //Number of steps to bring the motor down from current speed to max speed (S = (V^2 - V0^2)/(2*-a)))
939  this->accelSteps = 0; //No acceleration phase is needed
940  }
941 
942  else if(curVel < this->velocity) //If the current velocity is less than the desired velocity
943  {
944  this->state = ACCEL; //Start accelerating
945  this->accelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(2.0*this->acceleration)); //Number of Steps needed to accelerate from current velocity to full speed
946  }
947 
948  else //If motor is currently running at desired speed
949  {
950  this->state = CRUISE; //We should just run at cruise speed
951  }
952  }
953  }
954 
955  else //If motor is currently stopped (state = STOP)
956  {
957  this->direction = dir;
958  this->state = ACCEL; //Start accelerating
959  if(dir) //Set the motor direction pin to the desired setting
960  {
961  PORTD |= (1 << 7);
962  }
963  else
964  {
965  PORTD &= ~(1 << 7);
966  }
967  this->accelSteps = (velocity*velocity)/(2.0*acceleration); //Number of steps to bring the motor to max speed (S = (V^2 - V0^2)/(2*a)))
968 
969  this->exactDelay.setValue(INTFREQ/sqrt(2.0*this->acceleration)); //number of interrupts before the first step should be performed.
970 
971  if(this->exactDelay.getFloatValue() > 65535.0)
972  {
973  this->delay = 0xFFFF;
974  }
975  else
976  {
977  this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5); //Truncate the exactDelay variable, since we cant perform fractional steps
978  }
979  }
980 
981  this->startTimer(); //start timer so we can perform steps
982  this->enableMotor(); //Enable motor
983 }
984 
985 void uStepper::moveSteps(uint32_t steps, bool dir, bool holdMode)
986 {
987  float curVel;
988 
989  if(this->dropIn)
990  {
991  return; //Drop in feature is activated. just return since this function makes no sense with drop in activated!
992  }
993 
994  this->stopTimer(); //Stop interrupt timer so we dont fuck stuff up !
995  steps--;
996  this->direction = dir; //Set direction variable to the desired direction of rotation for the interrupt routine
997  this->hold = holdMode; //Set the hold variable to desired hold mode (block motor or release motor after end movement) for the interrupt routine
998  this->totalSteps = steps; //Load the desired number of steps into the totalSteps variable for the interrupt routine
999  this->continous = 0; //Set continous variable to 0, since the motor should not run continous
1000 
1001  if(state != STOP) //if the motor is currently running and we want to move the opposite direction, we need to decelerate in order to change direction.
1002  {
1003  curVel = INTFREQ/this->exactDelay.getFloatValue(); //Use this to calculate current velocity
1004 
1005  if(dir != digitalRead(DIR)) //If current direction is different from desired direction
1006  {
1007  this->state = INITDECEL; //We should decelerate the motor to full stop
1008  this->initialDecelSteps = (uint32_t)((curVel*curVel)/(2.0*this->acceleration)); //the amount of steps needed to bring the motor to full stop. (S = (V^2 - V0^2)/(2*-a)))
1009  this->accelSteps = (uint32_t)((this->velocity * this->velocity)/(2.0*this->acceleration)); //Number of steps to bring the motor to max speed (S = (V^2 - V0^2)/(2*a)))
1010  this->totalSteps += this->initialDecelSteps; //Add the steps used for initial deceleration to the totalSteps variable, since we moved this number of steps, passed the initial position, and therefore need to move this amount of steps extra, in the desired direction
1011 
1012  if(this->accelSteps > (this->totalSteps >> 1)) //If we need to accelerate for longer than half of the total steps, we need to start decelerating before we reach max speed
1013  {
1014  this->accelSteps = this->decelSteps = (this->totalSteps >> 1); //Accelerate and decelerate for the same amount of steps (half the total steps)
1015  this->accelSteps += this->totalSteps - this->accelSteps - this->decelSteps; //If there are still a step left to perform, due to rounding errors, do this step as an acceleration step
1016  }
1017  else
1018  {
1019  this->decelSteps = this->accelSteps; //If top speed is reached before half the total steps are performed, deceleration period should be same length as acceleration period
1020  this->cruiseSteps = this->totalSteps - this->accelSteps - this->decelSteps; //Perform remaining steps, as cruise steps
1021  }
1022 
1023  this->exactDelay.setValue(INTFREQ/sqrt((curVel*curVel) + 2.0*this->acceleration)); //number of interrupts before the first step should be performed.
1024 
1025  if(this->exactDelay.getFloatValue() >= 65535.5)
1026  {
1027  this->delay = 0xFFFF;
1028  }
1029  else
1030  {
1031  this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5); //Truncate the exactDelay variable, since we cant perform fractional steps
1032  }
1033  }
1034  else //If the motor is currently rotating the same direction as desired, we dont necessarily need to decelerate
1035  {
1036  if(curVel > this->velocity) //If current velocity is greater than desired velocity
1037  {
1038  this->state = INITDECEL; //We need to decelerate the motor to desired velocity
1039  this->initialDecelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(-2.0*this->acceleration)); //Number of steps to bring the motor down from current speed to max speed (S = (V^2 - V0^2)/(2*-a)))
1040  this->accelSteps = 0; //No acceleration phase is needed
1041  this->decelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->acceleration)); //Number of steps needed to decelerate the motor from top speed to full stop
1042  this->exactDelay.setValue((INTFREQ/sqrt((curVel*curVel) + 2*this->acceleration)));
1043 
1044  if(this->totalSteps <= (this->initialDecelSteps + this->decelSteps))
1045  {
1046  this->cruiseSteps = 0;
1047  }
1048  else
1049  {
1050  this->cruiseSteps = steps - this->initialDecelSteps - this->decelSteps; //Perform remaining steps as cruise steps
1051  }
1052 
1053 
1054  }
1055 
1056  else if(curVel < this->velocity) //If current velocity is less than desired velocity
1057  {
1058  this->state = ACCEL; //Start accelerating
1059  this->accelSteps = (uint32_t)(((this->velocity*this->velocity) - (curVel*curVel))/(2.0*this->acceleration)); //Number of Steps needed to accelerate from current velocity to full speed
1060 
1061  if(this->accelSteps > (this->totalSteps >> 1)) //If we need to accelerate for longer than half of the total steps, we need to start decelerating before we reach max speed
1062  {
1063  this->accelSteps = this->decelSteps = (this->totalSteps >> 1); //Accelerate and decelerate for the same amount of steps (half the total steps)
1064  this->accelSteps += this->totalSteps - this->accelSteps - this->decelSteps; //If there are still a step left to perform, due to rounding errors, do this step as an acceleration step
1065  this->cruiseSteps = 0;
1066  }
1067  else
1068  {
1069  this->decelSteps = this->accelSteps; //If top speed is reached before half the total steps are performed, deceleration period should be same length as acceleration period
1070  this->cruiseSteps = this->totalSteps - this->accelSteps - this->decelSteps; //Perform remaining steps, as cruise steps
1071  }
1072 
1073  this->cruiseSteps = steps - this->accelSteps - this->decelSteps; //Perform remaining steps as cruise steps
1074  this->initialDecelSteps = 0; //No initial deceleration phase needed
1075  }
1076 
1077  else //If current velocity is equal to desired velocity
1078  {
1079  this->state = CRUISE; //We are already at desired speed, therefore we start at cruise phase
1080  this->decelSteps = (uint32_t)((this->velocity*this->velocity)/(2.0*this->acceleration)); //Number of steps needed to decelerate the motor from top speed to full stop
1081  this->accelSteps = 0; //No acceleration phase needed
1082  this->initialDecelSteps = 0; //No initial deceleration phase needed
1083 
1084  if(this->decelSteps >= this->totalSteps)
1085  {
1086  this->cruiseSteps = 0;
1087  }
1088  else
1089  {
1090  this->cruiseSteps = steps - this->decelSteps; //Perform remaining steps as cruise steps
1091  }
1092  }
1093  }
1094  }
1095 
1096  else //If motor is currently at full stop (state = STOP)
1097  {
1098  if(dir) //Set the motor direction pin to the desired setting
1099  {
1100  PORTD |= (1 << 7);
1101  }
1102  else
1103  {
1104  PORTD &= ~(1 << 7);
1105  }
1106  this->state = ACCEL;
1107  this->accelSteps = (uint32_t)((this->velocity * this->velocity)/(2.0*this->acceleration)); //Number of steps to bring the motor to max speed (S = (V^2 - V0^2)/(2*a)))
1108  this->initialDecelSteps = 0; //No initial deceleration phase needed
1109 
1110  if(this->accelSteps > (steps >> 1)) //If we need to accelerate for longer than half of the total steps, we need to start decelerating before we reach max speed
1111  {
1112  this->cruiseSteps = 0; //No cruise phase needed
1113  this->accelSteps = this->decelSteps = (steps >> 1); //Accelerate and decelerate for the same amount of steps (half the total steps)
1114  this->accelSteps += steps - this->accelSteps - this->decelSteps; //if there are still a step left to perform, due to rounding errors, do this step as an acceleration step
1115  }
1116 
1117  else
1118  {
1119  this->decelSteps = this->accelSteps; //If top speed is reached before half the total steps are performed, deceleration period should be same length as acceleration period
1120  this->cruiseSteps = steps - this->accelSteps - this->decelSteps; //Perform remaining steps as cruise steps
1121  }
1122  this->exactDelay.setValue(INTFREQ/sqrt(2.0*this->acceleration)); //number of interrupts before the first step should be performed.
1123 
1124  if(this->exactDelay.getFloatValue() > 65535.0)
1125  {
1126  this->delay = 0xFFFF;
1127  }
1128  else
1129  {
1130  this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5); //Truncate the exactDelay variable, since we cant perform fractional steps
1131  }
1132  }
1133 
1134  this->startTimer(); //start timer so we can perform steps
1135  this->enableMotor(); //Enable motor driver
1136 }
1137 
1138 void uStepper::hardStop(bool holdMode)
1139 {
1140  if(this->dropIn)
1141  {
1142  return; //Drop in feature is activated. just return since this function makes no sense with drop in activated!
1143  }
1144 
1145  this->stopTimer(); //Stop interrupt timer, since we shouldn't perform more steps
1146  this->hold = holdMode;
1147 
1148  if(state != STOP)
1149  {
1150  this->state = STOP; //Set current state to STOP
1151 
1152  this->startTimer();
1153  }
1154 
1155  else
1156  {
1157  if(holdMode == SOFT)
1158  {
1159  this->disableMotor();
1160  }
1161 
1162  else if (holdMode == HARD)
1163  {
1164  this->enableMotor();
1165  }
1166  }
1167 }
1168 
1169 void uStepper::softStop(bool holdMode)
1170 {
1171  float curVel;
1172 
1173  if(this->dropIn)
1174  {
1175  return; //Drop in feature is activated. just return since this function makes no sense with drop in activated!
1176  }
1177 
1178  this->stopTimer(); //Stop interrupt timer, since we shouldn't perform more steps
1179  this->hold = holdMode;
1180 
1181  if(state != STOP)
1182  {
1183  curVel = INTFREQ/this->exactDelay.getFloatValue(); //Use this to calculate current velocity
1184 
1185  this->decelSteps = (uint32_t)((curVel*curVel)/(2.0*this->acceleration)); //Number of steps to bring the motor down from current speed to max speed (S = (V^2 - V0^2)/(2*-a)))
1186  this->accelSteps = this->initialDecelSteps = this->cruiseSteps = 0; //Reset amount of steps in the different phases
1187  this->state = DECEL;
1188 
1189  this->exactDelay.setValue(INTFREQ/sqrt(2.0*this->acceleration)); //number of interrupts before the first step should be performed.
1190 
1191  if(this->exactDelay.getFloatValue() > 65535.0)
1192  {
1193  this->delay = 0xFFFF;
1194  }
1195  else
1196  {
1197  this->delay = (uint16_t)(this->exactDelay.getFloatValue() - 0.5); //Truncate the exactDelay variable, since we cant perform fractional steps
1198  }
1199 
1200  this->startTimer();
1201  }
1202 
1203  else
1204  {
1205  if(holdMode == SOFT)
1206  {
1207  this->disableMotor();
1208  }
1209 
1210  else if (holdMode == HARD)
1211  {
1212  this->enableMotor();
1213  }
1214  }
1215 }
1216 
1217 void uStepper::setup(bool mode, uint8_t microStepping, float faultSpeed, uint32_t faultTolerance)
1218 {
1219  this->dropIn = mode;
1220  if(mode)
1221  {
1222  pinMode(2,INPUT);
1223  pinMode(3,INPUT);
1224  pinMode(4,INPUT);
1225  digitalWrite(2,HIGH);
1226  digitalWrite(3,HIGH);
1227  digitalWrite(4,HIGH);
1228  this->stepResolution = 360.0/((float)(200*microStepping));
1229  this->tolerance = ((float)faultTolerance)*this->stepResolution;
1230  this->faultStepDelay = (uint16_t)((INTFREQ/faultSpeed) - 1);
1231  EICRA = 0x0D; //int0 generates interrupt on any change and int1 generates interrupt on rising edge
1232  EIMSK = 0x03; //enable int0 and int1 interrupt requests
1233  }
1234 
1235  TCCR2B &= ~((1 << CS20) | (1 << CS21) | (1 << CS22) | (1 << WGM22));
1236  TCCR2A &= ~((1 << WGM20) | (1 << WGM21));
1237  TCCR2B |= (1 << CS21); //Enable timer with prescaler 8. interrupt base frequency ~ 7.8125kHz
1238  TCCR2A |= (1 << WGM21); //Switch timer 2 to CTC mode, to adjust interrupt frequency
1239  OCR2A = 70; //Change top value to 60 in order to obtain an interrupt frequency of 33.333kHz
1240  this->encoder.setup();
1241 }
1242 
1244 {
1245  TCNT2 = 0; //Clear counter value, to make sure we get correct timing
1246  TIFR2 |= (1 << OCF2A); //Clear compare match interrupt flag, if it is set.
1247  TIMSK2 |= (1 << OCIE2A); //Enable compare match interrupt
1248 
1249  sei();
1250 }
1251 
1253 {
1254  TIMSK2 &= ~(1 << OCF2A); //disable compare match interrupt
1255 }
1256 
1258 {
1259  PORTB &= ~(1 << 0); //Enable motor driver
1260 }
1261 
1263 {
1264  PORTB |= (1 << 0); //Disable motor driver
1265 }
1266 
1268 {
1269  return this->direction;
1270 }
1271 
1273 {
1274  if(this->state != STOP)
1275  {
1276  return 1; //Motor running
1277  }
1278 
1279  return 0; //Motor not running
1280 }
1281 
1283 {
1284  if(this->direction == CW)
1285  {
1286  return this->stepsSinceReset + this->currentStep;
1287  }
1288  else
1289  {
1290  return this->stepsSinceReset - this->currentStep;
1291  }
1292 }
1293 
1294 void i2cMaster::cmd(uint8_t cmd)
1295 {
1296  uint16_t i = 0;
1297  // send command
1298  TWCR = cmd;
1299  // wait for command to complete
1300  while (!(TWCR & (1 << TWINT)));
1301 
1302  // save status bits
1303  status = TWSR & 0xF8;
1304 }
1305 
1306 bool i2cMaster::read(uint8_t slaveAddr, uint8_t regAddr, uint8_t numOfBytes, uint8_t *data)
1307 {
1308  uint8_t i, buff[numOfBytes];
1309 
1310  TIMSK1 &= ~(1 << OCIE1A);
1311 
1312  I2C.start(slaveAddr, WRITE);
1313 
1314  I2C.writeByte(regAddr);
1315 
1316  I2C.restart(slaveAddr, READ);
1317 
1318  for(i = 0; i < (numOfBytes - 1); i++)
1319  {
1320  I2C.readByte(ACK, &data[i]);
1321  }
1322 
1323  I2C.readByte(NACK, &data[numOfBytes-1]);
1324 
1325  I2C.stop();
1326 
1327  TIMSK1 |= (1 << OCIE1A);
1328 
1329  return 1;
1330 }
1331 
1332 bool i2cMaster::write(uint8_t slaveAddr, uint8_t regAddr, uint8_t numOfBytes, uint8_t *data)
1333 {
1334  uint8_t i;
1335 
1336  TIMSK1 &= ~(1 << OCIE1A);
1337 
1338  I2C.start(slaveAddr, WRITE);
1339  I2C.writeByte(regAddr);
1340 
1341  for(i = 0; i < numOfBytes; i++)
1342  {
1343  I2C.writeByte(*(data + i));
1344  }
1345  I2C.stop();
1346 
1347  TIMSK1 |= (1 << OCIE1A);
1348 
1349  return 1;
1350 }
1351 
1352 bool i2cMaster::readByte(bool ack, uint8_t *data)
1353 {
1354  if(ack)
1355  {
1356  this->cmd((1 << TWINT) | (1 << TWEN) | (1 << TWEA));
1357  }
1358 
1359  else
1360  {
1361  this->cmd((1 << TWINT) | (1 << TWEN));
1362  }
1363 
1364  *data = TWDR;
1365 
1366  return 1;
1367 }
1368 
1369 bool i2cMaster::start(uint8_t addr, bool RW)
1370 {
1371  // send START condition
1372  this->cmd((1<<TWINT) | (1<<TWSTA) | (1<<TWEN));
1373 
1374  if (this->getStatus() != START && this->getStatus() != REPSTART)
1375  {
1376  return false;
1377  }
1378 
1379  // send device address and direction
1380  TWDR = (addr << 1) | RW;
1381  this->cmd((1 << TWINT) | (1 << TWEN));
1382 
1383  if (RW == READ)
1384  {
1385  return this->getStatus() == RXADDRACK;
1386  }
1387 
1388  else
1389  {
1390  return this->getStatus() == TXADDRACK;
1391  }
1392 }
1393 
1394 bool i2cMaster::restart(uint8_t addr, bool RW)
1395 {
1396  return this->start(addr, RW);
1397 }
1398 
1399 bool i2cMaster::writeByte(uint8_t data)
1400 {
1401  TWDR = data;
1402 
1403  this->cmd((1 << TWINT) | (1 << TWEN));
1404 
1405  return this->getStatus() == TXDATAACK;
1406 }
1407 
1409 {
1410  uint16_t i = 0;
1411  // issue stop condition
1412  TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
1413 
1414  // wait until stop condition is executed and bus released
1415  while (TWCR & (1 << TWSTO));
1416 
1417  status = I2CFREE;
1418 
1419  return 1;
1420 }
1421 
1423 {
1424  return status;
1425 }
1426 
1428 {
1429  // set bit rate register to 12 to obtain 400kHz scl frequency (in combination with no prescaling!)
1430  TWBR = 12;
1431  // no prescaler
1432  TWSR &= 0xFC;
1433 }
1434 
1436 {
1437 
1438 }
#define R
Definition: uStepper.h:197
uStepper(void)
Constructor of uStepper class.
Definition: uStepper.cpp:781
uStepperEncoder(void)
Constructor.
Definition: uStepper.cpp:652
void setup(bool mode=NORMAL, uint8_t microStepping=SIXTEEN, float faultSpeed=3000.0, uint32_t faultTolerance=20)
Initializes the different parts of the uStepper object.
Definition: uStepper.cpp:1217
uint32_t currentStep
Definition: uStepper.h:457
uint16_t getStrength(void)
Measure the strength of the magnet.
Definition: uStepper.cpp:737
#define CRUISE
Definition: uStepper.h:178
#define WRITE
Definition: uStepper.h:203
float getSpeed(void)
Measure the current speed of the motor.
Definition: uStepper.cpp:695
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 ...
Definition: uStepper.cpp:1332
bool getMotorState(void)
Get the current state of the motor.
Definition: uStepper.cpp:1272
float2 multiplier
Definition: uStepper.h:445
float acceleration
Definition: uStepper.h:477
bool continous
Definition: uStepper.h:461
Prototype of class for accessing all features of the uStepper in a single object. ...
Definition: uStepper.h:439
volatile float curSpeed
Definition: uStepper.h:428
void enableMotor(void)
Enables the stepper driver output stage.
Definition: uStepper.cpp:1257
#define A
Definition: uStepper.h:235
float getMaxAcceleration(void)
Get the value of the maximum motor acceleration.
Definition: uStepper.cpp:830
#define CW
Definition: uStepper.h:182
#define DECEL
Definition: uStepper.h:179
float getTemp(void)
Request a reading of current temperature.
Definition: uStepper.cpp:637
#define RXADDRACK
Definition: uStepper.h:213
uint32_t cruiseSteps
Definition: uStepper.h:455
uint32_t totalSteps
Definition: uStepper.h:459
#define C
Definition: uStepper.h:237
bool getCurrentDirection(void)
Returns the direction the motor is currently configured to rotate.
Definition: uStepper.cpp:1267
float getAngleMoved(void)
Measure the angle moved from reference position.
Definition: uStepper.cpp:657
uint32_t accelSteps
Definition: uStepper.h:449
#define ENCODERADDR
Definition: uStepper.h:187
void hardStop(bool holdMode)
Stop the motor without deceleration.
Definition: uStepper.cpp:1138
void setMaxAcceleration(float accel)
Set the maximum acceleration of the stepper motor.
Definition: uStepper.cpp:810
void startTimer(void)
Starts timer for stepper algorithm.
Definition: uStepper.cpp:1243
void setMaxVelocity(float vel)
Sets the maximum rotational velocity of the motor.
Definition: uStepper.cpp:860
void moveSteps(uint32_t steps, bool dir, bool holdMode)
Make the motor perform a predefined number of steps.
Definition: uStepper.cpp:985
#define STOP
Definition: uStepper.h:176
float getMaxVelocity(void)
Returns the maximum rotational velocity of the motor.
Definition: uStepper.cpp:893
bool writeByte(uint8_t data)
Writes a byte to a device on the I2C bus.
Definition: uStepper.cpp:1399
i2cMaster(void)
Constructor.
Definition: uStepper.cpp:1435
void softStop(bool holdMode)
Stop the motor with deceleration.
Definition: uStepper.cpp:1169
uint8_t status
Definition: uStepper.h:735
uint8_t detectMagnet(void)
Detect if magnet is present and within range.
Definition: uStepper.cpp:755
uint8_t getStatus(void)
Get current I2C status.
Definition: uStepper.cpp:1422
#define READ
Definition: uStepper.h:201
void cmd(uint8_t cmd)
Sends commands over the I2C bus.
Definition: uStepper.cpp:1294
bool restart(uint8_t addr, bool RW)
Restarts connection between arduino and I2C device.
Definition: uStepper.cpp:1394
bool readByte(bool ack, uint8_t *data)
Reads a byte from the I2C bus.
Definition: uStepper.cpp:1352
int64_t stepsSinceReset
Definition: uStepper.h:467
uStepperEncoder encoder
Definition: uStepper.h:527
#define HARD
Definition: uStepper.h:184
void stopTimer(void)
Stops the timer for the stepper algorithm.
Definition: uStepper.cpp:1252
uint8_t getAgc(void)
Read the current AGC value of the encoder chip.
Definition: uStepper.cpp:746
bool start(uint8_t addr, bool RW)
sets up connection between arduino and I2C device.
Definition: uStepper.cpp:1369
#define MAGNITUDE
Definition: uStepper.h:192
void runContinous(bool dir)
Make the motor rotate continuously.
Definition: uStepper.cpp:898
#define INTFREQ
Definition: uStepper.h:181
#define ENCODERSPEEDCONSTANT
Definition: uStepper.h:195
Prototype of class for accessing the TWI (I2C) interface of the AVR (master mode only).
Definition: uStepper.h:732
#define ANGLE
Definition: uStepper.h:189
void setHome(void)
Define new reference(home) position.
Definition: uStepper.cpp:719
#define SOFT
Definition: uStepper.h:185
uint16_t cruiseDelay
Definition: uStepper.h:443
float getAngle(void)
Measure the current shaft angle.
Definition: uStepper.cpp:732
#define ACK
Definition: uStepper.h:215
#define B
Definition: uStepper.h:236
bool stop(void)
Closes the I2C connection.
Definition: uStepper.cpp:1408
#define AGC
Definition: uStepper.h:191
i2cMaster I2C
Definition: uStepper.cpp:73
volatile float oldAngle
Definition: uStepper.h:426
#define I2CFREE
Definition: uStepper.h:199
#define REPSTART
Definition: uStepper.h:207
void begin(void)
Setup TWI (I2C) interface.
Definition: uStepper.cpp:1427
#define TXDATAACK
Definition: uStepper.h:211
#define NACK
Definition: uStepper.h:217
Function prototypes and definitions for the uStepper library.
#define ACCEL
Definition: uStepper.h:177
#define INITDECEL
Definition: uStepper.h:180
float velocity
Definition: uStepper.h:475
float2 exactDelay
Definition: uStepper.h:469
volatile float angleMoved
Definition: uStepper.h:429
uint8_t state
Definition: uStepper.h:447
uStepperTemp(void)
Constructor.
Definition: uStepper.cpp:632
uint16_t delay
Definition: uStepper.h:471
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 ...
Definition: uStepper.cpp:1306
uint32_t decelSteps
Definition: uStepper.h:451
bool direction
Definition: uStepper.h:465
bool hold
Definition: uStepper.h:463
#define START
Definition: uStepper.h:205
float encoderOffset
Definition: uStepper.h:425
void disableMotor(void)
Disables the stepper driver output stage.
Definition: uStepper.cpp:1262
#define TXADDRACK
Definition: uStepper.h:209
int64_t getStepsSinceReset(void)
Get the number of steps applied since reset.
Definition: uStepper.cpp:1282
void setup(void)
Setup the encoder.
Definition: uStepper.cpp:700
uint32_t initialDecelSteps
Definition: uStepper.h:453