RGB LED Color Control via Arduino-linked JPEG Camera

Good day all. This is first post here, even though I have gained quite a lot from the contributions in this forum. Here is the problem, I am working on a project where the aim is to control an RGB LED to display the color (even if roughly) of an image placed in front of a JPEG Color Camera TTL Interface (the camera here: http://www.sparkfun.com/products/10061). I am a beginning programmers, so this code might be look a bit sloppy (pardon me for that). The basic aim of this code is just to take a pixel from the data coming from the camera after every few seconds, feed it to the digital pins where the RGB LED are and discard the rest. The code used three subroutines (Camera, getdata and process) given at the end of the void loop. The code does not seem to work the way I expected. And I have been on this for three weeks. Sometimes the RGB LED is on produces a color different from what is placed in front of the camera. Sometimes, there is no reponse at al. I can’t seem to be able to figure out the problem.

Firstly, I would be grateful if I can be helped on the possibility of achieving the aim of the project.Secondly, any help on how to improve the code or alternative means would greatly appreciated. By the way, I have used color sensor to do the same, but since color sensors are of limited range, the camera is preferred. Thank you all.

int sync[] = {0xaa,0x0d,0x00,0x00,0x00,0x00};           // Sync command
int initial[] = {0xaa,0x01,0x00,0x06,0x01,0x03};        // initial command
int ack[] = {0xaa,0x0e,0xff,0x00,0x00,0x00};            // ack command
int snap[] = {0xaa,0x05,0x01,0x00,0x00,0x00};           // snap command
int getpic[] = {0xaa,0x04,0x02,0x00,0x00,0x00};         // get the snaped pic comma nd
int reset[] = {0xaa,0x08,0x01,0x00,0x00,0xff};           // reset the camera (special) 


byte incomingByte[24];                                 // reserved bytes for incoming data

//The boolean variables below are just flags for initial, sync, snap,getpic and reset
boolean Initial = 0;                                   
boolean Sync = 0;                                       
boolean Snap = 0;
boolean Getpic = 0;
boolean Reset = 0;

//Loop counters
int i = 0;
int n = 0;
int k = 0;

int R ,G , B;                                  // out put R G and B value, in int, 0-255.
int G1,G2;                                      // used when calculating G VALUE


void setup()
{

  Serial.begin (57600);//set serial bund rate = 57600
  pinMode(9, OUTPUT);// pin 9 is the positive pole of the LED
  pinMode(10, OUTPUT);//R PWM output
  pinMode(11, OUTPUT);//G PWM output
  pinMode(12, OUTPUT);//B PWM output
  pinMode(2, OUTPUT);//

}

void loop()
{  
  digitalWrite(2, HIGH);
  /***************SYNC**************/
  
  while (!Sync)//check whether sync had beed done
        {
          Camera(sync);                                           //call subroutine (Camera) and send command sync
          delay(200) ;
          if (Serial.available())  
          {
             n=12;                                                //answer for sync is 12byte.
             getdata();                                           //call subroutine (getdata). Get the ansewer which is stored in incomingByte.
             if(incomingByte[0]==0xaa && incomingByte[1]== 0x0e)    //if the command have been received, camera will return an answer begging with 0xaa, 0x0e
             {Sync = 1;}
          }
        }   
//Now that Sync is done, send an ack command to camera
  Camera(ack);            
  /***************INITIAL************************/
  while (!Initial)      
         {
             Camera(initial);  
             delay(200) ;
            if (Serial.available())
            {
              n=6;
              getdata();
             if(incomingByte[0]==0xaa && incomingByte[1]== 0x0e)
              {Initial = 1;}
            else {Initial = 0;}
            }
          }    
  
  /******GETPICTURE************************/
  while (!Getpic)
          {
              Camera(getpic);
               if (Serial.available())
                  {
                   n=24;
                  //Take only 24 byte data. data 1-12 is camera's responding for the getpicture command,*****//
                  //***data 13-24 is the data of first  pixels **/
                  getdata();      
                  if(incomingByte[0]==0xaa && incomingByte[1]== 0x0e)
                      {
                        Getpic = 1;
                      //call subroutine (process). 
                       process(18);
                       }
                  else 
                  {Snap=0;Getpic = 0;}
    delay(5000) ;
    Camera(ack);
    
                }  
  } 

  /******RESET************************/
   while (!Reset)
             {
               Camera(reset);  
               delay(200) ;
               if (Serial.available())
                   {
                     n=12;
                   getdata();
                   if(incomingByte[0]==0xaa && incomingByte[1]== 0x0e)
                       {Reset = 1;}
                   }
           }   
   
   Camera(ack);
   digitalWrite(12, LOW);
   Initial = 0;
   Sync = 0;
   Snap = 0;
   Getpic = 0;
   Reset = 0;
  delay(1000);

}



/******************Subrotine1-->(Camera)*************/

void Camera(int wanttosend[6])//subrotine for sending an command to camera.
        {
            for(int i= 0;i<6;i++)
                {Serial.write(wanttosend[i]);}  //send byte by byte}
        }


/****************Subrotine2-->(getdata)*****************/


void getdata()// this is to get data from the serial prot
      {
            int k = 0;
            while (Serial.available())// get data continually until all data had been got
                {
                  for( i=Serial.available();i<n; i--){
                  incomingByte[k] = Serial.read();//data are stored in incomingByte[]
                  k++;
                  delay (10);
                }
          Serial.flush();//fulsh the serial port to insure the income buf is clear
        }
    }

/***********************Subrotine3--> (process)*********/

void process(int j)//calculate the RGB FROM DATA.
{

  //data format is RGB565, ie. 5bit R value , 6 bit G value and then 5 bit B value.
  Serial.println(incomingByte[j],HEX);
  Serial.println(incomingByte[j+1],HEX);
  R = incomingByte[j]>>3;
  R = R*8;//for R, the high byte right shift fro 3 bits . and times 8 to make is ranges from 0 - 255
  B = incomingByte[j+1];
  bitClear(B,7);
  bitClear(B,6);
  bitClear(B,5);
  B =B*8;//for B , the low byte's lower 5bits. so clear the higher 3 bits and times 8 to make it ranges from 0 -255

  
  G1 = incomingByte[j]<<5;
  G1 = incomingByte[j+1]>>5;
  G2 = incomingByte[j+1]>>5;
  G = (G1*8+G2)*4;//the lower 3 bit of incomingByte[12] is the G value's higher 3 bits; the higher 3 bit of incomingBytr[13] is the lower 3 bit.


  digitalWrite(12, HIGH);
  analogWrite(9, 255-R); 
  analogWrite(10, 255-G); 
  analogWrite(11, 255-B); //generate color display from RGB Value.
  
}

The basic aim of this code is just to take a pixel from the data coming from the camera

I don't see where you're doing your JPEG decode. Does this camera have an uncompressed output?

How are you doing the RS232 level conversion/inversion? EDIT: Scratch that - the linked page is for TTL, but the manual link is for RS232.

Can you provide a link to the datasheet for the actual camera you're using - the one at that page ssems to have a completely different protocol.

Thank you for your response and sorry for the mixed up. Here is the link to the manual of the camera is here (http://www.sgbotic.com/products/datasheets/camera/uCAM-DS-rev4.pdf) and the camera is (http://www.sgbotic.com/index.php?dispatch=products.view&product_id=506). Actually, the camera can output 7 different color types (page 8 of the manual): 2-bit gray scale, 4-bit gray scale, 8-bit gray scale, 8-bit color (RAW 332(RGB)), 12-bit color (RAW 444(RGB)), 16-bit color (RAW 565(RGB)) and JPEG. In order to avoid the problem of decompression with JPEG, I decided to stick with 16-bit color (RAW 565(RGB)).

Thank you once again.

OK, assuming that you've got the TTL version, what I'd do is forget about using the serial pins 0 and 1 to talk to it (for now), and use one of the software serial libraries, so you can reserve the serial interface for debug messages.

Failing that, I'd probably write a simpler version of of your LED driver, taking three 8 bit values for each of R G and B, and design some easily distinguishable colours. Then instead of serial debug messages (assuming that route isn't open to you), use colours to signal the progress of the sketch. This may also need some delays - just make sure that your debug code is easily removeable (the macro preprocessor is very useful for this).e.g.

#ifdef DEBUG
  #define DBG(r,g,b) {displayColour(r,g,b);delay(200);}

I'd debug the LED code separately first with a simple sketch, then scatter DBGs around the camera sketch.
Shuffle, rinse and repeat.

(looks an interesting device - I may have to invest)
#else
  #define DBG(r,g,b)
#endif

First post for me! :slight_smile:

I’m very interested in this. As I’m sketching on a project where extraction of a pixel in an image received from a camera is needed.

I haven’t been programming for years, so I’m very very rusty, to say the least. But I think I understand your code.

This confuses me thought, and perhaps you’ve spotted it already?

  G1 = incomingByte[j]<<5;
  G1 = incomingByte[j+1]>>5;  
  G2 = incomingByte[j+1]>>5;
  G = (G1*8+G2)*4;//the lower 3 bit of incomingByte[12] is the G value's higher 3 bits; the higher 3 bit of incomingBytr[13] is the lower 3 bit.

When calculating G you’re using the same value for G1 and G2?