DS3231 - можно ли подружить с ESP-07 ???

ki314
Offline
Зарегистрирован: 03.03.2017

Удавалось ли кому-нибудь подружить часы 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;
}

 

ki314
Offline
Зарегистрирован: 03.03.2017

Т.к. i2 сканер видит адрес часов, то получается, что соединил я их с ESP-07 правильно - через GPIO2 и GPIO14.

Питание беру не с ESP-07, а прямо с блока питания (через DC-DC step-down преобразователь) - 3,35В

Код не использует библиотеки, а напрямую работает с часами через регистры. Код работает на Uno R3 - его же без изменений гружу и в ESP-07 - то есть в код 100% рабочий. Но при этом с предварительно запущенных часов, этот код считывает нулевые значения...

В чем косяк???

sadman41
Offline
Зарегистрирован: 19.10.2016

А в случае с Uno как питаете модуль? 

ki314
Offline
Зарегистрирован: 03.03.2017

через usb, то есть 5В - без внешнего питания.

ki314
Offline
Зарегистрирован: 03.03.2017

ESP-07 питанию тоже от USB порта компа, через DC-DC step-down

sadman41
Offline
Зарегистрирован: 19.10.2016

Перефразирую. Когда часы подключены к Uno - от чего (какого напряжения 5V/3V) они питаются?

ki314
Offline
Зарегистрирован: 03.03.2017

пробовал оба и 3,3 и 5 - брал прямо Уно. в обеих случаях работает нормально. это была первая идея, которую проверил - что эта плата не работает от 3,3В

sadman41
Offline
Зарегистрирован: 19.10.2016

Конечно классический вариант тут - несогласованность уровней TTL или отсутсвие общей земли, но раз вы говорите, что I2C Scaner обнаруживает...

А если, положим, какой-нить другой I2C модуль подключить к ESP - как он себя поведет? 

ki314
Offline
Зарегистрирован: 03.03.2017

Это еще не пробовал. Есть BMP-085 и BMP-180 - попробую их.

Спасибо за идею.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Думаю, проблемы с питание. Как только здесь на форуме слышу фразу "пробовал оба" или "пробовал десяток" - 100% запутался и напарил.

Вы можете запустить посмотреть, убедиться, что не работает и конкретно сказать как питается. От "оба" она питаться не может.

ki314
Offline
Зарегистрирован: 03.03.2017

Делал два варианта подключения:

- первый от пина 5В на Uno R3 - код выложенный выше - работал. Время шло, температура измерялась.

- второй от пина 3,3В на Uno R3 - код выложенный выше - работал. Время шло, температура измерялась.

 

ki314
Offline
Зарегистрирован: 03.03.2017

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...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Того же самого преобразователя или другого? Какое там напряжение?

ki314
Offline
Зарегистрирован: 03.03.2017

Заработало...

Код 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) - не нашел, подстава подстав :)

ki314
Offline
Зарегистрирован: 03.03.2017

Спасибо за поддержку.

ki314
Offline
Зарегистрирован: 03.03.2017

Синтаксис wire.begin(int,int),где параметры являются номерами выводов  SDA и SCL работает только при компиляции скетча для ESP.

Если этот же самый код комплироать для Uno R3 - компилятор выдает ошибку и нужно писать wire.begin().

Погуглил немножко - или я плохо ищу или это нигде не описано.

Странно, что не нашел сообщений похожих на мое - неужели никто не подключал SD3231 к ESP-07?

Или все об это знают и это написано на всех заборах, а я этого не в упор не вижу???

sadman41
Offline
Зарегистрирован: 19.10.2016

Я не подключал, если вам интересно. Но теперь буду знать.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Так у нашего Атмеля пины несменяемые, хардварные без вариантов.
А у ЕСП скорее всего софтварный и2ц

ki314
Offline
Зарегистрирован: 03.03.2017

trembo пишет:
Так у нашего Атмеля пины несменяемые, хардварные без вариантов. А у ЕСП скорее всего софтварный и2ц

пробовал из любопытства переназначить пины i2c на esp-07 - не получилось. хотя я не упирался - может и можно....