Hi,
Is there any way to simulate a full I2C bidirectional communication link using Flowcode to test the program?
Also, do you have any additional I2C program examples and documentation for the I2C component?
Thank you,
Ralph
I2C Simulation
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: I2C Simulation
Hello Ralph
The I2C is currently only operational in master mode via Flowcode. This means that you cannot currently use it as a bus between two microcontrollers. Maybe the RS232 or SPI bus would be ok for you to use.
You can use Flowcode to test your programs by queing up bytes in the component receive buffer.
The I2C is currently only operational in master mode via Flowcode. This means that you cannot currently use it as a bus between two microcontrollers. Maybe the RS232 or SPI bus would be ok for you to use.
You can use Flowcode to test your programs by queing up bytes in the component receive buffer.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Re: I2C Simulation
Hi Ben,
The master mode is what I need.
What I am trying to do is communicate with a Smart Battery over the SMBUS. The battery can be a master for event driven messages, however it will act as a slave when polled for data. That is how I intend to use it.
The battery pack is the nl2044hd22 manufactured by Inspired Energy (http://www.inspired-energy.com). From their data sheet the read word protocol is below.
http://www.inspired-energy.com/Standard ... NL2044.htm NL2044HD22 (High Current Discharge version) Engineering data sheet, page 12.
____________________________
3.3.4.2.Read Word
Reading data is slightly more complex than writing data. First the host must write a command to the slave device.
Then it must follow that command with a repeated start condition to denote a read from that device's address. The
slave then returns two bytes of data.
Note that there is not a stop condition before the repeated start condition, and that a "Not Acknowledge" signifies
the end of the read transfer.
I couldn't figure out how to paste in the "Read Word" bit definition image from the data sheet, so here goes:
Bits Descritpion
1 Start
7 Battery Address
1 Write
1 Ack
8 Command Code
1 Ack
1 Start
7 Battery Address
1 Read
1 Ack
8 Data Byte Low
1 Ack
8 Data Byte High
1 Ack
Read Word Protocol
SMBus Host (master) Smart Battery (slave)
____________________________________________
What I have tried is:
1. MI2C_Init
2. MI2C_Start
3. MI2C_Transmit_Byte (0x16 is the address with the LSB=0)
4. MI2C_Transmit_Byte (0x09 is the Command Code for reading the voltage)
5. MI2C_Start_Restart
6. MI2C_Transmit_Byte (0x17 is the address with the LSB=1)
7. MI2C_Receive_Btye (I set the β€Last(BYTE)=1 and a variable β€LOWβ€ for the return value)
8. MI2C_Receive_Btye (I set the β€Last(BYTE)=0 and a variable β€HIGHβ€ for the return value)
9. MI2C_Stop
I am receiving ACKs when addressing the battery and sending the command code, however, I can not receive any data.
I’m not sure if the problem is with sending the command code or the receive command.
My understanding of communicating with a slave is that the master generates the clock on the SCL line and the slave returns the data during this period on the SDA line.
Does the PIC generate the clock during the β€MI2C_Receive_Btyeβ€ command?
What is the purpose of the β€Last(BYTE)β€ field in the β€MI2C_Receive_Btyeβ€ command?
Do you have any thoughts on my communication problem? Any help would be much appreciated.
Thank you,
Ralph
The master mode is what I need.
What I am trying to do is communicate with a Smart Battery over the SMBUS. The battery can be a master for event driven messages, however it will act as a slave when polled for data. That is how I intend to use it.
The battery pack is the nl2044hd22 manufactured by Inspired Energy (http://www.inspired-energy.com). From their data sheet the read word protocol is below.
http://www.inspired-energy.com/Standard ... NL2044.htm NL2044HD22 (High Current Discharge version) Engineering data sheet, page 12.
____________________________
3.3.4.2.Read Word
Reading data is slightly more complex than writing data. First the host must write a command to the slave device.
Then it must follow that command with a repeated start condition to denote a read from that device's address. The
slave then returns two bytes of data.
Note that there is not a stop condition before the repeated start condition, and that a "Not Acknowledge" signifies
the end of the read transfer.
I couldn't figure out how to paste in the "Read Word" bit definition image from the data sheet, so here goes:
Bits Descritpion
1 Start
7 Battery Address
1 Write
1 Ack
8 Command Code
1 Ack
1 Start
7 Battery Address
1 Read
1 Ack
8 Data Byte Low
1 Ack
8 Data Byte High
1 Ack
Read Word Protocol
SMBus Host (master) Smart Battery (slave)
____________________________________________
What I have tried is:
1. MI2C_Init
2. MI2C_Start
3. MI2C_Transmit_Byte (0x16 is the address with the LSB=0)
4. MI2C_Transmit_Byte (0x09 is the Command Code for reading the voltage)
5. MI2C_Start_Restart
6. MI2C_Transmit_Byte (0x17 is the address with the LSB=1)
7. MI2C_Receive_Btye (I set the β€Last(BYTE)=1 and a variable β€LOWβ€ for the return value)
8. MI2C_Receive_Btye (I set the β€Last(BYTE)=0 and a variable β€HIGHβ€ for the return value)
9. MI2C_Stop
I am receiving ACKs when addressing the battery and sending the command code, however, I can not receive any data.
I’m not sure if the problem is with sending the command code or the receive command.
My understanding of communicating with a slave is that the master generates the clock on the SCL line and the slave returns the data during this period on the SDA line.
Does the PIC generate the clock during the β€MI2C_Receive_Btyeβ€ command?
What is the purpose of the β€Last(BYTE)β€ field in the β€MI2C_Receive_Btyeβ€ command?
Do you have any thoughts on my communication problem? Any help would be much appreciated.
Thank you,
Ralph
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: I2C Simulation
Hello Ralph
The last byte variable tells the I2C slave device that no more bytes will be read. So you will need to send a 0 for the first byte and a 1 for the second byte.
Also have you used pull up resistors on the line. The I2C driver cannot pull up the line to +5V so it requires the two pull up resistors.
The last byte variable tells the I2C slave device that no more bytes will be read. So you will need to send a 0 for the first byte and a 1 for the second byte.
Also have you used pull up resistors on the line. The I2C driver cannot pull up the line to +5V so it requires the two pull up resistors.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Re: I2C Simulation
Hi Ben,
You are correct! I sent a a 0 for the first byte and a 1 for the second byte and received the correct data.
Now I have another question regarding processing the data received. Since I am receivig the data in a High Byte and a Low Byte I need to combond them to be a useful number. For example, the battery voltage is sent in mV from the battery:
High Byte = 64
Low Byte = 119
Normally I would do the following to get the correct number:
Voltage = (High Byte * 256)+Low Byte ==> (64*256)+119 = 16536 mV
Using this equation I run into a problem as the answer is limited to 1 byte, or 256.
How would you do this operation?
Thank you,
Ralph
You are correct! I sent a a 0 for the first byte and a 1 for the second byte and received the correct data.
Now I have another question regarding processing the data received. Since I am receivig the data in a High Byte and a Low Byte I need to combond them to be a useful number. For example, the battery voltage is sent in mV from the battery:
High Byte = 64
Low Byte = 119
Normally I would do the following to get the correct number:
Voltage = (High Byte * 256)+Low Byte ==> (64*256)+119 = 16536 mV
Using this equation I run into a problem as the answer is limited to 1 byte, or 256.
How would you do this operation?
Thank you,
Ralph
Re: I2C Simulation
Follow-on to above:
For the voltage example I could just use the high byte and loose some resolution, however, for other fields I need all 16 bits.
For the voltage example I could just use the high byte and loose some resolution, however, for other fields I need all 16 bits.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: I2C Simulation
Hello Ralph
Thats great news glad its working correctly for you now.
You could simply fit the 16 bit number into a INT variable.
Eg.
High Byte = 64
Low Byte = 119
Result Int = ( High Byte << 8 ) + Low Byte
Thats great news glad its working correctly for you now.
You could simply fit the 16 bit number into a INT variable.
Eg.
High Byte = 64
Low Byte = 119
Result Int = ( High Byte << 8 ) + Low Byte
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Re: I2C Simulation
Thanks Ben! The INT Variable worked.
Now I have a question for display purposes.
The INT output that I display is 16536 mV. Now if I want to convert the number to volts I would divide by 1000. If I do this, the number calculated is 16 since it won't calculate decimals.
How can I split the number for display purposes. For example, the right 3 digits = variable 1 and the left 2 digits = variable 2.
Then I could display:
Variable 2 "." Variable 1 ==> 16.536 Volts.
Thanks again,
Ralph
Now I have a question for display purposes.
The INT output that I display is 16536 mV. Now if I want to convert the number to volts I would divide by 1000. If I do this, the number calculated is 16 since it won't calculate decimals.
How can I split the number for display purposes. For example, the right 3 digits = variable 1 and the left 2 digits = variable 2.
Then I could display:
Variable 2 "." Variable 1 ==> 16.536 Volts.
Thanks again,
Ralph
-
- Valued Contributor
- Posts: 548
- Joined: Tue Jun 26, 2007 11:23 am
- Has thanked: 6 times
- Been thanked: 44 times
- Contact:
Re: I2C Simulation
hello Ralph,
I have attached a simple demonstration program that converts a mV value into a voltage display. Leading zeros must be inserted into the fractional part of the display if it is less than 3 digits long.
A similar technique - using spaces - can be used to justify the entire number based on the length of the integer part.
I have attached a simple demonstration program that converts a mV value into a voltage display. Leading zeros must be inserted into the fractional part of the display if it is less than 3 digits long.
A similar technique - using spaces - can be used to justify the entire number based on the length of the integer part.