You are not logged in.
Pages: 1
Topic closed
How Rexlang block is used for I2C integration, I have made the connections and able to access it via command line sudo i2cdetect -y 1, but unable to integrate the same using Rexlang or any other block. The PCA9555 GPIO expander is used in my case.
Offline
Examples for integrating I2C devices are included in our GitHub repository, links in the Downloads section. After downloading, go into the "Integrating_external_devices/I2C" directory. You should be able to modify the examples for your GPIO expander.
Monarco HAT for Raspberry Pi - Lightweight I/O for monitoring, archiving and control.
Raspberry Pi in industrial automation!
Offline
Error message while compiling: validation error:109,[rex i/o driver error]in pin pca955_gpio3:value
validation error:307[file open error] in pin pca9555_task.REXLANG:srcname
Please help!
Offline
Without your source files (*.mdl and *.c) there is very little I can do. Zip your files and upload it here.
Monarco HAT for Raspberry Pi - Lightweight I/O for monitoring, archiving and control.
Raspberry Pi in industrial automation!
Offline
I am trying to interface PCA9555 I2C i/O port expander, this the following code for i/o extender mpc23017, could you please tell me what to edit for PCA9555.I am unable to access any pins.
/************************************************************
*
* REXLANG - Using the MCP23017 I/O expander via I2C
*
*************************************************************/
#define I2CDEV_FNAME 67 // I2C device is defined by the fname parameter of the REXLANG block (e.g. set it to /dev/i2c-1 on the Raspberry Pi minicomputer)
//assigning inputs to variables, these variables are READ-ONLY
long input(3) digital_out; //the signal controlling the outputs is connected to input u3 of the REXLANG block
long output(10) digital_in; //the state of the input pins is published via output y10 of the REXLANG block
//declaration of variables
long i2c_bufTx[3]; //buffer for transmitting data
long i2c_bufRx[3]; //buffer for receiving data
long i2c_bus_handle;
long i2c_chip_address;
long i2c_write_count;
long i2c_read_count;
long i2c_ret_fun;
//the init procedure is executed once when the REXLANG function block initializes
long init(void)
{
i2c_bus_handle = Open(I2CDEV_FNAME); // open I2C bus
i2c_chip_address = 0x20; // 7-bit address of the I2C device
// !!!!!!!!!!!!!
// By default, IOCON.BANK=0, therefore see Table 1-6 in the datasheet for register mapping
//
// Table 1-5, which confusingly appears sooner in the datasheet, displays register addresses
// for IOCON.BANK=1, which are significantly different
// !!!!!!!!!!!!!
//Setting PORTA to output
i2c_bufTx[0] = 0x00; //register no. (IODIRA)
i2c_bufTx[1] = 0x00; //IODIRA data, bitmask, 0=output, 1=input
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Setting PORTB to input
i2c_bufTx[0] = 0x01; //register no. (IODIRB)
i2c_bufTx[1] = 0xFF; //IODIRB data, bitmask, 0=output, 1=input
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Enabling pull-up resistors on PORTB
i2c_bufTx[0] = 0x0D; //register no. (GPPUB)
i2c_bufTx[1] = 0xFF; //GPPUB data, bitmask, 0=no pull-up, 1=pull-up enabled
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
return 0;
}
//the main procedure is executed once in each sampling period
long main(void)
{
//Controlling outputs
i2c_bufTx[0] = 0x12; //register no. (GPIOA)
i2c_bufTx[1] = digital_out & 0xFF; //masking the data to control the outputs
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Reading inputs
i2c_bufTx[0] = 0x13; //register no. (GPIOB)
i2c_write_count = 1;
i2c_read_count = 1;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
digital_in = i2c_bufRx[0]; //publishing the received data
return 0;
}
//the exit procedure is executed once when the task is correctly terminated
// (system shutdown, downloading new control algorithm, etc.)
long exit(void)
{
if(i2c_bus_handle>=0) Close(i2c_bus_handle); // close I2C bus
return 0;
}
Offline
This is the file I edited for interfacing PCA9555. I have changed the register addresses accordingly in the below program but still unable to access pins. In the c code example for MCP23017, It says By default, IOCON.BANK=0. How to edit this parameter because in PCA9555 both banks are of 8 bit addressing. Please help
/************************************************************
*
* REXLANG - Using the MCP23017 I/O expander via I2C
*
*************************************************************/
#define I2CDEV_FNAME 67 // I2C device is defined by the fname parameter of the REXLANG block (e.g. set it to /dev/i2c-1 on the Raspberry Pi minicomputer)
//assigning inputs to variables, these variables are READ-ONLY
long input(3) digital_out; //the signal controlling the outputs is connected to input u3 of the REXLANG block
long output(10) digital_in; //the state of the input pins is published via output y10 of the REXLANG block
//declaration of variables
long i2c_bufTx[3]; //buffer for transmitting data
long i2c_bufRx[3]; //buffer for receiving data
long i2c_bus_handle;
long i2c_chip_address;
long i2c_write_count;
long i2c_read_count;
long i2c_ret_fun;
//the init procedure is executed once when the REXLANG function block initializes
long init(void)
{
i2c_bus_handle = Open(I2CDEV_FNAME); // open I2C bus
i2c_chip_address = 0x20; // 7-bit address of the I2C device
// !!!!!!!!!!!!!
// , therefore see Table 1-6 in the datasheet for register mapping
//
// Table 1-5, which confusingly appears sooner in the datasheet, displays register addresses
// for IOCON.BANK=1, which are significantly different
// !!!!!!!!!!!!!
//Setting PORTA to output
i2c_bufTx[0] = 0x06; //register no. (IODIRA)
i2c_bufTx[1] = 0x00; //IODIRA data, bitmask, 0=output, 1=input
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Setting PORTB to input
i2c_bufTx[0] = 0x07; //register no. (IODIRB)
i2c_bufTx[1] = 0xFF; //IODIRB data, bitmask, 0=output, 1=input
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Enabling pull-up resistors on PORTB
i2c_bufTx[0] = 0x0D; //register no. (GPPUB)
i2c_bufTx[1] = 0xFF; //GPPUB data, bitmask, 0=no pull-up, 1=pull-up enabled
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
return 0;
}
//the main procedure is executed once in each sampling period
long main(void)
{
//Controlling outputs
i2c_bufTx[0] = 0x06; //register no. (GPIOA)
i2c_bufTx[1] = digital_out & 0xFF; //masking the data to control the outputs
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Reading inputs
i2c_bufTx[0] = 0x07; //register no. (GPIOB)
i2c_write_count = 1;
i2c_read_count = 1;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
digital_in = i2c_bufRx[0]; //publishing the received data
return 0;
}
//the exit procedure is executed once when the task is correctly terminated
// (system shutdown, downloading new control algorithm, etc.)
long exit(void)
{
if(i2c_bus_handle>=0) Close(i2c_bus_handle); // close I2C bus
return 0;
}
Offline
I faced the same problem !. Dont bother with the IOCON.BANK attribute in the c program. Your address for configuring Port A & Port B are correct.(0x06 & 0x07) This is the part of the program what you must edit to read Bank 0 of PCA 9555 as Output and Bank 1 as input.
//the main procedure is executed once in each sampling period
long main(void)
{
//Controlling outputs
i2c_bufTx[0] = 0x06; //CHANGE 0x06 TO 0x02 (REFER PCA 9555 DATASHEET)
i2c_bufTx[1] = digital_out & 0xFF; //masking the data to control the outputs
i2c_write_count = 2;
i2c_read_count = 0;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
//Reading inputs
i2c_bufTx[0] = 0x07; //CHANGE 0x07 TO 0x01 (REFER PCA 9555 DATASHEET)
i2c_write_count = 1;
i2c_read_count = 1;
i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
digital_in = i2c_bufRx[0]; //publishing the received data
return 0;
}
This worked for me successfully.
Offline
Yeah...It worked...!!!
Offline
//Sending data via I2C
i2c_ret_fun = I2C(i2c_port_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count);
adc_value = (i2c_bufRx[0]<<8) + i2c_bufRx[1];
Is there any syntax error in these lines??
Offline
I do not see any syntax error. However, the problem is probably the variable i2c_port_handle, which you should change to i2c_bus_handle, as you were instructed in the other topic. Check the definitions of variables at the beginning of your code. You'll probably find this definition of a variable:
long i2c_bus_handle;
So that's why you get an error when compiling and why you have to make this change.
Offline
Yep!!
Offline
...an example with port expander MCP23017 (soxso2011, I hope you don't mind I used a part of your script)
8 inputs and 8 outputs
Offline
Pages: 1
Topic closed