Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trying to use ds1307 with ssd1306 oled #74

Closed
2 tasks done
VedantParanjape opened this issue Apr 15, 2020 · 14 comments
Closed
2 tasks done

Trying to use ds1307 with ssd1306 oled #74

VedantParanjape opened this issue Apr 15, 2020 · 14 comments
Labels
question Further information is requested

Comments

@VedantParanjape
Copy link

VedantParanjape commented Apr 15, 2020

Devcie type

  • ESP32

Framework version

  • ESP-IDF latest master

Describe the bug
I am using https://github.com/TaraHoleInIt/tarablessd1306 to drive the oled. When i try to use both in the same code, ESP crashes.

Error Log from serial monitor
Code:

// #include <stdio.h>
// #include <freertos/FreeRTOS.h>
// #include <freertos/task.h>
// #include "ds1307.h"
// #include <string.h>
// #include "esp_log.h"

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

#define SDA_GPIO 5
#define SCL_GPIO 18

void ds1307_test(void *pvParameters)
{
    i2c_dev_t dev;
    memset(&dev, 0, sizeof(i2c_dev_t));

    ESP_ERROR_CHECK(ds1307_init_desc(&dev, 0, SDA_GPIO, SCL_GPIO));
    struct tm time ;
    // = {
    //     .tm_year = 2020,
    //     .tm_mon  = 4,  // 0-based
    //     .tm_mday = 15,
    //     .tm_hour = 01,
    //     .tm_min  = 01,
    //     .tm_sec  = 00
    // };
    // ds1307_set_time(&dev, &time);

    while (1)
    {
        ds1307_get_time(&dev, &time);

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

        vTaskDelay(500 / portTICK_PERIOD_MS);
    }
}


#define USE_I2C_DISPLAY
#define USE_SPI_DISPLAY

#if defined USE_I2C_DISPLAY
    static const int I2CDisplayAddress = 0x3C;
    static const int I2CDisplayWidth = 128;
    static const int I2CDisplayHeight = 64;
    static const int I2CResetPin = -1;

    struct SSD1306_Device I2CDisplay;
#endif

#if defined USE_SPI_DISPLAY
    static const int SPIDisplayChipSelect = 15;
    static const int SPIDisplayWidth = 128;
    static const int SPIDisplayHeight = 64;
    static const int SPIResetPin = 5;

    struct SSD1306_Device SPIDisplay;
#endif

static struct SSD1306_Device* Displays[ ] = {
#if defined USE_I2C_DISPLAY
    &I2CDisplay,
#endif
#if defined USE_SPI_DISPLAY
    &SPIDisplay,
#endif
    NULL
};

const int DisplayCount = sizeof( Displays ) / sizeof( Displays[ 0 ] );

const struct SSD1306_FontDef* FontList[ ] = {
    &Font_droid_sans_fallback_11x13,
    &Font_droid_sans_fallback_15x17,
    &Font_droid_sans_fallback_24x28,
    &Font_droid_sans_mono_7x13,
    &Font_droid_sans_mono_13x24,
    &Font_droid_sans_mono_16x31,
    &Font_liberation_mono_9x15,
    &Font_liberation_mono_13x21,
    &Font_liberation_mono_17x30,
    NULL
};

const int FontCount = sizeof( FontList ) / sizeof( FontList[ 0 ] );

void SetupDemo( struct SSD1306_Device* DisplayHandle, const struct SSD1306_FontDef* Font );
void SayHello( struct SSD1306_Device* DisplayHandle, const char* HelloText );

bool DefaultBusInit( void ) {
    #if defined USE_I2C_DISPLAY
        assert( SSD1306_I2CMasterInitDefault( ) == true );
        assert( SSD1306_I2CMasterAttachDisplayDefault( &I2CDisplay, I2CDisplayWidth, I2CDisplayHeight, I2CDisplayAddress, I2CResetPin ) == true );
    #endif

    #if defined USE_SPI_DISPLAY
        assert( SSD1306_SPIMasterInitDefault( ) == true );
        assert( SSD1306_SPIMasterAttachDisplayDefault( &SPIDisplay, SPIDisplayWidth, SPIDisplayHeight, SPIDisplayChipSelect, SPIResetPin ) == true );
    #endif

    return true;
}

void FontDisplayTask( void* Param ) {
    struct SSD1306_Device* Display = ( struct SSD1306_Device* ) Param;
    int NextFontTime = 0;
    int i = 0;

    if ( Param != NULL ) {
        for ( i = 0; i < FontCount && FontList[ i ] != NULL; i++ ) {
            if ( FontList[ i ] != NULL ) {
                SSD1306_SetFont( Display, FontList[ i ] );
                NextFontTime = time( NULL ) + 2;

                while ( time( NULL ) < NextFontTime ) {
                    SSD1306_Clear( Display, SSD_COLOR_BLACK );
                    SSD1306_FontDrawAnchoredString( Display, TextAnchor_Center, "Hello!", SSD_COLOR_WHITE );
                    SSD1306_Update( Display );

                    vTaskDelay( pdMS_TO_TICKS( 100 ) );
                }

                printf( "On to next font\n" );
            }
        }
    }

    printf( "Finished!\n" );
    vTaskDelete( NULL );
}

void app_main( void ) {
    int i = 0;
    xTaskCreate(ds1307_test, "ds1307_test", 2048, NULL, 5, NULL);
    printf( "Ready...\n" );

    if ( DefaultBusInit( ) == true ) {
        printf( "BUS Init lookin good...\n" );
        printf( "Drawing.\n" );

        for ( i = 0; i < DisplayCount; i++ ) {
            if ( Displays[ i ] != NULL ) {
                xTaskCreate( FontDisplayTask, "FontDisplayTask", 4096, Displays[ i ], 1, NULL );
            }
        }
    }
}
@UncleRus
Copy link
Owner

UncleRus commented Apr 15, 2020

Code of ssd1306 driver does not use i2cdev library which is the core of all i2c drivers in this repo.
You can make a pull request to https://github.com/TaraHoleInIt/tarablessd1306 to support usage with esp-idf-lib.

@VedantParanjape
Copy link
Author

How do i port to use i2cdev?

@UncleRus
Copy link
Owner

See https://github.com/TaraHoleInIt/tarablessd1306/blob/master/ifaces/default_if_i2c.c
Something like

#ifdef CONFIG_USE_I2CDEV_LIB
#include <i2cdev.h>
#endif
...
#ifdef CONFIG_USE_I2CDEV_LIB
static i2c_dev_t dev;
#endif
...
bool SSD1306_I2CMasterInitDefault( void ) {
#ifdef CONFIG_USE_I2CDEV_LIB
    ESP_ERROR_CHECK_NONFATAL( i2cdev_init(), return false );
    memset (&dev, 0, sizeof( i2c_dev_t ) );
    dev.port = 0;
    dev.addr = I2CAddress;
    dev.cfg.sda_io_num = SDAPin;
    dev.cfg.sda_pullup_en = GPIO_PULLUP_ENABLE;
    dev.cfg.scl_io_num = SCLPin;
    dev.cfg.scl_pullup_en = GPIO_PULLUP_ENABLE;
    dev.cfg.master.clk_speed = I2CDisplaySpeed;
    ESP_ERROR_CHECK_NONFATAL( i2c_dev_create_mutex(dev), return false );
#else
    ...
#endif
    return true;
}
...
static bool I2CDefaultWriteBytes( int Address, bool IsCommand, const uint8_t* Data, size_t DataLength ) {
#ifdef CONFIG_USE_I2CDEV_LIB
    NullCheck( Data, return false );
    ESP_ERROR_CHECK_NONFATAL( i2c_dev_take_mutex( &dev ), return false );
    ESP_ERROR_CHECK_NONFATAL( i2c_dev_write_reg( &dev, ( IsCommand == true ) ? SSD1306_I2C_COMMAND_MODE: SSD1306_I2C_DATA_MODE, Data, DataLength ), 
        do { i2c_dev_give_mutex( &dev ); return false; } while (0) );
    ESP_ERROR_CHECK_NONFATAL( i2c_dev_give_mutex( &dev ); return false );
#else
    ...
#endif
    return true;
}

@UncleRus
Copy link
Owner

Of course, you will need the appropriate changes to the Kconfig of ssd1306 driver and its makefiles.

@VedantParanjape
Copy link
Author

VedantParanjape commented Apr 17, 2020

Cool, Thanks for the help.

I will close the issue.

@chandanchan0086
Copy link

chandanchan0086 commented Apr 28, 2021

@VedantParanjape is this issue solved?

now I'm facing the same problem but instead of ds1307, I'm using qmc5883l with ssd1306 OLED.

if you got a solution please help me out with this.

@VedantParanjape
Copy link
Author

VedantParanjape commented Apr 28, 2021

@VedantParanjape is this issue solved?

now I'm facing the same problem but instead of ds1307, I'm using qmc5883l with ssd1306 OLED.

if you got a solution please help me out with this.

I don't remember, but I ditched that OLED library use u8g2 instead and it works fine with this driver.

@chandanchan0086
Copy link

@VedantParanjape thank you for your quick response,

Using any library is ok with me. Finally I need to integrate qmc5883l magneto meter and ssd1306oled.
Is that ok to share sample working code. I really got stuck since am new to esp-idf.

@VedantParanjape
Copy link
Author

@VedantParanjape thank you for your quick response,

Using any library is ok with me. Finally I need to integrate qmc5883l magneto meter and ssd1306oled.
Is that ok to share sample working code. I really got stuck since am new to esp-idf.

https://github.com/VedantParanjape/esp-2fa

@chandanchan0086
Copy link

chandanchan0086 commented Apr 29, 2021 via email

@chandanchan0086
Copy link

@VedantParanjape this issue is solved and thank you so much for your time and help.

@VedantParanjape
Copy link
Author

@VedantParanjape this issue is solved and thank you so much for your time and help.

Welcome :)

@politsin
Copy link

politsin commented Sep 8, 2021

Спасибо! у меня в итоге заработало!
приложу код, вдруг кому пригодися:

CMakeLists.txt добавить стрчку REQUIRES i2cdev log esp_idf_lib_helpers
component.mk добавить стрчку COMPONENT_DEPENDS = i2cdev log esp_idf_lib_helpers

default_if_i2c.c

// i2c.
#include "i2cdev.h"
#include <esp_err.h>
#include <esp_idf_lib_helpers.h>
#include <esp_log.h>
static i2c_dev_t dev;
#define SSD1360_DEVICE_ADDRESS 0x3C
...
esp_err_t SSD1306_I2CMasterInitDefault(i2c_port_t port, gpio_num_t sda_gpio,
                                       gpio_num_t scl_gpio) {
  ESP_ERROR_CHECK_NONFATAL(i2cdev_init(), return false);
  memset(&dev, 0, sizeof(i2c_dev_t));
  dev.port = port;
  dev.addr = SSD1360_DEVICE_ADDRESS;
  dev.cfg.sda_io_num = sda_gpio;
  dev.cfg.scl_io_num = scl_gpio;
  dev.cfg.sda_pullup_en = GPIO_PULLUP_ENABLE;
  dev.cfg.scl_pullup_en = GPIO_PULLUP_ENABLE;
  dev.cfg.master.clk_speed = 100000;
  ESP_ERROR_CHECK_NONFATAL(i2c_dev_create_mutex(&dev), return false);
  return true;
}
...
bool SSD1306_I2CMasterAttachDisplayDefault(struct SSD1306_Device *DisplayHandle,
                                           int Width, int Height, int RSTPin) {
  NullCheck(DisplayHandle, return false);
  return SSD1306_Init_I2C(DisplayHandle, Width, Height, SSD1360_DEVICE_ADDRESS,
                          RSTPin, I2CDefaultWriteCommand, I2CDefaultWriteData,
                          I2CDefaultReset);
}
...
static bool I2CDefaultWriteBytes(int Address, bool IsCommand,
                                 const uint8_t *Data, size_t DataLength) {

  NullCheck(Data, return false);
  ESP_ERROR_CHECK_NONFATAL(i2c_dev_take_mutex(&dev), return false);
  ESP_ERROR_CHECK_NONFATAL(
      i2c_dev_write_reg(&dev,
                        (IsCommand == true) ? SSD1306_I2C_COMMAND_MODE
                                            : SSD1306_I2C_DATA_MODE,
                        Data, DataLength),
      do {
        i2c_dev_give_mutex(&dev);
        return false;
      } while (0));
  ESP_ERROR_CHECK_NONFATAL(i2c_dev_give_mutex(&dev), return false);
  return true;
}

ssd1306_default_if.h

esp_err_t SSD1306_I2CMasterInitDefault(i2c_port_t port, gpio_num_t sda_gpio,
                                       gpio_num_t scl_gpio);
bool SSD1306_I2CMasterAttachDisplayDefault(struct SSD1306_Device *DisplayHandle,
                                           int Width, int Height, int RSTPin);

Task

void clear() {
  SSD1306_Clear(&I2Cdspl, SSD_COLOR_BLACK);
  SSD1306_Update(&I2Cdspl);
}
void displayTask(void *pvParam) {
  i2cdev_init();
  SSD1306_I2CMasterInitDefault(I2C_NUM_0, (gpio_num_t)19, (gpio_num_t)23);
  SSD1306_I2CMasterAttachDisplayDefault(&I2Cdisplay, displayWidth, displayHeight, displaylPin);
  SetupDemo(&I2Cdisplay, &Font_droid_sans_fallback_24x28);
  SayHello(&I2Cdspl, "Hello world!");
  while (true) {
    clear();
    SayHello(&I2Cdisplay, "Hello world!");
    vTaskDelay(1500 / portTICK_PERIOD_MS);
    clear();
    SayHello(&I2Cdisplay, "---");
    vTaskDelay(1500 / portTICK_PERIOD_MS);
  }
}

@VedantParanjape
Copy link
Author

Спасибо! у меня в итоге заработало!
приложу код, вдруг кому пригодися:

CMakeLists.txt добавить стрчку REQUIRES i2cdev log esp_idf_lib_helpers
component.mk добавить стрчку COMPONENT_DEPENDS = i2cdev log esp_idf_lib_helpers

default_if_i2c.c

// i2c.
#include "i2cdev.h"
#include <esp_err.h>
#include <esp_idf_lib_helpers.h>
#include <esp_log.h>
static i2c_dev_t dev;
#define SSD1360_DEVICE_ADDRESS 0x3C
...
esp_err_t SSD1306_I2CMasterInitDefault(i2c_port_t port, gpio_num_t sda_gpio,
                                       gpio_num_t scl_gpio) {
  ESP_ERROR_CHECK_NONFATAL(i2cdev_init(), return false);
  memset(&dev, 0, sizeof(i2c_dev_t));
  dev.port = port;
  dev.addr = SSD1360_DEVICE_ADDRESS;
  dev.cfg.sda_io_num = sda_gpio;
  dev.cfg.scl_io_num = scl_gpio;
  dev.cfg.sda_pullup_en = GPIO_PULLUP_ENABLE;
  dev.cfg.scl_pullup_en = GPIO_PULLUP_ENABLE;
  dev.cfg.master.clk_speed = 100000;
  ESP_ERROR_CHECK_NONFATAL(i2c_dev_create_mutex(&dev), return false);
  return true;
}
...
bool SSD1306_I2CMasterAttachDisplayDefault(struct SSD1306_Device *DisplayHandle,
                                           int Width, int Height, int RSTPin) {
  NullCheck(DisplayHandle, return false);
  return SSD1306_Init_I2C(DisplayHandle, Width, Height, SSD1360_DEVICE_ADDRESS,
                          RSTPin, I2CDefaultWriteCommand, I2CDefaultWriteData,
                          I2CDefaultReset);
}
...
static bool I2CDefaultWriteBytes(int Address, bool IsCommand,
                                 const uint8_t *Data, size_t DataLength) {

  NullCheck(Data, return false);
  ESP_ERROR_CHECK_NONFATAL(i2c_dev_take_mutex(&dev), return false);
  ESP_ERROR_CHECK_NONFATAL(
      i2c_dev_write_reg(&dev,
                        (IsCommand == true) ? SSD1306_I2C_COMMAND_MODE
                                            : SSD1306_I2C_DATA_MODE,
                        Data, DataLength),
      do {
        i2c_dev_give_mutex(&dev);
        return false;
      } while (0));
  ESP_ERROR_CHECK_NONFATAL(i2c_dev_give_mutex(&dev), return false);
  return true;
}

ssd1306_default_if.h

esp_err_t SSD1306_I2CMasterInitDefault(i2c_port_t port, gpio_num_t sda_gpio,
                                       gpio_num_t scl_gpio);
bool SSD1306_I2CMasterAttachDisplayDefault(struct SSD1306_Device *DisplayHandle,
                                           int Width, int Height, int RSTPin);

Task

void clear() {
  SSD1306_Clear(&I2Cdspl, SSD_COLOR_BLACK);
  SSD1306_Update(&I2Cdspl);
}
void displayTask(void *pvParam) {
  i2cdev_init();
  SSD1306_I2CMasterInitDefault(I2C_NUM_0, (gpio_num_t)19, (gpio_num_t)23);
  SSD1306_I2CMasterAttachDisplayDefault(&I2Cdisplay, displayWidth, displayHeight, displaylPin);
  SetupDemo(&I2Cdisplay, &Font_droid_sans_fallback_24x28);
  SayHello(&I2Cdspl, "Hello world!");
  while (true) {
    clear();
    SayHello(&I2Cdisplay, "Hello world!");
    vTaskDelay(1500 / portTICK_PERIOD_MS);
    clear();
    SayHello(&I2Cdisplay, "---");
    vTaskDelay(1500 / portTICK_PERIOD_MS);
  }
}

English please !

@UncleRus UncleRus added the question Further information is requested label Jan 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

4 participants