I2C y TX/RX juntos

Hola a todos. A ver si alguien me puede ayudar.
Estoy montando con un Arduino Nano:

  • una pantalla OLED 128x64 a través de bus I2C,
  • un módulo RTC a través de I2C también,
  • y un módulo MP3 a través de TX/RX.

Por separado me funcionan perfectamente, la pantalla y el módulo RTC juntos también, el problema está con el MP3. Con este módulo deja de funcionar todo.
Haciendo pruebas veo que deja de funcionar con esta línea

SoftwareSerial DFPlayerSerial(RX, TX)

si la dejo comentada funciona. Entiendo que es un problema con los buses pero, por más que he leído, todo el mundo dice que se pueden usar los dos simultáneamente, y yo no lo consigo :(.

OLED_128x64_RTC_MP3.ino (2.55 KB)

Hi,
Nunca he trabajado con mp3 player pero adjunto un link que explica como hacerlo. A veces tienes que invertir el tx y rx. En otras palabras Rx del arduino va al tx y el arduino tx va al rx.De todas manera mira el tutorial para ver si te ayuda a resolver el problema. Mira a ver si el modulo mp3 se parece al tuyo.

Una pregunta, según el esquema del nano

El pin 11 es del MOSI

Tu tienes

#define RX 10         // Módulo MP3
#define TX 11         // Módulo MP3
SoftwareSerial DFPlayerSerial(RX, TX);

¿por qué no usas el 0 y el 1 que son el RX y TX por defecto?

Por cierto, no hagas #define para eso, usa una constante

const PRX = 10;
const PTX = 11; 
SoftwareSerial DFPlayerSerial(PRX, PTX);

Moderador:
Por favor, códigos menores a 9k deben postearse usando etiquetas para código.
Lee las normas y edita tu post inicial.

@bermar
Nada tiene que ver I2C con el Serial.
Si funcionan bien solos deben hacerlo bien juntos.
El error seguramente estará en como has unido los códigos o si arrastras algún delay que entorpece el funcionamiento de alguno de los dispositivos.
cuando postees el código te daré una mejor respuesta, ahora como digo siempre, quien no cumple con las normas no merece una respuesta completa.

@tauro0221, si te dice que el código Serial funciona para que le sugieres que invierta los cables RX y TX? Ese no puede ser el problema.

@TonyDiana

TonyDiana:
Por cierto, no hagas #define para eso, usa una constante

const PRX = 10;

const PTX = 11;
SoftwareSerial DFPlayerSerial(PRX, PTX);

Tony se te ha escapado algo de otro lenguaje.
En Arduino debes indicar que tipo de variable será la constante y ahi no lo has especificado.

Solemos decir que lo mejor es

const byte PRX = 10;
const byte PTX = 11;

Pero no entiendo porque no estas de acuerdo con usar #define.
Recuerdo un hilo donde se probó que era mas barato usar #define que usar const byte o const int.

Otro tema. Usar 0 y 1 o sea el HardwareSerial te quita la posibilidad de leer cosas con el MonitorSerie.
Estoy de acuerdo en su uso pero cuando ya sabes que el código funciona perfectamente.
Imagina que en esta etapa no es el caso.
Una vez resuelto el código con SoftwareSerial, bien puede usar tu consejo de olvidar SofwareSerial y aprovechar 0 y 1 con mínimos cambios.

Oh sí que fallo jejje se me olvidó tipar, se nota que hoy estuve con Python

El problema del define es que el precompilador lo cambia en cualquier lado y te puede montar un desastre, ocupa menos porque queda a nivel de código, cierto, pero si tienes una variable que has llamado RXColor, la renombra también a 10Color, ya que cambia cualquier RX por 10

No sabía lo del puerto serie, hoy aprendí algo más gracias

Okay Tony, me la vas a ganar en otros casos pero no en este jajaja

Solo hablo de los pines no de otras constantes.
Los pines terminan siendo mas baratos con #define pero la ganancia es leve y hasta sería debatible.
Entre nos, define pone esa constante en FLASH no? y su acceso es mas lento o no lo es?
En cambio una const en RAM tiene un acceso mas veloz.
Que opinan?

Puerto Serie.
Yo recomiendo con el tema puerto Serie, siempre usar algo con varios puertos, un MEGA por ejemplo tienes 4 Seriales.
SoftwareSerial funciona bien entonces lo uso hasta que me aseguro y la versión final la monto en el puerto Serie ya que prescindo del MonitorSerie. Pero luego a no quejarse!!!

Hi,
Yo me deje llevar por lo que el dice

Por separado me funcionan perfectamente, la pantalla y el módulo RTC juntos también, el problema está con el MP3.

Dice que cuando pone el MP# deja de trabajar. Si mira los pines del MP3 tiene TX y RX. Creia que el no habia conectado el mp3 todavia. Algunas veces uno se va por la tarjente.

Una pregunta, si pines 0 y 1 sin los serial del usb, ¿entonces usarlos como interrupciones tiene el mismo efecto de pérdida de serial?

Ni remotamente podría ser que se quede sin memoria, no?

Bueno si quieres usar define para los pines, usa al menos un nombre más largo, tipo PIN_RX, algo difícil de que el complicador la líe parda. Recuerdo una vez un problema maldito en otro lenguaje (Abal de Prologue) que tuve que editar en hexadecimal para darme cuenta de lo que estaba pasando precisamente por lo mismo

@surbyte perdón, posteo el código

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"             // Librería para el módulo RTC
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Objeto reloj RTC
RTC_DS3231 miReloj;

// Objeto MP3
#define RX 10         // Módulo MP3
#define TX 11         // Módulo MP3
SoftwareSerial DFPlayerSerial(RX, TX);


int prueba = 25;
int hora, minuto, segundo, dia, mes, ano;
float temperatura;
String monthsNames[13] = {"", "ene", "feb", "mar", "abr", "may", "jun", "jul","ago","sep","oct","nov","dic" };
String nombreMes;

void setup() {
 Serial.begin(9600);

 // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
 if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
   Serial.println(F("SSD1306 allocation failed"));
   for(;;); // Don't proceed, loop forever
 }

 // Show initial display buffer contents on the screen --
 // the library initializes this with an Adafruit splash screen.
 display.display();
 delay(2000);
}

void loop() {
   /* Obtener la fecha actual */
 DateTime now = miReloj.now();
 hora = now.hour();
 minuto = now.minute();
 segundo = now.second();
 dia = now.day();
 mes = now.month();
 nombreMes = monthsNames[mes];
 ano = now.year();
 temperatura = miReloj.getTemperature();

 display.clearDisplay();
 display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
 display.setTextColor(SSD1306_WHITE);        // Draw white text
 
 display.setCursor(30,5);
 display.setTextSize(1);
 display.print(dia);
 display.print(".");
 display.print(nombreMes);
 display.print( ".");
 display.println(ano);

 display.setCursor(18,20);
 display.setTextSize(2);
 if (hora <= 9){
   display.print(0);
 }
 display.print(hora);
 display.print(":");
 if (minuto <= 9){
   display.print(0);
 }
 display.print(minuto);
 display.print(":");
 if (segundo <= 9){
   display.print(0);
 }
 display.println(segundo);
 
 display.setCursor(5,45);
 display.setTextSize(1);
 display.print ("Temperatura: ");
 display.print (temperatura);
 display.println (" C");

 display.display();
}

Moderador:
He editado el código porque parece que el español ahora hay que traducirlo.
Si escribo

Por favor, códigos menores a 9k deben postearse usando etiquetas para código.

Porqué lo posteas como un texto común?
Y si lo haces mal, vuelves y lo editas.
Finalmente en post posteriores lo has hecho, asi que doy por terminado el tema código.

deberías posteral el código correctamente, mira las normas, te van a zumbar ahora mismo

no me aclaro

#include <SPI.h>[color=#222222][/color]
#include <Wire.h>[color=#222222][/color]
#include <Adafruit_GFX.h>[color=#222222][/color]
#include <Adafruit_SSD1306.h>[color=#222222][/color]
#include "RTClib.h"             // Librería para el módulo RTC[color=#222222][/color]
#include <Adafruit_GFX.h>[color=#222222][/color]
#include <Adafruit_SSD1306.h>[color=#222222][/color]
#include <SoftwareSerial.h>[color=#222222][/color]
[color=#222222][/color]
#define SCREEN_WIDTH 128 // OLED display width, in pixels[color=#222222][/color]
#define SCREEN_HEIGHT 64 // OLED display height, in pixels[color=#222222][/color]
[color=#222222][/color]
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)[color=#222222][/color]
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)[color=#222222][/color]
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);[color=#222222][/color]
[color=#222222][/color]
//Objeto reloj RTC[color=#222222][/color]
RTC_DS3231 miReloj;[color=#222222][/color]
[color=#222222][/color]
// Objeto MP3[color=#222222][/color]
#define RX 10         // Módulo MP3[color=#222222][/color]
#define TX 11         // Módulo MP3[color=#222222][/color]
SoftwareSerial DFPlayerSerial(RX, TX);[color=#222222][/color]
[color=#222222][/color]
[color=#222222][/color]
int prueba = 25;[color=#222222][/color]
int hora, minuto, segundo, dia, mes, ano;[color=#222222][/color]
float temperatura;[color=#222222][/color]
String monthsNames[13] = {"", "ene", "feb", "mar", "abr", "may", "jun", "jul","ago","sep","oct","nov","dic" };[color=#222222][/color]
String nombreMes;[color=#222222][/color]
[color=#222222][/color]
void setup() {[color=#222222][/color]
  Serial.begin(9600);[color=#222222][/color]
[color=#222222][/color]
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally[color=#222222][/color]
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64[color=#222222][/color]
    Serial.println(F("SSD1306 allocation failed"));[color=#222222][/color]
    for(;; // Don't proceed, loop forever[color=#222222][/color]
  }[color=#222222][/color]
[color=#222222][/color]
  // Show initial display buffer contents on the screen --[color=#222222][/color]
  // the library initializes this with an Adafruit splash screen.[color=#222222][/color]
  display.display();[color=#222222][/color]
  delay(2000);[color=#222222][/color]
}[color=#222222][/color]
[color=#222222][/color]
void loop() {[color=#222222][/color]
    /* Obtener la fecha actual */[color=#222222][/color]
  DateTime now = miReloj.now();[color=#222222][/color]
  hora = now.hour();[color=#222222][/color]
  minuto = now.minute();[color=#222222][/color]
  segundo = now.second();[color=#222222][/color]
  dia = now.day();[color=#222222][/color]
  mes = now.month();[color=#222222][/color]
  nombreMes = monthsNames[mes];[color=#222222][/color]
  ano = now.year();[color=#222222][/color]
  temperatura = miReloj.getTemperature();[color=#222222][/color]
[color=#222222][/color]
  display.clearDisplay();[color=#222222][/color]
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);[color=#222222][/color]
  display.setTextColor(SSD1306_WHITE);        // Draw white text[color=#222222][/color]
  [color=#222222][/color]
  display.setCursor(30,5);[color=#222222][/color]
  display.setTextSize(1);[color=#222222][/color]
  display.print(dia);[color=#222222][/color]
  display.print(".");[color=#222222][/color]
  display.print(nombreMes);[color=#222222][/color]
  display.print( ".");[color=#222222][/color]
  display.println(ano);[color=#222222][/color]
[color=#222222][/color]
  display.setCursor(18,20);[color=#222222][/color]
  display.setTextSize(2);[color=#222222][/color]
  if (hora <= 9){[color=#222222][/color]
    display.print(0);[color=#222222][/color]
  }[color=#222222][/color]
  display.print(hora);[color=#222222][/color]
  display.print(":");[color=#222222][/color]
  if (minuto <= 9){[color=#222222][/color]
    display.print(0);[color=#222222][/color]
  }[color=#222222][/color]
  display.print(minuto);[color=#222222][/color]
  display.print(":");[color=#222222][/color]
  if (segundo <= 9){[color=#222222][/color]
    display.print(0);[color=#222222][/color]
  }[color=#222222][/color]
  display.println(segundo);[color=#222222][/color]
  [color=#222222][/color]
  display.setCursor(5,45);[color=#222222][/color]
  display.setTextSize(1);[color=#222222][/color]
  display.print ("Temperatura: ");[color=#222222][/color]
  display.print (temperatura);[color=#222222][/color]
  display.println (" C");[color=#222222][/color]
[color=#222222][/color]
  display.display();[color=#222222][/color]
}

en la anterior me ha puesto al final de cada línea, no sé porque.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"             // Librería para el módulo RTC
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Objeto reloj RTC
RTC_DS3231 miReloj;

// Objeto MP3
#define pin_RX 10         // Módulo MP3
#define pin_TX 11         // Módulo MP3
SoftwareSerial DFPlayerSerial(pin_RX, pin_TX);


int prueba = 25;
int hora, minuto, segundo, dia, mes, ano;
float temperatura;
String monthsNames[13] = {"", "ene", "feb", "mar", "abr", "may", "jun", "jul","ago","sep","oct","nov","dic" };
String nombreMes;

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000);
}

void loop() {
    /* Obtener la fecha actual */
  DateTime now = miReloj.now();
  hora = now.hour();
  minuto = now.minute();
  segundo = now.second();
  dia = now.day();
  mes = now.month();
  nombreMes = monthsNames[mes];
  ano = now.year();
  temperatura = miReloj.getTemperature();

  display.clearDisplay();
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  
  display.setCursor(30,5);
  display.setTextSize(1);
  display.print(dia);
  display.print(".");
  display.print(nombreMes);
  display.print( ".");
  display.println(ano);

  display.setCursor(18,20);
  display.setTextSize(2);
  if (hora <= 9){
    display.print(0);
  }
  display.print(hora);
  display.print(":");
  if (minuto <= 9){
    display.print(0);
  }
  display.print(minuto);
  display.print(":");
  if (segundo <= 9){
    display.print(0);
  }
  display.println(segundo);
  
  display.setCursor(5,45);
  display.setTextSize(1);
  display.print ("Temperatura: ");
  display.print (temperatura);
  display.println (" C");

  display.display();
}

Algo subiste mal, este es tu código

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"             // Librería para el módulo RTC
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

//Objeto reloj RTC
RTC_DS3231 miReloj;

// Objeto MP3
#define RX 10         // Módulo MP3
#define TX 11         // Módulo MP3
SoftwareSerial DFPlayerSerial(RX, TX);


int prueba = 25;
int hora, minuto, segundo, dia, mes, ano;
float temperatura;
String monthsNames[13] = {"", "ene", "feb", "mar", "abr", "may", "jun", "jul","ago","sep","oct","nov","dic" };
String nombreMes;

void setup() {
  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;; // Don't proceed, loop forever
  }

  // Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(2000);
}

void loop() {
    /* Obtener la fecha actual */
  DateTime now = miReloj.now();
  hora = now.hour();
  minuto = now.minute();
  segundo = now.second();
  dia = now.day();
  mes = now.month();
  nombreMes = monthsNames[mes];
  ano = now.year();
  temperatura = miReloj.getTemperature();

  display.clearDisplay();
  display.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, SSD1306_WHITE);
  display.setTextColor(SSD1306_WHITE);        // Draw white text
  
  display.setCursor(30,5);
  display.setTextSize(1);
  display.print(dia);
  display.print(".");
  display.print(nombreMes);
  display.print( ".");
  display.println(ano);

  display.setCursor(18,20);
  display.setTextSize(2);
  if (hora <= 9){
    display.print(0);
  }
  display.print(hora);
  display.print(":");
  if (minuto <= 9){
    display.print(0);
  }
  display.print(minuto);
  display.print(":");
  if (segundo <= 9){
    display.print(0);
  }
  display.println(segundo);
  
  display.setCursor(5,45);
  display.setTextSize(1);
  display.print ("Temperatura: ");
  display.print (temperatura);
  display.println (" C");

  display.display();

}  /// ---- OJO A ESTO

No sé si ha sido un error de copiar y pegar, pero te faltaba el último }
Como no tengo tu hardware no puedo probarlo, pero si nos das alguna pista de por donde te falla, te podemos ayudar, de entrada me he guardado tu código por si preguntas luego

Ok, si fue el copiar y pegar

¿nos das una pista de por donde te está fallando o cómo?

Prueba esto y nos cuentas

// Objeto MP3
Serial.println("Estoy aquí");
#define RX 10         // Módulo MP3
Serial.println("Solo por necedad, veo que valgo " + String(RX) );
#define TX 11         // Módulo MP3
Serial.println("Solo por necedad, veo que valgo " + String(TX) );
SoftwareSerial DFPlayerSerial(RX, TX);
Serial.println("Dinos si llegas hasta aquí");

@TonyDiana cierto, al pegar el código el último corchete faltaba pero en el programa sí que está.

Está montado en un Arduino nano con una pantalla OLED 128x64, un módulo RTC y un módulo DFPlayer Mini.

si dejo la siguiente línea comentada //

SoftwareSerial DFPlayerSerial(pin_RX, pin_TX);

me funciona la pantalla y el OLED, pero cuando le quito // no hace nada.
Acabo de hacer pruebas con otra librería para la pantalla OLED, una de Alexey Dynda y, oh sorpresa, con esta sí que funciona.

El problema de esta librería es que solo muestra strings, y me obliga a convertir los valores numéricos, algo que en Arduino me parece un coñazo.
No entiendo nada.

¡¡¡ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA !!!!

Es que ese es un problema muy común en algunos dispositivos, no tienen forma de presentar números, busca como convertir números a string

https://www.arduino.cc/en/Reference.StringConstructor

No es el arduino, es la pantalla

TonyDiana:
Prueba esto y nos cuentas

// Objeto MP3

Serial.println("Estoy aquí");
#define RX 10         // Módulo MP3
Serial.println("Solo por necedad, veo que valgo " + String(RX) );
#define TX 11         // Módulo MP3
Serial.println("Solo por necedad, veo que valgo " + String(TX) );
SoftwareSerial DFPlayerSerial(RX, TX);
Serial.println("Dinos si llegas hasta aquí");

Probado, si dejo comentada la línea

//SoftwareSerial DFPlayerSerial(RX, TX);

funciona, pero si la descomento, me aparece el mensaje de que ha fallado la localización de SSD1306, no encuentra la pantalla.