Mostrando entradas con la etiqueta dado electrónico. Mostrar todas las entradas
Mostrando entradas con la etiqueta dado electrónico. Mostrar todas las entradas

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.








sábado, 25 de agosto de 2012

Dado Electrónico

Dado electrónico con Arduino UNO.

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

En este ejercicio se construye un circuito electrónico con un display de siete segmentos con ánodo común. Las terminales (a, b, c, d, e, f y g) se conectaron a las I/O (2, 3, 4, 5, 6, 7 y 8) respectivamente. En la I/O número 9 se conectó un botón pulsador conectando un extremo al polo positivo (+5V), el otro extremo a una resistencia de 10K conectada a la terminal GND (tierra) de la tarjeta Arduino UNO. Los valores del uno al seis se despliegan simultáneamente en el display LED y en el monitor serial del ambiente Arduino. El monitor serial muestra además el estado de la entrada digital, el botón pulsador. Los números del uno al seis se despliegan 50 veces rápidamente (50 ms HIGH y 15 ms LOW). Durante esta etapa se aprieta el botón pulsador y el número seleccionado queda guardado en la variable optn. Al terminar el despliegue de la serie de números, el display LED muestra el número seleccionado (destellando 15 veces, 250 ms HIGH y 15 ms LOW) cuando se apretó el botón pulsador.

 
Figura 1. Display de LED, botón pulsador y placa Arduino UNO.

En el desarrollo del proyecto se comenzó con una primera versión del programa completo, aunque este no funcionaba correctamente pero sí era compilado. Después se construyó el circuito electrónico y se reinició la escritura del código. Primero haciendo encender y apagar cada uno de los segmentos del display y corrigiendo cualquier error en el hardware. Una vez que el hardware funcionó, se codificaron las funciones para generar los números (uno al seis). A continuación se estableció la comunicación con el monitor serial y la entrada digital a través del botón pulsador. Por último se desarrollaron dos fracciones de código, uno con la instrucción for, para seleccionar el valor a través del botón pulsador asociado a la asignación del valor para la variable optn y otra con la instrucción switch/case, para desplegar el valor seleccionado por la pulsación del botón.
Aunque el código que se presenta adelante es bastante extenso, es posible quitar partes que no intervienen directamente con el funcionamiento del dado. Las funciones para desplegar los números se repiten, cambiando únicamente los valores de la instrucción delay();. Como ejercicio, se puede quitar un juego de estos números colocando como argumentos de las funciones, las duraciones para la instrucción mencionada.

El código desarrollado para el proyecto es el siguiente:

/*
Un display LED de 7 segmentos despliega rápidamente números
del uno al seis. Se detiene cuando se presiona un botón
pulsador, mostrando el valor en forma estática.
Al pulsar nuevamente el botón pulsador vuelve a comenzar el
despliegue de números del uno al seis
Se utiliza la instrucción switch / case
*/

int a=2;
int b=3;
int c=4;
int d=5;
int e=6;
int f=7;
int g=8;
int pulsador=9;

void setup ()  {
  Serial.begin(9600);
  pinMode(a, OUTPUT);
  pinMode(b, OUTPUT);
  pinMode(c, OUTPUT);
  pinMode(d, OUTPUT);
  pinMode(e, OUTPUT);
  pinMode(f, OUTPUT);
  pinMode(g, OUTPUT);
  pinMode(pulsador, INPUT);  }


void loop ()  {
  digitalWrite(a, HIGH);
  delay(250);
  digitalWrite(a, LOW);
  delay(75);

  digitalWrite(b, HIGH);
  delay(250);
  digitalWrite(b, LOW);
  delay(75);

  digitalWrite(c, HIGH);
  delay(250);
  digitalWrite(c, LOW);
  delay(75);

  digitalWrite(d, HIGH);
  delay(250);
  digitalWrite(d, LOW);
  delay(75);

  digitalWrite(e, HIGH);
  delay(250);
  digitalWrite(e, LOW);
  delay(75);

  digitalWrite(f, HIGH);
  delay(250);
  digitalWrite(f, LOW);
  delay(75);

  digitalWrite(g, HIGH);
  delay(250);
  digitalWrite(g, LOW);
  delay(75);

  digitalWrite(a, HIGH);
  delay(200);
  digitalWrite(b, HIGH);
  delay(200);
  digitalWrite(c, HIGH);
  delay(200);
  digitalWrite(d, HIGH);
  delay(200);
  digitalWrite(e, HIGH);
  delay(200);
  digitalWrite(f, HIGH);
  delay(200);
  digitalWrite(g, HIGH);
  delay(200);

  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  digitalWrite(e, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);

  int optn =0;

for (int i=0; i<50; i++)  {
  Uno();
  int valUno= digitalRead(pulsador);
  Serial.print(" 1 ");
  Serial.println(valUno);
  if (valUno == 1)  {
    optn =1;  }

  Dos();
  int valDos= digitalRead(pulsador);
  Serial.print(" 2 ");
  Serial.println(valDos);
  if (valDos == 1)  {
    optn =2;  }

  Tres();
  int valTres= digitalRead(pulsador);
  Serial.print(" 3 ");
  Serial.println(valTres);
  if (valTres == 1)  {
    optn =3;  }

  Cuatro();
  int valCuatro= digitalRead(pulsador);
  Serial.print(" 4 ");
  Serial.println(valCuatro);
  if (valCuatro == 1)  {
    optn =4;  }

  Cinco();
  int valCinco= digitalRead(pulsador);
  Serial.print(" 5 ");
  Serial.println(valCinco);
  if (valCinco == 1)  {
    optn =5;  }

  Seis();
  int valSeis= digitalRead(pulsador);
  Serial.print(" 6 ");
  Serial.println(valSeis);
  if (valSeis == 1)  {
    optn =6;  }  }

Serial.print("el valor de optn es: ");
Serial.println(optn);

switch (optn)  {
  case 1:  {
    UnoDisplay();
    break;  }
  case 2:  {
    DosDisplay();
    break;  }
  case 3:  {
    TresDisplay();
    break;  }
  case 4:  {
    CuatroDisplay();
    break;  }
  case 5:  {
    CincoDisplay();
    break;  }
  case 6:  {
    SeisDisplay();
    break;  }
  default:
    break;  }  }

void Uno ()  {
  digitalWrite(f, HIGH);
  digitalWrite(e, HIGH);
  delay(50);
  digitalWrite(f, LOW);
  digitalWrite(e, LOW);
  delay(15);  }

void Dos ()  {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(d, HIGH);
  delay(50);
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(g, LOW);
  digitalWrite(e, LOW);
  digitalWrite(d, LOW);
  delay(15);  }

void Tres ()  {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  delay(50);
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(g, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  delay(15);  }

void Cuatro ()  {
  digitalWrite(f, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(c, HIGH);
  delay(50);
  digitalWrite(f, LOW);
  digitalWrite(b, LOW);
  digitalWrite(g, LOW);
  digitalWrite(c, LOW);
  delay(15);  }

void Cinco ()  {
  digitalWrite(a, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  delay(50);
  digitalWrite(a, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  delay(15);  }

void Seis ()  {
  digitalWrite(a, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(c, HIGH);
  delay(50);
  digitalWrite(a, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(e, LOW);
  digitalWrite(d, LOW);
  digitalWrite(c, LOW);
  delay(15);  }

void UnoDisplay ()  {
  for (int i=0; i<15; i++)  {
  digitalWrite(f, HIGH);
  digitalWrite(e, HIGH);
  delay(250);
  digitalWrite(f, LOW);
  digitalWrite(e, LOW);
  delay(15);  }  }

void DosDisplay ()  {
  for (int i=0; i<15; i++)  {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(d, HIGH);
  delay(250);
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(g, LOW);
  digitalWrite(e, LOW);
  digitalWrite(d, LOW);
  delay(15);  }  }

void TresDisplay ()  {
  for (int i=0; i<15; i++)  {
  digitalWrite(a, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  delay(250);
  digitalWrite(a, LOW);
  digitalWrite(b, LOW);
  digitalWrite(g, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  delay(15);  }  }

void CuatroDisplay ()  {
  for (int i=0; i<15; i++)  {
  digitalWrite(f, HIGH);
  digitalWrite(b, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(c, HIGH);
  delay(250);
  digitalWrite(f, LOW);
  digitalWrite(b, LOW);
  digitalWrite(g, LOW);
  digitalWrite(c, LOW);
  delay(15);  }  }

void CincoDisplay ()  {
  for (int i=0; i<15; i++)  {
  digitalWrite(a, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(c, HIGH);
  digitalWrite(d, HIGH);
  delay(250);
  digitalWrite(a, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(c, LOW);
  digitalWrite(d, LOW);
  delay(15);  }  }

void SeisDisplay ()  {
  for (int i=0; i<15; i++)  {
  digitalWrite(a, HIGH);
  digitalWrite(f, HIGH);
  digitalWrite(g, HIGH);
  digitalWrite(e, HIGH);
  digitalWrite(d, HIGH);
  digitalWrite(c, HIGH);
  delay(250);
  digitalWrite(a, LOW);
  digitalWrite(f, LOW);
  digitalWrite(g, LOW);
  digitalWrite(e, LOW);
  digitalWrite(d, LOW);
  digitalWrite(c, LOW);
  delay(15);  }  }


Como se comentó al inicio, el desarrollo del proyecto se hizo mediante avances parciales hasta completar las funciones que se habían contemplado en el programa inicial. Con la diferencia de que el formato final funcionó correctamente.
El proyecto y el código correspondiente fueron desarrollados por Miguel Angel Orduña Bustamante en el año 2012. Saludos.