-
Notifications
You must be signed in to change notification settings - Fork 0
example for esp32, nucleo 64 and arduino uno r4 #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
1c50a53
initial version for esp32 example
LeonieFierz 9ef0c47
update platform in sketch
LeonieFierz 07b9ea0
add pyserial dependency to workflow
LeonieFierz 651274b
move helper functions to above loop
LeonieFierz ccea002
try to change to platform again
LeonieFierz 6e0e4bf
update pullup description
LeonieFierz 312e3f1
fix clang definition
LeonieFierz d1362a5
remove building sketch in CI
LeonieFierz 355a813
format esp32 example
LeonieFierz 32cb06b
Improve documentation
psachs 143b36f
update example to work also for nucleo
LeonieFierz 8564122
add docu for nucleo64 board
LeonieFierz e244563
fix nucleo wiring table
LeonieFierz 98aa118
add documentation for arduino uno r4
LeonieFierz 5b7f0e6
improve README structure
LeonieFierz 4dae334
move pull up docs to separate file
LeonieFierz 3646642
rename example
LeonieFierz 5211c8a
remove hackster specific section
LeonieFierz ea1767d
add build for arduino uno r4 to ci
LeonieFierz b68ab94
fixing typos
LeonieFierz e99df71
readme fixes
LeonieFierz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--- | ||
Language: Cpp | ||
BasedOnStyle: LLVM | ||
IndentWidth: 4 | ||
AlignAfterOpenBracket: Align | ||
AllowShortBlocksOnASingleLine: false | ||
AllowShortCaseLabelsOnASingleLine: false | ||
AllowShortFunctionsOnASingleLine: false | ||
IndentCaseLabels: true | ||
SpacesBeforeTrailingComments: 2 | ||
PointerAlignment: Left | ||
AlignEscapedNewlines: Left | ||
ForEachMacros: ['TEST_GROUP', 'TEST'] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
name: Quality check | ||
on: | ||
pull_request: | ||
branches: | ||
- main | ||
push: | ||
branches: | ||
- main | ||
jobs: | ||
clang_format_check: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: RafikFarhad/clang-format-github-action@v4 | ||
with: | ||
sources: "esp32-different-i2c-buses-example/*.ino" | ||
style: file | ||
build_sketch: | ||
runs-on: ubuntu-latest | ||
env: | ||
CLI_PATH: ./cli | ||
steps: | ||
- name: checkout | ||
uses: actions/checkout@v4 | ||
- name: install arduino-cli | ||
run: | | ||
mkdir -p $CLI_PATH | ||
export PATH=$PATH:$CLI_PATH | ||
curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | BINDIR=$CLI_PATH sh | ||
|
||
- name: build sketch | ||
run: | | ||
${CLI_PATH}/arduino-cli compile --profile arduino-uno-r4 ./differentI2cBusesExample |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,305 @@ | ||
# arduino-i2c-different-buses-example | ||
Tutorial how to set up different I2C buses on Arduino platform | ||
# Introduction | ||
|
||
You have a micro controller and two identical sensors, meaning that they have the same I2C address. Without a multiplexer | ||
or the possibility to configure the I2C address of the sensor, you cannot attach them to the same I2C bus. However, on a | ||
board that provides the ability to configure any GPIO pin pairs as an I2C bus, you can connect the two sensors to their | ||
own individual I2C buses. In this article, we will explain how to set up separate I2C buses for each sensor for a few different boards. | ||
|
||
# General working principle | ||
|
||
The two SCD41 sensors we want to connect have an I2C address of 0x62, which cannot be changed. Therefore, to communicate | ||
with both sensors from the micro controller, we will use a separate I2C bus for each. Each I2C bus requires one pin for | ||
the SDA line and one for the SCL line. Depending on the board and library implementation, we can either use pre-configured | ||
instances of the `Wire` library or we need to create our own instances of the `TwoWire` class and assign the pins used for | ||
SDA and SCL lines. As a final step, we will create two instances of our sensor driver class and | ||
initialize one with the first I2C bus and the other with the second I2C bus. | ||
|
||
# ESP32 DevKitC | ||
|
||
## Wiring | ||
|
||
First, we need to define the pins we will use for the two I2C buses. For I2C bus A, we can use the default I2C pins | ||
of the board. For the ESP32 DevKitC, these are pin 21 (SCL) and pin 22 (SDA). For I2C bus B, we can choose any two | ||
GPIO (General Purpose Input Output) pins. | ||
|
||
If you are using a different board, it is important to check the specifications to determine if any pins have special | ||
configurations that prevent them from being used as GPIO pins. In our case, we have selected pins 17 and 16 for | ||
I2C bus B. | ||
|
||
### Pull-up resistors | ||
|
||
Having pull-up resistors in place on the I2C data (SDA) and clock (SCL) lines is important to have a good signal quality and robust communication. You can read more about it on [I2C Pull-Up Resistors Intro](i2c-pull-up-resistors-intro.md) | ||
|
||
The ESP32 DevKitC Board ensures that GPIO lines are automatically pulled to a high state. Therefore, there is no need to | ||
manually wire or configure pull-up resistors for the pins you intend to use. | ||
|
||
### Wiring diagram | ||
|
||
Since the SCD41 sensor is compatible with both 3.3V and 5V, we can connect one sensor to the 3.3V pin and the other to | ||
the 5V pin. If both sensors require the same voltage, they can be connected through a breadboard. | ||
|
||
For this example, the wiring should be carried out as follows: | ||
|
||
 | ||
|
||
- SEK-SCD41 A - Pin 1 to ESP32 Pin 22 (SCL, yellow cable) | ||
- SEK-SCD41 A - Pin 2 to ESP32 GND (Ground, black cable) | ||
- SEK-SCD41 A - Pin 3 to ESP32 3V3 (Sensor supply voltage, red cable) | ||
- SEK-SCD41 A - Pin 4 to ESP32 Pin 21 (SDA, green cable) | ||
|
||
- SEK-SCD41 B - Pin 1 to ESP32 Pin 17 (SCL, yellow cable) | ||
- SEK-SCD41 B - Pin 2 to ESP32 GND (Ground, black cable) | ||
- SEK-SCD41 B - Pin 3 to ESP32 5V (Sensor supply voltage, red cable) | ||
- SEK-SCD41 B - Pin 4 to ESP32 Pin 16 (SDA, green cable) | ||
|
||
When configuring the software later on, it is important to remember the pins allocated for the second I2C bus. | ||
Specifically, we used pin 17 for the I2C clock (SCL) and pin 18 for the I2C data (SDA). | ||
|
||
## Software setup | ||
|
||
First, you need to include the Wire library: | ||
|
||
``` | ||
#include <Wire.h> | ||
``` | ||
|
||
We are using the Arduino ESP32 platform, which includes the `Wire` library, that is already configured for | ||
the default I2C bus on pins 21/22. | ||
We can use the `Wire` instance without any modification for the sensor attached to the "I2C bus A" (default I2C bus). | ||
We just need to initialize the bus with: | ||
|
||
``` | ||
Wire.begin(); | ||
``` | ||
|
||
For the "I2C bus B" we need to configure a custom `TwoWire` instance. There is a predefined instance named `Wire1` we | ||
can configure to use the pins we defined with the following lines of code within the `setup()` function: | ||
|
||
``` | ||
const int sda_B = 16; | ||
const int scl_B = 17; | ||
Wire1.begin(sda_B, scl_B); | ||
``` | ||
|
||
Then, the code sending the commands to the sensors over the I2C bus needs to know which bus to use for which sensor. | ||
Thus, you need to configure the sensor instances accordingly. First, create a driver instance per sensor. | ||
Their scope should be global, such that those can be referred to from within `setup()` and `loop()`. | ||
|
||
``` | ||
SensirionI2cScd4x sensorA; | ||
SensirionI2cScd4x sensorB; | ||
``` | ||
|
||
Then, in the `setup()` function, assign the I2C buses to the sensors: | ||
|
||
``` | ||
sensorA.begin(Wire, SCD41_I2C_ADDR_62); | ||
sensorB.begin(Wire1, SCD41_I2C_ADDR_62); | ||
``` | ||
|
||
Look out that you really have `Wire1` assigned for sensorB, so that it uses the custom set-up I2C bus. | ||
|
||
You can now send any I2C command to the sensor, such as initiating the measurement and retrieving values. | ||
|
||
``` | ||
sensorA.startMeasurement(); | ||
sensorB.startMeasurement(); | ||
... | ||
``` | ||
|
||
You can find more details and options how to configure several I2C buses on the ESP32 platform using the Arduino IDE under [ESP32 I2C Tutorial](https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/) | ||
|
||
|
||
## Example sketch | ||
|
||
You find a complete example under [differentI2cBusesExample.ino](differentI2cBusesExample/differentI2cBusesExample.ino). | ||
Make sure to only have the define for your board `#define ESP32_DEVKITC_V4 1` uncommented, which you find at the beginning of the sketch. | ||
|
||
# STM32 Nucleo 64 Board | ||
|
||
## Wiring | ||
|
||
The STM32 Nucleo 64 board has pre-defined I2C pins. We use I2C1 (SDA on pin 14, SCL on pin 15) and | ||
I2C2 (SDA on pin 3, SCL on pin 6). | ||
|
||
### Pull Ups | ||
The Nucleo board nor the development kit board has pull-up resistors built in. | ||
Thus, we need to wire a resistor into each of the I2C communication lines. Four 8.26kOhm resistors were used in | ||
this example and the wiring was done using a bread board so that no soldering was needed. | ||
|
||
### Wiring diagram | ||
 | ||
|
||
Names R.1 to R.4 stand for resistors with a value of 8.26kOhm. | ||
|
||
- SEK-SCD41 A Pin 1 to R.1 (SCL, yellow) | ||
- R.1 to Nucleo Pin 15 (SCL, yellow) | ||
- R.1 to Nucleo 3V3 | ||
- SEK-SCD41 A Pin 2 to Nucleo GND | ||
- SEK-SCD41 A Pin 3 to Nucleo 3V3 | ||
- SEK-SCD41 A Pin 4 to R.2 (SDA, green) | ||
- R.2 to Nucleo Pin 14 (SDA, green) | ||
- R.2 to Nucleo 3V3 | ||
|
||
- SEK-SCD41 B Pin 1 to R.3 (SCL, yellow) | ||
- R.3 to Nucleo Pin 6 (SCL, yellow) | ||
- R.3 to Nucleo 3V3 | ||
- SEK-SCD41 B Pin 2 to ESP32 GND (Ground, black cable) | ||
LeonieFierz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- SEK-SCD41 B Pin 3 to ESP32 5V (Sensor supply voltage, red cable) | ||
LeonieFierz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- SEK-SCD41 B Pin 4 to R.4 (SDA, green) | ||
- R.4 to Nucleo Pin 3 (SDA, green) | ||
- R.4 to Nucleo 3V3 | ||
|
||
What we have to remember for the configuration in the software later is the pins we used for the I2C buses. | ||
|
||
## Software setup | ||
|
||
First, you need to include the Wire library: | ||
|
||
``` | ||
#include <Wire.h> | ||
``` | ||
|
||
For configuring the I2C buses with the correct pins, we need to instantiate two TwoWire instances and pass | ||
the pins to be used for the I2C communication. | ||
Their scope should be global, thus the definition is outside `setup()` and `loop()`. | ||
|
||
``` | ||
// I2C Bus A on Pins 14 (SDA) / 15 (SCL) | ||
const int sda_A = 14; | ||
const int scl_A = 15; | ||
TwoWire i2cBusA(sda_A, scl_A); | ||
|
||
// I2C Bus B on Pins 3 (SDA) / 6 (SCL) | ||
const int sda_B = 3; | ||
const int scl_B = 6; | ||
TwoWire i2cBusB(sda_B, scl_B); | ||
``` | ||
|
||
Then, the code sending the commands to the sensors over the I2C Bus needs to know which bus to use for which sensor. | ||
Thus, you need to configure the sensors instances accordingly. First, create a driver instance per sensor. | ||
Their scope should be global, such that they can be referred to from within `setup()` and `loop()`. | ||
|
||
``` | ||
SensirionI2cScd4x sensorA; | ||
SensirionI2cScd4x sensorB; | ||
``` | ||
|
||
Then, in the `setup()` function, assign the I2C Buses to the sensors: | ||
|
||
``` | ||
sensorA.begin(i2cBusA, SCD41_I2C_ADDR_62); | ||
sensorB.begin(i2cBusB, SCD41_I2C_ADDR_62); | ||
``` | ||
|
||
You can now send any I2C command to the sensor, such as initiating the measurement and retrieving values. | ||
The complete example code is provided in the link. | ||
|
||
``` | ||
sensorA.startMeasurement(); | ||
sensorB.startMeasurement(); | ||
... | ||
``` | ||
|
||
## Example sketch | ||
|
||
You find a complete example under [differentI2cBusesExample.ino](differentI2cBusesExample/differentI2cBusesExample.ino). | ||
Make sure to only have the define for your board `#define STM32_NUCLEO_64 1` uncommented, which you find at the beginning of the sketch. | ||
|
||
# Arduino Uno R4 WIFI | ||
|
||
# Wiring | ||
|
||
The Arduino Uno R4 WIFI provides one I2C bus on the pin header, which has no pull-ups on the board. | ||
Thus, we need to connect a pull up resistor between SDA and VDD and SCL and VDD. | ||
In the example two 2.2kOhm resistors were used. | ||
|
||
The second I2C bus is on the Qwiic. We use here the breakout board from Adafruit. | ||
The board includes 10K pull-up on SDA and SCL. | ||
|
||
### Pull Ups | ||
|
||
The Arduino Uno R4 WIFI provides no pull-ups on the board. | ||
|
||
The SEK SCD41 board we are going to connect to the I2C Bus on the pin header has no pull-up resistors built in. | ||
Thus, we need to connect a pull-up resistor between SDA and VDD and SCL and VDD. Two 8.26kOhm resistors were used in | ||
this example and the wiring was done using a bread board so that no soldering was needed. | ||
|
||
The second sensor is on a Adafruit breakout board. This one includes a pull-up resistor. Thus, | ||
no pull-up resistors have to be wired into this connection, for which a Qwiic cable is used. | ||
|
||
### Wiring diagram | ||
|
||
 | ||
LeonieFierz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The list below describes the wiring, where R.1 and R.2 are resistors with a value of 8.26kOhm. | ||
|
||
- SEK-SCD41 Pin 1 to R.1 (SCL, yellow) | ||
- R.1 to Arduino Pin SCL (yellow) | ||
- R.1 to Arduino 3V3 | ||
- SEK-SCD41 Pin 2 to Arduino GND | ||
- SEK-SCD41 Pin 3 to Arduino 3V3 | ||
- SEK-SCD41 Pin 4 to R.2 (SDA, green) | ||
- R.2 to Arduino Pin 14 (green) | ||
- R.2 to Arduino 3V3 | ||
|
||
- Adafruit SCD41 to Arduino Qwiic | ||
|
||
|
||
## Software setup | ||
|
||
First, you need to include the Wire library: | ||
|
||
``` | ||
#include <Wire.h> | ||
``` | ||
|
||
For the Arduino Uno R4, this library defines two I2C buses. The first, "Wire" is configured | ||
for the SDA/SCL pins on the pin header, where "Wire1" is configured for the Qwiic connector. | ||
We can use those two instances without any further configuration. You just need to initialize them: | ||
|
||
``` | ||
Wire.begin(); | ||
Wire1.begin(); | ||
``` | ||
|
||
Then, the code sending the commands to the sensors over the I2C bus needs to know which bus to use for which sensor. | ||
Thus, you need to configure the sensor instances accordingly. First, create a driver instance per sensor. | ||
Their scope should be global, such that those can be referred to from within `setup()` and `loop()`. | ||
|
||
``` | ||
SensirionI2cScd4x sensorOnPins; | ||
SensirionI2cScd4x sensorOnQwiic; | ||
``` | ||
|
||
Next, in the `setup()` function, assign the I2C buses to the sensors: | ||
|
||
``` | ||
sensorOnPins.begin(Wire, SCD41_I2C_ADDR_62); | ||
sensorOnQwiic.begin(Wire1, SCD41_I2C_ADDR_62); | ||
``` | ||
|
||
Look out that you really have `Wire1` assigned for `sensorOnQwiic`. | ||
|
||
You can now send any I2C command to the sensor, such as initiating the measurement and retrieving values. | ||
The complete example code is provided in the link. | ||
|
||
``` | ||
sensorOnPins.startMeasurement(); | ||
sensorOnQwiic.startMeasurement(); | ||
... | ||
``` | ||
|
||
|
||
## Example sketch | ||
|
||
You find a complete example under [differentI2cBusesExample.ino](differentI2cBusesExample/differentI2cBusesExample.ino). | ||
Make sure to only have the define for your board `#define ARDUINO_UNO_R4_WIFI 1` uncommented, which you find at the beginning of the sketch. | ||
|
||
# Other Arduino Boards | ||
|
||
Documentation for Arduino boards can be found under [Arduino Wire Library](https://docs.arduino.cc/language-reference/en/functions/communication/wire/). | ||
|
||
Note that not all boards support multiple I2C buses and that it is recommended to use a custom pull-up resistor configuration, | ||
as the built in resistors are likely not strong enough (resistor value is too big). | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.