viernes, 10 de octubre de 2014

Datalogger y dado electrónico con Arduino.

Data-logger y dado electrónico con Arduino.


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

Las placas electrónicas de desarrollo están entrando al mercado ofreciendo cada vez más aplicaciones, para varios sectores de interés, desde los hobbystas, los aficionados a las transformaciones automotrices, los desarrolladores de robots en aplicaciones a pequeña y mediana escala, hasta los trabajos más formales de ingeniería, o en el diseño de experimentos. Aplicaciones interesantes se desarrollan para controlar sistemas a escala en laboratorio así como en el censado automático de algunas variables dentro de esos mismos sistemas. En las aplicaciones más formales es posible diseñar el hardware, escribir el código necesario e integrarlo en un sistema embebido que contiene por así decirlo, trabajo previamente hecho de manera que el proyecto final involucra menos esfuerzo de desarrollo en cuestiones básicas. Esto se cumple tanto en el hardware como en el software.

En esta ocasión se describen dos proyectos: 1) un sistema de censado de datos basado en una tarjeta de desarrollo Arduino UNO, un Shield MicroSD Sparkfun y un sensor de temperatura LM35; 2) un dado electrónico basado en una tarjeta de desarrollo Arduino UNO y un display de 7 segmentos.

En una entrada anterior había explicado un dado electrónico que hacía exactamente lo mismo que este nuevo proyecto. La diferencia notable está en el software, que esta vez está mejor presentado.

El código de los dos proyectos así como la descripción de los circuitos electrónicos periféricos la puedes ver en Programa 1 y Programa 2 abajo, en esta misma página.

Para ilustrar el uso de la función Random() en la generación de números aleatorios se escribió el código siguiente:

/************************************************
Random
************************************************/
void setup()
{
  Serial.begin(115200);
  pinMode(3,OUTPUT);
  randomSeed(analogRead(0));
}
void loop()
{
  float num = random(0,11.5);  // Para obtener un máximo de 0.6*11.5=6.9
  num *= 0.6;
  int dado = num;
  Serial.print("num = ");
  Serial.println(num);
  Serial.print("dado = ");
  Serial.println(dado);
  Serial.println("");
  digitalWrite(3,HIGH);
  delay(15);
  digitalWrite(3,LOW);
  delay(50);
  digitalWrite(3,HIGH);
  delay(15);
  digitalWrite(3,LOW);
  delay(5000);
}

En el código para el dado electrónico (Programa 1) se excluye la posibilidad de generar un cero, ya que los dados no tienen ese número, mediante una condición do { ... } while (num == 0);

Como ejercicio se propone escribir un código para generar números aleatorios del 1 al 6 y guardarlos en un archivo en la microSD. Después de un número infinito de eventos, digamos 1000, generando un número aleatorio cada 2 sec, se puede calcular la frecuencia de ocurrencia para cada resultado. Para este ejercicio se propone formatear la salida al archivo de texto de la siguiente manera:
  String dataString = "";
  dataString += "\n";
  dataString += String(dado);

  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) 
  {
    dataFile.println(dataString);
    dataFile.close();
  }

Este código se coloca dentro de un ciclo for con 1000 iteraciones dentro de la función setup(), para que se ejecute una sola vez. La función loop() { ... } se deja vacía.

El archivo de texto se abre con Excel y aparecerán todos los valores en la primera columna, separados por [enter]. Así se pueden agrupar de menor a mayor y calcular las frecuencias correspondientes.


Conclusiones:

- El proyecto data-logger utiliza una entrada analógica de la placa Arduino UNO. Como este modelo tiene capacidad para 6 entradas analógicas, es posible colocar ese mismo número de sensores.

- El código de programa de data-logger genera un archivo de 19,598 bytes de un total de 32,256 bytes máximo de capacidad de memoria del AT_Mega_328 de Arduino UNO. De esta manera es posible utilizar más funciones. Si se utiliza la Shield Ethernet de Arduino es posible desplegar los resultados en una página web visible dentro de la misma red donde sea conectado el dispositivo.

- El proyecto dado electrónico ilustra la utilización de la función random(min,max); en el IDE de Arduino. Esta misma idea puede aplicarse cuando se quiere simular un proceso en el que una o más variables pueden tener fluctuaciones irregulares fuera del control del operador. Por ejemplo en la carga contaminante de un caudal de agua residual que entra en una planta de tratamiento para su depuración.

- El código de este programa genera un archivo de 2890 bytes de un total de 32,256 bytes máximo de capacidad de memoria del AT_Mega_328 de Arduino UNO.

1
 2
 3
En la imagen 1 se muestra a la izquierda el sensor TMP102 (PCB roja) y el micrófono (forma circular, junto al TL082), al centro el sensor de temperatura LM35 y a la derecha el Shield MicroSD Sparkfun acoplado a Arduino UNO (PCB azul - Arduino original -, debajo); en la imagen 2 el sensor TMP102; y en la imagen 3 una fuente de alimentación de 12V con la que se puede alimentar la placa Arduino UNO mediante un Jack macho de 2.1mm con el positivo al centro.


Fuentes de información:


http://www.onemansanthology.com/blog/sparkfun-tmp102-temperature-sensor-and-arduino-code/

Sitio oficial Arduino: http://www.arduino.cc/


Nota:
En este mismo blog he dedicado otras entradas a describir proyectos utilizando las tarjetas de desarrollo Arduino. Te facilito enlaces a ellas:

- Proyectos de electrónica con Arduino.
- Registro de datos a una micro SD.
- Sensor analógico y señal luminosa con Arduino UNO.
- Manejo de la micro SD del Shield Ethernet.
- Dado electrónico.

***********************************                  *****************************

Programa 1. Datalogger.

/***************************************************
TMP102

Este sensor de temperatura utiliza comunicación I2C (Inter Integrated Circuit) para enviar el dato al microcontrolador maestro.

http://www.onemansanthology.com/blog/sparkfun-tmp102-temperature-sensor-and-arduino-code/

Circuito TMP102:
- ADD0 -> GND
- ALT  -> unused
- SCL  -> A5
- SDA  -> A4
- GND  -> GND
- VCC  -> 3.3V

Circuito LM35:
- +Vcc -> +5V
- Vout -> A0
- GND  -> GND

Circuito Mic (TL082):
- Pin1   OUT   2
- Pin2   -IN   Mic (-)
- Pin3   +IN   Mic (+)
- Pin4   GND   GND
- Pin5   +IN2  N/C
- Pin6   -IN2  N/C
- Pin7   OUT2  N/C
- Pin8   Vdd   +5V

Nota: La tarjeta microSd utiliza los pines de comunicacion
SPI, por lo que no deben conectarse periféricos en esos
puntos.
Pin_11  RB3  MOSI
Pin_12  RB4  MISO
Pin_13  RB5  SCK
Ademas utiliza los pines:
Pin_4   RD4  CS  Ethernet Shield
Pin_10  RB2  CS  Se inicializa como OUTPUT.
Pin_8   RB0  CS  Sparkfun MicroSd
Nota: El microfono genera un conflicto cuando se conecta su
senal en una entrada analogica. Por eso se utilizo un pin I/O
digital.

***************************************************/

#include <Wire.h>
#include <SD.h>

int tmp102Address = 0x48;
#define TERMBAUD  115200
#define led 3
#define ruido 2
unsigned long T;
unsigned long T_ant=0;
unsigned long lap=3000;  // 3 sec
int estado = 0;
float minute = 0.0;
const int chipSelect = 8;

void setup()
{
  Wire.begin();
  Serial.begin(TERMBAUD);
  T= millis();
  Serial.print(" **** INICIO **** t= ");
  Serial.print(T);
  Serial.print(" **** TMP102 **** LM35 ****\n");
  pinMode(led,OUTPUT);
  pinMode(10,OUTPUT);
  
  Serial.println("Inicializando SD card ...");
  if (!SD.begin(chipSelect))
  {
    Serial.println("Falla en tarjeta. Inserta tarjeta ...");
    return;
  }
  Serial.println("Se inicilizo tarjeta SD ...");
}

void loop()
{
  T=millis();
  analogReference(DEFAULT);
  minute = ((T*0.001)/60);
  micEstado();  
  if (T - T_ant > lap)
  {
    digitalWrite(led,HIGH);
    T_ant=millis();
    Serial.print("T_TMP102= ");
    Serial.print(getTemperature_TMP102());
    Serial.print(" T_LM35= ");
    Serial.print(getTemperature_LM35());
    Serial.print(" Time= ");
    Serial.print(minute);
    Serial.print(" MicState= ");
    Serial.println(estado);
    escribeArchivo();
    if (estado != 0)
    {
      estado=0;
    }
    
    delay(15);
    digitalWrite(led,LOW);
    delay(50);
    digitalWrite(led,HIGH);
    delay(15);
    digitalWrite(led,LOW);
  }
}

/******************             ****************/

float getTemperature_TMP102()
{
  Wire.requestFrom(tmp102Address,2); 
  byte MSB = Wire.read();
  byte LSB = Wire.read();
  int TemperatureSum = ((MSB << 8) | LSB) >> 4; 
  float celsius = TemperatureSum*0.0625;
  return celsius;
}

/*****************             *******************/

float getTemperature_LM35()
{
  analogReference(INTERNAL);
  int sens=analogRead(A0);
  float temp=sens/9.31;  // conversion a grados celsius.
  analogReference(DEFAULT);
  return temp;
}

/**********************          ********************/

void micEstado()
{
  int mic = digitalRead(ruido);
  if (mic)
  {
    estado = 1;
  }
  else
  {
    estado = 0;
  }
}

/***************       ****************/

void escribeArchivo()
{
  String dataString = "";
  int tiempo = T/60000;
  int TMP102 = getTemperature_TMP102();
  int LM35 = getTemperature_LM35();
  dataString += "\n";
  dataString += String(tiempo);
  dataString += "\t";
  dataString += String(TMP102);
  dataString += "\t";
  dataString += String(LM35);
  dataString += "\t";
  dataString += String(estado);

  File dataFile = SD.open("datalog.txt", FILE_WRITE);
  if (dataFile) 
  {
    dataFile.println(dataString);
    // dataFile.flush();
    dataFile.close();
  }  
  else {
    Serial.println("error opening datalog.txt");
  } 
}


El código de este programa genera un archivo de 19,598 bytes de un total de 32,256 bytes máximo de capacidad de memoria del AT_Mega_328 de Arduino UNO.


******************************             ***********************************


Programa 2. Dado electrónico.

/*************************************************
DadoElectronico

Circuito:
- Display de 7 segmentos. Catodo comun. DC05.
- Pin7 pulsador. Colocar resistencia de 10k_Ohm a +Vcc.

Pin0  a
Pin1  b
Pin2  c
Pin3  d
Pin4  e
Pin5  f
Pin6  g

g  f  gnd  a b
**************
*            *
*            *
*            *
*            *
**************
e  d  gnd  c dp

*************************************************/

#define push 7
int uno = 0x06;
int dos = 0x5B;
int tres = 0x4F;
int cuatro = 0x66;
int cinco = 0x6D;
int seis = 0x7D;
int disp_num[]={uno,dos,tres,cuatro,cinco,seis};

void setup()
{
  Serial.begin(9600);
  DDRB=0x00;  // PuertoB saliida.
  PORTB = 0x00;
  pinMode (7,INPUT);  // Pin7 entrada digital.
  randomSeed(analogRead(0));
}
void loop()
{
  int num;
  
  do
  {
    float dado = random(0,11.5);  // Para obtener un máximo de 0.6*11.5=6.9.
    num = dado * 6;
  }
  while (num == 0);
  
  if (!push)
  {
    for (int s=0; s<1000; s++)
    {
      PORTB = num;
      delay(8);
      PORTB = 0x00;
      delay(12);
    }
  }
  
  for (int v=0; v<6; v++)
  {
    PORTB = disp_num[v];
    delay(200);
    PORTB = 0x00;
    delay(50);
  }
}
  
El código de este programa genera un archivo de 2890 bytes de un total de 32,256 bytes máximo de capacidad de memoria del AT_Mega_328 de Arduino UNO.








No hay comentarios:

Publicar un comentario