TCS3472 color sensor on ATTiny85 does not initialise

link to breadboard picture on github

I am trying to transfer this project with TCS3472 color sensor from Arduino Nano to ATTiny85. At first I encountered som problems compiling the project because the "Adafruit_TCS34725.h" is using the arduino wire library, but finally succeeded compiling it successfull by using ATTinycore with options Board: ATTiny/25/45/85(no bootloader) and Programmer: Arduino as ISP. The next problem is that the TCS3472 somehow does not initialise. I use i2c connections that I used in other projects: SCL pin4 and SDA pin0. Tried using TinyWireM.h and wire.h which both compiles OK. Any suggestions? (beginner)

// using  ATTinycore
// Board: ATTiny/25/45/85(no bootloader)
// Programmer: Arduino as ISP

#include <Adafruit_NeoPixel.h>
#include "Adafruit_TCS34725.h"
#define  Tiny 1                   // compile for ATTiny85

#ifdef  Tiny
  #include <avr/power.h>          // Required for 16 MHz Adafruit Trinket
  #include <TinyWireM.h>          // I2C Master lib for ATTinys which use USI
  #define LED_PIN    3            // PB3 pin to which the NeoPixels are attached  
#else
  #include <Wire.h>
  #define LED_PIN    6            // pin to which the NeoPixels are attached
#endif
#define   LED_COUNT  8            // number of pixels attached to Attiny85

Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);
  
int minr,ming,minb,maxr,maxg,maxb;
int myred,mygre,myblu;
    
void setup() {

  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
    clock_prescale_set(clock_div_1);
  #endif

  strip.begin();           // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();            // Turn OFF all pixels ASAP
  strip.setBrightness(5);  // Set BRIGHTNESS to about 1/5 (max = 255)

  #ifndef  Tiny
    Serial.begin    (115200);
    while           (!Serial);
    Serial.println  ("Color View Test!");
  #else
    setcolor(0,255,0);        //green: show leds are working 
  #endif

  if (tcs.begin()) {
  #ifndef  Tiny    
    Serial.println  ("Found sensor");
  #else
    setcolor        (0,0,255);//blue: show blue leds found sensor
    delay           (1000);
  #endif
  } else {
  #ifndef  Tiny    
    Serial.println  ("No TCS34725 found ... check your connections");
  #else
    setcolor        (255,0,0);//red: show red leds no sensor found
  #endif
  while (1);                // halt!
  }

  minr=255;
  ming=minr;
  minb=minr;

}

void loop() {
  float red, green, blue;    
  delay(60);  // takes 50ms to read
  tcs.getRGB  (&red, &green, &blue);
  if (red>maxr)  {maxr=red;}
  if (red<minr)  {minr=red;}
  if (green>maxg){maxg=green;}
  if (green<ming){ming=green;}
  if (blue>maxb) {maxb=blue;}
  if (blue<minb) {minb=blue;}
  
  myred=map(int(red),  minr,maxr,0,255);
  mygre=map(int(green),ming,maxg,0,255);
  myblu=map(int(blue), minb,maxb,0,255);

#ifndef  Tiny
  Serial.print("R:");   Serial.print(String(int(red))  +"("+String(minr)+"-"+String(maxr)+")"); 
  Serial.print("\tG:"); Serial.print(String(int(green))+"("+String(ming)+"-"+String(maxg)+")"); 
  Serial.print("\tB:"); Serial.print(String(int(blue)) +"("+String(minb)+"-"+String(maxb)+")");
  Serial.print("\t");
  Serial.print((int)red, HEX); Serial.print((int)green, HEX); Serial.print((int)blue, HEX);
  Serial.print("\t");
  Serial.print(String(myred)+"/"+String(mygre)+"/"+String(myblu));
  Serial.print("\n");
#endif

  setcolor(myred,mygre,myblu);
  delay (100);
}

void setcolor(int r,int g,int b){
  strip.clear ();
  for         (int n=0;n<LED_COUNT;n++){
    strip.setPixelColor(n, strip.Color(r,g,b));
    strip.show();
    delay   (250);
  }
}

With an I2C sensor, the very first thing to do is to test the I2C connection by loading and running the I2C address scanner program, and make sure that it recognizes the sensor with the expected address.

If not, check connections, and that you have the required pullup resistors on the I2C lines.

Somehow the i2c device doesnot showup when connected to the ATTiny.

I tried this:

  • wrote a i2c scanner that displays the found address binairy on the led strip but it finds nothing
  • checked the ATTiny is running at 16MHz : Yes
  • Wire.setClock() to set the I2C clock speed to 100kHz and 10kHz, which should be compatible with the ATTiny85.
  • two pullups of 10k to sda and scl
  • 3.3v and 5v
  • compiled succesfully with wire.h or TinyWireM.h

does "i2c scanner" sketch find TCS3472 on other Arduino?

Actually it didn't and I forgot to test it on Arduino because the sensor is working there. I changed the scanner (forgot Wire.begin():wink: and now it works on arduino but still finds nothing on ATTiny i2c.
I did not succeed in changing the clock speed to 100.000. My code is on Git chameleon/MyBot4.8.ino at main · gtmans/chameleon · GitHub

There are likely to be one or more errors in the ATtiny code and/or wiring.

Post the required details, as outlined in the "How to get the best out of this forum" post, and perhaps someone can help.

chameleon

The Adafruit TCS3472 color sensor is not found on i2c bus when connected to ATTiny85

// using  ATTinycore (which supports Wire.h)
// Board: ATTiny/25/45/85(no bootloader)
// Programmer: Arduino as ISP
// ATTiny85 running at 16MHz(PLL) and burned bootloader 

#define  Tiny         1           // if defined compile for ATTiny85 io. Arduino
#define  Use_TinyWire 1           // if defined uses TiniWireM.h io. Wire.h 

#ifdef   Use_TinyWire
  #include <TinyWireM.h>          // I2C Master lib for ATTinys which use USI
//#include <USI_TWI_Master.h>
#else
//#include <Wire.h>
#endif

#ifdef   Tiny
  #include <avr/power.h>          // Required for 16 MHz Adafruit Trinket
  #define LED_PIN    3            // PB3 pin to which the NeoPixels are attached  
#else
  #define LED_PIN    6            // pin to which the NeoPixels are attached
#endif
#define   LED_COUNT  8            // number of pixels attached to NEO pixelstrip

#include <Adafruit_NeoPixel.h>
#include "Adafruit_TCS34725.h"

Adafruit_NeoPixel strip (LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);//https://learn.adafruit.com/adafruit-color-sensors/library-reference
  
int minr,ming,minb,maxr,maxg,maxb;
int myred,mygre,myblu;
    
void setup() {

  #ifndef  Tiny
    Serial.begin              (115200);
    while                     (!Serial);
    Serial.println            ("Color View Test!");
  #endif

  strip.begin();              // INITIALIZE NeoPixel strip object (REQUIRED)
  strip.show();               // Turn OFF all pixels ASAP
  strip.setBrightness(5);     // Set BRIGHTNESS to about 1/5 (max = 255)

  #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
    clock_prescale_set(clock_div_1);
//  USI_TWI_Master::init();
//  TinyWireM::USI_TWI_Master twi;
    #ifndef   Use_TinyWire
//    Wire.setClock(100000);  // set I2C clock speed to 100kHz
      Wire.setClock(10000);   // set I2C clock speed to 100kHz
    #endif                    // TinyWireM.setClock() doesnot exist
    setcolor(0,255,0);        // green: processor is running at 16mhz
  #else
    setcolor(255,0,0);        // red:   processor is not running at 16mhz or not ATTiny
  #endif

  delay(1000);
  displayAddresses();         // scan i2c bus for devices and diplay found address binairy on 8 pixel ledstrip 

  if (tcs.begin()) {
  #ifndef  Tiny    
    Serial.println            ("Found sensor");
  #else
    setcolor                  (0,0,255);//blue: show blue leds found sensor
  #endif
  } else {
  #ifndef  Tiny    
    Serial.println            ("No TCS34725 found ... check your connections");
  #else
    setcolor                  (255,0,255);//violet: no sensor found
  #endif
  while (1);                  // halt!
  }

  setcolor(0,255,0);          //green: show everything is OK
  delay                       (1000);

  minr=255;
  ming=minr;
  minb=minr;
}

void loop() {
  float red, green, blue;    
  delay(60);  // takes 50ms to read
  tcs.getRGB     (&red, &green, &blue);
  if (red>maxr)  {maxr=red;}
  if (red<minr)  {minr=red;}
  if (green>maxg){maxg=green;}
  if (green<ming){ming=green;}
  if (blue>maxb) {maxb=blue;}
  if (blue<minb) {minb=blue;}
  
  myred=map(int(red),  minr,maxr,0,255);
  mygre=map(int(green),ming,maxg,0,255);
  myblu=map(int(blue), minb,maxb,0,255);

#ifndef  Tiny
  Serial.print("R:");   Serial.print(String(int(red))  +"("+String(minr)+"-"+String(maxr)+")"); 
  Serial.print("\tG:"); Serial.print(String(int(green))+"("+String(ming)+"-"+String(maxg)+")"); 
  Serial.print("\tB:"); Serial.print(String(int(blue)) +"("+String(minb)+"-"+String(maxb)+")");
  Serial.print("\t");
  Serial.print((int)red, HEX); Serial.print((int)green, HEX); Serial.print((int)blue, HEX);
  Serial.print("\t");
  Serial.print(String(myred)+"/"+String(mygre)+"/"+String(myblu));
  Serial.print("\n");
#endif

  setcolor  (myred,mygre,myblu);
  delay     (100);
}

void setcolor(int r,int g,int b){
  strip.clear ();
  for         (int n=0;n<LED_COUNT;n++){
    strip.setPixelColor(n, strip.Color(r,g,b));
    strip.show();
    delay   (250);
  }
}


void displayAddresses() {
  int nDevices = 0;

  #ifndef  Tiny
    Serial.println("Scanning...");
  #endif
  
  #ifdef   Use_TinyWire
  //const uint32_t TWI_SPEED = 100000UL; // desired clock speed
  //TinyWireM.begin(TWI_SPEED); // set I2C clock frequency to 100 kHz does not work
    TinyWireM.begin(); 
  #else
    Wire.begin();
  #endif
  
  for (byte address = 1; address < 127; ++address) {
    byte saveA=address;
    byte binaryAddress[8]="00000000";
    byte index = 0;  
    // Converteer het I2C-adres naar binaire notatie
    while (saveA > 0) {
      binaryAddress[index++] = saveA % 2;
      saveA /= 2;
    }
    strip.clear ();
    // Schrijf het binaire adres naar de ledstrip
    for (int i = 0; i < 8; i++) {
      if (binaryAddress[i] == 1) {
        strip.setPixelColor(i, 255);
      } else {
        strip.setPixelColor(i, 0);
      }
    }
    strip.show();
    #ifndef  Tiny
      Serial.println(address);
    #endif
        
    #ifndef  Use_TinyWire
      TinyWireM.beginTransmission(address);
      byte error = TinyWireM.endTransmission();
    #else
      Wire.beginTransmission(address);
      byte error = Wire.endTransmission();
    #endif
    
    if (error == 0) {
      #ifndef  Tiny
        Serial.print("I2C device found at address 0x");
        if (address < 16) {
          Serial.print("0");
        }
        Serial.print  (address, HEX);
        Serial.print  ("HEX ");
        Serial.print  (address, BIN);
        Serial.println("BIN");
      #endif
      ++nDevices;
      delay(5000); 
     
    } else if (error == 4) {
      #ifndef  Tiny
        Serial.print("Unknown error at address 0x");
        if (address < 16) {
          Serial.print("0");
        }
        Serial.println(address, HEX);        
      #else
        setcolor(255,255,0);//REDGREEN
        delay   (5000);
      #endif
      }
      delay(50);
  }
    if (nDevices == 0) {
    #ifndef  Tiny
      Serial.println("No I2C devices found\n");
    #else
      setcolor(0,255,255);//BLUEGREEN
      delay   (5000);
    #endif
    }
}

Neither the Fritzing diagram, nor the photo, show the required 100 nF decoupling capacitor across the ATTiny power and ground connections.

The breadboard PHOTO does not show the required pullup resistors on SDA and SCL. Please explain.

Does the ATtiny run any program? Add an LED plus current limiting resistor, and test it with the Blink program.

Sorry. The breadboard PHOTO was taken earlier. First I added 10K pullups, later replaced them by 2k2 as on the fritzing sceme

Yes the ATTiny runs this and other programs. This running program does a portscan and displays the binairy addresses it scans on the Neopixel strip. After that it diplays a specific color when no mudule was found.

When I replace the sensor by another i2c device it finds the address straight away.

I will try to get that capacitor. Thx for the tip.

To test a new device, always start with the minimum possible example code.

For example, the neopixel library turns off interrupts, required for I2C communications.

So back to the minimum. Written an i2c scan that only uses one led. When it blinks 5 times it found a device on i2c. It does not find the TCS3472 but does find (when connected instead of TCS-module) other i2c devices like .96 oled screen

new i2c scanner for one led:

// --------------------------------------
// i2c_scanner ATTiny85 led debug blinks 5 times when i2c device found
// using  ATTinycore (which supports Wire.h)
// Board: ATTiny/25/45/85(no bootloader)
// Programmer: Arduino as ISP
// ATTiny85 running at 16MHz(PLL) and burned bootloader for 16MHz
// --------------------------------------

#include <TinyWireM.h>          // I2C Master lib for ATTinys which use USI
#include <avr/power.h>          // Required for 16 MHz Adafruit Trinket
#include "Adafruit_TCS34725.h"
#define   TST_LED    4          // PB4 pin to which the led is attached  

Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_50MS, TCS34725_GAIN_4X);//https://learn.adafruit.com/adafruit-color-sensors/library-reference

void setup() {
   pinMode                   (TST_LED, OUTPUT);
   for (int i=0;i<3;i++)     {digitalWrite(TST_LED, HIGH);delay(500);digitalWrite(TST_LED, LOW);delay(500);}
                             delay(1000); // blink 3 times and wait a second
   TinyWireM.begin();
   scani2c();                 // (3 initial+) 5 blinks=found device 10 blinks=error 15 blinks=no deviced found
 
   if (tcs.begin()) {
    digitalWrite(TST_LED, HIGH);// led on  means found a device  on i2c
   } else {
    digitalWrite(TST_LED, LOW);// led off means no device found on i2c
   }
}

void loop() {}

void scani2c() {
  int nDevices=0;
  for (byte address = 1; address < 127; ++address) {
    // The i2c_scanner uses the return value of
    // the Wire.endTransmission to see if
    // a device did acknowledge to the address.
    TinyWireM.beginTransmission(address);
    byte error = TinyWireM.endTransmission();

    if (error == 0) {
      // I2C device found at address 0x
      for (int i=0;i<5;i++)   {digitalWrite(TST_LED, HIGH);delay(500);digitalWrite(TST_LED, LOW);delay(500);}
                              delay(1000); // blink 5 times and wait a second      
      nDevices++;
    } else if (error == 4) {
      for (int i=0;i<10;i++)  {digitalWrite(TST_LED, HIGH);delay(500);digitalWrite(TST_LED, LOW);delay(500);}
                              delay(1000); // blink 10 times and wait a second
    }
  }
  if (nDevices == 0) {
      for (int i=0;i<15;i++)  {digitalWrite(TST_LED, HIGH);delay(500);digitalWrite(TST_LED, LOW);delay(500);}
                              delay(1000); // blink 15 times and wait a second
  }
}

result

I could not get the TCS3472 color sensor to work with ATTiny85. So I switched to Seeeduino Xiao and it works like a charm. This post can be closed, thanks for your help. More at https://github.com/gtmans/chameleon

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.