Same as mallet... but distance
Dependencies: EthernetInterface NetworkAPI mbed-rtos mbed
Fork of MalletFirmware by
AngleEncoder.cpp@30:1da0bb9c31a6, 2014-12-09 (annotated)
- Committer:
- willange
- Date:
- Tue Dec 09 17:37:12 2014 +0000
- Revision:
- 30:1da0bb9c31a6
- Parent:
- 22:523e316cbe70
a basic timer
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
timmey9 | 22:523e316cbe70 | 1 | #include "AngleEncoder.h" |
timmey9 | 22:523e316cbe70 | 2 | #include "mbed.h" |
timmey9 | 22:523e316cbe70 | 3 | |
timmey9 | 22:523e316cbe70 | 4 | AngleEncoder::AngleEncoder(PinName mosi, PinName miso, PinName sclk, PinName cs, int bits, int mode, int hz) : |
timmey9 | 22:523e316cbe70 | 5 | _spi(mosi, miso, sclk), |
timmey9 | 22:523e316cbe70 | 6 | _cs(cs) { |
timmey9 | 22:523e316cbe70 | 7 | // constructor |
timmey9 | 22:523e316cbe70 | 8 | _cs = 1; |
timmey9 | 22:523e316cbe70 | 9 | _spi.format(bits,mode); |
timmey9 | 22:523e316cbe70 | 10 | _spi.frequency(hz); |
timmey9 | 22:523e316cbe70 | 11 | |
timmey9 | 22:523e316cbe70 | 12 | wait_ms(1000); // Angle encoder requires 0.1 seconds to boot up, so I gave it an entire second. |
timmey9 | 22:523e316cbe70 | 13 | |
timmey9 | 22:523e316cbe70 | 14 | } |
timmey9 | 22:523e316cbe70 | 15 | |
timmey9 | 22:523e316cbe70 | 16 | |
timmey9 | 22:523e316cbe70 | 17 | |
timmey9 | 22:523e316cbe70 | 18 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
timmey9 | 22:523e316cbe70 | 19 | * |
timmey9 | 22:523e316cbe70 | 20 | * Sends a NOP command. This is a read command. |
timmey9 | 22:523e316cbe70 | 21 | * |
timmey9 | 22:523e316cbe70 | 22 | * Returns the 8 bit data read from the encoder. |
timmey9 | 22:523e316cbe70 | 23 | * 0xA5 indicates communication is good, but no data to receive from encoder |
timmey9 | 22:523e316cbe70 | 24 | * |
timmey9 | 22:523e316cbe70 | 25 | * 0x00 indicates that angle encoder probably wasn't read. May need to |
timmey9 | 22:523e316cbe70 | 26 | * increase SPI_DELAY |
timmey9 | 22:523e316cbe70 | 27 | * |
timmey9 | 22:523e316cbe70 | 28 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
timmey9 | 22:523e316cbe70 | 29 | int AngleEncoder::nop() { // this function takes about 90us to complete (tested using Timer library) |
timmey9 | 22:523e316cbe70 | 30 | _cs = 0; |
timmey9 | 22:523e316cbe70 | 31 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 32 | int received = _spi.write(0x00); |
timmey9 | 22:523e316cbe70 | 33 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 34 | _cs = 1; |
timmey9 | 22:523e316cbe70 | 35 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 36 | return received; |
timmey9 | 22:523e316cbe70 | 37 | } |
timmey9 | 22:523e316cbe70 | 38 | |
timmey9 | 22:523e316cbe70 | 39 | |
timmey9 | 22:523e316cbe70 | 40 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
timmey9 | 22:523e316cbe70 | 41 | * |
timmey9 | 22:523e316cbe70 | 42 | * Sets the current position as the zero point from which angles are calculated |
timmey9 | 22:523e316cbe70 | 43 | * |
timmey9 | 22:523e316cbe70 | 44 | * Returns true if successful, false otherwise |
timmey9 | 22:523e316cbe70 | 45 | * |
timmey9 | 22:523e316cbe70 | 46 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
timmey9 | 22:523e316cbe70 | 47 | bool AngleEncoder::set_zero() { |
timmey9 | 22:523e316cbe70 | 48 | char received; |
timmey9 | 22:523e316cbe70 | 49 | |
timmey9 | 22:523e316cbe70 | 50 | // send "set_zero_point" command |
timmey9 | 22:523e316cbe70 | 51 | _cs = 0; |
timmey9 | 22:523e316cbe70 | 52 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 53 | received = _spi.write(0x70); // send the command |
timmey9 | 22:523e316cbe70 | 54 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 55 | _cs = 1; |
timmey9 | 22:523e316cbe70 | 56 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 57 | |
timmey9 | 22:523e316cbe70 | 58 | // send NOP until reset is confirmed |
timmey9 | 22:523e316cbe70 | 59 | while(received == 0xa5) received = nop(); |
timmey9 | 22:523e316cbe70 | 60 | |
timmey9 | 22:523e316cbe70 | 61 | // 0x80 indicates that reset is confirmed |
timmey9 | 22:523e316cbe70 | 62 | if(received == 0x80) return true; |
timmey9 | 22:523e316cbe70 | 63 | else return false; |
timmey9 | 22:523e316cbe70 | 64 | } |
timmey9 | 22:523e316cbe70 | 65 | |
timmey9 | 22:523e316cbe70 | 66 | |
timmey9 | 22:523e316cbe70 | 67 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
timmey9 | 22:523e316cbe70 | 68 | * |
timmey9 | 22:523e316cbe70 | 69 | * Sets the current position as the zero point from which angles are calculated |
timmey9 | 22:523e316cbe70 | 70 | * @param rotary_count The address to the rotary_count variable, allowing this |
timmey9 | 22:523e316cbe70 | 71 | * function to reset both the absolute and relative angles. |
timmey9 | 22:523e316cbe70 | 72 | * |
timmey9 | 22:523e316cbe70 | 73 | * Returns true if successful, false otherwise |
timmey9 | 22:523e316cbe70 | 74 | * |
timmey9 | 22:523e316cbe70 | 75 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
timmey9 | 22:523e316cbe70 | 76 | bool AngleEncoder::set_zero(int* rotary_count) { |
timmey9 | 22:523e316cbe70 | 77 | |
timmey9 | 22:523e316cbe70 | 78 | *rotary_count = 0; // reset relative counter |
timmey9 | 22:523e316cbe70 | 79 | return set_zero(); // reset absolute counter |
timmey9 | 22:523e316cbe70 | 80 | } |
timmey9 | 22:523e316cbe70 | 81 | |
timmey9 | 22:523e316cbe70 | 82 | |
timmey9 | 22:523e316cbe70 | 83 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
timmey9 | 22:523e316cbe70 | 84 | * |
timmey9 | 22:523e316cbe70 | 85 | * Reads the absolute angle from the angle encoder via SPI |
timmey9 | 22:523e316cbe70 | 86 | * Returns the 12 bit angle (-2048, 2047) |
timmey9 | 22:523e316cbe70 | 87 | * |
timmey9 | 22:523e316cbe70 | 88 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
timmey9 | 22:523e316cbe70 | 89 | int AngleEncoder::absolute_angle() { // this function takes about 500us to complete (tested using Timer library) |
timmey9 | 22:523e316cbe70 | 90 | char received; |
timmey9 | 22:523e316cbe70 | 91 | uint16_t absolute_pos; |
timmey9 | 22:523e316cbe70 | 92 | |
timmey9 | 22:523e316cbe70 | 93 | // send read command |
timmey9 | 22:523e316cbe70 | 94 | _cs = 0; |
timmey9 | 22:523e316cbe70 | 95 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 96 | received = _spi.write(0x10); |
timmey9 | 22:523e316cbe70 | 97 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 98 | _cs = 1; |
timmey9 | 22:523e316cbe70 | 99 | |
timmey9 | 22:523e316cbe70 | 100 | // wait for angle encoder to echo the command |
timmey9 | 22:523e316cbe70 | 101 | wait_us(SPI_DELAY); |
timmey9 | 22:523e316cbe70 | 102 | |
timmey9 | 22:523e316cbe70 | 103 | // read until encoder sends 0x10 |
timmey9 | 22:523e316cbe70 | 104 | for(uint32_t i = 0; i < 100; i++) |
timmey9 | 22:523e316cbe70 | 105 | { |
timmey9 | 22:523e316cbe70 | 106 | received = nop(); |
timmey9 | 22:523e316cbe70 | 107 | if(received == 0x10) break; |
timmey9 | 22:523e316cbe70 | 108 | } |
timmey9 | 22:523e316cbe70 | 109 | |
timmey9 | 22:523e316cbe70 | 110 | //while(received != 0x10) received = nop(); // read until 0x10 is received |
timmey9 | 22:523e316cbe70 | 111 | |
timmey9 | 22:523e316cbe70 | 112 | // the command should have been echoed back. If so, then read the angle |
timmey9 | 22:523e316cbe70 | 113 | if(received == 0x10) |
timmey9 | 22:523e316cbe70 | 114 | { |
timmey9 | 22:523e316cbe70 | 115 | // receive the most significatn 4 bits of the 12 bit angle |
timmey9 | 22:523e316cbe70 | 116 | absolute_pos = nop(); // read first 4 bits of absolute angle |
timmey9 | 22:523e316cbe70 | 117 | absolute_pos <<= 8; // shift the 4 bits into the right spot |
timmey9 | 22:523e316cbe70 | 118 | absolute_pos |= nop(); // receive the last 8 bits of absolute angle |
timmey9 | 22:523e316cbe70 | 119 | |
timmey9 | 22:523e316cbe70 | 120 | //make data symmetric around 0. |
timmey9 | 22:523e316cbe70 | 121 | //if(absolute_pos > 2048) absolute_pos -= 4096; |
timmey9 | 22:523e316cbe70 | 122 | //absolute_pos = ~absolute_pos + 1; // inverts the data |
timmey9 | 22:523e316cbe70 | 123 | return absolute_pos; |
timmey9 | 22:523e316cbe70 | 124 | } |
timmey9 | 22:523e316cbe70 | 125 | else return 0x00ff0000; // this is just a random number outside of the range of the encoder |
timmey9 | 22:523e316cbe70 | 126 | } |