Tsl2561 luminosity sensor not giving correct value

int scl=52;
int sda=53;
unsigned int arr[4];
double ch0,ch1;

#define SDA_HIGH   pinMode(sda,INPUT)
#define SDA_LOW   pinMode(sda,OUTPUT)
#define SCL_HIGH  digitalWrite(scl,HIGH)
#define SCL_LOW   digitalWrite(scl,LOW)


void delay_i2c()
{
  delayMicroseconds(1);
}
void starti2c()
{
  SDA_HIGH;
  delay_i2c();
  SCL_HIGH;
  delay_i2c();
  SDA_LOW;
  delay_i2c();
  SCL_LOW;
}

void stopi2c(void)
{
  SCL_LOW;
  delay_i2c();
  SCL_HIGH;
  delay_i2c();
  SDA_LOW;
  delay_i2c();
  SDA_HIGH;             
  delay_i2c();
}
void clocki2c()
{
  SCL_HIGH;
  delay_i2c();
  SCL_LOW;
  delay_i2c();
}

void i2c_tx(byte data) {
  for (byte bits = 0; bits < 8 ; bits++) {              /////////////1-7 bit
    if(0x80 & data)
    {
      SDA_HIGH;
    }
    else
    {
       SDA_LOW;
    }
    data = data << 1;
    clocki2c();
 }
 SDA_LOW;
 clocki2c();
 
 SCL_HIGH;
 SDA_HIGH;
 SCL_LOW;
 delay_i2c();  
}

unsigned char i2c_rx()
{
  byte d=0;
  SDA_HIGH;
  for (int bits = 0; bits < 8 ; bits++) {              /////////////1-7 bit
    if(digitalRead(sda))
    {
      d=d+1;
    }
    else
    {
      d=d+0;
    }
    SCL_HIGH;
    //delay_i2c();    
    
    d = d << 1;
    SCL_LOW;
    //delay_i2c();
 }
 SDA_LOW;
 clocki2c();
 
 SCL_HIGH;
 delay_i2c();
 SCL_LOW;
 SDA_HIGH;
 return d;     
}

void wakeupi2c()
{
  ////////////////////////////////////////power on
  starti2c();
  i2c_tx(0x39);        //0x39
  i2c_tx(0x80);       //0x80
  i2c_tx(0x03);      //0x03
  stopi2c();
////////////////////////////////////////set gain
  starti2c();
  i2c_tx(0x39);
  i2c_tx(0x81);     //0x81
  i2c_tx(0x02);     //0x02
  stopi2c();
}

void fetching_output()         
{
  for(int i = 0; i < 4; i++)
  {
    ///////////////////////////////////////////////////////////sending ch0,ch1 registers value
    starti2c();
    i2c_tx(57);
    i2c_tx(140+i); ////////////////////////// 08C,08D,08E,08F
    //stopi2c();
   ////////////////////////////////////////////////////////////  reading
    starti2c();
    i2c_tx(57);
    arr[i]=i2c_rx();
    stopi2c();
    delay(200);
  }
}

void disp_data()
{
  ch0=(256*(arr[1]& 0xFF)+(arr[0]& 0xFF));
  ch1=(256*(arr[3]& 0xFF)+(arr[2]& 0xFF));
  Serial.print("ch0 = ");
  Serial.println(ch0);
  Serial.print("ch1 = ");
  Serial.println(ch1);
  Serial.print("ch1 - ch0 = ");
  Serial.println(ch0-ch1);
}

void setup() {
  pinMode(scl,OUTPUT);
  Serial.begin(9600);
  wakeupi2c();
}
void loop() {
  //Serial.println(read_TSL2561C0());
  fetching_output();
  disp_data();
  delay(500);
}

How do you know that the value is wrong ?

its giving the max value.

Does it work correctly if you use a library such as GitHub - adafruit/TSL2561-Arduino-Library: Arduino library for using the TSL2561 Luminosity sensor

Yes its working fine with the library

Did you write the pin-toggle code yourself ? And it never worked before ? So you question is not about the TSL2561, but about your pin-toggle code ?
You can still edit the topic title. For example: "Trying pin-toggle I2C".

The text of your code is not consistent. The indents, the style with the brackets, the way you use new lines. I sometimes say that a sketch will not work well if the text layout of the source code is a mess.

I'm sorry to say, but that will not work. If I have to fix it, then I have to rewrite everything from scratch.
I get the feeling that the code is not okay in at least three places.
So I put your code in Wokwi and used the simulated logic analyzer: pinToggleI2C.ino - Wokwi Arduino and ESP32 Simulator
On my computer I let PulseView try to read the I2C signal, but it can not do that correctly.
Wokwi does not have the TSL2561, so I replaced it with a DS1307.

If you want a pin-toggle software I2C library, you can pick one from this list: https://github.com/Testato/SoftwareWire/wiki/Arduino-I2C-libraries.

However, if you want a software I2C library, I would like to hear a good explanation. Please just use the normal hardware I2C bus and the Arduino Wire library.

But i want to run it without using the library

its giving the max value pinToggleI2C.ino - Wokwi Arduino and ESP32 Simulator

Please explain.
Which library do you not want to use and why ?

As I wrote before, I can not fix your code. I would have to rewrite it from scratch.

My Wokwi simulation is not about the data, it was to get the signals in PulseView.

without using the wire library in arduino. The i2c_tx function is giving the sensor address correctly which is (57 DEC) but no giving the sensor value.

i just want to make my own code for tsl2561 using clock pulses.

Why do you not want to use the Arduino Wire library ?

If you want a good programming exercise, then I suggest to start all over. You need a Logic Analyzer to check everything you do. A simulated Logic Analyzer in Wokwi is helpful, but a real Logic Analyzer might be easier.

In my screendump of Reply #6, the first writing of the address is okay. After that the I2C decoder can not read the I2C signal anymore, then it can read it again and then it fails again.

Please change the topic title.

its giving max value not fetching the correct one

Your code is not correct. You have to start all over.
Please change the topic title.

To avoid pulling SCL low in setup(), you can do this:

void setup() {
  digitalWrite(scl, HIGH);      // preset SCL to HIGH
  pinMode(scl, OUTPUT);         // turn it to OUTPUT HIGH

Note that you can not use a Arduino as a I2C Slave and probably also not a BNO055 sensor when the SCL signal is not a open-drain (or open-collector) signal.

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