Proyecto 29 - OPTREX DMF-50773NF-FW LCD Module
En tutoriales anteriores vimos como mostrar gráficos en displays de 240x64 pixels.
El modelo con el que vamos a trabajar hoy es un OPTREX DMF-50773NF-FW-ACE de 240x128 pixels. Utiliza el controlador Toshiba T6963C y por suerte para nosotros es compatible con la librería u8glib.
La forma de proceder es la misma que en los proyectos 13.1 y 13.2. Se instala la librería y se desmarca el constructor correspondiente al controlador utilizado en el módulo LCD.
Proyecto 29.1 X-Ray Generator Interface
Esquema
La conexión de este módulo es un poco más complicada que el POWERTIP utilizado en proyectos anteriores. Esto se debe a que necesita de tres tensiones para funcionar.
Una alimentación de +5V proporcionada por Arduino para las señales lógicas, otra de +12V para el CCFL Backlit, que es un pequeño tubo fluorescente para retroiluminar el panel y una tercera alimentación negativa de aproximadamente -13,5V para en LCD. Nada que no se pueda solucionar con la fuente de laboratorio que hicimos en el Proyecto 28.
Otra solución es conectar los +12V del Inverter, al pin VIN del Arduino y con los +5V del regulador interno alimentar el LCD.
Para más detalles consultad el datasheet al final de la página.
Sketch
La imagen que se muestra más abajo corresponde con un diseño propio y simplificado de la interfaz de un generador de Rayos-X. De momento es sólo una imagen .bmp que he subido al LCD pero con el tiempo espero hacerlo realidad.
No lo incluyo aquí el sketch por ser muy extenso. Se puede descargar al final de la página.
Proyecto 29.2 - RTC with Meteo Icons
En los siguientes ejemplos de aplicación del módulo OPTREX DMF-50773NF-FW-ACE conectaremos un RTC DS3231. Puedes descargar la librería del RTC aquí.
En un primer ejemplo mostraremos la fecha, la hora y la temperatura. Y en un segundo sketch voy a incluir varios iconos meteorológicos.
Esquema
El esquema de conexión es prácticamente igual que el ejemplo anterior, solo hay que cambiar la señal READ del pin A4 al D3 para poder conectar el RTC en los pines SDA y SCL del Arduino.
Sketch nº 1
/*
Real Time Clock with Graphic LCD Module OPTREX DMF-50773NF-FW-ACE
https://sites.google.com/site/angmuz/
_______________________________
RTC with Graphic LCD Module
OPTREX DMF-50773NF-FW-ACE
Sabado 12 Diciembre 2015
1:14:40
Temperatura 23.5ºC
Proyectos con Arduino
sites.google.com/site/angmuz
______________________________
Se ha cambiado el pin RD A4(18) en el original por D3, para dejar libres las entradas SDA y SCL
Universal 8bit Graphics Library, http://code.google.com/p/u8glib/
Copyright (c) 2012, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "U8glib.h"
#include "ds3231.h"
#include <Wire.h>
#define BUFF_MAX 128
uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;
U8GLIB_T6963_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 3, 16);
// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=3, reset=16
void draw(void) {
// graphic commands to redraw the complete screen should be placed here
u8g.setFont(u8g_font_unifont);
u8g.drawStr( 0, 11, " RTC with Graphic LCD Module");
u8g.drawStr( 0, 25, " OPTREX DMF-50773NF-FW-ACE");
char in;
char tempF[6];
float temperature;
char buff[BUFF_MAX];
unsigned long now = millis();
struct ts t;
// show time once in a while
//if ((now - prev > interval) && (Serial.available() <= 0)) {
DS3231_get(&t); //Get time
parse_cmd("C",1);
temperature = DS3231_get_treg(); //Get temperature
dtostrf(temperature, 5, 1, tempF);
// dia de la semana
u8g.setPrintPos(0, 53);
printDay(t.wday);
// dia del mes
u8g.setPrintPos(72, 53);
u8g.print(t.mday);
// mes
u8g.setPrintPos(100, 53);
printMonth(t.mon);
// año
u8g.setPrintPos(180, 53);
u8g.print(t.year);
// hora
if(t.hour<10)
{
u8g.setPrintPos(8, 67);//
u8g.print(t.hour);
}
else
{
u8g.setPrintPos(0, 67);
u8g.print(t.hour);
}
u8g.setPrintPos(16, 67);
u8g.print(":");
if(t.min<10)
{
u8g.setPrintPos(20, 67);
u8g.print("0");
u8g.setPrintPos(28, 67);
u8g.print(t.min);
}
else
{
u8g.setPrintPos(22, 67);
u8g.print(t.min);
}
u8g.setPrintPos(38, 67);
u8g.print(":");
if(t.sec<10)
{
u8g.setPrintPos(48, 67);
u8g.print("0");
u8g.setPrintPos(56, 67);
u8g.print(t.sec);
}
else
{
u8g.setPrintPos(48, 67);
u8g.print(t.sec);
}
// temperatura
u8g.setPrintPos(0, 82);
u8g.print("Temperatura");
u8g.setPrintPos(96, 82);
u8g.print(tempF);
u8g.setPrintPos(140, 82);
u8g.print((char)176);
u8g.setPrintPos(145, 82);
u8g.print("C");
// creditos
u8g.setPrintPos(0, 109);
u8g.print(" Proyectos con Arduino");
u8g.setPrintPos(0, 124);
u8g.print(" sites.google.com/site/angmuz");
//prev = now;
//}
if (Serial.available() > 0) {
in = Serial.read();
if ((in == 10 || in == 13) && (recv_size > 0)) {
parse_cmd(recv, recv_size);
recv_size = 0;
recv[0] = 0;
} else if (in < 48 || in > 122) {; // ignore ~[0-9A-Za-z]
} else if (recv_size > BUFF_MAX - 2) { // drop lines that are too long
// drop
recv_size = 0;
recv[0] = 0;
} else if (recv_size < BUFF_MAX - 2) {
recv[recv_size] = in;
recv[recv_size + 1] = 0;
recv_size += 1;
}
}
}
void setup(void) {
Serial.begin(9600);
Wire.begin();
DS3231_init(DS3231_INTCN);
memset(recv, 0, BUFF_MAX);
// (seconds,minutes,hour,week day,date, month,year)
// parse_cmd("T004300631102015",16);
// flip screen, if required
// u8g.setRot180();
// set SPI backup if required
//u8g.setHardwareBackup(u8g_backup_avr_spi);
// assign default color value
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
}
void loop(void) {
// picture loop
u8g.firstPage();
do {
draw();
} while( u8g.nextPage() );
// rebuild the picture after some delay
delay(50);
}
void parse_cmd(char *cmd, int cmdsize)
{
uint8_t i;
uint8_t reg_val;
char buff[BUFF_MAX];
struct ts t;
//snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
//Serial.print(buff);
// TssmmhhWDDMMYYYY aka set time
if (cmd[0] == 84 && cmdsize == 16) {
//T355720619112011
t.sec = inp2toi(cmd, 1);
t.min = inp2toi(cmd, 3);
t.hour = inp2toi(cmd, 5);
t.wday = inp2toi(cmd, 6);
t.mday = inp2toi(cmd, 8);
t.mon = inp2toi(cmd, 10);
t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
DS3231_set(t);
//Serial.println("OK");
} else if (cmd[0] == 49 && cmdsize == 1) { // "1" get alarm 1
DS3231_get_a1(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 50 && cmdsize == 1) { // "2" get alarm 1
DS3231_get_a2(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 51 && cmdsize == 1) { // "3" get aging register
//Serial.print("aging reg is ");
//Serial.println(DS3231_get_aging(), DEC);
} else if (cmd[0] == 65 && cmdsize == 9) { // "A" set alarm 1
DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
//ASSMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
}
byte flags[5] = { 0, 0, 0, 0, 0 };
DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
DS3231_get_a1(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 66 && cmdsize == 7) { // "B" Set Alarm 2
DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
//BMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
}
byte flags[5] = { 0, 0, 0, 0 };
DS3231_set_a2(time[0], time[1], time[2], flags);
DS3231_get_a2(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 67 && cmdsize == 1) { // "C" - get temperature register
//Serial.print("temperature reg is ");
//Serial.println(DS3231_get_treg(), DEC);
} else if (cmd[0] == 68 && cmdsize == 1) { // "D" - reset status register alarm flags
reg_val = DS3231_get_sreg();
reg_val &= B11111100;
DS3231_set_sreg(reg_val);
} else if (cmd[0] == 70 && cmdsize == 1) { // "F" - custom fct
reg_val = DS3231_get_addr(0x5);
//Serial.print("orig ");
//Serial.print(reg_val,DEC);
//Serial.print("month is ");
//Serial.println(bcdtodec(reg_val & 0x1F),DEC);
} else if (cmd[0] == 71 && cmdsize == 1) { // "G" - set aging status register
DS3231_set_aging(0);
} else if (cmd[0] == 83 && cmdsize == 1) { // "S" - get status register
//Serial.print("status reg is ");
//Serial.println(DS3231_get_sreg(), DEC);
} else {
//Serial.print("unknown command prefix ");
//Serial.println(cmd[0]);
//Serial.println(cmd[0], DEC);
}
}
void printDay(int wday)
{
switch(wday)
{
case 1: u8g.print("Lunes");break;
case 2: u8g.print("Martes");break;
case 3: u8g.print("Miercoles");break;
case 4: u8g.print("Jueves");break;
case 5: u8g.print("Viernes");break;
case 6: u8g.print("Sabado");break;
case 7: u8g.print("Domingo");break;
default: u8g.print("Error");break;
}
}
void printMonth(int month)
{
switch(month)
{
case 1: u8g.print("Enero");break;
case 2: u8g.print("Febrero");break;
case 3: u8g.print("Marzo");break;
case 4: u8g.print("Abril");break;
case 5: u8g.print("Mayo");break;
case 6: u8g.print("Junio");break;
case 7: u8g.print("Julio ");break;
case 8: u8g.print("Agosto");break;
case 9: u8g.print("Septiempre");break;
case 10: u8g.print("Octubre");break;
case 11: u8g.print("Noviembre");break;
case 12: u8g.print("Diciembre");break;
default: u8g.print("Error");break;
}
}
Seguidamente podéis ver una imagen con el resultado.
Sketch nº 2
/*
Real Time Clock with Graphic LCD Module OPTREX DMF-50773NF-FW-ACE
https://sites.google.com/site/angmuz/
_______________________________
RTC with Graphic LCD Module
OPTREX DMF-50773NF-FW-ACE
Sabado 12 Diciembre 2015
1:14:40
Temperatura 23.5ºC
Proyectos con Arduino
sites.google.com/site/angmuz
______________________________
Se ha cambiado el pin RD A4(18) en el original por D3, para dejar libres las entradas SDA y SCL
Universal 8bit Graphics Library, http://code.google.com/p/u8glib/
Copyright (c) 2012, olikraus@gmail.com
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "U8glib.h"
#include "ds3231.h"
#include <Wire.h>
#define BUFF_MAX 128
uint8_t time[8];
char recv[BUFF_MAX];
unsigned int recv_size = 0;
unsigned long prev, interval = 1000;
U8GLIB_T6963_240X128 u8g(8, 9, 10, 11, 4, 5, 6, 7, 14, 15, 17, 3, 16);
// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7, cs=14, a0=15, wr=17, rd=3, reset=16
#define u8g_logo_width 240
#define u8g_logo_height 64
//static unsigned char u8g_logo_bits[] = {
static unsigned char u8g_logo_bits[] U8G_PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x70, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xf0, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xe0, 0x01, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x00, 0x3c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x7c, 0x00, 0x3c, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xfe, 0x07, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xfc, 0x0f, 0x3e, 0x00, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0x00,
0x00, 0xfc, 0x01, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x87, 0xff, 0x1f, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x0e, 0xff, 0x3f, 0x1c, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00,
0x00, 0xf8, 0x03, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x0f, 0x00, 0x00,
0x00, 0xf0, 0x03, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x1f, 0x00, 0x00,
0x00, 0xe0, 0x83, 0xff, 0xc1, 0x07, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xff, 0xfb, 0x3f, 0x00, 0x00,
0x00, 0xc0, 0xe1, 0xff, 0x87, 0x03, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0xfe, 0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0xfc, 0x03, 0x00, 0x00, 0xe0, 0x3f, 0xc0, 0x7f, 0x00, 0x00,
0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x03, 0xf8, 0x01, 0x00, 0x00, 0x80, 0xff, 0xff, 0x07, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0xf8, 0xff, 0x1f, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x07, 0xf0, 0x03, 0x00, 0x00, 0xc0, 0xff, 0xff, 0x0f, 0xe0, 0x07, 0x00, 0x00, 0xf0, 0x03, 0x00, 0xfe, 0x00, 0x00,
0x00, 0x00, 0xfc, 0xff, 0x3f, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xfe, 0x0f, 0xf0, 0x03, 0x00, 0x00, 0xe0, 0xff, 0xfd, 0x1f, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x03, 0x00, 0xf8, 0x7f, 0x00,
0x00, 0x00, 0xfe, 0x81, 0x7f, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0xf0, 0x1f, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x1f, 0xe0, 0x3f, 0xc0, 0x07, 0x00, 0x00, 0xf8, 0x01, 0x00, 0xf8, 0xff, 0x01,
0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfc, 0x03, 0xc0, 0x3f, 0xe0, 0xc3, 0x3f, 0x00, 0xf8, 0x07, 0x80, 0x7f, 0xc0, 0x87, 0x7f, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0xff, 0x03,
0x00, 0x00, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x3f, 0xe0, 0xc3, 0x3f, 0x00, 0xf8, 0x01, 0x00, 0x7f, 0xc0, 0x87, 0x7f, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0xff, 0x07,
0x00, 0x00, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0xff, 0xc3, 0x3f, 0x00, 0xfc, 0x01, 0x00, 0xfc, 0xff, 0x87, 0x7f, 0x00, 0x7c, 0x00, 0x00, 0xe0, 0xff, 0x0f,
0x00, 0x00, 0x1f, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xfe, 0xff, 0xc3, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0xfc, 0xff, 0x87, 0x7f, 0x00, 0x7c, 0x00, 0x00, 0x60, 0xe0, 0x1f,
0xf0, 0x0f, 0x1f, 0x00, 0xf8, 0xf0, 0x0f, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x1f,
0xf0, 0x0f, 0x1f, 0x00, 0xf8, 0xf0, 0x0f, 0x00, 0x3f, 0x00, 0x00, 0xfc, 0xff, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0xf8, 0xff, 0x07, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3f,
0xf0, 0x0f, 0x1f, 0x00, 0xf8, 0xf0, 0x0f, 0x00, 0x1f, 0x00, 0x00, 0xf8, 0xff, 0x03, 0x00, 0x00, 0x3e, 0x00, 0x00, 0xf0, 0xff, 0x07, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3f,
0xf0, 0x0f, 0x1f, 0x00, 0xf8, 0xf0, 0x0f, 0x00, 0x1f, 0x00, 0x00, 0x18, 0xf8, 0x07, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x30, 0xf0, 0x0f, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x1f, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0xff, 0x00, 0x3e,
0x00, 0x00, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x7c, 0x00, 0xe0, 0xff, 0x00, 0x3e,
0x00, 0x00, 0x3f, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x7f, 0x00, 0x3e,
0x00, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x7f, 0x00, 0x3e,
0x00, 0x00, 0xfe, 0x81, 0x7f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf8, 0x01, 0xf0, 0x3f, 0x00, 0x3e,
0x00, 0x00, 0xfc, 0xe7, 0x3f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x1f, 0x00, 0x3e,
0x00, 0x00, 0xf8, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x03, 0xf8, 0x1f, 0x00, 0x3f,
0x00, 0x00, 0xf0, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xf0, 0x0f, 0xf8, 0x0f, 0x80, 0x1f,
0x00, 0xc0, 0xe1, 0xff, 0x87, 0x03, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0xe0, 0x3f, 0xfc, 0x0f, 0xe0, 0x1f,
0x00, 0xe0, 0x83, 0xff, 0xc1, 0x07, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0xc0, 0x7f, 0xfc, 0x07, 0xf0, 0x0f,
0x00, 0xf0, 0x03, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x80, 0x7f, 0xfc, 0xff, 0xf9, 0x07,
0x00, 0xf8, 0x03, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0xfc, 0x03, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00, 0x00, 0x3f, 0xfe, 0xff, 0xfd, 0x03,
0x00, 0xfc, 0x01, 0x00, 0x80, 0x3f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xe0, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0xfe, 0xff, 0xfe, 0x01,
0x00, 0xfc, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xe0, 0x87, 0x01, 0x60, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x30, 0xfe, 0x7f, 0x7e, 0x00,
0x00, 0x7c, 0x00, 0x3c, 0x00, 0x3e, 0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0xc3, 0x03, 0xf0, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00,
0x00, 0x38, 0x00, 0x3c, 0x00, 0x1c, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0xe3, 0x07, 0xf8, 0xf1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf8, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x1f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf8, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void draw(void) {
// graphic commands to redraw the complete screen should be placed here
u8g.drawXBMP( 0, 64, u8g_logo_width, u8g_logo_height, u8g_logo_bits);
u8g.setFont(u8g_font_unifont);
char in;
char tempF[6];
float temperature;
char buff[BUFF_MAX];
unsigned long now = millis();
struct ts t;
// show time once in a while
//if ((now - prev > interval) && (Serial.available() <= 0)) {
DS3231_get(&t); //Get time
parse_cmd("C",1);
temperature = DS3231_get_treg(); //Get temperature
dtostrf(temperature, 5, 1, tempF);
// dia de la semana
u8g.setPrintPos(0, 11);
printDay(t.wday);
// dia del mes
u8g.setPrintPos(72, 11);
u8g.print(t.mday);
// mes
u8g.setPrintPos(100, 11);
printMonth(t.mon);
// año
u8g.setPrintPos(180, 11);
u8g.print(t.year);
// hora
if(t.hour<10)
{
u8g.setPrintPos(8, 25);//
u8g.print(t.hour);
}
else
{
u8g.setPrintPos(0, 25);
u8g.print(t.hour);
}
u8g.setPrintPos(16, 25);
u8g.print(":");
if(t.min<10)
{
u8g.setPrintPos(20, 25);
u8g.print("0");
u8g.setPrintPos(28, 25);
u8g.print(t.min);
}
else
{
u8g.setPrintPos(22, 25);
u8g.print(t.min);
}
u8g.setPrintPos(38, 25);
u8g.print(":");
if(t.sec<10)
{
u8g.setPrintPos(48, 25);
u8g.print("0");
u8g.setPrintPos(56, 25);
u8g.print(t.sec);
}
else
{
u8g.setPrintPos(48, 25);
u8g.print(t.sec);
}
// temperatura
u8g.setPrintPos(0, 40);
u8g.print("Temperatura");
u8g.setPrintPos(96, 40);
u8g.print(tempF);
u8g.setPrintPos(140, 40);
u8g.print((char)176);
u8g.setPrintPos(145, 40);
u8g.print("C");
// creditos
u8g.setPrintPos(0, 60);
u8g.print(" Lunes Martes Mierc. Jueves");
//prev = now;
//}
if (Serial.available() > 0) {
in = Serial.read();
if ((in == 10 || in == 13) && (recv_size > 0)) {
parse_cmd(recv, recv_size);
recv_size = 0;
recv[0] = 0;
} else if (in < 48 || in > 122) {; // ignore ~[0-9A-Za-z]
} else if (recv_size > BUFF_MAX - 2) { // drop lines that are too long
// drop
recv_size = 0;
recv[0] = 0;
} else if (recv_size < BUFF_MAX - 2) {
recv[recv_size] = in;
recv[recv_size + 1] = 0;
recv_size += 1;
}
}
}
void setup(void) {
Serial.begin(9600);
Wire.begin();
DS3231_init(DS3231_INTCN);
memset(recv, 0, BUFF_MAX);
// (seconds,minutes,hour,week day,date, month,year)
// parse_cmd("T004300631102015",16);
// flip screen, if required
// u8g.setRot180();
// set SPI backup if required
//u8g.setHardwareBackup(u8g_backup_avr_spi);
// assign default color value
if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
u8g.setColorIndex(255); // white
}
else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3); // max intensity
}
else if ( u8g.getMode() == U8G_MODE_BW ) {
u8g.setColorIndex(1); // pixel on
}
else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
u8g.setHiColorByRGB(255,255,255);
}
}
void loop(void) {
// picture loop
u8g.firstPage();
do {
draw();
} while( u8g.nextPage() );
// rebuild the picture after some delay
delay(50);
}
void parse_cmd(char *cmd, int cmdsize)
{
uint8_t i;
uint8_t reg_val;
char buff[BUFF_MAX];
struct ts t;
//snprintf(buff, BUFF_MAX, "cmd was '%s' %d\n", cmd, cmdsize);
//Serial.print(buff);
// TssmmhhWDDMMYYYY aka set time
if (cmd[0] == 84 && cmdsize == 16) {
//T355720619112011
t.sec = inp2toi(cmd, 1);
t.min = inp2toi(cmd, 3);
t.hour = inp2toi(cmd, 5);
t.wday = inp2toi(cmd, 6);
t.mday = inp2toi(cmd, 8);
t.mon = inp2toi(cmd, 10);
t.year = inp2toi(cmd, 12) * 100 + inp2toi(cmd, 14);
DS3231_set(t);
//Serial.println("OK");
} else if (cmd[0] == 49 && cmdsize == 1) { // "1" get alarm 1
DS3231_get_a1(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 50 && cmdsize == 1) { // "2" get alarm 1
DS3231_get_a2(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 51 && cmdsize == 1) { // "3" get aging register
//Serial.print("aging reg is ");
//Serial.println(DS3231_get_aging(), DEC);
} else if (cmd[0] == 65 && cmdsize == 9) { // "A" set alarm 1
DS3231_set_creg(DS3231_INTCN | DS3231_A1IE);
//ASSMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // ss, mm, hh, dd
}
byte flags[5] = { 0, 0, 0, 0, 0 };
DS3231_set_a1(time[0], time[1], time[2], time[3], flags);
DS3231_get_a1(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 66 && cmdsize == 7) { // "B" Set Alarm 2
DS3231_set_creg(DS3231_INTCN | DS3231_A2IE);
//BMMHHDD
for (i = 0; i < 4; i++) {
time[i] = (cmd[2 * i + 1] - 48) * 10 + cmd[2 * i + 2] - 48; // mm, hh, dd
}
byte flags[5] = { 0, 0, 0, 0 };
DS3231_set_a2(time[0], time[1], time[2], flags);
DS3231_get_a2(&buff[0], 59);
//Serial.println(buff);
} else if (cmd[0] == 67 && cmdsize == 1) { // "C" - get temperature register
//Serial.print("temperature reg is ");
//Serial.println(DS3231_get_treg(), DEC);
} else if (cmd[0] == 68 && cmdsize == 1) { // "D" - reset status register alarm flags
reg_val = DS3231_get_sreg();
reg_val &= B11111100;
DS3231_set_sreg(reg_val);
} else if (cmd[0] == 70 && cmdsize == 1) { // "F" - custom fct
reg_val = DS3231_get_addr(0x5);
//Serial.print("orig ");
//Serial.print(reg_val,DEC);
//Serial.print("month is ");
//Serial.println(bcdtodec(reg_val & 0x1F),DEC);
} else if (cmd[0] == 71 && cmdsize == 1) { // "G" - set aging status register
DS3231_set_aging(0);
} else if (cmd[0] == 83 && cmdsize == 1) { // "S" - get status register
//Serial.print("status reg is ");
//Serial.println(DS3231_get_sreg(), DEC);
} else {
//Serial.print("unknown command prefix ");
//Serial.println(cmd[0]);
//Serial.println(cmd[0], DEC);
}
}
void printDay(int wday)
{
switch(wday)
{
case 1: u8g.print("Lunes");break;
case 2: u8g.print("Martes");break;
case 3: u8g.print("Miercoles");break;
case 4: u8g.print("Jueves");break;
case 5: u8g.print("Viernes");break;
case 6: u8g.print("Sabado");break;
case 7: u8g.print("Domingo");break;
default: u8g.print("Error");break;
}
}
void printMonth(int month)
{
switch(month)
{
case 1: u8g.print("Enero");break;
case 2: u8g.print("Febrero");break;
case 3: u8g.print("Marzo");break;
case 4: u8g.print("Abril");break;
case 5: u8g.print("Mayo");break;
case 6: u8g.print("Junio");break;
case 7: u8g.print("Julio ");break;
case 8: u8g.print("Agosto");break;
case 9: u8g.print("Septiempre");break;
case 10: u8g.print("Octubre");break;
case 11: u8g.print("Noviembre");break;
case 12: u8g.print("Diciembre");break;
default: u8g.print("Error");break;
}
}
Una imagen del reloj con los iconos meteorológicos
Special thanks to:
Olikraus for the U8g Arduino Monochrom Graphics Library.
Petre Rodan for the arduino library for DS3231 RTC.
Adam Whitcroft for the weather icons.
Puedes descargar el proyecto completo en un zip aquí abajo.