10

For my daughter's science fair project (Computer Science and Math category), she'd like to use the RPi to go around and measure whether different loud sounds are above the threshold of pain and are damaging our ears. She's a 6th grader, but she has experience with RPi and programming in Python. Phillip Heels Nichols has answered some questions on the FB RPi page, but suggested that we come over here for more help. She wants to calibrate the Pi with a sound pressure meter (I have one of these) to figure out how many millivolts are produced

Here is what we are thinking so far. We bought an adc (mcp3008) from adafruit and are awaiting its arrival. If we connect the digital output from the adc to the GPIO pin 11 and GPIO pin 12 to a red LED, will this simple program work?

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(11,GPIO.IN)
GPIO.setup(12,GPIO.OUT)
GPIO.output(12,GPIO.LOW)    #make sure LED is off
SPL=0 #zero the variable

While SPL<??:            #Where ?? is the value in millivolts produced by a sound at 130 db
    SPL=GPIO.input(11)   #get value from adc connected to microphone
GPIO.output(12,GPIO.HIGH)   #turn LED on if the sound level is higher than ??

If this would work, what code could be put at the end to reset the program with the press of a button connected to GPIO pins? She wants this to be portable, so she won't be able to type commands to run the program again.

Vincent P
  • 2,210
  • 15
  • 24
user5769
  • 109
  • 1
  • 1
  • 3
  • For some reason, the code got cut off. Let me try again:

    import RPi.GPIO as GPIO

    GPIO.setmode(GPIO.BOARD) GPIO.setup(11,GPIO.IN) GPIO.setup(12,GPIO.OUT) GPIO.output(12,GPIO.LOW) #make sure LED is off SPL=0 #zero the variable

    While SPL<??: #Where ?? is the value in millivolts produced by a sound at 130 db SPL=GPIO.input(11) #get value from adc connected to microphone GPIO.output(12,GPIO.HIGH) #turn LED on if the sound level is higher than ??

    – user5769 Feb 01 '13 at 05:49
  • 1
    You can edit your post, if you put 4 spaces in front of the code, it puts it into a special "code" box, and keeps formatting. Makes it a lot easier to read. Not really relating to the question, but that's impressive for a 6th grader!!!! I wish I started that young. – Impulss Feb 01 '13 at 06:47
  • 1
    Out of interest, what make/model is the sound pressure meter? – recantha Feb 01 '13 at 07:35
  • Is the output from the meter pre-amplified? Otherwise, microphone output will be way too small for an MCP3008 to read. – scruss Feb 01 '13 at 12:48
  • Note that you can't just use an ADC to meaningfully measure sound pressure. You must either measure the oscillating waveform and then measure it's amplitude in software (possibly applying frequency-dependent weighting as real meters tend to) or else rectify the signal before it reaches the ADC. You might want to run some experiments using a PC with a soundcard first to get an idea of the algorithm. – Chris Stratton Mar 10 '13 at 23:35

2 Answers2

3

Using the SPI bus by just connecting the digital out pin of the ADC to pin 11 of the RPi GPIO will not work. This bus need a couple of more wires, 4 to be precise.

The ADC will also need an SPI input, Clock and Chip Select pins connected to function properly. Luckily there is good information on this available from multiple sources.

First if you would like to know a little more on the working of SPI, I suggest to read this page on Wikipedia to get to know SPI a little better.

Second there is a very nice tutorial of Adafruits that exactly discusses this subject, it includes Python code and guides you through the processes of connecting the ADC itself and communicating with it. One (minor) disadvantage is that the code used in this tutorial does not use the SPI port itself, it software emulates the SPI bus (called bit-banging), this means that you are more free to use the pins on the GPIO port that you want.

I suppose for your relatively simple project (although I am happily surprised nowadays 6th graders do these sort of tasks!, for them a lot of new information is thrown at them by making these types of projects), the bit-banging solution will work just fine. An advantage of using bit banging is that for learning purposes it suits better because you create all the SPI signals yourself, the processor does nothing automatically, so you'll end up with a much better insight knowledge of SPI and serial communications in general!

Maybe it is a nice idea to start out with the examples from Adafruit and move at a later point to using the hardware implementation on the RPi for SPI, in that case you'll need the datasheet (also handy while using the Adafruit software implementation), Chapter 5 and 6 describe the communication and what needs to be configured to use the ADC.

ikku
  • 4,494
  • 1
  • 25
  • 28
  • I'd avoid the bit-banging implementations altogether, and go straight for the hardware version. Good, simple example here: Jeremy's Blog: Raspberry Pi hardware SPI analog inputs using the MCP3008. – scruss Feb 01 '13 at 12:50
  • Thanks. We've looked at adafruit's tutorial and plan to use it to connect the adc to the RPi. We just left that step out of our description. However, the adafruit code and the idea of bit banging is far too complicated for her (and me) at this point. She'd never be able to explain that to the judges. We'll check out the hardware version and see how that looks. But . . . the fact that the microphone output is too small (@scruss) will be an issue for sure. Thanks for all of your answers, they'll help a great deal! – user5769 Feb 01 '13 at 17:28
  • There is the Electret Microphone Amplifier from Adafruit that steps up the electret's output to something that the ADC can read. It includes a mic capsule. – scruss Feb 01 '13 at 21:07
0

For hardware SPI with MCP3008 and Adafruit_MCP3008 and Adafruit.SPI Python libraries:

I have tried to tweak into the function set_clock_frequency('value in Hz') of the SpiDev object of the Adafruit.SPI library. So something like,

import Adafruit_SPI as SPI  
ChangeClk=SPI.SpiDev(spi=0, port=0, max_speed = default)
ChangeClk.set_clock_frequency(90000)

I wanted a 5 KHz sampling rate (5 V was given to MCP3008) but the Raspberry Pi model 2 B was giving a serial CLOCK of 25 KHz when observed on DSO. For an analog input signal sampling rate of 5 KHz, the Serial CLK from Pi should be 90 KHz (18 times sampling rate, as given in MCP 3008 datasheet). However even this could not help and things remain unchanged while the python script runs.

Also surprisingly, the same code when ran on SPYDER IDE on RPi printed a 1006 values in 1 second indicating an improved sampling rate with the settings kept same as above to 1 KHz unlike the inbuilt Python-2 shell.

Dave Jones
  • 3,978
  • 15
  • 22
S Vyas
  • 1
  • Could you have a go at reformatting this? Your answer in it's current format is difficult to read. If you need any pointers give the Help Center a look. – Darth Vader Aug 24 '16 at 20:05