DS1302_clock_burst_write function problem

Hi everybody.

My name is Martin. I want to use DS1302 basic library made by user named "Krodal" (This is the link Arduino Playground - DS1302) in my application where of course I use DS1302 rtc timer.
I am not familiar whit new convenience in C language programming, so I want to ask another people who know better.
I do not seem, that this function "void DS1302_clock_burst_write(uint8_t *p)" from that library works well. I do not think when I use there in function pointer to structure and I convert it to pointer to integer it begins to work with first member of that structure. For example: " DS1302_clock_burst_write((uint8_t *) &rtc)". First of course I filled members of "rtc" structure by values and then I used this function. But results I was expecting were different.

So I made test where I put values of my defined structure "rtc" to serial monitor of Arduino and results were so, as I wrote them into "rtc" structure.

seconds = 15;
minutes = 0;
hours = 9;
dayofweek = 3;
dayofmonth = 9;
month = 7;
year = 2014;

memset((uint8_t*)&rtc, 0, sizeof(rtc));

rtc.Seconds = bin2bcd_l(seconds);
rtc.Seconds10 = bin2bcd_h(seconds);
rtc.CH = 0;
rtc.Minutes = bin2bcd_l(minutes);
rtc.Minutes10 = bin2bcd_h(minutes);
rtc.h24.Hour = bin2bcd_l(hours);
rtc.h24.Hour10 = bin2bcd_h(hours);
rtc.h24.hour_12_24 = 0;
rtc.Date = bin2bcd_l(dayofmonth);
rtc.Date10 = bin2bcd_h(dayofmonth);
rtc.Day = dayofweek;
rtc.Month = bin2bcd_l(month);
rtc.Month10 = bin2bcd_h(month);
rtc.Year = bin2bcd_l(year - 2000);
rtc.Year10 = bin2bcd_h(year - 2000);
rtc.WP = 0;

// here it is correct and I can see correct values which are written in "rtc" structure also on serial monitor

#ifdef TEST
Serial.println(bcd2bin(rtc.Minutes10, rtc.Minutes));
Serial.println(bcd2bin(rtc.h24.Hour10, rtc.h24.Hour));
Serial.println(bcd2bin(rtc.Date10, rtc.Date));
Serial.println(rtc.Day);
Serial.println(bcd2bin(rtc.Month10, rtc.Month));
Serial.println(bcd2bin(rtc.Year10, rtc.Year));
#endif

/But after using these functions values on serial monitor are all zeros and I do not know why?
DS1302_clock_burst_write((uint8_t *) &rtc);

#ifdef TEST

DS1302_clock_burst_read((uint8_t*) &rtc);

Serial.println(bcd2bin(rtc.Minutes10, rtc.Minutes));
Serial.println(bcd2bin(rtc.h24.Hour10, rtc.h24.Hour));
Serial.println(bcd2bin(rtc.Date10, rtc.Date));
Serial.println(rtc.Day);
Serial.println(bcd2bin(rtc.Month10, rtc.Month));
Serial.println(bcd2bin(rtc.Year10, rtc.Year));

#endif

Can anybody help me please? Maybe someone of you hook up already whit this issue. I also controlled connection between Arduino an DS1302 module and controlled supply voltage and it seemed to be correct. And pins are correctly defined in my program too. So what can be problem?

Thanks for your help. Martin.

Can you share output & complete code that your trying, Previously i tired with ds1302 it worked fine

Hi Amps.
Code which I used, one part of it I already led in my first query and the rest is the same as on the link I also led in the firs query. But here I am giving my own written part of program below

DS1302_write(DS1302_ENABLE, 0); // Enable writing to DS1302
DS1302_write(DS1302_TRICKLE, 0x00); //Disable Trickle charger

//Filling of variables to save in rtc structure
seconds = 15;
minutes = 0;
hours = 9;
dayofweek = 3;
dayofmonth = 9;
month = 7;
year = 2014;

memset((uint8_t*)&rtc, 0, sizeof(rtc)); //Clear all the rtc structure

//Saving values into rtc structure

rtc.Seconds = bin2bcd_l(seconds);
rtc.Seconds10 = bin2bcd_h(seconds);
rtc.CH = 0;
rtc.Minutes = bin2bcd_l(minutes);
rtc.Minutes10 = bin2bcd_h(minutes);
rtc.h24.Hour = bin2bcd_l(hours);
rtc.h24.Hour10 = bin2bcd_h(hours);
rtc.h24.hour_12_24 = 0;
rtc.Date = bin2bcd_l(dayofmonth);
rtc.Date10 = bin2bcd_h(dayofmonth);
rtc.Day = dayofweek;
rtc.Month = bin2bcd_l(month);
rtc.Month10 = bin2bcd_h(month);
rtc.Year = bin2bcd_l(year - 2000);
rtc.Year10 = bin2bcd_h(year - 2000);
rtc.WP = 0;

#ifdef TEST

//write some values of rtc structure to serial monitor of Arduino IDE before saving them into DS1302

Serial.println(bcd2bin(rtc.Minutes10, rtc.Minutes));
Serial.println(bcd2bin(rtc.h24.Hour10, rtc.h24.Hour));
Serial.println(bcd2bin(rtc.Date10, rtc.Date));
Serial.println(rtc.Day);
Serial.println(bcd2bin(rtc.Month10, rtc.Month));
Serial.println(bcd2bin(rtc.Year10, rtc.Year));
#endif

DS1302_clock_burst_write((uint8_t *) &rtc); //clock burst write into DS1302

//Test of working RTC timer DS1302

#ifdef TEST

DS1302_clock_burst_read((uint8_t*) &rtc); //clock burst read from DS1302

//write some values from DS1302 to serial monitor of Arduino IDE after burst reading from DS1302

Serial.println(bcd2bin(rtc.Minutes10, rtc.Minutes));
Serial.println(bcd2bin(rtc.h24.Hour10, rtc.h24.Hour));
Serial.println(bcd2bin(rtc.Date10, rtc.Date));
Serial.println(rtc.Day);
Serial.println(bcd2bin(rtc.Month10, rtc.Month));
Serial.println(bcd2bin(rtc.Year10, rtc.Year));

#endif

This is results from serial monitor of Arduino

0 //First six numbers are before writing it to DS1302 RTC timer
9
9
3
7
14
0 //and this is after reading values from DS1302 rtc timer
0
0
0
0
0
Another statements like function declarations, defines, variable definitions are alright. A lot of them I copied from original code and compile successfully build the sketch. I use Arduino IDE and arduino nano ATmega 328 board. Pins are set like in original code and connected to proper pins in rtc module.

Thanks for your help. Martin.

Check below code. This code has worked out for me. I have attached library for your reference with example codes

DS1302.rar (71.1 KB)

Thanks AMPS to your willingness :smiley:

It has been a while since I wrote the page: Arduino Playground - DS1302
I wrote it because the timing and use of the toggle was wrong in many other example code.
The code is okay, and I started to make a class around it, but never finished that.

Reading in a burst and writing in a burst is done with "uint8_t", those are bytes. I did that because the functions might be used in another way, they only read and write bytes in a burst.

As far as I understand, when you read from the DS1302, you are only reading zeros ?
It could be a hardware problem. Perhaps you are not communicating with the chip at all.
Could you try the normal read function "DS1302_read(int address)" to read a few bytes from the chip ?

Hi Krodal.

Thanks for your respond. I am aware that functions DS1302_clock_burst_write and DS1302_clock_burst_read write/read all clock registers at the same time. As you wrote in your comment. Yes I can only read all zeros. I also figured that problem could be in hardware connection. So I controlled connectivity, whether right pins on Arduino board (according to defines in code) are attached to right pins in DS1302 module and everything seems to be OK.

I want to ask you. At beginning of communication, does function "DS1302_write (DS1302_ENABLE, 0)" have to go like first every time? And what about halt clock bit? Proper working of DS1302 (in this case, I think reading and writing from/to DS timer) is not dependent of state of halt clock bit? I suppose, that bit is only for working internal clock in DS1302, but it does not influence communication between Arduino and RTC module?! Or do I have to fill also second register with Halt clock bit and send it to DS1302 in order to be able to communicate to rtc timer?

Last question. Are there any possibilities how to debug your functions in code or to control if these functions did what they had do?

Thanks for your help. Martin

The Halt or WriteProtect should not clear the data in the registers of the DS1302.
I have seen libraries that set the WriteProtect after writing every time. Just to be sure that it is not accidently written.
The Halt bit can be cleared just once or every time.

Perhaps your DS1302 is not working. If you bought a cheap module from Ebay, it can have many problems with voltage, battery or crystal. Or do you use a breadboard with bad connections ?
The RTC modules from Adafruit.com or Sparkfun.com do work.

You use a Arduino Nano with pins 6, 7, 8 ? Are you sure that you have the right pins ? Could you check the wiring once more ? Could you make a photo of it ?

You can do a test. Run an empty sketch, so the Arduino pins are not set yet. Measure the voltage of the three wires to the DS1302. Those three wires should be low, since the DS1302 has internal pull-down resistors.

Hi Krodal.

Thanks for your advices. I am not sure which type of module I have because I got it. I figure, that I use logic analyzer and I will watch signals on it. It is the quickest way. And I will see what will happen.

Thank you Martin.

Hi Krodal.

I finally figured it out. I made one newbie mistake in electronic :blush:. I attached DS1302 module to different electrical potential from Arduino board. Because my Arduino board was supplied through USB from my computer, but DS1302 module was supplied by DC adapter and they were galvanic separated. That was that problem, that DS1302 did not want give me back correct values. Right now, when I reattached to one potential it finally does.

Thanks for your willingness to help me. Martin.

You forgot the ground wire ?
Seperate voltages should not be a problem as long as you have the grounds connected.

The DS1302 is strange chip. If you want to do something serious, use the DS1307.

Hi Krodal.

Communication works fine right now. But I also found one bug, but I do not know whether it is my own code or DS1302 library
I used this code below to find out if the rtc timer works properly and counts seconds. As you can see I use there function DS1302_read(int address) to read seconds from rtc DS1302. Everything works good it counts from zero to nine, but then it springs to 16 instead of ten. And this step it always does after each ninth time, that then shows number which greater about 7. Can't you help what can be problem. For example 0 1 2 3 4 5 6 7 8 9 then 16 17 18 19 20 21 22 23 24 25 then 32 and so on. Initial value of second register was set to zero by writing through rtc structure.

Thanks for your help. Martin

#ifdef TEST

uint8_t i = 0;
while( i <= 65)
{
seconds = DS1302_read(DS1302_SECONDS);
/*DS1302_clock_burst_read((uint8_t )&rtc);
Serial.println(bcd2bin(rtc.Seconds10, rtc.Seconds));
/
Serial.println(seconds);
delay(1000);
i++;
}

#endif

You have two things mixed in your code.
You read the 'seconds', but don't convert it with bcd2bin. When you print the seconds, you print the raw register value.
Since the register value is bcd instead of binary, you get that jump from 9 to 16 (16 is actually '1' '0', meaning "ten").