Go Down

Topic: (Solucionado) Problemas enviando datos i2c si hay Display por medio  (Read 1 time) previous topic - next topic

mojisi

Hola a Todos,

estoy intentando enviar una cadena ("1234") de un arduino a otro mediante el protocolo I2C, pero cuando en el cliente utilizo pantalla OLED (0,96 inch i2c BUS OLED) no funciona.

Como Maestro tengo un Arduino Yun (pero aqui no esta el problema).

Como Cliente tengo un Arduino Due, al que esta conectada la pantalla y no me llega la cadena si utilizo ésta OLED.

Si comento lo referente a la esta pantalla OLED si que la cadena llega al cliente, apareciendo el mensaje en Monitor Serie ("1234").

Me podrías ayudar?, llevo varios días con esto y no se si habrá conflicto, o será otra cosa.


¿Se os ocurre que puede estar pasando?

Adjunto codigo maestro y esclavo.

mojisi

Puede ser que el cliente se bloquee  por medio de la pantalla OLED, y no deja recibir los datos del maestro?

tauro0221

Hi,
Chequeastes de que cada cual tenga diferentes addreses.

mojisi

yes,

pero no funciona. Estoy probando con otro código más reducido pero sigue fallando. Los codigo los cojo de los ejemplos de la librerias de Adafruit SSD1306 (ssd1306_128x32_i2c) y de Wire->master_writer y Wire->slave_receiver.

En arduino yun tengo cargado:

MAESTRO:
Code: [Select]

// Wire Master Writer
// by Nicholas Zambetti <http://www.zambetti.com>

// Demonstrates use of the Wire library
// Writes data to an I2C/TWI slave device
// Refer to the "Wire Slave Receiver" example for use with this

// Created 29 March 2006

// This example code is in the public domain.


#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop() {
  Wire.beginTransmission(11); // transmit to device #8
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}


-----------------------------------------------
En el esclavo (arduino Due) si cargo el ejemplo Wire->slave_receiver ponien Wire.begin(11) funciona correctamente.
El problema viene al intentar utilizar también el OLED Screen 1306.

mojisi

CLIENTE:

Code: [Select]
/*********************************************************************
This is an example for our Monochrome OLEDs based on SSD1306 drivers

  Pick one up today in the adafruit shop!
  ------> http://www.adafruit.com/category/63_98

This example is for a 128x32 size display using I2C to communicate
3 pins are required to interface (2 I2C and one reset)

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada  for Adafruit Industries. 
BSD license, check license.txt for more information
All text above, and the splash screen must be included in any redistribution
*********************************************************************/

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// (inicio) Si comento esto funciona
//--------------------------- inicio valore por defecto de la libreria ------------

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2


#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif
//--------------------------- fin valore por defecto de la libreria ------------
// (fin) Si comento esto funciona


void setup()   {   
   // join i2c bus with address #11
  Wire.begin(11);
 
  Wire.onReceive(receiveEvent); // register event

             
  Serial.begin(9600);
 

// (inicio2) Si comento esto funciona 
  // ------------------------------------ COMENTAR PARA QUE FUNCIONE DATOS DE LA PANTALLA OLED SSD1306 ------------------------
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done
 
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();



  testfillroundrect();
  delay(2000);
  display.clearDisplay();

  // Clear the buffer.
  display.clearDisplay();

  display.setTextSize(2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("BIENVENIDO");
  display.display();
  // <<<<< --------------------------------  COMENTAR HASTA AQUI Y FUNCIONA. DATOS DE LA PANTALLA OLED SSD1306 ------------------------
// (fin2) Si comento esto funciona

 
  Serial.println("Fin SETUP");
}


void loop() {
 
}


// (inicio3) Si comento esto funciona

void testfillroundrect(void) {
  uint8_t color = WHITE;
  for (int16_t i=0; i<display.height()/2-2; i+=2) {
    display.fillRoundRect(i, i, display.width()-2*i, display.height()-2*i, display.height()/4, color);
    if (color == WHITE) color = BLACK;
    else color = WHITE;
    display.display();
    delay(1);
  }
 
}
// (inicio3) Si comento esto funciona


// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}


----------------------------------------------
Si comento las 3 partes de inicio1, inicio2 e inicio3 funciona y llegan caracteres

Que estoy haciendo mal?

¿Como debería usar esta pantalla y a la vez recibir datos del maestro?

surbyte

Pregunto: usaste I2Cscanner para ver si display y esclavo lucen presentes para ese programa? Debería mostrar dos direcciones.

tauro0221

Hi,
Otra cosa le instalaste las resistencias de 10k a los pines de  SDA/SCL?  La sugerencia de SURBYTE es muy buena pues te dice los address de los deivices que estan conectados.

mojisi

A ver,

tengo colocado las resistencias de 10k ohms en SCL y en SDA.

En el i2c scanner  en Yun (maestro) me da sólo la dirección de la pantalla OLED, siempre que tenga en el cliente (DUE) todo el código de mi programa cliente. Si comento lo que ya dije (Si comento las 3 partes de inicio1, inicio2 e inicio3) me aparecen las dos dirección 1-la de la pantalla 0x03 y 2-la de arduino DUE.

Creo que el problema esta con la libreria de la pantalla OLED.
He tomado el ejemplo de la propia librería de Adafruit SSD1306 (ssd1306_128x32_i2c) y le he añadido al comienzo del setup:
Code: [Select]

// join i2c bus with address #11
  Wire.begin(9);  
  Wire.onReceive(receiveEvent); // register event


y luego le añado el método de la librería oficial de wire (slave_receiver):


Code: [Select]

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
  while(1 < Wire.available()) // loop through all but the last
  {
    char c = Wire.read(); // receive byte as a character
    Serial.print(c);         // print the character
  }
  int x = Wire.read();    // receive byte as an integer
  Serial.println(x);         // print the integer
}


-------------------------------------------------------------------

y nada no funciona. En la pantalla OLED aparece la animación pero no recibe ningún carácter del maestro (YUN). con el código:

Maestro (YUN):


Code: [Select]
#include <Wire.h>

void setup()
{
 Wire.begin(8); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
 Wire.beginTransmission(9); // transmit to device #4
 Wire.write("x is ");        // sends five bytes
 Wire.write(x);              // sends one byte  
 Wire.endTransmission();    // stop transmitting

 x++;
 delay(500);
}


Moderador: Agregado de etiquetas para presentación de código </>
------------------------------------------

Estoy atascado aquí. ¿Alguna idea?, ya no se que mas probar.

¿Que puede estar pasando?

tauro0221

Hi,
Pregunta tu ests usando el pin A4 = SDA y el pin A5=CLK?

mojisi

Gracias por vuestras respuestas.

Aunque seguimos igual, tauro0221 me indicas que diga el estado del pin A4 y A5, no se muy bien como hacer esto.

Además, yo trabajo con el Arduino DUE con pin 21 (SCL) y pin 20 (SDA).

Pero gracias a tu comentario  tauro0221, me empezado a probar mi codigo en otro arduino UNO que tengo, y aquí si que funciona la pantalla y la recepción de caracteres del arduino YUN (maestro), siempre que no ponga delay o llamada a otras funciones dentro del método receiveEvent, porque se queda bloqueado (no se porque).

El caso que con arduino UNO funciona pero con el DUE nada.


Se os ocurre que puede pasar?

problema de frecuencias en el DUE?

librería?

algo de luz, please!.

tauro0221

Hi,
Cuando usas el UNO que pines usas? Normalmenta  para los display se usan los pin A4 = SDA  y  A5 = CLK  para mandar la data al display y hasta ahora yo no he podido cambiarlos. Ellos estan asignados en  la libreria. No se porque no la hacen en el setup poder cambiar los pines.  Conecta el SDA al pin A4 y el clock al pin A5 de la tarjeta de YUN a ver que pasa.

mojisi

En el arduino UNO usé el pin A4 y A5.

He probado en el YUN en el pin A4 y A5 y nada no funciona. También he probado en el DUE en el A4 y A5 con igual resultado. :smiley-sad-blue:


tauro0221

Hi,
Yo probe un OLED que trabajaba pero se me cayo y se rompio el display y no lo volvi a usar pues creo que es my fragil. De todas manera yo usaba la siguente libreria en mi sketch.

Code: [Select]
/*This program use the libray using the pin 4 and pin 5 for the clock and data*/
#include "OLedI2C.h"
OLedI2C LCD;
#include <Arduino.h>
#include <Wire.h>  // Comes with Arduino IDE
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2); // Set the LCD I2C address


Puedes tratar a ver si te trabaja en tu projecto. Haz un google :"OLedI2C.h"  para que te diga donde la puedes bajar.




tauro0221

Hi,
Encontre uno de mis Oled display que es de 1/2 de ancho y 1 pulgada de largo y corri el programa  que esta en el Arduino/example/adafruit SSD1306/SSD1306 128.32.I2C  y lo corrio sin problema. Como ya tu estas usando el  ssd1306 driver  trata de correrlo en tu systema. Si el programa corre bien entonces el problema esta en  otro lado. El programa corre diferentes patrones de displays.

mojisi

tauro0221 este ejemplo que comentas ya lo he probado en mi arduino DUE (cliente)  y  funciona perfectamente, ya lo comenté.

El problema viene cuando a este ejemplo le añades un Wire.begin(9) y el método receiveEvent como comenté en el correo del día:

Mar 11, 2018, 04:15 pm

Creo que algún problema hay con las direcciones o la librería estoy desesperado ya.

Ćreo que el error hay que reproducirlo con un arduino DUE como cliente y estas librerías #include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
(32) sino no hay nada que ver. Pues con un arduino UNO ya dije que funciona.


A ver el/los moderador/es que opinan.


Go Up