TCS34725 always the same output color

Go To Last Post
15 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys. I'm using TCS34725 connected to a Arduino Nano, reading the RGB values and seding it through Two Wire Interface (based on atmega328p Datasheet).
The TCS34725 is well connected but only prints the same values for the clear, red, green and blue color.
Like this: 

 

 

The code I'm using is not the one provided by the Adafruit https://github.com/adafruit/Adafruit_TCS34725/blob/master/Adafruit_TCS34725.cpp, but one that I had to make in order to fulfill the unit course requirements I'm taking (although mine is based on this one).
Here is the main code: 

void setup() {

   pinMode(OUTPUT, RED);
   pinMode(OUTPUT, BLUE);
   pinMode(OUTPUT, GREEN);

     Serial.begin(9600);
   Serial.print("SCL Frequency -> "); Serial.print(TWISetup()); Serial.println(" Hz");
   Serial.println("---------------------------------");   

   setGain();
   setTime();

   /* Check if the device is connected */
     while (getID() != NUMBER_IDENTIFICATION) {
        Serial.println("Device is not connected!");
      powerON();
      delay(1000);
     } 

   Serial.println("Device is connected!");

}

void loop() {

   enableTCS34725();

   clear_color = getColor(CDATA);
   red_color = getColor(RDATA);
   green_color = getColor(GDATA);
   blue_color = getColor(BDATA);

   delay(INTEGRATION_DELAY);

   Serial.print("[ "); Serial.print(clear_color); Serial.print(" ], ");
   Serial.print("[ "); Serial.print(red_color); Serial.print(" ], ");
   Serial.print("[ "); Serial.print(green_color); Serial.print(" ], ");
   Serial.print("[ "); Serial.print(blue_color); Serial.println(" ] ");

}

This is the enable function meant to initialzed RGBC:

void enableTCS34725() {
    powerON(); //(PON 1)
    enableRGBC(); //(PON 1 AEN 1)
    delay(INTEGRATION_DELAY);
}

And finally this is the getColor function I'm using to get color data:

uint16_t getColor(uint8_t color) {

    TWIStart();
    TWIWrite(SLA_W);
    TWIWrite(COMMAND_BIT | color);
    TWIStart();
    TWIWrite(SLA_R);
    x = (TWIRead() << 8);
    x |= TWIRead();

    return x;
}

(x is a unit16_t variable)

Did you guys had some kind of problem like this one? I would appreciate some help. Thanks.

This topic has a solution.

nguterresn

Last Edited: Mon. Jan 6, 2020 - 08:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NGUTERRESN wrote:
TCS34725

This:  https://ams.com/tcs34725  ?

 

The TCS34725 is well connected

How do you know that?

 

You are not checking any status returns from any of your TWI functions - so how do you know that they're not all just failing, and giving a "default" answer?

 

Isn't Wire the standard I2C library for Arduino?

 

https://www.arduino.cc/en/reference/wire

 

Why aren't you using that?

 

 

The code I'm using is not the one provided by the Adafruit

Have you at least tried that code?

 

That would show you if your setup is working.

 

Then you could go from there to your own code ...

 

 

but only prints the same values

The sensor does not "print values" at all - your code does that.

 

Are you sure that your printing code is working correctly?

 

 

NGUTERRESN wrote:
unit course requirements I'm taking

If this is for school/college, you should be going to your teacher/supervisor for help

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NGUTERRESN wrote:
(x is a unit16_t variable)

Where is it defined?

 

It's not declared within the getColor() function - so, if it's a global, what't the point of

return x;

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NGUTERRESN wrote:
TCS34725

This:  https://ams.com/tcs34725  ?

 

- > That one.

 

The TCS34725 is well connected

How do you know that?

 

You are not checking any status returns from any of your TWI functions - so how do you know that they're not all just failing, and giving a "default" answer?

 

-> I do know I'm not checking. It works to the device ID and to command registers. It's working, otherwise wouldn't answer with device ID or would boot up from sleep state. I don't think the error is on the TWI.

 

Isn't Wire the standard I2C library for Arduino?

 

https://www.arduino.cc/en/reference/wire

 

Why aren't you using that?

 

- > Unit course Requirement.

 

 

The code I'm using is not the one provided by the Adafruit

Have you at least tried that code?

 

That would show you if your setup is working.

 

Then you could go from there to your own code ...

 

- > No, I did not try. That's actually a good ideia smiley

 

but only prints the same values

The sensor does not "print values" at all - your code does that.

 

Are you sure that your printing code is working correctly?

 

 

NGUTERRESN wrote:
unit course requirements I'm taking

If this is for school/college, you should be going to your teacher/supervisor for help

 

nguterresn

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is global.

 

uint16_t x;


uint16_t getColor(uint8_t color) {

    x = 0; 

    TWIStart();
    TWIWrite(SLA_W);
    TWIWrite(COMMAND_BIT | color);
    TWIStart();
    TWIWrite(SLA_R);
    x = (TWIRead() << 8);
    x |= TWIRead();

    return x;
}

 

nguterresn

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NGUTERRESN wrote:
It is global.

So what's the point of the return ?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You might like to look at this tutorial on how to make replies in this forum:

 

https://www.avrfreaks.net/forum/...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NGUTERRESN wrote:
It works to the device ID

True - I missed that.

 

So that must, indeed, mean that the hardware is OK.

 

However, it does not guarantee that you aren't getting comms errors when you're actually reading the sensor.

 

Again, you really should be checking for errors at each stage.

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You were totally right. 

I tried the Adafruit code and it worked - so no problem with HW at all. Further I made some checking improvements on TWI:

#include "twi.h"
#include <Arduino.h>

float TWISetup(){

    float sclf;
    // Fscl = 333kHz  (max400kHz)  Fcpu = 16MHz //
    // Set I2C Bit Rate Register (16 bits) //
    TWBR |= 0b00010000;
    TWCR |= (1<<TWEN);

    sclf = (float) CPU_F / (float) (16 + (2*TWBR));
    return sclf;

}

uint8_t TWIStart() {

    /* Enable and start TWI */
    TWCR |= (1<<TWEN)|(1<<TWSTA)|(1<<TWINT);
    while (!(TWCR & (1<<TWINT)));

    /* Check if Status code Errors */
    if ((TWSR == BUS_ERROR) ||
        (TWSR == ARBILOST)) {

            #ifdef DEBUG
                Serial.print("Status code for TWISTART: ");
                Serial.println(TWSR);
            #endif

            return ERROR;
        }

    return TWSR;
}

uint8_t TWIWrite(uint8_t reg){

    TWDR = reg;
    TWCR = (1<<TWINT)|(1<<TWEN);
    while (!(TWCR & (1<<TWINT)));

    if ((TWSR == BUS_ERROR) ||
        (TWSR == ARBILOST) ||
        (TWSR == SLAW_T_NACK) ||
        (TWSR == SLAR_T_NACK) ||
        (TWSR == DATA_T_NACK)) {

            #ifdef DEBUG
                Serial.print("Status code for TWIWrite: ");
                Serial.println(TWSR);
            #endif

            return ERROR;
        }

    return TWSR;
}

uint8_t TWIRead() {

    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    while (!(TWCR & (1<<TWINT)));

    if ((TWSR == BUS_ERROR) ||
        (TWSR == ARBILOST) ||
        (TWSR == DATA_R_NACK)) {

            #ifdef DEBUG
                Serial.print("Status code for TWIRead: ");
                Serial.println(TWSR);
            #endif

            return ERROR;
        }

    return TWDR;
}

void TWIStop(){
    TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}

It is returning error on writing SLA+W and writing data - 0x20 and 0x30 respectively - which means the TCS34725 is not returning ACK. Interesting is that the device ID is returning well.

 

EDIT:

 

Although is it not working well when asking for device ID, it is working well to others cases, for example:

 

void setGain() {

    TWIStart();
    TWIWrite(SLA_W);
    TWIWrite(COMMAND_BIT | CONTROL_REGISTER);
    TWIWrite(AGAIN);

}

void setTime() {

    TWIStart();
    TWIWrite(SLA_W);
    TWIWrite(COMMAND_BIT | TIMING_REGISTER);
    TWIWrite(ATIME);

}

Works well and has no errors.

 

nguterresn

Last Edited: Mon. Jan 6, 2020 - 04:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

NGUTERRESN wrote:

float TWISetup(){

Why on earth is that a float ?!

 

surprise

 

It is returning error on writing SLA+W ... which means the TCS34725 is not returning ACK.

Commonest reason for that is that you have the Slave Address wrong.

 

Be sure that you are presenting it correctly: strictly, the slave address is just a seven-bit number; but it is often presented as eight bits - ie, including the R/W bit.

 

See: https://www.avrfreaks.net/commen...

 

 

Or it could be some specific timing and/or sequencing requirement of the TCS34725.

 

So look at the working code, and see how yours differs ...

 

As it's a school project, you should have an oscilloscope or logic analyser to look at what's actually happening on the wires ...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Commonest reason for that is that you have the Slave Address wrong.

 

Be sure that you are presenting it correctly: strictly, the slave address is just a seven-bit number; but it is often presented as eight bits - ie, including the R/W bit.

 

See: https://www.avrfreaks.net/commen...

The address is stated as 0x29 + R/W, making it a 7-bit number. I defined like

#define SLA_W 0b1010010
#define SLA_R 0b1010011

I got no problems writing to get device ID, I don't really know what is happening.

 

Or it could be some specific timing and/or sequencing requirement of the TCS34725.

 

So look at the working code, and see how yours differs ...

 

As it's a school project, you should have an oscilloscope or logic analyser to look at what's actually happening on the wires ...

 

 

I have reduced the SCL frequency even although the TCS34725 supports data rates up to 400kbit/s. Currently using 31.25kHz.

 

For now I have no access to oscilloscope...

 

nguterresn

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have a look at the Arduino core code for the Wire object. This should give you an idea of what your code needs to do.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the reply.

I actually already did that. I'm not receiving ACK from the slave sensor, which could mean 5 things: 

1. No receiver is present on the bus with the transmitted address so there is no device to respond with an acknowledge.

2. The receiver is unable to receive or transmit because it is performing some real-time function and is not ready to start communication with the master.

3. During the transfer, the receiver gets data or commands that it does not understand.

4. During the transfer, the receiver cannot receive any more data bytes.
5. A master-receiver must signal the end of the transfer to the slave transmitter.

Since I got the correct ID value from the sensor, I don't think the first one is correct.

Still don't know what to do.

 

This is my TWIWrite function:

uint8_t TWIWrite(uint8_t reg){

    TWDR = reg;
    TWCR = (1<<TWINT)|(1<<TWEN); 
    while (!(TWCR & (1<<TWINT)));

    if ((TWSR == BUS_ERROR) || 
        (TWSR == ARBILOST) ||  
        (TWSR == SLAW_T_NACK) ||  
        (TWSR == SLAR_T_NACK) ||
        (TWSR == DATA_T_NACK)) {

            #ifdef DEBUG 
                Serial.print("Status code for TWIWrite: ");
                Serial.println(TWSR);
            #endif

            return ERROR;
        }
        
    return TWSR;
}

 

nguterresn

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys I found the solution.

 

I re-read the  I2C-bus specification and user manual. and found that the last packet read by the master receiver MUST be followed by a NACK. In others words, this: 

TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);

Must be changed to this:

TWCR = (1<<TWINT)|(1<<TWEN);

when last packed is received.

 

Thanks for the replies. Your effort was important.

nguterresn

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for feeding back.

 

Now please mark the solution - see Tip #5 (in my signature, below; may not be visible on mobile).

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...