PCF8591 use and Python control

PCF8591 use and Python control

INTRODUCTION

  You must be very confused about the PCF8591 chip, the A0, A1, A2, channel0-channel3, AIN0-AIN3, AOUT, SCL, SDA, etc. and the I2C protocol. At the same time, I did not fully understand what the 0x40, 0x41, 0x42, 0x43, and 0x48 in the Python code are, and what exactly bus.write_byte(0x48, 0x40) bus.write_byte(0x48, 0x40, value) bus.read_byte(0x48)these codes control.

  This article will help you sort out the above content.

1. The relationship between PCF8591 and Raspberry Pi

  Make a very simple visualization and treat the entire system as an inlet/outlet device.
Schematic diagram of MASTER and SLAVER
  The device has four inlet pipes, named AIN0, AIN1, AIN2, AIN3, and the only outlet pipe, named AOUT. There are also four transfer channels, named channel0, channel1, channel2, and channel3 respectively. The water from the four inlet pipes can flow out of a certain channel under control, enter the main pipeline, and then pass through two outlet pipes——SDA And SCL, enter a water processing and storage facility.

  Raspberry PI is "MASTER", PCF is "SLAVER", and they have a master-slave relationship. If the master device wants to send data to the slave device, it will start the data transfer, and send the data to the slave device, and finally terminate the data transfer; if the master device wants to accept the data sent by the slave device, it will also issue a command to start the data transfer and receive The data sent from the device finally terminates the receiving process.
  Emphasize one point : each data transmission is actively started by " MASTER " .   Is it clearer? After sorting out the general relationship, we will look at the specific details.

2. PCF address and A0-A2 pins

  A "MASTER" cannot have only one "SLAVER". So for "MASTER", "SLAVERS" needs to be numbered for control and command. This number is also the PCF address. The coding rules of the address are as follows: It
ADDRESS coding rules
  can be seen that this is a seven-digit binary number, the first four digits are the fixed number, and the last three digits correspond to the three pins of the PCF-A0, A1, A2. The value of each pin can be 0 or 1, a total of 2^3=8 kinds of arrangements, that is, a total of 8 usable addresses. So one "MASTER" can control 8 "SLAVER" at most at the same time. For PCF8591, its default address is 0x48 (hexadecimal number), converted to binary number is 1001000, so it can be known that its A0, A1, and A2 pins are all 0.

  It needs to be emphasized in advance that all 0x hexadecimal numbers in Python code, only 0x48 represents Address , and only PCF owns Address , and all other hexadecimal numbers do not represent Address. (This is a sinkhole)

3. I2C protocol and SDA SCL

  There needs to be communication between "MASTER" and "SLAVERS", assign work to "SLAVER" or let "SLAVER" report the work, and tell "SLAVER" how to do it. Therefore, there is a specific way of communication between them, which is called the I^2 C communication protocol (Inter-Integrated Circuit). The I^2 C bus requires two wires to realize the information transmission between devices connected to the bus, one is the SDA (Serial Data) serial data line, and the other is the SCL (Serial Clock) serial clock line.

  The following figure shows the I2C data transmission process of AD convert.
I2C transmission
  Isn't it confusing? It doesn't matter, here comes a visual explanation. As mentioned before, I2C is a way of communication, so this data transmission process can be understood as a communication in a specific way of communication like I2C. Speaking more popularly, it's just a chat conversation. How to understand?

  The first step in chatting is to take out your phone and open WeChat. (Corresponding to the START condition, when the levels of the SDA and SCL lines meet a certain condition at the same time, the transmission starts.)

  After opening WeChat, you need to find a contact to chat. We said before that "MASTER" has a lot of "SLAVERS", this step is "MASTER" chooses to talk to a certain "SLAVER". (Corresponding to ADDRESS.)

  In the third step, "MASTER" determines whether the purpose of this dialogue is to allocate work to "SLAVER" or let "SLAVER" report after finishing the work. (Corresponding to R/W, R means read, W means write, the purpose of controlling this data transmission is whether the Raspberry Pi writes a value to the PCF or the Raspberry Pi reads a value from the PCF.)
You can see that there is Many ACKs. ACK means Acknowledge character, which means that the data receiver tells the data transmitter, "received".

  After that is the data transmission, every time a byte of data is transmitted, an ACK will be sent back to confirm the data receipt.
chatting

Four, Python code controls reading/writing values

import smbus
import time

if __name__ == "__main__":
    bus=smbus.SMBus(1)
    bus.write_byte(0x48,0x42)
    bus.read_byte(0x48)
    while True:
        num= bus.read_byte(0x48)
        print(num)
        bus.write_byte_data(0x48,0x42,160)
        time.sleep(0.01)

  In fact, the code is very simple. The main reason why the code given in the previous references is confusing is that many methods have been customized. Now write it in the simplest way. There are only three core methods used:

bus.read_byte(ADDRESS)
bus.write_byte(ADDRESS, CONTROL_byte)
bus.write_byte_data(ADDRESS, CONTROL_byte, value)

  As the name implies, read_byte is to read a byte of data from PCF, write_byte is to write a byte of data to PCF, write_byte_data is to write data to PCF.

  Someone will ask, what is the difference between write_byte and write_byte_data?

  Remember the points emphasized in PART1? Each data transmission must be actively started by the "MASTER", so the purpose of write_byte is to clarify which "SLAVER" the "MASTER" talks to, establish a connection, and use a "CONTROL byte" to tell the "SLAVER" how to work without transmitting value. This is why the first step in the code isbus.read_byte(0x48)

  The Raspberry Pi takes the initiative to open a dialogue, establish a connection with the PCF8591 corresponding to the address 0x48, and specify the working mode (Analog Input Mode) through a CONTROL byte.

  The second question is, what is CONTROL byte? Isn't that an address?

  At this time, you should remember the content emphasized by PART2 (only 0x48 is the address). The second parameter of the write_byte method is a CONTROL byte.
analog input mode
  This is the official document's explanation of the CONTROL byte. 8-bit binary code, where the first and fifth digits are fixed number—0, and the part that can be programmed is the second digit—representing whether the AOUT output port is turned on, 0 means not turned on, 1 means turned on, only this bit When it is 1, DA will work, and the digital signal will be converted into an analog signal and output from the AOUT port; the third and fourth digits represent four different analog input modes to clarify the data relationship between the AIN port and the channel.
?
  In the first picture, there is a big question mark, and the analog input mode is to clarify this question mark. There are two correspondences: one is single-ended, that is, one to one. For example, in 00 mode, the data read from channel0 is the digital value of the analog input from AIN0 port after AD conversion. The four AIN ports in 00 mode correspond to a channel one by one; in 10 mode, AIN0 and AIN1 correspond to channel0 and channel1 one to one. Another correspondence is differential, that is, differential. For example, in 01 mode, the value of channel0 is the difference between AIN0 and AIN3; in 10 mode, the value of channel2 is the difference between AIN2 and AIN3.

  The seventh-eighth bit of the CONTROL byte is the AD channel number, which is used to control which channel to read data from. The sixth bit is auto-increment. When the value is 1, the channel will be automatically switched every time the data is read. The data of channel0 is read the first time, the data of channel1 is read the next time, and so on.

  In the Python code, the CONTROL byte is a hexadecimal number, which is an eight-bit binary after being converted to binary. The control method is: determine the value you want on the codeable bits in the CONTROL byte, get an eight-digit binary number, convert it to a hexadecimal number, and enter the Python method.

  After talking about this, most of the content is almost finished. Continuing with the code example, read_byte, the process of reading the value does not require CONTROL byte, so the parameter is only ADDRESS.

  As you can see, there is another empty read before the desired num is actually read. This is because after receiving the read command, PCF8591 performs the last conversion data transmission and this data conversion at the same time, so the data of the first empty read is an uncertain number, and the first empty read is just In order to start the next normal read.

bus.write_byte_data(0x48,0x42,160)

  The write_byte_data method will be explained more. The written value will be directly used as a digital value, which will be output from the AOUT port as an analog quantity in the form of voltage after conversion. The PCF8591 we use is an 8bits AD/DA converter. 8bits means that AD/DA has a total of 2^8=256 scales, so the transmitted digital value range is 0-255. For example, if you want to output a 3.13V voltage to the LED light from the AOUT port, the value that should be written is 3.13v/5v*255=160 (here the ADC is connected to the 5v reference voltage), but actually it is measured with a voltmeter At this time, the voltage across the LED lamp is 2.64v, which has a certain error from the ideal value.

五、Something More

  I have tried almost all analog input modes, connecting the microphone to different AIN ports, choosing different channels, and doing a lot of experiments with the graphs drawn by oscilloscope/voltmeter+python. There are still many difficult to explain in the differential mode. However, it is basically certain that the whole principle is not wrong.

  In addition, in single-ended mode, the analog value of AD conversion is the voltage between the AIN port and GND; in differential mode, the analog value of AD conversion is the voltage difference between the two AIN ports, so if only one AIN is used If you want to use differential mode, remember to ground the other AIN port.

六、Learning Experience

The experience gained during the learning process of more than 30 hours:
①Never think that your previous understanding is correct. It is found that there are errors in the whole understanding process, and sometimes it is necessary to overthrow and rebuild.
②The information on the Internet is uneven and full of errors. You must not believe it blindly.
③The experiment must clearly record the conditions and phenomena, otherwise the experiment will be repeated many times because the phenomena/conditions are not clearly recorded.
④In the process of learning a brand-new knowledge system, there will be a lot of information flooding in. Often when searching for information to solve problem 1, problem 2 will be found, and then attention will be shifted to problem 2, and then new problems will be discovered. An endless loop. So you need to stop in time and think about who you are, where you are, and what you want to do.
⑤ Record the problem, and then continue to explore. It is very likely that on the second day you will look back at the first day’s question and sigh: How could I ask such a stupid question.
⑥ Teammates are very important. Discussion/Stop Loss/Question/Review/Summary.

My first CSDN blog, I hope to make it clear. Hope you all like it! !

Guess you like

Origin blog.csdn.net/m0_47262669/article/details/109140960