Hi all, I have the I2C Extender / Active Terminator - STEMMA QT / Qwiic 4756 attached to a Metro Express Airlift... with I2C wires that are about 24" total... working great.
But then adding 20 feet of CAT6 twisted pair to the setup seems to fail.
The twisted line for data and clock are connected to ground on both ends of the run... which I think is how to reduce noise as much as possible.
The extender is supposed to be good for about 100 feet... so 20 feet shouldn't be an issue.
Why might this be failing?
Thank you for your kind help
I2c extender falling short
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- mikeysklar
- Posts: 14194
- Joined: Mon Aug 01, 2016 8:10 pm
Re: I2c extender falling short
Did you double up the eight conductors on the ethernet? Each pin Vcc/GND/SDA/SDL getting two pins?
Have you tried lowering the i2c bus speed just to confirm that communication was going through at a lower rate?
Have you tried lowering the i2c bus speed just to confirm that communication was going through at a lower rate?
- adafruit2
- Posts: 22200
- Joined: Fri Mar 11, 2005 7:36 pm
Re: I2c extender falling short
do *not* twist data or clock with ground. that increases capacitiance and its not differential! use a scope to look at your traces at the end of the line
- SkyRyder
- Posts: 45
- Joined: Fri Mar 06, 2020 6:05 pm
Re: I2c extender falling short
Well, they are twisted pairs (which are supposedly a good thing with respect to noise...
But as they are physically twisted, should I twist data and clock with a conductor that is not connected at either end?
Also, I don't know how to lower the I2C data rate...
what is the normal rate, and the command to set a lower one?
Thank you!
But as they are physically twisted, should I twist data and clock with a conductor that is not connected at either end?
Also, I don't know how to lower the I2C data rate...
what is the normal rate, and the command to set a lower one?
Thank you!
- mikeysklar
- Posts: 14194
- Joined: Mon Aug 01, 2016 8:10 pm
Re: I2c extender falling short
@SkyRyder,
What example code are you running? Is it Arduino or Python? Can you paste it in CODE tags here?
What example code are you running? Is it Arduino or Python? Can you paste it in CODE tags here?
- SkyRyder
- Posts: 45
- Joined: Fri Mar 06, 2020 6:05 pm
Re: I2c extender falling short
Thank you for your help...mikeysklar wrote:@SkyRyder,
What example code are you running? Is it Arduino or Python? Can you paste it in CODE tags here?
Code: Select all
// TFT display resolution 320x240 (rotation 1)
//version 2.3 adds arrays to help with defining and handling different regions.
// Adds a message display area. Updates Temperature display.
//version 2.2 gets rid of writing to the serial port... instead
// sending messages to the display. We also add a button to
// drive the relay
// What's this < > thing? With < >, the compiler searches INCLUDE directories for the file.
// With quotes, the compiler searches the INCLUDE directories and the *current directory*.
#include "Adafruit_MCP9601.h" //for thermocouple
#include "SPI.h" //for display
#include "Adafruit_GFX.h" //for display
#include "Adafruit_ILI9341.h" //for display
#include <Adafruit_FT6206.h> //for display
#include <Wire.h> //for relay
#define COMMAND_RELAY_OFF 0x00 //for relay
#define COMMAND_RELAY_ON 0x01 //for relay
#define COMMAND_CHANGE_ADDRESS 0x03 //for relay
//The actual default address is SUPPOSED to be 0x18, but 0x19 is what works!
volatile byte qwiicRelayAddress = 0x18; // Set Address for relay
// The FT6206 uses hardware I2C (SCL/SDA)
Adafruit_FT6206 ts = Adafruit_FT6206(); //for touch screen
boolean ValveCondition = false; // don't know what this is
boolean FingerUp = true; // touch latch for TS
// For the Adafruit shield, these are the default.
#define TFT_DC 9 // for display but what?
#define TFT_CS 10 // for display but what?
#define TEMP1_ADDRESS (0x67) //for thermocouple
Adafruit_MCP9601 mcp; //for thermocouple
// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
int PumpButton[] = {220, 1, 100, 50}; //an array that holds the region used for the pump button
int WaterTempDisplay[] = {0, 50, 100, 50}; //an array that holds the region used to display temp
int MsgDisplay[] = {0, 214, 319, 25}; //an array that holds the region used to display messages
int TempDisplay[] = {92, 100, 75, 50}; //an array that holds the region used to display the temperature
int ClrScreen[] = {290, 210, 30, 30}; //an array of a hidden button intended to clear the screen
void setup()
{
// this needs to be here so that we can stop code from executing (by not opening a serial monitor
// in case there is some lock up situation.
Serial.begin(9600);
while (!Serial) {
delay(10);
}
// we will now start with the display so we can send messages to it
// instead of the serial port
tft.begin(); // start display process?
delay(10); // delay needed to prevent display inversion?
testFillScreen(); // makes some flashy screens
delay(500);
tft.setRotation(1); // initialize the desired screen rotation
tft.fillScreen(ILI9341_BLACK);
yield();
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setTextSize(1);
tft.println("Display Enabled"); // Send to display
// ts.begin(40); // start touch screen
// tft.println("Touchscreen Enabled"); // Send to display
// This may not be needed since the TC module is also using Wire
Wire.begin(); // join the I2C Bus (relay)
//Wire.setClock(10000); // set I2C to only 10% of standard
Wire.beginTransmission(qwiicRelayAddress); // transmit to device
delay(100);
//check here for an ACK from the slave
tft.println("begin wire transmission test");
if (Wire.endTransmission() != 0 ) {
tft.println("Check Connections. Slave not found.");
}
else {
tft.println("Qwiic Relay found at 0x19!");
}
relayOff(); //set relay to non-ambiguous state
// required or subsequent mcp call fails
delay (10); // only 1ms required
/* Initialise the driver with XXX_ADDRESS and the default I2C bus. */
if (! mcp.begin(TEMP1_ADDRESS)) {
tft.println("Thermocouple not found. Check wiring!");
//while (1);
}
mcp.setADCresolution(MCP9600_ADCRESOLUTION_18); //set TC resolution to 18 bits
mcp.setThermocoupleType(MCP9600_TYPE_K); //set TC type to K
mcp.setFilterCoefficient(3); //not sure what this does
mcp.enable(true); //not sure what this does
tft.println("Thermocouple Enabled"); // Send to display
delay(2000); //let messages linger before we continue
tft.fillScreen(ILI9341_BLACK); //clear screen after setup
ValveBtn(0, PumpButton); //initialize button and valve states to closed
DispMsg("Display Message test.");
}
//why is void in the arguments? because it doesn't return a value
void loop(void) {
tft.setCursor(0, 0);
//text color to green and background to black
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setTextSize(2);
tft.println("Tiny Recirculator");
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
DispTemp(mcp.readThermocouple());
// See if there's any touch data for us
// we need a latch so that a finger has to come UP first
if (ts.touched()) {
delay(15); //psudo-debounce
if (CheckTouch(ClrScreen) == true) { //check hidden button touch
tft.fillScreen(ILI9341_BLACK);
}
if (CheckTouch(PumpButton) == true) { //check for a touch in the PumpButton region
if (FingerUp == true) { //only continue if finger was not down prior
FingerUp = false; //flag the finger on the button
if (ValveCondition == true) { //if the valve condtion is open, close it
ValveBtn(0, PumpButton); //close valve
}
else { // ValveCondition == false
ValveBtn(1, PumpButton); //open valve
}
}
}
}
else { //finger was not touching... let's remember this
FingerUp = true;
}
}
/* Begin function definitions.... */
unsigned long testFillScreen() {
unsigned long start = micros();
tft.fillScreen(ILI9341_BLACK);
yield();
tft.fillScreen(ILI9341_RED);
yield();
tft.fillScreen(ILI9341_GREEN);
yield();
tft.fillScreen(ILI9341_BLUE);
yield();
tft.fillScreen(ILI9341_BLACK);
yield();
return micros() - start; // this calculates how long it took to fill screen
}
//The following is a whack text display... needs much work
unsigned long testText() {
tft.fillScreen(ILI9341_BLACK);
unsigned long start = micros();
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_GREEN);
tft.setTextSize(2);
tft.println("Tiny Recirculator");
tft.setTextSize(1);
tft.println("Ver 1.0");
return micros() - start;
}
void relayOn() {
Wire.beginTransmission(qwiicRelayAddress);
Wire.write(COMMAND_RELAY_ON);
if (Wire.endTransmission() != 0) {
DispMsg("Check Connections. No slave attached");
}
}
// RelayOff() turns off the relay at the qwiicRelayAddress
// Checks to see if a slave is connected and prints a
// message to the Monitor if no slave found.
void relayOff() {
Wire.beginTransmission(qwiicRelayAddress);
Wire.write(COMMAND_RELAY_OFF);
if (Wire.endTransmission() != 0) {
DispMsg("Check Connections. No slave attached");
}
}
void DispTemp(float theTemp) {
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setCursor(TempDisplay[0], TempDisplay[1]);
tft.setTextSize(1);
tft.println("Temp (F):");
tft.setCursor(TempDisplay[0], TempDisplay[1] + 12);
tft.setTextSize(5);
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.print(theTemp * 1.8 + 32); //convert c to f before displaying
}
void DispMsg( String theMsg) {
tft.setTextSize(2);
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setCursor(MsgDisplay[0] + 2 , MsgDisplay[1] + 10);
tft.print(theMsg);
tft.print(" ");
}
void ValveBtn(int ValveState, int TheRegion[]) // 0="CLOSE" 1="OPEN" 2="TOGGLE", region array
{
//tft.drawRect(OFFBUTTON_X, OFFBUTTON_Y, OFFBUTTON_W, OFFBUTTON_H, ILI9341_GREEN);
//add some code here to set for valve state 2: toggle to force valve state to 0 or 1
tft.drawRect(TheRegion[0], TheRegion[1], TheRegion[2], TheRegion[3], ILI9341_BLUE);
tft.setTextSize(2);
switch (ValveState) {
case 0:
tft.setTextColor(ILI9341_BLUE, ILI9341_BLACK);
tft.setCursor(TheRegion[0] + 14 , TheRegion[1] + 18);
tft.println("CLOSED");
relayOff(); //turn off relay
ValveCondition = false; //false is closed
break;
case 1: //open the valve
tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK);
tft.setCursor(TheRegion[0] + 14 , TheRegion[1] + 18);
tft.println(" OPEN ");
relayOn(); //turn on relay
ValveCondition = true;
break;
}
}
boolean CheckTouch(int TheRegion[])
{
TS_Point p = ts.getPoint(); // Retrieve a point
delay(15); //psudo-debounce
if (FingerUp == true) { // only do something if finger is touching but wasn't
// rotate coordinate system
// flip it around to match the screen.
p.x = map(p.x, 0, 240, 240, 0);
p.y = map(p.y, 0, 320, 320, 0);
int y = tft.height() - p.x;
int x = p.y;
//check to see if we are touching the button
if ((x > TheRegion[0]) && (x < (TheRegion[0] + TheRegion[2]))) {
if ((y > TheRegion[1]) && (y <= (TheRegion[1] + TheRegion[3]))) {
return true; // terminate function & return true if region was touched
}
}
}
return false; // terminate function & return false if region was not touched
}
- SkyRyder
- Posts: 45
- Joined: Fri Mar 06, 2020 6:05 pm
Re: I2c extender falling short
I set the clock speed to 10,000 and I did not see a difference... I'm not sure that is a valid speed though.mikeysklar wrote:Did you double up the eight conductors on the ethernet? Each pin Vcc/GND/SDA/SDL getting two pins?
Have you tried lowering the i2c bus speed just to confirm that communication was going through at a lower rate?
- SkyRyder
- Posts: 45
- Joined: Fri Mar 06, 2020 6:05 pm
Re: I2c extender falling short
Here is a photo of the clock read at only 24 inches from the metro express airlift.
(See more photos)
(See more photos)
- Attachments
-
- 0804A1F4-3887-4D2E-B8FC-F27C278C446F.jpeg (89.65 KiB) Viewed 201 times
- SkyRyder
- Posts: 45
- Joined: Fri Mar 06, 2020 6:05 pm
Re: I2c extender falling short
Here is the clock when connected to 20’ of cat 6 wire… measured at about 22’ total length
- Attachments
-
- CB71539E-D059-4DFE-9AED-AF420F37FF24.jpeg (89.76 KiB) Viewed 200 times
- mikeysklar
- Posts: 14194
- Joined: Mon Aug 01, 2016 8:10 pm
Re: I2c extender falling short
Thank you for the scope pics and trying the lower i2c speed.
Can you show how you have connected the cat-5 cable? Maybe it is an increased capacitence issue as @adafruit2 suggested or something else that will be obvious from photos.
Can you show how you have connected the cat-5 cable? Maybe it is an increased capacitence issue as @adafruit2 suggested or something else that will be obvious from photos.
- SkyRyder
- Posts: 45
- Joined: Fri Mar 06, 2020 6:05 pm
Re: I2c extender falling short
On one side I've got a terminal block and I plug in a standard ethernet connector. That connector is wired directly to the solder terminals on the I2C extender (which is connected to the metro board 20 inches away).
20 feet later, the cable goes to another network connector to a terminal block that connects to i2C modules just a few inches away.
I've tried with clock and data twisted together, clock+ gnd and data+gnd twisted together, and then just separate data and clock lines, twisted with disconnected wires.
All look the exact same on the o-scope.
is it possible it's a power issue over that distance?
20 feet later, the cable goes to another network connector to a terminal block that connects to i2C modules just a few inches away.
I've tried with clock and data twisted together, clock+ gnd and data+gnd twisted together, and then just separate data and clock lines, twisted with disconnected wires.
All look the exact same on the o-scope.
is it possible it's a power issue over that distance?
- mikeysklar
- Posts: 14194
- Joined: Mon Aug 01, 2016 8:10 pm
Re: I2c extender falling short
I'll need to see a diagram or photo of how you are using the twisted pairs. I understand what you are saying about trying different combinations of CLK and GND twisted together or with their ground, but there are 8-pins on an RJ-45 so I'd like to see how you are using all of them and ganging or not of the connections.
I've used RJ-45 in a lot of projects and found it to be an excellent conductor when using two pin pairs that are pre-twisted for the same signal.
I don't think it will be a power issue over this distance, but the way to test would be to start cutting the length of the cable into halves to see where the failure occurs after we verify the pinouts.
I've used RJ-45 in a lot of projects and found it to be an excellent conductor when using two pin pairs that are pre-twisted for the same signal.
I don't think it will be a power issue over this distance, but the way to test would be to start cutting the length of the cable into halves to see where the failure occurs after we verify the pinouts.
- adafruit_support_bill
- Posts: 88154
- Joined: Sat Feb 07, 2009 10:11 am
Re: I2c extender falling short
Judging from the shape of the waveform, it doesn't look like a problem with capacitance. The rise time is nice and crisp with just a bit of overshoot. But it doesn't look even remotely like your clock signal either.
Your scope is showing a clock frequency of about 4.2 KHz with the short cabling. With the long cable your scope is saying just 170 Hz (!?!)
If you look at the schematic, the signal on the board is connected straight through from one side to the other. The LTC4311 is just an active pullup. What you see on the other end of your cable should at least be the same frequency as what goes in. If not, you must have something connected wrong.
https://learn.adafruit.com/adafruit-ltc ... /downloads
Your scope is showing a clock frequency of about 4.2 KHz with the short cabling. With the long cable your scope is saying just 170 Hz (!?!)
If you look at the schematic, the signal on the board is connected straight through from one side to the other. The LTC4311 is just an active pullup. What you see on the other end of your cable should at least be the same frequency as what goes in. If not, you must have something connected wrong.
https://learn.adafruit.com/adafruit-ltc ... /downloads
- adafruit2
- Posts: 22200
- Joined: Fri Mar 11, 2005 7:36 pm
Re: I2c extender falling short
yah are you sure you have it wired right? those are squariest square waves. thats not the issue
Please be positive and constructive with your questions and comments.