As Part of the Orange Pi Series we will be seeing how to get analog input for Orange Pi Zero. The Orange Pi Zero does not have any analog input much like Raspberry pi. So we need to interface with another chip which provides analog input. There are plenty of such chips which provide analog input and today we are going to see the chip MCP3208 from Microchip.
The MCP3208 is a 12bit, 8 channel, Serial Peripheral Interface (SPI) Analogue to Digital Converter. It comes as a 16 pin DIP and is also available as the 3201/2/4 with 1, 2 and 4 channels.
I am using Orange Pi Zero with Armbian image and it has two SPI interface. SPI is used for boot purpose by SPI Flash hence it cannot be used for other purpose. The next interface is used for connecting to MCP3208. To know which Pins are allocated I used the fex script.
bin2fex /boot/script.bin orangepi.txt
[spi0] spi_used = 1 spi_cs_bitmap = 1 spi_mosi = port:PC00<3><default><default><default> spi_miso = port:PC01<3><default><default><default> spi_sclk = port:PC02<3><default><default><default> spi_cs0 = port:PC03<3><1><default><default> [spi1] spi_used = 1 spi_cs_bitmap = 1 spi_cs0 = port:PA13<2><1><default><default> spi_sclk = port:PA14<2><default><default><default> spi_mosi = port:PA15<2><default><default><default> spi_miso = port:PA16<2><default><default><default>
From that we can see that the SPI1 uses PIN PA13,14,15,16. So the connection between Orange Pi Zero and MCP3208 will look like below
Ofcourse the Vdd and Vref both should be connected to 5V of Orange Pi Zero and similary DGND and AGND should be connected to Ground of the Orange Pi Zero.
In software side the kernel driver is already configured and ready to use. There are two spi devices namely /dev/spidev0.0 and /dev/spidev1.0. We will be using /dev/spidev1.0 which means device number 1 and port no 0. We can use python for this and for that you need to install the spidev package from pip.
apt-get install python-dev python-pip virtualenv localpy source localpy/bin/activate pip install spidev
I am installing the spidev in a local installation because it is safer to keep the system python undisturbed for experiments.
Now for the code I took this code from https://gist.github.com/yoggy/7096133 and modified it for my purpose.
#!/usr/bin/python # import spidev import time class MCP3208: def __init__(self, spi_channel=0): self.spi_channel = spi_channel self.conn = spidev.SpiDev(1, spi_channel) self.conn.max_speed_hz = 1000000 # 1MHz def __del__( self ): self.close def close(self): if self.conn != None: self.conn.close self.conn = None def bitstring(self, n): s = bin(n)[2:] return '0'*(8-len(s)) + s def read(self, adc_channel=0): # build command cmd = 128 # start bit cmd += 64 # single end / diff if adc_channel % 2 == 1: cmd += 8 if (adc_channel/2) % 2 == 1: cmd += 16 if (adc_channel/4) % 2 == 1: cmd += 32 # send & receive data reply_bytes = self.conn.xfer2([cmd, 0, 0, 0]) # reply_bitstring = ''.join(self.bitstring(n) for n in reply_bytes) # print reply_bitstring # see also... http://akizukidenshi.com/download/MCP3204.pdf (page.20) reply = reply_bitstring[7:19] return int(reply, 2) if __name__ == '__main__': spi = MCP3208(0) count = 0 a0 = 0 a1 = 0 a2 = 0 a3 = 0 while True: count += 1 a0 += spi.read(0) a1 += spi.read(1) a2 += spi.read(2) a3 += spi.read(3) if count == 10: print "ch0=%04d, ch1=%04d, ch2=%04d, ch3=%04d" % (a0/10, a1/10, a2/10, a3/10) count = 0 a0 = 0 a1 = 0 a2 = 0 a3 = 0
I will post more example based on this ADC in my up coming posts.