Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of DSP_200kHz by
Diff: AngleEncoder.cpp
- Revision:
- 22:523e316cbe70
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AngleEncoder.cpp Wed Dec 03 05:30:45 2014 +0000 @@ -0,0 +1,126 @@ +#include "AngleEncoder.h" +#include "mbed.h" + +AngleEncoder::AngleEncoder(PinName mosi, PinName miso, PinName sclk, PinName cs, int bits, int mode, int hz) : + _spi(mosi, miso, sclk), + _cs(cs) { + // constructor + _cs = 1; + _spi.format(bits,mode); + _spi.frequency(hz); + + wait_ms(1000); // Angle encoder requires 0.1 seconds to boot up, so I gave it an entire second. + +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Sends a NOP command. This is a read command. + * + * Returns the 8 bit data read from the encoder. + * 0xA5 indicates communication is good, but no data to receive from encoder + * + * 0x00 indicates that angle encoder probably wasn't read. May need to + * increase SPI_DELAY + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int AngleEncoder::nop() { // this function takes about 90us to complete (tested using Timer library) + _cs = 0; + wait_us(SPI_DELAY); + int received = _spi.write(0x00); + wait_us(SPI_DELAY); + _cs = 1; + wait_us(SPI_DELAY); + return received; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Sets the current position as the zero point from which angles are calculated + * + * Returns true if successful, false otherwise + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +bool AngleEncoder::set_zero() { + char received; + + // send "set_zero_point" command + _cs = 0; + wait_us(SPI_DELAY); + received = _spi.write(0x70); // send the command + wait_us(SPI_DELAY); + _cs = 1; + wait_us(SPI_DELAY); + + // send NOP until reset is confirmed + while(received == 0xa5) received = nop(); + + // 0x80 indicates that reset is confirmed + if(received == 0x80) return true; + else return false; +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Sets the current position as the zero point from which angles are calculated + * @param rotary_count The address to the rotary_count variable, allowing this + * function to reset both the absolute and relative angles. + * + * Returns true if successful, false otherwise + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +bool AngleEncoder::set_zero(int* rotary_count) { + + *rotary_count = 0; // reset relative counter + return set_zero(); // reset absolute counter +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Reads the absolute angle from the angle encoder via SPI + * Returns the 12 bit angle (-2048, 2047) + * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +int AngleEncoder::absolute_angle() { // this function takes about 500us to complete (tested using Timer library) + char received; + uint16_t absolute_pos; + + // send read command + _cs = 0; + wait_us(SPI_DELAY); + received = _spi.write(0x10); + wait_us(SPI_DELAY); + _cs = 1; + + // wait for angle encoder to echo the command + wait_us(SPI_DELAY); + + // read until encoder sends 0x10 + for(uint32_t i = 0; i < 100; i++) + { + received = nop(); + if(received == 0x10) break; + } + + //while(received != 0x10) received = nop(); // read until 0x10 is received + + // the command should have been echoed back. If so, then read the angle + if(received == 0x10) + { + // receive the most significatn 4 bits of the 12 bit angle + absolute_pos = nop(); // read first 4 bits of absolute angle + absolute_pos <<= 8; // shift the 4 bits into the right spot + absolute_pos |= nop(); // receive the last 8 bits of absolute angle + + //make data symmetric around 0. + //if(absolute_pos > 2048) absolute_pos -= 4096; + //absolute_pos = ~absolute_pos + 1; // inverts the data + return absolute_pos; + } + else return 0x00ff0000; // this is just a random number outside of the range of the encoder +}