Announcement

REXYGEN forum has been moved. This one is closed.
Head over to the new REXYGEN Community Forum at https://forum.rexygen.com.

Looking forward to meeting you there!
 

#1 2015-11-25 20:09:23

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Integrating I2C device using REXLANG

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

#2 2015-11-26 01:00:42

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Integrating I2C device using REXLANG

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.

Offline

#3 2015-11-26 15:04:17

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Re: Integrating I2C device using REXLANG

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

#4 2015-11-26 18:11:52

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Integrating I2C device using REXLANG

Without your source files (*.mdl and *.c) there is very little I can do. Zip your files and upload it here.

Offline

#5 2015-11-27 03:22:48

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Re: Integrating I2C device using REXLANG

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

#6 2015-11-27 08:26:10

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Re: Integrating I2C device using REXLANG

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

#7 2015-11-27 17:16:58

deepak
Member
Registered: 2015-11-27
Posts: 9

Re: Integrating I2C device using REXLANG

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

#8 2015-11-28 12:38:25

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Re: Integrating I2C device using REXLANG

Yeah...It worked...!!!

Offline

#9 2015-11-28 12:40:50

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Re: Integrating I2C device using REXLANG

//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

#10 2015-11-28 20:47:47

josar
Member
From: Czech Rep.
Registered: 2015-11-03
Posts: 17

Re: Integrating I2C device using REXLANG

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

#11 2015-11-29 12:52:45

soxso2011
Member
From: India
Registered: 2015-11-25
Posts: 37

Re: Integrating I2C device using REXLANG

Yep!!

Offline

#12 2017-05-03 19:40:55

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Integrating I2C device using REXLANG

...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

REX_MCP23017.zip

Offline

Board footer

Powered by FluxBB