uStepper S
uStepperEncoder.cpp
Go to the documentation of this file.
1 /********************************************************************************************
2 * File: uStepperEncoder.cpp *
3 * Version: 2.2.0 *
4 * Date: September 22nd, 2020 *
5 * Authors: Thomas Hørring Olsen *
6 * Emil Jacobsen *
7 * *
8 *********************************************************************************************
9 * (C) 2020 *
10 * *
11 * uStepper ApS *
12 * www.ustepper.com *
13 * administration@ustepper.com *
14 * *
15 * The code contained in this file is released under the following open source license: *
16 * *
17 * Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International *
18 * *
19 * The code in this file is provided without warranty of any kind - use at own risk! *
20 * neither uStepper ApS nor the author, can be held responsible for any damage *
21 * caused by the use of the code contained in this file ! *
22 * *
23 ********************************************************************************************/
33 #include <uStepperS.h>
34 /* At initialition setup the SPI hardware protocal to communicate with SSI interface */
35 extern uStepperS * pointer;
37 {
38  /* Prepare Hardware SPI communication */
39 
40  /*
41  * SPE = 1: SPI enabled
42  * MSTR = 1: Master
43  * SPR0 = 1 & SPR1 = 0: fOSC/16 = 1Mhz
44  * CPOL = 1: Idle at HIGH
45  * CPHA = 0: Sample at leading edge
46  */
47  // SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<CPOL);
48 }
49 
51 {
52  this->pointer = _pointer;
53  angle = 0;
54 
55  /* Set the interrupt mode to 14 with a prescaler of 1 */
56  TCCR1A = (1 << WGM11);
57  TCCR1B = (1 << WGM12) | (1 << WGM13) | (1 << CS10);
58 
59  /* Reset Timer1 and set compare interrupt each: 62.5 ns * 16000 = 1 milliseconds */
60  TCNT1 = 0;
61  if(pointer->mode == DROPIN)
62  {
63  ICR1 = 16000;
64  }
65  else{
66  ICR1 = 8000;
67  }
68 
69 
70  TIFR1 = 0;
71 
72  /* Enable Timer1 compare interrupt */
73  TIMSK1 = (1 << OCIE1A);
74 
75  /* As long as we only use SSI, the MOSI_ENC/DIN (NSL) should be pulled LOW */
76  PORTC &= ~(1 << MOSI_ENC);
77 
78  /* Enable global interrupts */
79  sei();
80 }
81 
82 void uStepperEncoder::setHome(float initialAngle)
83 {
84  cli();
85  TCNT1 = 0;
86  this->encoderOffset = this->captureAngle();
87  this->oldAngle = 0;
88  this->angle = 0;
89  this->angleMoved = ANGLETOENCODERDATA * initialAngle;
90  this->angleMovedRaw=this->angleMoved;
91  this->smoothValue = this->angleMoved;
92  pointer->driver.setHome(this->angleMoved * ENCODERDATATOSTEP);
93  this->encoderFilter.posError = 0.0;
94  this->encoderFilter.posEst = 0.0;
95  this->encoderFilter.velIntegrator = 0.0;
96  this->encoderFilter.velEst = 0.0;
97  this->speedSmoothValue = 0.0;
98  sei();
99 }
100 
102 {
103  uint8_t status;
104 
105  //this->captureAngle();
106 
107  status = this->getStatus();
108 
109  if((status & 0xE0) != 0x80)
110  {
111  return 0;
112  }
113 
114  return 1;
115 }
116 
118 {
119  pointer->setSPIMode(2);
120 
121  uint16_t value = 0;
122  int32_t deltaAngle;
123  uint16_t curAngle;
124 
125  chipSelect(true); // Set CS HIGH
126 
127  /* Write dummy and read the incoming 8 bits */
128  value = pointer->SPI(0x00);
129  value <<= 8;
130 
131  /* Write dummy and read the incoming 8 bits */
132  value |= pointer->SPI(0x00);
133  /* Write dummy and read the incoming 8 bits */
134  this->status = pointer->SPI(0x00);
135 
136  chipSelect(false); // Set CS LOW
137 
138  curAngle = value;
139  curAngle -= this->encoderOffset;
140  this->angle = curAngle;
141 
142  deltaAngle = (int32_t)this->oldAngle - (int32_t)curAngle;
143  this->oldAngle = curAngle;
144 
145  if(deltaAngle < -32768)
146  {
147  deltaAngle += 65536;
148  }
149  else if(deltaAngle > 32768)
150  {
151  deltaAngle -= 65536;
152  }
153 
154  angleMovedRaw += deltaAngle;
156  this->smoothValue = (this->smoothValue<< this->Beta)-this->smoothValue;
157  this->smoothValue += angleMovedRaw;
158  this->smoothValue >>= this->Beta;
159 
160  if(pointer->mode != DROPIN)
161  {
162  this->speedSmoothValue *= 0.99;
163  this->speedSmoothValue += (this->smoothValue-this->angleMoved)*0.01;
165  }
166 
167  this->angleMoved=this->smoothValue;
168 
169  return (uint16_t)value;
170 
171 }
172 
174 {
175  return (float)angle * 0.005493164; //360/65536 0.087890625
176 }
177 
179 {
180  return angle;
181 }
182 
183 
184 float uStepperEncoder::getAngleMoved(bool filtered)
185 {
186  if(filtered == true)
187  {
188  return this->angleMoved * 0.005493164; //360/65536
189  }
190  else
191  {
192  return this->angleMovedRaw * 0.005493164; //360/65536
193  }
194 
195 
196 }
197 
198 int32_t uStepperEncoder::getAngleMovedRaw(bool filtered)
199 {
200  if(filtered == true)
201  {
202  return this->angleMoved;
203  }
204  else
205  {
206  return this->angleMovedRaw;
207  }
208 
209 
210 }
211 
212 
214 {
215  return this->status;
216 }
217 
219 {
221 }
222 
224 {
226 }
227 
229 {
230  if(state)
231  PORTD |= (1 << CS_ENCODER); // Set CS HIGH
232  else
233  PORTD &= ~(1 << CS_ENCODER); // Set CS LOW
234 }
int32_t readRegister(uint8_t address)
Reads a register from the motor driver.
void setHome(int32_t initialSteps=0)
Resets the internal position counter of the motor driver.
volatile int32_t angleMoved
int32_t getAngleMovedRaw(bool filtered=true)
Returns the angle moved from reference position in raw encoder readings.
volatile int32_t smoothValue
uint8_t getStatus(void)
Get encoder status.
uint16_t captureAngle(void)
Capture the current shaft angle.
float getAngleMoved(bool filtered=true)
Returns the angle moved from reference position in degrees.
void setHome(float initialAngle=0)
Define new reference(home) position.
volatile int32_t angleMovedRaw
volatile uint16_t oldAngle
void init(uStepperS *_pointer)
Initiation of the encoder.
float getSpeed(void)
Measure the current speed of the motor.
volatile posFilter_t encoderFilter
volatile float speedSmoothValue
uint16_t getAngleRaw(void)
Return the current shaft angle in raw encoder readings.
uStepperEncoder(void)
Constructor of uStepperEncoder class.
float getRPM(void)
Measure the current speed of the motor.
float getAngle(void)
Return the current shaft angle in degrees.
volatile uint16_t encoderOffset
void chipSelect(bool state)
Set the output level of the chip select pin.
volatile uint16_t angle
bool detectMagnet(void)
detect magnet
uStepperS * pointer
volatile uint8_t Beta
Prototype of class for accessing all features of the uStepper S in a single object.
Definition: uStepperS.h:279
volatile uint8_t mode
Definition: uStepperS.h:751
uStepperEncoder encoder
Definition: uStepperS.h:291
void setSPIMode(uint8_t mode)
Definition: uStepperS.cpp:400
uint8_t SPI(uint8_t data)
Definition: uStepperS.cpp:415
uStepperDriver driver
Definition: uStepperS.h:288
float velIntegrator
Definition: uStepperS.h:206
float posEst
Definition: uStepperS.h:205
float posError
Definition: uStepperS.h:204
float velEst
Definition: uStepperS.h:207
#define VACTUAL
uStepperS * pointer
Definition: uStepperS.cpp:34
#define ANGLETOENCODERDATA
#define ENCODERDATATOREVOLUTIONS
#define ENCODERDATATOSTEP
#define CS_ENCODER
Definition: uStepperS.h:223
#define DROPIN
Definition: uStepperS.h:232
#define ENCODERINTFREQ
Definition: uStepperS.h:242
#define MOSI_ENC
Definition: uStepperS.h:226