niedziela, 31 grudnia 2017

Raspberry pi - Python - PCF8591

W tym poście chciałbym opisać sposób użycia układu PCF8591 czyli czterokanałowego przetwornika ADC.

Znalezione obrazy dla zapytania raspberry pi
[Ź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:

  1. class ADCCHANNELS:
  2.     devAddress = 0x48
  3.     A0 = 0x40
  4.     A1 = 0x41
  5.     A2 = 0x42
  6.     A3 = 0x43
  7.     RESOLUTION = 255
  8.     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:

  1. class ADCREADDATA:
  2.     lastRawDataA0 = 0
  3.     lastConverValueA0 = 0.0
  4.     lastRawDataA1 = 0
  5.     lastConverValueA1 = 0.0
  6.     lastRawDataA2 = 0
  7.     lastConverValueA2 = 0.0
  8.     lastRawDataA3 = 0
  9.     lastConverValueA3 = 0.0

Trzecia klasa zawiera operacje odczytu wartości nie przetworzonych oraz przetworzonych:

  1. class AdcValue(object):
  2.     lastRawData = 0
  3.     lastConvertValue = 0.0
  4.     i2cBus = smbus.SMBus(1)
  5.  
  6.     def getRawData(channel):
  7.         AdcBattery.i2cBus.write_byte(ADCCHANNELS.devAddress, channel)
  8.         readValue = AdcBattery.i2cBus.read_byte(ADCCHANNELS.devAddress)
  9.         return readValue
  10.  
  11.     def getRawValueFromChannel0():
  12.         rawDataA0 = AdcValue.getRawData(ADCCHANNELS.A0)
  13.         return rawDataA0
  14.  
  15.     def getRawValueFromChannel1():
  16.         rawDataA1 = AdcValue.getRawData(ADCCHANNELS.A1)
  17.         return rawDataA1
  18.  
  19.     def getRawValueFromChannel2():
  20.         rawDataA2 = AdcValue.getRawData(ADCCHANNELS.A2)
  21.         return rawDataA2
  22.  
  23.     def getRawValueFromChannel3():
  24.         rawDataA3 = AdcValue.getRawData(ADCCHANNELS.A3)
  25.         return rawDataA3
  26.  
  27.     def getRawDataFrom(channel):
  28.         if channel == 0:
  29.             convertValue = AdcValue.getRawValueFromChannel0()
  30.         if channel == 1:
  31.             convertValue = AdcValue.getRawValueFromChannel1()
  32.         if channel == 2:
  33.             convertValue = AdcValue.getRawValueFromChannel2()
  34.         if channel == 3:
  35.             convertValue = AdcValue.getRawValueFromChannel3()
  36.  
  37.         return convertValue;
  38.  
  39.     def convertValueCalcul(rawData, adcRefVoltage, adcResolution):
  40.         convertValueRet = (rawData * adcRefVoltage / adcResolution)
  41.         return convertValueRet
  42.  
  43.     def convertValueChannel(channel):
  44.         if channel == 0:
  45.             ADCREADDATA.lastConverValueA0 = AdcValue.convertValueCalcul(ADCREADDATA.lastRawDataA0, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
  46.         if channel == 1:
  47.             ADCREADDATA.lastConverValueA1 = AdcValue.getRawValueFromChannel1(ADCREADDATA.lastRawDataA1, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
  48.         if channel == 2:
  49.             ADCREADDATA.lastConverValueA2 = AdcValue.getRawValueFromChannel2(ADCREADDATA.lastRawDataA2, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
  50.         if channel == 3:
  51.             ADCREADDATA.lastConverValueA3 = AdcValue.getRawValueFromChannel3(ADCREADDATA.lastRawDataA3, ADCCHANNELS.VOLTAGE,ADCCHANNELS.RESOLUTION)
  52.  
  53.     def readConvertValueChannel(channel):
  54.         raw = getRawDataFrom(channel)
  55.         convert = convertValueChannel(channel)
  56.  
  57.         #forDebug
  58.         print("AOUT0:%1.3f" %AdcBattery.lastConvertValue)
  59.  
  60.         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.