Aventuras y Desventuras de un hobbyist

Aventuras y Desventuras de un hobbyist....

Vinciduino-Cargar bootloader con Arduino UNO.

Para realizar la  carga del bootloader en una placa Vinciduino con un Arduino UNO/Diecimila necesitaremos lo siguiente:

1.       Hardware.

a.       Arduino UNO +cable usb

b.      Vinciduino  +cable usb

c.       Cable para conectar Arduino UNO con el ISP de Vinciduino. (6 cables macho por un lado hembra por otro)





d.      Ordenador.

2.       Software.

a.       Arduino IDE 21 o 22(testeado con ambos)


c.       Arduino v 1.00 RC2.

d.      SO Windows 7.



Primero necesitaremos tener instalada la versión Arduino IDE 21 y Arduino IDE 1.00 RC2.

Ahora necesitamos añadir este archivo ArduinoISPleonardo en el folder “examples” de Arduino IDE 21.




Ahora conectamos nuestro Arduino UNO  abrimos Arduino IDE 21 seleccionamos en Tools.

Bord= Arduino UNO

Serial Port= COM del Arduino

Abrimos y  cargamos  el sketch que hemos añadido en “examples”




Para estar completamente seguros de que nuestro hardware es decir la placa Vinciduino esta con funcionando correctamente debemos hacer la siguiente comprobación:


Enchufar la placa Vinciduino mediante un cable USB al ordenador, si todo esta correcto veremos el siguiente mensaje:




<<Para las personas que hayan soldado las placas:
Es muy importante realizar la comprobación descrita arriba antes de iniciar la carga del bootloader ya que hay la posibilidad de pensar que el proceso de cargar el bootloader no funciona cuando en realidad lo que no funciona es nuestro hardware debido a soldaduras mal hechas o componentes mal ubicados>>

El siguiente paso es conectar nuestro Arduino UNO a Vinciduino.

Mediante el  conector ISP solo y únicamente ya que he intentado hacerlo como se hace con Arduinos (http://arduino.cc/es/Tutorial/ArduinoISP)y no funciona. 








Una vez que tenemos la conexión como en la imagen de arriba procedemos a cerrar ArduinoIDE 21 y abrir Arduino 1.00 RC2. En “Tools” seleccionamos:

Board= Arduino Leonardo

Serial Port = COM del Arduino

Programmer = Arduino as ISP



Una vez tengamos todos los settings procedemos a cargar el bootloder:








Presionamos el botón de reset de la  Vinciduino(para ponerlo en modo bootloader) he inmediatamente hacemos click en “Burn Bootloader”.



















Entonces los leds rx,tx y “L” de Arduino UNO parpadearan intermitente durante aproximadamente 1 minuto. Si todo va bien recibiremos la confirmación:










El Paso siguiente es conectar el Vinciduino a nuestro ordenador mediante usb, he probado en dos ordenadores con Windows 7 y en ningún caso reconoce el driver automáticamente por lo que deberemos instalarlo. Debemos ir a al administrador de dispositivos de Windows :


















Hacemos click derecho en  Leonardo y actulizamos el controlador seleccionando la siguiente ruta que esta en  la ruta donde hemos instalado Arduino 1.00 RC2.

En mi caso:

C:\Users\yopero\Desktop\arduino-1.0-rc2\drivers













Finalmente volvemos a verificar en el administrador de dispositivos:





Vinciduino


He empezado a colaborar con el Vinciduino team.(https://bitbucket.org/fmalpartida/vinciduino/wiki/Bienvenido)


El objetivo es la creación de un nuevo clon de arduino Leonardo usando un ATmega32U4 y componentes SMD.


El objetivo de este grupo es tratar de llevar el open hardware un paso mas allá del estado existente. 
  • Cualquiera puede ir a la página de la placa y descargarse el esquemático, layout o los ficheros de fabricación para mandar a un fabricante de PCBs, en nuestro caso hemos usado ITEAD para la primera versión de la placa, donde por menos de 30 euros te dan 10 placas con un acabado profesional.
  • Una vez encargadas las placas se va a un distribuidor de componentes electrónicos y se carga el carrito de la compra, donde en un click de ratón conseguimos todos los componentes necesarios. Cualquiera que no tenga unos conocimientos medios en electrónica no sabrá seleccionar los componentes para montar la placa, por lo que si queremos que la difusión de la placa sea máxima hay que facilitar un carrito, a la vez que sirve para ver el coste de la placa.
  • Recibidos las placas y componentes cualquiera se la puede montar siguiendo elesquema de montaje, descargar el entorno Arduino o de Atmel para programar la placa teniendo un foro donde preguntar dudas y compartir ideas/proyectos. 


Aqui un par de fotos de mi Vinciduino montado, aunque todavia no he probado el bootloader o arduino IDE. Debo confesar que es muy gratificante tener una de estas placas montadas, hasta ahora me habia dedicado a crear mis PCB y el acabado no tiene nada que ver, con un placa realizada por maquinas hasta soldar SMD se hace muy facil.




DomoLeroyDuino

Sistema de control de encendido y apagado de dispositivos eléctricos a través de control remoto. Se trata de un sistema que se compone de uno o varios receptores (enchufes, interruptores y portalámparas) y un mando a distancia. Los enchufes de esta gama permiten dos funciones: la de encendido y apagado de los dispositivos eléctricos conectados al enchufe. El mando a distancia de esta serie permite el encendido y apagado de 8 líneas de enchufes, esto lo he comprado en Leroy Merlin y vienen en packs de 3 enchufes y un mando.

Para poder controlar esos enchufes necesitamos integrar arduino al control remoto existente.
Dicho control remoto consta de 2 botones de encendido( 1 y 2) y dos botones de apagado (1 y 2) además de un mini interruptor de  4 posiciones  A,B,C y D.
 Es decir que por cada canal seleccionado podemos controlar dos enchufes haciendo un total de 8.
Para controlar los 8 enchufes necesitamos por tanto 8 pines de Arduino:
  1. Seleccionar canal A
  2. Seleccionar canal B
  3. Seleccionar canal C
  4. Seleccionar canal D
  5. Encender 1
  6. Apagar 1
  7. Encender 2
  8. Apagar 2
 Por ejemplo:
Para encender el 1 en el canal A, ordenaremos Arduino  encender el pin del Canal A + el pin de Encender 1.
Para apagar el 2 en el canal B, ordenaremos Arduino encender el pin del Canal D + el pin de Apagar 2

Aun no tengo decidido como controlar los encendidos y las posibilidades son las siguientes:
  • Ethernet Shield.
  • RTC Real time clock, con el que dejare todo programado en el atmega.
  • A través de un PC enviando comandos via Serial port.
Luego de las consideraciones teóricas es hora de encender nuestro multímetro y ponernos a investigar como funciona el control remoto.
Los botones de encendido son simples de controlar usando un relé o un transistor(x4).
 El mini interruptor de 4 posiciones requiere un poco mas de trabajo ya que la forma en que se conecta (ver foto detalle en la parte inferior derecha:



















Cuando esta en posición A conecta GND con la linea de A (dos patillas) esto lo podríamos solventar con un relé pero las lineas(ABCD) deben estar aisladas ya que si hay contacto entre ellas solo el canal A estaría disponible.Mi solución es tener una linea de control para cada patilla haciendo un total de 8 controles aislados aunque luego en el arduino solo necesitaremos 4 ordenes ya que activaremos dos con un solo pin pero estas deben estar aisladas.
Había pensado en usar relés pero al pensar que necesito 12 me parece que ocupara mucho sitio, otra posible solución es usar un multiplexer 74hc585 o 12 transistores NPN.
Yo lo haré con 12 transistores y el circuito es el siguiente. Muy importante conectar el GND del mando remoto y de Arduino.


Update:

La aplicación para el control domotico ya esta terminada y testeada, simplemente queda determinar que items controlar .
La aplicación esta hecha en python :




Agitador para etching v.1 part 2

No te olvides leer la parte 1 :  http://yopero-tech.blogspot.com/2011/10/agitador-para-etching.html

Siguiendo con este proyecto una vez recibido el Attiny85 he decido montar la placa en una stripboard de 11*11.

Abajo el detalle del circuito completo:



Y aquí el mapa de donde cortar las lineas  y puentes:


Y aquí el detalle de la parte de los componentes:


La carga del codigo en el Attiny85 la he realizado utilizando el siguiente link donde se explica muy claramente los pasos a seguir:
http://txapuzas.blogspot.com/2009/12/paperattinyprogrammer-un-programador.html

El código que he cargado en el Attiny85 es el siguiente:

// Arduino Code:
// etching agitator by yOPERO
//ATTiny45

void setup () {
pinMode(2, OUTPUT);  
   pinMode ( 0 , OUTPUT ) ; // tell Arduino to use pin 0 as OUTPUT
   pinMode ( 1 , OUTPUT ) ; // tell Arduino to use pin 1 as OUTPUT
   // you can use other outputs, they must support PWM
}

void loop () {

    
    digitalWrite(2, HIGH);   // set the LED on
    izquierda();
  delay(500);
    paro();
    delay(200);
  derecha();
  delay(500);
  paro(); 
  delay(3000); 
}
   

void izquierda() {
  analogWrite ( 0 , 150 ) ; // run motor one way half speed
   analogWrite ( 1 , 0   ) ;
}
void derecha() {
analogWrite ( 0 , 0 ) ; // run motor one way half speed
   analogWrite ( 1 , 150   ) ;
}
void paro() {
 analogWrite ( 0 , 0 ) ; // stops motor
   analogWrite ( 1 , 0 ) ;
}




Finalmente aqui las fotos del con el resultado final:





 

..y un pequeño video del invento funcionando:

Agitador para etching v.1


Luego de un largo periodo de no escribir  pero que he continuado experimentando me dispongo a hacer una herramienta indispensable para el hobbyist; un agitador para etching.


Ya sabéis que cuando queremos realizar una PCB personalizada a nuestros requerimientos tenemos que pedirlas a un fabricante enviándole nuestro diseño, esto sería viable para cuando se necesita hacer una cierta cantidad de PCBs pero cuando solo es una y al menos yo por temas de economía me la fabrico en casa.


Transfiero el diseño a la placa de cobre mediante el método de la plancha y luego procedo a hacer el etching o tratamiento químico de la placa, para ello uso Cloruro Férrico. El procedimiento debemos de hacerlo al aire libre y de ser posible debemos subir la temperatura del cloruro férrico y agitar el recipiente. 


Suena fácil eh?? Pues luego de hacer unas cuantas placas eso de estar moviendo el recipiente es un poco engorroso y aburrido, en el mercado existen agitadores comerciales que hacen que el cloruro férrico este en movimiento y así el etching es mas rápido y efectivo. 
Rapidamente me he hecho un modelo en Sketchup para tener las ideas claras.



Aprovechando que me he encontrado con dos motores DC de unos descolgadores eléctricos de teléfono. 


Los reciclare para hacerme un "etching agitator".


Mi idea es poner un motor en cada extremo del recipiente para que empuje el recipiente hacia el otro lado. Servo 1 envía recipiente a la izquierda luego baja y Servo 2 envía recipiente a la derecha luego baja así sucesivamente. 

Para mantener el recipiente usare dos guías laterales y probablemente algo en la base para un movimiento más suave. 


Para controlar ambos servos usare un Attiny 85(si es que llega desde China) caso contrario un Atmega168 aunque me da pena dejar muchos pines sin uso, cualquiera de los anteriores  con Arduino bootloader  y un h-Briged modelo L293D.





El código que usaré sera el siguiente:
//
/*
 *  CIRC-22 Controlling Motors (L293D)
 * 
 * A demo program which demonstrates how to control two
 * DC motors
 * For more details and links visit: http://tinyurl.com/nsuwln
 */
 
 
//L293 Pin assignments


//Motor one
int enable12 = 9;  //bridge 1 and 2 enable (pin 1 on the 16 pin IC) 
                   //pull this pin HIGH to turn the outputs on and LOW to turn them off
                   //using PWM on this puin will control speed
int in1      = 2;  //in1 (out1 will be HIGH when set HIGH and LOW when set LOW) (pin 2 on the 16 pin IC)
int in2      = 3;  //in2 (out2 will be HIGH when set HIGH and LOW when set LOW) (pin 7 on the 16 pin IC)

//Motor two
int enable34 = 10;  //bridge 1 and 2 enable (pin 1 on the 16 pin IC)
                    //pull this pin HIGH to turn the outputs on and LOW to turn them off
                    //using PWM on this puin will control speed
int in3      = 4;  //in1 (out1 will be HIGH when set HIGH and LOW when set LOW) (pin 2 on the 16 pin IC)
int in4      = 5;  //in2 (out2 will be HIGH when set HIGH and LOW when set LOW) (pin 7 on the 16 pin IC)


void setup(){
  pinMode(enable12, OUTPUT);  //Set the three pins for bridge 1 & 2 to outputs
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);

  pinMode(enable34, OUTPUT);  //Set the three pins for 3 & 4 to outputs
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);  
}

void loop(){
  setSpeedMotorOne(255);     //Set the speed of motor one 255 = on 0 = off (simply a call to analogWrite on enable12 pin)
  setSpeedMotorTwo(255);     //Set the speed of motor two 255 = on 0 = off (simply a call to analogWrite on enable34 pin)  
  motorOneForward();         //Spin motor one forwards (set one bridge HIGH and the other LOW)
  motorTwoBackward();        //Spin motor two backwards (set one bridge LOW and the other HIGH)
  delay(1000);               //wait for a second
  brakeMotorOne();           //by leaving the bridge on the motors are braked (stop quicker than setting the speed to zero) (sets both sides of the bridge to LOW)
  brakeMotorTwo();           //by leaving the bridge on the motors are braked (stop quicker than setting the speed to zero) (sets both sides of the bridge to LOW)
  delay(1000);               //wait for a second
  motorOneBackward();        //Spin motor one backwards (set one bridge LOW and the other HIGH)
  motorTwoForward();         //Spin motor two forwards (set one bridge HIGH and the other LOW)
  delay(1000);               //wait for a second
  setSpeedMotorOne(0);       //Set the speed of motor one 255 = on 0 = off (simply a call to analogWrite on enable12 pin)
  setSpeedMotorTwo(0);       //Set the speed of motor two 255 = on 0 = off (simply a call to analogWrite on enable34 pin)    
  delay(1000);               //wait for a second  
}

////// Motor One Routines  ////////////

void motorOneForward(){
 digitalWrite(in1, LOW); 
 digitalWrite(in2, HIGH); 
}

void motorOneBackward(){
 digitalWrite(in1, HIGH); 
 digitalWrite(in2, LOW); 
}   

void setSpeedMotorOne(int newSpeed){
  analogWrite(enable12, newSpeed);
}

void brakeMotorOne(){
 digitalWrite(in3, LOW); 
 digitalWrite(in4, LOW); 
} 

////// Motor Two Routines  ////////////

void motorTwoForward(){
 digitalWrite(in3, LOW); 
 digitalWrite(in4, HIGH); 
}

void motorTwoBackward(){
 digitalWrite(in3, HIGH); 
 digitalWrite(in4, LOW); 
}   

void setSpeedMotorTwo(int newSpeed){
  analogWrite(enable34, newSpeed);
}

void brakeMotorTwo(){
 digitalWrite(in1, LOW); 
 digitalWrite(in2, LOW); 
}   
Y este el esquema de conexión del L293D

Tennis/Padel Scoreboard

Video del funcionamiento del Tennis/Padel  Scoreboard

Update 19/09/2011:
Finalmente luego de mucho trabajo en Eagle tengo terminada la pcb ArduScore v.1 lista para etching.






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

Hardware:
 











Debido a diferencias de opinion con unos amigos cuando jugamos al padel, he decido montar un Scoreboard o Marcador Digital para padel/tennis.

Mi idea para el hardware es la siguiente:


Como siempre empezare a hacer el montaje en un breadboard, mi intencion es tener el software  antes de lanzarme con el hardware para lo cual utilizare una breadboard con cuatro pulsadores y el serial como pantalla para ver los resultados.

2 pulsadores para cada equipo, optare por wireless cuando ya tenga todo funcionando. Un pulsador da puntos (+) y el otro quita(-).

La pantalla debera mostrar 5 columnas y dos filas, seguro que hare todo con leds.

columna 1 =set 1
columna 2 =set 2
columna 3 = set 3
columna 5y4 = puntos que se juegan.
Antes de empezar a programar le he dado unas cuantas vueltas para ser exacto muchas vueltas.

Finalmente os presento mi razonamiento inicial:

Para comenzar necesitare ver los puntajes como 0, 15, 30 y 40 dado que no son proporcionales los pondre como text strings.
Internamente representaremos los puntajes como dos variables (0, 0) osea "0 - 0", (1 ,0) osea "15 - 0", (1 , 3) osea "15 - 40"

Ahora viene la parte dificil que es manejar el tema de Ventaja/Deuce. Cambiaremos de dos variables a una; -1 es ventaja para el Player1, +1 es ventaja para el Player2 y 0 significa Deuce.

Hay dos maneras de ganar el juego, el primer modo  seria si uno de los Players  llega a 4 y el otro es 2 o menos (60 -30), el segundo modo es cuando el valor es o -2 o +2

El cambio del primer modo  a "Ventaja/Deuce" ocurre cuando el puntaje es (3 ,3) (40-40)

Para introducir los puntos usare 4 pulsadores:
  • Pulsador 1 = Añade puntos al player1
  • Pulsador 2 = Quita puntos al player1
  • Pulsador 3 = Añade puntos al player2
  • Pulsador 4 = Quita puntos al player2

IOT



Sen.se embeded:




Arduino Radiofrecuencia II

En una entrada anterior hice un pequeño experimento con radiofrecuencia con unas luces a control remoto de los chinos, esta vez realizare un montaje de 2 Arduinos  uno receptor y otro emisor.
El emisor tendrá 4 botones que enviaran datos según su estado (high,low) con lo que tendremos 8 valores que serán enviamos en forma de letras a,b,c,d,e,f,g,h,i. Luego la decodificación y posteriores comportamientos serán hechos en el Arduino  con el receptor.
En esta ocasión usare una libreria para Arduino llamada Virtual wire con un emisor y receptor de Aurel:




El código para el emisor seria el siguiente
 
// transmitter.pde
//
// Simple example of how to use VirtualWire to transmit messages
// Implements a simplex (one-way) transmitter with an TX-C1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: transmitter.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $


#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);      // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);     // Bits per sec
}

void loop()
{
    const char *msg = "hello";

    digitalWrite(13, true); // Flash a light to show transmitting
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); // Wait until the whole message is gone
    digitalWrite(13, false);
    delay(200);
}


y el código para el receptor:

// receiver.pde
//
// Simple example of how to use VirtualWire to receive messages
// Implements a simplex (one-way) receiver with an Rx-B1 module
//
// See VirtualWire.h for detailed API docs
// Author: Mike McCauley (mikem@open.com.au)
// Copyright (C) 2008 Mike McCauley
// $Id: receiver.pde,v 1.3 2009/03/30 00:07:24 mikem Exp $

#include 

void setup()
{
    Serial.begin(9600); // Debugging only
    Serial.println("setup");

    // Initialise the IO and ISR
    vw_set_ptt_inverted(true); // Required for DR3100
    vw_setup(2000);  // Bits per sec

    vw_rx_start();       // Start the receiver PLL running
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;

    if (vw_get_message(buf, &buflen)) // Non-blocking
    {
 int i;

        digitalWrite(13, true); // Flash a light to show received good message
 // Message with a good checksum received, dump it.
 Serial.print("Got: ");
 
 for (i = 0; i < buflen; i++)
 {
     Serial.print(buf[i], HEX);
     Serial.print(" ");
 }
 Serial.println("");
        digitalWrite(13, false);
    }
}

Real Time clock para Arduino(DS1307)

El uso de un reloj es fundamental en algunos procesos con nuestro arduino especialmente cuando queremos enviar datos usando cualquier protocolo.
El reloj nos servira  para no tener simplemente datos sino saber cuando se han relalizado dichos cambios en los inputs.
Para este proyecto necesitaremos lo siguiente:
  • Arduino
  • Cristal de quarzo de 32.768 kHz
  • MAXIM DS1307
  • Socket de 8 pines
  • CR2032 3v bateria
  • CR2032 PCB socket
  • 2* resistencias de 2.2K.
  • Perfboard.
El diagrama es el siguiente:

    Luego de soldar el resultado es este:



    El código al final del post.

    Mas datos:

    El DS1307 es un reloj/calendario de bajo consumo con 56 bytes SRAM. El reloj/calendario nos da segundos, minutos, horas, dias y años. La fecha al finla del mes is automaticamente ajustada para meses con menos de 31 dias. El DS1307 funciona como esclavo en el us I2C . Se obtine acceso implementando una condición START y dando un codigo de identificación (0x68) seguido por una dirección registrada asi registros subsecuentes puenden ser accedidos secuencialmente. El DS1307 vienen en un 8-pin dip package. 

    Bit 7 del registro 0 es el clock halt (CH) bit. Cuando este bit  se cambia a 1, el oscilador se deshabilitathe y si vuelve a 0, el oscilador se habilita. Si no se cambia a 0 el reloj no funcionara.

    Ds1307 pin out
    Solo los primeros 8 bytes (0x00 - 0x07) son usados por el reloj y los otros 56 se usan com RAM adicional.
    DESCRIPCIÓN DE PINES
    Pins 1, 2 para el cristal de quarzo 32.768kHz no se necesita capacitor.
    Pin 3 VBAT Bateria de backup de 3v.
    Pin 4 GND Ground
    Pin 5 SDA Serial Data Input/Output. SDA es el data input/output para la interface I2C y requiere una resistencia pull-up Arduino pin 4.
    Pin 6 SCL Serial Clock Input. SCL  es el input del reloj para el  I2C y es usado para sincronizar el movimiento de datos en el puerto serie . Arduino pin 5.
    7 SWQ/OUT Square Wave/Output Driver. cuando esta habilitado el  SQWE bit  con valor 1,  SQW/OUT pin outputs uno de cuatro square-wave frecuencias (1Hz, 4kHz, 8kHz, 32kHz). El SQW/OUT pin requiere una resistencia pull-up. SQW/OUT Funciona con  VCC o VBAT . Un LED y 220 ohm resistencia en series conectada a VCC produce 1 HZ blink.  Esta es una buena forma de saber si el reloj esta funcionando.
    8 VCC (5 volts)


    //
    // Maurice Ribble
    // 4-17-2008
    // http://www.glacialwanderer.com/hobbyrobotics
    
    // This code tests the DS1307 Real Time clock on the Arduino board.
    // The ds1307 works in binary coded decimal or BCD.  You can look up
    // bcd in google if you aren't familior with it.  There can output
    // a square wave, but I don't expose that in this code.  See the
    // ds1307 for it's full capabilities.
    
    #include "Wire.h"
    #define DS1307_I2C_ADDRESS 0x68
    
    // Convert normal decimal numbers to binary coded decimal
    byte decToBcd(byte val)
    {
      return ( (val/10*16) + (val%10) );
    }
    
    // Convert binary coded decimal to normal decimal numbers
    byte bcdToDec(byte val)
    {
      return ( (val/16*10) + (val%16) );
    }
    
    // Stops the DS1307, but it has the side effect of setting seconds to 0
    // Probably only want to use this for testing
    /*void stopDs1307()
    {
      Wire.beginTransmission(DS1307_I2C_ADDRESS);
      Wire.send(0);
      Wire.send(0x80);
      Wire.endTransmission();
    }*/
    
    // 1) Sets the date and time on the ds1307
    // 2) Starts the clock
    // 3) Sets hour mode to 24 hour clock
    // Assumes you're passing in valid numbers
    void setDateDs1307(byte second,        // 0-59
                       byte minute,        // 0-59
                       byte hour,          // 1-23
                       byte dayOfWeek,     // 1-7
                       byte dayOfMonth,    // 1-28/29/30/31
                       byte month,         // 1-12
                       byte year)          // 0-99
    {
       Wire.beginTransmission(DS1307_I2C_ADDRESS);
       Wire.send(0);
       Wire.send(decToBcd(second));    // 0 to bit 7 starts the clock
       Wire.send(decToBcd(minute));
       Wire.send(decToBcd(hour));      // If you want 12 hour am/pm you need to set
                                       // bit 6 (also need to change readDateDs1307)
       Wire.send(decToBcd(dayOfWeek));
       Wire.send(decToBcd(dayOfMonth));
       Wire.send(decToBcd(month));
       Wire.send(decToBcd(year));
       Wire.endTransmission();
    }
    
    // Gets the date and time from the ds1307
    void getDateDs1307(byte *second,
              byte *minute,
              byte *hour,
              byte *dayOfWeek,
              byte *dayOfMonth,
              byte *month,
              byte *year)
    {
      // Reset the register pointer
      Wire.beginTransmission(DS1307_I2C_ADDRESS);
      Wire.send(0);
      Wire.endTransmission();
    
      Wire.requestFrom(DS1307_I2C_ADDRESS, 7);
    
      // A few of these need masks because certain bits are control bits
      *second     = bcdToDec(Wire.receive() & 0x7f);
      *minute     = bcdToDec(Wire.receive());
      *hour       = bcdToDec(Wire.receive() & 0x3f);  // Need to change this if 12 hour am/pm
      *dayOfWeek  = bcdToDec(Wire.receive());
      *dayOfMonth = bcdToDec(Wire.receive());
      *month      = bcdToDec(Wire.receive());
      *year       = bcdToDec(Wire.receive());
    }
    
    void setup()
    {
      byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
      Wire.begin();
      Serial.begin(9600);
    
      // Change these values to what you want to set your clock to.
      // You probably only want to set your clock once and then remove
      // the setDateDs1307 call.
      second = 45;
      minute = 3;
      hour = 7;
      dayOfWeek = 5;
      dayOfMonth = 17;
      month = 4;
      year = 8;
      setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
    }
    
    void loop()
    {
      byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    
      getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
      Serial.print(hour, DEC);
      Serial.print(":");
      Serial.print(minute, DEC);
      Serial.print(":");
      Serial.print(second, DEC);
      Serial.print("  ");
      Serial.print(month, DEC);
      Serial.print("/");
      Serial.print(dayOfMonth, DEC);
      Serial.print("/");
      Serial.print(year, DEC);
      Serial.print("  Day_of_week:");
      Serial.println(dayOfWeek, DEC);
    
      delay(1000);
    }