Michael Ernst Peter / PM2_Libary

Dependencies:   LSM9DS1 RangeFinder FastPWM

Dependents:   PM2_Example_PES_board PM2_Example_PES_board PM2_Example_PES_board PM2_Example_PES_board ... more

Committer:
pmic
Date:
Thu May 05 07:40:34 2022 +0000
Revision:
24:f2614d8577a1
Child:
25:51e92f2c89e2
Included SensorBar and AvgFilter (not finished yet)

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pmic 24:f2614d8577a1 1 #include "SensorBar.h"
pmic 24:f2614d8577a1 2
pmic 24:f2614d8577a1 3 const float SensorBar::TS = 0.004f; // period of 1 ms
pmic 24:f2614d8577a1 4
pmic 24:f2614d8577a1 5 const char REG_I_ON[16] = {REG_I_ON_0, REG_I_ON_1, REG_I_ON_2, REG_I_ON_3,
pmic 24:f2614d8577a1 6 REG_I_ON_4, REG_I_ON_5, REG_I_ON_6, REG_I_ON_7,
pmic 24:f2614d8577a1 7 REG_I_ON_8, REG_I_ON_9, REG_I_ON_10, REG_I_ON_11,
pmic 24:f2614d8577a1 8 REG_I_ON_12, REG_I_ON_13, REG_I_ON_14, REG_I_ON_15};
pmic 24:f2614d8577a1 9
pmic 24:f2614d8577a1 10 const char REG_T_ON[16] = {REG_T_ON_0, REG_T_ON_1, REG_T_ON_2, REG_T_ON_3,
pmic 24:f2614d8577a1 11 REG_T_ON_4, REG_T_ON_5, REG_T_ON_6, REG_T_ON_7,
pmic 24:f2614d8577a1 12 REG_T_ON_8, REG_T_ON_9, REG_T_ON_10, REG_T_ON_11,
pmic 24:f2614d8577a1 13 REG_T_ON_12, REG_T_ON_13, REG_T_ON_14, REG_T_ON_15};
pmic 24:f2614d8577a1 14
pmic 24:f2614d8577a1 15 const char REG_OFF[16] = {REG_OFF_0, REG_OFF_1, REG_OFF_2, REG_OFF_3,
pmic 24:f2614d8577a1 16 REG_OFF_4, REG_OFF_5, REG_OFF_6, REG_OFF_7,
pmic 24:f2614d8577a1 17 REG_OFF_8, REG_OFF_9, REG_OFF_10, REG_OFF_11,
pmic 24:f2614d8577a1 18 REG_OFF_12, REG_OFF_13, REG_OFF_14, REG_OFF_15};
pmic 24:f2614d8577a1 19
pmic 24:f2614d8577a1 20 const char REG_T_RISE[16] = {0xFF, 0xFF, 0xFF, 0xFF,
pmic 24:f2614d8577a1 21 REG_T_RISE_4, REG_T_RISE_5, REG_T_RISE_6, REG_T_RISE_7,
pmic 24:f2614d8577a1 22 0xFF, 0xFF, 0xFF, 0xFF,
pmic 24:f2614d8577a1 23 REG_T_RISE_12, REG_T_RISE_13, REG_T_RISE_14, REG_T_RISE_15};
pmic 24:f2614d8577a1 24
pmic 24:f2614d8577a1 25 const char REG_T_FALL[16] = {0xFF, 0xFF, 0xFF, 0xFF,
pmic 24:f2614d8577a1 26 REG_T_FALL_4, REG_T_FALL_5, REG_T_FALL_6, REG_T_FALL_7,
pmic 24:f2614d8577a1 27 0xFF, 0xFF, 0xFF, 0xFF,
pmic 24:f2614d8577a1 28 REG_T_FALL_12, REG_T_FALL_13, REG_T_FALL_14, REG_T_FALL_15};
pmic 24:f2614d8577a1 29
pmic 24:f2614d8577a1 30 SensorBar::SensorBar(I2C& i2c, float distAxisToSensor) : i2c(i2c), thread(osPriorityAboveNormal, 4096)
pmic 24:f2614d8577a1 31 {
pmic 24:f2614d8577a1 32 // Store the received parameters into member variables
pmic 24:f2614d8577a1 33 deviceAddress = 0x3E<<1;
pmic 24:f2614d8577a1 34 pinInterrupt = 255;
pmic 24:f2614d8577a1 35 pinOscillator = 255;
pmic 24:f2614d8577a1 36 pinReset = 255;
pmic 24:f2614d8577a1 37 invertBits = 0;
pmic 24:f2614d8577a1 38 barStrobe = 0; //Default always on
pmic 24:f2614d8577a1 39
pmic 24:f2614d8577a1 40 this->distAxisToSensor = distAxisToSensor;
pmic 24:f2614d8577a1 41 lastBarRawValue = lastBarPositionValue = 0;
pmic 24:f2614d8577a1 42
pmic 24:f2614d8577a1 43 clearBarStrobe(); // to illuminate all the time
pmic 24:f2614d8577a1 44 clearInvertBits(); // to make the bar look for a dark line on a reflective surface
pmic 24:f2614d8577a1 45 begin();
pmic 24:f2614d8577a1 46
pmic 24:f2614d8577a1 47 // set up thread
pmic 24:f2614d8577a1 48 thread.start(callback(this, &SensorBar::update));
pmic 24:f2614d8577a1 49 ticker.attach(callback(this, &SensorBar::sendThreadFlag), std::chrono::microseconds{static_cast<long int>(1.0e6f * TS)});
pmic 24:f2614d8577a1 50 }
pmic 24:f2614d8577a1 51
pmic 24:f2614d8577a1 52 SensorBar::~SensorBar()
pmic 24:f2614d8577a1 53 {
pmic 24:f2614d8577a1 54 ticker.detach();
pmic 24:f2614d8577a1 55 }
pmic 24:f2614d8577a1 56
pmic 24:f2614d8577a1 57 // --- Functions pulled from the SX1509 driver
pmic 24:f2614d8577a1 58
pmic 24:f2614d8577a1 59 /*
pmic 24:f2614d8577a1 60 void SensorBar::debounceConfig(uint8_t configValue)
pmic 24:f2614d8577a1 61 {
pmic 24:f2614d8577a1 62 // First make sure clock is configured
pmic 24:f2614d8577a1 63 uint8_t tempuint8_t = readByte(REG_MISC);
pmic 24:f2614d8577a1 64 if ((tempuint8_t & 0x70) == 0) {
pmic 24:f2614d8577a1 65 tempuint8_t |= (1 << 4); // Just default to no divider if not set
pmic 24:f2614d8577a1 66 writeByte(REG_MISC, tempuint8_t);
pmic 24:f2614d8577a1 67 }
pmic 24:f2614d8577a1 68 tempuint8_t = readByte(REG_CLOCK);
pmic 24:f2614d8577a1 69 if ((tempuint8_t & 0x60) == 0) {
pmic 24:f2614d8577a1 70 tempuint8_t |= (1 << 6); // default to internal osc.
pmic 24:f2614d8577a1 71 writeByte(REG_CLOCK, tempuint8_t);
pmic 24:f2614d8577a1 72 }
pmic 24:f2614d8577a1 73
pmic 24:f2614d8577a1 74 configValue &= 0b111; // 3-bit value
pmic 24:f2614d8577a1 75 writeByte(REG_DEBOUNCE_CONFIG, configValue);
pmic 24:f2614d8577a1 76 }
pmic 24:f2614d8577a1 77
pmic 24:f2614d8577a1 78 void SensorBar::debounceEnable(uint8_t pin)
pmic 24:f2614d8577a1 79 {
pmic 24:f2614d8577a1 80 unsigned int debounceEnable = readWord(REG_DEBOUNCE_ENABLE_B);
pmic 24:f2614d8577a1 81 debounceEnable |= (1 << pin);
pmic 24:f2614d8577a1 82 writeWord(REG_DEBOUNCE_ENABLE_B, debounceEnable);
pmic 24:f2614d8577a1 83 }
pmic 24:f2614d8577a1 84
pmic 24:f2614d8577a1 85 unsigned int SensorBar::interruptSource(void)
pmic 24:f2614d8577a1 86 {
pmic 24:f2614d8577a1 87 unsigned int intSource = readWord(REG_INTERRUPT_SOURCE_B);
pmic 24:f2614d8577a1 88 writeWord(REG_INTERRUPT_SOURCE_B, 0xFFFF); // Clear interrupts
pmic 24:f2614d8577a1 89 return intSource;
pmic 24:f2614d8577a1 90 }
pmic 24:f2614d8577a1 91
pmic 24:f2614d8577a1 92 void SensorBar::configClock(uint8_t oscSource, uint8_t oscPinFunction, uint8_t oscFreqOut, uint8_t oscDivider)
pmic 24:f2614d8577a1 93 {
pmic 24:f2614d8577a1 94 // RegClock constructed as follows:
pmic 24:f2614d8577a1 95 // 6:5 - Oscillator frequency souce
pmic 24:f2614d8577a1 96 // 00: off, 01: external input, 10: internal 2MHz, 1: reserved
pmic 24:f2614d8577a1 97 // 4 - OSCIO pin function
pmic 24:f2614d8577a1 98 // 0: input, 1 ouptut
pmic 24:f2614d8577a1 99 // 3:0 - Frequency of oscout pin
pmic 24:f2614d8577a1 100 // 0: LOW, 0xF: high, else fOSCOUT = FoSC/(2^(RegClock[3:0]-1))
pmic 24:f2614d8577a1 101 oscSource = (oscSource & 0b11) << 5; // 2-bit value, bits 6:5
pmic 24:f2614d8577a1 102 oscPinFunction = (oscPinFunction & 1) << 4; // 1-bit value bit 4
pmic 24:f2614d8577a1 103 oscFreqOut = (oscFreqOut & 0b1111); // 4-bit value, bits 3:0
pmic 24:f2614d8577a1 104 uint8_t regClock = oscSource | oscPinFunction | oscFreqOut;
pmic 24:f2614d8577a1 105 writeByte(REG_CLOCK, regClock);
pmic 24:f2614d8577a1 106
pmic 24:f2614d8577a1 107 // Config RegMisc[6:4] with oscDivider
pmic 24:f2614d8577a1 108 // 0: off, else ClkX = fOSC / (2^(RegMisc[6:4] -1))
pmic 24:f2614d8577a1 109 oscDivider = (oscDivider & 0b111) << 4; // 3-bit value, bits 6:4
pmic 24:f2614d8577a1 110 uint8_t regMisc = readByte(REG_MISC);
pmic 24:f2614d8577a1 111 regMisc &= ~(0b111 << 4);
pmic 24:f2614d8577a1 112 regMisc |= oscDivider;
pmic 24:f2614d8577a1 113 writeByte(REG_MISC, regMisc);
pmic 24:f2614d8577a1 114 }
pmic 24:f2614d8577a1 115 */
pmic 24:f2614d8577a1 116
pmic 24:f2614d8577a1 117 //Call .setBarStrobing(); to only illuminate while reading line
pmic 24:f2614d8577a1 118 void SensorBar::setBarStrobe()
pmic 24:f2614d8577a1 119 {
pmic 24:f2614d8577a1 120 barStrobe = 1; //Do strobe
pmic 24:f2614d8577a1 121 }
pmic 24:f2614d8577a1 122
pmic 24:f2614d8577a1 123 //Call .clearBarStrobing(); to illuminate all the time
pmic 24:f2614d8577a1 124 void SensorBar::clearBarStrobe()
pmic 24:f2614d8577a1 125 {
pmic 24:f2614d8577a1 126 barStrobe = 0; //Always on
pmic 24:f2614d8577a1 127 }
pmic 24:f2614d8577a1 128
pmic 24:f2614d8577a1 129 // .setInvertBits(); to make the bar functions look for a white line on dark surface
pmic 24:f2614d8577a1 130 void SensorBar::setInvertBits()
pmic 24:f2614d8577a1 131 {
pmic 24:f2614d8577a1 132 invertBits = 1; //Do strobe
pmic 24:f2614d8577a1 133 }
pmic 24:f2614d8577a1 134
pmic 24:f2614d8577a1 135 // .clearInvertBits(); to make the bar look for a dark line on a reflective surface
pmic 24:f2614d8577a1 136 void SensorBar::clearInvertBits()
pmic 24:f2614d8577a1 137 {
pmic 24:f2614d8577a1 138 invertBits = 0; //Always on
pmic 24:f2614d8577a1 139 }
pmic 24:f2614d8577a1 140
pmic 24:f2614d8577a1 141 //****************************************************************************//
pmic 24:f2614d8577a1 142 //
pmic 24:f2614d8577a1 143 // Bar functions
pmic 24:f2614d8577a1 144 //
pmic 24:f2614d8577a1 145 //****************************************************************************//
pmic 24:f2614d8577a1 146
pmic 24:f2614d8577a1 147 uint8_t SensorBar::getRaw()
pmic 24:f2614d8577a1 148 {
pmic 24:f2614d8577a1 149 return lastBarRawValue;
pmic 24:f2614d8577a1 150 }
pmic 24:f2614d8577a1 151
pmic 24:f2614d8577a1 152 int8_t SensorBar::getBinaryPosition()
pmic 24:f2614d8577a1 153 {
pmic 24:f2614d8577a1 154 return lastBarPositionValue;
pmic 24:f2614d8577a1 155 }
pmic 24:f2614d8577a1 156
pmic 24:f2614d8577a1 157 float SensorBar::getAngleRad()
pmic 24:f2614d8577a1 158 {
pmic 24:f2614d8577a1 159 int8_t binaryPosition = getBinaryPosition();
pmic 24:f2614d8577a1 160 float position = static_cast<float>(binaryPosition) / 127.0f * 0.0445f; // 0.0445 m is half of sensor length
pmic 24:f2614d8577a1 161 return atan2f(position, distAxisToSensor);
pmic 24:f2614d8577a1 162 }
pmic 24:f2614d8577a1 163
pmic 24:f2614d8577a1 164 uint8_t SensorBar::getNrofLedsActive()
pmic 24:f2614d8577a1 165 {
pmic 24:f2614d8577a1 166 uint8_t bitsCounted = 0;
pmic 24:f2614d8577a1 167 uint8_t i;
pmic 24:f2614d8577a1 168
pmic 24:f2614d8577a1 169 //count bits
pmic 24:f2614d8577a1 170 for ( i = 0; i < 8; i++ ) {
pmic 24:f2614d8577a1 171 if ( ((lastBarRawValue >> i) & 0x01) == 1 ) {
pmic 24:f2614d8577a1 172 bitsCounted++;
pmic 24:f2614d8577a1 173 }
pmic 24:f2614d8577a1 174 }
pmic 24:f2614d8577a1 175 return bitsCounted;
pmic 24:f2614d8577a1 176 }
pmic 24:f2614d8577a1 177
pmic 24:f2614d8577a1 178
pmic 24:f2614d8577a1 179 //****************************************************************************//
pmic 24:f2614d8577a1 180 //
pmic 24:f2614d8577a1 181 // Utilities
pmic 24:f2614d8577a1 182 //
pmic 24:f2614d8577a1 183 //****************************************************************************//
pmic 24:f2614d8577a1 184
pmic 24:f2614d8577a1 185 //Run this once during initialization to configure the SX1509 as a sensor bar
pmic 24:f2614d8577a1 186 //Returns 1 for success
pmic 24:f2614d8577a1 187 uint8_t SensorBar::begin(void)
pmic 24:f2614d8577a1 188 {
pmic 24:f2614d8577a1 189 uint8_t returnVar = 0;
pmic 24:f2614d8577a1 190
pmic 24:f2614d8577a1 191 // Reset the SX1509
pmic 24:f2614d8577a1 192 reset();
pmic 24:f2614d8577a1 193
pmic 24:f2614d8577a1 194 // Communication test. We'll read from two registers with different
pmic 24:f2614d8577a1 195 // default values to verify communication.
pmic 24:f2614d8577a1 196 unsigned int testRegisters = 0;
pmic 24:f2614d8577a1 197 testRegisters = readWord(REG_INTERRUPT_MASK_A); // This should return 0xFF00
pmic 24:f2614d8577a1 198 // Then read a uint8_t that should be 0x00
pmic 24:f2614d8577a1 199 if (testRegisters == 0xFF00) {
pmic 24:f2614d8577a1 200 //Success! Configure the device.
pmic 24:f2614d8577a1 201 writeByte(REG_DIR_A, 0xFF);
pmic 24:f2614d8577a1 202 writeByte(REG_DIR_B, 0xFC);
pmic 24:f2614d8577a1 203 writeByte(REG_DATA_B, 0x01);
pmic 24:f2614d8577a1 204
pmic 24:f2614d8577a1 205 returnVar = 1;
pmic 24:f2614d8577a1 206 } else {
pmic 24:f2614d8577a1 207 returnVar = 0;
pmic 24:f2614d8577a1 208 }
pmic 24:f2614d8577a1 209
pmic 24:f2614d8577a1 210 return returnVar;
pmic 24:f2614d8577a1 211 }
pmic 24:f2614d8577a1 212
pmic 24:f2614d8577a1 213 // Do a software reset
pmic 24:f2614d8577a1 214 void SensorBar::reset()
pmic 24:f2614d8577a1 215 {
pmic 24:f2614d8577a1 216 // No hardware option, try software reset
pmic 24:f2614d8577a1 217 writeByte(REG_RESET, 0x12);
pmic 24:f2614d8577a1 218 writeByte(REG_RESET, 0x34);
pmic 24:f2614d8577a1 219 }
pmic 24:f2614d8577a1 220
pmic 24:f2614d8577a1 221 // readByte(uint8_t registerAddress)
pmic 24:f2614d8577a1 222 // This function reads a single uint8_t located at the registerAddress register.
pmic 24:f2614d8577a1 223 // - deviceAddress should already be set by the constructor.
pmic 24:f2614d8577a1 224 // - Return value is the uint8_t read from registerAddress
pmic 24:f2614d8577a1 225 //
pmic 24:f2614d8577a1 226 // Currently returns 0 if communication has timed out
pmic 24:f2614d8577a1 227 //
pmic 24:f2614d8577a1 228 uint8_t SensorBar::readByte(uint8_t registerAddress)
pmic 24:f2614d8577a1 229 {
pmic 24:f2614d8577a1 230 char readValue;
pmic 24:f2614d8577a1 231 char data[2] = {registerAddress, 0};
pmic 24:f2614d8577a1 232 i2c.write(deviceAddress, data, 1);
pmic 24:f2614d8577a1 233 uint8_t val = i2c.read(deviceAddress, &readValue, 1);
pmic 24:f2614d8577a1 234
pmic 24:f2614d8577a1 235 return readValue;
pmic 24:f2614d8577a1 236 }
pmic 24:f2614d8577a1 237
pmic 24:f2614d8577a1 238 // readWord(uint8_t registerAddress)
pmic 24:f2614d8577a1 239 // This function will read a two-uint8_t word beginning at registerAddress
pmic 24:f2614d8577a1 240 // - A 16-bit unsigned int will be returned.
pmic 24:f2614d8577a1 241 // - The msb of the return value will contain the value read from registerAddress
pmic 24:f2614d8577a1 242 // - The lsb of the return value will contain the value read from registerAddress + 1
pmic 24:f2614d8577a1 243 unsigned int SensorBar::readWord(uint8_t registerAddress)
pmic 24:f2614d8577a1 244 {
pmic 24:f2614d8577a1 245 unsigned int readValue;
pmic 24:f2614d8577a1 246 unsigned int msb, lsb;
pmic 24:f2614d8577a1 247 //unsigned int timeout = RECEIVE_TIMEOUT_VALUE * 2;
pmic 24:f2614d8577a1 248 char data[2] = {registerAddress, 0};
pmic 24:f2614d8577a1 249 char r_data[2];
pmic 24:f2614d8577a1 250 uint8_t val = i2c.write(deviceAddress, data, 1);
pmic 24:f2614d8577a1 251 val = i2c.read(deviceAddress, r_data, 2);
pmic 24:f2614d8577a1 252 msb = ((unsigned int)r_data[0] & 0x00FF) << 8;
pmic 24:f2614d8577a1 253 lsb = ((unsigned int)r_data[1] & 0x00FF);
pmic 24:f2614d8577a1 254 readValue = msb | lsb;
pmic 24:f2614d8577a1 255
pmic 24:f2614d8577a1 256 return readValue;
pmic 24:f2614d8577a1 257 }
pmic 24:f2614d8577a1 258
pmic 24:f2614d8577a1 259 // readBytes(uint8_t firstRegisterAddress, uint8_t * destination, uint8_t length)
pmic 24:f2614d8577a1 260 // This function reads a series of uint8_ts incrementing from a given address
pmic 24:f2614d8577a1 261 // - firstRegsiterAddress is the first address to be read
pmic 24:f2614d8577a1 262 // - destination is an array of uint8_ts where the read values will be stored into
pmic 24:f2614d8577a1 263 // - length is the number of uint8_ts to be read
pmic 24:f2614d8577a1 264 // - No return value.
pmic 24:f2614d8577a1 265 void SensorBar::readBytes(uint8_t firstRegisterAddress, char * destination, uint8_t length)
pmic 24:f2614d8577a1 266 {
pmic 24:f2614d8577a1 267 char data[2] = {firstRegisterAddress, 0};
pmic 24:f2614d8577a1 268 i2c.write(deviceAddress, data, 1);
pmic 24:f2614d8577a1 269 uint8_t val = i2c.read(deviceAddress, destination, length);
pmic 24:f2614d8577a1 270 }
pmic 24:f2614d8577a1 271
pmic 24:f2614d8577a1 272 // writeByte(uint8_t registerAddress, uint8_t writeValue)
pmic 24:f2614d8577a1 273 // This function writes a single uint8_t to a single register on the SX509.
pmic 24:f2614d8577a1 274 // - writeValue is written to registerAddress
pmic 24:f2614d8577a1 275 // - deviceAddres should already be set from the constructor
pmic 24:f2614d8577a1 276 // - No return value.
pmic 24:f2614d8577a1 277 void SensorBar::writeByte(uint8_t registerAddress, uint8_t writeValue)
pmic 24:f2614d8577a1 278 {
pmic 24:f2614d8577a1 279 char data[2] = {registerAddress, writeValue};
pmic 24:f2614d8577a1 280 i2c.write(deviceAddress, data, 2);
pmic 24:f2614d8577a1 281 }
pmic 24:f2614d8577a1 282
pmic 24:f2614d8577a1 283 // writeWord(uint8_t registerAddress, ungisnged int writeValue)
pmic 24:f2614d8577a1 284 // This function writes a two-uint8_t word to registerAddress and registerAddress + 1
pmic 24:f2614d8577a1 285 // - the upper uint8_t of writeValue is written to registerAddress
pmic 24:f2614d8577a1 286 // - the lower uint8_t of writeValue is written to registerAddress + 1
pmic 24:f2614d8577a1 287 // - No return value.
pmic 24:f2614d8577a1 288 void SensorBar::writeWord(uint8_t registerAddress, unsigned int writeValue)
pmic 24:f2614d8577a1 289 {
pmic 24:f2614d8577a1 290 uint8_t msb, lsb;
pmic 24:f2614d8577a1 291 msb = ((writeValue & 0xFF00) >> 8);
pmic 24:f2614d8577a1 292 lsb = (writeValue & 0x00FF);
pmic 24:f2614d8577a1 293 char data[3] = {registerAddress, msb, lsb};
pmic 24:f2614d8577a1 294 i2c.write(deviceAddress, data, 3);
pmic 24:f2614d8577a1 295 }
pmic 24:f2614d8577a1 296
pmic 24:f2614d8577a1 297 // writeBytes(uint8_t firstRegisterAddress, uint8_t * writeArray, uint8_t length)
pmic 24:f2614d8577a1 298 // This function writes an array of uint8_ts, beggining at a specific adddress
pmic 24:f2614d8577a1 299 // - firstRegisterAddress is the initial register to be written.
pmic 24:f2614d8577a1 300 // - All writes following will be at incremental register addresses.
pmic 24:f2614d8577a1 301 // - writeArray should be an array of uint8_t values to be written.
pmic 24:f2614d8577a1 302 // - length should be the number of uint8_ts to be written.
pmic 24:f2614d8577a1 303 // - no return value.
pmic 24:f2614d8577a1 304 void SensorBar::writeBytes(uint8_t firstRegisterAddress, uint8_t * writeArray, uint8_t length)
pmic 24:f2614d8577a1 305 {
pmic 24:f2614d8577a1 306 char data[10] = {};
pmic 24:f2614d8577a1 307 data[0] = firstRegisterAddress;
pmic 24:f2614d8577a1 308 for(int i = 0; i < length; i++) {
pmic 24:f2614d8577a1 309 data[1+i] = writeArray[i];
pmic 24:f2614d8577a1 310 }
pmic 24:f2614d8577a1 311 i2c.write(deviceAddress, data, length+1);
pmic 24:f2614d8577a1 312 }
pmic 24:f2614d8577a1 313
pmic 24:f2614d8577a1 314 void SensorBar::update()
pmic 24:f2614d8577a1 315 {
pmic 24:f2614d8577a1 316 while(true) {
pmic 24:f2614d8577a1 317 ThisThread::flags_wait_any(threadFlag);
pmic 24:f2614d8577a1 318
pmic 24:f2614d8577a1 319 //Assign values to each bit, -127 to 127, sum, and divide
pmic 24:f2614d8577a1 320 int16_t accumulator = 0;
pmic 24:f2614d8577a1 321 uint8_t bitsCounted = 0;
pmic 24:f2614d8577a1 322 int16_t i;
pmic 24:f2614d8577a1 323
pmic 24:f2614d8577a1 324 //Get the information from the wire, stores in lastBarRawValue
pmic 24:f2614d8577a1 325 if( barStrobe == 1 ) {
pmic 24:f2614d8577a1 326 writeByte(REG_DATA_B, 0x02); //Turn on IR
pmic 24:f2614d8577a1 327 thread_sleep_for(2); // wait_us(2000);
pmic 24:f2614d8577a1 328 writeByte(REG_DATA_B, 0x00); //Turn on feedback
pmic 24:f2614d8577a1 329 } else {
pmic 24:f2614d8577a1 330 writeByte(REG_DATA_B, 0x00); //make sure both IR and indicators are on
pmic 24:f2614d8577a1 331 }
pmic 24:f2614d8577a1 332 //Operate the I2C machine
pmic 24:f2614d8577a1 333 lastBarRawValue = readByte( REG_DATA_A ); //Peel the data off port A
pmic 24:f2614d8577a1 334
pmic 24:f2614d8577a1 335 if( invertBits == 1 ) { //Invert the bits if needed
pmic 24:f2614d8577a1 336 lastBarRawValue ^= 0xFF;
pmic 24:f2614d8577a1 337 }
pmic 24:f2614d8577a1 338
pmic 24:f2614d8577a1 339 if( barStrobe == 1 ) {
pmic 24:f2614d8577a1 340 writeByte(REG_DATA_B, 0x03); //Turn off IR and feedback when done
pmic 24:f2614d8577a1 341 }
pmic 24:f2614d8577a1 342
pmic 24:f2614d8577a1 343 //count bits
pmic 24:f2614d8577a1 344 for ( i = 0; i < 8; i++ ) {
pmic 24:f2614d8577a1 345 if ( ((lastBarRawValue >> i) & 0x01) == 1 ) {
pmic 24:f2614d8577a1 346 bitsCounted++;
pmic 24:f2614d8577a1 347 }
pmic 24:f2614d8577a1 348 }
pmic 24:f2614d8577a1 349
pmic 24:f2614d8577a1 350 //Find the vector value of each positive bit and sum
pmic 24:f2614d8577a1 351 for ( i = 7; i > 3; i-- ) { //iterate negative side bits
pmic 24:f2614d8577a1 352 if ( ((lastBarRawValue >> i) & 0x01) == 1 ) {
pmic 24:f2614d8577a1 353 accumulator += ((-32 * (i - 3)) + 1);
pmic 24:f2614d8577a1 354 }
pmic 24:f2614d8577a1 355 }
pmic 24:f2614d8577a1 356 for ( i = 0; i < 4; i++ ) { //iterate positive side bits
pmic 24:f2614d8577a1 357 if ( ((lastBarRawValue >> i) & 0x01) == 1 ) {
pmic 24:f2614d8577a1 358 accumulator += ((32 * (4 - i)) - 1);
pmic 24:f2614d8577a1 359 }
pmic 24:f2614d8577a1 360 }
pmic 24:f2614d8577a1 361
pmic 24:f2614d8577a1 362 if ( bitsCounted > 0 ) {
pmic 24:f2614d8577a1 363 lastBarPositionValue = accumulator / bitsCounted;
pmic 24:f2614d8577a1 364 } else {
pmic 24:f2614d8577a1 365 lastBarPositionValue = 0;
pmic 24:f2614d8577a1 366 }
pmic 24:f2614d8577a1 367 }
pmic 24:f2614d8577a1 368 }
pmic 24:f2614d8577a1 369
pmic 24:f2614d8577a1 370 void SensorBar::sendThreadFlag()
pmic 24:f2614d8577a1 371 {
pmic 24:f2614d8577a1 372 thread.flags_set(threadFlag);
pmic 24:f2614d8577a1 373 }
pmic 24:f2614d8577a1 374
pmic 24:f2614d8577a1 375 //****************************************************************************//
pmic 24:f2614d8577a1 376 //
pmic 24:f2614d8577a1 377 // Circular buffer
pmic 24:f2614d8577a1 378 //
pmic 24:f2614d8577a1 379 //****************************************************************************//
pmic 24:f2614d8577a1 380 /*
pmic 24:f2614d8577a1 381 //Construct a CircularBuffer type with arguments
pmic 24:f2614d8577a1 382 // uint16_t inputSize: number of elements
pmic 24:f2614d8577a1 383
pmic 24:f2614d8577a1 384 //mbed has CircularBuffer
pmic 24:f2614d8577a1 385 namespace name
pmic 24:f2614d8577a1 386 {
pmic 24:f2614d8577a1 387
pmic 24:f2614d8577a1 388 CircularBuffer::CircularBuffer(uint16_t inputSize)
pmic 24:f2614d8577a1 389 {
pmic 24:f2614d8577a1 390 cBufferData = new int16_t[inputSize];
pmic 24:f2614d8577a1 391 cBufferLastPtr = 0;
pmic 24:f2614d8577a1 392 cBufferElementsUsed = 0;
pmic 24:f2614d8577a1 393 cBufferSize = inputSize;
pmic 24:f2614d8577a1 394 }
pmic 24:f2614d8577a1 395
pmic 24:f2614d8577a1 396 CircularBuffer::~CircularBuffer()
pmic 24:f2614d8577a1 397 {
pmic 24:f2614d8577a1 398 delete[] cBufferData;
pmic 24:f2614d8577a1 399 }
pmic 24:f2614d8577a1 400
pmic 24:f2614d8577a1 401 //Get an element at some depth into the circular buffer
pmic 24:f2614d8577a1 402 //zero is the push location. Max is cBufferSize - 1
pmic 24:f2614d8577a1 403 //
pmic 24:f2614d8577a1 404 //Arguments:
pmic 24:f2614d8577a1 405 // uint16_t elementNum: number of element in
pmic 24:f2614d8577a1 406 //
pmic 24:f2614d8577a1 407 int16_t CircularBuffer::getElement( uint16_t elementNum )
pmic 24:f2614d8577a1 408 {
pmic 24:f2614d8577a1 409 //Translate elementNum into terms of cBufferLastPtr.
pmic 24:f2614d8577a1 410 int16_t virtualElementNum;
pmic 24:f2614d8577a1 411 virtualElementNum = cBufferLastPtr - elementNum;
pmic 24:f2614d8577a1 412 if( virtualElementNum < 0 ) {
pmic 24:f2614d8577a1 413 virtualElementNum += cBufferSize;
pmic 24:f2614d8577a1 414 }
pmic 24:f2614d8577a1 415
pmic 24:f2614d8577a1 416 //Output the value
pmic 24:f2614d8577a1 417 return cBufferData[virtualElementNum];
pmic 24:f2614d8577a1 418 }
pmic 24:f2614d8577a1 419
pmic 24:f2614d8577a1 420 //Put a new element into the buffer.
pmic 24:f2614d8577a1 421 //This also expands the size up to the max size
pmic 24:f2614d8577a1 422 //Arguments:
pmic 24:f2614d8577a1 423 //
pmic 24:f2614d8577a1 424 // int16_t elementVal: value of new element
pmic 24:f2614d8577a1 425 //
pmic 24:f2614d8577a1 426 void CircularBuffer::pushElement( int16_t elementVal )
pmic 24:f2614d8577a1 427 {
pmic 24:f2614d8577a1 428 //inc. the pointer
pmic 24:f2614d8577a1 429 cBufferLastPtr++;
pmic 24:f2614d8577a1 430
pmic 24:f2614d8577a1 431 //deal with roll
pmic 24:f2614d8577a1 432 if( cBufferLastPtr >= cBufferSize ) {
pmic 24:f2614d8577a1 433 cBufferLastPtr = 0;
pmic 24:f2614d8577a1 434 }
pmic 24:f2614d8577a1 435
pmic 24:f2614d8577a1 436 //write data
pmic 24:f2614d8577a1 437 cBufferData[cBufferLastPtr] = elementVal;
pmic 24:f2614d8577a1 438
pmic 24:f2614d8577a1 439 //increase length up to cBufferSize
pmic 24:f2614d8577a1 440 if( cBufferElementsUsed < cBufferSize ) {
pmic 24:f2614d8577a1 441 cBufferElementsUsed++;
pmic 24:f2614d8577a1 442 }
pmic 24:f2614d8577a1 443 }
pmic 24:f2614d8577a1 444
pmic 24:f2614d8577a1 445 //Averages the last n numbers and provides that. Discards fractions
pmic 24:f2614d8577a1 446 int16_t CircularBuffer::averageLast( uint16_t numElements )
pmic 24:f2614d8577a1 447 {
pmic 24:f2614d8577a1 448 //Add up all the elements
pmic 24:f2614d8577a1 449 int32_t accumulator = 0;
pmic 24:f2614d8577a1 450 int8_t i;
pmic 24:f2614d8577a1 451 for( i = 0; i < numElements; i++ ) {
pmic 24:f2614d8577a1 452 accumulator += getElement( i );
pmic 24:f2614d8577a1 453 }
pmic 24:f2614d8577a1 454 //Divide by number of elements
pmic 24:f2614d8577a1 455 accumulator /= numElements;
pmic 24:f2614d8577a1 456 return accumulator;
pmic 24:f2614d8577a1 457 }
pmic 24:f2614d8577a1 458
pmic 24:f2614d8577a1 459 //Returns the current size of the buffer
pmic 24:f2614d8577a1 460 uint16_t CircularBuffer::recordLength()
pmic 24:f2614d8577a1 461 {
pmic 24:f2614d8577a1 462 return cBufferElementsUsed;
pmic 24:f2614d8577a1 463 }
pmic 24:f2614d8577a1 464
pmic 24:f2614d8577a1 465 }
pmic 24:f2614d8577a1 466 */