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 }
uStepperS
Prototype of class for accessing all features of the uStepper S in a single object.
Definition: uStepperS.h:279
uStepperEncoder::getAngleRaw
uint16_t getAngleRaw(void)
Return the current shaft angle in raw encoder readings.
Definition: uStepperEncoder.cpp:178
uStepperEncoder::angle
volatile uint16_t angle
Definition: uStepperEncoder.h:209
uStepperDriver::readRegister
int32_t readRegister(uint8_t address)
Reads a register from the motor driver.
Definition: uStepperDriver.cpp:316
uStepperEncoder::angleMovedRaw
volatile int32_t angleMovedRaw
Definition: uStepperEncoder.h:248
uStepperS.h
uStepperEncoder::Beta
volatile uint8_t Beta
Definition: uStepperEncoder.h:230
uStepperEncoder::angleMoved
volatile int32_t angleMoved
Definition: uStepperEncoder.h:213
posFilter_t::velIntegrator
float velIntegrator
Definition: uStepperS.h:206
uStepperEncoder::status
uint8_t status
Definition: uStepperEncoder.h:245
uStepperEncoder::getAngleMoved
float getAngleMoved(bool filtered=true)
Returns the angle moved from reference position in degrees.
Definition: uStepperEncoder.cpp:184
uStepperEncoder::oldAngle
volatile uint16_t oldAngle
Definition: uStepperEncoder.h:219
posFilter_t::velEst
float velEst
Definition: uStepperS.h:207
uStepperS::setSPIMode
void setSPIMode(uint8_t mode)
Definition: uStepperS.cpp:400
uStepperEncoder::captureAngle
uint16_t captureAngle(void)
Capture the current shaft angle.
Definition: uStepperEncoder.cpp:117
uStepperDriver::setHome
void setHome(int32_t initialSteps=0)
Resets the internal position counter of the motor driver.
Definition: uStepperDriver.cpp:258
uStepperEncoder::detectMagnet
bool detectMagnet(void)
detect magnet
Definition: uStepperEncoder.cpp:101
uStepperEncoder::encoderFilter
volatile posFilter_t encoderFilter
Definition: uStepperEncoder.h:227
uStepperEncoder::smoothValue
volatile int32_t smoothValue
Definition: uStepperEncoder.h:199
uStepperEncoder::getAngle
float getAngle(void)
Return the current shaft angle in degrees.
Definition: uStepperEncoder.cpp:173
uStepperS::encoder
uStepperEncoder encoder
Definition: uStepperS.h:291
ENCODERDATATOSTEP
#define ENCODERDATATOSTEP
Definition: uStepperEncoder.h:41
uStepperEncoder::getRPM
float getRPM(void)
Measure the current speed of the motor.
Definition: uStepperEncoder.cpp:223
uStepperEncoder::speedSmoothValue
volatile float speedSmoothValue
Definition: uStepperEncoder.h:202
uStepperEncoder::getAngleMovedRaw
int32_t getAngleMovedRaw(bool filtered=true)
Returns the angle moved from reference position in raw encoder readings.
Definition: uStepperEncoder.cpp:198
MOSI_ENC
#define MOSI_ENC
Definition: uStepperS.h:226
posFilter_t::posError
float posError
Definition: uStepperS.h:204
uStepperEncoder::init
void init(uStepperS *_pointer)
Initiation of the encoder.
Definition: uStepperEncoder.cpp:50
uStepperS::mode
volatile uint8_t mode
Definition: uStepperS.h:749
uStepperEncoder::pointer
uStepperS * pointer
Definition: uStepperEncoder.h:235
CS_ENCODER
#define CS_ENCODER
Definition: uStepperS.h:223
uStepperEncoder::uStepperEncoder
uStepperEncoder(void)
Constructor of uStepperEncoder class.
Definition: uStepperEncoder.cpp:36
uStepperEncoder::encoderOffset
volatile uint16_t encoderOffset
Definition: uStepperEncoder.h:205
uStepperEncoder::getStatus
uint8_t getStatus(void)
Get encoder status.
Definition: uStepperEncoder.cpp:213
uStepperS::driver
uStepperDriver driver
Definition: uStepperS.h:288
ENCODERINTFREQ
#define ENCODERINTFREQ
Definition: uStepperS.h:242
ANGLETOENCODERDATA
#define ANGLETOENCODERDATA
Definition: uStepperEncoder.h:43
uStepperEncoder::setHome
void setHome(float initialAngle=0)
Define new reference(home) position.
Definition: uStepperEncoder.cpp:82
uStepperS::SPI
uint8_t SPI(uint8_t data)
Definition: uStepperS.cpp:415
DROPIN
#define DROPIN
Definition: uStepperS.h:232
uStepperEncoder::getSpeed
float getSpeed(void)
Measure the current speed of the motor.
Definition: uStepperEncoder.cpp:218
uStepperEncoder::chipSelect
void chipSelect(bool state)
Set the output level of the chip select pin.
Definition: uStepperEncoder.cpp:228
VACTUAL
#define VACTUAL
Definition: uStepperDriver.h:55
pointer
uStepperS * pointer
Definition: uStepperS.cpp:34
posFilter_t::posEst
float posEst
Definition: uStepperS.h:205
ENCODERDATATOREVOLUTIONS
#define ENCODERDATATOREVOLUTIONS
Definition: uStepperEncoder.h:42