jueves, 6 de septiembre de 2012

Manejo de la micro SD del Shield Ethernet

Manejo de la micro SD del Shield Ethernet.

Categoría: 1. Programación y electrónica.

Se desarrolló un programa (C/C++) para tener juntas algunas instrucciones útiles en el manejo de los archivos contenidos en la tarjeta micro SD del Shield Ethernet de Arduino. Con base en algunos programas de ejemplo como dumpFile, cardInfo y readWrite se desarrolló un menú y las acciones leerArchivo, leerMicroSD y borrarArchivo se programaron como funciones. El monitor serial despliega el menú de opciones y el usuario introduce a través del mismo monitor serial la opción que desea que el programa ejecute. Se verificó cada una de las tres opciones del menú por separado, una vez que crrieron correctamente al cargarlas en la tarjeta Arduino se procedió a colocarlas en un programa único una a una, y teniendo cuidado de no sobrepasar el límite de almacenamiento de la tarjeta (32256 bytes). Para terminar, se verificó el programa completo (16598 bytes) y se cargó en la tarjeta electrónica.

El código es el siguiente:

#include <SD.h>
Sd2Card card;
SdVolume volume;
SdFile root;
const int chipSelect = 4;
void setup ()  {
  Serial.begin(9600);
  pinMode(10, OUTPUT);
  Serial.println("enter:\n 1. cardInfo\n 2. leerArchivo\n 3. borrarArchivo\n 0. Salir ");  }
 
void loop()  {
  if (Serial.available() > 0)  {
    char ch = Serial.read();
    if (ch == '1')  {
       cardInfo(); }
    else if (ch == '2')  {
       leerArchivo(); }
    else if (ch == '3')  {
       borrarArchivo();  }
    else if (ch == '4')  {  }
    else if (ch == '0')  {  }  }  }

void cardInfo ()  {
  Serial.print("\ninitializing SD card... ");
  if (!card.init(SPI_HALF_SPEED, chipSelect)) {
    Serial.println("initialization failed. Things to check:");
    Serial.println("* is a card is inserted?");
    Serial.println("* Is your wiring correct?");
    Serial.println("* did you change the chipSelect pin to match your shield or module?");
    return;  }
    else {
   Serial.println("Wiring is correct and a card is present.");  }
  Serial.print("\nCard type: ");
  switch(card.type()) {
    case SD_CARD_TYPE_SD1:
      Serial.println("SD1");
      break;
    case SD_CARD_TYPE_SD2:
      Serial.println("SD2");
      break;
    case SD_CARD_TYPE_SDHC:
      Serial.println("SDHC");
      break;
    default:
      Serial.println("Unknown");  }
  if (!volume.init(card)) {
    Serial.println("Could not find FAT16/FAT32 partition.\nMake sure you've formatted the card");
    return;  }
  uint32_t volumesize;
  Serial.print("\nVolume type is FAT");
  Serial.println(volume.fatType(), DEC);
  Serial.println();
 
  volumesize = volume.blocksPerCluster();   
  volumesize *= volume.clusterCount();      
  volumesize *= 512;                        
  Serial.print("Volume size (bytes): ");
  Serial.println(volumesize);
  Serial.print("Volume size (Kbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
  Serial.print("Volume size (Mbytes): ");
  volumesize /= 1024;
  Serial.println(volumesize);
 
  Serial.println("\nFiles found on the card (name, date and size in bytes): ");
  root.openRoot(volume);
 
  root.ls(LS_R | LS_DATE | LS_SIZE);  }


void borrarArchivo ()  {
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect))  {
    Serial.println("initialization failed!...");
    return;  }
  Serial.println("initialization done!...");
 
  if (SD.exists("pulsedat.txt"))  {
    Serial.println("pulsedat.txt exists...");  }
  else  {
    Serial.println("pulsedat.txt doesn't exist...");  }
  Serial.println("removing pulsedat.txt...");
  SD.remove("pulsedat.txt");
 
  if (SD.exists("pulsedat.txt"))  {
    Serial.println("pulsedat.txt exists...");  }
  else  {
    Serial.println("pulsedat.txt doesn't exist..");  }  }


void leerArchivo ()  {
  Serial.print("Initializing SD card...");
    if (!SD.begin(chipSelect))  {
      Serial.println("initialization failed!...");
      return;  }
  Serial.println("initialization done!...");
 
  File dataFile = SD.open("pulsedat.txt", FILE_READ);
  if (dataFile)  {
    Serial.println("pulsedat.txt exists...");
    while (dataFile.available())  {
      Serial.write(dataFile.read());  }
      dataFile.close();  }
  else  {
    Serial.println("error opening pulsedat.txt...");  }  }
     
De esta manera, se puede trabajar de manera más amigable con el programa presentado anteriormente como EjercicioPulseDat04 para el registro de pulsaciones generadas por un multivibrador astable construido con un circuito integrado NE555 (o NE556).

Es todo por ahora. Saludos.

La bibliografía contenida en la entrada 'registro de datos a una micro SD' también aplica para esta entrada, y es la siguiente:
Bibliografía.

Stengel, Lester. 2006. El ABC de la electrónica. Steren Electrónica SA de CV. México.
Arduino. Sitio web: http://www.arduino.cc/. Consulta el 31 de julio de 2012.







sábado, 1 de septiembre de 2012

Registro de datos a una micro SD

Registro de un generador de pulsos a un archivo de texto (pulsedat.txt).

Categoría: 1. Programación y electrónica.

El programa generador de pulsos funciona registrando los momentos en que un generador de pulsos, un botón pulsador conectado a una resistencia de 10K o, como en este ejercicio, un circuito electrónico generador de pulsos. Este circuito está basado en un circuito integrado NE555 o NE556.

El circuito astable es como sigue:



El programa EjercicioPulseDat04 lee la salida digital del vibrador astable (pin 3 en el NE555 o pines 5 o 9 del NE556), registra en el monitor serial los tiempos de encendido (HIGH) y de apagado (LOW) utilizando la instrucción millis(); y también registra el número de pulsos acumulado. De esta manera es posible medir el tiempo de duración en HIGH y el tiempo de duración en LOW.
Estos mismos datos se registran en un archivo llamado pulsedat.txt, almacenado en la tarjeta de datos micro SD contenida en el Shield Ethernet de Arduino. Como se sabe, esta tarjeta va acoplada con la tarjeta electrónica Arduino UNO.

Las siguientes imágenes muestran la salida en el monitor serial y la ventana del ambiente Arduino con parte del programa a la vista.





El programa se desarrolló tomando como base el ejemplo 'state change detection' (edge detection) que proorciona el ambiente Arduino para la tarjeta electrónica Arduino UNO. También se utilizó parte del código del ejemplo 'datalogger' para la tarjeta Ethernet Shield.

/*
EjercicioPulseDat04
*/
/*
  State change detection (edge detection)

 Often, you don't need to know the state of a digital input all the time,
 but you just need to know when the input changes from one state to another.
 For example, you want to know when a button goes from OFF to ON.  This is called
 state change detection, or edge detection.

 This example shows how to detect when a button or button changes from off to on
 and on to off.

 The circuit:
 * pushbutton attached to pin 2 from +5V
 * 10K resistor attached to pin 2 from ground
 * LED attached from pin 13 to ground (or use the built-in LED on
   most Arduino boards)

 created  27 Sep 2005
 modified 30 Aug 2011
 by Tom Igoe
This example code is in the public domain.

 http://arduino.cc/en/Tutorial/ButtonStateChange

 */
#include <SD.h>
const int  buttonPin = 2;   
const int ledPin = 13;      
int buttonPushCounter = 0; 
int buttonState = 0;       
int lastButtonState = 0; 
File dataFile;
void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
  pinMode(10, OUTPUT);
 
    if (!SD.begin(4))  {
    Serial.println("card failed, or not present...");
    return;  }
  Serial.println("card initialized...");
 
  Serial.println("removing pulsedat.txt...");
  SD.remove("pulsedat.txt");
  if (SD.exists("pulsedat.txt"))  {
    Serial.println("pulsedat.txt exists...");  }
  else  {
    Serial.println("pulsedat.txt doesn't exist...");  }  }

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState != lastButtonState)
  {
    if (buttonState == HIGH)
    {
      buttonPushCounter++;
      Serial.print("number of button pushes:  ");
      Serial.println(buttonPushCounter);
      Serial.print("time on= ");
      Serial.println(millis());
 
  dataFile = SD.open("pulsedat.txt", FILE_WRITE);
  if (dataFile) 
      {
    Serial.println("writing to pulsedat.txt...");
    dataFile.print("number of button pushes:  ");
    dataFile.println(buttonPushCounter);
    dataFile.print("time on= ");
    dataFile.println(millis());   
    dataFile.close();
    Serial.println("action done..."); 
      }
  else 
      {
    Serial.println("error opening pulsedat.txt"); 
      }   
    }
 
   
    else
      {
      Serial.print("time off= ");
      Serial.println(millis());
     
  dataFile = SD.open("pulsedat.txt", FILE_WRITE);
  if (dataFile) 
        {
    Serial.println("writing to pulsedat.txt...");
    dataFile.print("time off= ");
    dataFile.println(millis());
   
    dataFile.close();
    Serial.println("action done..."); 
        }
  else 
        {
    Serial.println("error opening pulsedat.txt"); 
        }
      }
 
  lastButtonState = buttonState;
  if (buttonPushCounter % 4 == 0)
      {
    digitalWrite(ledPin, HIGH);
      }
  else
      {
   digitalWrite(ledPin, LOW);
      }
  }
}
Este programa con algunas modificaciones puede adaptarse para medir variables de uno o más sensores (temperatura, humedad, presión atmosférica, intensidad lumínica, voltaje, etc) conectados a las entradas analógicas de la tarjeta electrónica.

Por lo pronto es todo. Saludos.

Bibliografía.

Stengel, Lester. 2006. El ABC de la electrónica. Steren Electrónica SA de CV. México.
Arduino. Sitio web: http://www.arduino.cc/. Consulta el 31 de julio de 2012.