Mostrando entradas con la etiqueta I2C. Mostrar todas las entradas
Mostrando entradas con la etiqueta I2C. Mostrar todas las entradas

Chip calendario (DS1307) + PICAXE



Este post lo dedico a la programación y configuración de la hora para el Circuito Integrado DS1307.

DS1307

Es un IC de reloj en tiempo real, el que funciona con una pequeña circuitería y una batería CS2032 de 3V. Funciona con comunicación I2C, provee de: segundos, minutos, horas, día, fecha, mes y año. Está programado automáticamente para meses inferiores a 31 días y años bisiestos. El reloj puede funcionar en formado de 12 o 24 horas con indicador de AM y PM.

La circuitería es:



Los pines son:



  • X1 y X2: Pines de conexión para un cristal estándar de 32.768kHz. El circuito oscilador interno está diseñado para trabajar a una carga capacitivo de 12.5pF. X1 es la entrada al oscilador y puede ser conectado opcionalmente con un oscilador externo, la salida del oscilador interno es X2.
  • VBAT: fuente de alimentación de respaldo, puede ser una batería de litio de 3V.
  • Ground: Tierra
  • SDA (Serial Data Input/Output): SDA  es la entrada de información por el protocolo I2c, este pin es colector abierto así que debe colocarse una Resistencia pull-up a VCC.
  • SCL (Serial Clock Input): Es la entrada del protocolo I2C del pulso de reloj para sincronizar los datos.
  • SQW/OUT (Square Wave/Output Driver): Cuando está en 1 lógico, la SQW/OUT saca una de las ondas cuadradas (1Hz, 4kHz, 8kHz, 32kHz). Este pin es colector abierto así que debe colocarse una Resistencia pull-up a VCC
  • VCC: 5V


Código para ver y programar la hora con PICAXE:

Los pines de comunicación al DS1307 con el PICAXE, son los pines dedicados para I2C, SDA y SCL.

 symbol segundos = b0
symbol minutos = b1
symbol horas = b2
symbol dia = b3
symbol fecha = b4
symbol mes = b5
symbol ano = b6
symbol control = b7

i2cslave %11010000, i2cslow, i2cbyte 'configura para la dirección del chip calendario
output b.2
input c.0,b.0,b.1,b.2 'pulsadores para configurar segundos, minutos, horas y activar el modo de moficación de hora

main:
    if pinc.0 = 0 then 'switch para grabar la hora
        pause 300
        readi2c 0,(segundos,minutos,horas,dia,fecha,mes,ano) 'lee la hora del reloj
        if pinc.0 = 1 then
        do 'ciclo para escoger los segundos, minutos y la hora
            if pinb.0 = 0 then
                pause 200
                segundos = segundos + $01
                if segundos > $09 and segundos < $11 then
                    segundos = $10
                endif
                if segundos > $19 and segundos < $21 then
                    segundos = $20
                endif
                if segundos > $29 and segundos < $31 then
                    segundos = $30
                endif
                if segundos > $39 and segundos < $41 then
                    segundos = $40
                endif
                if segundos > $49 and segundos < $51 then
                    segundos = $50
                endif
                if segundos > $59 then
                    segundos = $00
                endif
            endif
            if pinb.1 = 0 then
                pause 200
                minutos = minutos + $01
                if minutos > $09 and minutos < $11 then
                    minutos = $10
                endif
                if minutos > $19 and minutos < $21 then
                    minutos = $20
                endif
                if minutos > $29 and minutos < $31 then
                    minutos = $30
                endif
                if minutos > $39 and minutos < $41 then
                    minutos = $40
                endif
                if minutos > $49 and minutos < $51 then
                    minutos = $50
                endif
                if minutos > $59 then
                    minutos = $00
                endif
            endif
            if pinb.2 = 0 then
                pause 200
                horas = horas + $01
                if horas > $09 and horas < $11 then
                    horas = $10
                endif
                if horas > $19 and horas < $21 then
                    horas = $20
                endif
                if horas > $23 then
                    horas = $00
                endif
            endif
            sertxd(#horas,":",#minutos,":",#segundos,13,10)
            if pinc.0 = 0 then
                pause 200
                writei2c 0,(segundos,minutos,horas,dia,fecha,mes,ano,control)'graba la hora en el chip calendario
                goto main
            endif
        loop
        endif
    endif
    readi2c 0,(segundos,minutos,horas,dia,fecha,mes,ano) 'lee la hora del reloj
    sertxd(#horas,":",#minutos,":",#segundos,13,10) 'despliega la hora en la terminal
goto main

Usando el protocolo I2C en comunicación con varios picaxe

Este documento originalmente lo publiqué en el foro ucontrol el 30 de enero de 2011, ahora lo posteo aca en mi blog.

El protocolo I2c (Inter-Integrated Cirtuit) fue desarrollado por Phillips, y es una interfaz que consiste en un bus de 2 líneas (reloj (scl), data (sda)), la versatilidad de este protocolo es que se pueden aplicar unas 128 asignaciones (osea podríamos agregar 128 dispositivos a esas 2 líneas de transmisión). Se diseño este protocolo con la finalida de comunicar varios integrados en una placa de circuito impreso.

La mayoría de dispositivos I2C se diseñan de 8 pines por lo que hace que sea muy factible en un diseño de circuito impreso. Hay 4 datos de configuración que debemos tener claro:

  • Dirección de esclavo: cada dispositivo debe tener una dirección distinta, es de una longitud de 7 bits y un octavo que es reservado para indicar si es escritura o lectura
  • Velocidad de bus: La mínima es de 100khz y la máxima de 400khz y algunos dispositivos solo trabajan a 100 Khz
  • Tamaño de dirección de registo: todos los datos enviados del maestro al esclavo son ESCRITURA, los de esclavo a maestro son LECTURA. Cuando el maestro o el esclavo tranmite ellos hacen las líneas del bus 0.
  • Buffer de escritura de página: Las memorias eeprom tienen un tiempo de escritura de 5 a 10ms, para evitar un retraso de escritura poseen un buffer que puede aceptar más de un bit al mismo tiempo, asi que si recibe 90 bytes no se tardaria 90ms sino que reduciría aproximadamente a 10ms de escritura
 
Así que con esta información podemos empezar la comunicación y unas pequeñas practicas de I2C: estas prácticas fueron realizadas con 2 20X2, conectando sus pines sda y slc y agregandole 2 resistencias de 4.7k como pull up. El pic o el dispositivo i2c que sera conectado debe poseer una dirección ej: %10100000, algunos dispositivos deben ser revisada en su hoja de datos la dirección recomendada para i2c, los desarrolladores de picaxe nos recomienda que si no sabemos que dirección colocar podemos usar %10100000, asi que empezamos:

comando hi2csetup:

      hi2csetup i2cmaster, direcciondelesclavo, modo, largodedirrección

En modo pueden escoger la velocidad máxima o mínima (i2cslow 100khz o i2cfast 400khz), deben ver la hoja de datos del dispositivo para ver a que velocidad pueden trabajar.

Largo de dirección: depende del dispositivos que usemos, si utiliza 8 bits (byte) o 16 (word), por ejemplo las eeprom 24lCxxB se debe usar un i2cbyte pero para eepro mayores se utiliza i2cword.

ej:
     hi2csetup i2cmaster, %10100000, icsolw, i2cbyte

El siguiente ejercicio mandara dos datos binarios al pic esclavo.


hi2csetup i2cmaster, %10100010, i2cslow, i2cbyte
b0 = 1
main:
 if b0 = 1 then
  hi2cout 0,(b0)
  b0 = 2
  pause 150
 endif
 if b0 = 2 then
  hi2cout 0,(b0)
  b0 = 1
  pause 150
 endif
goto main

El siguiente código es el pic esclavo el cual con los datos binarios invertirá el estado de dos de sus pines. Cuando recibe un dato por i2c el esclavo se activará su bandera hi2cflag, luego de activarse debe de restablecerse la bandera con hi2cflag = 0. 

Para configurar el pic esclavo se utiliza la siguiente sentencia:

hi2csetup i2cslave, direccion ej:      hi2csetup i2cslave, %10100010

hi2csetup i2cslave, %10100010
main:
 if hi2cflag = 0 then main
 hi2cflag = 0
 get hi2clast,b1
 if b1 = 1  then
  toggle c.0
 end if
 if b1 = 2 then
  toggle c.1
 end if
goto main

Ahora vamos a LEER un dato del pic esclavo por medio del pic maestro.

Empezaremos con el código del pic esclavo, para esto debemos tener en cuenta que el protocolo i2c no utiliza como lectura las variables b1, b2, etc. si no utiliza lo que es el SCRATPAD (pueden verlo en la pagina 12 del segundo manual de picaxe) para el pic 20x2 tengo la opcion de usar de 0 a 127 bytes en el scratchpad, el scratchpad es una memoria temporal para almacenar datos como arreglos, el cual usa el comando PUT (grabar) Y LET (leer).

En este ejemplo el pic grabará el valor de una entrada analógica en b5 y lo colocará en el scratpad.


hi2csetup i2cslave, %10100010
main:
 readadc 3, b5
 put 2,b5
goto main

 

El pic maestro solo debe de agregarse el comando hi2cin, seguido por el bloque en donde esta el scratchpad que en este caso es 2 y almacenarlo en una variable para luego mandarlo a la pc.

 

hi2csetup i2cmaster, %10100010, i2cslow, i2cbyte
main:
      hi2cin 2,(b1)
      sertxd ("data: ",#b1,13,10)
goto main

 

NOTA: observa que ahora en estos ultimos dos ejemplos le cambié la dirección al picaxe esclavo. 


Ahora supongamos que tengo 3 picaxe conectados en i2c, dos son esclavos y uno maestro, si la direcciones de los esclavos son : %10100000 y % 10100010 y el maestro quiere leer en ambos una entrada analogica digital (usaremos para los esclavos el mismo codigo para el esclavo del ejemplo anterior solo hay que cambiar las direcciones para cada pic). El código del maestro sería: 



hi2csetup i2cmaster, %10100000, i2cslow, i2cbyte
main:
 hi2cin [%10100000],2,(b1)
 sertxd ("data: ",#b1,13,10)
        pause 15
 hi2cin [%10100010],2,(b3)
 sertxd ("data: ",#b31,13,10)
goto main

Como verás el uso del i2c es muy fácil e intuitivo, debes tener en cuenta cada uno de los aspectos mencionados, puedes probarlos cambiandoles la velocidad a fast, espero que esta pequeña guia de cortos ejercicios te aclare la mente en la implementación del protocolo I2c comunicando 2 o más picaxes en su bus.

Almacenamiento de información (parte 3)


GENERANDO NÚMERO ALEATORIOS

Antes de continuar con el método de almacenamiento de información, necesitaremos tener un código que genere números aleatorios y los almacene en memoria temporal. Puedes modificar estos programas para almacenarlo en la memoria EEPROM interna.







Generaremos números aleatorios con la función random de PICAXE, pero la cual nos da una secuencia de valores aleatorios, así que si quieres que te salga valores más variados debes cambiar el valor de la variable antes de la función random para cambiar dicho valor. El comando sertxd sirve para enviar datos del PICAXE al PC y que se puedan desplegar en la ventana de PICAXE presionando F8.

main:
            random b0
            sertxd("valor aleatorio: ",#b0,13,10)
            pause 150       
goto main

Con memoria EEPROM interna:

for b0 = 0 to 10
            random b1
            write b0,b1
next b0

pause 2500

for b0=0 to 10
            read b0,b2
            sertxd("dato: ",#b2,13,10)
next b0







Se generarán 20 números aleatorios usando la función rand(), la cual es dividida por 1767 para colocar número inferiores de 20 en el arreglo. La función rand() al igual que la de PICAXE, genera números aleatorios en secuencia, así que si se quiere variar más los números se debe utilizar el comando srand().

int aleatorio[21],i;
char info[8], inf2[8];

void main(){
     Lcd_Init(&PORTB);
     Lcd_Cmd(Lcd_CLEAR);
     Lcd_Cmd(Lcd_CURSOR_OFF);

     for (i=0; i<=20;i++){
          aleatorio[i] = (rand()/1767);  //1767 es un valor para reducir el número aleatorio
          Lcd_out (1,1, "posicion: ");
          IntToStr(i,info); //convierte valor entero a char
          Lcd_out (1,11, info);
          IntToStr(aleatorio[i],inf2);
          Lcd_out (2,4,inf2);
          delay_ms(1000);
          Lcd_Cmd(Lcd_CLEAR);
     }
}











Utilizamos la función que proporciona el lenguaje para generar un número aleatorio y almacenarlo en un arreglo de 10 posiciones. Cabe destacar que la funcion Random siempre tiene la misma secuencia, así que si quieres que en tu programa genere varias veces números al azar y que no sean los mismos, debes usar randomSeed(valordereferencia) para hacer que se ajuste la aleatorización.

int datos[10],val;

void setup() {
  Serial.begin(9600);
  for (int j=0;j<11;j++){
    randomSeed(j+val);
    datos[j] = random(0, 50);
    val++;
    }
  for (int i=0;i<11;i++){ 
    Serial.println(datos[i]);
  }
  Serial.println("-----------");
}

void loop() {
 
}

BUSQUEDA DE INFORMACIÓN

Cuando almacenamos de una forma desordenada los datos en el microcontrolador, no tenemos un orden o un carácter de criterio para almacenar. A este tipo de arreglo de datos se les llama “Arreglos desordenados”.

Imaginemos el siguiente ejemplo: hemos creado un arreglo y queremos que a través de un ID tag busquemos el valor censado en el arreglo y si lo encuentra enciende un LED verde. Sino un LED rojo.

Así que tenemos que implementar una búsqueda, en un arreglo desordenado. La búsqueda se utiliza generalmente para recuperar datos que se habían almacenado antes. Los métodos de búsqueda pueden ser internos y externos.

La búsqueda interna trabaja con los elementos almacenados en la memoria del microcontrolador.

La búsqueda externa trabaja con los elementos almacenados en una memoria externa.

El único método que podemos utilizar (y el que pensamos utilizar casi intuitivamente) en un arreglo desordenado es una búsqueda secuencial desordenada. La cual consiste en revisar elemento tras elemento hasta encontrar el dato.

BUSQUEDA SECUENCIAL DESORDENADA – MEMORIA EEPROM INTERNA

El siguiente algoritmo muestra una búsqueda secuencial desordenada, en la cual lo que se busca comprobar es la posición del dato en el arreglo.

I: variable tipo entero.
X: elemento de un arreglo desordenado
V: arreglo
N: datos

Hacer I = 0
Mientras ((I<=N)y(v[I]<>X)) repetir
            Hacer I = I +1
{fin del ciclo}
Si (I>N)
            Entonces
                        Escribir: “no se encuentra la información”
            Si no
                        Escribir: “la información se encuentra en la posición: “, I
{fin de condición}

Ahora traducimos el algoritmo a cada uno de los microcontroladores que utilizamos:








Utilizaremos la función generadora de valores aleatorios y almacenaremos 11 datos al azar, buscaremos un número específico (11) y comprobaremos la funcionalidad del algoritmo. Debido a que PICAXE no tiene para arreglos, el programa se probará en la memoria EEPROM interna y además el algoritmo sufre un leve cambio ya que no se pueden implementar arreglos en este lenguaje.

#no_data 'no sobrescribe la EEPROM al momento de grabar este programa

pause 2500

b3 = 0
b5 = 0
do
            read b5,b4
            b3 = b3+1
            b5 = b5+1
loop while b3<=10 and b4<>11

if b3 > 10 then
            sertxd ("dato no encontrado")
else
            sertxd ("dato encontrado en posición: ", #b3,13,10)
endif







Utilizamos el código para generar números aleatorios, y comprobaremos la funcionalidad del algoritmo, buscando el número 7. El proceso lo realizaremos en memoria RAM, se hace esto para reducir el uso en la memoria EEPROM del microcontrolador.

int aleatorio[21],i,j;
char info[8],inf2[8];

void main(){
     TRISA.F0 = 0;
     Lcd_Init(&PORTB);
     Lcd_Cmd(Lcd_CLEAR);
     Lcd_Cmd(Lcd_CURSOR_OFF);
     PORTA.F0=0;

     for (j=0; j<=20;j++){
          aleatorio[j] = (rand()/1767);  //1767 es un valor para reducir el número aleatorio
     }

     /*for (i=0; i<=20;i++){  //se puede usar este ciclo para desplegar el arreglo y comprobar en que posición esta el número 7
          aleatorio[i] = (rand()/1767);
          Lcd_out (1,1, "posicion: ");
          IntToStr(i,info);
          Lcd_out (1,11, info);
          IntToStr(aleatorio[i],inf2);
          Lcd_out (2,4,inf2);
          delay_ms(1000);
          Lcd_Cmd(Lcd_CLEAR);
     } */

    
     delay_ms(750);
    
     i = 0;
     while ((i<=20) && (aleatorio[i]!=7)) {
           i++;
     }
     if (i>20){
        Lcd_Out(1,1,"no encontrado");
        }
     else{
        PORTA.F0=1;
        Lcd_Out(1,1,"posicion:");
        IntToStr(i, info);
        Lcd_Out(1,10,info);
     }
}












Utilizaremos la función generadora de valores aleatorios y almacenaremos 60 datos al azar, buscaremos un número específico (30) y comprobaremos la funcionalidad del algoritmo. El proceso lo realizaremos en memoria RAM.

int datos[60],val;

void setup() {
  Serial.begin(9600);
  for (int j=0;j<61;j++){ //generación de número aleatorios
    randomSeed(j+val);
    datos[j] = random(0, 80);
    val++;
    }
  for (int i=0;i<61;i++){   //despliega el arreglo
    Serial.print(i);
    Serial.print(": ");
    Serial.println(datos[i]);
  }
  Serial.println("-----------");
  int I = 1;  //algoritmo de búsqueda
  while (I<61 && datos[I]!=30)
  {
    I++;
  }
  if (I > 60)  {
    Serial.println("dato no encontrado");
    }
  else{
    Serial.print("la informacion se encuentra en la posicion: ");
    Serial.println(I);
  }   
}

void loop() {
 
}

El algoritmo anterior esta diseñado para buscar el primer valor y desplegarlo o si no se encontró, el siguiente algoritmo posee recursividad, lo cual significa que aunque encontró un valor, buscará los demás que son iguales.

I: variable tipo entero que inicia en 0.
X: elemento de un arreglo desordenado
V: arreglo
N: datos

Si (I>N)
            Entonces
                        Escribir: “información no encontrada”
            Si no
                        Si (V[I]=X)
                                   Entonces
                                               Escribir: “la información se encuentra en la posición”, I
                        {fin de la condición}
                        I = I +1
                        Regresar al paso 1 del algoritmo
{fin de la condición}







Generaremos 60 valores aleatorios y se realizará una búsqueda para encontrar el número 11 y que despliegue en pantalla en donde se encontró. Se ha agregado un ciclo para desplegar los valores y así comprobar la efectividad del ciclo de búsqueda.

for b0 = 0 to 60 'almacena valores
            random b1
            write b0,b1
next b0

'pause 1000   'ciclo para mostrar los valores almacenados (opcional)
'sertxd("datos",13,10)

'for b0=0 to 60
'           read b0,b2
'           sertxd("dato: ",#b2,13,10)
'next b0

pause 2500
sertxd ("buscando...",13,10)

b2= 0 'ciclo de busqueda
ciclo: if b2 > 60 then
                        sertxd("busqueda finalizada")
             else
                        read b2,b3
                        if b3 = 11 then
                                   sertxd("información encontrada en ",#b2,13,10)
                        endif
                        b2 = b2 +1
                        goto ciclo
             endif
stop







Se generan 20 números aleatorios, de los cuales se buscarán todos los números 7. Se esta utilizando un arreglo, así que si quieres hacer pruebas con la EEPROM del microcontrolador, debes modificar un poco el código. NOTA: el algorimo se modifico un poco, específicamente en la parte del salto para volver al primer paso del algoritmo. Se utilizo una sentencia while y un if.

int aleatorio[21],i,j;
char info[8],inf2[8];

void main(){
     TRISA.F0 = 0;
     Lcd_Init(&PORTB);
     Lcd_Cmd(Lcd_CLEAR);
     Lcd_Cmd(Lcd_CURSOR_OFF);
     PORTA.F0=0;

     for (j=0; j<=20;j++){
          aleatorio[j] = (rand()/1767);  //1767 es un valor para reducir el número aleatorio
     }

     /*for (i=0; i<=20;i++){  //se puede usar este ciclo para desplegar el arreglo y comprobar en que posición esta el número 7
          aleatorio[i] = (rand()/1767);
          Lcd_out (1,1, "posicion: ");
          IntToStr(i,info);
          Lcd_out (1,11, info);
          IntToStr(aleatorio[i],inf2);
          Lcd_out (2,4,inf2);
          delay_ms(1000);
          Lcd_Cmd(Lcd_CLEAR);
     }*/

     delay_ms(750);

     i = 0;          // ciclo de búsqueda
     while (i <= 20){
           if (aleatorio[i] == 7 ){
                    Lcd_Cmd(Lcd_CLEAR);
                    Lcd_Out(1,1,"posicion:");
                    IntToStr(i, info);
                    Lcd_Out(1,10,info);
                    delay_ms(700);
           }
           i++;
     }
     if (i > 20){
        Lcd_Cmd(Lcd_CLEAR);
        Lcd_Out(1,1,"busqueda fin.");
     }
}











Grabaremos 60 números aleatorios, de los cuales desplegaremos todos los números 4 que se encuentren  y se desplieguen en el monitor serial de Arduino. NOTA: el código para esta búsqueda tiene el mismo cambio que el que se hizo para PIC.

int datos[60],val;

void setup() {
  Serial.begin(9600);
  for (int j=0;j<61;j++){ //generación de número aleatorios
    randomSeed(j+val);
    datos[j] = random(0, 80);
    val++;
    }
  for (int i=0;i<61;i++){   //despliega el arreglo
    Serial.print(i);
    Serial.print(": ");
    Serial.println(datos[i]);
  }
  Serial.println("-----------");
 
  int I = 0; //algoritmo de búsqueda
  while (I <= 60){
    if (datos[I] == 4){
      Serial.print("posicion: ");
      Serial.println(I);
    }
    I++;
  }
  if (I > 60){
    Serial.println("busqueda finalizada");
   }
}

void loop() {
 
}

BUSQUEDA SECUENCIAL DESORDENADA – MEMORIA EEPROM EXTERNA

Para realizar una búsqueda externa se requiere de más tiempos de proceso por lo que la búsqueda es más lenta, si queremos optimizar y reducir el tiempo de lectura y escritura, debemos ordenar la memoria (tema que discutiremos en otra entrada).

El algoritmo para una búsqueda externa es el mismo para ambos casos, salvo que en este tipo de búsqueda se necesita identificar qué dispositivo externo es por lo tanto debemos utilizar correctamente el CS (bus SPI) o la dirección del dispositivo por I2C.







Utilizaremos el algoritmo de generación de números aleatorios y de búsqueda secuencial desordenada, almacenará 35 datos en la memoria EEPROM 24LC256 y buscará el número 11.



hi2csetup i2cmaster, %10100000, i2cslow, i2cword
pause 1500

main:
            for b1 = 0 to 35 'ciclo de almacenamiento aleatorio
                        random b0
                        sertxd("valor aleatorio ",#b1,": ",#b0,13,10)
                        hi2cout b1,(b0)
                        pause 10
            next b1

            b3 = 0 'ciclo de búsqueda
            b5 = 0
            sertxd(“buscando…”,13,10)
            do
                        hi2cin b5,(b4)
                        if b4 <> 11 then
                                   b3 = b3+1
                                   b5 = b5+1
                        endif
            loop while b3<=35 and b4<>11

            if b3 > 35 then
                        sertxd ("dato no encontrado")
            else
                        sertxd ("dato encontrado en posición: ", #b3,13,10)
            endif

El siguiente código es para la búsqueda secuencial desordenada con recursividad, con la misma configuración de datos de búsqueda del algoritmo pasado.

hi2csetup i2cmaster, %10100000, i2cslow, i2cword
pause 1500

main:
            for b1 = 0 to 35 'ciclo de almacenamiento aleatorio
                        random b0
                        sertxd("valor aleatorio ",#b1,": ",#b0,13,10)
                        hi2cout b1,(b0)
                        pause 10
            next b1

            sertxd ("buscando...",13,10)

            b2= 0 'ciclo de busqueda
            ciclo: if b2 > 35 then
                                   sertxd("busqueda finalizada")
                         else
                                    hi2cin b2,(b3)
                                   if b3 = 11 then
                                               sertxd("información encontrada en ",#b2,13,10)
                                   endif
                        b2 = b2 +1
                        goto ciclo
             endif
stop











El siguiente programa almacena 10 datos aleatorios en la memoria EEPROM 25LC256 y realiza una búsqueda secuencial desordenada. Pon atención en como esta trabajando el código y sus cambios que sufre al convertirse de un arreglo a un dispositivo externo SPI. Observa que hay un cambio en el algoritmo para incrementar I.



#include <SPI.h>
int datos,val,resultado=0;

void setup() {
  Serial.begin(9600);
  pinMode(10,OUTPUT);
  pinMode(2,OUTPUT);
  digitalWrite(10, HIGH);
  digitalWrite(2, HIGH);
  SPI.begin(); 
  SPI.setDataMode(SPI_MODE3);  //configura protocolo SPI
  SPI.setClockDivider(SPI_CLOCK_DIV2); // 10 Mhz max para 25LC256
  SPI.setBitOrder(MSBFIRST);
 
  digitalWrite(10, LOW);
  SPI.transfer(6);  // escritura habilitada 6
  digitalWrite(10, HIGH);
 
  digitalWrite(10, LOW);
  SPI.transfer(1); // remueve protección de bloque 1,0
  SPI.transfer(0);
  digitalWrite(10, HIGH);
  delay(5);
 
  for (int j=0;j<11;j++){ //generación de número aleatorios
    randomSeed(j+val);
    datos = random(0, 80);
   
    digitalWrite(10, LOW);
    SPI.transfer(6); // escritura habilitada 6
    digitalWrite(10, HIGH);
     
    digitalWrite(10, LOW);
    SPI.transfer(2); // write 2,0
    SPI.transfer(0);
    SPI.transfer(j); // registro
    SPI.transfer(datos); // dato a almacenar
    digitalWrite(10, HIGH);
    delay(5);
     
    digitalWrite(10, LOW);
    SPI.transfer(6); // escritura habilitada 6
    digitalWrite(10, HIGH);
   
    val++;
    Serial.print(j); //despliega el arreglo
    Serial.print(": ");
    Serial.println(datos);
    }
  digitalWrite(10, LOW);
  SPI.transfer(4); // escritura deshabilitada 4
  digitalWrite(10,HIGH);
  Serial.println("--------");
 
  int I = 0;  //algoritmo de búsqueda secuencial   
  while (I<11 && resultado!=56) //se busca el número 56
  {
    digitalWrite(10, LOW);
    SPI.transfer(3); // lee 3,0
    SPI.transfer(0);
    SPI.transfer(I);
    resultado = SPI.transfer(0x00);
    digitalWrite(10, HIGH);
   
    if (resultado != 56){ //si se cambia el número de búsqueda, cambiarlo también aquí
      I++;
    }
  }
  if (I > 10)  {
    Serial.println("dato no encontrado");
    }
  else{
    Serial.print("la informacion se encuentra en la posicion: ");
    Serial.println(I);
  }
}

void loop() {
}

Espera la próxima entrada y la última de almacenamiento de información, donde hablaremos sobre los arreglos ordenados.