test

Dependents:   controller_naive

Files at this revision

API Documentation at this revision

Comitter:
yxyang
Date:
Sat Feb 24 01:24:57 2018 +0000
Commit message:
avg intensity

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 9c6145a1d114 TSL1401CL.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TSL1401CL.cpp	Sat Feb 24 01:24:57 2018 +0000
@@ -0,0 +1,132 @@
+#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;
+}
+
+int TSL1401CL::findPixelIntensity() {
+    int ans = 0;
+    for (int i = 0; i < 128; i++) {
+        ans += data[i];
+    }
+    return ans / 128;
+}
+
+int TSL1401CL::findLineWidth (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) {
+        if (maxchange > minchange) {
+            return (precision*maxchange-precision*minchange);
+        } else {
+            return (precision*minchange-precision*maxchange);
+        }
+    }
+    return -1;
+}
+
+
+uint32_t TSL1401CL::getData(uint8_t index)
+{
+    return data[index];
+}
\ No newline at end of file
diff -r 000000000000 -r 9c6145a1d114 TSL1401CL.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TSL1401CL.h	Sat Feb 24 01:24:57 2018 +0000
@@ -0,0 +1,74 @@
+/*
+ * 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);
+    int findLineWidth (uint16_t threshold, uint8_t precision = 1, 
+            size_t crop_amount = 0);
+            
+    int findPixelIntensity();
+    
+    /**
+    * 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