UncleRus / esp-idf-lib

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

Adafruit Seesaw #207

Closed kickhad closed 3 years ago

kickhad commented 3 years ago

I am requesting a driver for ABC-123.

Seesaw is an open source microcontroller friend for other chips. It provides a variety of capabilities such as UART, ADC, DAC, extra GPIO, etc. to chips that don't have them.

I2C.

ABC-123 is a chip to do a great thing. It supports both SPI and I2C. It supports VDD from 3.3V to 5V. You can use it for saving the world.

Device information

The product information and the data sheet can be found at: https://github.com/adafruit/Adafruit-STEMMA-Soil-Sensor-PCB

Purchasing the product

The device can be purchased at:

The URLs where you can buy the device are:

https://www.adafruit.com/?q=seesaw&sort=BestMatch

Other implementation

There is an Arduino driver here https://github.com/adafruit/Adafruit_Seesaw There is a CircuitPython driver here https://github.com/adafruit/Adafruit_CircuitPython_seesaw Seesaw firmware. https://github.com/adafruit/seesaw

Sample ESPIDF implementation working:

UncleRus commented 3 years ago

Sorry, but I do not want to develop a driver for Adafruit Seesaw, because this is just another external "all-in-one" device based on a microcontroller, whose functions are not declared in the datasheet and depends only on its firmware.

Simply put, drivers for such devices are difficult to maintain.

If you want to use this device in your project you can just write simple code with i2cdev lib.

UncleRus commented 3 years ago

BTW if all you need is a soil sensor, you can just use simple capacitive sensor and ADC.

https://www.aliexpress.com/item/32864255890.html

kickhad commented 3 years ago

That's fair, I'll consider the ADC route, and I'll tinker with a fork.

I got stuck using your i2cdev because it needs 3 consecutive write_byte. Is there a "prototype" or cookiecutter you use for a new device?

Cheers

i2c_master_write_byte(read_moisture_cmd, STEMMA_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(read_moisture_cmd, STEMMA_MOISTURE_BASE_REG, ACK_CHECK_EN);
i2c_master_write_byte(read_moisture_cmd, STEMMA_MOISTURE_FUNC_REG, ACK_CHECK_EN);

i2c_cmd_handle_t read_moisture_cmd = i2c_cmd_link_create();
i2c_master_start(read_moisture_cmd);
i2c_master_write_byte(read_moisture_cmd, STEMMA_SENSOR_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(read_moisture_cmd, STEMMA_MOISTURE_BASE_REG, ACK_CHECK_EN);
i2c_master_write_byte(read_moisture_cmd, STEMMA_MOISTURE_FUNC_REG, ACK_CHECK_EN);
i2c_master_stop(read_moisture_cmd);
ret = i2c_master_cmd_begin(i2c_num, read_moisture_cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(read_moisture_cmd);
vTaskDelay((50) / portTICK_RATE_MS);

// Now read sensor value
read_moisture_cmd = i2c_cmd_link_create();
i2c_master_start(read_moisture_cmd);
i2c_master_write_byte(read_moisture_cmd, STEMMA_SENSOR_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read(read_moisture_cmd, moisture_data, len - 1, ACK_VAL);
i2c_master_read_byte(read_moisture_cmd, moisture_data + len - 1, NACK_VAL); //second parameter is pointer to byte len-1 in data buffer
i2c_master_stop(read_moisture_cmd);
ret = i2c_master_cmd_begin(i2c_num, read_moisture_cmd, 1000 / portTICK_RATE_MS);

Sorry, but I do not want to develop a driver for Adafruit Seesaw, because this is just another external "all-in-one" device based on a microcontroller, whose functions are not declared in the datasheet and depends only on its firmware.

Simply put, drivers for such devices are difficult to maintain.

If you want to use this device in your project you can just write simple code with i2cdev lib.

UncleRus commented 3 years ago
// configure i2c_dev_t first
i2c_dev_t dev;
dev.port = port;
dev.addr = addr;
dev.cfg.sda_io_num = sda_gpio;
dev.cfg.scl_io_num = scl_gpio;
dev.cfg.master.clk_speed = I2C_FREQ_HZ;

...

// then you can create mutex for this device (optional, needed for thread safety)
if (i2c_dev_create_mutex(&dev) != ESP_OK) { ... }

...

// now it's ready to read/write

// if you using device mutex, take it before transaction
if (i2c_dev_take_mutex(&dev) != ESP_OK) { ... }

// let's read from device
uint8_t out_buf[2] = { STEMMA_MOISTURE_BASE_REG, STEMMA_MOISTURE_FUNC_REG };
uint8_t in_buf[SOME_SIZE];
if (i2c_dev_read(&dev, out_buf, sizeof(out_buf), in_buf, SOME_SIZE) == ESP_OK)
{
    // you got the data, use it
    ...
}

// do not forget to release mutex if needed
if (i2c_dev_give_mutex(&dev) != ESP_OK) { ... }
kickhad commented 3 years ago

Awesome! I spent half the night trying to get it to work.