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.
Dependencies: mbed
Fork of Chemical_Sensor_DMA by
Diff: AngleEncoder.cpp
- Revision:
- 2:3771b3195c7b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AngleEncoder.cpp Thu Oct 29 17:15:20 2015 +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 +}