Enter Your Project for a chance to win an Oscilloscope Grand Prize Package for the Most Creative Vision Thing Project! | Project14 Home | |
Monthly Themes | ||
Monthly Theme Poll |
As I am currently restricted to my home office at the moment (the plaster is in doing his thing) I have spent some time progressing the LDR camera, which is now working on all 64 pixels. I had one non working pixel and rather than try to fix the hardware wiring rat's nest, I decided to take a software solution and use the redundancy that is available in image data. I have averaged the data from the bad pixels (there are now two of these) using adjacent pixel data, as listed below.
LDRdata[3][1] = (LDRdata[2][0] +
LDRdata[3][0] +
LDRdata[4][0] +
LDRdata[2][1] +
LDRdata[4][1] +
LDRdata[2][2] +
LDRdata[3][2] +
LDRdata[4][2])/8;
LDRdata[7][5] = (LDRdata[6][4] +
LDRdata[7][4] +
LDRdata[6][5] +
LDRdata[6][6] +
LDRdata[7][6])/5;
It is not an elegant solution but it works and it didn't take too long to implemente and didn't break anything else. I have used a simple average giving equal weight to all pixels. I could use something a little bit more sophisticated such as only giving the diagonals a 50% weighting, but it didn't seem worth the effort, so I didn't. The second non-working pixel in on the edge, so there are only five surrounding pixels.
It was while I was doing this that I realised that I had not been saving the image data to an array, I was just stuffing each pixel data value straight out to the matrix display and serial output. As I wanted to average the data and later I will need to transfer the data to the ANN I needed an 8x8 integer array. I also now have a number of functions to handle this data which I pass into the function as an integer array rather than a pointer. I was a bit concerned that stuffing this much data onto the stack might cause problems and slow everything down, but it still seems to be working properly and quite quickly. The delays I have inserted to allow the analogue multiplexers to settle down are probably more significant in speed terms.
Once I had everything all working I played around trying to get nice images on the matrix display, but there are some 'funny' things happening. I guess these are common to many image systems and seem to be related to light levels, incident light and similar. Just for fun I decided to put in a linearly increasing threshold value when displaying the data on the matrix display, starting at a low level (most sensitive to light) and increasing to a high level (less sensitive to light). This provides a sort of dynamic display of the image, which is quite intereesting, see video below. This will not impact on the ANN part as the image data will be used directly.
So now it really is time to try and get my BeagleBone AI powered up and running. Hopefully I will not immediately 'fry' it.
Dubbie
A full programme listing is given below. I've put in some nice nested for loops to compact the programme and it is now much simpler and easier to access and manipulate the LDR data.
#include <Wire.h>
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
#ifndef _BV
#define _BV(bit) (1<<(bit))
#endif
#define S0 2
#define S1 3
#define S2 4
#define S3 5
#define mux0_enable 9
#define mux1_enable 10
#define mux2_enable 11
#define mux3_enable 12
#define muxsettledelay 1
Adafruit_8x8matrix matrix = Adafruit_8x8matrix();
uint8_t counter = 0;
int LDR0pin = A0; // LDR Analogiue Input pins
int LDR1pin = A1;
int LDR2pin = A2;
int LDR3pin = A3;
int LDRvalue = 0; // variable to store the LDR value
int LDRdata[8][8] =
{{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0}};
void setup()
{
pinMode(S0, OUTPUT);
pinMode(S1, OUTPUT);
pinMode(S2, OUTPUT);
pinMode(S3, OUTPUT);
pinMode(mux0_enable, OUTPUT);
pinMode(mux1_enable, OUTPUT);
pinMode(mux2_enable, OUTPUT);
pinMode(mux3_enable, OUTPUT);
digitalWrite(S0, LOW);
digitalWrite(S1, LOW);
digitalWrite(S2, LOW);
digitalWrite(S3, LOW);
digitalWrite(mux0_enable, HIGH);
digitalWrite(mux1_enable, HIGH);
digitalWrite(mux2_enable, HIGH);
digitalWrite(mux3_enable, HIGH);
Serial.begin(9600);
Serial.println("LDR on matrix Display");
matrix.begin(0x70); // pass in the address
} /* setup */
uint16_t x = 0;
uint16_t y =0;
uint16_t color=0;
int threshold;
int channel;
int mux;
void loop()
{
x = 0;
y = 0;
color = 1;
threshold = 250;
channel = 0;
mux = 0; //Increments in 2s
while (1)
{
for (threshold = 30; threshold < 670; threshold=threshold+2)
{
digitalWrite(mux0_enable, LOW); // Enable the analogue mux
delay(muxsettledelay); // Allow mux some settling time
for (channel = 0; channel < 16; channel++)
{
getpixeldata(mux, channel);
} /* for */
digitalWrite(mux0_enable, HIGH); // Disable mux 0
digitalWrite(mux1_enable, LOW); // Enable mux 1
delay(muxsettledelay); // Allow mux some settling time
for (channel = 0; channel < 16; channel++)
{
getpixeldata(mux+2, channel);
} /* for */
digitalWrite(mux1_enable, HIGH); // Disable mux 1
digitalWrite(mux2_enable, LOW); // Enable mux 2
delay(muxsettledelay); // Allow mux some settling time
for (channel = 0; channel < 16; channel++)
{
getpixeldata(mux+4, channel);
} /* for */
digitalWrite(mux2_enable, HIGH); // Disable mux 2
digitalWrite(mux3_enable, LOW); // Enable mux 3
delay(muxsettledelay); // Allow mux some settling time
for (channel = 0; channel < 16; channel++)
{
getpixeldata(mux+6, channel);
} /* for */
digitalWrite(mux3_enable, HIGH); // Disable mux 3
// Fix the broken pixels
LDRdata[3][1] = (LDRdata[2][0] +
LDRdata[3][0] +
LDRdata[4][0] +
LDRdata[2][1] +
LDRdata[4][1] +
LDRdata[2][2] +
LDRdata[3][2] +
LDRdata[4][2])/8;
LDRdata[7][5] = (LDRdata[6][4] +
LDRdata[7][4] +
LDRdata[6][5] +
LDRdata[6][6] +
LDRdata[7][6])/5;
displayLDRdata(LDRdata);
// printLDRarray(LDRdata);
delay(1);
// matrix.writeDisplay(); // write the changes we just made to the display
delay(1);
} /* for - threshold control */
printLDRarray(LDRdata);
} /* while */
} /* loop */
void setchannel(int chan)
{
digitalWrite(S0, chan & 0x01);
digitalWrite(S1, chan & 0x02);
digitalWrite(S2, chan & 0x04);
digitalWrite(S3, chan & 0x08);
delay(1); //delay to allow analogue voltage tostabilise
} /* setchannel */
void getpixeldata(int mux, int chan)
{
setchannel(chan);
switch (mux)
{
case 0 : LDRvalue = analogRead(LDR0pin); break;
case 2 : LDRvalue = analogRead(LDR1pin); break;
case 4 : LDRvalue = analogRead(LDR2pin); break;
case 6 : LDRvalue = analogRead(LDR3pin); break;
default : LDRvalue = 0; Serial.println("Error : ADC select ");
break;
} /* switch */
LDRdata[mux + chan/8][chan%8] = LDRvalue;
} /*getpixeldata */
void displayLDRdata(int data[8][8])
{
int x_index, y_index;
x_index = 0;
y_index = 0;
matrix.clear(); // clear display
for (y_index = 0; y_index < 8; y_index++)
{
for (x_index = 0; x_index < 8; x_index++)
{
if (data[x_index][y_index] > threshold)
matrix.drawPixel(x_index, y_index, 1);
else
matrix.drawPixel(x_index, y_index, 0);
} /* for */
} /* for */
matrix.writeDisplay(); // write the changes we just made to the display
} /* displayLDRdata */
void printLDRarray(int data[8][8])
{
int x_index, y_index;
for (y_index = 0; y_index < 8; y_index++)
{
for (x_index = 0; x_index < 8; x_index++)
{
Serial.print(data[x_index][y_index]);
Serial.print(" ");
} /* for */
Serial.println(" ");
} /* for */
Serial.println(" "); // Leave a blank line between arrays
} /* printLDRarray */
Top Comments