Giter Site home page Giter Site logo

pisynth's Introduction

Pi Synth

Raspberry Pi synth based on the Adafruit CAP1188 8-pad capacitive touch sensor, and other things.

Status

This is first and foremost a playground/hobby-horse, and as such will likely never be complete. As components resolve and stabilize, they'll be split out into separate repos as necessary.

Ergo, at the moment this is probably mostly useful as an example and resource roundup.

License

BSD.

References and Inspiration

  1. Cap1188 Breakout Documentation adafruit.com
  2. Configuring i2c on the Raspberry Pi adafruit.com
  3. Cap Touch on the RasPi adafruit.com
  4. Raspberry Pi and Arduino Connected Using I2C oscarliang.net
  5. Adafruit CAP1188 Arduino Library adafruit.com
  6. How to use Interrupts with Python on the Raspberry Pi and RPI.GPIO RasPI.TV
  7. Wiring Pi wiringpi.com
  8. The RPIO 0.10.0 Documentation pythonhosted.org
  9. FluidSynth elementsofsound.org — sound synthesis
  10. Mingus code.google.com — the ivories.

BOM

  • 1 Raspberry Pi
  • 2x AdaFruit Cap1188 8-pad cap touch sensor
  • 1x AdaFruit Pi Cobbler
  • Solderless Breadboard, jumpers, etc.

Pi Preparation

Software and Configuration

I2C Support

Kernel Modules

Make sure I2C support has been added to the pi, as per #2 above. Specifically:

First, check to see that the i2c components have not been blacklisted in /etc/modprobe.d/raspi-blacklist.conf. This will probably be the case if you're using Raspian.

If it exists, comment out the i2c-bcm2708 entry as such:

 # blacklist spi-bcm2708 # OK to leave this blacklisted, not needed for i2c
  blacklist i2c-bcm2708

Next, tell the system to load the i2c kernel modules at startup:

$ sudo echo i2c-bcm2708 >> /etc/modules # if it's not already there
$ sudo echo i2c-dev >> /etc/modules     # if it's not already there
$ /sbin/reboot

Finally, for convenience, add your account (e.g. pi) to the i2c group, so that you don't have to sudo every command that acceses i2c:

$ sudo adduser pi i2c
Tools

Make sure the user tools for interacting with i2c are installed:

$ sudo apt-get install i2c-tools python-smbus
Check

With nothing on the i2c bus, there should be no addresses taken. Note: The "UU" at 3b is due to a kernel audio driver using this address, unrelated to this project.

$ i2cdetect -y 1
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 70: -- -- -- -- -- -- -- --                         

GPIO Support

The forgan.py script uses RPIO to access the Pi's GPIO pins.

$ sudo pip install rpio

I also recommend installing @drogon's excellent Wiring Pi native GPIO suite. While all of the code here (so far) is written in Python, Wiring Pi includes some great tools including a pin test utility which will likely come in very handy.

Sound and Notes

forgan.py uses the Mingus Python library to play individual notes; Mingus in turn uses FluidSynth for sound synthesis. Both packages are required.

$ sudo apt-get install fluidsynth
$ sudo apt-get install python-setuptools   # for pip, if you don't already have it
$ sudo pip install mingus

Alternatively, if you prefer easy-install to pip, you can probably use that to install Mingus as well (although I haven't tried it).

Wiring

Perform all wiring and checks while disconnected from the pi.

cap1 (i2c: 0x28):

Cap1188 Pin RasPi Pin
VIN 3v3
GND GND
SDA SDA
SCL SCK
RST -
AD 3Vo ON CAP1188. This selects i2c address 0x28.
INT 24

cap1 (i2c: 0x29):

Cap1188 Pin RasPi Pin
VIN 3v3
GND GND
SDA SDA
SCL SCK
RST
AD -
INT 24

After wiring and double-checks:

  1. Power off the pi.
  2. Plug the cobbler onto the pi; when looking down at the pi, with the SD card on the right, the text "FC-26P" on the top of the cobbler's pi-side plug should be right-side-up.
  3. Power up the pi.
  4. Once powered up, verify i2c:
pi@pi ~ $ sudo i2cdetect -y 1
      0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
 00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 20: -- -- -- -- -- -- -- 28 29 -- -- -- -- -- -- -- 
 30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 
 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
 70: -- -- -- -- -- -- -- --                         

Log

7/13/2014 Interrupt Stickiness

Symptom

Since moving to interrupt-driven input, there's been a problem where interrupts would not be recognized until some random and unacceptable delay after start from a power-on or reset. However, it reliably worked if I restarted from a previously-running state (after interrupts started being recognized).

Diagnosis

  1. Ran the pintest tool from the Wiring Pi kit, and verified that all of the GPIO input pins were functioning correctly.

  2. Tested the RPi's pull-up resistor on the GPIO used for interrupts by measuring potential across the pin and GND when pulled up. 3.3v, check.

  3. Removed all non-essential wiring on the IRQ path, leaving only one CAP1188 IRQ pin connected. No change in behavior.

  4. Placed the multimeter leads in series between the IRQ pin on the active CAP1188 and the interrupt GPIO. Expected results were that upon startup, the voltage would float around a few millivolts, and then shoot up to 3.3v once an interrupt was detected. Instead, it immediately went to 3.3v on startup.

What was happening is that on startup, the CAP1188's INT flag on register MAIN is set to 1, meaning that an interrupt is being asserted. This happened whether starting from power-up, or after asserting the RESET pin. It was unexpected, since according to the datasheet, the default value of the Main Control Register (address 0x00) is 0x00 (Datasheet section 5.1).

According to the Datasheet 4.2, driving the RESET pin low after previously driving it high will cause an interrupt to be generated

So, the interrupt was being asserted before I started listening, so I was never seeing a rising edge once I started listening (except, apparently, for noise—eventually, after some period of time I'd see something and clear the interrupt).

Resolution

The resolution was to reset the interrupts by clearing the MAIN_INT flag after driving the RESET pin low.

    # set MAIN_INT flag to 0
    logging.debug("Resetting interrupts.")
    cap1.reset_interrupt();
    cap2.reset_interrupt();

After making this change, interrupts are detected immediately after start.

Followup

Going back to the contributed Adafruit example interrupt code for the CAP1188, I noticed the line:

    EIFR = 1;

I ignored it, since I hadn't heard of EIFR (however since I also didn't see it in the Adafruit library or the contributed code, I should have been suspicous). As it turns out, this is the Arduino External Interrupt Flag Register. This forum post shed some light: EIFR = 1; is very important to making the Arduino code work properly; setting MAIN_INT to low accomplishes basically the same thing in the case of the Pi.

pisynth's People

Contributors

jrmiddle avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.