I am currently working on a project that's reading accelerometer data from MPU6050 via I2C communication. I am attempting to do the communication via bit banging as instructed by my projects guidelines. I am able to go through the initial power up sequence for the MPU 6050 and write the the register I want to read from. After that, I try to read from the MPU 6050, nothing is read by the ESP32 other than the ack but that comes after writing the address of 0x68 to the MPU.
What could be causing the issue? I know it's not the MPU's issue because I have tried it on wokwi simulation and gotten the same resulting waveforms. I have tried doing the initial wake sequence in setup rather than in loop but that only resulted to the same issue.
It would be greatly appreciated if someone can help me with resolving this issue. Below I have attached the sketch that have been working on along with a screenshot showing the waveform it produces. D0 is SDA and D1 is SCL.
#define SCL 22
#define SDA 21
uint8_t checker = 0b10000000;
int addr = 0;
void setup() {
// put your setup code here, to run once:
pinMode(SCL, OUTPUT_OPEN_DRAIN);
digitalWrite(SCL, HIGH);
pinMode(SDA, OUTPUT_OPEN_DRAIN);
digitalWrite(SDA, HIGH);
Serial.begin(115200);
}
void loop() {
// put your main code here, to run repeatedly:
// Transaction 1:
pinMode(SCL, OUTPUT_OPEN_DRAIN);
digitalWrite(SCL, HIGH);
pinMode(SDA, OUTPUT_OPEN_DRAIN);
digitalWrite(SDA, HIGH);
delayMicroseconds(10);
bit_start();
int accel = 0x68;
int power = 0x6B;
int wake = 0x00;
accel = 0x68 << 1; // Write Bit
int ack = write(accel);
if (ack) {
Serial.println("Failure");
return;
}
Serial.println("Success");
delayMicroseconds(10);
ack = write(power);
if (ack) {
Serial.println("Failure");
return;
}
Serial.println("Success");
delayMicroseconds(10);
ack = write(wake);
if (ack) {
Serial.println("Failure");
return;
}
Serial.println("Success");
delayMicroseconds(10);
bit_stop();
delayMicroseconds(10);
// Transaction 2
pinMode(SCL, OUTPUT_OPEN_DRAIN);
digitalWrite(SCL, HIGH);
pinMode(SDA, OUTPUT_OPEN_DRAIN);
digitalWrite(SDA, HIGH);
delayMicroseconds(10);
bit_start();
accel = 0x68;
int addr = 0x3B;
accel = 0x68 << 1; // Write Bit
ack = write(accel);
if (ack) {
Serial.println("Failure");
return;
}
Serial.println("Success");
delayMicroseconds(10);
ack = write(addr);
if (ack) {
Serial.println("Failure");
return;
}
Serial.println("Success");
delayMicroseconds(10);
bit_stop();
delayMicroseconds(10);
// Transaction Read
pinMode(SCL, OUTPUT_OPEN_DRAIN);
digitalWrite(SCL, HIGH);
pinMode(SDA, OUTPUT_OPEN_DRAIN);
digitalWrite(SDA, HIGH);
delayMicroseconds(10);
bit_start();
accel = 0x68;
int read_dat = 0;
accel = 0x68 << 1 | 1; // Write Bit
ack = write(accel);
if (ack) {
Serial.println("Failure");
return;
}
Serial.println("Success");
delayMicroseconds(10);
read_dat = read(false);
Serial.println(read_dat);
delayMicroseconds(10);
bit_stop();
delayMicroseconds(10);
delayMicroseconds(100);
}
void bit_start() {
digitalWrite(SDA, HIGH);
digitalWrite(SCL, HIGH);
delayMicroseconds(10);
digitalWrite(SDA, LOW);
delayMicroseconds(10);
digitalWrite(SCL, LOW);
delayMicroseconds(10);
}
void bit_stop() {
Serial.println("STOP");
digitalWrite(SCL,LOW);
digitalWrite(SDA, LOW);
delayMicroseconds(10);
digitalWrite(SCL, HIGH);
delayMicroseconds(10);
digitalWrite(SDA, HIGH);
delayMicroseconds(100);
}
bool write(int data) {
bool ack;
pinMode(SDA, OUTPUT_OPEN_DRAIN);
for (int i = 0; i < 8; i++) {
if (data & 0x80) {
digitalWrite(SDA, HIGH);
} else {
digitalWrite(SDA, LOW);
}
data = data << 1;
delayMicroseconds(10);
digitalWrite(SCL, HIGH);
delayMicroseconds(10);
digitalWrite(SCL, LOW);
delayMicroseconds(10);
}
pinMode(SDA, INPUT_PULLUP);
delayMicroseconds(10);
//digitalWrite(SDA, HIGH);
digitalWrite(SCL, HIGH);
ack = digitalRead(SDA);
// Timeout mechanism (for example, 100 iterations)
int timeout = 100;
while (ack && timeout > 0) {
delayMicroseconds(10);
ack = digitalRead(SDA);
timeout--;
}
delayMicroseconds(10);
digitalWrite(SCL, LOW);
delayMicroseconds(10);
pinMode(SDA, OUTPUT_OPEN_DRAIN);
digitalWrite(SDA, LOW);
return ack;
}
int read(bool ack) {
int dat = 0;
digitalWrite(SDA, HIGH);
pinMode(SDA, INPUT_PULLUP);
pinMode(SCL, OUTPUT_OPEN_DRAIN);
delayMicroseconds(10);
for (int i = 0; i < 8; i++) {
dat = dat << 1;
/*do {
pinMode(SCL, OUTPUT_OPEN_DRAIN);
delayMicroseconds(10);
digitalWrite(SCL, HIGH);
pinMode(SCL, INPUT_PULLUP);
delayMicroseconds(10);
} while (digitalRead(SCL) == 0);*/
digitalWrite(SCL, HIGH);
delayMicroseconds(10);
if (digitalRead(SDA)) dat |= 1;
delayMicroseconds(10);
digitalWrite(SCL, LOW);
delayMicroseconds(10);
}
pinMode(SDA, OUTPUT_OPEN_DRAIN);
delayMicroseconds(10);
ack ? digitalWrite(SDA, LOW) : digitalWrite(SDA, HIGH);
delayMicroseconds(10);
digitalWrite(SCL, HIGH);
delayMicroseconds(10);
digitalWrite(SCL, LOW);
digitalWrite(SDA, HIGH);
return(dat);
}
