I'm reading the data from two "slave" AS5601 I2C absolute angle sensors connected via I2C multiplexer PCA9544A on Atmega328P-AU Arduino Pro (5V, 16MHz)
I never used any I2C sensors in the past, only I2C OLED displays.
So, yesterday, I wanted to check the signal on my Rigol DS1052E oscilloscope and I found a very strange (to me) I2C waveform and extremely slow falling edge after the transmission's end on both sensors channels.
Here is the best picture I can get from the oscilloscope.:
here is the simple code that I'm used to read the data from sensors.
#include <Wire.h>
//------------ I2C Chips ------------
#define AS5601 0x36 // AS5601 HEX address
#define MUX 0x70 // PCA9544A Multiplexer HEX address
byte mux_channel = 0; // Multiplexer channel number (0,1,2,3)
int reading = 0;
int Raw_Angle = 0;
int Angle = 0;
byte result;
int InputPos =0;
int Motor_Position =0;
//============= SETUP ===============
void setup()
{
Wire.begin();
delay(500);
//TWBR = 4; // Set I2C speed to ~650 khz
}
//=========== MAIN LOOP ===========
void loop()
{
MultiplexerChannel(0); // Select multiplexer channel 0
AngleSensorRead(); // Read value from Input Rotary Encoder 1
MultiplexerChannel(1); // Select multiplexer channel 3
AngleSensorRead(); // Read value from Motor1 angle sensor
MultiplexerChannel(2); // Select multiplexer channel 3
AngleSensorRead(); // Read value from Motor1 angle sensor
MultiplexerChannel(3); // Select multiplexer channel 3
AngleSensorRead(); // Read value from Motor1 angle sensor
}
//==================================================//
// SELECT MULTIPLEXER CHANNEL //
//==================================================//
void MultiplexerChannel(byte channel)
{
byte controlRegister = 0x04;
controlRegister |= channel;
mux_channel = channel;
Wire.beginTransmission(0x70); // Multiplexer Address
if (channel == 0xFF) {
Wire.write(0x00); // Unselect all channels
}
else {
Wire.write(controlRegister); // Set to selected channel
}
Wire.endTransmission();
}
//==================================================//
// READ SENSORS VALUE //
//==================================================//
void AngleSensorRead()
{
// Raw angle
Wire.beginTransmission(0x36); // Transmit to device as5601
Wire.write(byte(0x0E)); // Sets register pointer
result = Wire.endTransmission(); // Stop transmitting
Wire.requestFrom(0x36, 2); // Request 2 bytes from as5601
Raw_Angle = Wire.read(); // Receive high byte
Raw_Angle = Raw_Angle << 8; // Shift high byte to be high 8 bits
Raw_Angle |= Wire.read(); // Receive low byte as lower 8 bits
switch (mux_channel)
{
case 0:
InputPos = Raw_Angle; // Assign the value from Input Rotary Encoder1 on Ch0
break;
case 3:
Motor_Position = Raw_Angle; // Assign the value from Motor1 angle sensor on Ch3
break;
default:
// Nothing to do here
break;
}
}
I also connected SSD1306 OLED display to show the values from sensors, and the waveform on the "main line" is a nice square wave (with some minor noise ).
Could someone help me to understand what could cause that slow falling edge ?
Every I2C bus before and after the mux, should be high when not in use.
Do you have pullup resistors at that part of the I2C bus ?
Can you give a schematic, I don't know how everything is connected.
Multiplexer is connected to Arduono's SDA and SCL (HW) pins and there are two 4.7K pull-up resistors.
Each sensor also has it's own pair of 4.7K pull-up resistors.
There is only one pin which I have left "floating", it's multiplexer "INT" pin.
Not sure if it could cause that issue with falling edge...
The /INT is an output. You don't have to use it, and a pullup resistor is only needed when it is connected to the Arduino.
The schematic seems fine.
Something else is going on. There are hundreds of possibilities.
Perhaps you forgot a pullup resistor.
Perhaps the oscilloscope is in AC mode.
Is something else connected ? For example a servo motor or other motor, that causes a peak that resets the PCA9544A chip ?
Perhaps there is a bad ground.
Could you exchange modules, or try other components, new cables, try another oscilloscope, another Arduino, another computer.
Do you have a multimeter ? Can you measure that the voltage is 0V and not staying at 5V? It must stay at 5V when that part of the I2C bus is inactive.
I don't have a PCA9544A to test it. But that slow falling with that schematic, it seems impossible.
I've checked pull up resistors and they are all in place and they are all 4.7K.
All grounds are OK. It''s a custom PCB with Atmega328p-au, similar to Arduino Pro Mini 5V, 16MHz.
There are, indeed, 2 x DC motors controlled by two MC33926 H-bridge drivers.
But drivers are powered from separate 5V, 1A supply and motors from the separate 12V, 8A power supply.
When motors are rotating (PWM) there is slight "noise" on sensors I2C bus. (not on the main line)
Maybe because PCB traces to motor and motor sensors are quite close to each other.
Or maybe because I use unshielded cable (50cm) to connect motor and sensor (inside of the gearbox) to PCB.
Sure I have a voltmeter, and will check the voltage.
But first I will reset the oscilloscope and will check the waveform again.
In your schematic, the sensor is configured for 3.3V operation but is being powered with 5V. See figure 11 in the datasheet ... also need to change the 10µF capacitors to 1µF.
Multiplexer is connected to Arduono's SDA and SCL (HW) pins and there are two 4.7K pull-up resistors.
Each sensor also has it's own pair of 4.7K pull-up resistors.
There is only one pin which I have left "floating", it's multiplexer "INT" pin.
Not sure if it could cause that issue with falling edge...
Regards
I Agree with dlloyd :
dlloyd:
In your schematic, the sensor is configured for 3.3V operation but is being powered with 5V. See figure 11 in the datasheet ... also need to change the 10µF capacitors to 1µF.
You have the Sensor wired for 3.3V but you schematic says you are powering it with 5V?
Which is accurate?
This image is from the DataSheet you linked, on page 9.
If you are actually powering the sensor from 5V then use the schematic on the left. Directly Connect 5v to the 5v pin(pin 1), connect the 100nf directly between the pin 1 and pin 4 (gnd), ONLY connect the 1uf cap from pin2 (VDD3v3) to ground.
If you are actually powering it from 3.3v then everything is correct.
Hi guys,
it seems that I forgot to update my schematic.
Good find , guys.
In fact, I have used 3.3V circuit for ZERO angle programming (Figure 33.)
Then after programming I changed it back to 5V circuit, so there is no joint between 3.3V pin, BUT I have indeed forgot to replace 10uF capacitor by the 0.1uF, and haven't updated the schematic.
Regarding the slow falling edge, I have reset the oscilloscope, and now it seems that the problem is gone
I'm very happy that I've select AS5601 for my project.
It's very precise and cheap, absolute angle sensor with 4096 PPR in digital mode or up to 2048 positions in quadrature output mode.
By the way, they send free samples.
Now I'm testing the TWBR = 6; which sets I2C speed to ~568 khz
It runs pretty stable (as for me) and my OLED display loops now takes only 4,5ms instead of pervious 7.6ms.