Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By RFZ
#70668 Hi,
I wanted to write an I2C sniffer and wanted to use pin change interrupts to monitor the changes of SCL/SDA.
The problem is, the code is way too slow for 400kHz I2C.

Here is my code:

Code: Select all#define PIN_SDA 5 // D1
#define PIN_SCL 4 // D2 -- yellow scope trace
#define PIN_SDA_O 0 // D3
#define PIN_SCL_O 2 // D4 -- blue scope trace


void setup()
{
   pinMode(PIN_SDA_O, OUTPUT);
   pinMode(PIN_SCL_O, OUTPUT);
   pinMode(PIN_SDA, INPUT);
   pinMode(PIN_SCL, INPUT);
   attachInterrupt(PIN_SCL, chgSCL, CHANGE);
   attachInterrupt(PIN_SDA, chgSDA, CHANGE);
}

void loop()
{
}

void chgSCL() {
   uint8_t _sda = ((GPI >> PIN_SDA) & 1);
   uint8_t _scl = ((GPI >> PIN_SCL) & 1);
   if (_scl) {
      GPOS = (1 << PIN_SCL_O);
   }
   else {
      GPOC = (1 << PIN_SCL_O);
   }
}

void chgSDA() {
   uint8_t _sda = ((GPI >> PIN_SDA) & 1);
   uint8_t _scl = ((GPI >> PIN_SCL) & 1);
   if (_sda) {
      GPOS = (1 << PIN_SDA_O);
   }
   else {
      GPOC = (1 << PIN_SDA_O);
   }
}


And this is what I get on the scope, yellow connected to PIN_SCL and blue to PIN_SCL_O.
Where is the error? I cannot believe it is supposed to be so slow...
Thx :)
You do not have the required permissions to view the files attached to this post.
User avatar
By schufti
#70686 since you allready use direct pin manipulation I don't see much room for improvement.
Did you try with disabled WiFi?
Maybe faster if isr put into iram?
maybe compiler messes with variables and

if ((GPI >> PIN_SDA) & 1) {
GPOS = (1 << PIN_SDA_O);
}

is faster?

maybe CNLohr has some knowledge, he did amazing things with esp (e.g. USB on esp, TV chan3 transmitter in colour)
https://github.com/cnlohr/