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
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
+}
