Thanks for the help!
One other common I2C Problem: Do you have pull-up resistors on the clock and data lines to 3V3? 2K to 5K are common values.
The ESP-32 has internal pull up resistors which I am using. Thanks for the suggestion!
I was able to get outputs working with the following code.
Code: Select all
/*
* test_main.c
*
* Created on: Jan 24, 2017
* Author: Greg
*/
#include <stdio.h>
#include "driver/i2c.h"
#define MCP23017_ADDR 0x23 /*!< slave address for MCP23017 sensor */
#define ACK_CHECK_EN 0x1
#define I2C_MASTER_NUM I2C_NUM_1 /*!< I2C port number for master dev */
#define I2C_MASTER_SCL_IO 19 /*!< gpio number for I2C master clock */
#define I2C_MASTER_SDA_IO 18 /*!< gpio number for I2C master data */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */
#define READ_BIT I2C_MASTER_READ /*!< I2C master read */
void app_main(void)
{
int i2c_master_port = I2C_MASTER_NUM;
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = I2C_MASTER_SDA_IO;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = I2C_MASTER_SCL_IO;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = I2C_MASTER_FREQ_HZ;
i2c_param_config(i2c_master_port, &conf);
i2c_driver_install(i2c_master_port, conf.mode, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0);
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
int ret;
printf("Driver Installed...\n");
printf("Moving on to outputs...\n");
i2c_master_start(cmd);
i2c_master_write_byte(cmd, MCP23017_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);//Access IODIRA
i2c_master_write_byte(cmd, 0x00, ACK_CHECK_EN);//Set all as outputs on A
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_FAIL) {
printf("ERROR\n");
}else{
printf("Passed step 1\n");
}
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, MCP23017_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x12, ACK_CHECK_EN);//Access GPIOA
i2c_master_write_byte(cmd, 11000011, ACK_CHECK_EN);// Set 0,1,6,7 as high, the rest low
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_FAIL) {
printf("ERROR\n");
}else{
printf("Passed step 2\n");
}
printf("Outputs now set...\n");
printf("Moving on to inputs...\n");
vTaskDelay(30 / portTICK_RATE_MS);
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, MCP23017_ADDR << 1 | WRITE_BIT, ACK_CHECK_EN);
i2c_master_write_byte(cmd, 0x01, ACK_CHECK_EN);// Access IODIRB
i2c_master_write_byte(cmd, 11111111, ACK_CHECK_EN); // Set all as inputs on B
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_FAIL) {
printf("ERROR\n");
}else{
printf("Passed step 3\n");
}
while(1){
vTaskDelay(30 / portTICK_RATE_MS);
int sensor_data_h;
cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
i2c_master_write_byte(cmd, MCP23017_ADDR << 1 | READ_BIT, ACK_CHECK_EN);
i2c_master_read_byte(cmd, &sensor_data_h, 0x13);//Read data back on B
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(I2C_NUM_1, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
if (ret == ESP_FAIL) {
printf("ERROR\n");
}else{
printf("Passed step 4\n");
printf("Result: %02x\n", sensor_data_h);//Should show hex value of input.
}
}
return;
}
But my inputs never return anything but 0x00.
BTW kolban I am a huge fan of your work. I've used your tutorials and ESP32 book to get to this point. Excellent job!