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