moreno teeri
/
as5048spi
gestion encodeur 5048 par spi
Revision 0:5a1830df0b66, committed 2019-10-08
- Comitter:
- PC2ROBOT
- Date:
- Tue Oct 08 14:59:11 2019 +0000
- Commit message:
- as5048
Changed in this revision
diff -r 000000000000 -r 5a1830df0b66 as5048spi.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/as5048spi.cpp Tue Oct 08 14:59:11 2019 +0000 @@ -0,0 +1,132 @@ +#include "as5048spi.h" + +As5048Spi::As5048Spi(PinName mosi, PinName miso, PinName sclk, PinName chipselect, int ndevices) : + _nDevices(ndevices), + _chipSelectN(chipselect), + _spi(mosi, miso, sclk) +{ + _chipSelectN.write(1); + // AS5048 needs 16-bits for is commands + // Mode = 1: + // clock polarity = 0 --> clock pulse is high + // clock phase = 1 --> sample on falling edge of clock pulse + _spi.format(16, 1); + + // Set clock frequency to 1 MHz (max is 10Mhz) + _spi.frequency(1000000); + + _readBuffer = new int[ndevices]; +} + +As5048Spi::~As5048Spi() +{ + delete [] _readBuffer; +} + +int As5048Spi::degrees(int sensor_result) +{ + return mask(sensor_result) * 36000 / 0x4000; +} + + +int As5048Spi::radian(int sensor_result) +{ + return mask(sensor_result) * 62832 / 0x4000; +} + +bool As5048Spi::error(int device) +{ + if( device == -1 ) { + for(int i = 0; i < _nDevices; ++i) { + if( _readBuffer[i] & 0x4000 ) { + return true; + } + } + } else if( device < _nDevices ) { + return (_readBuffer[device] & 0x4000) == 0x4000; + } + return false; +} + + +void As5048Spi::frequency(int hz) +{ + _spi.frequency(hz); +} + +int As5048Spi::mask(int sensor_result) +{ + return sensor_result & 0x3FFF; // return lowest 14-bits +} + + +void As5048Spi::mask(int* sensor_results, int n) +{ + for(int i = 0; i < n; ++i) { + sensor_results[i] &= 0x3FFF; + } +} + + +bool As5048Spi::parity_check(int sensor_result) +{ + // Use the LSb of result to keep track of parity (0 = even, 1 = odd) + int result = sensor_result; + + for(int i = 1; i <= 15; ++i) { + sensor_result >>= 1; + result ^= sensor_result; + } + // Parity should be even + return (result & 0x0001) == 0; +} + +const int* As5048Spi::read(As5048Command command) +{ + _read(command); // Send command to device(s) + return _read(AS_CMD_NOP); // Read-out device(s) +} + +const int* As5048Spi::read_sequential(As5048Command command) +{ + return _read(command); +} + +const int* As5048Spi::read_angle() +{ + _read(AS_CMD_ANGLE); // Send command to device(s) + return _read(AS_CMD_NOP); // Read-out device(s) +} + +const int* As5048Spi::read_angle_sequential() +{ + return _read(AS_CMD_ANGLE); +} + + +int* As5048Spi::_read(As5048Command command) +{ + if(_nDevices == 1) + { + // Give command to start reading the angle + _chipSelectN.write(0); + wait_us(1); // Wait at least 350ns after chip select + _readBuffer[0] = _spi.write(command); + _chipSelectN.write(1); + wait_us(1); // Wait at least 350ns after chip select + } else + { + // Enable the sensor on the chain + _chipSelectN.write(0); + wait_us(1); // Wait at least 350ns after chip select + for(int i = 0; i < _nDevices; ++i) + { + _readBuffer[i] = _spi.write(command); + } + _chipSelectN.write(1); + wait_us(1); // Wait at least 350ns after chip select + } + return _readBuffer; +} + +
diff -r 000000000000 -r 5a1830df0b66 as5048spi.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/as5048spi.h Tue Oct 08 14:59:11 2019 +0000 @@ -0,0 +1,85 @@ +#include "mbed.h" +typedef enum { + AS_FLAG_PARITY = 0x8000, + AS_FLAG_READ = 0x4000, +} As5048Flag; + +typedef enum { + AS_CMD_NOP = 0x0000, + AS_CMD_ERROR = 0x0001 | AS_FLAG_READ, // Reads error register of sensor and clear error flags + AS_CMD_DIAGNOSTICS = 0x3FFD | AS_FLAG_READ, // Reads automatic gain control and diagnostics info + AS_CMD_MAGNITUDE = 0x3FFE | AS_FLAG_READ, + + AS_CMD_ANGLE = 0x3FFF| AS_FLAG_PARITY | AS_FLAG_READ, +} As5048Command; + +// Masks for bits in the result of the AS_CMD_DIAGNOSTICS command +typedef enum { + AS_DIAG_CORDIC_OVERFLOW = 0x0200, + AS_DIAG_HIGH_MAGNETIC = 0x0400, + AS_DIAG_LOW_MAGNETIC = 0x0800, +} As5048Diagnostics; + + +//! Class for interfacing with the AMS AS5048A magnetic rotary sensor over the SPI-interface. +class As5048Spi +{ +public: + As5048Spi(PinName mosi, PinName miso, PinName sclk, PinName chipselect, int nDevices = 1); + ~As5048Spi(); + + bool error(int device = -1); + + /// Sets the SPI clock frequency in Hz. Maximum tested frequency is 10MHz. + void frequency(int frequency = 1000000); + + /// Sends a read command to the sensor. + const int* read(As5048Command command); + + /// Sends a read command to the sensor. + /// A call to this function will not directly return the requested value. The + /// requested value will be returned in a next read_sequential call. + /// Use this function to read sensor values with minimum speed impact on SPI-bus + /// and microcontroller. + const int* read_sequential(As5048Command command); + + /// Performs a single angle measurement on all sensors + /// @return Array of raw angle data. To get the 14-bit value representing + /// the angle, apply the mask() to the result. + const int* read_angle(); + + /// Performs sequential angle measurements on all sensors. The first time this + /// method is called the result is not usefull, the measurement data of the call + /// will be returned by the next call to this method. + /// @return Array of raw angle data. To get the 14-bit value representing + /// the angle, apply the mask() to the result. + const int* read_angle_sequential(); + + /// Returns lowest 14-bits + static int mask(int sensor_result); + + /// Applies the mask to the first n bytes in the read buffer (for daisychained sensors). + static void mask(int* sensor_results, int n); + + /// Checks if the return value from the sensor has the right parity + /// @return true if ok + static bool parity_check(int sensor_result); + + /// Returns an angle from 0 to 36000 (degrees times 100). + /// @param sensor_result is one of the values returned by read_angle or read_angle_sequential + static int degrees(int sensor_result); + + /// Returns an angle from 0 to 2*PI*100 + /// @param sensor_result is one of the values returned by read_angle or read_angle_sequential + static int radian(int sensor_result); + + +protected: + int _nDevices; + DigitalOut _chipSelectN; + SPI _spi; + + int* _readBuffer; // Stores the results of the last sequential read + + int* _read(As5048Command command); +};
diff -r 000000000000 -r 5a1830df0b66 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Oct 08 14:59:11 2019 +0000 @@ -0,0 +1,47 @@ +#include "mbed.h" +#include "as5048spi.h" + +#define rayon_roue 0.0045 +#define pi 3.14159 + +#define intervalle 0.005 + +As5048Spi sensor(PB_15, PB_14, PB_13, PB_12); //MOSI, MISO, SCKL, CS +Serial pc(USBTX, USBRX); // tx, rx +InterruptIn bouton(PC_13); +Ticker timer; +int angle, degrees_avant, degrees_maintenant, degrees_vitesse; +float vitesse; + +void donnee_saisie() +{ + const int* angles = sensor.read_angle(); + angle = angles[0]; + //Récupération de l'angle précédent + degrees_avant = degrees_maintenant; + + //Aquisition du nouvel angle + degrees_maintenant = sensor.degrees(angle)/100; + + //Calcul de la différence + degrees_vitesse = (degrees_maintenant - degrees_avant) / intervalle; + + vitesse = (rayon_roue * degrees_vitesse * 2 * pi / 360) /*/ (5 + 0.01 / (2 * pi))*/; +} + +void print_speed() +{ + timer.detach(); + //Affichage du résultat + pc.printf("rotation = %d degrees/s, vitesse = %.4f mm/s \r", degrees_vitesse, vitesse * 1000); + timer.attach(&donnee_saisie, intervalle); //Lancement de la fonction "donnee_saisie()" toutes les 1 sec +} + +int main() { + bouton.rise(&print_speed); + timer.attach(&donnee_saisie, intervalle); //Lancement de la fonction "donnee_saisie()" toutes les 1 sec + while(1) + { + + } +} \ No newline at end of file
diff -r 000000000000 -r 5a1830df0b66 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Oct 08 14:59:11 2019 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file