RTC e i2c

Altro problema con il protocollo i2c.
Ho un rtc comprato da byVac che non riesco a far funzionare.

Provo questo codice:

/******************************************************************************
Example program I2C-RTC interface with Arduino.

SETUP:    I2C-RTC => Arduino
          PIN1 => A5, PIN2 => A4, PIN3 => ground, PIN6 => +5V
Note:     The program is written for address 0xD0 (Arduino address 0x68).
          This program was tested using Arduino Nano
Document: DS1340 datasheet
Updated:  September 4, 2008
E-mail:   support@gravitech.us
          Gravitech
(C) Copyright 2008 All Rights Reserved
*******************************************************************************/

#include <Wire.h> 

#define Binary 0
#define Hex 1

/*******************************************************************************
                      Function Prototype
*******************************************************************************/  
unsigned int SerialNumRead (byte);
void SetTime();
void DisplayTime();

/*******************************************************************************
                    Global variables
*******************************************************************************/ 
const int I2C_address = 0x68;  // I2C write address 
//byte    TenthSecond;     // Store first value
byte    Second;     // Store second value
byte    Minute;     // Store minute value
byte    Hour;       // Store hour value
byte    Day;        // Store day value
byte    Date;       // Store date value
byte    Month;      // Store month value
byte    Year;       // Store year value

/*******************************************************************************
                      Setup
*******************************************************************************/ 
void setup() 
{ 
  Serial.begin(9600);
  Wire.begin();        // join i2c bus (address optional for master) 
  delay(1000);
} 
 
/*******************************************************************************
                      Main Loop
*******************************************************************************/  
void loop() 
{ 
  boolean Readtime;       // Set/Read time flag
  unsigned int Incoming;  // Incoming serial data

  // Display prompt
  Serial.println("What would you like to do?");
  Serial.println("(0) To set the current time.");
  Serial.println("(1) To display the current time.");
  Serial.print("Enter 0 or 1: ");
   
  Incoming = SerialNumRead (Binary);  // Get input command
  Serial.println(Incoming, DEC);      // Echo the value
  Serial.println();
  
  if (Incoming == 0)                  // Process input command
    SetTime();
  else if (Incoming == 1)
    DisplayTime();
  
  delay (1000);
}

/*******************************************************************************
       Read a input number from the Serial Monitor ASCII string
       Return: A binary number or hex number
*******************************************************************************/ 
unsigned int SerialNumRead (byte Type)
{
  unsigned int Number = 0;       // Serial receive number
  unsigned int digit = 1;        // Digit
  byte  i = 0, j, k=0, n;        // Counter
  byte  ReceiveBuf [5];          // for incoming serial data
  
  while (Serial.available() <= 0);
  
  while (Serial.available() > 0)  // Get serial input
  {
    // read the incoming byte:
    ReceiveBuf[i] = Serial.read();
    i++;
    delay(10);
  }
  
  for (j=i; j>0; j--)
  {
    digit = 1;
    
    for (n=0; n<k; n++)          // This act as pow() with base = 10
    {
      if (Type == Binary)
        digit = 10 * digit;
      else if (Type == Hex)
        digit = 16 * digit;
    }
        
    ReceiveBuf[j-1] = ReceiveBuf[j-1] - 0x30;    // Change ASCII to BIN
    Number = Number + (ReceiveBuf[j-1] * digit); // Calcluate the number
    k++;
  }
  return (Number);    
}

/*******************************************************************************
                   Set time function
*******************************************************************************/ 
void SetTime()
{
  Serial.print("Enter seconds (00-59): ");
  Second = (byte) SerialNumRead (Hex);
  Serial.println(Second, HEX);      // Echo the value
  Second = Second & 0x7F;           // Enable oscillator
  Serial.print("Enter minutes (00-59): ");
  Minute = (byte) SerialNumRead (Hex);
  Serial.println(Minute, HEX);      // Echo the value
  Serial.print("Enter hours (00-23): ");
  Hour = (byte) SerialNumRead (Hex);
  Serial.println(Hour, HEX);        // Echo the value
  Hour = Hour & 0x3F;               // Disable century
  Serial.print("Enter day (01-07): ");
  Day = (byte) SerialNumRead (Hex);
  Serial.println(Day, HEX);         // Echo the value
  Serial.print("Enter date (01-31): ");
  Date = (byte) SerialNumRead (Hex);
  Serial.println(Date, HEX);        // Echo the value
  Serial.print("Enter month (01-12): ");
  Month = (byte) SerialNumRead (Hex);
  Serial.println(Month, HEX);       // Echo the value
  Serial.print("Enter year (00-99): ");
  Year = (byte) SerialNumRead (Hex);
  Serial.println(Year, HEX);        // Echo the value

  Wire.beginTransmission(I2C_address);
  Wire.send(0);
 // Wire.send(TenthSecond);
  Wire.send(Second);
  Wire.send(Minute);
  Wire.send(Hour);
  Wire.send(Day);
  Wire.send(Date);
  Wire.send(Month);
  Wire.send(Year);
  Wire.endTransmission();
//  I2COUT SDA, I2C_WR, [2,Second,Minute,Hour,Day,Date,Month,Year]
  Serial.println();
  Serial.println ("The current time has been successfully set!");
}

/*******************************************************************************
                   Display time function
*******************************************************************************/ 
void DisplayTime()
{
  char tempchar [7];
  byte i = 0;
  Wire.beginTransmission(I2C_address);
  Wire.send(0);
  Wire.endTransmission();
  
  Wire.requestFrom(I2C_address, 7);
  
  while(Wire.available())          // Checkf for data from slave
  { 
    tempchar [i] = Wire.receive(); // receive a byte as character 
    i++;
  } 
  Second = tempchar [0];
  Minute = tempchar [1];
  Hour   = tempchar [2];
  Day    = tempchar [3];
  Date   = tempchar [4];
  Month  = tempchar [5];
  Year   = tempchar [6];
  
  // Display time
  Serial.print("The current time is ");
  Serial.print(Month, HEX);
  Serial.print("/");
  Serial.print(Date, HEX);
  Serial.print("/20");
  if (Year<10)
    Serial.print("0");
  Serial.print(Year, HEX);
  Serial.print("    ");
  Serial.print(Hour, HEX);
  Serial.print(":");
  Serial.print(Minute, HEX);
  Serial.print(".");
   Serial.println(Second, HEX);
 
}

riesco ad impostare tutto tranne i secondi e questo fa anche si che l’orologio “non parta”…rimangono sempre fermi anche i minuti ecc…

Il datasheet del bv4236 scrive:

7.2. The Real Time Clock
The RTC needs a battery to operate and this
should be fitted to the battery holder provided.
The + sign points away from the PCB. The
RTC address is 0xD0
The RTC is very easy to read and write as it
has a set of registers that can be addressed in
a similar way to a memory location.
The registers are allocated as follows:

  1. Tenths/Hundredths of a Second Register
  2. Seconds Register
  3. Minutes Register
  4. Century/Hours Register
  5. Day Register
  6. Date Register
  7. Month Register
  8. Year Register
  9. Control Register
  10. Watchdog Register
    11 - 16. Alarm Registers
    17 - 19. Reserved
  11. Square Wave Register

non è per caso la presenza dei millesecondi sposti il settaggio impedendone il funzionamento?
Spero di essere stato chiaro e che qualcuno riesca ad illuminarmi.
Davide

ciao
puoi postare il link dell’oggetto e del datasheet?
Nelle specifiche all’inizio il tuo codice dice: Document: DS1340 datasheet.
Il DS1340 lavora con una codifica in formato BDC mentre il tuo programma, mi sembra usi il sistema binario…

Mi sa che il problema stia qui: The clock will appear to have stopped until the HT flag is cleared, this must be done for each power down/up cycle. Hai provato ad effettuare il Clearing the HT flag

Il datasheet è questo: www.byvac.com/bv/datasheets/BV4236%20DataSheet-a.pdf

Purtroppo non riesco a tradurre i comandi del datasheet in comandi di arduino... Questo sarebbe il comando Clearing Ht flag:

0xD0>s c 0 p come si traduce?

Wire.beginTransmission(0x68); Wire.send(0); Wire.send(0xC); Wire.endTransmission();

non credo perchè non funziona.. :(

Sto provando un altro codice e riesco ad inserire anche i secondi…ma poi l’orologio non parte…probabilmente manca il comando che da l’avvio…è possibile?

Semmai invia questo:

Wire.beginTransmission(0x68); Wire.send(0xC); Wire.send(0); Wire.endTransmission();

Cerca il datasheet del M41T81 e vedi se risolvi.

E' partito! :)

Ho avuto anche io qualche problema nel far andare il modulo BV4236.
Riporto lo script da me cambiato per far andare correttamente tale modulo e leggere anche il valore di temperatura (visto che tale modulo ha anche il sensore di temperatura)

ciao


Example program I2C-RTC and Temp Sensor (BV4236) interface with Arduino.

SETUP: I2C-RTC => Arduino
PIN1 => A5, PIN2 => A4, PIN3 => ground, PIN6 => +5V
Note: The program is written for address 0xD0 (Arduino address 0x68).
This program was tested using Arduino Nano
Document: BV4236 datasheet
Updated: November 29, 2009

(C) Copyright 2008 All Rights Reserved
*******************************************************************************/

#include <Wire.h>

#define Binary 0
#define Hex 1

/*******************************************************************************
Function Prototype
*******************************************************************************/
unsigned int SerialNumRead (byte);
void SetTime();
void DisplayTime();

/*******************************************************************************
Global variables
*******************************************************************************/
const int I2C_address_rtc = 0x68; // I2C write address
const int I2C_address_tsens = 0x48; // I2C write address

byte TenthSecond; // Store first value
byte Second; // Store second value
byte Minute; // Store minute value
byte Hour; // Store hour value
byte Day; // Store day value
byte Date; // Store date value
byte Month; // Store month value
byte Year; // Store year value

byte Temp; // Store year value

boolean HTset ; // HT should be reset at every power on phase
/*******************************************************************************
Setup
*******************************************************************************/
void setup()
{
Serial.begin(9600);
Wire.begin(); // join i2c bus (address optional for master)
delay(1000);
}

/*******************************************************************************
Main Loop
*******************************************************************************/
void loop()
{
boolean Readtime; // Set/Read time flag
unsigned int Incoming; // Incoming serial data

// Display prompt
Serial.println(“What would you like to do?”);
Serial.println("(0) To set the current time.");
Serial.println("(1) To display the current time.");
Serial.println("(2) To display Temperature.");
Serial.print("Enter 0, 1 or 2: ");

Incoming = SerialNumRead (Binary); // Get input command
Serial.println(Incoming, DEC); // Echo the value
Serial.println();

if (Incoming == 0) // Process input command
SetTime();
else if (Incoming == 1)
DisplayTime();
else if (Incoming == 2)
DisplayTemp();

delay (1000);
}

/*******************************************************************************
Read a input number from the Serial Monitor ASCII string
Return: A binary number or hex number
*******************************************************************************/
unsigned int SerialNumRead (byte Type)
{
unsigned int Number = 0; // Serial receive number
unsigned int digit = 1; // Digit
byte i = 0, j, k=0, n; // Counter
byte ReceiveBuf [5]; // for incoming serial data

while (Serial.available() <= 0);

while (Serial.available() > 0) // Get serial input
{
// read the incoming byte:
ReceiveBuf = Serial.read();

  • i++;*
  • delay(10);*
  • }*
  • for (j=i; j>0; j–)*
  • {*
  • digit = 1;*
  • for (n=0; n<k; n++) // This act as pow() with base = 10*
  • {*
  • if (Type == Binary)*
    _ digit = 10 * digit;_
  • else if (Type == Hex)*
    _ digit = 16 * digit;_
  • }*
  • ReceiveBuf[j-1] = ReceiveBuf[j-1] - 0x30; // Change ASCII to BIN*
    _ Number = Number + (ReceiveBuf[j-1] * digit); // Calcluate the number_
  • k++;*
  • }*
  • return (Number);*
    }
    /*******************************************************************************
  • Set time function*
    *******************************************************************************/
    void SetTime()
    {
  • Serial.print("Enter seconds (00-59): ");*
  • Second = (byte) SerialNumRead (Hex);*
  • Serial.println(Second, HEX); // Echo the value*
  • Second = Second & 0x7F; // Enable oscillator*
  • Serial.print("Enter minutes (00-59): ");*
  • Minute = (byte) SerialNumRead (Hex);*
  • Serial.println(Minute, HEX); // Echo the value*
  • Serial.print("Enter hours (00-23): ");*
  • Hour = (byte) SerialNumRead (Hex);*
  • Serial.println(Hour, HEX); // Echo the value*
  • Hour = Hour & 0x3F; // Disable century*
  • Serial.print("Enter day (01-07): ");*
  • Day = (byte) SerialNumRead (Hex);*
  • Serial.println(Day, HEX); // Echo the value*
  • Serial.print("Enter date (01-31): ");*
  • Date = (byte) SerialNumRead (Hex);*
  • Serial.println(Date, HEX); // Echo the value*
  • Serial.print("Enter month (01-12): ");*
  • Month = (byte) SerialNumRead (Hex);*
  • Serial.println(Month, HEX); // Echo the value*
  • Serial.print("Enter year (00-99): ");*
  • Year = (byte) SerialNumRead (Hex);*
  • Serial.println(Year, HEX); // Echo the value*
  • Wire.beginTransmission(I2C_address_rtc);*
  • Wire.send(0);*
  • Wire.send(TenthSecond);*
  • Wire.send(Second);*
  • Wire.send(Minute);*
  • Wire.send(Hour);*
  • Wire.send(Day);*
  • Wire.send(Date);*
  • Wire.send(Month);*
  • Wire.send(Year);*
  • Wire.endTransmission();*
    // I2COUT SDA, I2C_WR, [2,Second,Minute,Hour,Day,Date,Month,Year]
  • Serial.println();*
  • Serial.println (“The current time has been successfully set!”);*
    }
    /*******************************************************************************
  • Display time function*
    *******************************************************************************/
    void DisplayTime()
    {
  • if (HTset == false)*
  • {*
  • Wire.beginTransmission(0x68);*
  • Wire.send(0xC);*
  • Wire.send(0);*
  • Wire.endTransmission();*
  • HTset = true ;*
  • }*
  • char tempchar [7];*
  • byte i = 0;*
  • Wire.beginTransmission(I2C_address_rtc);*
  • Wire.send(0);*
  • Wire.endTransmission();*
  • Wire.requestFrom(I2C_address_rtc, 8);*
  • while(Wire.available()) // Checkf for data from slave*
  • {*
    _ tempchar = Wire.receive(); // receive a byte as character_
    * i++;*
    * }*
    * TenthSecond = tempchar [0];*
    * Second = tempchar [1];*
    * Minute = tempchar [2];*
    * Hour = tempchar [3];*
    * Day = tempchar [4];*
    * Date = tempchar [5];*
    * Month = tempchar [6];*
    * Year = tempchar [7];*
    * // Display time*
    * Serial.print("The current time is : ");*
    * Serial.print(Month, HEX);*
    * Serial.print("/");*
    * Serial.print(Date, HEX);*
    * Serial.print("/20");*
    * if (Year<10)*
    * Serial.print(“0”);*
    * Serial.print(Year, HEX);*
    * Serial.print(" ");*
    * Serial.print(Hour, HEX);*
    * Serial.print(":");*
    * Serial.print(Minute, HEX);*
    * Serial.print(".");*
    * Serial.println(Second, HEX);*
    }
    void DisplayTemp()
    {
    * char tempchar [7];*
    * byte i = 0;*
    * Wire.beginTransmission(I2C_address_tsens);
    _
    Wire.send(0);_
    _
    Wire.endTransmission();_
    Wire.requestFrom(I2C_address_tsens, 1);
    _
    while(Wire.available()) // Checkf for data from slave*_
    * {*
    _ tempchar = Wire.receive(); // receive a byte as character
    * i++;
    }
    Temp = tempchar [0];
    // Display time*
    * Serial.print("The current temperature is : ");
    Serial.println(Temp, DEC);
    }*_

con questo modulo puoi impostare un'allarme che alza un pin da usare come interrupt da arduino, ad esempio per risvegliarlo?

ciaoe e grazie