You are on page 1of 5

Lab 03 - Inverting Amplifier

John Stenson, David Coy


December 20, 2015

Introduction

In this experiment, an operational amplifier will be used to implement a circuit


with an inverting effect, with analog output feeding into an Analog to Digital
Converter. This format is used so that the inputs and output of the inverting circuit can be varied greatly, but may also be mapped by a Raspberry Pi
computer, for ease of viewing. Inverting operational amplifier configurations
are important in boo-instrumentation applications because of their large input
impedances, which causes minimal current draw from the circuit being measured in the body, therefore being minimally disruptive to body function.

Interface

The circuit will be fed input from an output pin of the Raspberry pi, and
send output back to the Raspberry Pi through a managed Analog to Digital
Converter, namely the MCP30008. The data will be displayed to the user on a
graph of both the input value, and the output value.

Design

The inverting amplifier circuit will consist of one operational amplifier, four
resistors, and connections to inputs and outputs, including rail values of the
resistor. The circuit diagram for this circuit is shown below in Figure 1.
As can be seen, the operational amplifier is fooled by providing a new
reference ground of 2V5, allowing the amplifier to receive negative inputs to
produce positive outputs for measurement, without ever exceeding the rails of
5V and 0V.
The Vin value is an input from output pin 4 on the Raspberry Pi, while
Vout leads to the MCP 3008 ADC before being routed to the Pi. The pinout
used between the Pi and the MCP is shown in figure 2.

Implementation

When actually implementing the design, two potentiometers were used rather
than the 4 resistors. Each potentiometer was set at half, so that both end pin to
center resistances were equal. This created the equal voltage dividers necessary
for the circuit to function as simply an inverting amplifier, with a gain of -1,
rather than producing a circuit with a larger gain magnitude.
Additionally, when implementing, it became necessary to change the planned
output pin of the Raspberry Pi from Pin 4 to Pin 17, due to a hardware issue.
The issue was causing rapid shifts in input making the output unstable, and
eventually, both input and output would head to ground, and remain there.
The code used in this experiment is attached.
However, once these obstacles were overcome, the circuit performed as expected.

Conclusions

Overall, this experiment was effective for demonstrating the functionality of and
design elements involved in using operational amplifiers to measure analog input
and display the results on a digital system.
The particular failure of the GPIO Pin on the Raspberry Pi was fortunate
in that it reminded the participants that flaws can be found in any portion of
the device, not just those designed and assembled by the participants.
Combined with the other sections of the experiment, this lab forms a good
basis for the understanding of operational amplifiers and their applications.
Taken together, the experiments provide good references for the intuitive understanding of the principals of operational amplifiers, allowing them to be used
in future experiments with a reasonable expectation that the participants will
understand what the op amps function and purpose are in that case.

CODE
#!/usr/bin/python
import
import
import
import
import
import
import

spidev
time
os
matplotlib.pyplot as plt
threading
numpy
RPi.GPIO as GPIO

pos_volt = 3.3
neg_volt=0.0
SigPin = 17
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(SigPin, GPIO.OUT)
GPIO.output(SigPin,GPIO.LOW)
spi = spidev.SpiDev()
spi.open(0,0)
# send 1xxx0000 w/ xxx=channel(0-7)
# rec 3 bytes, 10 bit value is last part:
# xmit[0] xmit[1] xmit[2]
# xxxxxxxx xxxxxxA9 87654321
# xmit[1]&3 = 000000A9
# shift left 8 = 000000A900000000
# add xmit[2] = 000000A987654321
def ReadMCP3008(channel):
xmit = spi.xfer2([1,(8+channel)<<4,0])
cdata = ((xmit[1]&3) << 8) + xmit[2]
return cdata
# volts is from a 10 bit (2^10-1=1023), Vref=3.3
# note 10 bits is approx 3 decimal places
def ConvertVolts(data):
volts = round((data * (pos_volt-neg_volt)) / float(1023),3)
return volts

Hz=100
delay = 1.0/float(Hz)
3

SqHz=1
sqdelay = 2.0/float(SqHz)
#class MyThread (threading.Thread)
# This just simulates reading from a socket.
def get_data():
global data
global minref
global maxref
data = [[0] for i in range(7)]
myref=ConvertVolts(ReadMCP3008(7))
minref=myref
maxref=myref
for i in range(7):
data[i][0]=ConvertVolts(ReadMCP3008(i))-myref
while True:
myref=ConvertVolts(ReadMCP3008(7))
for i in range(7):
data[i].append(ConvertVolts(ReadMCP3008(i))-myref)
if myref>maxref:
maxref=myref
elif myref<minref:
minref=myref
time.sleep(delay)
def square_wave():
while True:
GPIO.output(SigPin,GPIO.HIGH)
time.sleep(sqdelay)
GPIO.output(SigPin,GPIO.LOW)
time.sleep(sqdelay)
if __name__ == __main__:
try:
#put data reader in a thread so it can run simultaneous
thread1 = threading.Thread(target=get_data)
thread1.daemon = True
thread1.start()
thread2 = threading.Thread(target=square_wave)
thread2.daemon = True
thread2.start()
#setup plt and make interactive
plt.ion()
4

fig=plt.figure()
datalen=len(data[0])-1
ln0 = plt.plot(range(datalen),data[0][0:datalen],r-)[0]
ln1 = plt.plot(range(datalen),data[1][0:datalen],g-)[0]
ln2 = plt.plot(range(datalen),data[2][0:datalen],c-)[0]
avgref=(maxref+minref)/2
rngref=maxref-minref
plt.axis([0,datalen-1,neg_volt-avgref-rngref-0.1,pos_volt-avgref+rngref+0.1])
plt.show()
#keep plotting
while True:
datalen=len(data[0])-1
ln0.set_xdata(range(datalen))
ln0.set_ydata(data[0][0:datalen])
ln1.set_xdata(range(datalen))
ln1.set_ydata(data[1][0:datalen])
ln2.set_xdata(range(datalen))
ln2.set_ydata(data[2][0:datalen])
avgref=(maxref+minref)/2
rngref=maxref-minref
plt.axis([0,datalen-1,neg_volt-avgref-rngref-0.1,pos_volt-avgref+rngref+0.1])
fig.canvas.draw()
time.sleep(delay)
except KeyboardInterrupt:
spi.close()
GPIO.cleanup()

You might also like