Dependents: controller_with_imu controller_with_autostop ros_openroach
Revision 0:57ff45e3cb20, committed 2017-05-30
- Comitter:
- yxyang
- Date:
- Tue May 30 06:41:58 2017 +0000
- Commit message:
Changed in this revision
TSL1401CL.cpp | Show annotated file Show diff for this revision Revisions of this file |
TSL1401CL.h | Show annotated file Show diff for this revision Revisions of this file |
diff -r 000000000000 -r 57ff45e3cb20 TSL1401CL.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSL1401CL.cpp Tue May 30 06:41:58 2017 +0000 @@ -0,0 +1,93 @@ +#include "TSL1401CL.h" + +TSL1401CL::TSL1401CL(PinName pin_clk, PinName pin_si, PinName pin_adc) : clk(pin_clk), si(pin_si), adc(pin_adc), integration_time(0) +{ + clk.write(0); + integration_timer.start(); +} + +bool TSL1401CL::integrationReady() +{ + return static_cast<uint32_t>(integration_timer.read_us()) >= integration_time; +} + +void TSL1401CL::read() +{ + integration_timer.reset(); + integration_timer.start(); + clk.write(0); + si.write(1); + clk.write(1); + si.write(0); + + for (uint8_t i = 0; i < TSL1401CL_PIXEL_COUNT; i++) { + clk.write(0); + data[i] = adc.read_u16(); + clk.write(1); + } + clk.write(0); +} + +void TSL1401CL::setIntegrationTime(uint32_t int_time_desired) +{ + integration_time = int_time_desired; +} + +int TSL1401CL::findLineEdge (uint16_t threshold, uint8_t precision, size_t crop_amount, bool invert) +{ + if(precision == 0) precision = 1; + + // Create an array with resolution determined by precision containing the change between points in data + uint16_t change_len = (TSL1401CL_PIXEL_COUNT - 2*crop_amount)/precision - 1; + int32_t change_in_data[change_len]; + for(uint16_t i = crop_amount, j = 0; i < TSL1401CL_PIXEL_COUNT - crop_amount - precision; i += precision, j++) { + change_in_data[j] = (int)data[i+precision] - (int)data[i]; + } + + // Find the index of the maximum value in change_in_data + uint16_t maxchange = 0; + for(uint16_t i = 1; i < change_len; i++) { + if(invert) { + if(change_in_data[i] < change_in_data[maxchange]) maxchange = i; + } else { + if(change_in_data[i] > change_in_data[maxchange]) maxchange = i; + } + } + + // If there isn't a sharp enough change returns -1 + if((change_in_data[maxchange] >= threshold && !invert) || (change_in_data[maxchange]*-1 >= threshold && invert)) { + return maxchange*precision + crop_amount; + } + else return -1; +} + +int TSL1401CL::findLineCenter (uint16_t threshold, uint8_t precision, size_t crop_amount) +{ + if(precision == 0) precision = 1; + + // Create an array with resolution determined by precision containing the change between points in data + uint16_t change_len = (TSL1401CL_PIXEL_COUNT - 2*crop_amount)/precision - 1; + int32_t change_in_data[change_len]; + for(uint16_t i = crop_amount, j = 0; i < TSL1401CL_PIXEL_COUNT - crop_amount - precision; i += precision, j++) { + change_in_data[j] = (int)data[i+precision] - (int)data[i]; + } + + // Find the index of the maximum and minimum value in change_in_data + uint16_t maxchange = 0; + uint16_t minchange = 0; + for(uint16_t i = 1; i < change_len; i++) { + if(change_in_data[i] > change_in_data[maxchange]) maxchange = i; + if(change_in_data[i] < change_in_data[minchange]) minchange = i; + } + + // Return the average of the max and min value + if(change_in_data[maxchange] >= threshold && change_in_data[minchange]*-1 >= threshold) { + return (precision*maxchange+precision*minchange)/2 + crop_amount; + } + return -1; +} + +uint32_t TSL1401CL::getData(uint8_t index) +{ + return data[index]; +} \ No newline at end of file
diff -r 000000000000 -r 57ff45e3cb20 TSL1401CL.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TSL1401CL.h Tue May 30 06:41:58 2017 +0000 @@ -0,0 +1,70 @@ +/* + * An mbed library for the TSL1401CL line sensor. + * Author: Galen Savidge + */ + +#ifndef TSL1401CLh +#define TSL1401CLh + +#include "mbed.h" + +#define TSL1401CL_PIXEL_COUNT 128 + +class TSL1401CL +{ +public: + /** + * Parameters: binary pin connected to clock, binary pin connected to serial- + * input (SI), adc pin connected to analog out (AO) + */ + TSL1401CL(PinName pin_clk, PinName pin_si, PinName pin_adc); + + /** + * Returns whether enough time has passsed for integration to complete. The + * sensor should not be read until integrationReady() returns true. + */ + bool integrationReady(); + + /** + * Reads from the sensor into private data storage. + */ + void read(); + + /** + * Sets the integration time of the sensor in microseconds. Can be called mid + * integration. + */ + void setIntegrationTime(uint32_t int_time_desired); + + /** + * Returns the dark-to-light edge of a line as an int between 0 and cam + * resolution. Returns -1 when no line is found. Use higher precision value + * for fewer samples, default is 1 (lowest, most precise). Ignores + * crop_amount pixels on beginning/end of data. Set invert to true to instead + * return the light-to-dark line edge (if found). + */ + int findLineEdge (uint16_t threshold, uint8_t precision = 1, + size_t crop_amount = 0, bool invert = false); + + /** + * Like FindLineEdge, but finds both edges of the line and returns their + * midpoint. Returns -1 if either edge is not found. + */ + int findLineCenter (uint16_t threshold, uint8_t precision = 1, + size_t crop_amount = 0); + + /** + * Returns the value of the sensor's last read data at a specified index. + */ + uint32_t getData(uint8_t index); +protected: + DigitalOut clk; + DigitalOut si; + AnalogIn adc; + + uint32_t data[TSL1401CL_PIXEL_COUNT]; + uint32_t integration_time; + Timer integration_timer; +}; + +#endif \ No newline at end of file