Hi, I want to build a large display with 4 7-segment digits. A master-ESP32 gets the data to display via MQTT and sends them via an i2c-bus to the digits, which each have a ESP32-slave. The slaves shall compile their i2c-address from 3 jumpers according to their position in the display. So I only have one type of spare and can configure it via jumpers.
From https://www.arduino.cc/reference/en/lib ... i2c-slave/ I found a library and copied the examples for testing with minor changes. This worked as expected.
When I added the code for reading the jumpers and changed
bool success = WireSlave.begin(SDA_PIN, SCL_PIN, I2C_SLAVE_ADDR);
to
bool success = WireSlave.begin(SDA_PIN, SCL_PIN, position);
where position is an int, it gave me
E (25) i2c: i2c_param_config(671): i2c clock choice is invalid, please check flag and frequency
[ 29][E][WireSlave.cpp:53] begin(): invalid I2C parameters
I changed back, but the error remains (
Any ideas what goes wrong here?
TIA, Karl
[Codebox]/**
* S-tv22004-display
*
* gets a string (number + DP or blank) and controls a 7-digit-display
* seen at https://diyi0t.com/segment-led-display- ... d-esp8266/
* v0.1 2022-06-29 upload-test, blink-test and simple digit-test
* v0.2 2022-06-29 displays a random number
* v0.3 2022-06-30 gets number to display via i2c-bus (address hardcoded)
* v0.4 2022-07-08 read address-pins
*
* create test-mode (segments a to g for 1 sec, then lamp-test for 5 sec)
*/
// libraries
#include "Arduino.h"
#include <Wire.h>
#include <WireSlave.h>
// define used pins and segments
int LEDs[] = {27,26,25,33,32,19,18,17}; // pins on ESP32 microcontroller for segments a-g + DP
#define SDA_PIN 21
#define SCL_PIN 22
#define I2C_SLAVE_ADDR 0x02
// define used pins
int ADDRs[] = {5,2,15}; // pins on ESP32 microcontroller for address-selection
int display[][7] = {
{1,1,1,1,1,1,0}, /* 0 */
{0,1,1,0,0,0,0}, /* 1 */
{1,1,0,1,1,0,1}, /* 2 */
{1,1,1,1,0,0,1}, /* 3 */
{0,1,1,0,0,1,1}, /* 4 */
{1,0,1,1,0,1,1}, /* 5 */
{1,0,1,1,1,1,1}, /* 6 */
{1,1,1,0,0,0,0}, /* 7 */
{1,1,1,1,1,1,1}, /* 8 */
{1,1,1,1,0,1,1}, /* 9 */
{0,0,0,0,0,0,0} /* blank */
};
// variables
int num = 10; // I forgot why I set this to 10
// functions
void receiveEvent(int howMany);
void requestEvent();
void display_num(int num){
Serial.print("L52 num=");
Serial.println(num);
if (num ==20){
for (int i = 0; i<7; i++) digitalWrite(LEDs, display[0][10]); // write "blank" to display
digitalWrite(LEDs[7], LOW);
}
else if (num > 9){
num = num - 10;
for (int i = 0; i<7; i++) digitalWrite(LEDs, display[num]); // write num to display
digitalWrite(LEDs[7], HIGH);
}
else {
for (int i = 0; i<7; i++) digitalWrite(LEDs, display[num]); // write 0 to display
digitalWrite(LEDs[7], LOW);
}
}
void receiveEvent(int howMany) {
while (1 < WireSlave.available()) // loop through all but the last byte
{
char c = WireSlave.read(); // receive byte as a character
Serial.print(c); // print the character
}
num = WireSlave.read(); // receive byte as an integer
Serial.print("L77 num=");
Serial.println(num); // print the integer
display_num(num);
}
void requestEvent() {
static byte y = 0;
WireSlave.print("y is ");
WireSlave.write(y++);
Serial.print("L86 requestEvent - Y = ");
Serial.println(y);
}
// select which position to display from ADDR-jumpers
int get_position(){
int pos = 0;
if(!digitalRead( ADDRs[0])){
pos = pos + 1;
}
if(!digitalRead(ADDRs[1])){
pos = pos + 2;
}
if(!digitalRead(ADDRs[2])){
pos = pos + 4;
}
Serial.print("L102 pos= ");
Serial.println(pos);
return pos;
}
////////////////////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
for (int i = 0; i<7; i++) pinMode(LEDs, OUTPUT);
for (int i = 0; i<3; i++) pinMode(ADDRs, INPUT_PULLUP); // sets up position-select-pins
int position = get_position();
Serial.print("L114 position= ");
Serial.println(position);
if (position == 0){
Serial.println("test-mode");
}
// Serial.print("L144 i2c_addr= ");
// Serial.println(I2C_SLAVE_ADDR, HEX);
bool success = WireSlave.begin(SDA_PIN, SCL_PIN, position);
if (!success) {
Serial.println("I2C slave init failed");
while(1) delay(100);
}
else {
Serial.printf("Slave joined I2C bus with addr #%d\n", I2C_SLAVE_ADDR);
}
WireSlave.onReceive(receiveEvent);
//WireSlave.onRequest(requestEvent);
for (int i = 0; i<7; i++) digitalWrite(LEDs, display[8]); // write 8 to display
digitalWrite(LEDs[7], HIGH); // DP on
delay(3000);
for (int i = 0; i<7; i++) digitalWrite(LEDs, display[0][10]); // write "blank" to display
digitalWrite(LEDs[7], LOW); // DP off
Serial.println("L140 setup completed");
}
////////////////////////////////////////////////////////////////////////////////////
void loop() {
WireSlave.update();
delay(1);
}[/Codebox]
[solved] i2c-slave stopped working
[solved] i2c-slave stopped working
Last edited by karls0 on Mon Jul 11, 2022 9:41 am, edited 1 time in total.
-
- Posts: 826
- Joined: Mon Jul 22, 2019 3:20 pm
Re: i2c-slave stopped working
The overload options have gotten a bit confusing with the introduction of I2C slave mode. I would recommend you call Wire like this to make the instruction unambiguous:
Code: Select all
WireSlave.setPins(SDA_PIN, SCL_PIN);
WireSlave.begin(I2C_ADDRESS);
Re: i2c-slave stopped working
Thank you for the tip, but it does not work for me. After changing the code I get:
Do you know what's going wrong here?
Thanks, Karl
Code: Select all
src/main.cpp:128:13: error: 'class TwoWireSlave' has no member named 'setPins'
WireSlave.setPins(SDA_PIN, SCL_PIN);
^~~~~~~
src/main.cpp:130:33: error: no matching function for call to 'TwoWireSlave::begin(int)'
WireSlave.begin(I2C_SLAVE_ADDR);
Thanks, Karl
Re: i2c-slave stopped working
Hi,
I switched to the Wire-library which was updated recently, following a tip from @Koepel I got in
https://forum.arduino.cc/t/i2c-slave-st ... /1010793/7
Now it works in one direction. I will test the other direction sometime this week.
Thank you, Karl
I switched to the Wire-library which was updated recently, following a tip from @Koepel I got in
https://forum.arduino.cc/t/i2c-slave-st ... /1010793/7
Now it works in one direction. I will test the other direction sometime this week.
Thank you, Karl
-
- Posts: 826
- Joined: Mon Jul 22, 2019 3:20 pm
Re: i2c-slave stopped working
I don't know what WireSlave.h is. There is I2C slave functionality in the Wire library since v2.0.1.
https://github.com/espressif/arduino-es ... Wire.h#L80
https://github.com/espressif/arduino-es ... Wire.h#L80
Re: [solved] i2c-slave stopped working
I did try the Wir-library first, but it did not work. So I searched for a i2c-slave library as sayd in my first post. On arduino.cc I found the mentioned library, but in the meantime have switched to the latest version of Wire. Now everything works fine.
Who is online
Users browsing this forum: No registered users and 86 guests