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 - не получилось. хотя я не упирался - может и можно....