Плата mega2560, часы реального времени ds3231, индикатор tm1637.Код взял в теме " Arduino uno часы с температурой на DS3231 и дисплее TM1637". отличные получились часы код может кому и пригодится отдельное спасибо Tomasina за помощь в написании кода. #include <Wire.h> #include "TM1637.h" #define DS1307_I2C_ADDRESS 0x68 #define CLK 2 #define DIO 3 TM1637 tm1637(CLK,DIO); ///// часы .. byte decToBcd(byte val){ return((val/10*16)+(val%10)); } byte bcdToDec(byte val){ return((val/16*10)+(val%16)); } 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.write(0); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 7); *second = bcdToDec(Wire.read()&0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read()&0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } float get3231Temp(){ byte tMSB, tLSB; float temp3231; Wire.beginTransmission(0x68); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(0x68, 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; } ///////////////// void setup(){ Wire.begin(); tm1637.init(); tm1637.set(4);// яркость, от 0 до 7 /* // установка часов byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; second = 0; minute = 59; hour = 21; dayOfWeek = 1; // день недели dayOfMonth = 11; // день month = 4; year = 16; 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); byte temp = get3231Temp(); int8_t TimeDisp[4]; // вывод температуры .. каждые 10 сек на 2 сек if(second >=0&& second <=1|| second >=10&& second <=11|| second >=20&& second <=21|| second >=30&& second <=31|| second >=40&& second <=41|| second >=50&& second <=51) { tm1637.point(POINT_OFF);// выключаем точки TimeDisp[0]=19;// TimeDisp[1]= temp /10;// заполняем массив TimeDisp[2]= temp %10; TimeDisp[3]=12;// C } /* // дата else if(second >= 25 && second <= 26 || second >= 45 && second <= 46) { tm1637.point(POINT_OFF); TimeDisp[0] = dayOfMonth / 10; TimeDisp[1] = dayOfMonth % 10; TimeDisp[2] = month / 10; TimeDisp[3] = month % 10; }*/ /// часы else { tm1637.point(POINT_ON);// включаем точки TimeDisp[0]= hour /10; TimeDisp[1]= hour %10; TimeDisp[2]= minute /10; TimeDisp[3]= minute %10; } tm1637.display(TimeDisp);// отправляем массив на экран } Но почему то на индикаторе выводит "45:-5" и ни чего не моргает и не движется. До этого пробовал другие скетчи, там было "45: 5" без черточки. Библиотеки все стоят. В программировании очень слабо. Помогите пожалуйста найти ошибку.
Код (C++): byte temp = get3231Temp(); Функция get3231Temp() возвращает тип float, а Вы его в byte пишите. Нехорошо. Почему бы немного не изменить текст и вместо: Код (C++): // вывод температуры .. каждые 10 сек на 2 сек if(second >=0&& second <=1|| second >=10&& second <=11|| second >=20&& second <=21|| second >=30&& second <=31|| second >=40&& second <=41|| second >=50&& second <=51) { tm1637.point(POINT_OFF);// выключаем точки TimeDisp[0]=19; TimeDisp[1]= temp /10;// заполняем массив TimeDisp[2]= temp %10; TimeDisp[3]=12;// C } написать так: Код (C++): // вывод температуры .. каждые 10 сек на 2 сек if(second % 10 <= 1) { tm1637.point(POINT_OFF);// выключаем точки TimeDisp[0]=19; TimeDisp[1]= temp /10;// заполняем массив TimeDisp[2]= temp %10; TimeDisp[3]=12;// C tm1637.display(TimeDisp); delay(2000); } Время из часов читается правильное?
Спасибо. Все заработало. И часы и температура. Ошибка была в питании реального времени (нужно 3,3в) и в самом подключении. (scl sda). Код оставил прежний. На этом вылазит ошибка 'TimeDisp' is not captured и замирает температура (не переключается на часы) Хотелось бы программно уменьшить температуру. Показывает 29С,а реально 24С.
Максимальное допустимое напряжение питания для DS3231 - 5.5 В. Так что, скорее всего, дело было не в питании. Что бы уменьшить значение температуры с 29 до 24: Код (C++): byte temp = get3231Temp(); temp -= 5; По поводу ошибок, если интересно, попробуйте так (убрал неиспользуемый код): Код (C++): #include <Wire.h> #include "TM1637.h" #define DS3231_I2C_ADDRESS 0x68 #define CLK 2 #define DIO 3 TM1637 tm1637(CLK,DIO); byte bcdToDec(byte val) { return((val / 16 * 10) + (val % 16)); } void getDateDs3231(byte *second, byte *minute, byte *hour) { Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 7); *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); } float get3231Temp() { byte tMSB, tLSB; float temp3231; Wire.beginTransmission(DS3231_I2C_ADDRESS); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(DS3231_I2C_ADDRESS, 2); if(Wire.available()){ tMSB = Wire.read(); tLSB = Wire.read(); temp3231 = (tMSB & B01111111); temp3231 += ((tLSB >> 6) * 0.25); } return temp3231; } void setup() { Wire.begin(); tm1637.init(); tm1637.set(4); } void loop() { byte second, minute, hour; byte TimeDisp[4]; getDateDs3231(&second, &minute, &hour); if (second % 10 <= 1) { byte temp = get3231Temp(); tm1637.point(POINT_OFF); TimeDisp[0] = 19; TimeDisp[1] = temp / 10; TimeDisp[2] = temp % 10; TimeDisp[3] = 12; tm1637.display(TimeDisp); delay(1000); } else { tm1637.point(POINT_ON); TimeDisp[0]= hour / 10; TimeDisp[1]= hour % 10; TimeDisp[2]= minute / 10; TimeDisp[3]= minute % 10; tm1637.display(TimeDisp); } delay(1000); } Протестировал с выводом в Serial, все работает.
Извиняюсь, мой огрех. В функции loop() вместо "byte TimeDisp[4];" должно быть "int8_t TimeDisp[4];". Кстати, в таком виде: "byte temp = get3231Temp();" в переменную будет записываться только целая часть значения температуры, а дробная будет отброшена. Если хотите округлять температуру до целого числа, то надо так: "byte temp = round(get3231Temp());"
Все заработало. Спасибо. Одно но. Питаю я пока от usb. Если отключить питание,почему то пока не нажмешь сброс на плате,часы не запускаются. Индикатор вообще не горит.Либо повторно скетч выгружаешь,тогда работать начинает.