TSL1401 and Arduino

re Line-Scan Camera TSL1401-DB and DB to 12 pin Expander Board and Arduino Duemilanove Mother Board (http://arduino.cc/en/Main/ArduinoBoardDuemilanove).
I am trying to write Arduino C code to operate the TSL1401-DB in one-shot imaging.
Could an expert in TSL1401-DB programming review my timing in the function "getcamera" below? I would be grateful for your advice.
int syncPin = 12;
int clockPin = 11;
int dataPin = 2; // must be in range 0 to 5
int lightVal[128];
unsigned long utime;
int itime = 0;
int expose = 7390; // 8333uSec ie 1/120th second
void setup()
{
pinMode(clockPin, OUTPUT);
pinMode(syncPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
int b = Serial.read();
if (b == 's')
{
getCamera();
delay(2000);
}
}
void getCamera()
{
digitalWrite(clockPin, LOW);
pinMode(syncPin, OUTPUT);
digitalWrite(syncPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(syncPin, LOW);
utime = micros();
digitalWrite(clockPin, LOW);
for (int j = 0; j < 128; j++)
{
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
delayMicroseconds(expose);
digitalWrite(syncPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(syncPin, LOW);
utime = micros() - utime;
digitalWrite(clockPin, LOW);
for (int j = 0; j < 128; j++)
{
delayMicroseconds(20);
lightVal[j] = analogRead(dataPin);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
delayMicroseconds(20);
for (int j = 0; j < 128; j++)
{
itoa(lightVal[j], 'S');
}
itime = (int)utime;
itoa(itime, 'S');
}
Regards,
Kevin
I am trying to write Arduino C code to operate the TSL1401-DB in one-shot imaging.
Could an expert in TSL1401-DB programming review my timing in the function "getcamera" below? I would be grateful for your advice.
int syncPin = 12;
int clockPin = 11;
int dataPin = 2; // must be in range 0 to 5
int lightVal[128];
unsigned long utime;
int itime = 0;
int expose = 7390; // 8333uSec ie 1/120th second
void setup()
{
pinMode(clockPin, OUTPUT);
pinMode(syncPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
int b = Serial.read();
if (b == 's')
{
getCamera();
delay(2000);
}
}
void getCamera()
{
digitalWrite(clockPin, LOW);
pinMode(syncPin, OUTPUT);
digitalWrite(syncPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(syncPin, LOW);
utime = micros();
digitalWrite(clockPin, LOW);
for (int j = 0; j < 128; j++)
{
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
delayMicroseconds(expose);
digitalWrite(syncPin, HIGH);
digitalWrite(clockPin, HIGH);
digitalWrite(syncPin, LOW);
utime = micros() - utime;
digitalWrite(clockPin, LOW);
for (int j = 0; j < 128; j++)
{
delayMicroseconds(20);
lightVal[j] = analogRead(dataPin);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
delayMicroseconds(20);
for (int j = 0; j < 128; j++)
{
itoa(lightVal[j], 'S');
}
itime = (int)utime;
itoa(itime, 'S');
}
Regards,
Kevin
Comments
I have written a code in c, but I have a true doubts how to connect sensor to my arduino.
I have written datasheet and there is no literal explanation how to connect exactply nodes as:
tr, sd, st, so
My question is where to find this? And I have some interesting code for you, but I have to check it so I won't paste it there yet.
Please help me and if the code works, i will give it to you.
thanks
Piter
/* * ========================================================================= * * File...... TSL1401_scan.ino * Purpose... Image capture and processing demo using the TSL1401-DB * Author.... Phil Pilgrim, Bueno Systems, Inc. * Started... 11 July 2007 * * Author.... Martin Heermance * Updated... 13 September 2012 - ported to C++ on Arduino. * * ========================================================================= * Program Description * This program demonstrates image capture and processing using the * TSL1401-DB (Parallax p/n 28317). It continuously acquires and displays * images from the TSL1401R sensor chip. It then locates both left and right * bright edges, displaying them graphically using DEBUG. Finally it * computes both the area and extent of the object found. * Revision History */ // I/O Definitions const int ao = 0; // TSL1401's analog output (threhsolded by MCU). const int si = 1; // TSL1401's SI pin. const int clk = 2; // TSL1401's CLK pin. // Constants const int DRK = 0; // Value assignd to "which" for dark pixels. const int BRT = 1; // Value assigned to "which" for bright pixels. const int FWD = 0; // Value assigned to "dir" for left-to-right search. const int BKWD = 1; // Value assigned to "dir" for right-to-left search. const int PIXEL_CNT = 128; // ASCII terminal control codes to match PBASIC commands. const char * CLREOL = "\033[K"; const char * CRSRXY = "\033[%d;%dH"; const char * HOME = "\033[H"; // Variables byte pdata[PIXEL_CNT/8]; // Pixel data, as acquired LSB first from sensor. // Program Code void setup() { // initialize serial communications: Serial.begin(9600); Serial.print(HOME); // Go to home position on DEBUG screen. dispHdr(); // Display the pixel location header. } void loop() { char buf[32]; //Begin the scan-and-process loop. getPix(8333); // Obtain a pixel scan with exposure time of 8333uSec (1/120th sec). sprintf(buf, CRSRXY, 2, 0); Serial.print(buf); // Move to column 0, row 2. dispPix(); // Display the pixels here. int lptr = 0; // Left pixel pointer for count and find operations. int rptr = 127; // Right pixel pointer for count and find operations. // Indicates pixels found (= 1), or not found (= 0). bool found = findEdge(lptr, rptr, FWD, BRT); // Find first dark-to-light edge going L->R. // Switch directions. found = found & findEdge(lptr, rptr, BKWD, BRT); // Find first dark-to-light edge going L<-R. Serial.print(CLREOL); // Clear the next line. if (found) { // Both edges found? // Yes: Display left edge. sprintf(buf, CRSRXY, 3, lptr - 1); Serial.print(buf); Serial.print("_|"); // Display right edge. sprintf(buf, CRSRXY, 3, rptr); Serial.print(buf); Serial.print("|_"); Serial.println("\nArea = "); // Display area by computing light pixel count. Serial.print( countPix(lptr, rptr, BRT) ); Serial.print(" Extent = "); //... and extent of object. Serial.print(rptr - lptr + 1); Serial.print(CLREOL); } else { //No: Display failure message. Serial.print("\n\nNo object found."); Serial.print(CLREOL); } } // Subroutines // getPix // Acquire 128 thresholded pixels from sensor chip. // exp is the exposure time in microseconds. void getPix(int expose) { clockSI(si, clk); // Clock out the SI pulse. // Rapidly send CLKs to throw away old image. for (int i = 0; i < PIXEL_CNT/8; i++) shiftIn(ao, clk, LSBFIRST); // delay to allow the new image to expose. delayMicroseconds(expose); clockSI(si, clk); // Clock out another SI pulse. // Shift in all the pixels using digital I/O to threshold. for (int i = 0; i < PIXEL_CNT/8; i++) pdata[i] = shiftIn(ao, clk, LSBFIRST); } // clockSI is used to signal the TSL1401 that commands are comming. void clockSI(int dataPin, int clockPin) { // set the pinModes for the clock and data pins: pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); digitalWrite(dataPin, 1); // pulse the clock: digitalWrite(clockPin, HIGH); delayMicroseconds(100); digitalWrite(clockPin, LOW); } // dispHdr // Display a header to aid in identifying pixel positions. void dispHdr() { // Display tens digits. for(int i = 0; i <= 12; i++) { Serial.print (i); // DIG 0 if (i < 12) Serial.print(" "); else Serial.println(""); } // Display ones digits. for(int i = 0; i < PIXEL_CNT; i++) Serial.print(i % 10); } // dispPix // Display 128 pixels: light pixels as "1"; dark, as "_". void dispPix() { for(int i = 0; i < PIXEL_CNT; i++) Serial.print( bitRead(pdata[i >> 3], i % 8) ? "1" : "."); } // findEdge // Find the first edge within the range lptr through rptr, in the direction // given by dir and of the type indicated by which (0 = light-to-dark; // 1 = dark-to-light). bool findEdge(int & lptr, int & rptr, bool dir, bool which) { which = !which; // Look for opposite kind of pixel first. bool found = findPix(lptr, rptr, dir, which); which = !which; // Then look for desired pixel, // by falling through to FindPix. return found & findPix(lptr, rptr, dir, which); } // findPix // Find the first pixel within the range lptr through rptr, in the direction // given by dir and of the type indicated by which (0 = dark; 1 = light). bool findPix(int & lptr, int & rptr, bool dir, bool which) { if (lptr <= rptr && rptr < PIXEL_CNT) { // Still looking & within bounds? if (dir = FWD) { // Yes: Search left-to-right? for(; lptr <= rptr; lptr++) // Yes: Loop forward. if (bitRead(pdata[lptr >> 3], lptr % 8) == which) return true; } else { for(; rptr >= lptr; rptr--) // No: Loop backward. if (bitRead(pdata[rptr >> 3], rptr % 8) == which) return true; } } // Didn't look or nothing found. return false; } // countPix // Count pixels within the range lptr through rptr, of the type indicated by // which (0 = dark; 1 = light). int countPix(int & lptr, int & rptr, int which) { // Initialize count. int cnt = 0; // Valid range? if (lptr <= rptr && rptr < PIXEL_CNT) { // Yes: Loop over desired range. for (int i = lptr; i < rptr; i++) { // Add to count when pixel matches. if (bitRead(pdata[i >> 3], i % 8) == which) { cnt++; } } } return cnt; }
Here is the breadboard -
There are 2 64 pixel arrays, so AO1 connects to AO2, and SO1 connects to SI2 to trigger the second array. I've simplified the code to only display the pixel values on a single line in the serial monitor. Once I have that working, I can move on to the more interesting stuff. I also made analog versions of getPix and dispPix so I can see something other than 0 or 1. So far with the digital input all I get are 0 with my Arduino Micro, or 1 with an Uno. With analog inputs, I get 95 from AO2. If I wire the sensor to only use the first 64 pixel array and take only AO1, I get 0.
I changed clockSI slightly, so SI goes low before the clock goes high. There was a footnote in the datasheet saying that was necessary. Also I left the clock high, because the first bit comes through with the first rising clock after SI. If I take the clock low during clockSI I will miss that first bit.
It didn't make any difference, I can't get this code to work any more than the original. I have two of these sensor, and neither of them worked. I know it's not the 1401, but I don't see anything different about its operation other than the need for the pulldown resistor.
/** ========================================================================= * * File...... TSL1401_scan.ino * Purpose... Image capture and processing demo using the TSL1401-DB * Author.... Phil Pilgrim, Bueno Systems, Inc. * Started... 11 July 2007 * * Author.... Martin Heermance * Updated... 13 September 2012 - ported to C++ on Arduino. * * ========================================================================= * Program Description * This program demonstrates image capture and processing using the * TSL1401-DB (Parallax p/n 28317). It continuously acquires and displays * images from the TSL1401R sensor chip. It then locates both left and right * bright edges, displaying them graphically using DEBUG. Finally it * computes both the area and extent of the object found. * Revision History */ // I/O Definitions const int ao = 8; // TSL1401's analog output (threhsolded by MCU). const int si = 4; // TSL1401's SI pin. const int clk = 8; // TSL1401's CLK pin. const int analog_ao = 5; // Constants const int PIXEL_CNT = 128; // Variables byte pdata[PIXEL_CNT/8]; // Pixel data, as acquired LSB first from sensor. The array is 16 bits long for 128 pixel sensor int analogpdata[PIXEL_CNT]; // Program Code void setup() { // initialize serial communications: Serial.begin(115200); pinMode (ao,INPUT); } void loop() { getPix(8333); // Obtain a pixel scan with exposure time of 8333uSec (1/120th sec). dispPix(); // Display the pixels here. Serial.println(" "); //getAnalogPix(8333); //analogdispPix(); Serial.println(" "); // Serial.println(analogRead(analog_ao)); } // Subroutines // getPix // Acquire 128 thresholded pixels from sensor chip. // exp is the exposure time in microseconds. void getPix(int expose) { clockSI(si, clk); // Clock out the SI pulse. Tells sensor to start sending data by triggering sync pin // Rapidly send CLKs to throw away old image. for (int i = 0; i++; i < 129) { digitalWrite (clk, 1); digitalWrite (clk, 0); } // delay to allow the new image to expose. delayMicroseconds(expose); clockSI(si, clk); // Clock out another SI pulse. // Shift in all the pixels using digital I/O to threshold. for (int i = 0; i < PIXEL_CNT/8; i++) { pdata[i] = shiftIn(ao, clk, LSBFIRST); } //shiftIn sends a clock pulse and records data into array position i // one last clock to reset the sensor digitalWrite (clk, 1); digitalWrite (clk, 0); } // clockSI is used to signal the TSL1401 that commands are comming. void clockSI(int dataPin, int clockPin) { // set the pinModes for the clock and data pins: pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); digitalWrite(dataPin, HIGH); digitalWrite(dataPin, LOW); delayMicroseconds(6); digitalWrite(clockPin, HIGH); } // dispPix // Display 128 pixels: light pixels as "1"; dark, as "_". void dispPix() { for(int i = 0; i < PIXEL_CNT; i++){ Serial.print(bitRead(pdata[i >> 3], i % 8));} } void getAnalogPix(int expose) { clockSI(si, clk); // Clock out the SI pulse. Tells sensor to start sending data by triggering sync pin // Rapidly send CLKs to throw away old image. for (int i = 0; i++; i < 129) { digitalWrite (clk, 1); digitalWrite (clk, 0); } // delay to allow the new image to expose. delayMicroseconds(expose); digitalWrite(si, HIGH); for (int i=0;i<=PIXEL_CNT;i++){ digitalWrite(clk, HIGH); analogpdata[i]=analogRead(analog_ao); delayMicroseconds(2); digitalWrite(clk, LOW); delayMicroseconds(2); if (i==1) digitalWrite(si, LOW); } // one last clock to reset the sensor digitalWrite (clk, 1); digitalWrite (clk, 0); } // analogdispPix // Display 128 pixels: light pixels as "1"; dark, as "_". void analogdispPix() { for(int i = 0; i < 24; i++){ Serial.print(analogpdata[i]); Serial.print(",");} }
I have the same issue with a TSL201R, which is 64 pixel array in one only, both doesn't work, I have 1 everywhere...
Have you found a solution ?