Skip to content

Instantly share code, notes, and snippets.

@AlexAti
Forked from ladyada/adafruit_mcp3008.py
Last active May 21, 2017 20:19
Show Gist options
  • Save AlexAti/7e58f12538fa4c957c982cb78af1add3 to your computer and use it in GitHub Desktop.
Save AlexAti/7e58f12538fa4c957c982cb78af1add3 to your computer and use it in GitHub Desktop.
C.H.I.P. Computer Analog Input with MCP3008
#!/usr/bin/env python3
# Adapted for CHIP Computer and Python3 from Limor "Ladyada" Fried for Adafruit Industries, (c) 2015
# This code is released into the public domain
import time
import os
import CHIP_IO.GPIO as GPIO
DEBUG = 1
# change these as desired - depending on how you cable your CHIP computer with the MCP
SPICLK = "XIO-P3"
SPIMISO = "XIO-P1"
SPIMOSI = "XIO-P0"
SPICS = "XIO-P2"
# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
if ((adcnum > 7) or (adcnum < 0)):
return -1
GPIO.output(cspin, GPIO.HIGH)
GPIO.output(clockpin, GPIO.LOW) # start clock low
GPIO.output(cspin, GPIO.LOW) # bring CS low
commandout = adcnum
commandout |= 0x18 # start bit + single-ended bit
commandout <<= 3 # we only need to send 5 bits here
for i in range(5):
if (commandout & 0x80):
GPIO.output(mosipin, GPIO.HIGH)
else:
GPIO.output(mosipin, GPIO.LOW)
commandout <<= 1
GPIO.output(clockpin, GPIO.HIGH)
GPIO.output(clockpin, GPIO.LOW)
adcout = 0
# read in one empty bit, one null bit and 10 ADC bits
for i in range(11):
GPIO.output(clockpin, GPIO.HIGH)
GPIO.output(clockpin, GPIO.LOW)
adcout <<= 1
if (GPIO.input(misopin)):
adcout |= 0x1
GPIO.output(cspin, GPIO.HIGH)
return adcout
# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)
def one_channel_track (potentiometer_adc, handler):
"I receive a handler function I will call with only a value from 0 to 100, when it changes."
last_read = 0 # this keeps track of the last potentiometer value
tolerance = 5 # to keep from being jittery we'll only change
# volume when the pot has moved more than 5 'counts'
while True:
# we'll assume that the pot didn't move
trim_pot_changed = False
# read the analog pin
trim_pot = readadc(potentiometer_adc, SPICLK, SPIMOSI, SPIMISO, SPICS)
# how much has it changed since the last read?
pot_adjust = abs(trim_pot - last_read)
if DEBUG:
print( "trim_pot:", trim_pot)
print( "pot_adjust:", pot_adjust)
print( "last_read", last_read)
if ( pot_adjust > tolerance ):
trim_pot_changed = True
if DEBUG:
print( "trim_pot_changed", trim_pot_changed)
if ( trim_pot_changed ):
set_volume = trim_pot / 10.24 # convert 10bit adc0 (0-1024) trim pot read into 0-100 volume level
set_volume = round(set_volume) # round out decimal value
set_volume = int(set_volume) # cast volume as integer
handler(set_volume) # call the handler
last_read = trim_pot # save the potentiometer reading for the next loop
# hang out and do nothing for a half second
time.sleep(0.5)
def two_channel_track (potentiometer_adc_0, potentiometer_adc_1, handler):
"I receive a handler function I will call with values from 0 to 100 of both channels, when at least one changes."
last_read_0 = 0 # this keeps track of the last potentiometer value
last_read_1 = 0
tolerance = 5 # to keep from being jittery we'll only change
# volume when the pot has moved more than 5 'counts'
while True:
# we'll assume that the pot didn't move
trim_pot_changed = False
# read the analog pin
trim_pot_0 = readadc(potentiometer_adc_0, SPICLK, SPIMOSI, SPIMISO, SPICS)
trim_pot_1 = readadc(potentiometer_adc_1, SPICLK, SPIMOSI, SPIMISO, SPICS)
# how much has it changed since the last read?
pot_adjust_0 = abs(trim_pot_0 - last_read_0)
pot_adjust_1 = abs(trim_pot_1 - last_read_1)
if DEBUG:
print( "trim_pot:", trim_pot_0, ", ", trim_pot_1)
print( "pot_adjust:", pot_adjust_0, ", ", pot_adjust_1)
print( "last_read", last_read_0, ", ", last_read_1)
if ( pot_adjust_0 > tolerance or pot_adjust_1 > tolerance ):
trim_pot_changed = True
if DEBUG:
print( "trim_pot_changed", trim_pot_changed)
if ( trim_pot_changed ):
set_volume_0 = trim_pot_0 / 10.24 # convert 10bit adc0 (0-1024) trim pot read into 0-100 volume level
set_volume_0 = round(set_volume_0) # round out decimal value
set_volume_0 = int(set_volume_0) # cast volume as integer
set_volume_1 = trim_pot_1 / 10.24 # convert 10bit adc0 (0-1024) trim pot read into 0-100 volume level
set_volume_1 = round(set_volume_1) # round out decimal value
set_volume_1 = int(set_volume_1) # cast volume as integer
handler(set_volume_0, set_volume_1) # call the handler
last_read_0 = trim_pot_0 # save the potentiometer reading for the next loop
last_read_1 = trim_pot_1 # save the potentiometer reading for the next loop
# hang out and do nothing for a half second
time.sleep(0.5)
def change_volume (set_volume):
print( 'Volume = {volume}%' .format(volume = set_volume))
set_vol_cmd = 'sudo amixer cset numid=1 -- {volume}% > /dev/null' .format(volume = set_volume)
os.system(set_vol_cmd) # set volume
if DEBUG:
print( "set_volume", set_volume)
print( "tri_pot_changed", set_volume)
def where_am_i (x, y):
width = 60
height = 40
posx = int(x / 100.0 * width)
posy = int(y / 100.0 * height)
os.system('cls' if os.name == 'nt' else 'clear')
for j in range(height, 0, -1):
print(" ")
for i in range (width):
if (i == posx and j == posy):
print("X", end="")
else:
print("_", end="")
# one_channel_track(7, change_volume) # 10k trim pot connected to adc #7
two_channel_track(5,7, where_am_i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment