Mostrando las entradas con la etiqueta ds1302. Mostrar todas las entradas
Mostrando las entradas con la etiqueta ds1302. Mostrar todas las entradas
Vamos a programar #76 - Neo Clock View.
Hola de nuevo a todos, el día de hoy vamos a ver un poco de algo a lo que decidí llamar "Neo Clock View". Para fabricarlo vamos a hacer uso de los displays de siete segmentos que vimos en el post anterior.
En la versiones anteriores de Clock View, usamos el módulo DS1302. En esta ocasión haremos uso del modulo DS1307 y haremos una versión solo para probar si los "displays" funcionan cómo esperamos.
Antes de comenzar, deberás de instalar la librería para poder usar el modulo de reloj de forma sencilla. La puedes descargar del GitHub del dueño.
Una vez instalada, vamos a realizar las conexiones. Para esto simplemente conectamos de la siguiente manera.
El código consta de tres funciones. La primera de ellas en orden de aparicion es "PrintNumber", hay que recordar que diseñamos los segmentos de forma tal; que cada tres LED's representan un segmento. La función recibe cinco parámetros. El primero es el valor que el digito tendrá y técnicamente puede ser cualquier valor (dentro del tipo "integer"), pero debido a que solo podemos mostrar valores dentro del rango 0 ~ 9, deberíamos pasar valores que no excedan nueve. El siguiente parámetro debe de ser un valor que nos indicara que digito es el que queremos usar, dado que empezamos de derecha a izquierda, si decimos que queremos usar el digito uno, estaríamos usando el del lado derecho.
Los ultimos tres parametrosn, son los valores que se usaran para cada color empezando por el rojo, luego el verde y finalmente el azul. El valor para cada uno de estos deberá de estar entre los valores 0 ~ 255, y mezclandolos, podemos crear cualquier color.
la siguiente función es "ShowIntro()", esta función sirve para hacer una animación que recorrerá cada un de los LED de inicio a fin, solo se hará una vez y sirve para demostrar de que otra forma se pueden controlar los LED's.
La siguiente función es "PrintTime()". Recibe tres parámetros del tipo "int", el primero es el valor que representan las horas, el segundo es un valor que representa a los minutos y finalmente el tercero es un valor que representa a los segundos. dentro de la función se usan tres condiciones; la primera para los segundos; cuando se le hace la consulta del tiempo al modulo de reloj, si el tiempo es menor a diez segundos, este devolverá un solo dígito; es decir, si el tiempo tiene solo siete segundos en lugar de devolver "07" que seria el valor que esperamos, solo nos regresaría "7". La comprobación sirve para cuando sucede este caso. Para solucionarlo, si el tiempo (segundos, minutos u horas) es menor a 10, llamamos a la función "PrintTime()" dos veces y en la primera llamada, le pasamos como primer parámetro el valor de los segundos y en el segundo parámetro el valor "0" que indica que queremos usar la primer matriz (el orden ya lo había dicho). Para la segunda llamada, le pasaremos el valor de "0" cómo primer parámetro y "1" cómo segundo, así cuando pase el caso de siete segundos (por ejemplo) tendremos un número para mostrar en el segundo display. Cuando es el caso contrario o mejor dicho cuando los valores son mayores o iguales a diez, lo único que hacemos dividir y en la primera llamada pasamos el resultado del modulo del valor actual (segundos, minutos u horas) y diez. Para la segunda llamada simplemente dividimos en valor entre diez y esto nos dará el valor que debemos de mostrar en la segunda llamada.
Dentro del bucle principal lo primero que hacemos es llamar a la función "ShowIntro" valiendonos de un flag llamado "Intro" que se inicializa en "true", la condición dice que cuando esta variable es verdadero se hace la animación, al se una variable global, cuando la animación acaba, cambia el valor de la variable "Intro" a "false" por lo que la animación solo se produce una sola vez. Acabada la animación, usamos las funciones de la libreria del reloj. Primero comprobamos si se puede leer desde el módulo, si es así llamamos a la función "PrintTime()" con las horas; "tm.Hour", los minutos; "tm.Minute", y los segundos "tm.Seconds". Con esto mostramos la hora en los "displays". Si no se puede obtener la hora del módulo, se trata de comprobar si el chip está disponible, si es así solamente bastará con subir el ejemplo que viene en la librería (disponible en Ejemplos >> DS1307RTC >> SetTime). Solo tendremos que subirlo antes que este código y ya tendrá la hora ajustada.
Y bien, por ahora es todo, en el próximo post veremos cómo mejorar un poco más el reloj, aunque creo que lo ideal seria usar el código de clock view y solamente adaptar las partes que necesitemos.
Los leo luego.
En la versiones anteriores de Clock View, usamos el módulo DS1302. En esta ocasión haremos uso del modulo DS1307 y haremos una versión solo para probar si los "displays" funcionan cómo esperamos.
Antes de comenzar, deberás de instalar la librería para poder usar el modulo de reloj de forma sencilla. La puedes descargar del GitHub del dueño.
Una vez instalada, vamos a realizar las conexiones. Para esto simplemente conectamos de la siguiente manera.
- SDA - Al pin A4 del arduino.
- SCL - Al pin A5 del arduino.
- VCC - A 5v del arduino.
- GND - A GND del arduino.
//Reloj
// A4 - SDA
// A5 - SCL
#include <FastLED.h>
#define NUM_LEDS 126
#define DATA_PIN 9
#include <Wire.h>
#include <TimeLib.h>
#include <DS1307RTC.h>
CRGB leds[NUM_LEDS];
int XC = 0;
void setup() {
// Serial.begin(9600);
// while (!Serial) ;
// delay(200);
LEDS.addLeds<WS2812,DATA_PIN,RGB>(leds,NUM_LEDS);
LEDS.setBrightness(10);
}
void PrintNumber(int Value, int Digit, int Green, int Red, int Blue){
for(int i = 0; i < 7; i++) {
switch (Value)
{
case 0:
if (i == 6){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0, 0, 0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0, 0, 0);
leds[i * 3 + (Digit * 21)].setRGB(0, 0, 0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i*3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i*3+ (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 1:
if (i == 0 || i == 1){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i*3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}
FastLED.show();
break;
case 2:
if (i == 0 || i == 3){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 3:
if (i == 3 || i == 4){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 4:
if (i == 2 || i == 4 || i == 5){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 5:
if (i == 1 || i == 4){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 6:
if (i == 1){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 7:
if (i == 3 || i == 6 || i == 4 || i == 5){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3)+ 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3)+ 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
case 8:
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
FastLED.show();
break;
case 9:
if (i == 4){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
default:
if (i == 0 || i == 1){
leds[(i * 3) + 2 + (Digit * 21)].setRGB(0,0,0);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(0,0,0);
leds[i * 3 + (Digit * 21)].setRGB(0,0,0);
}else{
leds[(i * 3) + 2 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[(i * 3) + 1 + (Digit * 21)].setRGB(Green, Red,Blue);
leds[i * 3 + (Digit * 21)].setRGB(Green, Red,Blue);
}
FastLED.show();
break;
}
}
}
void ShowIntro(){
for(int i = 0; i < NUM_LEDS; i++) {
leds[i] = CHSV(255, 255, 255);
FastLED.show();
delay(5);
}
Intro = false;
}
void PrintTime(int Hour, int Minutes, int Seconds){
if(Seconds < 10){
PrintNumber(Seconds,0,255,0,0);
PrintNumber(0,1,255,0,0);
}else{
PrintNumber(Seconds % 10, 0, 255, 0, 0);
PrintNumber(Seconds / 10, 1, 255, 0, 0);
}
if(Minutes < 10){
PrintNumber(Minutes,2,0,255,0);
PrintNumber(0,3,0,255,0);
}else{
PrintNumber(Minutes % 10, 2, 0, 255, 0);
PrintNumber(Minutes / 10, 3,0 , 255, 0);
}
if(Hour < 10){
PrintNumber(Hour,4,0,0,255);
PrintNumber(0,5,255,0,0);
}else{
PrintNumber(Hour % 10, 4, 0, 0,255);
PrintNumber(Hour / 10, 5, 0, 0,255);
}
}
tmElements_t tm;
bool Intro = true;
void loop() {
if (Intro == true) ShowIntro();
if (RTC.read(tm)) {
PrintTime(tm.Hour,tm.Minute,tm.Second);
} else {
if (RTC.chipPresent()) {
PrintTime(1025,1024,1023);
// Serial.println("The DS1307 is stopped. Please run the SetTime");
// Serial.println("example to initialize the time and begin running.");
// Serial.println();
} else {
// Serial.println("DS1307 read error! Please check the circuitry.");
// Serial.println();
}
delay(9000);
}
delay(100);
}
El código consta de tres funciones. La primera de ellas en orden de aparicion es "PrintNumber", hay que recordar que diseñamos los segmentos de forma tal; que cada tres LED's representan un segmento. La función recibe cinco parámetros. El primero es el valor que el digito tendrá y técnicamente puede ser cualquier valor (dentro del tipo "integer"), pero debido a que solo podemos mostrar valores dentro del rango 0 ~ 9, deberíamos pasar valores que no excedan nueve. El siguiente parámetro debe de ser un valor que nos indicara que digito es el que queremos usar, dado que empezamos de derecha a izquierda, si decimos que queremos usar el digito uno, estaríamos usando el del lado derecho.
Los ultimos tres parametrosn, son los valores que se usaran para cada color empezando por el rojo, luego el verde y finalmente el azul. El valor para cada uno de estos deberá de estar entre los valores 0 ~ 255, y mezclandolos, podemos crear cualquier color.
la siguiente función es "ShowIntro()", esta función sirve para hacer una animación que recorrerá cada un de los LED de inicio a fin, solo se hará una vez y sirve para demostrar de que otra forma se pueden controlar los LED's.
La siguiente función es "PrintTime()". Recibe tres parámetros del tipo "int", el primero es el valor que representan las horas, el segundo es un valor que representa a los minutos y finalmente el tercero es un valor que representa a los segundos. dentro de la función se usan tres condiciones; la primera para los segundos; cuando se le hace la consulta del tiempo al modulo de reloj, si el tiempo es menor a diez segundos, este devolverá un solo dígito; es decir, si el tiempo tiene solo siete segundos en lugar de devolver "07" que seria el valor que esperamos, solo nos regresaría "7". La comprobación sirve para cuando sucede este caso. Para solucionarlo, si el tiempo (segundos, minutos u horas) es menor a 10, llamamos a la función "PrintTime()" dos veces y en la primera llamada, le pasamos como primer parámetro el valor de los segundos y en el segundo parámetro el valor "0" que indica que queremos usar la primer matriz (el orden ya lo había dicho). Para la segunda llamada, le pasaremos el valor de "0" cómo primer parámetro y "1" cómo segundo, así cuando pase el caso de siete segundos (por ejemplo) tendremos un número para mostrar en el segundo display. Cuando es el caso contrario o mejor dicho cuando los valores son mayores o iguales a diez, lo único que hacemos dividir y en la primera llamada pasamos el resultado del modulo del valor actual (segundos, minutos u horas) y diez. Para la segunda llamada simplemente dividimos en valor entre diez y esto nos dará el valor que debemos de mostrar en la segunda llamada.
Dentro del bucle principal lo primero que hacemos es llamar a la función "ShowIntro" valiendonos de un flag llamado "Intro" que se inicializa en "true", la condición dice que cuando esta variable es verdadero se hace la animación, al se una variable global, cuando la animación acaba, cambia el valor de la variable "Intro" a "false" por lo que la animación solo se produce una sola vez. Acabada la animación, usamos las funciones de la libreria del reloj. Primero comprobamos si se puede leer desde el módulo, si es así llamamos a la función "PrintTime()" con las horas; "tm.Hour", los minutos; "tm.Minute", y los segundos "tm.Seconds". Con esto mostramos la hora en los "displays". Si no se puede obtener la hora del módulo, se trata de comprobar si el chip está disponible, si es así solamente bastará con subir el ejemplo que viene en la librería (disponible en Ejemplos >> DS1307RTC >> SetTime). Solo tendremos que subirlo antes que este código y ya tendrá la hora ajustada.
Y bien, por ahora es todo, en el próximo post veremos cómo mejorar un poco más el reloj, aunque creo que lo ideal seria usar el código de clock view y solamente adaptar las partes que necesitemos.
Los leo luego.
7/14/2019 03:05:00 p.m.
ds1302
,
ds1307
,
programacion
,
ws2812b
Vamos a programar #32 - Clock view en Windows.
Hola de nuevo a todos, el día de hoy vamos a continuar con un poco más de clock view.
En los post anteriores, vimos cómo controlarlo desde una aplicación para android, pero mucha gente me pregunto si era posible hacer algo similar pero desde una computadora con Windows.
La respuesta: Clock View para Windows.
Para llevar a cabo la conexión, primeramente debemos emparejar el bluetooth de Clock view con el de la computadora que vayamos a usar.
Cuando ya estén emparejados, hay que revisar cual es el puerto que se asigno al bluetooth. Para eso, hay que ir a: Panel de control > Dispositivos e impresoras > "Nombre del Arduino", luego hay que hacer clic secundario y después propiedades.En la ficha "Servicios", nos mostrará cual es el puerto que se usará.
Una vez que sabemos esa información, pasaremos al código de C# que es el siguiente:
Para hacer uso del puerto serial, debemos de crear un objeto SerialPort que se incluye en el espacio de nombres System.IO.Ports.
Cuando el formulario se carga, lo primero que hará es buscar todos los puertos disponibles, pero eso no quiere decir que este conectado o en uso el periférico. Si cuando inicias el programa no puedes ver el puerto al que está conectado tu arduino, basta con que escribas el nombre en la lista. Despues solo hay que hacer clic en conectar y si todo está en orden, se podrá controlar ClockView desde la computadora con BlueTooth.
Al igual que la aplicación para android, en está aplicación se incluyen los controles que cambian las configuraciones de ClockView. Además está aplicación sirve con un cable, si conectas Clock View con un cable USB, también podrás cambiar los ajustes, pero esa no es la idea; aun si prefieres hacer uso del cable, es recomendable que desconectes el módulo HC-05/06 del arduino para que no haya ningún tipo de problemas.
Al igual que todos los otros programas, dejo el código fuente para que los descargues y lo pruebes. El Código fuente de la aplicacion para android, aun lo voy a mejorar un poco y el software para arduino también.
Por ahora es todo. Los leo luego.
En los post anteriores, vimos cómo controlarlo desde una aplicación para android, pero mucha gente me pregunto si era posible hacer algo similar pero desde una computadora con Windows.
La respuesta: Clock View para Windows.
Para llevar a cabo la conexión, primeramente debemos emparejar el bluetooth de Clock view con el de la computadora que vayamos a usar.
![]() |
| En mi caso es "Siqueiros printer" (ignora el nombre es un arduino) |
Cuando ya estén emparejados, hay que revisar cual es el puerto que se asigno al bluetooth. Para eso, hay que ir a: Panel de control > Dispositivos e impresoras > "Nombre del Arduino", luego hay que hacer clic secundario y después propiedades.En la ficha "Servicios", nos mostrará cual es el puerto que se usará.
Una vez que sabemos esa información, pasaremos al código de C# que es el siguiente:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Windows.Forms;
using System.Configuration;
namespace ClockView
{
public partial class FrmMain : Form
{
private SerialPort Port = new SerialPort();
private void ArduinoMessage(string Message)
{
try
{
Port.Write(Message);
}
catch (Exception e)
{
MessageBox.Show(e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public FrmMain()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] Ports = SerialPort.GetPortNames();
CboPorts.Items.AddRange(Ports);
Port.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
}
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
if (indata == "Done")
{
}
}
private void BtnConnect_Click(object sender, EventArgs e)
{
try
{
if (Port.IsOpen == false)
{
Port.BaudRate = int.Parse(TxtSpeed.Text);
Port.PortName = CboPorts.Text;
Port.Parity = Parity.None;
Port.StopBits = StopBits.One;
Port.Parity = Parity.Even;
Port.DataBits = 8;
Port.Open();
}
} catch (Exception ex) {
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void BtnDisconnect_Click(object sender, EventArgs e)
{
if (Port.IsOpen == true)
{
Port.Close();
}
}
private void Btn1224_Click(object sender, EventArgs e)
{
ArduinoMessage(">SETF");
}
private void BtnShowSeconds_Click(object sender, EventArgs e)
{
ArduinoMessage(">DISS");
}
private void BtnLights_Click(object sender, EventArgs e)
{
ArduinoMessage(">SCRA");
}
private void trkbarBrillo_MouseUp(object sender, MouseEventArgs e)
{
ArduinoMessage(">SETB" + trkbarBrillo.Value.ToString());
}
private void BtnSync_Click(object sender, EventArgs e)
{
//>SETH2016122119001004
string HourData = string.Concat(">SETH", DateTime.Now.Year, DateTime.Now.Month.ToString("D2"), DateTime.Now.Day.ToString("D2"),
DateTime.Now.Hour.ToString("D2"), DateTime.Now.Minute.ToString("D2"), DateTime.Now.Second.ToString("D2"),
(((int)DateTime.Now.DayOfWeek)+1).ToString("D2"));
ArduinoMessage(HourData);
}
}
}
Para hacer uso del puerto serial, debemos de crear un objeto SerialPort que se incluye en el espacio de nombres System.IO.Ports.
Cuando el formulario se carga, lo primero que hará es buscar todos los puertos disponibles, pero eso no quiere decir que este conectado o en uso el periférico. Si cuando inicias el programa no puedes ver el puerto al que está conectado tu arduino, basta con que escribas el nombre en la lista. Despues solo hay que hacer clic en conectar y si todo está en orden, se podrá controlar ClockView desde la computadora con BlueTooth.
Al igual que la aplicación para android, en está aplicación se incluyen los controles que cambian las configuraciones de ClockView. Además está aplicación sirve con un cable, si conectas Clock View con un cable USB, también podrás cambiar los ajustes, pero esa no es la idea; aun si prefieres hacer uso del cable, es recomendable que desconectes el módulo HC-05/06 del arduino para que no haya ningún tipo de problemas.
Al igual que todos los otros programas, dejo el código fuente para que los descargues y lo pruebes. El Código fuente de la aplicacion para android, aun lo voy a mejorar un poco y el software para arduino también.
Por ahora es todo. Los leo luego.
3/24/2017 01:47:00 a.m.
bluetooth
,
clock view
,
csharp
,
DIY
,
ds1302
,
LED
,
matriz led
,
max7219
,
programacion
,
rfcomm
,
socket bluetooth
Vamos a programar #29 - Inútil Apps #2 - Creando un socket bluetooth (arduino y android)
Hola a todos, el día de hoy vamos a continuar con Clock View. Ahora con todo el hardware listo y con la parte de software de arduino también listo, solo queda crear una forma de interactuar con el hardware de Clock View. Al carecer de botones solo nos queda la opción de usar el modulo Bluetooth, para comunicarnos por medio de este, podemos usar aplicaciones que ya estan disponibles en la Playstore (S2 Terminal for bluetooth por ejemplo), pero esa no es la idea del blog, en la mediada de lo posible trataremos de usar nuestro propio software para hacer las cosas.
El dia de hoy les quiero presentar Clock View para android, una aplicación que tiene cómo unica función; conectar con el modulo bluetooth HC-05 o HC-06 y cambiar los ajustes de Clock View.
La aplicacion dispone de 6 botones y una barra de "seek". Para usarla, primero debes de asegurarte de que todo el hardware está listo, despues debes de iniciar la conexion con el boton "Conectar con clock view", cuando aparace un mensaje diciendo que la conexion se llevo a cabo, puedes modificar los ajustes.
Hoy solo veremos el código, en el siguiente post, explicaré un poco acerca de cómo se realiza el intercambio de datos entre arduino y android.
Cómo todo el código requiere una explicacion detallada (o si no quieres meterte en programacion), por ahora solo dejo el APK ya compilado,
Los leo luego.
El dia de hoy les quiero presentar Clock View para android, una aplicación que tiene cómo unica función; conectar con el modulo bluetooth HC-05 o HC-06 y cambiar los ajustes de Clock View.
La aplicacion dispone de 6 botones y una barra de "seek". Para usarla, primero debes de asegurarte de que todo el hardware está listo, despues debes de iniciar la conexion con el boton "Conectar con clock view", cuando aparace un mensaje diciendo que la conexion se llevo a cabo, puedes modificar los ajustes.
Hoy solo veremos el código, en el siguiente post, explicaré un poco acerca de cómo se realiza el intercambio de datos entre arduino y android.
El código.
El siguiente es el código en java que se encarga de hacer funcionar las cosas, los estilos y demás "layouts", irán en la descarga completa al final del post.
package com.mdev.clockview;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Handler;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.Calendar;
import static com.mdev.clockview.R.layout.paired_devices_list;
public class MainActivity extends Activity {
BluetoothAdapter myBluetoothAdapter = null;
Button BtnConnect, BtnOnOff, BtnSecondsShow, BtnSyncHour, BtnChangeFormat,BtnDisconnect;
SeekBar SkBright;
TextView TxtArduinoRec, TxtBrigthValue;
String address = null;
private ProgressDialog progress;
BluetoothSocket btSocket = null;
private boolean isBtConnected = false;
private static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
final int RECEIVE_MESSAGE = 1;
private StringBuilder sb = new StringBuilder();
private ConnectedThread mConnectedThread;
Handler h;
private Set<BluetoothDevice> pairedDevices;
ListView myListView;
ArrayAdapter BTArrayAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
BtnConnect = (Button)findViewById(R.id.BtnConnect);
myListView = (ListView)findViewById(R.id.BTList);
TxtArduinoRec = (TextView)findViewById(R.id.TxtArduinoReturn);
BtnOnOff = (Button)findViewById(R.id.BtnOn);
BtnSecondsShow = (Button)findViewById(R.id.BtnShowS);
BtnSyncHour = (Button)findViewById(R.id.BtnSync);
BtnChangeFormat = (Button)findViewById(R.id.BtnFormat);
BtnDisconnect = (Button)findViewById(R.id.BtnDisconnect);
SkBright = (SeekBar)findViewById(R.id.SKBrillo);
TxtBrigthValue = (TextView)findViewById(R.id.txtSeekValue);
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (myBluetoothAdapter == null) {
msg("El bluetooth no es soportado por este dispositivo");
}
else {
msg("Esperando la conexion");
}
SkBright.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener(){
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
TxtBrigthValue.setText(String.valueOf(progress));
if (isBtConnected)
{
String result = String.format(">SETB%1$02d", progress);
mConnectedThread.write(result);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
BtnConnect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!myBluetoothAdapter.isEnabled()) {
Intent turnOnIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOnIntent, 1);
}else{
showBTDialog();
}
}
});
BtnOnOff.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view){
if (isBtConnected)
{
mConnectedThread.write(">SCRA");
}
}
});
BtnSecondsShow.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view){
if (isBtConnected)
{
mConnectedThread.write(">DISS");
}
}
});
BtnSyncHour.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view){
if (isBtConnected)
{
mConnectedThread.write(BuildHourToArduino());
}
}
});
BtnChangeFormat.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view){
if (isBtConnected)
{
mConnectedThread.write(">SETF");
}
}
});
BtnDisconnect.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view){
if (isBtConnected)
{
Disconnect();
}
}
});
//encargado de procesar los mensajes.
h = new Handler() {
public void handleMessage(android.os.Message msg) {
switch (msg.what)
{
case RECEIVE_MESSAGE:
byte[] readBuf = (byte[]) msg.obj;
String strIncom = new String(readBuf, 0, msg.arg1);
sb.append(strIncom);
int endOfLineIndex = sb.indexOf("\r\n");
if (endOfLineIndex > 0)
{
String sbprint = sb.substring(0, endOfLineIndex);
sb.delete(0, sb.length());
TxtArduinoRec.setText("Data from Arduino: " + sbprint);
}
break;
}
};
};
}
private void msg(String s)
{
Toast.makeText(getApplicationContext(),s,Toast.LENGTH_LONG).show();
}
private String BuildHourToArduino(){
//>SETH2016122119001004
//>SETHAAAAMMDDHHMMSSWW
Calendar c = Calendar.getInstance();
int DiaSemana = c.get(Calendar.DAY_OF_WEEK);
int Anio = c.get(Calendar.YEAR);
int Mes = c.get(Calendar.MONTH);
int Dia = c.get(Calendar.DAY_OF_MONTH);
int Horas = c.get(Calendar.HOUR_OF_DAY);
int Minutos = c.get(Calendar.MINUTE);
int Segundos = c.get(Calendar.SECOND);
String DateForArduino = String.format(">SETH%1$04d%2$02d%3$02d%4$02d%5$02d%6$02d%7$02d",
Anio, Mes + 1, Dia, Horas, Minutos,Segundos, DiaSemana);
msg(DateForArduino);
return DateForArduino;
}
private void Disconnect()
{
if (btSocket!=null)
{
try
{
btSocket.close();
isBtConnected = false;
}
catch (IOException e)
{ msg("Error");}
}
}
private AdapterView.OnItemClickListener myListClickListener = new AdapterView.OnItemClickListener()
{
public void onItemClick (AdapterView<?> av, View v, int arg2, long arg3) {
if (myBluetoothAdapter.isEnabled()) {
String info = ((TextView) v).getText().toString();
address = info.substring(info.length() - 17);
msg(address);
} else {
msg("El Bluetooth debe de estar encendido.");
}
}
};
public void showBTDialog() {
final AlertDialog.Builder popDialog = new AlertDialog.Builder(this);
final LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
final View Viewlayout = inflater.inflate(paired_devices_list, (ViewGroup) findViewById(R.id.bt_list));
popDialog.setTitle("Dispositivos Bluetooth:");
popDialog.setView(Viewlayout);
myListView = (ListView) Viewlayout.findViewById(R.id.BTList);
BTArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
myListView.setAdapter(BTArrayAdapter);
pairedDevices = myBluetoothAdapter.getBondedDevices();
for(BluetoothDevice device : pairedDevices)
BTArrayAdapter.add(device.getName()+ "\n" + device.getAddress());
myListView.setOnItemClickListener(myListClickListener);
// Button OK
popDialog.setPositiveButton("Conectar",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (address != null)
{
new ConnectBT().execute();
}
dialog.dismiss();
}
});
popDialog.create();
popDialog.show();
}
private class ConnectedThread extends Thread {
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
h.obtainMessage(RECEIVE_MESSAGE, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
break;
}
}
}
public void write(String message) {
byte[] msgBuffer = message.getBytes();
try {
mmOutStream.write(msgBuffer);
} catch (IOException e) {
msg("Error al enviar: " + e.getMessage());
}
}
}
private class ConnectBT extends AsyncTask<Void, Void, Void>
{
private boolean ConnectSuccess = true;
@Override
protected void onPreExecute()
{
progress = ProgressDialog.show(MainActivity.this, "Conectando...", "Espera...!!!");
}
@Override
protected Void doInBackground(Void... devices)
{
try
{
if (btSocket == null || !isBtConnected)
{
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
BluetoothDevice dispositivo = myBluetoothAdapter.getRemoteDevice(address);
btSocket = createBluetoothSocket(dispositivo);
btSocket.connect();
}
}
catch (IOException e)
{
ConnectSuccess = false;
}
return null;
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
if(Build.VERSION.SDK_INT >= 10){
try {
final Method m = device.getClass().getMethod("createInsecureRfcommSocketToServiceRecord", new Class[] { UUID.class });
return (BluetoothSocket) m.invoke(device, myUUID);
} catch (Exception e) {
msg("No se pudo crear la conexion");
}
}
return device.createRfcommSocketToServiceRecord(myUUID);
}
@Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("La conexion falló, intentelo de nuevo");
isBtConnected = false;
}
else
{
msg("Conectado.");
isBtConnected = true;
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
}
progress.dismiss();
}
}
}
Cómo todo el código requiere una explicacion detallada (o si no quieres meterte en programacion), por ahora solo dejo el APK ya compilado,
Los leo luego.
1/26/2017 06:02:00 p.m.
android
,
bluetooth
,
capacitores
,
clock view
,
ds1302
,
electronica basica
,
how to
,
java
,
LED
,
matriz led
,
max7219
,
programacion
,
Resistencias
,
rfcomm
,
socket bluetooth
Vamos a programar #27 - Inútil Apps #2 - Clock View ++
Hola de nuevo a todos, el día de hoy vamos a continuar con el proyecto ClockView. En entregas anteriores, implementamos las funcionalidades básicas, pero ahora vamos a extender un poco más la funcionalidad.
Si has seguido los últimos post, sabrás que todo se retraso por falta de hardware, pero hace un par de días, llegó todo lo necesario. Al inicio no sabia de que forma iba cambiar los ajustes del reloj, la primer opción era usar botones, pero para mi caso concreto, no sería una opción, ya que acabaría desmontando todo el proyecto para hacer otro, además de que todo lo que se ha armado antes es un prototipo, en un futuro cambiare el arduino uno por un arduino nano, ademas de que agregaría 5 matrices más para mostrar todos los datos, en fin, crear un reloj que se pueda colgar en la pared, cosa que no es el caso ahora porque lo tengo instalado en protoboard.
Para poder usarlo de una forma más sencilla, llegué a la conclusión de que la manera más fácil de cambiar los ajustes, es mediante bluetooth.
Para continuar con el proyecto vamos a usar los siguiente materiales en adición a los que ya teníamos:
Para poder usar todos los componentes, vamos a cambiar las conexiones que ya teníamos antes, esto para evitar complicarnos, es cierto que podemos usar más de un Modulo en el mismo pin mediante el uso de SPI (Serial Peripheral Interface), pero cómo este proyecto está diseñado para ser estático, podemos usar todos los pines disponibles.
Hay que recordar que ya hemos definido algunos comandos entonces si queremos omitir o no cambiar su valor, basta con cambiar una letra del inicio. basado en lo estricto que es cada parámetro, entonces para cambiar al formato de 24 horas, hay que recordar que usamos una variable del tipo boolean, al inicio del código se declara y tiene un valor de verdadero (true), para no hacer ningun tipo de cambio, debemos de hacer que el comando que se guarde en la tarjeta SD no tenga la forma correcta. La manera correcta de hacerlo, seria eliminar la linea que lo contiene, pero en su lugar, decidí simplemente escribir "XSETF", al hacer esto, el reloj permanecerá en formato de 24 horas, esto debido a que el código indica eso, para hacer que al momento de encender el reloj este este en formato de 12 horas, debemos de guardar ">SETF" debido a que cada vez que introducimos ese comando, al momento de ser procesado, simplemente se invierte su valor, por lo que si queremos que este sea falso (false) basta que lo guardemos de esa manera.
Para la funcion "SaveSettings" simplemente sobre-escribimos el texto, para el brillo, siempre tendrá la forma: >SETBnn, donde nn es un número entre 1 y 15, luego >SETF, solo si se quiere que cada vez que el reloj encienda, este tenga el formato de 12 horas, y finalmente >DISS que al igual que >SETF solo se debe de escribir así, cuando NO se quiera mostrar los segundos, si se quiere el valor por default, basta con poner "XDISS". El código lo puedes bajar de mi dropbox.
Bien, por ahora es todo, en el siguiente Post veremos cómo controlar ClockView desde nuestro teléfono móvil. Además me enorgullece decir que el primer reto de XWork ha sido completado, en los proximos dias mostrare al ganado y además, lanzaré el segundo reto.
Los leo luego.
Si has seguido los últimos post, sabrás que todo se retraso por falta de hardware, pero hace un par de días, llegó todo lo necesario. Al inicio no sabia de que forma iba cambiar los ajustes del reloj, la primer opción era usar botones, pero para mi caso concreto, no sería una opción, ya que acabaría desmontando todo el proyecto para hacer otro, además de que todo lo que se ha armado antes es un prototipo, en un futuro cambiare el arduino uno por un arduino nano, ademas de que agregaría 5 matrices más para mostrar todos los datos, en fin, crear un reloj que se pueda colgar en la pared, cosa que no es el caso ahora porque lo tengo instalado en protoboard.
Para poder usarlo de una forma más sencilla, llegué a la conclusión de que la manera más fácil de cambiar los ajustes, es mediante bluetooth.
Para continuar con el proyecto vamos a usar los siguiente materiales en adición a los que ya teníamos:
- 1 Módulo bluetooth H06.
- 1 Módulo de tarjeta lector de tarjeta SD.
![]() |
| Módulo bluetooth HC06, se puede conseguir por un par de dolares. |
Ademas haremos uso de la libreria SD.h (ya incluida en la instalacion del arduino IDE), para controlar la tarjeta SD, en está ya se indican cuales son los pines que se usan para el módulo SD. Entonces para poder usar el código, antes vamos a realizar las siguiente conexiones.
- Del módulo SD:
- CLK al pin 13.
- MISO al pin 12.
- MOSI al pin 11.
- CS al pin 10.
- Para las matrices:
- DIN al pin 9.
- CS al pin 8.
- CLK al pin 7.
- Para el módulo de reloj (DS1302):
- CE(RST) al pin 6.
- IO (DAT) al pin 5.
- SCLK (CLK) al pin 4.
- Para el módulo Bluetooth HC06:
- TXD al pin RX (0) del arduino.
- RXD al pin TX (1) del arduino.
Una vez que las conexiones se han realizado, vamos a ver el código que hace funcionar las cosas.
Algunas partes del código fueron tomadas de los ejemplos que se incluyen con las librerías que se usan.
//Clockview 1.0
#include <DS1302.h>
#include "LedControl.h"
#include <SD.h>
/*
Para la conexión del modulo SD se siguen los siguientes:
** MOSI - pin 11
** MISO - pin 12
** CLK - pin 13
** CS - pin 10 - Este es el que se puede cambiar
*/
//Pin SD
int CS_PIN = 10;
//Constantes para los pines usados en la matriz
const int MaxDIn = 9;
const int MaxCS = 8;
const int MaxCLK = 7;
int MaxNDevices = 3;
bool IsConnected = false;
//Constantes para los pines usados en el reloj
const int kCePin = 6; // RST
const int kIoPin = 5; // Dat
const int kSclkPin = 4; // Serial Clock
//Inicializacion de la matriz
//DIN,CLK,CS
LedControl lc = LedControl(MaxDIn, MaxCLK, MaxCS, MaxNDevices);
//Inicializacion del reloj
DS1302 rtc(kCePin, kIoPin, kSclkPin);
//Algunas variables
File Archivo;
char Texto[24];
int MatrixB = 10;
bool H24 = true;
bool HalfSecond = true;
bool IsScreenEnable = true;
bool ShowSeconds = true;
bool SDCardReady = false;
//Matriz con los "Numeros"
const unsigned char Numbers[] = {
B111110, B100010, B111110, //0
B100100, B111110, B100000, //1
B111010, B101010, B101110, //2
B100010, B101010, B111110, //3
B001110, B001000, B111110, //4
B101110, B101010, B111010, //5
B111110, B101010, B111010, //6
B000010, B000010, B111110, //7
B111110, B101010, B111110, //8
B001110, B001010, B111110, //9
B111110, B001010, B001110, //A - 10
B111110, B001100, B111110, //M - 11
B111110, B001010, B001110, //P - 12
B111110, B001000, B111110, //H - 13
B111110 ,B011010, B101110, //R - 14
};
//Definimos simbolos
const unsigned char Symbols[] = {
B0100010, B0010100, B0001000, B1111111, B0101010, B0010100, //BT 0
B0011110, B0100011, B0101101, B0100101, B0100101, B0011110, //Clock Adjust 1
};
//Imprimir simbolos
void PrintSymbol(byte Index,byte SymDevice){
for (int Y = 1; Y < 7; Y++){
lc.setRow(SymDevice, Y, Symbols[Index * 5 + Y - 1]);
}
}
//Funcion para escribir los numero en la matriz.
void PrintNumber(byte NumberOne, byte NumberTwo, byte Device){
for (int X = 1; X < 8; X++){
if (X < 4){
lc.setRow(Device, X, Numbers[NumberOne * 3 + X - 1]);
}
if (X == 4){
lc.setRow(Device, 4, 0);
}
if (X > 4){
lc.setRow(Device, X, Numbers[NumberTwo * 3 + X - 5]);
}
}
}
//Imprimir el tiempo en las matrices y en el monitor serie
void printTime(){
Time t = rtc.time();
const String day = dayAsString(t.day);
char buf[50];
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
PrintNumber(AdjustTime(t.hr, H24) / 10,AdjustTime(t.hr, H24) % 10, 0);
PrintNumber(t.min / 10, t.min % 10, 1);
if (ShowSeconds){
PrintNumber(t.sec / 10, t.sec % 10, 2);
}else{
if(H24)
PrintNumber(13, 14, 2);
if(!H24 && (t.hr-12) < 13)
PrintNumber(10, 11, 2);
if(!H24 && (t.hr-12) > 12)
PrintNumber(10, 12, 2);
}
//PrintSymbol(0, 2);
if (HalfSecond == true){
digitalWrite(3, HIGH);
HalfSecond = false;
}else{
digitalWrite(3, LOW);
HalfSecond = true;
}
Serial.println(buf);
}
//Ajustar la hora
int AdjustTime(int Hour, bool In24Hformat){
if(In24Hformat == true){
return Hour;
}
if(In24Hformat == false && Hour > 12){
Hour = Hour - 12;
return Hour;
}else{
return Hour;
}
}
void SaveSettings(){
Archivo = SD.open("Settings.clv", O_WRITE | O_CREAT);
char SaveBuf[8];
snprintf(SaveBuf, sizeof(SaveBuf), "%s%02d",">SETB", MatrixB);
Serial.println(SaveBuf);
if (Archivo){
Archivo.seek(0);
Archivo.println(SaveBuf);
if(H24)
Archivo.println(">SETF");
else
Archivo.println("XSETF");
if (ShowSeconds)
Archivo.println(">DISS");
else
Archivo.println("XDISS");
Archivo.flush();
Archivo.close();
Serial.println("Guardado");
} else {
Serial.println("error writing test.txt");
}
}
//Cargar los ajustes
void LoadSettings(){
Archivo = SD.open("Settings.clv", FILE_READ);
int B = 0;
byte CurRead;
char SettBuf[22];
if (Archivo) {
while (Archivo.available() > 0){
CurRead = Archivo.read();
if (CurRead != 10 && CurRead != 13){
SettBuf[B] = CurRead;
B++;
Serial.print(B);
}else{
CheckPetition(SettBuf, false);
Serial.print(B);
B = 0;
for (int BF = 0; BF < 22; BF++)
SettBuf[BF]=0;
}
}
Archivo.close();
}else{
Serial.println("error opening file");
}
}
//Comprobar que si hay algun comando
void CheckPetition(char DATA[], bool Save){
int i = 0;
int j = 0;
String Texto(DATA);
//>SETH2016122119001004
if (Texto.startsWith(">DISS")){
ShowSeconds = !ShowSeconds;
if (Save)
SaveSettings();
Serial.print("No/Se muestran los segundos");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, !IsScreenEnable);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SCRA")){
IsScreenEnable = !IsScreenEnable;
Serial.print("Las matrices se apagaron/encendieron");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, !IsScreenEnable);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">RESET")){
SD.remove("Settings.clv");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, !IsScreenEnable);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SETF")){
H24 = !H24;
if (Save)
SaveSettings();
Serial.print("EL reloj cambio de formato 12H-24H");
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SETH")){
AdjustTime(Texto.substring(9, 5).toInt(),Texto.substring(11,9).toInt(),Texto.substring(13, 11).toInt(),
Texto.substring(15, 13).toInt(), Texto.substring(17, 15).toInt(), Texto.substring(19, 17).toInt(),
Texto.substring(21, 19).toInt());
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SETB")){
MatrixB = Texto.substring(5).toInt();
if (Save)
SaveSettings();
Serial.println("El brillo se cambio");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.setIntensity(CurrentDevice, MatrixB);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
else {
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
}
//Convertir los dias
String dayAsString(const Time::Day day){
switch (day){
case Time::kSunday: return "DOM";
case Time::kMonday: return "LUN";
case Time::kTuesday: return "MAR";
case Time::kWednesday: return "MIE";
case Time::kThursday: return "JUE";
case Time::kFriday: return "VIE";
case Time::kSaturday: return "SAB";
}
return "(unknown day)";
}
//Ajustar la hora
void AdjustTime(int Year,int Month, int Day, int Hour, int Minute, int Second, int DayOfWeek){
Time::Day CurrentDay;
switch (DayOfWeek){
case 1:
CurrentDay = Time::kSunday;
break;
case 2:
CurrentDay = Time::kMonday;
break;
case 3:
CurrentDay = Time::kTuesday;
break;
case 4:
CurrentDay = Time::kWednesday;
break;
case 5:
CurrentDay = Time::kThursday;
break;
case 6:
CurrentDay = Time::kFriday;
break;
case 7:
CurrentDay = Time::kSaturday;
break;
}
//Esta parte se usa para actualizar la hora.
rtc.writeProtect(false);
rtc.halt(false);
Time t(Year, Month, Day, Hour, Minute, Second, CurrentDay);
rtc.time(t);
}
//Inicializar la tarjeta SD para usarla
void InitializeSD(){
pinMode(CS_PIN, OUTPUT);
if (SD.begin()){
SDCardReady = true;
Serial.println("La tarjeta SD esta lista");
}else{
SDCardReady = false;
Serial.println("La tarjeta SD no esta lista");
return;
}
}
//Setup
void setup(){
Serial.begin(9600);
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, false);
lc.setIntensity(CurrentDevice, MatrixB);
lc.clearDisplay(CurrentDevice);
}
InitializeSD();
pinMode(3, OUTPUT);
if(SDCardReady){
LoadSettings();
}else{
Serial.println("La tarjeta no está lista");
}
}
//Loop
void loop(){
int i = 0;
printTime();
delay(500);
if (Serial.available()) {
while (Serial.available() > 0) {
Texto[i] = Serial.read();
i++;
}
Texto[i] = '\0';
}
CheckPetition(Texto, true);
}
Al código que teníamos la primera vez lo hemos modificado, las partes que se agregaron fueron las que se encargan de modificar y guardar los ajustes. la funcion "LoadSettings" se encarga de buscar un archivo llamado "Settings.clv" en la tarjeta SD y lo lee, para procesar lo que se lee, va a usar la misma función que se usaba cuando se enviaba un comando por el monitor serie, es decir para que podamos modificar los ajustes desde la tarjeta de memoria, debemos de guardar los comandos; por ejemplo: >SETB15, si lo guardamos en la tarjeta de memoria, al momento de que se carga, la función buscara por la frase ">SETB", cualquier linea que empiece por esa frase, tratará de ser procesada y hay que recordar que solo si después de ">SETB" hay un numero válido entre 1 y 15, solo entonces el valor se pasará para que sea la intensidad del brillo.Hay que recordar que ya hemos definido algunos comandos entonces si queremos omitir o no cambiar su valor, basta con cambiar una letra del inicio. basado en lo estricto que es cada parámetro, entonces para cambiar al formato de 24 horas, hay que recordar que usamos una variable del tipo boolean, al inicio del código se declara y tiene un valor de verdadero (true), para no hacer ningun tipo de cambio, debemos de hacer que el comando que se guarde en la tarjeta SD no tenga la forma correcta. La manera correcta de hacerlo, seria eliminar la linea que lo contiene, pero en su lugar, decidí simplemente escribir "XSETF", al hacer esto, el reloj permanecerá en formato de 24 horas, esto debido a que el código indica eso, para hacer que al momento de encender el reloj este este en formato de 12 horas, debemos de guardar ">SETF" debido a que cada vez que introducimos ese comando, al momento de ser procesado, simplemente se invierte su valor, por lo que si queremos que este sea falso (false) basta que lo guardemos de esa manera.
Para la funcion "SaveSettings" simplemente sobre-escribimos el texto, para el brillo, siempre tendrá la forma: >SETBnn, donde nn es un número entre 1 y 15, luego >SETF, solo si se quiere que cada vez que el reloj encienda, este tenga el formato de 12 horas, y finalmente >DISS que al igual que >SETF solo se debe de escribir así, cuando NO se quiera mostrar los segundos, si se quiere el valor por default, basta con poner "XDISS". El código lo puedes bajar de mi dropbox.
Bien, por ahora es todo, en el siguiente Post veremos cómo controlar ClockView desde nuestro teléfono móvil. Además me enorgullece decir que el primer reto de XWork ha sido completado, en los proximos dias mostrare al ganado y además, lanzaré el segundo reto.
Los leo luego.
1/12/2017 10:35:00 a.m.
Arduino
,
capacitores
,
ds1302
,
electronica basica
,
how to
,
matriz led
,
max7219
,
programacion
,
Resistencias
Vamos a programar #26 - Inútil Apps #2 - Clock View
Hola de nuevo a todos, el día de hoy vamos a continuar con el código de Clock View, la vez anterior solo implementamos las parte mas "criticas" de el, y ya podría considerarse cómo un reloj funcional, pero vamos a agregar unas cuantas funciones para hacerlo más funcional.
Para empezar echemos un vistazo al nuevo código.
Analicemos un poco el código, para empezar, he creado algunas variables que sirven para controlar algunos de los aspectos del reloj. Podemos elegir entre mostrar la hora en formato de 12 o de 24 horas, decidir si se quiere mostrar o no los segundos y ademas, ahora podemos apagar las matrices, útil para cuando llega la hora de dormir.
En la matriz que almacena los datos de los números, ademas de agregar las letras "a", "m" y "p", se agregaron las letras "h" y "r", estas se usan cuando la hora esta en formato de 24 horas y ademas la opción de "no mostrar los segundos" está activa
Para poder mostrar algunas opciones, se han agregado algunos símbolos, pero por ahora no se usan, decidí ponerlos en una matriz a parte para que se puedan modificar sin alterar los numero, ademas estos serán un poco mas "grandes" que los números, lo que hace necesario crear una función aparte para imprimirlos en las matrices.
Para empezar echemos un vistazo al nuevo código.
//Clockview 1.0
#include <DS1302.h>
#include "LedControl.h"
//Constantes para los pines usados en la matriz
const int MaxDIn = 12;
const int MaxCS = 11;
const int MaxCLK = 10;
int MaxNDevices = 3;
bool IsConnected = false;
//Constantes para los pines usados en el reloj
const int kCePin = 7; // RST
const int kIoPin = 8; // Dat
const int kSclkPin = 9; // Serial Clock
//Inicializacion de la matriz
//DIN,CLK,CS
LedControl lc = LedControl(MaxDIn, MaxCLK, MaxCS, MaxNDevices);
//Inicializacion del reloj
DS1302 rtc(kCePin, kIoPin, kSclkPin);
//Algunas variables
char Texto[24];
int MatrixB = 4;
bool H24 = true;
bool HalfSecond = true;
bool IsScreenEnable = true;
bool ShowSeconds = true;
//Matriz con los "Numeros"
const unsigned char Numbers[] = {
B111110, B100010, B111110, //0
B100100, B111110, B100000, //1
B111010, B101010, B101110, //2
B100010, B101010, B111110, //3
B001110, B001000, B111110, //4
B101110, B101010, B111010, //5
B111110, B101010, B111010, //6
B000010, B000010, B111110, //7
B111110, B101010, B111110, //8
B001110, B001010, B111110, //9
B111110, B001010, B001110, //A
B111110, B001100, B111110, //M
B111110, B001010, B001110, //P
B111110, B001000, B111110, //H
B111110 ,B011010, B101110, //R
};
//Definimos simbolos
const unsigned char Symbols[] = {
B0100010, B0010100, B0001000, B1111111, B0101010, B0010100, //BT 0
B0011110, B0100011, B0101101, B0100101, B0100101, B0011110, //Clock Adjust 1
};
//Imprimir simbolos
void PrintSymbol(byte Index,byte SymDevice){
for (int Y = 1; Y < 7; Y++){
lc.setRow(SymDevice, Y, Symbols[Index * 5 + Y - 1]);
}
}
//Funcion para escribir los numero en la matriz.
void PrintNumber(byte NumberOne, byte NumberTwo, byte Device){
for (int X = 1; X < 8; X++){
if (X < 4){
lc.setRow(Device, X, Numbers[NumberOne * 3 + X - 1]);
}
if (X == 4){
lc.setRow(Device, 4, 0);
}
if (X > 4){
lc.setRow(Device, X, Numbers[NumberTwo * 3 + X - 5]);
}
}
}
//Imprimir el tiempo en las matrices y en el monitor serie
void printTime(){
Time t = rtc.time();
const String day = dayAsString(t.day);
char buf[50];
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
PrintNumber(AdjustTime(t.hr, H24) / 10,AdjustTime(t.hr, H24) % 10, 0);
PrintNumber(t.min / 10, t.min % 10, 1);
if (ShowSeconds){
PrintNumber(t.sec / 10, t.sec % 10, 2);
}else{
if(H24)
PrintNumber(13, 14, 2);
if(!H24 && (t.hr-12) < 13)
PrintNumber(10, 11, 2);
if(!H24 && (t.hr-12) > 12)
PrintNumber(10, 12, 2);
}
//PrintSymbol(0, 2);
if (HalfSecond == true){
digitalWrite(13, HIGH);
HalfSecond = false;
}else{
digitalWrite(13, LOW);
HalfSecond = true;
}
Serial.println(buf);
}
//Ajustar la hora
int AdjustTime(int Hour, bool In24Hformat){
if(In24Hformat == true){
return Hour;
}
else{
Hour = Hour - 12;
return Hour;
}
}
void CheckPetition(char DATA[]){
int i = 0;
int j = 0;
String Texto(DATA);
//>SETH2016121221001007
//Bright = Texto.substring(4).toInt();
//MatrixB
if (Texto.startsWith(">DISS")){
ShowSeconds = !ShowSeconds;
Serial.print("No/Se muestran los segundos");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, !IsScreenEnable);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SCRA")){
IsScreenEnable = !IsScreenEnable;
Serial.print("Las matrices se apagaron/encendieron");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, !IsScreenEnable);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SETF")){
H24 = !H24;
Serial.print("EL reloj cambio de formato 12H-24H");
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SETH")){
AdjustTime(Texto.substring(9, 5).toInt(),Texto.substring(11,9).toInt(),Texto.substring(13, 11).toInt(),
Texto.substring(15, 13).toInt(), Texto.substring(17, 15).toInt(), Texto.substring(19, 17).toInt(),
Texto.substring(21, 19).toInt());
Serial.print("La hora se ajusto.");
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
if (Texto.startsWith(">SETB")){
MatrixB = Texto.substring(5).toInt();
Serial.print("El brillo se cambio");
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.setIntensity(CurrentDevice, MatrixB);
}
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
else {
for (j = 0; j < 11; j++) {
DATA[j] = 0;
}
i = 0;
}
}
//Convertir los dias
String dayAsString(const Time::Day day){
switch (day){
case Time::kSunday: return "DOM";
case Time::kMonday: return "LUN";
case Time::kTuesday: return "MAR";
case Time::kWednesday: return "MIE";
case Time::kThursday: return "JUE";
case Time::kFriday: return "VIE";
case Time::kSaturday: return "SAB";
}
return "(unknown day)";
}
//Ajustar la hora
void AdjustTime(int Year,int Month, int Day, int Hour, int Minute, int Second, int DayOfWeek){
Time::Day CurrentDay;
switch (DayOfWeek){
case 1:
CurrentDay = Time::kSunday;
break;
case 2:
CurrentDay = Time::kMonday;
break;
case 3:
CurrentDay = Time::kTuesday;
break;
case 4:
CurrentDay = Time::kWednesday;
break;
case 5:
CurrentDay = Time::kThursday;
break;
case 6:
CurrentDay = Time::kFriday;
break;
case 7:
CurrentDay = Time::kSaturday;
break;
}
//Esta parte se usa para actualizar la hora.
rtc.writeProtect(false);
rtc.halt(false);
Time t(Year, Month, Day, Hour, Minute, Second, CurrentDay);
rtc.time(t);
}
//Setup
void setup(){
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++){
lc.shutdown(CurrentDevice, false);
lc.setIntensity(CurrentDevice, MatrixB);
lc.clearDisplay(CurrentDevice);
}
pinMode(13, OUTPUT);
Serial.begin(9600);
}
//Loop
void loop(){
int i = 0;
printTime();
delay(500);
if (Serial.available()) {
while (Serial.available() > 0) {
Texto[i] = Serial.read();
i++;
}
Texto[i] = '\0';
}
CheckPetition(Texto);
}
Analicemos un poco el código, para empezar, he creado algunas variables que sirven para controlar algunos de los aspectos del reloj. Podemos elegir entre mostrar la hora en formato de 12 o de 24 horas, decidir si se quiere mostrar o no los segundos y ademas, ahora podemos apagar las matrices, útil para cuando llega la hora de dormir.
En la matriz que almacena los datos de los números, ademas de agregar las letras "a", "m" y "p", se agregaron las letras "h" y "r", estas se usan cuando la hora esta en formato de 24 horas y ademas la opción de "no mostrar los segundos" está activa
![]() |
| La opción de 24 horas y la opción de "No mostrar los segundos" activos. |
![]() |
| La opción de 24 horas no está activa y la opción de no mostrar los segundos tampoco. |
//Imprimir simbolos
void PrintSymbol(byte Index,byte SymDevice){
for (int Y = 1; Y < 7; Y++){
lc.setRow(SymDevice, Y, Symbols[Index * 5 + Y - 1]);
}
}
Cómo notarás, la mayor parte del código es similar a la función "PrintNumber", solo que en este caso, lee completamente de 5 en 5 y no de 3 en tres como en la función para mostrar los números. Recibe cómo parámetros, el indice en donde se encuentra la primera fila a desplegar y ademas, también recibe en que numero de matriz se va a mostrar el resultado.
La función "PrintTime" se ha modificado para que la hora se muestre de acuerdo a las opciones que el usuario haya pedido, en los casos anteriores, para mostrar la información de un formato u otro, solo basta con que se le mande un comando para que se hagan los cambios pertinentes. Toda la parte de los comandos lo veremos un poquito más adelante.
//Imprimir el tiempo en las matrices y en el monitor serie
void printTime(){
Time t = rtc.time();
const String day = dayAsString(t.day);
char buf[50];
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",
day.c_str(), t.yr, t.mon, t.date, t.hr, t.min, t.sec);
PrintNumber(AdjustTime(t.hr, H24) / 10,AdjustTime(t.hr, H24) % 10, 0);
PrintNumber(t.min / 10, t.min % 10, 1);
if (ShowSeconds){
PrintNumber(t.sec / 10, t.sec % 10, 2);
}else{
if(H24)
PrintNumber(13, 14, 2);
if(!H24 && (t.hr-12) < 13)
PrintNumber(10, 11, 2);
if(!H24 && (t.hr-12) > 12)
PrintNumber(10, 12, 2);
}
//PrintSymbol(0, 2);
if (HalfSecond == true){
digitalWrite(13, HIGH);
HalfSecond = false;
}else{
digitalWrite(13, LOW);
HalfSecond = true;
}
Serial.println(buf);
}
Los cambios que se hicieron, son prácticamente los que indican el despliegue de la información, los nuevos "if" solo controlan que es lo que se debe de mostrar.
Cómo mencione en hace un poco, se han añadido algunos comandos que se usaran para modificar las propiedades del reloj sin la necesidad de re-compilar el código cada vez, actualmente los comandos disponibles son los siguientes:
- >DISS (Display Sesconds) - Intercambia entre mostrar o no los segundos.
- >SCRA (Screen Active) - Apaga o enciende las matrices.
- >SETF (Set Format) - Intercambia entre el formato de 12/24 horas.
- >SETHYYYYMMDDHHmmSSdd (Set Hour) - Cambia la hora del reloj, donde YYYY es el año, MM son los meses, DD son los días, HH son las horas en formato de 24 horas, mm son los minutos, SS los segundos y dd es el dia de la semana del 1 al 7 en donde el día 1 es domingo.
- >SETBxx (Set Brightness) - Cambia el brillo de las matrices, en donde xx es un valor que este entre el rango de 1 a 15, donde 1 es lo menos brillantes y 15 es el máximo.
Algo importante por mencionar es que todos los comados se enviaran por la interfaz serial, por lo que se puede usar el monitor serial del IDE de arduino u otros métodos que veremos un poco después.
Cuando se quiere ajustar la hora, podemos usar el comando ">SETH", si por ejemplo queremos establecer la siguiente hora:20:30:45 Miércoles 28 de diciembre del 2016, entonces el comando deberá de tener el siguiente aspecto. ">SETH2016122820304504". Si la hora que se quiere ingresar tiene un formato incorrecto, el reloj mostrará las 00:00:00 del 1/1/2000 domingo. si eso llegará a pasar, se corrige cuando se ingresa un fecha válida.
Para el caso del brillo, cualquier valor fuera de los limites validos (1-15) hará que las matrices tengan el brillo más bajo.
Por ultimo, se ha agregado una función que prende y apaga el LED que está conectado al PIN 13, esto con la finalidad de que se use como indicador, la mayoría de los relojes digitales, tiene un par de puntos entre cada par de dígitos que prenden y apagan cada segundo, si se quiere mostrar algo similar, bastara con conectar LED al pin 13.
Este reloj está lejos de ser terminado por completo, pero por ahora es todo, si en el transcurso de la semana llegan los otros componentes que quiero agregar, la semana que viene, veremos cómo agregar un medio para que todas las configuraciones que se cambien, queden guardadas y así si por alguna razón se quiere desconectar todo el proyecto, no se tendrán que hacer cambios a los ajustes cada vez.
Ademas de que agregaremos una solución "móvil" para que el reloj se pueda controlar a distancia.
Y bien, por ahora es todo, el código completo actualizado, cómo siempre, lo puedes descargar de mi dropbox.
Por ahora es todo. Los leo luego.
12/15/2016 04:49:00 p.m.
Arduino
,
DIY
,
ds1302
,
electronica basica
,
how to
,
LED
,
matriz led
,
max7219
,
programacion
Vamos a programar #25 - Inútil Apps #2 - Clock View
Hola a todos, el día de hoy vamos a realizar otro pequeño proyecto con arduino, es muy simple en realidad, pero creo que sirve para reforzar lo básico, además, si cómo yo, eres fanático de los LED's de seguro este proyecto te encantará.
Cuando hice el proyecto para mostrar la información de ITunes en las matrices LED, usaba una librería que se encargaba de desplegar las letras, los números y además, también proporcionaba algunos efectos básicos: scroll a la derecha, scroll a la izquierda, etc.
Para está ocasión, vamos a hacer algo un poco más sencillo, porque me parece un desperdicio de recursos utilizar toda la librería que use en el proyecto antes dicho para mostrar la hora.
Para los componentes de hoy vamos a requerir:
El primer parámetro indica en que dirección se encuentra la matriz que queremos usar (de cero a siete), es decir, si tenemos 4 matrices conectadas en "serie", y queremos prender el primer led de la tercera matriz, tendremos que poner un 3 en el primer parametro.
El segundo parámetro indica en que columna está el LED que queremos encender (mejor dicho controlar).
El tercero indica en que columna está el LED que queremos controlar.
El último parametro indica el estado en que vamos a poner el LED, cuando se pone "True", el LED se enciende y cuando se pone "False", el LED se apaga.
Está funcion recibe 3 parametros, el primero es el mismo que el de la funcion anterior, el segundo indica que fila es la que se va controlar, despues, el ultimo parametro nos indica que LED´s son los que se van a prender.Para este último, hay una forma relativamente sencilla de cómo establecer los LED´s que deben de prender, tomando por ejemplo el numero 2 y el número 5 que queremos mostrar,
Antes que nada, es importante tomar en cuenta donde se ubica el origen, en mi caso (y supongo que para los que tienen un kit similar al que uso yo), el origen se encuentra en la esquina inferior izquierda, viendo la matriz como en la primer imagen, por lo que las columnas están en el lado izquierdo de la matriz y las filas en el lado inferior, entonces los LED's se controlaran de abajo hacia arriba y de izquierda a derecha si usamos la funcion "setRow". una vez que ya has determinado donde empieza la matriz, se deben de hacer los cambios pertinentes.
Para asignar el ultimo parámetro, miremos la imagen anterior, en ella se puede ver claramente que cuando un led está encendido tiene el valor de 1 y cuando está apagado es 0 y cada digito esta compuesto por 3 llamadas a la funcion "setRow", para hacer de forma rapida el dos, podriamos llamar a la función "setRow" y como ultimo parámetro el valor "B00011101" en la primera llamada, en la segunda, el ultimo parametro "B00010101" y en la tercera llamada a la función usar cómo ultimo valor "B00010111".
Cómo los 0´s que están al lado izquierdo no son significativos, podemos omitirlos y simplemente poner "B11101" para la primer llamada a la funcion "setRow", si te fijas en el código, veras que hay algunos valores que conservan los ceros a la izquierda, esto solo es con fines "estéticos" y para que todos los valores estén alineados.
Cuando hice el proyecto para mostrar la información de ITunes en las matrices LED, usaba una librería que se encargaba de desplegar las letras, los números y además, también proporcionaba algunos efectos básicos: scroll a la derecha, scroll a la izquierda, etc.
Para está ocasión, vamos a hacer algo un poco más sencillo, porque me parece un desperdicio de recursos utilizar toda la librería que use en el proyecto antes dicho para mostrar la hora.
Para los componentes de hoy vamos a requerir:
- Un arduino Uno/Mega/Nano.
- Un protoboard.
- Dos o más matrices led con driver Max7219.
- Modulo de reloj en tiempo real con DS1302.
- Liberia "LedControl.h"
- Liberia "DS1302.h"
- Algunos cables jumper para hacer las conexiones.
- Un par de manos (o en su defecto una).
Las conexiones.
Lo primero que debemos de hacer las conexiones entre los componentes. Yo en mi caso voy a usar 3 matrices LED, justo ahora compre más por internet, pero como van a tardar mas de 15 días en llegar, solo usaré las que tengo disponibles.
Las conexiones que voy a poner en este post lo más seguro es que cambien un poco en futuras actualizaciones del proyecto, por lo que si quieres usar pines diferentes en el arduino, eres libre de hacerlo.
Para empezar, vamos a conectar las matrices de izquierda a derecha, es decir si miramos de frente, la primer matriz estará al lado izquierdo, y la ultima estará al lado derecho.
Las conexiones de la matriz que se conecta al arduino irán de las siguiente manera:
- VCC. Se conecta a +5 voltios.
- GND. Se conecta a tierra.
- DIN. Lo conectaremos al pin 12 del arduino.
- CS. Lo conectaremos al pin 11 del arduino.
- CLK. Lo conectaremos al pin 10 del arduino.
- VCC. Se conecta a VCC en la entrada de la siguiente matriz.
- GND. Se conecta a tierra.
- DIN. Lo conectaremos a DIN en la entrada de la siguiente matriz.
- CS. Lo conectaremos a CS en la entrada de la siguiente matriz.
- CLK. Lo conectaremos CLK en la entrada de la siguiente matriz.
Para el modulo de reloj, las conexiones se harán de la siguiente manera:
- VCC. Se conecta a +5 voltios.
- GND. Se conecta a tierra.
- CLK (Serial clock). Lo conectaremos al pin 9 del arduino.
- DAT (IO). Lo conectaremos al pin 8 del arduino.
- RST (Chip enable). Lo conectaremos al pin 7 del arduino.
El código en C.
Primero vamos a ver el código fuente completo y después explicare cada una de las partes que lo compone.
//Clockview 1.0
#include <DS1302.h>
#include "LedControl.h"
//Constantes para los pines usados en la matriz
const int MaxDIn = 12;
const int MaxCS = 11;
const int MaxCLK = 10;
int MaxNDevices = 3;
//Constantes para los pines usados en el reloj
const int kCePin = 7; // RST
const int kIoPin = 8; // Dat
const int kSclkPin = 9; // Serial Clock
//Inicializacion de la matriz
//DIN,CLK,CS
LedControl lc = LedControl(MaxDIn, MaxCLK, MaxCS, MaxNDevices);
//Inicializacion del reloj
DS1302 rtc(kCePin, kIoPin, kSclkPin);
//Algunas variables
int MatrixB = 1;
//Matriz con los "Numeros"
const unsigned char Numbers[] = {
B11111, B10001, B11111, //0
B10010, B11111, B10000, //1
B11101, B10101, B10111, //2
B10001, B10101, B11111, //3
B00111, B00100, B11111, //4
B10111, B10101, B11101, //5
B11111, B10101, B11101, //6
B00001, B00001, B11111, //7
B11111, B10101, B11111, //8
B00111, B00101, B11111, //9
B11111, B00101, B00111, //A
B11111, B01100, B11111, //M
B11111, B00101, B00111, //P
};
//Funcion para escribir los numero en la matriz.
void PrintNumber(byte NumberOne, byte NumberTwo, byte Device){
for (int X = 1; X < 8; X++){
if (X < 4){
lc.setRow(Device, X, Numbers[NumberOne * 3 + X - 1]);
}
if (X == 4){
lc.setRow(Device, 4, 0);
}
if (X > 4){
lc.setRow(Device, X, Numbers[NumberTwo * 3 + X - 5]);
}
}
}
//Imprimir el tiempo en las matrices y en el monitor serie
void printTime(){
Time t = rtc.time();
char buf[10];
snprintf(buf, sizeof(buf), "%02d:%02d:%02d", t.hr, t.min, t.sec);
PrintNumber(t.hr / 10, t.hr % 10, 0);
PrintNumber(t.min / 10, t.min % 10, 1);
PrintNumber(t.sec / 10, t.sec % 10, 2);
Serial.println(buf);
}
//Convertir los dias
String dayAsString(const Time::Day day) {
switch (day){
case Time::kSunday: return "Sunday";
case Time::kMonday: return "Monday";
case Time::kTuesday: return "Tuesday";
case Time::kWednesday: return "Wednesday";
case Time::kThursday: return "Thursday";
case Time::kFriday: return "Friday";
case Time::kSaturday: return "Saturday";
}
return "(unknown day)";
}
//Setup
void setup(){
for (int CurrentDevice = 0; CurrentDevice < MaxNDevices; CurrentDevice++)
{
lc.shutdown(CurrentDevice, false);
lc.setIntensity(CurrentDevice, MatrixB);
lc.clearDisplay(CurrentDevice);
}
Serial.begin(9600);
//Esta parte se usa para actualizar la hora.
//rtc.writeProtect(false);
//rtc.halt(false);
//Time t(2016, 12, 7, 23, 57, 00, Time::kWednesday);
//rtc.time(t);
}
//Loop
void loop() {
printTime();
delay(1000);
}
Lo primero que hacemos es incluir las librerías "LedControl.h" y "DS1302.h", creamos constantes para los pines que usara la primer matriz, para el reloj y después creamos los objetos "lc" y "rtc" para la matriz y para el reloj respectivamente.
El objeto lc se le asigna un objeto "LedControl"; el cual recibe cuatro parámetros: los números de pines a usar, el primer parámetro debe de ser el pin que se usará para conectará a "DIN" en la primer matriz, el segundo conectará a "CLK", el tercero conectará a "CS" y finalmente el cuarto, sirve para indicar cuantas matrices se usarán con ese objeto.
Para el reloj, crearemos un objeto "DS1302" y para "inicializarlo", le pasaremos como parámetros, los pines que se usarán. El primer parámetro es el pin que conecta a "RST", el segundo parámetro es el pin que conecta a "DAT" y finalmente el tercero es el pin que conecta "CLK".
Una vez que tenemos lo objetos listos, creamos unas variables, la primera es "MatrixB" que las usaremos para almacenar el brillo que tendrán las matrices, por ahora la única forma de cambiarlo, es editando el valor que le asignamos, pero un poco mas adelante, seremos capaces de cambiar el brillo de forma externa.
Después viene una matriz que contiene los datos que vamos a usar para crear los "números" que después veremos en las matrices, pero antes de eso hay que saber como es que se controlan los LED´s de las matrices.
El objeto lc se le asigna un objeto "LedControl"; el cual recibe cuatro parámetros: los números de pines a usar, el primer parámetro debe de ser el pin que se usará para conectará a "DIN" en la primer matriz, el segundo conectará a "CLK", el tercero conectará a "CS" y finalmente el cuarto, sirve para indicar cuantas matrices se usarán con ese objeto.
Para el reloj, crearemos un objeto "DS1302" y para "inicializarlo", le pasaremos como parámetros, los pines que se usarán. El primer parámetro es el pin que conecta a "RST", el segundo parámetro es el pin que conecta a "DAT" y finalmente el tercero es el pin que conecta "CLK".
Una vez que tenemos lo objetos listos, creamos unas variables, la primera es "MatrixB" que las usaremos para almacenar el brillo que tendrán las matrices, por ahora la única forma de cambiarlo, es editando el valor que le asignamos, pero un poco mas adelante, seremos capaces de cambiar el brillo de forma externa.
Después viene una matriz que contiene los datos que vamos a usar para crear los "números" que después veremos en las matrices, pero antes de eso hay que saber como es que se controlan los LED´s de las matrices.
LedControl y Matrices LED.
Para este proyecto estamos usando la librería LEdControl.h, está nos ofrece varias maneras de controlar los LED's de la matriz, las funciones disponibles son: setLed, setRow y setColum.
La función setLed tiene una forma similar a la siguiente:
void setLed(int addr, int row, int col, boolean state);
El segundo parámetro indica en que columna está el LED que queremos encender (mejor dicho controlar).
El tercero indica en que columna está el LED que queremos controlar.
El último parametro indica el estado en que vamos a poner el LED, cuando se pone "True", el LED se enciende y cuando se pone "False", el LED se apaga.
void setRow(int addr, int row, byte value);
![]() |
| Como lucirá el numero 25 |
Para asignar el ultimo parámetro, miremos la imagen anterior, en ella se puede ver claramente que cuando un led está encendido tiene el valor de 1 y cuando está apagado es 0 y cada digito esta compuesto por 3 llamadas a la funcion "setRow", para hacer de forma rapida el dos, podriamos llamar a la función "setRow" y como ultimo parámetro el valor "B00011101" en la primera llamada, en la segunda, el ultimo parametro "B00010101" y en la tercera llamada a la función usar cómo ultimo valor "B00010111".
Cómo los 0´s que están al lado izquierdo no son significativos, podemos omitirlos y simplemente poner "B11101" para la primer llamada a la funcion "setRow", si te fijas en el código, veras que hay algunos valores que conservan los ceros a la izquierda, esto solo es con fines "estéticos" y para que todos los valores estén alineados.
Mostrando dígitos en las matrices.
Para mostrar los dígitos en las matrices, he creado una función que se encarga de eso. La función "PrintNumber", recibe tres parámetros, el primero es el primer numero que queremos mostrar (al lado izquierdo), el segundo es el numero que queremos mostrar y finalmente,se debe de indicar en que numero de matriz vamos a despegarlos.
Todos los datos de los numero están pensados de tal forma que se puedan poner dos dígitos por cada matriz, entonces cada una nos da un rango de 00 a 99, pero para mostrar algo cómo la hora. los segundos o los minutos funciona. Para que la función "funcione", debemos de alinear los datos que componen a cada numero, si te fijas bien leemos de tres en tres y debido al acomodo que tiene la matriz "Numbers", cuando le pedimos el número 0, leerá los valores Numbers[0], Numbers[1] y Numbers[2].
La formula que dexcribe cómo se obtienen los valores del primer dígito es la siguiente:
Indice = NumeroDado * 3 +ValorDelIterador - 1Y para el segundo:
Indice = NumeroDado * 3 +ValorDelIterador - 5Y con eso, podemos obtener los valores del 0 al 9 y a partir de ahi, componer cualquier numero. Por eso es importante el orden en que está cada parte de la matriz (arreglo desde este momento para evitar confusiones.).
Completando el resto del código.
La función "PrintTime" se encargará de obtener la hora y de llamar a la función "PrintNumber" para desplegar la información en la matriz LED, debido a que hay que pasar los dígitos por separado, no es posible usar "12" cómo parámetro para la función "PrintNumber", entonces lo que hacemos es dividir, primero entre 10 y para el segundo dígito, solo tomamos el residuo de la división, por lo que si tenemos el numero 21, al hacer la división entre 10, obtenemos 2; este lo pasamos cómo primer parámetro y luego obtenemos el residuo que es 1 y lo asignamos como valor del segundo parámetro, ademas de que la hora la mostramos en el monitor serie, eso es opcional pero para fines de debug funciona.
Después viene la parte de las funciones propias del arduino, "setup()" y "loop()", En la parte de setup, es donde vamos a inicializar los componentes (prácticamente aquí todo lo que se necesita ejecutar una sola vez), ademas hay unas lineas que están comentadas, estas solo sirven para ajustar la hora del reloj, si es la primera vez que vas a usar el modulo de reloj, o si cambias la batería o hiciste cualquier cosa y quieres establecer la fecha y hora, esas lineas las debes de des-comentar y editar solo la que contiene la fecha y hora, cuando hayas cargado el proyecto al arduino, si modificas alguna parte del código y ya no quieres actualizar la hora, debes de comentar de nuevo esas lineas para evitar que la hora se cambie de nueva cuenta.
Finalmente en "loop()" ponemos el código que se va a ejecutar de manera cíclica, en este caso, solo es la función que muestra la hora y un retraso de 1000ms que se usa para que la hora solo se actualice cada segundo.
Y bien, por ahora es todo, pero en el próximo post vamos a agregar un poco mas de hardware para que el uso sea mas sencillo. Cómo siempre, el código lo puedes bajar de mi dropbox para que lo revises.
Por ahora es todo. Los leo luego.
12/08/2016 12:13:00 p.m.
Arduino
,
capacitores
,
DIY
,
ds1302
,
electronica basica
,
matriz led
,
max7219
,
programacion
,
Resistencias
Suscribirse a:
Entradas
(
Atom
)















