[SOLUCIONADO] I2C para display de 7 seg. y PCF8574

"Mas o menos se representar" dos o más displays de 7 segmentos con los 74HC595...gracias a los esfuerzos y explicaciones de miembros de este foro. Ahora quisiera aprender como representar 2 ó 4 ....etc.... dígitos de 7 seg. con los PCF8574. He mirado en la red y no se encontrar algún ejemplo que me indique de como hacer la estructura del programa ( Si hay para circuitos de 4 digitos y más pero me interesaría la aplicación para los PCF8574). Agradeceria de su ayuda ó consejos.
Salu2

Si lo tuyo son los led display y no querés/podés emplear la ténica de barrido, en vez de inventar la rueda tallarla/construirla, te conviene ir por estos ( MAX6950/MAX6951 - MAX7219/MAX7221 ) que son SPI y su finalidad es hacer transparente el manejo de los led display 7 segmento, podés manejar hasta 8 dígitos con ellos.

es muy sencillo, solo tienes que enviar la dirección del display en el que quieres escribir + 0 (orden escribir) luego envías el dato, si sigues enviando mas datos se van actualizando las salidas

Esto traducido a arduino es:

void setup()
{
  Wire.begin();
}

void loop()
{
Wire.beginTransmission(0b0100XXX0); 
  Wire.write(0b01111111); //para escribir un 8, para el resto de números dependerá del conexionado que hagas     
  Wire.endTransmission();
}

Siendo XXX diferente para cada display en función de como conectes a GDN o VCC las patas A2,A1,A0

Alex gracias ...pero en esta ocasión requiero los PCF8574....se que es "algo más fácil" con esta serie ( MAX6950/MAX6951 - MAX7219/MAX7221 ).
Salu2

GO_zalo...gracias.....este fin de semana me pongo con ello.....si tengo dudas lo comento..

Salu2

Si tengo que mandar a los PCF8574 una variable por ejemplo de un higrómetro de dos dígitos ó tres....como seria la aplicación.....en esta sección de código..que es para los 74HC595 :

void display(float Number){
 int iNum = (int)(Number*10); // con esto aseguro 1 digito decimal
 int decimal = iNum %10;   // digito decimal
 iNum /= 10;
 int unidad  = iNum % 10;
 iNum /= 10;
 int decena  = iNum % 10;
 displayNumb(decimal, unidad, decena);
}
void displayNumb(int a, int b, int c) {
  // saca el codigo de numeros
  byte bitsA = numberSet[a];
  byte bitsB = numberSet[b];
  byte bitsC = numberSet[c];
  // set listo para cambiar
  digitalWrite(latchPin, LOW);
  // decimal
  shiftOut(dataPin, clockPin, bitsA);
  // unidad
  shiftOut(dataPin, clockPin, bitsB);
  // decena
  shiftOut(dataPin, clockPin, bitsC);
  // shift salida datos
  digitalWrite(latchPin, HIGH);
}

void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
int i=0;
int pinState;
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
for (i=7; i>=0; i--)  {
digitalWrite(myClockPin, 0);
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else 
{	
pinState= 0;
}
digitalWrite(myDataPin, pinState);  
digitalWrite(myClockPin, 1);
digitalWrite(myDataPin, 0);
}
igitalWrite(myClockPin, 0);
}

Viendo como es.....me es más fácil estudiar y aplicarlo en otras ocasiones que requiera.

Salu2

Bueno estos son mis primeros pasos...pero no entiendo como poner las variables del ejemplo anterior....
(me pierdo)....ni que faltaría aplicar....espero consejos....

void setup()
{
  Wire.begin();
}

void loop()
{
Wire.beginTransmission(0b01000000); // Digito 0
  Wire.write(0b01111111);           //para escribir un 8  
  Wire.endTransmission();
}
 {
Wire.beginTransmission(0b01000010); // Digito 1
  Wire.write(0b01111101);           //para escribir un 6   
  Wire.endTransmission();
}
 {
Wire.beginTransmission(0b01000100); // Digito 2
  Wire.write(0b01101101);           //para escribir un 5    
  Wire.endTransmission();
}

Adjundo esquema con Proteus 8

Salu2

PCF8574A.zip (13.8 KB)

Si lo que me muestas ha funcionado yo probaria ya con

#include <Wire.h>

byte numberSet[10]={0b00111111,0b01011111/*Aqui todas las definiciones de segmentos-> a numeros*/};

void setup()

{
	Wire.begin();
}

void loop()
{}


void display(float Number){
 int iNum = (int)(Number*10); // con esto aseguro 1 digito decimal
 int decimal = iNum %10;   // digito decimal
 iNum /= 10;
 int unidad  = iNum % 10;
 iNum /= 10;
 int decena  = iNum % 10;
 displayNumb(decimal, unidad, decena);
}
void displayNumb(int a, int b, int c) {
  // saca el codigo de numeros
  byte bitsA = numberSet[a];
  byte bitsB = numberSet[b];
  byte bitsC = numberSet[c];
  
  Wire.beginTransmission(0b01000000); // Digito 0
  Wire.write(bitsA);           
  Wire.endTransmission();
  
  Wire.beginTransmission(0b01000010); // Digito 1
  Wire.write(bitsB);           
  Wire.endTransmission();
  
  Wire.beginTransmission(0b01000100); // Digito 2
  Wire.write(bitsC);  
  Wire.endTransmission();  
  
}

Gracias lo pruebo en un par de días......y comento resultado.
Salu2

Cambie el slave address PCF8574A creo que el que pisiste es el PCF8574. las lineas de SCL y SDA parece que funcionan ( en osciloscopio de proteus) pero los displays en simulación no encienden...no se que puede estar mal....adjunto simulación e ide :

#include <Wire.h>
#include <DHT.h>
#define DHTTYPE DHT22     // DHT 22 (AM2302)
float h,t;
DHT dht(7, DHTTYPE);      //Pin entrada del DHT22 
// caracteres display 7 seg. del 0-9
byte numberSet[10]= { 
  0b00111111, 0b00000110, 0b01011011, 0b01001111,  // 0,1,2,3
  0b01100110, 0b01101101, 0b01111101, 0b00000111,  // 4,5,6,7
  0b01111111, 0b01101111                           // 8,9
};

void setup()
{
 // inicializa serial
  Serial.begin(9600);
  // inicializa sensor de humedad
  dht.begin();	
  Wire.begin();
}
void loop()
{
 h = dht.readHumidity(); // leer el valor de la humedad
  // Compruebe si alguna de las lecturas es fallida y salir si es fallida (e intentarlo de nuevo)
  if (isnan(h)) {
  Serial.println("Failed to read from DHT sensor!");
  return;
 }
 Serial.print("Hum = ");
 Serial.print(h);
 display(h);
 delay(2000);
}

 void display(float Number){
 int iNum = (int)(Number*10); // con esto aseguro 1 digito decimal
 int decimal = iNum %10;   // digito decimal
 iNum /= 10;
 int unidad  = iNum % 10;
 iNum /= 10;
 int decena  = iNum % 10;
 displayNumb(decimal, unidad, decena);
}
void displayNumb(int a, int b, int c) {
  // saca el codigo de numeros
  byte bitsA = numberSet[a];
  byte bitsB = numberSet[b];
  byte bitsC = numberSet[c];
  
  Wire.beginTransmission(0b01110000); // Digito 0 como slave address PCF8574A
  Wire.write(bitsA);           
  Wire.endTransmission();
  
  Wire.beginTransmission(0b01110010); // Digito 1 como slave address PCF8574A
  Wire.write(bitsB);           
  Wire.endTransmission();
  
  Wire.beginTransmission(0b01110100); // Digito 2 como slave address PCF8574A
  Wire.write(bitsC);  
  Wire.endTransmission();  
  
}

Salu2....y en espera de consejos.....

PCF8574A.zip (18.4 KB)

prueba primero el código del PCF8574 y dime si ha funcionado

En vez de usar un osciloscopio en proteus existe una erramienta de depuración I2c en la que puedes ver los mensajes intercambiados

Te vas a reir francisco2v pero que librería DHT estas usando?

Ya la encontré.

Bueno Francisco2v, te resolví los errores. Detallo a continuacióni

  1. Las direcciones estaban mal.
    0b01110000 si lees bien es 0x70 y debe ser 0x38 o sea
    0b0111000 agregaste un 0 de mas

  2. Los displays deben ser de Cátodo común tal como estan definidos los segmentos.

Adjunto la solucion Proteus y programa

PCF8574A.zip (18.4 KB)

PCF8574A.zip (18.9 KB)

CO-zalo...gracias....sigo con ello.
Surbyte, ...gracias....el archivo que adjuntaste no es el que rectificaste..es el mismo que adjunte yo...je...je....
Salu2....sigo y comento resultados.....

1.-GO_zalo...poniendo display ánodo común y address para PCF8574...no logro que simule.(Como lo editaste).

2.-Según las indicaciones de surbyte si funciona perfecto. Pero no entiendo porque se suprime el bit Read/Write....?

0b01110000 con el bit de Read/Write y no me funciona bien. (PCF8574A).
0b0111000 sin el bit de Read/Write funciona bien como indica Surbyte (PCF8574A).

Agradecería su explicación...

Salu2

Funciona perfecto cambiando el Display, no lo olvides.

francisco2v:
Surbyte, ...gracias....el archivo que adjuntaste no es el que rectificaste..es el mismo que adjunte yo...je...je....
Salu2....sigo y comento resultados.....

No. No lo es. Mira mi ultimo adjunto. Esta perfecto, tiene el I2C debugger, tiene displays 7 segmentos catodo común y funciona correctamente leo la humedad sin problemas.

Va de nuevo con el sketch.

PCF8574A.zip (18.9 KB)

Surbyte...siento contradecirte..pero el archivo de proteus no tiene lo que comentas. El ino si esta en este ultimo.
Me gustaría ver tu ordenador echando humo con tanta metralla que imagino tiene. OH......quizás sea yo........si lo descargas podrás apreciar lo que comento.
Me puedes ilustrar a mi "paupérrimo nivel".....sobre el I2C debugger......Gracias.
Como I2c es por dos hilos quizás seria interesante poner lo de esta pagina...agradecería opinión:
http://www.ebay.es/itm/Arduino-2-4GHZ-NRF24L01-Module-with-wireless-Shield-SPI-to-IIC-I2C-TWI-Interface-/221634533463?hash=item339a729857
Una unidad a salida I2C de arduino y otra unidad a la entrada I2C de los PCF8574A....con los displays....para separarlos.
Salu2

Bueno no se que error cometí pero tenías razón francisco.
He corregido todos los archivos subidos para que no se generen problemas.
Ahora comprueba a ver.

Muchas gracias GO_zalo y como no Surbyte por vuestra inapreciable ayuda, funciona a la perfección.
Doy por cerrado este post.
Salu2

Buenas, disculpen por revivir este hilo pero, 2 dudas: como conexionan el display(a,b,c,d,e,f,g) con las salidas del pcf8574a?, es decir en que orden?
segunda, estoy intentando imprimir una variable en el display y no lo logro(a veces aparece una forma rara sin sentido o todo el display apagado)

el codigo que estoy usando:

#include <Wire.h>

void setup()
{
// inicializa serial
Serial.begin(9600);
Wire.begin();
}
void loop() {
int a=1;
Wire.beginTransmission(0x3F); // las 3 adress en "1"
Wire.write(a);
Wire.endTransmission();

}

gracias de antemano

Hola compi. Por favor, lee las normas. Entre otras cosas, no se puede revivir un tema tan antiguo y lee como poner el código. Y empieza un post de nuevo y bien hecho. Puedes, en el nuevo post, añadir un enlace (bien hecho) a este.