Проблема с функцией
- Войдите на сайт для отправки комментариев
Вс, 06/12/2015 - 17:21
Всем доброго вчерера. Есть некая библиотека получения времени с ds3231.
Есть функции возврата времения типа byte. Время выдает так: 1:5:2, а хотелось бы 01:05:02 (1час 5 мин 2сек)
Решил приколхозить в библеотеку часов функцию convert( byte k);
char* DS3231::convert(byte& k) {
strcpy(outline, "");
if(k>=0 && k<10){
sprintf(outline,"0%d",k);
}
else{
sprintf(outline,"%d",k);
}
return outline;
}
outline - массив char[10];
k - число на входе (минута или час или секунда)
собственно в основной программе, например:
second = Clock.getSecond();
minute = Clock.getMinute();
hour = Clock.getHour(h12, PM);
sprintf(out, "%s:%s:%s", Clock.convert(hour), Clock.convert(minute), Clock.convert(second));
выдаст 01:01:01 , а должно 01:05:02. Как я понимаю что то с указаетлем не то, но что конкретно, понять не могу.
Мне кажется, что вы сильно перемудрили.
Почитайте про строки формата для sprintf. А вообще здесь sprintf из пушки по воробьям, в интернете море примеров, как сделать проще
:) Да, не сразу заметил тоже. %2s:%2s:%2s было бы вернее, но реально очень дорого для скетча.
Хотя, да - ради одной этой строчки цеплять целый sprintf жалко.
А очень просто. Функция convert возврвщает указатель на буфер outline. На один и тот же буфер, всегда, все три раза. Соответственно, функция sprintf получает в качестве параметров три одинаковых указателя на outline, и три раза честно выводит то, что в этом буфере лежит на момент вызова.
я этот под себя приспособил. кидаю целиком то что где то нашлось:
#include <Wire.h> #define DS3231_I2C_ADDRESS 104 // SDA A4 // SCL A5 byte seconds, minutes, hours, day, date, month, year; char weekDay[4]; byte tMSB, tLSB; float temp3231; void setup() { Serial.begin(9600); Wire.begin(); //set control register to output square wave on pin 3 at 1Hz Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address Wire.write(0x0E); Wire.write(B00000000); Wire.write(B10001000); Wire.endTransmission(); } void loop() { watchConsole(); get3231Date(); Serial.print(weekDay); Serial.print(", "); Serial.print(month, DEC); Serial.print("/"); Serial.print(date, DEC); Serial.print("/"); Serial.print(year, DEC); Serial.print(" - "); Serial.print(hours, DEC); Serial.print(":"); Serial.print(minutes, DEC); Serial.print(":"); Serial.print(seconds, DEC); Serial.print(" Temperature: "); Serial.print(get3231Temp());Serial.print("; ");Serial.println(get3231Register(0x0F)); delay(1000); } // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } void watchConsole() { if (Serial.available()) { // Look for char in serial queue and process if found if (Serial.read() == 84) { //If command = "T" Set Date set3231Date(); get3231Date(); Serial.println(" "); } } } void set3231Date() { //T(sec)(min)(hour)(dayOfWeek)(dayOfMonth)(month)(year) //T(00-59)(00-59)(00-23)(1-7)(01-31)(01-12)(00-99) // Example: 02-Feb-09 @ 19:57:11 for the 3rd day of the week -> T1157193020209 !!!!!!!!!!!!!!!!!!!! seconds = (byte) ((Serial.read() - 48) * 10 + (Serial.read() - 48)); // Use of (byte) type casting and ascii math to achieve result. minutes = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); hours = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); day = (byte) (Serial.read() - 48); date = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); month = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); year = (byte) ((Serial.read() - 48) *10 + (Serial.read() - 48)); Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0x00); Wire.write(decToBcd(seconds)); Wire.write(decToBcd(minutes)); Wire.write(decToBcd(hours)); Wire.write(decToBcd(day)); Wire.write(decToBcd(date)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } byte get3231Register(byte regNo) { // send request to receive data starting at register regNo Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address Wire.write(regNo); // start at register regNo Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 1); // request one byte if(Wire.available()) return Wire.read(); } void set3231Register(byte regNo, byte value) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(regNo); Wire.write(value); Wire.endTransmission(); } void get3231Date() { // send request to receive data starting at register 0 Wire.beginTransmission(DS3231_I2C_ADDRESS); // 104 is DS3231 device address Wire.write(0x00); // start at register 0 Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // request seven bytes if(Wire.available()) { seconds = Wire.read(); // get seconds minutes = Wire.read(); // get minutes hours = Wire.read(); // get hours day = Wire.read(); date = Wire.read(); month = Wire.read(); //temp month year = Wire.read(); seconds = (((seconds & B11110000)>>4)*10 + (seconds & B00001111)); // convert BCD to decimal minutes = (((minutes & B11110000)>>4)*10 + (minutes & B00001111)); // convert BCD to decimal hours = (((hours & B00110000)>>4)*10 + (hours & B00001111)); // convert BCD to decimal (assume 24 hour mode) day = (day & B00000111); // 1-7 date = (((date & B00110000)>>4)*10 + (date & B00001111)); // 1-31 month = (((month & B00010000)>>4)*10 + (month & B00001111)); //msb7 is century overflow year = (((year & B11110000)>>4)*10 + (year & B00001111)); } else { //oh noes, no data! } switch (day) { case 1: strcpy(weekDay, "Sun"); break; case 2: strcpy(weekDay, "Mon"); break; case 3: strcpy(weekDay, "Tue"); break; case 4: strcpy(weekDay, "Wed"); break; case 5: strcpy(weekDay, "Thu"); break; case 6: strcpy(weekDay, "Fri"); break; case 7: strcpy(weekDay, "Sat"); break; } } float get3231Temp() { //temp registers (11h-12h) get updated automatically every 64s Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 2); if(Wire.available()) { tMSB = Wire.read(); //2's complement int portion tLSB = Wire.read(); //fraction portion temp3231 = (tMSB & B01111111); //do 2's math on Tmsb temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8 } else { //oh noes, no data! } return temp3231; }Хотя, да - ради одной этой строчки цеплять целый sprintf жалко.
А очень просто. Функция convert возврвщает указатель на буфер outline. На один и тот же буфер, всегда, все три раза. Соответственно, функция sprintf получает в качестве параметров три одинаковых указателя на outline, и три раза честно выводит то, что в этом буфере лежит на момент вызова.
все, понял, сделал "в лоб":
lcd.print(Clock.convert(hour)); lcd.print(":"); lcd.print(Clock.convert(minute)); lcd.print(":"); lcd.print(Clock.convert(second));