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: EthernetInterface NetworkAPI mbed-rtos mbed
Fork of MalletFirmware by
AngleEncoder.cpp
- Committer:
- timmey9
- Date:
- 2014-12-03
- Revision:
- 22:523e316cbe70
File content as of revision 22:523e316cbe70:
#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
}
