Skip to content

Commit 78148fd

Browse files
committed
FEAT updated with library version 1.4.0
1 parent 9c5ab16 commit 78148fd

28 files changed

+1982
-41
lines changed

arduino_foc_minimal_encoder/FOCutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "FOCutils.h"
22

33

4-
void setPwmFrequency(int pin) {
4+
void _setPwmFrequency(int pin) {
55
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) // if arduino uno and other atmega328p chips
66
// High PWM frequency
77
// https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328

arduino_foc_minimal_encoder/FOCutils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
* @param pin pin number to configure
2828
*/
29-
void setPwmFrequency(int pin);
29+
void _setPwmFrequency(int pin);
3030

3131
/**
3232
* Function implementing delay() function in milliseconds

arduino_foc_minimal_encoder/SimpleFOC.h

Lines changed: 0 additions & 9 deletions
This file was deleted.

arduino_foc_minimal_encoder/arduino_foc_minimal_encoder.ino

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,20 @@
3939
*
4040
*/
4141

42-
#include "SimpleFOC.h"
42+
#include "BLDCMotor.h"
43+
#include "Encoder.h"
4344

4445
// BLDCMotor( int phA, int phB, int phC, int pp, int en)
4546
// - phA, phB, phC - motor A,B,C phase pwm pins
4647
// - pp - pole pair number
4748
// - enable pin - (optional input)
48-
BLDCMotor motor = BLDCMotor(3, 10, 11, 11,7);
49+
BLDCMotor motor = BLDCMotor(9, 10, 11, 11,8);
4950

5051
//Encoder(int encA, int encB , int cpr, int index)
5152
// - encA, encB - encoder A and B pins
5253
// - ppr - impulses per rotation (cpr=ppr*4)
5354
// - index pin - (optional input)
54-
Encoder encoder = Encoder(A1, A2, 8196);
55+
Encoder encoder = Encoder(2, 3, 8196);
5556
// interrupt routine intialisation
5657
void doA(){encoder.handleA();}
5758
void doB(){encoder.handleB();}

arduino_foc_minimal_magnetic/BLDCMotor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ void BLDCMotor::init() {
7070
if(monitor_port) monitor_port->println("MONITOR: Set high frequency PWM.");
7171
// Increase PWM frequency to 32 kHz
7272
// make silent
73-
setPwmFrequency(pwmA);
74-
setPwmFrequency(pwmB);
75-
setPwmFrequency(pwmC);
73+
_setPwmFrequency(pwmA);
74+
_setPwmFrequency(pwmB);
75+
_setPwmFrequency(pwmC);
7676

7777
// sanity check for the voltage limit configuration
7878
if(PI_velocity.voltage_limit > voltage_power_supply) PI_velocity.voltage_limit = voltage_power_supply;

arduino_foc_minimal_magnetic/FOCutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "FOCutils.h"
22

33

4-
void setPwmFrequency(int pin) {
4+
void _setPwmFrequency(int pin) {
55
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__) // if arduino uno and other atmega328p chips
66
// High PWM frequency
77
// https://sites.google.com/site/qeewiki/books/avr-guide/timers-on-the-atmega328

arduino_foc_minimal_magnetic/FOCutils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
* @param pin pin number to configure
2828
*/
29-
void setPwmFrequency(int pin);
29+
void _setPwmFrequency(int pin);
3030

3131
/**
3232
* Function implementing delay() function in milliseconds
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
#include "MagneticSensorI2C.h"
2+
3+
// MagneticSensorI2C(uint8_t _chip_address, float _cpr, uint8_t _angle_register_msb)
4+
// @param _chip_address I2C chip address
5+
// @param _bit_resolution bit resolution of the sensor
6+
// @param _angle_register_msb angle read register
7+
// @param _bits_used_msb number of used bits in msb
8+
MagneticSensorI2C::MagneticSensorI2C(uint8_t _chip_address, int _bit_resolution, uint8_t _angle_register_msb, int _bits_used_msb){
9+
// chip I2C address
10+
chip_address = _chip_address;
11+
// angle read register of the magnetic sensor
12+
angle_register_msb = _angle_register_msb;
13+
// register maximum value (counts per revolution)
14+
cpr = pow(2,_bit_resolution);
15+
16+
// depending on the sensor architecture there are different combinations of
17+
// LSB and MSB register used bits
18+
// AS5600 uses 0..7 LSB and 8..11 MSB
19+
// AS5048 uses 0..5 LSB and 6..13 MSB
20+
// used bits in LSB
21+
lsb_used = _bit_resolution - _bits_used_msb;
22+
// extraction masks
23+
lsb_mask = (uint8_t)( (2 << lsb_used) - 1 );
24+
msb_mask = (uint8_t)( (2 << _bits_used_msb) - 1 );
25+
}
26+
27+
28+
void MagneticSensorI2C::init(){
29+
30+
//I2C communication begin
31+
Wire.begin();
32+
33+
// velocity calculation init
34+
angle_prev = 0;
35+
velocity_calc_timestamp = _micros();
36+
37+
// full rotations tracking number
38+
full_rotation_offset = 0;
39+
angle_data_prev = getRawCount();
40+
zero_offset = 0;
41+
}
42+
43+
// Shaft angle calculation
44+
// angle is in radians [rad]
45+
float MagneticSensorI2C::getAngle(){
46+
// raw data from the sensor
47+
float angle_data = getRawCount();
48+
49+
// tracking the number of rotations
50+
// in order to expand angle range form [0,2PI]
51+
// to basically infinity
52+
float d_angle = angle_data - angle_data_prev;
53+
// if overflow happened track it as full rotation
54+
if(abs(d_angle) > (0.8*cpr) ) full_rotation_offset += d_angle > 0 ? -_2PI : _2PI;
55+
// save the current angle value for the next steps
56+
// in order to know if overflow happened
57+
angle_data_prev = angle_data;
58+
59+
// zero offset adding
60+
angle_data -= (int)zero_offset;
61+
// return the full angle
62+
// (number of full rotations)*2PI + current sensor angle
63+
return full_rotation_offset + ( angle_data / (float)cpr) * _2PI;
64+
}
65+
66+
// Shaft velocity calculation
67+
float MagneticSensorI2C::getVelocity(){
68+
// calculate sample time
69+
float Ts = (_micros() - velocity_calc_timestamp)*1e-6;
70+
// quick fix for strange cases (micros overflow)
71+
if(Ts <= 0 || Ts > 0.5) Ts = 1e-3;
72+
73+
// current angle
74+
float angle_c = getAngle();
75+
// velocity calculation
76+
float vel = (angle_c - angle_prev)/Ts;
77+
78+
// save variables for future pass
79+
angle_prev = angle_c;
80+
velocity_calc_timestamp = _micros();
81+
return vel;
82+
}
83+
84+
// set current angle as zero angle
85+
// return the angle [rad] difference
86+
float MagneticSensorI2C::initRelativeZero(){
87+
float angle_offset = -getAngle();
88+
zero_offset = getRawCount();
89+
90+
// angle tracking variables
91+
full_rotation_offset = 0;
92+
return angle_offset;
93+
}
94+
// set absolute zero angle as zero angle
95+
// return the angle [rad] difference
96+
float MagneticSensorI2C::initAbsoluteZero(){
97+
float rotation = -(int)zero_offset;
98+
// init absolute zero
99+
zero_offset = 0;
100+
101+
// angle tracking variables
102+
full_rotation_offset = 0;
103+
// return offset in radians
104+
return rotation / (float)cpr * _2PI;
105+
}
106+
// returns 0 if it has no absolute 0 measurement
107+
// 0 - incremental encoder without index
108+
// 1 - encoder with index & magnetic sensors
109+
int MagneticSensorI2C::hasAbsoluteZero(){
110+
return 1;
111+
}
112+
// returns 0 if it does need search for absolute zero
113+
// 0 - magnetic sensor
114+
// 1 - ecoder with index
115+
int MagneticSensorI2C::needsAbsoluteZeroSearch(){
116+
return 0;
117+
}
118+
119+
120+
// function reading the raw counter of the magnetic sensor
121+
int MagneticSensorI2C::getRawCount(){
122+
return (int)MagneticSensorI2C::read(angle_register_msb);
123+
}
124+
125+
// I2C functions
126+
/*
127+
* Read a register from the sensor
128+
* Takes the address of the register as a uint8_t
129+
* Returns the value of the register
130+
*/
131+
int MagneticSensorI2C::read(uint8_t angle_reg_msb) {
132+
// read the angle register first MSB then LSB
133+
byte readArray[2];
134+
uint16_t readValue = 0;
135+
// notify the device that is aboout to be read
136+
Wire.beginTransmission(chip_address);
137+
Wire.write(angle_reg_msb);
138+
Wire.endTransmission(false);
139+
140+
// read the data msb and lsb
141+
Wire.requestFrom(chip_address, (uint8_t)2);
142+
for (byte i=0; i < 2; i++) {
143+
readArray[i] = Wire.read();
144+
}
145+
146+
// depending on the sensor architecture there are different combinations of
147+
// LSB and MSB register used bits
148+
// AS5600 uses 0..7 LSB and 8..11 MSB
149+
// AS5048 uses 0..5 LSB and 6..13 MSB
150+
readValue = ( readArray[1] & lsb_mask );
151+
readValue += ( ( readArray[0] & msb_mask ) << lsb_used );
152+
return readValue;
153+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#ifndef MAGNETICSENSORI2C_LIB_H
2+
#define MAGNETICSENSORI2C_LIB_H
3+
4+
#include "Arduino.h"
5+
#include <Wire.h>
6+
#include "FOCutils.h"
7+
#include "Sensor.h"
8+
9+
10+
class MagneticSensorI2C: public Sensor{
11+
public:
12+
/**
13+
* MagneticSensorI2C class constructor
14+
* @param chip_address I2C chip address
15+
* @param bits number of bits of the sensor resolution
16+
* @param angle_register_msb angle read register msb
17+
* @param _bits_used_msb number of used bits in msb
18+
*/
19+
MagneticSensorI2C(uint8_t _chip_address, int _bit_resolution, uint8_t _angle_register_msb, int _msb_bits_used);
20+
21+
22+
/** sensor initialise pins */
23+
void init();
24+
25+
// implementation of abstract functions of the Sensor class
26+
/** get current angle (rad) */
27+
float getAngle();
28+
/** get current angular velocity (rad/s) **/
29+
float getVelocity();
30+
/**
31+
* set current angle as zero angle
32+
* return the angle [rad] difference
33+
*/
34+
float initRelativeZero();
35+
/**
36+
* set absolute zero angle as zero angle
37+
* return the angle [rad] difference
38+
*/
39+
float initAbsoluteZero();
40+
/** returns 1 because it is the absolute sensor */
41+
int hasAbsoluteZero();
42+
/** returns 0 maning it doesn't need search for absolute zero */
43+
int needsAbsoluteZeroSearch();
44+
45+
46+
private:
47+
float cpr; //!< Maximum range of the magnetic sensor
48+
uint16_t lsb_used; //!< Number of bits used in LSB register
49+
uint8_t lsb_mask;
50+
uint8_t msb_mask;
51+
52+
// I2C variables
53+
uint8_t angle_register_msb; //!< I2C angle register to read
54+
uint8_t chip_address; //!< I2C chip select pins
55+
56+
// I2C functions
57+
/** Read one I2C register value */
58+
int read(uint8_t angle_register_msb);
59+
60+
word zero_offset; //!< user defined zero offset
61+
/**
62+
* Function getting current angle register value
63+
* it uses angle_register variable
64+
*/
65+
int getRawCount();
66+
67+
// total angle tracking variables
68+
float full_rotation_offset; //!<number of full rotations made
69+
float angle_data_prev; //!< angle in previous position calculation step
70+
71+
// velocity calculation variables
72+
float angle_prev; //!< angle in previous velocity calculation step
73+
long velocity_calc_timestamp; //!< last velocity calculation timestamp
74+
75+
};
76+
77+
78+
#endif

0 commit comments

Comments
 (0)