Skip to content

A hardware/software project that lets you setup some physical objects, and trigger software events when they change weight - e.g. play a particular playlist when a stopper is removed from a bottle.

License

Notifications You must be signed in to change notification settings

abworrall/glassware

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Glassware

A project that lets you setup some physical objects, and trigger software events when they change weight - e.g. play a particular playlist when a stopper is removed from a bottle.

This project has a few moving pieces:

  • an ardunio program, which polls the analog pins and prints values via serial output
  • a controller program that runs on a pi, reading the tty from arduino board(s), looking for significant changes
  • music streaming and audio output integration

Hardware: bill of materials

This was developed to run on the following hardware:

  • raspberry pi (any Pi with networking and USB will do), and a power supply
  • arduino board (link)
    • each board can handle 6 analog FSR sensors, can have multiple boards
  • force sensitive resistors (FSRs), one per bottle (link)
    • it's easier to establish strong contact on the bigger square sensor, and so get steadier values
  • a clincher connector for each FSR (link)
  • wiring breadboard (link)
  • mounting board for everything (link)
  • some 10Kohm resistors (link)
  • some wires (short and long)
  • a USB micro-B cable to link each ardino board back to the pi (link)

Setup

Dev machine

You'll want to setup some kind of dev machine (linux, mac, whatever):

  • configure SSH client stuff (so you can SSH/SCP to the pi)
  • install the arduino IDE
  • install the Go programming language, golang

Get and build the glassware software

# Check out the code, put it where the golang toolchain expects to see it
mkdir -p ~/go/src/github.com/abworrall
cd  ~/go/src/github.com/abworrall
git clone https://github.com/abworrall/glassware
cd glassware

# Compile the command, so you can run it locally
go build ./cmd/gw

To cross-compile the command to run on a Raspberry Pi, set a few ENV vars:

GOOS=linux GOARCH=arm go build ./cmd/gw

Arduino: board setup

  • Plug the arduino board into your dev machine, using the USB micro-B cable.
  • Start the arduino IDE, and open up the arduino sketch file ./arduino/readpins/readpins.ino.
  • In the IDE, set [tools>board] as Arduino UNO, and [tools>port] as /dev/ttyUSBS0.
    • If you're using a different flavor of Arduino, or not using Linux, you'll need to figure this bit out yourself.
  • If you're using multiple arduino boards, make sure to edit the readpins sketch each time, so that each board gets a unique controller ID.
  • Click 'upload', to load the sketch into the board.
    • If this works, you'll see the red LED on the board start flashing twice a second.

You should have gw compiled for your dev machine, as above. You can now run it in verbose mode, to see if it can talk to the arduino board, and that the board is sending back the right kind of output from readpins. It should look like this:

$ ~/go/src/github.com/abworrall/glassware/gw -v=1
 SerialController(C0), read(/dev/ttyUSB0)= "Controller:C0 A0:773 A1:673 A2:586 A3:507 A4:426 A5:383 "
 SerialController(C0), read(/dev/ttyUSB0)= "Controller:C0 A0:773 A1:674 A2:589 A3:511 A4:431 A5:388 "
 SerialController(C0), read(/dev/ttyUSB0)= "Controller:C0 A0:773 A1:674 A2:588 A3:509 A4:429 A5:384 "

Any unconnected analog pins will return noisy values.

Ardiuno: Force Sensitive Resistors (FSRs)

For each FSR, you should wire it up to an analog pin on the arduino (using the breadboard) with a 10Kohm pull-down resistor, as per this guide. Using a pull-down means the voltage signal will increase as the applied force increases.

This photo shows two FSRs wired up on pins A0 and A1.

photo of wiring setup

Once you have an FSR set up (say, on pin A0), run the gw -v=1 command again to see the values being reported by the FSR. Squeeze the FSR as hard as you can to see the max value, and then play with putting different weights on top of it.

FSRs are finicky

They are not accurate. You can put a known weight on/off the FSR a bunch of times, and each time get a different answer. All you can get reliably is a drop or jump in the right direction.

They are finicky in another way - the object's base needs to be entirely within the sensor. If it is partly outside, then the amount of weight borne by the FSR can vary enormously, and perhaps even be zero. The simplest way to manage this is to slide a quarter coin between the object and the FSR, so that all weight goes through the quarter.

Pi: host setup

Install some kind of Linux on the Pi. I went with raspbian. If Pies remain weirdly unavailable, you can use a random linux box.

Run sudo raspi-config and setup the following:

  • [System options > Wireless] - configure the Wifi your system will be using
  • [System options > password] - for the non-root user
  • [System options > hostname] - glasspi ?
  • [System options > audio] - use headphone jack, not HDMI
  • [System options > boot] - console, autologin
  • [Interface options > SSH] - enable, so you can ssh/scp to the Pi

You can plug the Arduino board into the Pi, instead of your dev machine, at this point.

You should also connect the headphone jack to your speaker, and check basic audio is working: aplay /usr/share/sounds/alsa/Front_Center.wav.

Now setup the software on the Pi.

Pi: the gw tool

From your dev machine, scp ./gw pi@glasspi:~, assuming gw was cross-compiled for ARM as described above, and that your non-root user is pi.

On the pi, you can test it by just running ~/gw -v=1. It should connect to the Arduino controller, and start printing out sensor readings.

When you're happy it all works, you will want the tool to start automatically on boot up - add something like

su pi -c /home/pi/gw > /home/pi/gw.log &

to /etc/rc.local, or something.

Pi: raspotify

This step will turn your Pi into a smart speaker that Spotify will stream to, via Spotify Connect.

Set up raspotify

Raspotify is a handy packaging of librespot, the spotify connect library.

There is a raspotify setup guide. The 'Easy Way' doesn't work, because PulseAudio. The 'Hard Way' ends up needing you to do this, to drive the headphone socket on a Raspbian Pi:

sudo cat <<EOT >> /etc/asound.conf
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.dmix.rate 44100
defaults.pcm.dmix.format S16_LE
EOT

Test it: speaker-test -c2 -l1 should generate some nice pink noise, if you've plugged something into the Pi's headphone socket.

There is a setting in /etc/raspotify/conf you might care about, LIBRESPOT_AUTOPLAY. If you want silence when your playlist runs out, comment this out; else spotify will play an infinite stream of similar songs.

TBH, librespot is a bit flakey with session management, and will sometimes lose the session. Longest I've seen it keep an idle session alive is 12 hours. When the session is lost, the gw tool will start saying StartPlayback: could not find device 'raspotify'. Only fix I have for this is to restart raspotify, e.g. sudo systemctl restart raspotify. Maybe should do that every few hours via crontab, sigh.

Use your phone to link your new smart speaker into your Spotify account

Get your phone, and run the spotify app. Go to [Menu>Devices>Devices Menu], and wait a little bit until you see something like raspotify (glasspi) show up in the list. Then select it. This makes the Pi a smart speaker destination that your Spotify account can play to, via their Spotify Connect API.

This is a one-time operation.

Pi: spotify login

These steps will authenticate the gw tool, so that it can use the Spotify web API to control streaming to your shiny new Pi-based smart speaker. This is kind of a PITA, but is a one-time setup operation.

Create yourself an 'app' on spotify

  • go to https://developer.spotify.com/dashboard/, log in
    • should turn your account into a 'developer account' at some point
  • create a new app (call it 'glassware' or whatever)
  • edit the app's settings, add a redirect URI: http://localhost:8081/oauth-callback
  • get the app's Client ID and Client Secret, cut-n-paste 'em somewhere
    • these will be cached by the gw tool (e.g. cat ~/.gw/secret)

Log the gw tool into spotify

  • The easy way:
    • do it all on your dev machine, and copy the token over
    • run gw -spotify-init -spotify-id=BADCAB1E -spotify-secret=BADCAB1E (but using your ID and Secret)
    • log in, click 'agree', get redirected back; then the tool should say something like:
2022/12/01 14:34:14 Stored the OAuth2 token: /home/abw/.gw/spotify-oauth-token.json
2022/12/01 14:34:14 Have a spotify client logged in as: Adam
  • now copy that token/id/secret over to your Pi: scp -r ~/.gw/ pi@glasspi:~/
  • The harder way:
    • do it directly on the pi ! you'll need to attach a monitor/mouse/keyboard to it
    • if it is booting into a terminal, start up desktop by running startx
    • start a browser, open a terminal window
    • run gw -spotify-init -spotify-id=BADCAB1E -spotify-secret=BADCAB1E (but using your ID and Secret)

After this is complete, the gw tool can reuse the oauth2 token indefinitely, as it will cache the spotify-id and spotify-secret values it needs to refresh the token.

Pi: bluetooth speakers

Having the Pi send audio to a bluetooth speaker is doable, but the internet says you'll want a dedicated bluetooth dongle for the Pi (link), because the Pi's builtin bluetooth is flakey when the Pi is trying to do both Bluetooth and Wifi, e.g. streaming music.

You'll need to figure out how to pair the speaker with the Pi, how to reconfigure alsa (/etc/asound.conf), and repeat the "Hard Way" steps in configuring raspotify. Please send me a PR if you figure it out :)

Spotify

Now the fun bit - deciding what music will be played when the sensors detect things !

Each sensor should get a corresponding playlist. The names are predetermined and based on the sensor names, which in turn are based on which arduino pins the sensors are connected to. If your sensor is wired to pin A3, then it will try to play the playlist Glassware C0/A3.

So create a Spotify playlist with that exact name, and add stuff to it.

About

A hardware/software project that lets you setup some physical objects, and trigger software events when they change weight - e.g. play a particular playlist when a stopper is removed from a bottle.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published