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