Tuesday, March 4, 2014

A simple behavioral protocol

Let's put together the tools we have so far and build a complete behavioral protocol. This is for an early phase of behavioral shaping, in which all a subject has to do is activate a touch sensor, after which he will immediately receive a reward. We also want the ability to give rewards at arbitrary times, even when the subject has done nothing.

Here's what will be running on the computer:

1) The chat interface. This receives input from the Arduino over the serial port and immediately writes it to a file on disk. Let's call this file 'ardulines'. Also, it checks a pipe, called 'TO_DEV' for any input from the user/experimenter, and sends it to the Arduino.

2) Another terminal which allows the user/experimenter to write to the pipe TO_DEV. This is the same pipe that is checked by the chat interface; anything written to it is sent to the Arduino. This is how the user/experimenter can signal the delivery of a reward at an arbitrary time.

3) A graphical display script which reads all of the text in ardulines, parses it, and displays the progress of the subject graphically.

I've intentionally separated the chat interface from everything else. That's because we want this to keep running even if something else, like the graphical display, crashes. We also want it to keep ardulines constantly updated with the latest info from the Arduino. Thus, in the worst case when everything crashes, we'll have all of the data from the session.

Later it might be nice to combine scripts 2 and 3, so that the user can both view the progress of the subject and send new signals to the Arduino within the same environment. Let's keep it simple for now though.


Here's what will be running on the Arduino:

The sketch will implement the chat receiver from last time, to catch text coming from the computer (such as user commands). It will also contain a simple state machine that goes through the following states.
  • State 0: Trial start. Send the time to the computer. Go to state 1.
  • State 1: Wait for input. If subject touches the sensor, or if the text 'REWARD' is received from the computer, go to State 1. Otherwise stay in State 0.
  • State 2: Deliver reward. Open the reward valve. Start a reward timer. Go to state 3.
  • State 3: Wait until reward timer reaches desired value. Close the valve. Go to State 0.
The nice thing about state machines is that it's very clear what the inputs and outputs are supposed to be in each state, as well as when to transition. That makes debugging easier.

The waiting state 3 is an example of how to avoid delay commands in the Arduino. Instead, we should aim to call loop() as often as possible, even if we do nothing on most of the calls. That way, our other code (such as receiving chats) will still run; if we had used delay, then nothing would happen until the delay was over.


The code


The chat.py module incorporates the chatting functions that I discussed in previous postings, as well as the logic relating to ardulines and TO_DEV pipe.

On the Arduino side, there are a couple of modules -- chat.cpp and mpr121.cpp -- that handle the chat receiving and the touch sensor, respectively. Thanks to Jim Lindblom and SparkFun for providing the MPR121 code!

Here is the loop() function in the main sketch that implements the state machine:


Here is a script, main1.py, which I use to start and run the chatter:


In operation!

I used this to run an experiment. Here's a screen shot:


Here's what's going on:
  • Upper right terminal: this is an IPython instance running main1.py, shown above. In addition to writing out ardulines and polling TO_DEV, it is also echoing everything to the terminal as a simple text-based readout of what's going on.
  • Lower right terminal: here's where I can write the string "REWARD" to TO_DEV whenever I want to send a reward manually, as opposed to the automatic rewards that the state machine delivers after touches.
  • Lower left terminal: another ipython instance where I'm running a simple graphical display script, shown on the upper left. This script parses ardulines and can display graphs based on the events it reads. In this case there is not much to display, so I'm simply creating a histogram over time of rewards. I'd like to have t

Next steps

There's a few user-interface niceties to take care of. It would be nice to have the graphical display script run continuously, so I don't have to update the graph manually. 

I'd like to standardize the text output from the arduino a bit more. Essentially we are creating a communication protocol. Ideally we'd be able to send asynchronous commands (like REWARD) to the Arduino, as well as set parameters (like the inter-trial interval) on the fly so that we don't need to hard code them in the sketch. Conversely, the Arduino should report on everything it is doing (like state changes, touches detected) so that they can be written to ardulines in a standardized format.

Probably most important is creating a more complex state machine, one that implements a standard two-alternative choice psychological paradigm, so that we can study more interesting behaviors.




No comments:

Post a Comment