Comments (31)
Hi Tipo,
I will make a branch with a test example so we have a "playground to test" OK?
from sht31.
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.
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.
just a thought
A possible workaround is using - https://github.com/RobTillaart/TCA9548
from sht31.
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.
@tipo1000A
Any progress made?
from sht31.
@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.
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.
- 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
from sht31.
- 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.
- 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.
And if you commented out b1 and b2 the other pair worked?
from sht31.
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.
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.
If I understand the theory correctly I would try sercom4 and pin 19, 20
You might notice that pin 17 and 18 are skipped in that column.
from sht31.
OK found where the numbers 16 and 17 possibly come from.
(page 33 datasheet)
Looking up these in the MUX table.
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.
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.
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
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.
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.
pinPeripheral(25, PIO_SERCOM);
pinPeripheral(26, PIO_SERCOM); // maybe SERCOM5 ???
nope
from sht31.
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.
did read
- https://cdn-learn.adafruit.com/downloads/pdf/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports.pdf
- https://learn.sparkfun.com/tutorials/adding-more-sercom-ports-for-samd-boards/adding-an-i2c
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.
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.
Only now I see this in the datasheet:
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.
(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.
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:
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.
Any progress made?
from sht31.
I think I'll have update on this on Monday 6.9.
from sht31.
Any progress?
from sht31.
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.
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.
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)
- Exposing the raw temperature and humidity? HOT 6
- Add lastHeaterStopTime variable to prevent switching on the heater too early HOT 2
- Return 0.0C and 0.0% HOT 5
- isConnected returns true if voltaje to SHT31 is not connected. HOT 4
- SoftWire library + SHT31 library HOT 23
- prototype for 'bool SHT31::begin(uint8_t, uint8_t, uint8_t)' does not match any in class 'SHT31' HOT 6
- Using SHT31 in High Humidity Environment HOT 9
- check SHT2x functions added HOT 1
- Heater HOT 5
- SHT31 library with Arduino-ESP32 v2.0.5 HOT 8
- support Wire2 for ESP32
- Question on i2c error handling HOT 23
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
š Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ā¤ļø Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sht31.