Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extracting data from output #1

Open
ITstreet1 opened this issue Nov 17, 2021 · 78 comments
Open

Extracting data from output #1

ITstreet1 opened this issue Nov 17, 2021 · 78 comments

Comments

@ITstreet1
Copy link

I tried this sniffer and it works just fine.

My question is:
If I get say, this line in the output buffer
S0100000W+00001000+s
I can see that on the 0100000 address I have 00001000 data. How to take this data for this specific address and do something with it? Maybe send to a server. Do anything.

The reason is, if there are multiple I2C devices, and I want to monitor only specific. So if I get a bunch of those readings and want to filter all of them and take only this one, cut everything and send this 00001000 to a server.

Any help would be appreciated.

@WhitehawkTailor
Copy link
Owner

Hi,

this is a very simple solution that displays the traffic only.
There is no logic implemented in the code to process the communication.
In order to implement the functionality you need to process the communication flow by separating the address part and the data part.
Having the address information it can be decided if it is the one you are interested.
For the observed address you can get the data sent by or read by the Master.
This data can be processed or transfered to other devices via any connection (other serial, WiFi, Bluetooth).

In my code the processDataBuffer() is the place that processes the communication flow. My code just prints out the characters. This is the place that can be extended with the additional code to identify the address and process the data.
The message exchange character series can be processed with a regexp expression (sorry I am not an expert in this), or with a string processing solution implemented by you.
this could go like:
create one string from the character flow from S to s
split the string to address and data. first part from S to W/R is the address
decide if the address is the one that you need
if so then process the data part from + to + and send it out.

I hope this pseudo code can help you.

@ITstreet1
Copy link
Author

I know the logic I need, but not how to achieve it. :)
I tried to "fix" a line or two, but just broke everything.
It is hard to follow the logic all the way. Maybe not to you.

@ITstreet1
Copy link
Author

I wonder, could it be packed in some sort of a string or so? So it could be sent to a server as it is.

@WhitehawkTailor
Copy link
Owner

There is a simple solution and a difficult.
Simple solution just send data are in the buffer as string to a server when processDataBuffer() is being called. This does not assure that the string will contain accomplished I2C communication. It may happen that the sting will contain one and a half message. In this case on the receiver server you have to implement the logic to understand the messages and process them.

Difficult solution is to put the complete command into a sting when all the character is read from the I2C line. This requires more logic implementation into processDataBuffer().

Would the simple solution be enough for you?

@ITstreet1
Copy link
Author

I have modified your sketch to filter specific I2C address, so in the output, I get only an array of bytes I need. That part is OK.
As an output, I get what I expect. It is ok to send it as it is on a server. When in a database, I can process it as I want.

Some solution to send it as simple as it can be, would be nice.

Later, I could post it here so you can give it a touch or two to make it useful for others.

@WhitehawkTailor
Copy link
Owner

That is nice from you.
When you think just send it over and I will extend the project with it.
Thx

@ITstreet1
Copy link
Author

/**
 * @AUTHOR Ákos Szabó (Whitehawk Tailor) - aaszabo@gmail.com
 * 
 * This is an I2C sniffer that logs traffic on I2C BUS.
 * 
 * It is not part of the I2C BUS. It is neither a Master, nor a Slave and puts no data to the lines.
 * It just listens and logs the communication.
 * 
 * Two pins as imput are attached to SDC and SDA lines.
 * Since the I2C communications runs on 400kHz so,
 * the tool that runs this program should be fast.
 * This was tested on an ESP32 bord Heltec WiFi Lora32 v2
 * ESP32 core runs on 240MHz.
 * It means there are 600 ESP32 cycles during one I2C clock tick.
 *
 * 
 * The program uses interrupts to detect
 * the raise edge of the SCL - bit transfer 
 * the falling edge of SDA if SCL is HIGH- START
 * the raise edge of SDA if SCL id HIGH - STOP 
 * 
 * In the interrupt routines there is just a few line of code
 * that mainly sets the status and stores the incoming bits.
 * Otherwise the program gets timeout panic in interrupt handler and
 * restart the CPU.
 * 
 */


//#include <Arduino.h>

//#define I2CTEST  //use it to  run a blinking LED test on SDA and SCL pins

#define PIN_SDA 12  //BLUE
#define PIN_SCL 13  //Yellow

#define I2C_IDLE 0
//#define I2C_START 1
#define I2C_TRX 2
//#define I2C_RESP 3
//#define I2C_STOP 4

bool stampaj = 1;

// Promeniti u trazenu adresu
//pcf8574 - S0100000
//bilo -S1101101
const volatile byte adresa[] = "S0100000";//Adresa I2C uredjaja, slovo S na pocetku ne brisati
//

static volatile byte i2cStatus = I2C_IDLE;//Status of the I2C BUS
static uint32_t lastStartMillis = 0;//stoe the last time
static volatile byte dataBuffer[9600];//Array for storing data of the I2C communication
static volatile uint16_t bufferPoiW=0;//points to the first empty position in the dataBufer to write
static uint16_t bufferPoiR=0;//points to the position where to start read from
static volatile byte bitCount = 0;//counter of bit appeared on the BUS
static volatile uint16_t byteCount =0;//counter of bytes were writen in one communication.
static volatile byte i2cBitD =0;//Container of the actual SDA bit
static volatile byte i2cBitD2 =0;//Container of the actual SDA bit
static volatile byte i2cBitC =0;//Container of the actual SDA bit
static volatile byte i2cClk =0;//Container of the actual SCL bit
static volatile byte i2cAck =0;//Container of the last ACK value
static volatile byte i2cCase =0;//Container of the last ACK value
static volatile uint16_t falseStart = 0;//Counter of false start events
//static volatile byte respCount =0;//Auxiliary variable to help detect next byte instead of STOP
//these variables just for statistic reasons
static volatile uint16_t sclUpCnt = 0;//Auxiliary variable to count rising SCL
static volatile uint16_t sdaUpCnt = 0;//Auxiliary variable to count rising SDA
static volatile uint16_t sdaDownCnt = 0;//Auxiliary variable to count falling SDA


////////////////////////////
//// Interrupt handlers
/////////////////////////////

/**
 * Rising SCL makes reading the SDA
 * 
 */
void IRAM_ATTR i2cTriggerOnRaisingSCL() 
{
  sclUpCnt++;
  
  //is it a false trigger?
  if(i2cStatus==I2C_IDLE)
  {
    falseStart++;
    //return;//this is not clear why do we have so many false START
  }


  //get the value from SDA
  i2cBitC =  digitalRead(PIN_SDA);

  //decide wherewe are and what to do with incoming data
  i2cCase = 0;//normal case

  if(bitCount==8)//ACK case
    i2cCase = 1;

  if(bitCount==7 && byteCount==0 )// R/W if the first address byte
    i2cCase = 2;

  bitCount++;

  switch (i2cCase)
  {
    case 0: //normal case
      dataBuffer[bufferPoiW++] = '0' + i2cBitC;//48
    break;//end of case 0 general
    case 1://ACK
      if(i2cBitC)//1 NACK SDA HIGH
        {
          dataBuffer[bufferPoiW++] = '-';//45
        }
        else//0 ACK SDA LOW
        {
          dataBuffer[bufferPoiW++] = '+';//43
        } 
      byteCount++;
      bitCount=0;
    break;//end of case 1 ACK
    case 2:
      if(i2cBitC)
      {
        dataBuffer[bufferPoiW++] = 'R';//82
      }
      else
      {
        dataBuffer[bufferPoiW++] = 'W';//87
      }
    break;//end of case 2 R/W

  }//end of switch

}//END of i2cTriggerOnRaisingSCL() 

/**
 * This is for recognizing I2C START and STOP
 * This is called when the SDA line is changing
 * It is decided inside the function wheather it is a rising or falling change.
 * If SCL is on High then the falling change is a START and the rising is a STOP.
 * If SCL is LOW, then this is the action to set a data bit, so nothing to do.
 */
void IRAM_ATTR i2cTriggerOnChangeSDA()
{
  //make sure that the SDA is in stable state
  do
  {
    i2cBitD =  digitalRead(PIN_SDA);
    i2cBitD2 =  digitalRead(PIN_SDA);
  } while (i2cBitD!=i2cBitD2);

  //i2cBitD =  digitalRead(PIN_SDA);

  if(i2cBitD)//RISING if SDA is HIGH (1)
  {
    
    i2cClk = digitalRead(PIN_SCL);
    if(i2cStatus=!I2C_IDLE && i2cClk==1)//If SCL still HIGH then it is a STOP sign
    {     
      //i2cStatus = I2C_STOP;
      i2cStatus = I2C_IDLE;
      bitCount = 0;
      byteCount = 0;
      bufferPoiW--;
      dataBuffer[bufferPoiW++] = 's';//115
      dataBuffer[bufferPoiW++] = '\n'; //10
    }
    sdaUpCnt++;
  }
  else //FALLING if SDA is LOW
  {
    
    i2cClk = digitalRead(PIN_SCL);
    if(i2cStatus==I2C_IDLE && i2cClk)//If SCL still HIGH than this is a START
    {
      i2cStatus = I2C_TRX;
      //lastStartMillis = millis();//takes too long in an interrupt handler and caused timeout panic and CPU restart
      bitCount = 0;
      byteCount =0;
      dataBuffer[bufferPoiW++] = 'S';//83 STOP
      //i2cStatus = START;    
    }
    sdaDownCnt++;
  }
}//END of i2cTriggerOnChangeSDA()


////////////////////////////////
//// Functions
////////////////////////////////

/**
 * Reset all important variable
 */
void resetI2cVariable()
{
  i2cStatus = I2C_IDLE;
  bufferPoiW=0;
  bufferPoiR=0;
  bitCount =0;
  falseStart = 0;
}//END of resetI2cVariable()


/**
* @DESC Write out the buffer to the serial console
*
*/
void processDataBuffer()
{
  if(bufferPoiW == bufferPoiR)//There is nothing to say
    return;

  uint16_t pw = bufferPoiW;
  //print out falseStart
  Serial.printf("\nSCL up: %d SDA up: %d SDA down: %d false start: %d\n", sclUpCnt, sdaUpCnt, sdaDownCnt, falseStart);

  //Adres filter
  for(int i=bufferPoiR; i< (bufferPoiR+8); i++)
  {
    if (dataBuffer[i] != adresa[i]) stampaj=0;
  }

  //print out the content of the buffer
  if (stampaj)
  {
    for(int i=bufferPoiR; i< pw; i++)
    {
      Serial.write(dataBuffer[i]);
      bufferPoiR++;  
    } 
  }
  stampaj=1;  
  
  //if there is no I2C action in progress and there wasn't during the Serial.print then buffer was printed out completly and can be reset.
  if(i2cStatus == I2C_IDLE && pw==bufferPoiW)
  {
    bufferPoiW =0;
    bufferPoiR =0;
  } 
}//END of processDataBuffer()


/////////////////////////////////
////  MAIN entry point of the program
/////////////////////////////////
void setup() 
{

  #ifdef I2CTEST
  pinMode(PIN_SCL, OUTPUT);   
    pinMode(PIN_SDA, OUTPUT); 
  #else
  //Define pins for SCL, SDA
  pinMode(PIN_SCL, INPUT_PULLUP);   
    pinMode(PIN_SDA, INPUT_PULLUP);
  //pinMode(PIN_SCL, INPUT);   
    //pinMode(PIN_SDA, INPUT);


    //reset variables
    resetI2cVariable();

    //Atach interrupt handlers to the interrupts on GPIOs
    attachInterrupt(PIN_SCL, i2cTriggerOnRaisingSCL, RISING); //trigger for reading data from SDA
  attachInterrupt(PIN_SDA, i2cTriggerOnChangeSDA, CHANGE); //for I2C START and STOP
  #endif
  Serial.begin(115200);
}//END of setup

/**
 * LOOP
 */
void loop() 
{

  #ifdef I2CTEST
  digitalWrite(PIN_SCL, HIGH);   //13 SARGA
    digitalWrite(PIN_SDA, HIGH);  //12 KEK
  delay(500);
  digitalWrite(PIN_SCL, HIGH);   //13 SARGA
    digitalWrite(PIN_SDA, LOW); //12 KEK
  delay(500);
  #else

    //if it is in IDLE, then write out the databuffer to the serial consol
    if(i2cStatus == I2C_IDLE)
  {
    processDataBuffer();
        Serial.print("\rStart delay    ");    
        delay(5000);
        Serial.print("\rEnd delay    ");
    delay(500);
  }

  #endif

}//END of loop

Here you are.

You may notice a new const volatile byte adresa[ ]
There one should put the I2C address that needs, and as output, there will be ONLY data from that address. This works.

In a processDataBuffer function, you will notice all the logic I implemented. It is only basic. Check if there are data with that address, if there is, print it. If not, move on.

@ITstreet1
Copy link
Author

ITstreet1 commented Dec 27, 2021

I connected basic PCF8574 with two LEDs on Nano. With ESP32 and ISO1540 I get the expected data. This is the form:

S0100000W+10001000+s
S0100000W+00001000+s
S0100000W+10001000+s
S0100000W+10000000+s
S0100000W+10001000+s
S0100000W+00001000+s

This should be packed in something like this as a String:

S0100000W+10001000+sS0100000W+00001000+sS0100000W+10001000+sS0100000W+10000000+sS0100000W+10001000+sS0100000W+00001000+s

@ITstreet1
Copy link
Author

If I change byte adresa [ ] from 0100000 to something else, I get nothing.

On a server, I can easily cut it into pieces and do whatever I want. But first things first. Let's send it.

@WhitehawkTailor
Copy link
Owner

thanx for the code.
But let me notice that this is not a perfect code. You cannot be sure this will work in any cases. You will experience data loss.
It works if you are lucky and all the circumstances are good.

The implemented logic to follow the communication uses interrupts.
That is why the main loop does nothing but process the buffer. The buffer is written by the routines called by the interrupts.

So here is the thing.
When processDataBuffer() is called from the main loop you cannot be sure that there is a whole complete message in it. It may happened the message has only a few bytes of an address like this:
S010000
And when the processDataBuffer() is called again then you will see the second part of it only, because former processDataBuffer() cleaned it up:
0W+10001000+s
In neither case your address checking will find it as a proper address.

In case when there is rare communication and only one or none happens during the delayed loop, then you are lucky and your code works in most of the time.
It can happen that the processDataBuffer() is called by the main loop in the middle of an I2C message then again you will see only part of a communication message. Your experience will be that some messages are missing.

To handle all of this makes it so difficult, if you want to implement the logic in the processDataBuffer().
The challenge is to process the data only in case that contains full I2C messages. Or in case there are multiple messages and a part as well, then process full messages only and leave the half in the array.

@ITstreet1
Copy link
Author

I noticed all the issues a time or two you mention. It is fair enough.

On a server, everything can be cut into pieces. And nothing is important that much. If you know what to expect, everything that is not a match, just cut off.

The main goal should be to send it to a server. And that is a little bit tricky for me. If you have a solution to take the data from a buffer, no matter what is in it, and put it in a String...

@WhitehawkTailor
Copy link
Owner

What is the protocol that the destination server expects?
Is it an HTTP request or any API that needs data in XML or JSON?
What is the transfer type? Is it WiFi?

@ITstreet1
Copy link
Author

HTTPGet request
ESP32.
SQL
PHP

I think if it could be packed in a String, it would be more than enough.

@WhitehawkTailor
Copy link
Owner

then the processDataBuffer() should be modified to check if the buffer contains whole S...s pieces and send them via a HTTP GET message.
One question that need to be checked is the frequency of I2C message.
If I2C messages come too frequently then you have to have a buffer big enough to store messages temporarily.
Second question is how frequently the server can be requested with the GET message.
This to timing question will define the delay in the main loop and the size of the buffer to store I2C messages temporarily.

@ITstreet1
Copy link
Author

I would try to go no matter if any garbage in or not. Is it whole or not. That could be easily filtered on the server. It is not that important if something is missing.
As for time, I think, some say 10 sec or so. Maybe more, it doesn't matter that much. Let's try it as is.

Later I will add some other I2C devices, just to see how it works. Or some other I2C expander with 2 ports.

To be honest my goal is to monitor some devices that do things in a loop. So if not good in the first reading, it will be in second. Or third.

@WhitehawkTailor
Copy link
Owner

In this case it is easy, just make the main loop to send out whatever is in the dataBuffer as a string. For this you just have to modify the processDataBuffer() to put everything into a message string from the dataBuffer and send it out.

@ITstreet1
Copy link
Author

I know that, but not sure how. I am messing up pretty much with putting buffer in a String. Didn't move an inch.
Not sure how to modify it.

That is why I am here.

@WhitehawkTailor
Copy link
Owner

I made some modification to make available the sending.
Please check parts in the code that is marked with v1.1 and see the descriptions.
I am not sure if it works, because I don't have the setup assembled to test it.
You have to extend this code with the communication, like access WiFi, send an HTTP request, etc.

Here is the modified code:
`/**

  • @author Ákos Szabó (Whitehawk Tailor) - aaszabo@gmail.com
  • This is an I2C sniffer that logs traffic on I2C BUS.
  • IDE: Visual Studio Code + PlatformIO
  • Platform: Arduino for ESP32
  • Board: Heltec WiFi Lora32 v2
  • GPIO12 SDA
  • GPIO13 SCL
  • This is not connecting to the BUS as an I2C device. It is neither a Master, nor a Slave.
  • It just listens and logs the communication.
  • The application does not interrupt the I2C communication.
  • Two pins as input are attached to SDC and SDA lines.
  • Since the I2C communications runs on 400kHz so,
  • the tool that runs this program should be fast.
  • This was tested on an ESP32 bord Heltec WiFi Lora32 v2
  • ESP32 core runs on 240MHz.
  • It means there are 600 ESP32 cycles during one I2C clock tick.
  • The program uses interrupts to detect
  • the raise edge of the SCL - bit transfer
  • the falling edge of SDA if SCL is HIGH- START
  • the raise edge of SDA if SCL id HIGH - STOP
  • In the interrupt routines there is just a few line of code
  • that mainly sets the status and stores the incoming bits.
  • Otherwise the program gets timeout panic in interrupt handler and
  • restart the CPU.
  • v1.0
  • Basic operation and put message to eh serial output
  • v1.1
  • See additional parts marked with the version title v1.1
  • The additionals makes possible to send the logged I2C communication content to a server via HTTP request.
    */

#include <Arduino.h>

//#define I2CTEST //use it to run a blinking LED test on SDA and SCL pins

#define PIN_SDA 12 //BLUE
#define PIN_SCL 13 //Yellow

#define I2C_IDLE 0
//#define I2C_START 1
#define I2C_TRX 2
//#define I2C_RESP 3
//#define I2C_STOP 4

static volatile byte i2cStatus = I2C_IDLE;//Status of the I2C BUS
static uint32_t lastStartMillis = 0;//stoe the last time
static volatile byte dataBuffer[9600];//Array for storing data of the I2C communication
static volatile uint16_t bufferPoiW=0;//points to the first empty position in the dataBufer to write
static uint16_t bufferPoiR=0;//points to the position where to start read from
static volatile byte bitCount = 0;//counter of bit appeared on the BUS
static volatile uint16_t byteCount =0;//counter of bytes were writen in one communication.
static volatile byte i2cBitD =0;//Container of the actual SDA bit
static volatile byte i2cBitD2 =0;//Container of the actual SDA bit
static volatile byte i2cBitC =0;//Container of the actual SDA bit
static volatile byte i2cClk =0;//Container of the actual SCL bit
static volatile byte i2cAck =0;//Container of the last ACK value
static volatile byte i2cCase =0;//Container of the last ACK value
static volatile uint16_t falseStart = 0;//Counter of false start events
//static volatile byte respCount =0;//Auxiliary variable to help detect next byte instead of STOP
//these variables just for statistic reasons
static volatile uint16_t sclUpCnt = 0;//Auxiliary variable to count rising SCL
static volatile uint16_t sdaUpCnt = 0;//Auxiliary variable to count rising SDA
static volatile uint16_t sdaDownCnt = 0;//Auxiliary variable to count falling SDA

//v1.1
//Store the begining of the communication string. Modify it according to your setup.
String msgToServer = "http://192.168.0.19:5544/I2cServer?ADDR=0100000&data=";

////////////////////////////
//// Interrupt handlers
/////////////////////////////

/**

  • This is the rising SCL interrupt handler
  • Rising SCL makes reading the SDA

*/
void IRAM_ATTR i2cTriggerOnRaisingSCL()
{
sclUpCnt++;

//is it a false trigger?
if(i2cStatus==I2C_IDLE)
{
	falseStart++;
	//return;//this is not clear why do we have so many false START
}


//get the value from SDA
i2cBitC =  digitalRead(PIN_SDA);

//decide wherewe are and what to do with incoming data
i2cCase = 0;//normal case

if(bitCount==8)//ACK case
	i2cCase = 1;

if(bitCount==7 && byteCount==0 )// R/W if the first address byte
	i2cCase = 2;

bitCount++;

switch (i2cCase)
{
	case 0: //normal case
		dataBuffer[bufferPoiW++] = '0' + i2cBitC;//48
	break;//end of case 0 general
	case 1://ACK
		if(i2cBitC)//1 NACK SDA HIGH
			{
				dataBuffer[bufferPoiW++] = '-';//45
			}
			else//0 ACK SDA LOW
			{
				dataBuffer[bufferPoiW++] = '+';//43
			}	
		byteCount++;
		bitCount=0;
	break;//end of case 1 ACK
	case 2:
		if(i2cBitC)
		{
			dataBuffer[bufferPoiW++] = 'R';//82
		}
		else
		{
			dataBuffer[bufferPoiW++] = 'W';//87
		}
	break;//end of case 2 R/W

}//end of switch

}//END of i2cTriggerOnRaisingSCL()

/**

  • This is the SDA interrupt handler

  • This is for recognizing I2C START and STOP

  • This is called when the SDA line is changing

  • It is decided inside the function wheather it is a rising or falling change.

  • If SCL is on High then the falling change is a START and the rising is a STOP.

  • If SCL is LOW, then this is the action to set a data bit, so nothing to do.
    */
    void IRAM_ATTR i2cTriggerOnChangeSDA()
    {
    //make sure that the SDA is in stable state
    do
    {
    i2cBitD = digitalRead(PIN_SDA);
    i2cBitD2 = digitalRead(PIN_SDA);
    } while (i2cBitD!=i2cBitD2);

    if(i2cBitD)//RISING if SDA is HIGH (1)
    {

     i2cClk = digitalRead(PIN_SCL);
     if(i2cStatus=!I2C_IDLE && i2cClk==1)//If SCL still HIGH then it is a STOP sign
     {			
     	//i2cStatus = I2C_STOP;
     	i2cStatus = I2C_IDLE;
     	bitCount = 0;
     	byteCount = 0;
     	bufferPoiW--;
     	dataBuffer[bufferPoiW++] = 's';//115
     	dataBuffer[bufferPoiW++] = '\n'; //10
     }
     sdaUpCnt++;
    

    }
    else //FALLING if SDA is LOW
    {

     i2cClk = digitalRead(PIN_SCL);
     if(i2cStatus==I2C_IDLE && i2cClk)//If SCL still HIGH than this is a START
     {
     	i2cStatus = I2C_TRX;
     	//lastStartMillis = millis();//takes too long in an interrupt handler and caused timeout panic and CPU restart
     	bitCount = 0;
     	byteCount =0;
     	dataBuffer[bufferPoiW++] = 'S';//83 STOP
     	//i2cStatus = START;		
     }
     sdaDownCnt++;
    

    }
    }//END of i2cTriggerOnChangeSDA()

////////////////////////////////
//// Functions
////////////////////////////////

/**

  • Reset all important variable
    */
    void resetI2cVariable()
    {
    i2cStatus = I2C_IDLE;
    bufferPoiW=0;
    bufferPoiR=0;
    bitCount =0;
    falseStart = 0;
    }//END of resetI2cVariable()

/**

  • @desc Write out the buffer to the serial console

*/
void processDataBuffer()
{
if(bufferPoiW == bufferPoiR)//There is nothing to say
return;

uint16_t pw = bufferPoiW;
//print out falseStart
Serial.printf("\nprocessDataBuffer\nSCL up: %d SDA up: %d SDA down: %d false start: %d\n", sclUpCnt, sdaUpCnt, sdaDownCnt, falseStart);
//print out the content of the buffer	
for(int i=bufferPoiR; i< pw; i++)
{
	Serial.write(dataBuffer[i]);
	bufferPoiR++;		
}

//if there is no I2C action in progress and there wasn't during the Serial.print then buffer was printed out completly and can be reset.
if(i2cStatus == I2C_IDLE && pw==bufferPoiW)
{
	bufferPoiW =0;
	bufferPoiR =0;
}	

}//END of processDataBuffer()

/**

  • v1.1
  • @desc This method returns a String that contains everything that is available in the dataBuffer
  • This function also resets the buffer, so this and processDataBuffer cannot be used in the same time.
  • @ret String value. Returns the whole content of the dataBuffer as a string.

*/
String getStringFromDataBuffer()
{
String ret = "";
if(bufferPoiW == bufferPoiR)//There is nothing to say
return;

uint16_t pw = bufferPoiW;
//print out falseStart
Serial.printf("\ngetStringFromDataBuffer\nSCL up: %d SDA up: %d SDA down: %d false start: %d\n", sclUpCnt, sdaUpCnt, sdaDownCnt, falseStart);
//print out the content of the buffer	
for(int i=bufferPoiR; i< pw; i++)
{
	ret += (char)dataBuffer[i];		
	bufferPoiR++;		
}

//if there is no I2C action in progress and there wasn't during the Serial.print then buffer was printed out completly and can be reset.
if(i2cStatus == I2C_IDLE && pw==bufferPoiW)
{
	bufferPoiW =0;
	bufferPoiR =0;
}

return ret;

}//END of processDataBuffer()

/**

  • v1.1
  • This is an empty method.
  • Write here any communication with a server

*/
void sendMsgOut(String argStr)
{

}

/////////////////////////////////
//// MAIN entry point of the program
/////////////////////////////////
void setup()
{

#ifdef I2CTEST
pinMode(PIN_SCL, OUTPUT);   
pinMode(PIN_SDA, OUTPUT);	
#else
//Define pins for SCL, SDA
pinMode(PIN_SCL, INPUT_PULLUP);   
pinMode(PIN_SDA, INPUT_PULLUP);
//pinMode(PIN_SCL, INPUT);   
//pinMode(PIN_SDA, INPUT);


//reset variables
resetI2cVariable();

//Atach interrupt handlers to the interrupts on GPIOs
attachInterrupt(PIN_SCL, i2cTriggerOnRaisingSCL, RISING); //trigger for reading data from SDA
attachInterrupt(PIN_SDA, i2cTriggerOnChangeSDA, CHANGE); //for I2C START and STOP
#endif
Serial.begin(115200);

}//END of setup

/**

  • LOOP

  • v1.0

  • @desc Writes I2C mcommunication to the serial if there is any.

  • v1.1

  • @desc uses sendMsgOut to send I2C mcommunication to the specified server and format given by the msgToServer variable
    */
    void loop()
    {

    #ifdef I2CTEST //do this in case it is testing the lines
    digitalWrite(PIN_SCL, HIGH); //13 Yellow
    digitalWrite(PIN_SDA, HIGH); //12 Blue
    delay(500);
    digitalWrite(PIN_SCL, HIGH); //13 Yellow
    digitalWrite(PIN_SDA, LOW); //12 Blue
    delay(500);
    #else
    //if it is in IDLE, then write out the databuffer to the serial consol
    if(i2cStatus == I2C_IDLE)
    {
    //v1.0
    //processDataBuffer();

     	//v1.1
     	//Get the content of the dataBuffer as a string and put it into a message
     	//Send out the message
     	//make sure that the msgToServer string variable is set properly above in the global variable section.
     	sendMsgOut( msgToServer + getStringFromDataBuffer());
    
     	//Delay the loop
         Serial.print("\rStart delay    ");		
         delay(5000);
         Serial.print("\rEnd delay    ");
         delay(500);
     }
    

    #endif

}//END of loop
`

@WhitehawkTailor
Copy link
Owner

I hope it helps you. Good luck!

@ITstreet1
Copy link
Author

Nagyon köszönöm!

I will try it and let you know.

@ITstreet1
Copy link
Author

String getStringFromDataBuffer()
{
String ret = "";
if(bufferPoiW == bufferPoiR)//There is nothing to say
return;

Can't compile. This return;

@ITstreet1
Copy link
Author

ITstreet1 commented Dec 30, 2021

Maybe the problem is with copy-paste, as you can see.
When copying the code, first paste it, then select all of it, and click insert code or ctrl+e. When inserting the code in those ```` it always messes up.

Or maybe better, add a new file in the repo.

Besides, this code you posted is not the one I modified with selecting the I2C address.

@WhitehawkTailor
Copy link
Owner

The compiler is right (of course :). The return should give back a String, since the value type of the function is String.
So the proper line is:
return null;
or
return "";

@ITstreet1
Copy link
Author

Boldog új évet!

No back to the problem.
return null;
trow this error:
'null' was not declared in this scope

return "";
Compiles.

@ITstreet1
Copy link
Author

ITstreet1 commented Jan 1, 2022

/**

    @author Ákos Szabó (Whitehawk Tailor) - aaszabo@gmail.com
    This is an I2C sniffer that logs traffic on I2C BUS.
    IDE: Visual Studio Code + PlatformIO
    Platform: Arduino for ESP32
    Board: Heltec WiFi Lora32 v2
    GPIO12 SDA
    GPIO13 SCL
    This is not connecting to the BUS as an I2C device. It is neither a Master, nor a Slave.
    It just listens and logs the communication.
    The application does not interrupt the I2C communication.
    Two pins as input are attached to SDC and SDA lines.
    Since the I2C communications runs on 400kHz so,
    the tool that runs this program should be fast.
    This was tested on an ESP32 bord Heltec WiFi Lora32 v2
    ESP32 core runs on 240MHz.
    It means there are 600 ESP32 cycles during one I2C clock tick.
    The program uses interrupts to detect
    the raise edge of the SCL - bit transfer
    the falling edge of SDA if SCL is HIGH- START
    the raise edge of SDA if SCL id HIGH - STOP
    In the interrupt routines there is just a few line of code
    that mainly sets the status and stores the incoming bits.
    Otherwise the program gets timeout panic in interrupt handler and
    restart the CPU.
    v1.0
    Basic operation and put message to eh serial output
    v1.1
    See additional parts marked with the version title v1.1
    The additionals makes possible to send the logged I2C communication content to a server via HTTP request.
    */

#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
//#define I2CTEST //use it to run a blinking LED test on SDA and SCL pins

#define PIN_SDA 12 //BLUE
#define PIN_SCL 13 //Yellow

#define I2C_IDLE 0
//#define I2C_START 1
#define I2C_TRX 2
//#define I2C_RESP 3
//#define I2C_STOP 4

static volatile byte i2cStatus = I2C_IDLE;//Status of the I2C BUS
static uint32_t lastStartMillis = 0;//stoe the last time
static volatile byte dataBuffer[9600];//Array for storing data of the I2C communication
static volatile uint16_t bufferPoiW=0;//points to the first empty position in the dataBufer to write
static uint16_t bufferPoiR=0;//points to the position where to start read from
static volatile byte bitCount = 0;//counter of bit appeared on the BUS
static volatile uint16_t byteCount =0;//counter of bytes were writen in one communication.
static volatile byte i2cBitD =0;//Container of the actual SDA bit
static volatile byte i2cBitD2 =0;//Container of the actual SDA bit
static volatile byte i2cBitC =0;//Container of the actual SDA bit
static volatile byte i2cClk =0;//Container of the actual SCL bit
static volatile byte i2cAck =0;//Container of the last ACK value
static volatile byte i2cCase =0;//Container of the last ACK value
static volatile uint16_t falseStart = 0;//Counter of false start events
//static volatile byte respCount =0;//Auxiliary variable to help detect next byte instead of STOP
//these variables just for statistic reasons
static volatile uint16_t sclUpCnt = 0;//Auxiliary variable to count rising SCL
static volatile uint16_t sdaUpCnt = 0;//Auxiliary variable to count rising SDA
static volatile uint16_t sdaDownCnt = 0;//Auxiliary variable to count falling SDA

//v1.1
//Store the begining of the communication string. Modify it according to your setup.
String msgToServer = "http://192.168.0.19:5544/I2cServer?ADDR=0100000&data=";
const char* ssid = "ssid";
const char* password = "pass";
const int deviceID = 1;

////////////////////////////
//// Interrupt handlers
/////////////////////////////

/**

    This is the rising SCL interrupt handler
    Rising SCL makes reading the SDA

*/
void IRAM_ATTR i2cTriggerOnRaisingSCL()
{
sclUpCnt++;

//is it a false trigger?
if(i2cStatus==I2C_IDLE)
{
  falseStart++;
  //return;//this is not clear why do we have so many false START
}


//get the value from SDA
i2cBitC =  digitalRead(PIN_SDA);

//decide wherewe are and what to do with incoming data
i2cCase = 0;//normal case

if(bitCount==8)//ACK case
  i2cCase = 1;

if(bitCount==7 && byteCount==0 )// R/W if the first address byte
  i2cCase = 2;

bitCount++;

switch (i2cCase)
{
  case 0: //normal case
    dataBuffer[bufferPoiW++] = '0' + i2cBitC;//48
  break;//end of case 0 general
  case 1://ACK
    if(i2cBitC)//1 NACK SDA HIGH
      {
        dataBuffer[bufferPoiW++] = '-';//45
      }
      else//0 ACK SDA LOW
      {
        dataBuffer[bufferPoiW++] = '+';//43
      } 
    byteCount++;
    bitCount=0;
  break;//end of case 1 ACK
  case 2:
    if(i2cBitC)
    {
      dataBuffer[bufferPoiW++] = 'R';//82
    }
    else
    {
      dataBuffer[bufferPoiW++] = 'W';//87
    }
  break;//end of case 2 R/W

}//end of switch

}//END of i2cTriggerOnRaisingSCL()

/**

    This is the SDA interrupt handler

    This is for recognizing I2C START and STOP

    This is called when the SDA line is changing

    It is decided inside the function wheather it is a rising or falling change.

    If SCL is on High then the falling change is a START and the rising is a STOP.

    If SCL is LOW, then this is the action to set a data bit, so nothing to do.
    */
    void IRAM_ATTR i2cTriggerOnChangeSDA()
    {
    //make sure that the SDA is in stable state
    do
    {
    i2cBitD = digitalRead(PIN_SDA);
    i2cBitD2 = digitalRead(PIN_SDA);
    } while (i2cBitD!=i2cBitD2);

    if(i2cBitD)//RISING if SDA is HIGH (1)
    {

     i2cClk = digitalRead(PIN_SCL);
     if(i2cStatus=!I2C_IDLE && i2cClk==1)//If SCL still HIGH then it is a STOP sign
     {      
      //i2cStatus = I2C_STOP;
      i2cStatus = I2C_IDLE;
      bitCount = 0;
      byteCount = 0;
      bufferPoiW--;
      dataBuffer[bufferPoiW++] = 's';//115
      dataBuffer[bufferPoiW++] = '\n'; //10
     }
     sdaUpCnt++;

    }
    else //FALLING if SDA is LOW
    {

     i2cClk = digitalRead(PIN_SCL);
     if(i2cStatus==I2C_IDLE && i2cClk)//If SCL still HIGH than this is a START
     {
      i2cStatus = I2C_TRX;
      //lastStartMillis = millis();//takes too long in an interrupt handler and caused timeout panic and CPU restart
      bitCount = 0;
      byteCount =0;
      dataBuffer[bufferPoiW++] = 'S';//83 STOP
      //i2cStatus = START;    
     }
     sdaDownCnt++;

    }
    }//END of i2cTriggerOnChangeSDA()

////////////////////////////////
//// Functions
////////////////////////////////

/**

    Reset all important variable
    */
    void resetI2cVariable()
    {
    i2cStatus = I2C_IDLE;
    bufferPoiW=0;
    bufferPoiR=0;
    bitCount =0;
    falseStart = 0;
    }//END of resetI2cVariable()

/**

    @desc Write out the buffer to the serial console

*/
void processDataBuffer()
{
if(bufferPoiW == bufferPoiR)//There is nothing to say
return;

uint16_t pw = bufferPoiW;
//print out falseStart
Serial.printf("\nprocessDataBuffer\nSCL up: %d SDA up: %d SDA down: %d false start: %d\n", sclUpCnt, sdaUpCnt, sdaDownCnt, falseStart);
//print out the content of the buffer 
for(int i=bufferPoiR; i< pw; i++)
{
  Serial.write(dataBuffer[i]);
  bufferPoiR++;   
}

//if there is no I2C action in progress and there wasn't during the Serial.print then buffer was printed out completly and can be reset.
if(i2cStatus == I2C_IDLE && pw==bufferPoiW)
{
  bufferPoiW =0;
  bufferPoiR =0;
} 

}//END of processDataBuffer()

/**

    v1.1
    @desc This method returns a String that contains everything that is available in the dataBuffer
    This function also resets the buffer, so this and processDataBuffer cannot be used in the same time.
    @ret String value. Returns the whole content of the dataBuffer as a string.

*/
String getStringFromDataBuffer()
{
String ret = "";
if(bufferPoiW == bufferPoiR)//There is nothing to say
return "";

uint16_t pw = bufferPoiW;
//print out falseStart
Serial.printf("\ngetStringFromDataBuffer\nSCL up: %d SDA up: %d SDA down: %d false start: %d\n", sclUpCnt, sdaUpCnt, sdaDownCnt, falseStart);
//print out the content of the buffer 
for(int i=bufferPoiR; i< pw; i++)
{
  ret += (char)dataBuffer[i];   
  bufferPoiR++;   
}

//if there is no I2C action in progress and there wasn't during the Serial.print then buffer was printed out completly and can be reset.
if(i2cStatus == I2C_IDLE && pw==bufferPoiW)
{
  bufferPoiW =0;
  bufferPoiR =0;
}

return ret;

}//END of processDataBuffer()

/**

    v1.1
    This is an empty method.
    Write here any communication with a server

*/
void sendMsgOut(String argStr){
  argStr.replace(" ","");
  Serial.println();
  Serial.println(argStr);
  Serial.println();
}

/////////////////////////////////
//// MAIN entry point of the program
/////////////////////////////////
void setup(){
Serial.begin(115200);
#ifdef I2CTEST
pinMode(PIN_SCL, OUTPUT);   
pinMode(PIN_SDA, OUTPUT); 
#else
//Define pins for SCL, SDA
pinMode(PIN_SCL, INPUT_PULLUP);   
pinMode(PIN_SDA, INPUT_PULLUP);
//pinMode(PIN_SCL, INPUT);   
//pinMode(PIN_SDA, INPUT);


//reset variables
resetI2cVariable();

//Atach interrupt handlers to the interrupts on GPIOs
attachInterrupt(PIN_SCL, i2cTriggerOnRaisingSCL, RISING); //trigger for reading data from SDA
attachInterrupt(PIN_SDA, i2cTriggerOnChangeSDA, CHANGE); //for I2C START and STOP
#endif

WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while(WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());
  
}//END of setup

/**

    LOOP

    v1.0

    @desc Writes I2C mcommunication to the serial if there is any.

    v1.1

    @desc uses sendMsgOut to send I2C mcommunication to the specified server and format given by the msgToServer variable
    */
    void loop()
    {

    #ifdef I2CTEST //do this in case it is testing the lines
    digitalWrite(PIN_SCL, HIGH); //13 Yellow
    digitalWrite(PIN_SDA, HIGH); //12 Blue
    delay(500);
    digitalWrite(PIN_SCL, HIGH); //13 Yellow
    digitalWrite(PIN_SDA, LOW); //12 Blue
    delay(500);
    #else
    //if it is in IDLE, then write out the databuffer to the serial consol
    if(i2cStatus == I2C_IDLE)
    {
    //v1.0
    //processDataBuffer();

      //v1.1
      //Get the content of the dataBuffer as a string and put it into a message
      //Send out the message
      //make sure that the msgToServer string variable is set properly above in the global variable section.
      sendMsgOut( msgToServer + getStringFromDataBuffer());

      //Delay the loop
         Serial.print("\rStart delay    ");   
         delay(5000);
         Serial.print("\rEnd delay    ");
         delay(500);
     }

    #endif

}//END of loop

@ITstreet1
Copy link
Author

Ok, so this code compiles. Problem is, there are empty spaces that I couldn't remove with replace() function.

Empty space in a string is not a valid URL. %20 is or no delimiter at all. How to remove that empty space? Or replace it?

@ITstreet1
Copy link
Author

You may notice I added some WiFi code. Not all.

@WhitehawkTailor
Copy link
Owner

I put this version into the code base as main-send.cpp
Can you send me few examples of string with empty characters.
Where the empty characters come from? Is it in the I2C communication or somewhere else?

@ITstreet1
Copy link
Author

My bad expression. Sorry. It is New Line that causes the problem.
I just edited it.

Stay tuned! More tests coming.

@ITstreet1
Copy link
Author

OK.
So I made a few tests. The changes I made in pull-request are ok. That, as it is works. I can send the data to a server. There is one issue. The leading S has disappeared somehow. It doesn't change anything as it is in the database and there I can do what I want.

Now the hard part...
My first sketch somewhere above has the part that filters the I2C addresses and prints only the one I need. Here we have a sketch that doesn't filter it. When I tried to merge them together, I get a non-working sketch. It doesn't print/sends the output. Although it is the same setup. Just as it didn't find the data with the selected address.

@WhitehawkTailor
Copy link
Owner

which code do you run that produces this output? Is it the origin code, or some modified?

@ITstreet1
Copy link
Author

Basic sketch from here.

@WhitehawkTailor
Copy link
Owner

It would be good to see the beginning of the message flow. The example I can see above has no S and s part to indicate the beginning (S-Star) and the end (s-stop).

@ITstreet1
Copy link
Author

It was a bad wire on SDA2. I fixed that and those 1111 are gone. Now there is still the problem with resets...

This is from the middle of the response.

S0100111W+00000000+11111000+s
S0100111W+00000010+s
S0100111R+11111000-s
S0100111W+00000010+11110000+s
S0100111W+00000010+s
S0100111R+11110000-s
S0100111W+00000010+11100000+s
S0100111W+00000010+s
S0100111R+11100000-s
S0100111W+00000010+11000000+s
S0100111W+00000010+s
S0100111R+11000000-s
S0100111W+00000010+10000000+s

Start delay    
End delay    ets Jun  8 2016 00:22:57

rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1284
load:0x40078000,len:12836
load:0x40080400,len:3032
entry 0x400805e4

Start delay    
End delay    
SCL up: 1782 SDA up: 379 SDA down: 379 false start: 1694
0100011W+00000011+s
S0100011R+11100001-s
S0100011W+00000011+11110001+s
S0100011W+00000011+s
S0100011R+11110001-s
S0100011W+00000011+11111001+s
S0100011W+00000011+s
S0100011R+11111001-s
S0100011W+00000011+11111101+s
S0100011W+00000011+s
S0100011R+11111101-s
S0100011W+00000011+11111111+s
S0100011W+00000011+s
S0100011R+11111111-s
S0100011W+00000011+11111111+s
S0100011W+00000010+s
S0100011R+00000000-s
S0100011W+00000010+10000000+s
S0100011W+00000010+s
S0100011R+10000000-s
S0100011W+00000010+11000000+s
S0100011W+00000010+s

@ITstreet1
Copy link
Author

Ok, I get the new PCBs

With ISO1540, when everything is connected, it works like a charm. When I turn on/off power on the device I sniff, it is ok. No issues. When I do the same on my sniffer, the device I sniff froze. After much testing, I noticed that when I want to do a simple reset of my sniffer, I have to disconnect VCC and I2C lines from the SIO1540, the side of the device I sniff. I tried with some MOSFETs but had no luck. Relays are overkill.

@WhitehawkTailor
Copy link
Owner

Just make sure that the power resources of the elements (sniffer, sniffed device and ISO1540) are independent.
Do not attache the module that you want to sniffe to the VCC pin of the sniffer device.
ISO1540 also should have its own pover suply, so do not either connect it to the VCC of the sniffer device.

@ITstreet1
Copy link
Author

schematic (2)

Mate, they are. Here you can see clearly.

While on wires, I have to disconnect VCC, SCL, and SDA. I thought VCC would be enough.

@WhitehawkTailor
Copy link
Owner

I can see now. The fet2 part causes the trouble. When it is switched of, or the sniffer is down, then SDCL2 and SDA2 lines flies away that causes the trouble for the sniffed device.
I think you don't need the R9 and R10 at all. This function should be implemented on the working side that you want to observe.
Just make sure your connection point on the I2C BUS is as close as possible to the observed device and don't use long wires.

@ITstreet1
Copy link
Author

ITstreet1 commented Apr 8, 2022

For ISO1540 I made a schematic according to this:
https://www.mikroe.com/i2c-isolator-click
Without those resistors, it acts the same.

While I tested it a lot, I realize I must cut the SDA line when ESP32 is off. I think it can be done with a MOSFET or so. Do you have some suggestions? I am all ears.

Edit:
As for wires, for testing, I use a standard jumper wire from an Uno to a PCA9535 with a 7seg display, and another jumper wire to this board I sent schematic. Just regular prototyping.

@WhitehawkTailor
Copy link
Owner

in my implementation I did not handle the Vcc and GND of the observed side. I just connected the 4 lines (Vcc, GND, SDC, SDA ) of he observed side to the ISO1540 and attached my ESP32 to the other side.

If you really want to switch all the four lines then try to find some multichannel low power switch for this purpose.

@ITstreet1
Copy link
Author

ITstreet1 commented Apr 9, 2022

There will be times I had to reset or power off the ESP32. In that case, the observed device will just be held in the middle of the loop. That is why I have to cut VCC and now the SDA.

For testing purposes, I use MikroE I2C Isolator Click. There is a link few posts above. The problem occurs the same, on protoboard with this Click, and on my PCB with ISO1540 soldered on.

Edit:
Can you please try this? Just make some simple LED blink on a PCF8574 or similar and see does this happens to you?
In my case, when it blinks and I shut down ESP32, blinking stops, no matter on or off.

@WhitehawkTailor
Copy link
Owner

I don't have PCF8574.
Are you sure that without the R9 , R10 and the whole fat2 part (R21, Q5, R24, Q4) it still makes trouble on the observed side?
Theoretically you don't have to switch off (isolate) the observed side, since you have an isolator. The isolator makes that nothing goes back and harms the observed side. The only connection between the two side is the fat2 part. The other changes you made on the observed side is the two pull-up resistors (R9, R10). So get rid of them.
These should solve the issue. Please confirm.

@WhitehawkTailor
Copy link
Owner

I think I know the reason why power off on sniffer side kills the observed side.
When you power off the sniffer than the isolator seems to pull down the observed side lines.
Can you measure the voltage level of the SDA2 and SDC2 lines when the sniffer side is powered off?
If it is not on the ground then maybe the power off event on the sniffer side pulls down only temporarily the observed SDA2 and SDC2. Either way it is bad from the observed I2C master point of view, because only the master can initiate pull down first.
This may cause the trouble.

@ITstreet1
Copy link
Author

Mate, you have a drink the first time you come to Belgrade!

The problem was, that I used MikroE I2C Isolator Click for testing and its schematic for a PCB. But on this click, there were 2 pull-up resistors on the observer side. They cause the problem while testing, and I tried to work around it on my design, not realizing that all I had to do is to remove those 2 resistors.

On the PCB I bypassed VCC2, removed pull-ups on the observer side, and it worked as expected. So far so good. No matter, I will order a new revision of the PCB. Hope it will arrive in a week or two.

Then, all that is left is the software. It worked last time as it sends the data to a server. But maybe to polish a thing or two. We will see.

I will post the schematic here later if some other needs it.

@WhitehawkTailor
Copy link
Owner

good news, congrats!
I will keep it in my mind and will find you when I go to Belgrade, thanks :)

@ITstreet1
Copy link
Author

New boars arrived. That also means new problems...

In the previous revision, I had a circuit for switching 3.3V on the ISO1540 (the ESP32 side). I remove it in this newer version. But as SDA is tied on GPIO12 and with 1K on 3.3V it won't boot. GPIO12 is a bootstrap pin and the boot fails if pulled HIGH. On the previous design, 3.3V is there only after I write digital logic on fet pin.

There are a few questions...
-do I need those pull-up resistors of 1K on ISO1540?
-can I use another pin for SDA?
-should I bring back this switch circuit on the 3.3V rail for ISO1540?
-something else?

@WhitehawkTailor
Copy link
Owner

Hi,
1)pull up resistor on your side (R7, R8) are needed, but on the observed side it is not required, because the system you observes should already has it.
2)On ESP you can use any PIN for SDA and SDC that is free to use, just modify the program accordingly. Be careful to avoid special pins that are used for any other function.
This part of the code need to e changed:
#define PIN_SDA 12 //BLUE
#define PIN_SCL 13 //Yellow
3) I don't see the necessity of the switch circuit part.
4) The only question is the ISO1540 operation. I think the issue is when you switch off your circuit part and this makes the ISO1540 to pulls down the observed SDA and SDC if the ISO1540 7PIn and 6PIN goes to ground or to any level that somehow interferes with the observed SDA or SDC. If you have an oscilloscope you could check the voltage level during operation or when your ESP side is switched off.
Theoretically it should not work on this way. In case any Vcc goes under 2.1V the output should become Z.
See the table of 8.5 Device Functional Modes in the bellow datasheet:
https://www.ti.com/lit/ds/symlink/iso1540.pdf?ts=1651344550926&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FISO1540

But for some reason it seems that the situation is not the described.
When you switch off the ESP what is the volt level on the observed side? Can you check it with an oscilloscope and see the transient if there is a small drop down or anything?

Does your observed device works if you switch on only that side and your observer ESP remains off?
So the question is whether the switching off ESP side as a transient kills the observed side, or it can work only with the switched on ESP side?

@ITstreet1
Copy link
Author

After a bunch of testing with the PCA9535 as it has two ports and is a little bit more complex than the PCF8574, I get some issues.

Sniffing works as expected, board too.
But the collected data is not what I expect.

It looks like the window when the ESP32 takes a picture is small. If I add two 7 seg displays and make it "blink" two numbers it doesn't capture whole segments at the time. Like it takes a capture while it hasn't turned on all segments. For PCA9535 I use an Uno and fire segment after segment in a loop, so it is obvious. Lib works this way.

So the question is, how can I make this window bigger? Should it mess the whole thing?

The sketch is here:
https://github.com/ITstreet1/I2C-sniffer/blob/main/main_wifi.ino
I didn't remove the fet part but it doesn't harm anything as there is nothing on the board.

@WhitehawkTailor
Copy link
Owner

my sniffer does not use any window. It is driven by the interrupts generated by the changes on the SDC and SDA lines.
The only possible reason I can imagine to have less data to display is when the I2C communication is too fast comparing the speed how you send data from the buffer and the dataBuffer is overwriten.

This may happen if the WiFi communication is too slow comparing to the i2c data cycles.
Try to increase the buffer size:
static volatile byte dataBuffer[64000];

And also try to put the output to the serial first instead to WiFi. This can help to see if the WiFi communication time it too much comparing to i2c and that is why data gets overwritten after a while.

The problem could be that if I2C data is a continuous flow, than after a while it will produce more data than WiFi can send it over and the buffer will fill up and will overwrite the data in it. This will cause that you won't see the complete i2c communication just part of it.

@WhitehawkTailor
Copy link
Owner

more explanation
There is no function to handle the situation when the databuffer is overwritten.
The idea was to empty the buffer in the loop before it is filled up.

Anyway if the I2C communication provides more data than the loop can send it either to the console or to the WiFi channel than it will be overwritten and it also can cause problems too when it writes to a non registered area outside of the reserved buffer.

@ITstreet1
Copy link
Author

Ok.
I finally managed to add my custom board to a board I want to sniff out. This board has a bunch of I2C devices while I tested on only one. So, there are additional problems.

Let's start from the start, shall we?
This is what Serial prints out with a 6400 dataBuffer:

S0100000W+S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10011000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+00000001+01111111+01111111+0S0010000R+10000011+11111111-01111111+0S1010000W+1S0000010WS0111111S0000011R-0S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S1010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011s000S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111110-11111010S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+00001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111+11111111-S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+10100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+11111111+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000s1S0100000R+01111111+11111111-S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001S0011111R-10111111-10S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000WsS0100000R+01111111+11111111-S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000010W-11111110-11111010S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+01100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+00000001+01000000+0S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00000000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S1010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000010W-00010000-00010000S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11s110100S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S1010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+1S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W-11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111110-11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000010W-11111110-11111110S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W-11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111+11111111-S0010001R+1S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0000000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S1010000W+0S0000000W+00100000-00111111-01111111-S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S001S0000000S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S1010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+1101101S0000100W+100S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010011R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S1010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+00001111+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111110-11111110S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11s110100S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111WS0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+11111111+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111110-11111010S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10010000-00010000S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W-S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0100011W+S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111110+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10011000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+00000001+01000100+01000100+0S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11111010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100001+01111111+11111111-S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+1S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+1S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+SsS0100000W+S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+1S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+SsS0100000W+S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S1010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111110S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000010W-11111010-10110100S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111110+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0001111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011W+S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S1010011W+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010SsS0100001W+S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S001000s100S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000011W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111S1010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10000000+S0000100W+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111+11111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111001+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100001+01111111+11111111-S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-01111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111S0111111W-0S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001S0000100W-0000S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000000W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111101+11011010+S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111100-10110100S0010000R+0S0000001W+11111111+11111101+S0010000W+0S0000001W+11111111+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0010001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+SsS0100111W+S0000001W+10001000+10001000+S0010000W+0S0000000W+00100000-00111111-01111111-1S0000001R+0S0000001W+11111111+11111111+S0010000R+0S0000001W+11111111+11111111+S0010000W+0S0000001W+S0111111R+S0000111R+S0010011R+0S0000001W+10001000+10001000+S0110000W+1S000

This is pretty much of an output. This resets the ESP32 after two readings.

Additional thing:
I don't get data inserted into DB. This I still have to debug as it could be a problem in the DB, my PHP code, or something else.

What do you suggest I do?

@WhitehawkTailor
Copy link
Owner

Good news is that we have progress again.
It seems there is a continuous communication on that observed I2C BUS.

The problem is that the sniffer writes faster the data than your program reads it. So after a while the buffer will be overloaded and the program writes data to area that is not allocated for the buffer. So it starts overwrite something, that is why the ESP32 will collapse after a while.

The program is not perfect, I did not prepared it for such situation that you have.
In my use case the communication went rarely, so there was time to write out the buffer and reset it.

It can be fixed by pausing the observation, while the buffer is not empty again.
You can also increase the buffer size even for couple of mega byte depending on you r ESP32 setup.

What really strange for me is that there is no stop sign in the data flow.
S is the START
s is the stop.
It could be a program issue or something strange on the communication.

I am sure this code would need a revisit, but I have no time at the moment.
A couple of week from now I may have chance to review this issue again.

Meanwhile you could check the I2C protocol and create a parser for the data flow.

I cannot help in the DB issue, since I don't know your code.

@ITstreet1
Copy link
Author

After a few attempts, I realize the URI is way too big (414 code).
Maybe to cut down the dataBuffer?

@ITstreet1
Copy link
Author

ITstreet1 commented Jun 24, 2022

Ok, tried with a smaller buffer, and ESP goes into reset all the time.
With a bigger buffer, it can not go through the URL as a GET request. Just it is a big URL address. I get URI too long (414).

There could be a few solutions.

  • to filter only specific I2C address before sending to the URL
  • to pack it somehow into a file and upload it to the server
  • to cut down on an ESP into smaller pieces and send it that way
  • maybe to tweak this existing code a little bit
  • you said to pause it. How?

I think this could be an interesting project for others when finished. I just don't believe I am the only one who needs to spy on one device's I2C lines and get data from it.

Edit:
Just check it out. Through URL it can go only some 25% of the whole reading from above.

@WhitehawkTailor
Copy link
Owner

A usual ESP32 has something like 4Mega byte memory.
About a 2Mega form the 4 can be used as a file system and you can write data there.
But the problem remains the same. More data coming than you can send it out.
So sooner or later file system will be full too.

Filtering the address can help, but this should be implemented.
Filtering helps in case you can send more data than you receives, otherwise the problem is the same.

Use POST instead of GET when sending, because GET has the limit.

In a few weeks I can start working on the code:

check the missing stop issue
implement the address filtering
handle the buffer overwrite situation
pause feature

@ITstreet1
Copy link
Author

I have a working solution for filtering. I have posted it somewhere here, LOL.
I can post it here again. Maybe those two sketches could be joined together.

It would be much easier to just cut all addresses but one. That means I will send to DB only what I need. If I send it all, then I will have to filer it on the server. Much fewer problems to filter it on the ESP.

@WhitehawkTailor
Copy link
Owner

You are right saying that it is easier to filter at the source.
The only thing is the computing capacity. If it will need too much time than the whole operation will slow down.

Anyway I will develop the filter capability that will be optional.
But in case the targeted source address will produce too much data you will have the same problem.
We will see.

I don't see the code you posted. Where is it?

@ITstreet1
Copy link
Author

It is at the top:
#1 (comment)

@WhitehawkTailor
Copy link
Owner

OK, thanks

@ITstreet1
Copy link
Author

I have a proposal for you. Feel free to contact me on dekip[at]beotel.rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants