Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

10/12/2014 #1


Conociendo al sensor de colores TCS3414
Buenas tardes,

El caso es que he adquirido el modulo sensor de colores de 16 bits TCS3414 ( Adjunto datasheet ). Está claro que me falta programar el sensor y es aquí donde necesitaría un poco de ayuda. Utilizo el compilador CCS 5.025. Iré posteando y actualizando lo que lleve programado, aunque estoy un poco verde.

No pido que me hagáis el programa, ya que lo haré yo, pero sí que pido asesoramiento. Ya he buscado si existía el driver en internet pero me ha sido imposible.

Entiendo que el modulo utiliza fotodiodos como filtros ( 4 filtros rojos, 4 filtros verdes, 4 filtros azules y 4 sin filtro, formando un array de 8x2 ). Esos filtros llevan incorporados los convertidores A/D para conseguir el color detectado.

Mediante el bus I2C se puede controlar la escritura/lectura del sensor. Ahora el caso es ir definiendo los registros que contiene el sensor que si no me equivoco están enumerados en la siguiente figura:



De esos registros, creo que con solo configurar los registros de command, control, timing,gain y los ADC channels me vale para hacer correr el sensor.

Ahora bien, la dirección del sensor de colores en modo esclavo indica que es:

Address = 0111001 = 0x39


Registro commando



Corregidme si me equivoco pero interpreto que después de ubicar la dirección del esclavo debo mandar lo siguiente:

Bit 7: Debe ser 1 obligatorio.
Bit 6-5: Protocolo de comunicación. Interpreto que para leer/escribir byte a byte o toda la palabra. Alguien me puede aclarecer la diferencia entre esos protocolos?
Bit 4-0: La dirección del registro en el que leer o escribir



registro de control

la dirección del registro es 0x00, donde los 8 bits se define:



De manera que deduzco que:
Activar modulo : 00000011 ( 0x03 )
Desactivar modulo: 00000000 ( 0x00 )

Registro timming



Para seleccionar el tiempo de conversión de los canales A/D
Creo que con el modo de 12ms de tiempo de conversión me es suficiente por lo que quedaría configurado de la siguiente manera:
Registro timming = 00000000

Registro gain
Para configurar la sensibilidad del sensor, aunque no sé qué consigo… mayor sensibilidad, más detecta el cambio de las diferentes gammas del rojo por ejemplo?



Registro ADC channels
Lectura de los conversores A/D


El codigo para configurar el sensor ( falta terminarlo )

Código:
#include<16F88.h>
#fuses NOMCLR
#fuses INTRC_IO
#fuses NOLVP
#fuses NOPROTECT
#fuses NOWDT
#use delay(internal=4000000)
#byte porta=0x05 
#byte portb=0x06 
#use i2c(Slave,Fast,sda=PIN_B1,scl=PIN_B4,address=0x39)

#define REGISTRO_CONTROL                  (0x00)             ////////////////////////////////////////////////////////////////////////
#define REGISTRO_TIMING                   (0x01)             //                                                                    //
#define REGISTRO_INTERRUPT                (0x02)             //                                                                    //
#define REGISTRO_INTSOURCE                (0x03)             //                                                                    //
#define REGISTRO_ID                       (0x04)             //                                                                    //
#define REGISTRO_GAIN                     (0x07)             //                                                                    //
#define REGISTRO_LOWTHRESHOLD_LOWBYTE     (0x08)             //                                                                    //
#define REGISTRO_LOWTHRESHOLD_HIGHBYTE    (0x09)             //                                                                    //
#define REGISTRO_HIGHTHRESHOLD_LOWBYTE    (0x0A)             //                                                                    //
#define REGISTRO_HIGHTHRESHOLD_HIGHBYTE   (0x0B)             //                Definición de los registros de la tabla 2           //
#define REGISTRO_GREENLOW                 (0x10)             //                  de la pagina 13 del datahseet.                    //  
#define REGISTRO_GREENHIGH                (0x11)             //                                                                    //  
#define REGISTRO_REDLOW                   (0x12)             //                                                                    //  
#define REGISTRO_REDHIGH                  (0x13)             //                                                                    //  
#define REGISTRO_BLUELOW                  (0x14)             //                                                                    //  
#define REGISTRO_BLUEHIGH                 (0x15)             //                                                                    //  
#define REGISTRO_CLEARLOW                 (0x16)             //                                                                    //  
#define REGISTRO_CLEARHIGH                (0x17)             //////////////////////////////////////////////////////////////////////// 

#define COMANDO_TIMMING                  (0x81)
#define COMANDO_CONTROL                  (0x80)
#define COMANDO_GAIN                     (0x87)
        



#define POWER_ON                        (0x03)             // Configuración registro control para activar el sensor
#define POWER_OFF                       (0x00)             // Configuración registro control para desactivar el sensor



void main()
{
disable_interrupts(GLOBAL);
set_tris_a(0x00); 
set_tris_b(0x00); 
porta=0; 
portb=0; 
setup_oscillator(OSC_4MHZ);
enable_interrupts(GLOBAL);
i2c_start();         //Inicializa
i2c_write(0x39);    // dirección del sensor
i2c_write(COMANDO_TIMMING);        // registro configuracion timming
i2c_write(0x00);        // registro configuracion timming a 12ms
i2c_stop();          //Finaliza
i2c_start();         //Inicializa
i2c_write(0x39);    // dirección del sensor
i2c_write(COMANDO_GAIN);        // registro configuracion gain
i2c_write(0x00);        // registro configuracion gain a 1X y divide by 1
i2c_stop();          //Finaliza
i2c_start();         //Inicializa
i2c_write(0x39);    // dirección del sensor
i2c_write(COMANDO_CONTROL);        // registro configuracion control
i2c_write(POWER_ON);        // Activación sensor
i2c_stop();          //Finaliza

while(1)
{
}

   
   

}
Visto así parece fácil, pero a la hora de trasladarlo al ccs se me hace un mundo... por eso pido asesoramiento.

Muchas gracias
11/12/2014 #2

Avatar de Ardogan

Fuentes84 dijo: Ver Mensaje
...
Registro commando
...
Corregidme si me equivoco pero interpreto que después de ubicar la dirección del esclavo debo mandar lo siguiente:

Bit 7: Debe ser 1 obligatorio.
Bit 6-5: Protocolo de comunicación. Interpreto que para leer/escribir byte a byte o toda la palabra. Alguien me puede aclarecer la diferencia entre esos protocolos?
Bit 4-0: La dirección del registro en el que leer o escribir
....
Cuando habla de escribir bytes/words/bloques se refiere al protocolo SMbus (SMB).
Vos estarías utilizando i2c así que siempre se escriben y se leen bytes.
Es decir, para i2c los bits 6:5 = 00

Fuentes84 dijo: Ver Mensaje
...
De manera que deduzco que:
Activar modulo : 00000011 ( 0x03 )
Desactivar modulo: 00000000 ( 0x00 )
Coincido (por ahora... )

Fuentes84 dijo: Ver Mensaje
...
Para seleccionar el tiempo de conversión de los canales A/D
Creo que con el modo de 12ms de tiempo de conversión me es suficiente por lo que quedaría configurado de la siguiente manera:
Registro timming = 00000000

Registro gain
Para configurar la sensibilidad del sensor, aunque no sé qué consigo… mayor sensibilidad, más detecta el cambio de las diferentes gammas del rojo por ejemplo?
Entonces por un lado está el tiempo de integración y por el otro tenemos ganancia y prescaler...

No veo que la hoja de datos lo aclare, pero si mal no entiendo el principio de funcionamiento del sensor es así:

señal analógica -> adaptación->conversor integrador -> registro de lectura
  • Señal analógica: corriente generada por el fotodiodo (un canal R, G, B, C)
  • Adaptación: convertidor de corriente a tensión de ganancia variable.
  • Conversor integrador: un convertidor de rampa (como los que usan los multímetros). La señal se integra durante un tiempo determinado (tiempo de integración) hasta alcanzar un nivel (simple rampa) o se carga con la tensión a medir y se descarga con una tensión conocida (doble rampa). El resultado de la conversión es el tiempo que lleva realizar esa operación.
  • Registro de lectura: al terminar la integración se escribe el resultado al registro de lectura.
Ojo!!! dije "principio de operación" puede implementarse distinto (por ejemplo, puede estar basado en un convertidor corriente a frecuencia y un contador) pero sirve para entender los parámetros de ajuste.

Entonces, en la hoja de datos cuando habla de "ganancia" (gain) está hablando de la ganancia de la etapa de adaptación.
¿Por qué quisiera aumentar esta ganancia?: porque hay poca luz y los valores registrados son bajos (<256 por decir algo).

Después está el tiempo de integración: mayor tiempo de integración implica que se puede detectar luz más débil, y filtrar ruido cuya frecuencia igual o múltiplo de 1/Tint. Por eso la opción de 100ms (10Hz) sirve para filtrar 50/60 Hz de la linea de alimentación (ya sea porque se mide luz de un foco, o por interferencia/ruido eléctrico).

Prescaler: el conversor integrador cuenta ciclos de reloj para obtener el resultado. Ese reloj se puede hacer más lento dividiendo por el prescaler, lo que termina dando más opciones para ajustar el tiempo de integración.

Que es lo que se busca evitar en la cadena de señal:
  1. Saturación analógica: que se sature la etapa de adaptación que puede amplificar (o no: x1) la señal antes de entrar al conversor integrador. También puede saturarse el conversor integrador al integrar la señal (la rampa se satura).
  2. Saturación digital: el conversor de rampa en realidad cuenta pulsos de reloj mientras dura el ciclo de integración. Si el tiempo de integración es largo la cuenta va a exceder 65535 (valor máximo para 16 bits = resolución sensor). En tal caso se puede bajar el tiempo de integración, o bajar la frecuencia del reloj (usar prescaler).
Fuentes84 dijo: Ver Mensaje
El codigo para configurar el sensor ( falta terminarlo )
Para el código podés encontrar librerías ya hechas, busca: tcs3414 library o tcs3414 library pic.

Para escribir tu código seguir la sugerencia de la hoja de datos para leer canales (página 23), y para configurar timing y ganancia (pag. 24). No le des importancia a lo que habla de integración en pag 24 y 25 en adelante porque eso es cuando queremos establecer el tiempo de integración en forma externa usando el pin sync. En tu caso estarías usando temporización interna.

Pero... primero lo primero. Seguro va a pasar que vas a meter un montón de código junto, lo grabás al PIC, y no funciona nada.
Es porque hay que ir de a poco, primero tenemos que ver que el bus i2c esta bien configurado.
Para eso tu primer objetivo tiene que ser leer un registro de contenido conocido, para verificar que en el pic configuramos todo bien, que no hay problemas de hardware, y que el bus i2c está bien inicializado.
Por eso te propongo que antes de entrar a trabajar en la librería intentes leer un registro, el ID por ejemplo que debería ser 0x1(REV).
Hecho eso ahí si pasamos a discutir el código de la librería.

Saludos.
11/12/2014 #3


Fenomenal tus recomendaciones Ardogan.

Como dices, primeramente empezare a hacer funcionar la comunicación I2C con el sensor para leer el registro de su identificacion (ID). Voy a utilizar un LCD 4x20 para visualizar los resultados. Cuando tenga el código y lo pruebe, te informo de los resultados.
El problema es que ahora debo comprar el PIC16LF88, ya que el sensor se recomienda alimentarlo entre 2.7 y 3.6V y el PIC16F88 necesita minimo 4V para que funcione correctamente, cosa que el PIC16LF88 solo necesita minimo 2V.
11/12/2014 #4

Avatar de Ardogan

Fuentes84 dijo: Ver Mensaje
El problema es que ahora debo comprar el PIC16LF88, ya que el sensor se recomienda alimentarlo entre 2.7 y 3.6V y el PIC16F88 necesita minimo 4V para que funcione correctamente, cosa que el PIC16LF88 solo necesita minimo 2V.
Cierto, eso eso eso . Aprovecha para comprar un regulador de 3.3V o 3.0V para alimentar a esos dos.
11/12/2014 #5


Ahora me corroe una duda. El modulo que compré es ese:



Lo compré en ebay y como no, no tengo datasheet de su esquemático, más que nada sé que:

3v3: los 3,3V para alimentar el TCS3414
LED: Lleva incorporado leds de apoyo, pero no se si se activan con un 1 o un 0
SYS: Sincronización TCS3414
INT: INterrupcion TCS3414
SDA: I2C
SCL: I2C
GND: está claro
VCC: Que valor? 5V?

Luego hay componentes como el PHU1, K36H... Esos componentes no se encargan de nivelar las tensiones entre 3,3V y la tension en VCC? He intentado encontrar el esquemático pero sin exito :(

HAré pruebas, lo unico que me da miedo romperlo
11/12/2014 #6

Avatar de Ardogan

Libro de códigos SMD
http://chip.tomsk.ru/chip/ChipDoc.ns...2501&count=500

PHU1: regulador de 3.3V TPS79333, 200 mA.
K36H: puede ser transistor mosfet dual para traducir niveles? (integrado del medio)

Y el transistor de arriba supongo será para convertir nivel de la pata SYS (que sería la sync del sensor de luz no?).

Pero sí, parece que esa placa tiene conversor de niveles y regulador como para que puedas usarla con una microcontrolador de 5V sin problemas (pic16F88 no problem). Probá sin miedo (siempre y cuando no conectes VCC y GND al reves....)
VCC = 5V
12/12/2014 #7


Editado ( leer ultima edición, más abajo )

Buenos dias,

He comprobado la comunicación I2C entre el PIC16F88 y el sensor sin éxito, cuando realizo la lectura del ID del sensor, siempre me da el valor de 0xFF cuando en realidad deberia dar 0x1(REV) donde REV es un numero de cuatro bits de identificación del sensor. Cuelgo el código:

Código:
#include<16F88.h>                   // libreria PIC16F88
#fuses NOMCLR                       // desactivar master clear
#fuses INTRC_IO                     // Utilización reloj interno, patillas OSC1 y OSC2 como entradas/salidas
#fuses NOLVP                        // Programación en baja tensión desactivada
#fuses NOPROTECT                    // Sin protección del codigo
#fuses NOWDT                        // Desactivado el watch dog 
#use delay(internal=4000000)        // utilización reloj interno 4Mhz
#byte porta=0x05                    // identificación byte porta
#byte portb=0x06                    // identificación byte portb
#use i2c(master,sda=PIN_B1,scl=PIN_B4)  // configuración comunicación I2C en modo master, rápido, sda en PIN B1 y scl en PIN B4
#include<lcd_420.c>

#define LED PIN_B3

#define DIRECCION                         0x39              //Dirección esclavo

#define REGISTRO_CONTROL                  0x00              ////////////////////////////////////////////////////////////////////////
#define REGISTRO_TIMING                   0x01             //                                                                    //
#define REGISTRO_INTERRUPT                0x02             //                                                                    //
#define REGISTRO_INTSOURCE                0x03             //                                                                    //
#define REGISTRO_ID                       0x04             //                                                                    //
#define REGISTRO_GAIN                     0x07             //                                                                    //
#define REGISTRO_LOWTHRESHOLD_LOWBYTE     0x08             //                                                                    //
#define REGISTRO_LOWTHRESHOLD_HIGHBYTE    0x09             //                                                                    //
#define REGISTRO_HIGHTHRESHOLD_LOWBYTE    0x0A             //                                                                    //
#define REGISTRO_HIGHTHRESHOLD_HIGHBYTE   0x0B             //                Definición de los registros de la tabla 2           //
#define REGISTRO_GREENLOW                 0x10             //                  de la pagina 13 del datahseet.                    //  
#define REGISTRO_GREENHIGH                0x11             //                                                                    //  
#define REGISTRO_REDLOW                   0x12             //                                                                    //  
#define REGISTRO_REDHIGH                  0x13             //                                                                    //  
#define REGISTRO_BLUELOW                  0x14             //                                                                    //  
#define REGISTRO_BLUEHIGH                 0x15             //                                                                    //  
#define REGISTRO_CLEARLOW                 0x16             //                                                                    //  
#define REGISTRO_CLEARHIGH                0x17             //////////////////////////////////////////////////////////////////////// 

#define COMANDO_CONTROL                  0x80               // Dirección para leer/escribir en registro control
#define COMANDO_TIMMING                  0x81               // Dirección para leer/escribir en registro timming
#define COMANDO_INTERRUPT_CONTROL        0x82               // Dirección para leer/escribir en registro control interrupción
#define COMANDO_ID                       0x84               // Dirección para leer/escribir en registro identificación ( solo permite lectura )
#define COMANDO_GAIN                     0x87               // Dirección para leer/escribir en registro gain
        


#define POWER_ON                            0x01             // Registro control: Solo Activo el sensor ( los conversores ADC no )
#define POWER_ON_ALL                        0x03             // Registro control: Activo el sensor y los conversores ADC
#define POWER_OFF                           0x00             // Registro control: Desactivo el sensor

int cnt;
int id;

#INT_EXT
void interrupcion()
{
   cnt++;
}

void main()
{
disable_interrupts(GLOBAL);   // desactivación interrupciones
set_tris_a(0x00);             // configuracion I/O puerto A
set_tris_b(0x01);             // configuracion I/O puerto B
porta=0x00;                      // Puerto A nivel bajo
portb=0x08;                      //  Puerto B a nivel bajo menos salida LED que se activa a nivel bajo.
setup_oscillator(OSC_4MHZ);      // configuracion reloj interno a 4MHz
enable_interrupts(INT_EXT);      // habilitación interrupcion RB0 mediante pulsador
ext_int_edge(l_to_h);            // interrupción RB0 por flanco de subida
enable_interrupts(GLOBAL);       // activación interrupciones
lcd_init();             // inicializa el LCD 4x20
output_high(LED);       // a nivel alto, led desactivado
cnt=0;
id=0;
printf(lcd_putc, "\f        ID:0x%x   ",id);



while(1)
{
  if(cnt==1)
  {
  
   // escritura para activar el sensor
   i2c_start();         //Inicializa
   i2c_write(DIRECCION);    // dirección del sensor
   i2c_write(COMANDO_CONTROL);        // Dirección comando para configurar el registro control
   i2c_write(POWER_ON);        // Encender el sensor, pero sin activar los conversores A/D
   i2c_stop();          //Finaliza
   delay_ms(10);        // Retardo 10ms
   
   // lectura para leer el ID del sensor, deberia dar 0x1Y   donde Y es el REVNO
   i2c_start();         //Inicializa
   i2c_write(DIRECCION);    // dirección del sensor
   i2c_write(COMANDO_ID);        // Dirección comando para leer el registro ID
   i2c_start();         // Reinicializa para lectura
   i2c_write(DIRECCION+1);    // dirección del sensor +1 para leer
   id=i2c_read(0);
   i2c_stop();          //Finaliza
   delay_ms(10);        // Retardo 10ms
   printf(lcd_putc, "\f        ID:0x%x   ",id); // visualizacion valor ID
   cnt=0; 
  }
} 
}


Ultima Edicion:

Ya he encontrado el problema, el problema es que:

Direccion Esclavo = 0111001 = 0x39 ( error mio )

cuando lo correcto es:

Dirección Esclavo + 0 ( escritura ) = 01110010 = 0x72
Dirección Esclavo + 1 (lectura) = 01110011 = 0x73

Codigo rectificado:

Código:
#include<16F88.h>                   // libreria PIC16F88
#fuses NOMCLR                       // desactivar master clear
#fuses INTRC_IO                     // Utilización reloj interno, patillas OSC1 y OSC2 como entradas/salidas
#fuses NOLVP                        // Programación en baja tensión desactivada
#fuses NOPROTECT                    // Sin protección del codigo
#fuses NOWDT                        // Desactivado el watch dog 
#use delay(internal=4000000)        // utilización reloj interno 4Mhz
#byte porta=0x05                    // identificación byte porta
#byte portb=0x06                    // identificación byte portb
#use i2c(master,sda=PIN_B1,scl=PIN_B4)  // configuración comunicación I2C en modo master, rápido, sda en PIN B1 y scl en PIN B4
#include<lcd_420.c>

#define LED PIN_B3


#define REGISTRO_CONTROL                  0x00              ////////////////////////////////////////////////////////////////////////
#define REGISTRO_TIMING                   0x01             //                                                                    //
#define REGISTRO_INTERRUPT                0x02             //                                                                    //
#define REGISTRO_INTSOURCE                0x03             //                                                                    //
#define REGISTRO_ID                       0x04             //                                                                    //
#define REGISTRO_GAIN                     0x07             //                                                                    //
#define REGISTRO_LOWTHRESHOLD_LOWBYTE     0x08             //                                                                    //
#define REGISTRO_LOWTHRESHOLD_HIGHBYTE    0x09             //                                                                    //
#define REGISTRO_HIGHTHRESHOLD_LOWBYTE    0x0A             //                                                                    //
#define REGISTRO_HIGHTHRESHOLD_HIGHBYTE   0x0B             //                Definición de los registros de la tabla 2           //
#define REGISTRO_GREENLOW                 0x10             //                  de la pagina 13 del datahseet.                    //  
#define REGISTRO_GREENHIGH                0x11             //                                                                    //  
#define REGISTRO_REDLOW                   0x12             //                                                                    //  
#define REGISTRO_REDHIGH                  0x13             //                                                                    //  
#define REGISTRO_BLUELOW                  0x14             //                                                                    //  
#define REGISTRO_BLUEHIGH                 0x15             //                                                                    //  
#define REGISTRO_CLEARLOW                 0x16             //                                                                    //  
#define REGISTRO_CLEARHIGH                0x17             //////////////////////////////////////////////////////////////////////// 

#define COMANDO_CONTROL                  0x80               // Dirección para leer/escribir en registro control
#define COMANDO_TIMMING                  0x81               // Dirección para leer/escribir en registro timming
#define COMANDO_INTERRUPT_CONTROL        0x82               // Dirección para leer/escribir en registro control interrupción
#define COMANDO_ID                       0x84               // Dirección para leer/escribir en registro identificación ( solo permite lectura )
#define COMANDO_GAIN                     0x87               // Dirección para leer/escribir en registro gain
        


#define POWER_ON                            0x01             // Registro control: Solo Activo el sensor ( los conversores ADC no )
#define POWER_ON_ALL                        0x03             // Registro control: Activo el sensor y los conversores ADC
#define POWER_OFF                           0x00             // Registro control: Desactivo el sensor

int cnt;
int id;

#INT_EXT
void interrupcion()
{
   cnt++;
}

void main()
{
disable_interrupts(GLOBAL);   // desactivación interrupciones
set_tris_a(0x00);             // configuracion I/O puerto A
set_tris_b(0x01);             // configuracion I/O puerto B
porta=0x00;                      // Puerto A nivel bajo
portb=0x08;                      //  Puerto B a nivel bajo menos salida LED que se activa a nivel bajo.
setup_oscillator(OSC_4MHZ);      // configuracion reloj interno a 4MHz
enable_interrupts(INT_EXT);      // habilitación interrupcion RB0 mediante pulsador
ext_int_edge(l_to_h);            // interrupción RB0 por flanco de subida
enable_interrupts(GLOBAL);       // activación interrupciones
lcd_init();             // inicializa el LCD 4x20
output_high(LED);       // a nivel alto, led desactivado
cnt=0;
id=0;
printf(lcd_putc, "\f        ID:0x%x   ",id);



while(1)
{
  if(cnt==1)
  {
  
   // escritura para activar el sensor
   i2c_start();         //Inicializa
   i2c_write(0x72);    // dirección del sensor
   i2c_write(COMANDO_CONTROL);        // Dirección comando para configurar el registro control
   i2c_write(POWER_ON);        // Encender el sensor, pero sin activar los conversores A/D
   i2c_stop();          //Finaliza
   delay_ms(10);        // Retardo 10ms
   
   // lectura para leer el ID del sensor, deberia dar 0x1Y   donde Y es el REVNO
   i2c_start();         //Inicializa
   i2c_write(0x72);    // dirección del sensor
   i2c_write(COMANDO_ID);        // Dirección comando para leer el registro ID
   i2c_start();         // Reinicializa para lectura
   i2c_write(0x73);    // dirección del sensor +1 para leer
   id=i2c_read(0);
   i2c_stop();          //Finaliza
   delay_ms(10);        // Retardo 10ms
   printf(lcd_putc, "\f        ID:0x%x   ",id); // visualizacion valor ID
   cnt=0; 
  }
} 
}
y la respuesta es correcta ya que da 0x10 ( lo que nos esperábamos )

Ahora voy a proceder a jugar con el sensor y a ver que lecturas me da de los filtros rojos, verdes, azules y los sin filtros.

Ardogan, vas a ser mi compañero en este proyecto
12/12/2014 #8

Avatar de Ardogan

Fuentes84 dijo: Ver Mensaje
...
y la respuesta es correcta ya que da 0x10 ( lo que nos esperábamos )

Ahora voy a proceder a jugar con el sensor y a ver que lecturas me da de los filtros rojos, verdes, azules y los sin filtros.

Ardogan, vas a ser mi compañero en este proyecto
Quizás ni haga falta... ya vas bien encaminado .

Empiezo a renegar <rant>
Un caso típico que se da en el foro: llega alguien con un programa de cientos de líneas, sin esquemático, y dice "no me funciona". Después se le pide el esquemático... después como se dió el problema y la respuesta muchas veces es "en el proteus me anda y cuando lo paso al micro ni siquiera ejecuta código" (porque ni siquiera logra encender 1 led).

Y ese es el problema... cuando se trabaja programando drivers (por drivers me refiero a cualquier cosa que maneje periféricos del micro: puertos de entrada/salida, buses i2c/spi/uart, entradas/salidas analógicas: comparador, adc, dac; timers, etc, etc) la forma de hacerlo es escribir una función elemental, programarla en el micro, y ver si funciona bien (midiendo con osciloscopio, multímetro, o con un led para ver si al poner un 1 en un pin realmente sale un 1).

La simulación puede ayudar a ver si un programa es coherente, pero no puede modelar todo lo que pasa en el mundo físico. Es la diferencia entre hacer software para PC y para un micro. En la PC el ambiente es un mundo digital donde las cosas que pueden pasar son limitadas por el sistema operativo. Con un micro el mundo con el que se trabaja es el real, donde pueden pasar cosas imprevistas y la única salvaguarda es nuestro propio programa.

Y esa es una mentalidad que a muchos nos impusieron en la facultad y después cuesta mucho sacársela de encima: no hay que resolver todo en papel antes de ir a la práctica. Hay que resolver una parte chiquita chiquita, VERIFICARLA, y luego seguir con otra partecita, verificarla... y cuando quiera unir todo ya se que el problema no es de las partecitas sino de la integración.
Es que bueno... en mi época la mentalidad impartida siempre fue analizar cosas, nunca implementarlas.
Fin reniego</rant>

Yendo a tu caso... fijate que bien lo pudiste resolver yendo de a poco (y no sugerí 1 sola línea de código ).
Mirá todas las cosas que ya sabés que funcionan:
  1. Los fuses bien configurados
  2. El micro está bien alimentado y tiene señal de reloj: esto es como ver si hay aire para que el micro respire.
  3. La conexión entre el micro y la placa del sensor funciona.
  4. El bus i2c está bien configurado: no hay problemas de pull-ups, y los pines de las líneas de reloj y datos están bien configurados.
  5. El programador funciona y graba bien el programa.
  6. El compilador no hizo cosas raras, genero bien el binario.
  7. Hasta verificaste que el LCD funciona: ya tenés capacidad de depurar el programa sin recurrir a la PC. Aunque claro, si sale un problema duro entonces no hay mejor herramienta que el depurador.
  8. Te diste el lujo de incorporar una interrupción y todo . Es un botón para que al apretarlo haga la lectura del ID ¿cierto?
A partir de este punto estás en una buena posición para sacarle el jugo al sensor, porque ya verificaste que todo eso está funcionando. Si de ahora en más hay un error no hace falta preocuparse de la lista de arriba.

Así que si, con todo gusto cualquier problema/duda/comentario estamos por acá.
12/12/2014 #9


Buenas Ardogan,

Menuda re-negación jeje, pero tienes toda la razón. Difiere mucho del mundo digital del proteus de la realidad, yo siempre hago los circuitos físicamente en la protoboard, aunque se queme algún integrado por haber hecho un mal uso, aun así es donde más se aprende.
Otro problema del foro es que algunos, no digo la mayoría, quieren la solución hecha por otra persona y para YA, por este motivo había recalcado en el primer post que no os pedía que hicierais el programa, que lo haría haciendo yo mismo con vuestro asesoramiento.

Has interpretado bien el programa jeje, por medio de un botón se activa una interrupción y realiza la lectura de la ID del sensor, donde el resultado se visualiza en un LCD 4x20 y fenomenal. Ahora a disfrutar del fin de semana, siempre que tenga tiempo voy a avanzar en el sensor. Iré posteando los avances y el resultado final y cualquier duda que tenga y no vea salida recurro a vosotros!

Muy agradecido.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.