DS3231 - можно ли подружить с ESP-07 ???
- Войдите на сайт для отправки комментариев
Пт, 23/02/2018 - 20:32
Удавалось ли кому-нибудь подружить часы DS3231 с ESP-07 (ESP-8266)
На Uno R3 и ESP-07 i2c сканер обнаруживает эту плату по адресам 0x57 (еепром) и 0x68 (часы).
C платой Uno R3 эта плата работает нормально - часы ставятся и тикают.
С ESP-07 эта плата не видит время, которое ранее было выставлено на Uno R3, время в регистры пишет - его можно прочитать после установки, но часы не тикают.
При этом после установки часов обратно на Uno R3 - часы показывают правильное время, то есть ESP-07 не сбивает ранее установленное время в DS3231.
Для работы с часами на Uno R3 и ESP-07 использую один и тот же код, работает через Wire.h, скачал из инета:
#include <Wire.h>
#define DS3231_I2C_ADDRESS 0x68
byte seconds, minutes, hours, day, date, month, year;
char weekDay[4];
byte tMSB, tLSB;
float temp3231;
void setup()
{
Wire.begin();
Serial.begin(115200);
Wire.beginTransmission(DS3231_I2C_ADDRESS); // 0x68 is DS3231 device address
Wire.write(0x0E); //
Wire.write(B00000000); // EOSC-0-запуск генератора,BBSQW-0-SQW-вкл,CONV-1-измерение темп-ры, RS2иRS1-частота SQW,INTCN-SQW-будильник или пила частотой RS1-RS2,A2IEиA1IE-прерывания по будильнику.
Wire.write(B00000000); // OSF-0-запуск генератора,0,0,0,EN32kHz,BSY-во время корректировки(автосброс),A2FиA1F - срабатывание будильника,
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: 22-Feb-18 @ 19:57:11 for the 3rd day of the week -> T1040195230218
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)); //0x00
Wire.write(decToBcd(minutes)); //0x01
Wire.write(decToBcd(hours)); //0x02
Wire.write(decToBcd(day)); //0x03
Wire.write(decToBcd(date)); //0x04
Wire.write(decToBcd(month)); //0x05
Wire.write(decToBcd(year)); //0x06
Wire.endTransmission();
Wire.beginTransmission(DS3231_I2C_ADDRESS); // 0x68 is DS3231 device address
Wire.write(0x0E); //
Wire.write(B00000000); // EOSC-0-запуск генератора,BBSQW-0-SQW-вкл,CONV-1-измерение темп-ры, RS2иRS1-частота SQW,INTCN-SQW-будильник или пила частотой RS1-RS2,A2IEиA1IE-прерывания по будильнику.
Wire.write(B00000000); // OSF-0-запуск генератора,0,0,0,EN32kHz,BSY-во время корректировки(автосброс),A2FиA1F - срабатывание будильника
//Wire.write(B10001000);
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); // 0x68 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;
}
Т.к. i2 сканер видит адрес часов, то получается, что соединил я их с ESP-07 правильно - через GPIO2 и GPIO14.
Питание беру не с ESP-07, а прямо с блока питания (через DC-DC step-down преобразователь) - 3,35В
Код не использует библиотеки, а напрямую работает с часами через регистры. Код работает на Uno R3 - его же без изменений гружу и в ESP-07 - то есть в код 100% рабочий. Но при этом с предварительно запущенных часов, этот код считывает нулевые значения...
В чем косяк???
А в случае с Uno как питаете модуль?
через usb, то есть 5В - без внешнего питания.
ESP-07 питанию тоже от USB порта компа, через DC-DC step-down
Перефразирую. Когда часы подключены к Uno - от чего (какого напряжения 5V/3V) они питаются?
пробовал оба и 3,3 и 5 - брал прямо Уно. в обеих случаях работает нормально. это была первая идея, которую проверил - что эта плата не работает от 3,3В
Конечно классический вариант тут - несогласованность уровней TTL или отсутсвие общей земли, но раз вы говорите, что I2C Scaner обнаруживает...
А если, положим, какой-нить другой I2C модуль подключить к ESP - как он себя поведет?
Это еще не пробовал. Есть BMP-085 и BMP-180 - попробую их.
Спасибо за идею.
Думаю, проблемы с питание. Как только здесь на форуме слышу фразу "пробовал оба" или "пробовал десяток" - 100% запутался и напарил.
Вы можете запустить посмотреть, убедиться, что не работает и конкретно сказать как питается. От "оба" она питаться не может.
Делал два варианта подключения:
- первый от пина 5В на Uno R3 - код выложенный выше - работал. Время шло, температура измерялась.
- второй от пина 3,3В на Uno R3 - код выложенный выше - работал. Время шло, температура измерялась.
ESP-07 питается от DC_DC step-down.
Часы так же подключены к выходу step down преобразователя.
DC-DC преобразователь ток max 3A, вот такой https://ru.aliexpress.com/item/Free-Shipping-1PCS-Ultra-small-size-DC-DC...
Того же самого преобразователя или другого? Какое там напряжение?
Заработало...
Код i2c сканера скачал из инета - там Wire инициализируется строкой wire.begin(2,14) - (GPIO2 и GPIO14) устройства подключенные к шине обнаруживаются.
Код для DS3231 инициализирует Wire сторокой wire.begin(). После того как поменял на wire.begin(2,14) - все заработало.
Гуглил этот "wire.begin(address) - address – 7-битный адрес ведомого устройства (опционально); если не указан, шина подсоединяется как ведущее устройство"
Про синтаксис wire.begin(2,14) - не нашел, подстава подстав :)
Спасибо за поддержку.
Синтаксис wire.begin(int,int),где параметры являются номерами выводов SDA и SCL работает только при компиляции скетча для ESP.
Если этот же самый код комплироать для Uno R3 - компилятор выдает ошибку и нужно писать wire.begin().
Погуглил немножко - или я плохо ищу или это нигде не описано.
Странно, что не нашел сообщений похожих на мое - неужели никто не подключал SD3231 к ESP-07?
Или все об это знают и это написано на всех заборах, а я этого не в упор не вижу???
Я не подключал, если вам интересно. Но теперь буду знать.
Так у нашего Атмеля пины несменяемые, хардварные без вариантов.
А у ЕСП скорее всего софтварный и2ц
пробовал из любопытства переназначить пины i2c на esp-07 - не получилось. хотя я не упирался - может и можно....