GithubHelp home page GithubHelp logo

Comments (31)

RobTillaart avatar RobTillaart commented on July 24, 2024

Hi Tipo,

I will make a branch with a test example so we have a "playground to test" OK?

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

check out - https://github.com/RobTillaart/SHT31/tree/issue_20

it has an extra example SHT31_two_I2C.ino which is straightforward 4 sensors.
I wrote it for an ESP32 that has 2 Wire buses and it compiles, I have no sensors around to test it.

You need to adapt in the top the TwoWire myWire(&sercom5, 16, 17); , declaration
And rename Wire1 to myWire in two of the four Begin() calls.

Give it a try and please post the result of the compilation and/or if it works.

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

updated the example a bit so less editing is needed.

Added a second example using array's (to be tested if the first works.


note: zero experience with ATSAMD21G18A

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

just a thought
A possible workaround is using - https://github.com/RobTillaart/TCA9548

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

Found - https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/overview

more specific
https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-wire

interesting part on that page

#include "wiring_private.h" // pinPeripheral() function
....
  // Assign pins 13 & 11 to SERCOM functionality
  pinPeripheral(11, PIO_SERCOM);
  pinPeripheral(13, PIO_SERCOM);

so after your

TwoWire myWire(&sercom5, 16, 17); 

you might need a reconfig of your pins too

#include "wiring_private.h" // pinPeripheral() function
...
  pinPeripheral(16, PIO_SERCOM);
  pinPeripheral(17, PIO_SERCOM);

other possible option is to use any other sercom. (just try all 6 to see which is free)

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

@tipo1000A
Any progress made?

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

@RobTillaart
Hi Rob,

I did try the solution/example you created (thanks), but it didn't seem to work. Then I had to dive to fix another issue on the same board. Now I have that done and I get back to "second I2C" issue.

I did double check with I2C scanner that second I2C I/F (sercom) is indeed working. I also checked with a scope that there is traffic ongoing on those I2C pins.

I'll post you better, more comprehensive info as I'm getting back to that now....

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

I have updated the branch, as I released 0..3.3 with a more robust heater code.
Should not change or disrupt the I2C investigation.

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024
  1. Checking second I2C (SERCOM) functionality with I2C scanner (attached)

To make sure SERCOM I2C is working I connected SHT31 with address 0x44 to default I2C and SHT31 with address 0x45 to SERCOM I2C. I2C scanner output below seems to confirm both I2Cā€™s are working.

I2C Scanner

Scanning myWire (sercom5 I2C)...
I2C device found at address 0x45  !
done

Scanning Wire (default I2C)...
I2C device found at address 0x44  !
done

I2C_scanner_SAMD21.ino.txt

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024
  1. Having confirmed the above I added other SHT31 sensors' so that both I2C's have 0x44 and 0x45, and then I tried to run your sketch with couple of edits to match my board.

The only output was this:

SHT31_LIB_VERSION: 0.3.3

Checking with scope at the same time I didn't see any traffic in SERCOM I2C. In default I2C I saw traffic one time, then no traffic.
KUI_NO_LoRa_ROB_I2C_orig.ino.txt

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024
  1. If I comment out this:
 b1 = sht_1.begin(SHT31_ADDRESS_1, &Wire);
  b2 = sht_2.begin(SHT31_ADDRESS_2, &Wire);
 // b3 = sht_3.begin(SHT31_ADDRESS_3, &myWire);
 // b4 = sht_4.begin(SHT31_ADDRESS_4, &myWire);

I get this output:

SHT31_LIB_VERSION: 	0.3.3
BEGIN:	1	1	0	0	
23.8	22.8	-45.0	-45.0	61.1	66.7	0.0	0.0
23.9	22.8	-45.0	-45.0	61.1	66.5	0.0	0.0
23.8	22.8	-45.0	-45.0	61.1	66.2	0.0	0.0
23.8	22.9	-45.0	-45.0	60.9	66.2	0.0	0.0
23.9	22.8	-45.0	-45.0	61.1	66.1	0.0	0.0

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

And if you commented out b1 and b2 the other pair worked?

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

With this:

  //b1 = sht_1.begin(SHT31_ADDRESS_1, &Wire);
  //b2 = sht_2.begin(SHT31_ADDRESS_2, &Wire);
  b3 = sht_3.begin(SHT31_ADDRESS_3, &myWire);
  b4 = sht_4.begin(SHT31_ADDRESS_4, &myWire);

The output is just this:

SHT31_LIB_VERSION: 0.3.3

So, didn't work...

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

rereading - https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-wire

and looked at this datasheet - https://www.microchip.com/en-us/product/ATSAMD21G18

you use pin 16 and 17. Can you explain why you choose those two pins?

CHapter 7, page 28/29 of the datasheet does not mention pin 17 for the 21G column.

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

If I understand the theory correctly I would try sercom4 and pin 19, 20

image
(page 29 datasheet)

You might notice that pin 17 and 18 are skipped in that column.

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

OK found where the numbers 16 and 17 possibly come from.
image
(page 33 datasheet)

Looking up these in the MUX table.

image
(page 30 datasheet)

It looks like you need to use sercom3, and pins 25 and 26 ?

TwoWire myWire(&sercom3, 25, 26);

#include "wiring_private.h" // pinPeripheral() function
...
  pinPeripheral(25, PIO_SERCOM);
  pinPeripheral(26, PIO_SERCOM);

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

The history is that before I started to make the layout for my custom board I prototyped the use of physical pins #47 and #48 on the chip. I did that with I2C scanner and it was working (still is) and so I chose to use those pins. They were also most convenient to use from PCB layout perspective.

Physical pins #47 and #48 translate to I/O pins PB02 and PB03 respectively. From datasheet table 7-1.

image

image

The pin numbers to use with "pinPeripheral" (16 and 17) I picked up from variants.cpp file of MKRWAN1300. https://github.com/arduino/ArduinoCore-samd/blob/master/variants/mkrwan1300/variant.cpp

image

I thought I did everything right since I was able to ping sensors with myWire.beginTransmission(address);
error = myWire.endTransmission(); with I2C scanner. It must mean that the right "port" can be opened and physically it works, right?

Can you explain why I'm able ping sensors with myWire.beginTransmission(address);
error = myWire.endTransmission(); but can't actually communicate with them using library functions?

And thanks again for putting your time into this.

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

As far as I understand it looks like you have used the right info.

Can you give a link to the version of the datasheet you use?
This to be sure we use the same reference.

Can you explain why I'm able ping sensors with myWire.beginTransmission(address);
error = myWire.endTransmission(); but can't actually communicate with them using library functions?

No, normally that is the way one tests the connection,
the host sending the address which is acknowledged by the slave.
If the slave is removed the ping fails.

You might call myWire.setClock(100000); but that is the default normally.

Have you tried to communicate with another I2C device on that sercom5 device? EEPROM ?

If it is a bug in the library, a minimal sketch that uses just Wire calls, something like below should be able to detect it

#include "Arduino.h"
#include "Wire.h"
#include "wiring_private.h" // pinPeripheral() function

TwoWire myWire(&sercom5, 16, 17);

void setup()
{
  Serial.begin(115200);
  Serial.println("test");
  delay(100);

  myWire.begin();
  pinPeripheral(16, PIO_SERCOM);
  pinPeripheral(17, PIO_SERCOM);

  myWire.beginTransmission(44);
  int err = myWire.endTransmission(); 
  Serial.print("E:\t");
  Serial.println(err);

  int n = myWire.requestFrom(44,  (uint8_t) 6);
  Serial.print("N:\t");
  Serial.println(n);
  for (int i = 0; i < n; i++)
  {
    Serial.print("\t");
    Serial.println( myWire.read(), HEX);
  }
}

void loop()
{
}

updated pin numbers to 16 / 17 in code snippet

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

pinPeripheral(25, PIO_SERCOM);
pinPeripheral(26, PIO_SERCOM); // maybe SERCOM5 ???

nope

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

in https://github.com/arduino/ArduinoCore-samd/blob/master/variants/mkrwan1300/variant.cpp

line 268 or so states that sercom5 is already used for Serial1.
Could that be interfering?
What if you comment these lines ?

// Serial1
Uart Serial1(&sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX);

void SERCOM5_Handler()
{
Serial.IrqHandler();
}

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

did read

resulting in updating the example

#include "Arduino.h"
#include "Wire.h"
#include "wiring_private.h" // pinPeripheral() function

TwoWire myWire(&sercom5, 16, 17);

void setup()
{
  Serial.begin(115200);
  Serial.println("test");
  delay(100);

  myWire.begin();
  pinPeripheral(16, PIO_SERCOM_ALT);   // as sercom 5  uses for PAD0 PAD1 the sercom alt multiplexer.
  pinPeripheral(17, PIO_SERCOM_ALT);  // ++++++++++++++++++++++++++++++++++++++++

  myWire.beginTransmission(44);
  int err = myWire.endTransmission(); 
  Serial.print("E:\t");
  Serial.println(err);

  int n = myWire.requestFrom(44,  (uint8_t) 6);
  Serial.print("N:\t");
  Serial.println(n);
  for (int i = 0; i < n; i++)
  {
    Serial.print("\t");
    Serial.println( myWire.read(), HEX);
  }
}

void loop()
{
}

so if this works it is the PIO_SERCOM_ALT

  pinPeripheral(16, PIO_SERCOM_ALT);
  pinPeripheral(17, PIO_SERCOM_ALT); 

however that still does not explain why the I2C ping did work.

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

I have datasheet DS40001882F https://www.mouser.fi/datasheet/2/268/mchp_s_a0010084422_1-2274877.pdf

You might call myWire.setClock(100000); but that is the default normally.
This doesn't make a difference.

Have you tried to communicate with another I2C device on that sercom5 device? EEPROM ?
No, I haven't.

Trying this example:

#include "Arduino.h"
#include "Wire.h"
#include "wiring_private.h" // pinPeripheral() function

TwoWire myWire(&sercom5, 16, 17);

void setup()
{
  Serial.begin(115200);
  Serial.println("test");
  delay(100);

  myWire.begin();
  pinPeripheral(16, PIO_SERCOM_ALT);   // as sercom 5  uses for PAD0 PAD1 the sercom alt multiplexer.
  pinPeripheral(17, PIO_SERCOM_ALT);  // ++++++++++++++++++++++++++++++++++++++++

  myWire.beginTransmission(44);
  int err = myWire.endTransmission(); 
  Serial.print("E:\t");
  Serial.println(err);

  int n = myWire.requestFrom(44,  (uint8_t) 6);
  Serial.print("N:\t");
  Serial.println(n);
  for (int i = 0; i < n; i++)
  {
    Serial.print("\t");
    Serial.println( myWire.read(), HEX);
  }
}

void loop()
{
}

Results this:

E:	2
N:	0

If I comment out this in variant.cpp, the result is the same:

// Serial1
Uart Serial1(&sercom5, PIN_SERIAL1_RX, PIN_SERIAL1_TX, PAD_SERIAL1_RX, PAD_SERIAL1_TX);

void SERCOM5_Handler()
{
Serial.IrqHandler();
}

So where does this leave us? I'm not educated enough in coding to say...

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

Only now I see this in the datasheet:
image

So those pins PB02 and PB03 was never meant to work as I2C...? But somehow pinging worked....?

If I have to make a new PCB layout, the pins (from the above list) I could use are preferably PA22 and PA23 (from layout perspective). Second option would be to use PA16 and PA17.

I could prototype with those pins before creating a new PCB layout. From what you understand they should work? Could you provide a test sketch to try out PA22 and PA23? I guess I could do it myself, but I don't trust myself on this right now...

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

(updated your post to get syntax highlighting - adding cpp after the three backquotes)

So where does this leave us? I'm not educated enough in coding to say...

For me this is also new territory, but I have the feeling we are closing in on the issue (which is outside the library context)

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

Results this:
E: 2
N: 0

Error code 2 means NOT connected => so it makes sense that it could not read the device.


Only now I see this in the datasheet:
image

So those pins PB02 and PB03 was never meant to work as I2C...? But somehow pinging worked....?

If I have to make a new PCB layout, the pins (from the above list) I could use are preferably PA22 and PA23 (from layout perspective). Second option would be to use PA16 and PA17.

I could prototype with those pins before creating a new PCB layout. From what you understand they should work? Could you provide a test sketch to try out PA22 and PA23? I guess I could do it myself, but I don't trust myself on this right now...

PA22/23 are pins 0 and 1 (based upon variants.cpp )
That would mean for the code to change to

#include "Arduino.h"
#include "Wire.h"
#include "wiring_private.h" // pinPeripheral() function

TwoWire myWire(&sercom5, 0, 1);  // <<<<<<<<<<<<<<<<<<<<

void setup()
{
  Serial.begin(115200);
  Serial.println("test");
  delay(100);

  myWire.begin();
  pinPeripheral(0, PIO_SERCOM_ALT);   // <<<<<<<<<<<<
  pinPeripheral(1, PIO_SERCOM_ALT);   // <<<<<<<<<<<<

  myWire.beginTransmission(44);
  int err = myWire.endTransmission(); 
  Serial.print("E:\t");
  Serial.println(err);

  int n = myWire.requestFrom(44,  (uint8_t) 6);
  Serial.print("N:\t");
  Serial.println(n);
  for (int i = 0; i < n; i++)
  {
    Serial.print("\t");
    Serial.println( myWire.read(), HEX);
  }
}

void loop()
{
}

Should be tested before making the PCB - very true...

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

Any progress made?

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

I think I'll have update on this on Monday 6.9.

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

Any progress?

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

Hi,

Using MKR WAN1310 board I tested SHT31 on pins PA22 (SDA) and PA23 (SCL) and it works.

TwoWire myWire(&sercom5, 0, 1);

  pinPeripheral(0, PIO_SERCOM_ALT);
  pinPeripheral(1, PIO_SERCOM_ALT);

I tested with one SHT31 (0x45) on this SERCOM5 interface. I still need to connect a sensor to default I2C I/F and make sure they both work in the same sketch.

from sht31.

tipo1000A avatar tipo1000A commented on July 24, 2024

I hooked up another SHT31 to default I2C and they both (default and SERCOM) work fine!

Thanks for putting your time and effort on this. In the end the whole thing was because I didn't read the spec carefully.

from sht31.

RobTillaart avatar RobTillaart commented on July 24, 2024

In the end the whole thing was because I didn't read the spec carefully.

Reading specs is hard, you are definitely not alone in that one.

Can you post your final sketch that works?
I would like to add it to the examples in the library.

from sht31.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.