Pecking Test Documentation - theunissenlab/lab-documentation GitHub Wiki

Software, hardware, and network configuration for Pecking test (NAF 125)

Table of Contents

  1. Pecking test code
  2. Sound input and output
  3. Webcams
  4. Computers and network
  5. Data syncing
  6. Arduino

Find our older documentation files (that much of this is based on) on Google Drive.


1 Pecking test code

Most commands are run on the two computers in 125 with the base command pecking_test. See this for the full documentation.

The python code that runs the boxes is saved in our fork of the pyoperant repository (as of Nov 2020 the live-playback branch, but hopefully to be updated to master soon). This code is cloned locally on both computers in 125. On the two computers in 125, this code is located at /home/fet/code/pyoperant.

YAML File

/home/fet/code/pyoperant/pyoperant/tlab/pecking_test.yaml

The relevant lines of this config are:

local_tlab.py File

/home/fet/code/pyoperant/pyoperant/tlab/local_tlab.py

The relevant section of this file is

Jupyter notebook

/home/fet/code/pecking_analysis?

PATH and PYTHONPATH

These should normally be already set (the relevant portions are set by /home/fet/.bash_path). Check them with the following commands. The majority of the path doesn't matter, what is important is that it includes the portions.

echo $PATH
# needs to include /home/fet/bin
echo $PYTHONPATH
# needs to include /home/fet/python_path

Listing the contents of these relevant directories will show you why:

2 Audio software and hardware

The audio software and hardware setup is the cause of many headaches. If we ever learn what it is doing, it should be documented here.

External USB soundcard

Pumpkin and chubbyninja now both have an external USB sound card Roccat Juke ("Juke") because the internal one appeared to die ("PCH"). We had to reconfigure the UDEV file to look for the new sound card. So the microphones and speaker outputs are connected to this usb dongle thing.

udev

This maps our new usb soundcards (the ROCCAT Juke) to the name "Analog". ATTRS{id}=="Juke" would be ATTRS{id}=="PCH" if we were using the built in soundcard.

# /etc/udev/rules.d/analog_audio.rules

KERNELS=="card[0-9]*", SUBSYSTEMS=="sound", ATTRS{id}=="Juke", ATTR{id}="Analog"

alsa

This configuration creates 3 virtual devices: (1) split, which is a two channel device mirroring the device named "Analog" which we configured with udev, and (2) speaker0 and (3) speaker1, which represent the left and right channels of split. We can now play audio out of the left and right channels independently by playing sound to speaker0 and speaker1, respectively. The python code references these virtual speakers, speaker0 and speaker1. You might have to change the name of the device Analog if it does not match what you find out typing lsusb and cat /proc/asound/cards.

# /etc/asound.conf

pcm.split {
	type dmix
	ipc_key 2048
	slave {
    	pcm "hw:Analog"
    	channels 2
	}
}
pcm.speaker0 {
	type plug
	slave.pcm "split"
	hint {
    	show on
    	description "Plays sound through the left channel only"
	}
	ttable.0.0 1
}
pcm.speaker1 {
	type plug
	slave.pcm "split"
	hint {
    	show on
    	description "Plays sound through the right channel only"
	}
	ttable.0.1 1

Amplifier

Audio is run out of the headphone jack where it connects to an amplifier. The amplifier should be adjusted to provide the desired output sound level within its corresponding boxes (appropriate levels for song and call may be labeled on the dial). The left and right channels output from the amplifier are sent one to each box that the computer controls.

3 Webcams

Webcams are identified by their ID. The rules are indicated in webcam.rules and copied to /etc/udev/rules.d on the computers (/etc/udev/rules.d/webcam.rules). If one webcam was to be added, those files would need to be changed. And then you should check that the simulinks are correct under /dev: video_box# are indeed simulinks to the correct webcams!

mjpg_streamer for webcams

This command will start up a webserver on the specified port that shows a simple html page with an embedded video stream. The html page and associated javascript can be edited to provide whatever we want (and should!)

Replace the first BOX=1 in the next command with the appropriate box number

BOX=1 && mjpg_streamer -i "/usr/local/lib/input_uvc.so -d $(readlink -e /dev/video_box$BOX)" -o "/usr/local/lib/output_http.so -p 808$BOX -w /usr/local/www" 2>/dev/null &

Then open a new tab in firefox and look at the camera at this url:

BOX=1 && firefox -new-tab http://192.168.0.102:808$BOX/stream_simple.html

or

BOX=1 && firefox -new-tab http://localhost:808$BOX/stream_simple.html

To remotely access the webcams via ssh

First your machine must be able to ssh the computers down in NWAF (see system folder notes). Then ssh chubbyninja behind the scene and make your port correspond to the one of chubbyninja using the following commands:

ssh -fN -L 8085:localhost:8085 -L 8086:localhost:8086 chubbyninja

Then same thing for pumpkin’s ports:

ssh -fN -L 8082:localhost:8082 -L 8083:localhost:8083 pumpkin

you can now go to your internet browser and visualize the webcam streaming using the following command where the ‘#’ sign is replace by the appropriate box number: 'http://localhost:808#/stream_simple.html'

4 Computers and Network

As of November 2020: The pecking test is set up in room NAF 125 in Boxes 2, 3, 5, and 6. There are 2 computers both Intel NUCs with nearly identical setup, each is responsible for the control of 2 boxes. (Product #BOXD34010WYKH1) and connected to the WiFi router set up in room 123E.

Host Boxes External IP Local IP SSH
chubbyninja 5, 6 192.168.0.112 10.42.0.1 ssh [email protected] -p 65454
pumpkin 2, 3 192.168.0.102 10.42.0.23 ssh [email protected] -p 65455
  • NWAF Network IP: 192.168.0.1

  • Incoming data is redirected by the router on chubbyninja (which acts as a virtual server, as the router itself cannot interpret incoming commands). Chubbyninja listens for incoming ssh connections on port 65454, which must be enabled in the file /etc/sshd_config. After adding the port the computer should listen to in this file, the ssh daemon must be restarted with sudo ssh service restart.

  • To ssh to the computers remotely, use ssh [email protected] -p 65455 for pumpkin and ssh [email protected] -p 65454 for chubbyninja. You can configure these in your own computer's ssh config file, which for windows would be in C:\Users\USERNAME.ssh\config:

Host pumpkin
  HostName 169.229.251.200
  Port 65455
  User fet
Host chubbyninja
  HostName 169.229.251.200
  Port 65454
  User fet

(old notes from Tyler). Here's an old description of the hardware from Tyler, and here is a similar description in google doc format which may be slightly more current.

5 Data syncing

The data saving system is set up in the following way. On each computer, the drive folder contain the Pecking_test folder which is synced using insync with the bdrive Pecking_test folder (account [email protected]). Only part of the content of Pecking_test under bdrive is synced with the local computers:

125_Computers
PythonConfig/scripts
PythonConfig/Commands
PythonConfig/Configuration
PythonConfig/Start Session Data Form.gdform
PythonConfig/Shaping Protocol Python Config.gddoc
PythonConfig/Pecking data.gdsheet
PythonConfig/Pecking data links.gddoc
PythonConfig/Fasting Data Form.gdform
PythonConfig/Session Data Form.gdform
PythonConfig/To-do list.gddoc
PythonConfig/Pyoperant additions.gddoc
PythonConfig/Run an experiment.gdform
PythonConfig/Rules to feed the birds!.gddoc
PythonConfig/Seed consumption experiment.gdform

Then each computer chubbyninja and pumpkin are synced with their respective data folder:

PythonConfig/experiment_chubbyninja or PythonConfig/experiment_pumpkin

When birds are done running one experiment then their data folder is transferred to PythonConfig/Projects under the corresponding project folder.

All the Pecking_test folder is entirely synced also using insync with tdrive: /auto/tdrive/julie/drive/Pecking_test including the Projects folder that contains all the data from the pecking test archived.

6 Arduino

The boxes are interfaced with using an Arduino Uno hooked up to each chamber. The Arduino outputs 3 digital signals to control the pecking button light, the feeder, and the main house light (I don't think this one works though...). It has 1 digital input from the pecking button. The functioning of the chamber and programmatic interface to it should be discussed elsewhere, but there are a few things that are needed to make things work on the computers.

  • The Arduino software must be installed
    • Can be done through sudo apt-get install arduino
  • User must be added to the "dialout" group. This is done automatically when the Arduino software is run for the first time. You must log out and log back in before this takes effect.
  • Again, udev will initialize the Arduinos in arbitrary order, so custom rules should be applied. These rules will create a symbolic link in /dev that points from a consistent and interpretable name like "ttyArduino_box2" to the randomly given name like "ttyACM1".

/etc/udev/rules.d/arduino.rules

### Box 2:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="95232343733351909201", SYMLINK+="ttyArduino_box2"

### Box 3:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="95232343733351403182", SYMLINK+="ttyArduino_box3"

### Box 5:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="9523234373335140A011", SYMLINK+="ttyArduino_box5"

### Box 6:
SUBSYSTEM=="tty", SUBSYSTEMS=="usb", ATTRS{manufacturer}=="Arduino (www.arduino.cc)", ATTRS{serial}=="952323437333518041A1", SYMLINK+="ttyArduino_box6"

Here are some other notes, probably written by Tyler in the before times. I'm confident you'll be able to figure it out.

  1. Initialize ArduinoInterface with device name and baud_rate

  2. Config write with _config_write(channel) then write with _write_bool(channel, True)

  3. Config read with _config_read(channel) then read with _read_bool(channel)

  4. Accessing an output pin on two python terminals works well. Only issue is the config_write command causes it to go to OFF state (equivalent to calling _write_bool(channel, False))

To find a new arduino's serial number, run:

udevadm info --query=all --name=/dev/ttyACM0

and copy id_serial from there.