UncleRus / esp-idf-lib

Component library for ESP32-xx and ESP8266
https://esp-idf-lib.readthedocs.io/en/latest/
1.38k stars 428 forks source link

Weird behavior when using ds3231 #16

Closed muhammadtalhas closed 5 years ago

muhammadtalhas commented 5 years ago

I'm messing around with the ds3231 library and it works great... most of the time.

Heres some code:

#include <stdio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <ds3231.h>
#include <stdbool.h>
#include <string.h>
#include "ssd1306.h"
#include "ssd1306_draw.h"
#include "ssd1306_font.h"
#include "ssd1306_default_if.h"

#define SDA_GPIO 21
#define SCL_GPIO 22

void ds3231_test(void *pvParameters)
{
    i2c_dev_t dev;

    while (i2cdev_init() != ESP_OK)
    {
        printf("Could not init I2Cdev library\n");
        //vTaskDelay(250 / portTICK_PERIOD_MS);
    }

    while (ds3231_init_desc(&dev, 0, SDA_GPIO, SCL_GPIO) != ESP_OK)
    {
        printf("Could not init device descriptor\n");
        //vTaskDelay(250 / portTICK_PERIOD_MS);
    }

    // setup datetime: 2016-10-09 13:50:10
    struct tm time = {
        .tm_year = 0,
        .tm_mon  = 0,  // 0-based
        .tm_mday = 0,
        .tm_hour = 0,
        .tm_min  = 0,
        .tm_sec  = 0
    };
    // while (ds3231_set_time(&dev, &time) != ESP_OK)
    // {
    //     printf("Could not set time\n");
    //     vTaskDelay(250 / portTICK_PERIOD_MS);
    // }

    while (1)
    {
        float temp;

        //vTaskDelay(250 / portTICK_PERIOD_MS);

        if (ds3231_get_temp_float(&dev, &temp) != ESP_OK)
        {
            printf("Could not get temperature\n");
            continue;
        }

        if (ds3231_get_time(&dev, &time) != ESP_OK)
        {
            printf("Could not get time\n");
            continue;
        }
        char hour[5];
        sprintf(hour,"%d",time.tm_hour);
        //itoa(time.tm_hour, hour, 10);

        char min[5];
        sprintf(min,"%d",time.tm_min);
        //itoa(time.tm_min, min, 10);

        char sec[5];
        sprintf(sec,"%d",time.tm_sec);
        //itoa(time.tm_sec, sec, 10);

        printf("%s\n", hour);
        printf("%s\n", min);
        printf("%s\n", sec);

        char timeStr[20];
        // strcat(timeStr, hour);
        // strcat(timeStr, ":");
        // strcat(timeStr, min);
        // strcat(timeStr, ":");
        // strcat(timeStr, sec);

        printf("%04d-%02d-%02d %02d:%02d:%02d, %.2f deg Cel\n", time.tm_year, time.tm_mon + 1,
            time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec, temp);

          printf("%s\n", timeStr);
    }
}

void app_main()
{
    xTaskCreate(ds3231_test, "ds3231_test", 4096, NULL, 5, NULL);
    //ds3231_test(NULL);
}

It results in this error:

Could not get temperature
E (419672) i2c: /home/talha/esp/esp-idf/components/driver/i2c.c:335 (i2c_driver_delete):i2c driver install error
E (419682) i2c: /home/talha/esp/esp-idf/components/driver/i2c.c:870 (i2c_set_pin):this i2c pin does not support internal pull-up

However, as soon as I remove the line

        char timeStr[20];

It starts pulling data no problem. No changes to the pins.

I'm farley new to ESP-IDF so I might just be doing something dumb but seems weird to me that creating the char array messes with the ability to read from the RTC

UncleRus commented 5 years ago

Oops, this is my fault. @kshyshkin investigated this bug in #12: this behavior is caused by garbage in i2c device descriptor (i2c_dev_t dev). You can fill this struct by zeroes before use:

...
i2c_dev_t dev;
memset(&dev, 0, sizeof(i2c_dev_t));
...

I've updated all examples.

muhammadtalhas commented 5 years ago

Ahh that makes sense!!

Thanks!