Problems reading from PCF8574A
-
Hello, I am Alexander and probing a lot with Rexygen, with good results until now. However, at this moment I am trying to read data from a PCF8574A, without succes. I am new with respect to the Rexlang block and i2c.
Below my code:
/************************************************************
*- REXLANG - Using the PCF8574A as Digital Input via I2C
*************************************************************/
string parameter(0) i2c_dev; // the I2C bus is defined by the p0 parameter
//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 = OpenI2C(i2c_dev); // open I2C bus
i2c_chip_address = 0x38; // 7-bit address of the I2C devicei2c_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)
{
//Reading inputs
i2c_bufTx[0] = 0x71; //Slave address (0x38) including the reading bit (1)
i2c_bufTx[1] = digital_out; //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);//Controlling outputs i2c_write_count = 0; i2c_read_count = 1; digital_in = i2c_bufRx[0]; //publishing the received data i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count); 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;
}Hopefully somebody can help me and tell/show me what I am doing wrong.
-
@AlexanderH Hi Alexander,
do you see any error messages in the system log? If so, what kind?Does setting the outputs work as expected?
When reading inputs, I think you should both write and read within the same I2C() call — in other words, both counters should be non-zero. Usually, sending a request and receiving a response over I²C takes much less time than the REXYGEN task execution period. That’s why the I2C() function is designed to send data and, if a response is expected, receive it within the same cycle. I don’t know the exact details of the PCF8574A protocol, but I would assume that you need to perform the write and the read together in one call.
By the way, the code you pasted looks a bit broken here on the forum – that’s probably due to Markdown formatting. Please enclose the entire script in a code block using triple backticks (```) or upload it here as a text file. That way it will be much easier to read.
Cheers,
Jan -
@Jan-Reitinger Hi Jan,
I tried already several things. So much I lost count already.
I dont get any error in the system log screen. But i think i am not getting it in the read modus.Hopefully somebody can help me with this problem.
With kind regards,
Alexander -
@Jan-Reitinger , Dear Jan,
yesterday I was not in the opportunity to include the code. Below the (little modified) code in a better way. Thank you already very much for your reply.
* * REXLANG - Using the PCF8574A as Digital Input via I2C * *************************************************************/ string parameter(0) i2c_dev; // the I2C bus is defined by the p0 parameter //assigning inputs to variables, these variables are READ-ONLY 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 = OpenI2C(i2c_dev); // open I2C bus i2c_chip_address = 0x38; // 7-bit address of the I2C device 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) { //Reading inputs i2c_bufTx[0] = 0xFF; //Slave address (0x38) including the reading bit (1) i2c_write_count = 1; i2c_read_count = 0; i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count); //Controlling outputs i2c_write_count = 0; i2c_read_count = 1; digital_in = i2c_bufRx[0]; //publishing the received data i2c_ret_fun = I2C(i2c_bus_handle, i2c_chip_address, i2c_bufTx, i2c_write_count, i2c_bufRx, i2c_read_count); 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; }
-
@Jan-Reitinger, Hi Jan,
I solved the problem and can read from the PCF8574.
Thank you very much for pointing me in the right direction :-).So this problem is solved -).
With kind regards,
Alexander -
@AlexanderH Hi,
I'm sorry. For some reason I didn't get an email notifying me that you had replied. I'm glad you finally resolved the issue.Cheers,
Jan