W tym poście chciałbym opisać sposób użycia układu PCF8591 czyli czterokanałowego przetwornika ADC.
[Źródło: https://www.element14.com/community/community/raspberry-pi]
Układ posiada cztery kanały A/C oraz jedno wyjście C/A. Dane przedstawiane są na 8 bitach, czyli rozdzielczość układu wynosi 255. Napięcie zasilania może być w przedziale od 2,5V do 6,0V.
Podłączenie:
Układ do podłączenia składa się z czterech linii VCC, GND oraz SDA i SCL.
VCC do 3.3V
GND do masy
SDA linia danych I2C
SCL linia zegara I2C
Kod programu:
Najpierw klasa deklarująca adresy wszystkich dostępnych kanałów:
Adres urządzenia (gdy jest domyślny i nie zmieniany przez zworki na płytce) wynosi 0x48 (72).
Druga klasa przechowuje wyniki wykonywanych operacji:
Trzecia klasa zawiera operacje odczytu wartości nie przetworzonych oraz przetworzonych:
- class ADCCHANNELS:
- devAddress = 0x48
- A0 = 0x40
- A1 = 0x41
- A2 = 0x42
- A3 = 0x43
- RESOLUTION = 255
- VOLTAGE = 3.3
Adres urządzenia (gdy jest domyślny i nie zmieniany przez zworki na płytce) wynosi 0x48 (72).
Druga klasa przechowuje wyniki wykonywanych operacji:
- class ADCREADDATA:
- lastRawDataA0 = 0
- lastConverValueA0 = 0.0
- lastRawDataA1 = 0
- lastConverValueA1 = 0.0
- lastRawDataA2 = 0
- lastConverValueA2 = 0.0
- lastRawDataA3 = 0
- lastConverValueA3 = 0.0
Trzecia klasa zawiera operacje odczytu wartości nie przetworzonych oraz przetworzonych:
- class AdcValue(object):
- lastRawData = 0
- lastConvertValue = 0.0
- i2cBus = smbus.SMBus(1)
- def getRawData(channel):
- AdcBattery.i2cBus.write_byte(ADCCHANNELS.devAddress, channel)
- readValue = AdcBattery.i2cBus.read_byte(ADCCHANNELS.devAddress)
- return readValue
- def getRawValueFromChannel0():
- rawDataA0 = AdcValue.getRawData(ADCCHANNELS.A0)
- return rawDataA0
- def getRawValueFromChannel1():
- rawDataA1 = AdcValue.getRawData(ADCCHANNELS.A1)
- return rawDataA1
- def getRawValueFromChannel2():
- rawDataA2 = AdcValue.getRawData(ADCCHANNELS.A2)
- return rawDataA2
- def getRawValueFromChannel3():
- rawDataA3 = AdcValue.getRawData(ADCCHANNELS.A3)
- return rawDataA3
- def getRawDataFrom(channel):
- if channel == 0:
- convertValue = AdcValue.getRawValueFromChannel0()
- if channel == 1:
- convertValue = AdcValue.getRawValueFromChannel1()
- if channel == 2:
- convertValue = AdcValue.getRawValueFromChannel2()
- if channel == 3:
- convertValue = AdcValue.getRawValueFromChannel3()
- return convertValue;
- def convertValueCalcul(rawData, adcRefVoltage, adcResolution):
- convertValueRet = (rawData * adcRefVoltage / adcResolution)
- return convertValueRet
- def convertValueChannel(channel):
- if channel == 0:
- ADCREADDATA.lastConverValueA0 = AdcValue.convertValueCalcul(ADCREADDATA.lastRawDataA0, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
- if channel == 1:
- ADCREADDATA.lastConverValueA1 = AdcValue.getRawValueFromChannel1(ADCREADDATA.lastRawDataA1, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
- if channel == 2:
- ADCREADDATA.lastConverValueA2 = AdcValue.getRawValueFromChannel2(ADCREADDATA.lastRawDataA2, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
- if channel == 3:
- ADCREADDATA.lastConverValueA3 = AdcValue.getRawValueFromChannel3(ADCREADDATA.lastRawDataA3, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
- def readConvertValueChannel(channel):
- raw = getRawDataFrom(channel)
- convert = convertValueChannel(channel)
- #forDebug
- print("AOUT0:%1.3f" %AdcBattery.lastConvertValue)
- return {'raw':raw, 'conv':convert }
W klasie powyżej znajdują się funkcje pobierające szukane wartości. Do każdego odczytu przygotowałem osobną funkcję która pobiera dane z kanałów. Można także korzystać z pojedynczej funkcji gdzie wprowadza się numer od 0 do 3. Na tej podstawie odczyta się dane z podanego kanału.
Cały kod można pobrać z dysku Google pod tym linkiem.
Cały kod można pobrać z dysku Google pod tym linkiem.