Go Down

### Topic: DS1307 adrress register help ! (Read 7501 times)previous topic - next topic

#### halejandro

#30
##### Aug 11, 2011, 08:27 am

Okay, what might be happening is that the recieved data is coming in as characters, so if you sent F049,
it would show up as
'F', '0', '4', '9'.
So you can test for 'F' no problem,
you can do the switch:case using '0', '1', '2', no problem.
The '2' and '7' you need to put back into 0x27 to send to the DS1307.

3rdchar = 3drchar-0x30; // or -48
4thchar - 4thchar-0x30; // or -49

then
databyte_to_write = (3rdchar<<4 + 4thchar); // should result in 0x27

3rdchar gets shifted left 4 bits, so 0x02 becomes 0x20, and then add 7.

Hello, Okay I´m testing this part but only works with numebers 0-9, and when I send 'F' shows 16, acording to the table 'F' is 46! In the last part why do I have to add 7?
I am Learning, please be Patient !

#31
##### Aug 11, 2011, 08:45 am
'F' was for the case where you had ascii characters coming in instead of HEX bytes.
If you are gettting 0x0F, that is decimal 16. No further processing needed.
if (commandByte == 0x0F)  will work the same as
if (commandByte == 16)

0x27 was just an example to show how to put two nibbles together to make up a byte.
So if you had '2' and '7' come in, you would do the math on them to get
0x02
0x07
so shift 2 left 4 bits:
highnibble = 0x02<<4; // hows its 0x20
add the low nibble 0x07, and you have 0x27, which will make the DS1307 happy when you send a seconds or minutes command.

But if you have HEX data coming in, like F027, then you can just pass along the 0x27 as data.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### halejandro

#32
##### Aug 11, 2011, 11:32 am
How does your board knows when you type for example f145, f1 register and 45 data? Can you explain me that comunication part ?
I am Learning, please be Patient !

#33
##### Aug 12, 2011, 04:26 am
Its in the code halejandro:

RTC_write_command = incomingCommand & 0xF0;  // mask off high byte  <<< Make the byte equal to 0xsomething0
if (RTC_write_command == 0xF0){  // check for Write command  <<< if the something was F, then continue
RTC_register = incomingCommand & 0x0F;  // mask off low byte  <<< Now make the byte equal to 0x0something
incomingCommand = 0;   <<< reset the byte so we don't re-execute before a new command is read
new_data = incomingData;    <<< read  the data byte to send to the DS1307
Serial1.print (" Sending a command ");
switch (RTC_register){
case 0: // write seconds   <<< now if the 0x0something == 0, do this case, or 1, or 2, etc.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### halejandro

#34
##### Aug 12, 2011, 10:08 am
I´m using the modulo operator with the ASCII chars, everything is fine with numbers but I don´t see the letters, to put together two nibbles, I´m doing the same you explained to me but when I introduce '1','0' the serial monitor shows 1,0 instead 10, what am I doing wrong ?
I am Learning, please be Patient !

#35
##### Aug 12, 2011, 11:56 pm
Show me what you have please.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### halejandro

#36
##### Aug 13, 2011, 03:41 amLast Edit: Aug 13, 2011, 06:39 am by halejandro Reason: 1
Code: [Select]
byte incomingCommand = 0;
byte incomingData = 0;
byte Option_to_write = 0;

void setup(){
Serial.begin(9600);
Serial.flush();
}

void loop(){
if (Serial.available()>2){

Option_to_write = (incomingCommand << 4) + incomingData;

Serial.print("Command:");
Serial.print(" Data:");
Serial.print(incomingData, HEX);
Serial.print(" Option to write:");
Serial.println(Option_to_write, HEX);

}
}
I am Learning, please be Patient !

#37
##### Aug 13, 2011, 06:01 am
halejandro,
This code works with the Arduino's IDE Serial Monitor at 57,600
Please review & understand the change  I made, I mostly left the old commands there so you can see the changes.

Commands are given as
F004, sets seconds to 04
F110, sets minutes to 10
F209, sets hours to 09
etc for F3, F4, F5, F6,F7

Code: [Select]

/*
Test of RTC DS1307 via I2C.
Counts
Seconds,
Minutes,
Hours,
Date of the Month,
Month,
Day of the week, and
Year with Leap-Year

56 bytes battery backed RAM
Square Wave Output, can connect to INT2/D6 or PD7
*/

/*
Modified to Run thru IDE Serial port
*/
#include <Wire.h>

//variables
byte seconds; // bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9

byte minutes;  // bits 6-5-4 = tens of minutes, bits 3-2-1-0 = units of minutes

byte hours;  // 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

byte day_week = 0; // range 01-07

byte date_month = 0; // range 01-31

byte month = 0; // range 01-12

int year = 0; // upper byte 0-9, lower byte 0-9

byte sqwe = 0;  // square wave enable
// Out-0-0-Sqwe-0-0-RS1-RS0
// Out, Sqwe = 0/0 - Square wave output = 0
// Out, Sqwe = 1/0 - Square wave output = 1
// Out, Sqwe = 0/1 or 1/1 - Square wave output per RS1/RS0
// RS1/RS0 = 00 = 1 Hz
// RS1/RSo = 01 = 4 KHz
// RS1/RS0 = 10 = 8 KHz
// RS1/RS0 = 11 = 32 KHz

byte RTC_ram_address = 0x08; //range = 08-63, 0x08-0x3F

int RTC_address = 0x68; // 1101 000

byte incomingCommand = 0;
byte RTC_write_command = 0;
byte RTC_ram_command = 0;

// use F0xx, F1xx,F2xx, F3xx, F4xx, F5xx, F6xx, F7xx
// to send one register write commands
// use E0xx to read registers back - not coded yet
// use C0xx to read RAM back - not coded yet

byte incomingRegister = 0;
byte RTC_register = 0;
byte incomingData1 = 0;
byte incomingData2 = 0;
byte new_data = 0;
byte outgoingData = 0;
int delay_time = 100;

unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long duration = 5000;

void setup() {
Wire.begin(); // no address, we are master
Serial.begin (57600);
Serial.flush();
currentMillis = millis();
}

void loop() {

if (Serial.available() >3){
incomingData1 = incomingData1 - 0x30; // convert ASCII to HEX
incomingData2 = incomingData2 - 0x30;  // convert ASCII to HEX
new_data = (incomingData1 << 4) + incomingData2;  // put the Upper/Lower nibbles together
Serial.print ("command ");
Serial.println (incomingCommand);
Serial.print ("register ");
Serial.println(incomingRegister);
Serial.print ("data1 ");
Serial.println (incomingData1, HEX);
Serial.print ("data2 ");
Serial.println (incomingData2, HEX);
Serial.print ("combined data ");
Serial.println (new_data, HEX);

}
// *******************************************
//  RTC_write_command = incomingCommand & 0xF0;  // mask off high byte
//  if (RTC_write_command == 0xF0){  // check for Write command
if ((incomingCommand == 'F') | (incomingCommand == 'f')){
incomingCommand = 0;  // reset for next pass
//    RTC_register = incomingCommand & 0x0F;  // mask off low btye
//    incomingCommand = 0;
//    new_data = incomingData;
Serial.println (" Sending a command ");
//    switch (RTC_register){
switch (incomingRegister){
case '0': // write seconds
Serial.println ("Seconds ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '1': // write minutes
Serial.println ("Minutes ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '2': // write hours
Serial.println ("Hours ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '3': // write day
Serial.println ("Day ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '4': // write date of month
Serial.println ("Day of Month ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '5': // write month
Serial.println ("Month ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '6': // write year
Serial.println ("Year ");
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '7': // write square wave
Serial.println ("Square Wave ");
Serial.println (RTC_register, HEX);
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
case '8': // write RAM
Serial.print ("RAM ");
Serial.println (RTC_register, HEX);
Wire.send(new_data);                  // queue data
Wire.endTransmission();            // send it
delay (delay_time);
break;
// all others,do nothing
Serial.println ("Invalid command ");
}  // end Switch
} // end if command == 'F'
// ************************************

currentMillis = millis();
if ( (currentMillis - previousMillis) >= duration){
previousMillis = currentMillis;
// Reset the register pointer
Wire.send(0x00);
Wire.endTransmission();

// Seconds
// bit 7 = Clock Halt, Enabled = 0, Halt = 1
// bits 6-5-3 = tens of seconds 0-6,  bits 3-2-1-0 = units of seconds, 0-9

// Hours
// 7=0. 6 = 1 for 12 hr, 0 for 24 hr.
// bit 5: 12 hr mode = AM(0)/PM(1). 24 hr mode = upper tens of hrs
// bit 4 =  lower tens of hrs, bits 3-2-1-0 = units of hours (0-9)

Serial.print ("Hrs " );
Serial.print (hours, HEX);
Serial.print (" Mins ");
Serial.print (minutes, HEX);
Serial.print (" Secs ");
Serial.print (seconds, HEX);
Serial.print (" Day ");
Serial.print (day_week, HEX);
Serial.print (" Date ");
Serial.print (date_month, HEX);
Serial.print (" Month ");
Serial.print (month, HEX);
Serial.print (" Year 20");
Serial.print (year, HEX);
Serial.print (" Square Wave ");
Serial.println (sqwe, HEX);

}
}
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### halejandro

#38
##### Aug 13, 2011, 06:26 amLast Edit: Aug 13, 2011, 06:28 am by halejandro Reason: 1
Oh man I'm so sorry, I wanted to do it by myself, but I´m pretty slow to build codes!
I am Learning, please be Patient !

#39
##### Aug 13, 2011, 06:41 am
Well, I needed it myself also so I could test from both serial ports on my board.
You weren't giving me very good confidence that the changes I was suggesting were actually correct, so I had to see.
Am helping 2 others with the same.
Apparantly my use of Serial1 vs Serial, and then a different program with more features than Arduino Serial Monitor has lent itself to much confusion all around.

Your task can be to add the extra 'C' and 'E' commands I didn't write to read back indivual registers and the 56 bytes of battery backed RAM.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### halejandro

#40
##### Aug 13, 2011, 07:04 amLast Edit: Aug 13, 2011, 07:18 am by halejandro Reason: 1
Ok I'll try it, THANKS A LOT !
I am Learning, please be Patient !

#### halejandro

#41
##### Aug 14, 2011, 02:52 am
Excuse me, What are the conditions for read back a register?
I am Learning, please be Patient !

#42
##### Aug 14, 2011, 03:36 am
I am not 100% sure.  That sketch was my first time getting back over I2C, I got parts of it from the playground.

So, I think this might work:
Code: [Select]

// Reset the register pointer
Wire.send(0x00);     <<< put in the address you want, 0x00 to 0x07
Wire.endTransmission();

altho one would think the two could be combined somehow, the way writing a single register is done:
Code: [Select]

>> send the register to read from - not sure what would be used here tho

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

#### halejandro

#43
##### Aug 16, 2011, 11:31 am
Hi, sorry but this is ok? I'm not sure if the square wave register reads that way! Normally we can access the F register, but if do we want to access to E register? I tried using else after the if (Serial.available() >3) with only the command and register data, but it didn´t work !

Code: [Select]
if ((incomingCommand == 'E') | (incomingCommand == 'e')){
incomingCommand = 0;  // reset for next pass
//    RTC_register = incomingCommand & 0x0F;  // mask off low btye
//    incomingCommand = 0;
//    new_data = incomingData;
Serial.println (" Sending Command ");
//    switch (RTC_register){
switch (incomingRegister){
Serial.println ("Seconds: ");
Wire.endTransmission();            // send it
Serial.println(seconds, HEX);
delay (delay_time);
break;
Serial.println ("Minutes: ");
Wire.endTransmission();             //  send it
Serial.println(minutes, HEX);
delay (delay_time);
break;
Serial.println ("Hours: ");
Wire.endTransmission();            // send it
Serial.println(hours, HEX);
delay (delay_time);
break;
Serial.println ("Day: ");
Wire.endTransmission();            // send it
Serial.println(day_week, HEX);
delay (delay_time);
break;
case '4': // read date of month
Serial.println ("Day of Month: ");
Wire.endTransmission();            // send it
Serial.println(date_month, HEX);
delay (delay_time);
break;
Serial.println ("Month: ");
Wire.endTransmission();            // send it
Serial.println(month, HEX);
delay (delay_time);
break;
Serial.println ("Year: ");
Wire.endTransmission();            // send it

Serial.println(year, HEX);
delay (delay_time);
break;
case '7': // read square wave
Serial.println ("Square Wave: ");
Serial.println (RTC_register, HEX);
Wire.endTransmission();            // send it
Serial.println(sqwe, HEX);
delay (delay_time);
break;
Serial.print ("RAM ");
Serial.println (RTC_register, HEX);
Wire.endTransmission();            // send it
delay (delay_time);
break;
// all others,do nothing
Serial.println ("Invalid command ");
}  // end Switch
} // end if command == 'E'
// ************************************
I am Learning, please be Patient !

#44
##### Aug 17, 2011, 12:19 am
Looks good halejandro! I would suggest changes at the start of void loop like this:
(and I took out some of old stuff)
Code: [Select]

void loop() {

if (Serial.available() >3){
incomingData1 = incomingData1 - 0x30; // convert ASCII to HEX
incomingData2 = incomingData2 - 0x30;  // convert ASCII to HEX
new_data = (incomingData1 << 4) + incomingData2;  // put the Upper/Lower nibbles together
Serial.print ("command ");
Serial.println (incomingCommand);
Serial.print ("register ");
Serial.println(incomingRegister);
Serial.print ("data1 ");
Serial.println (incomingData1, HEX);
Serial.print ("data2 ");
Serial.println (incomingData2, HEX);
Serial.print ("combined data ");
Serial.println (new_data, HEX);

}
// *******************************************
if ((incomingCommand == 'F') | (incomingCommand == 'f')){incomingCommand = 'F');
if ((incomingCommand == 'E') | (incomingCommand == 'e')){incomingCommand = 'E');
if ((incomingCommand == 'C') | (incomingCommand == 'c')){incomingCommand = 'C'); // or whatever you decide to go with

switch (incomingCommand) {
case 'F':
switch (RTC_register){
case '0':   /// and all the stuff from the original
:
:
case '8':
:
:
break;
// move this here now:

incomingCommand = 0;  // reset for next pass
}  // end switch:case RTC_register for command 'F
break;  // end command 'F'

// Now add the next command
case 'E':
switch (RTC_register){
case '0':   /// and all the stuff you just wrote
:
:
case '8':
:
:
break;
// move this here now:

incomingCommand = 0;  // reset for next pass
}  // end switch:case RTC_register for command 'E'
break;  // end command 'E'
//repeat for 'C'
Case 'C':
// etc.
break; //end command 'C'
incomingCommand = 0;  // reset for next pass
} // end switch:case incomingCommand

So now you'll have a switch:case within a switch:case!
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up

Please enter a valid email to subscribe