Animat Serial

The Animat Serial interface implements a simple serial protocol to allow the simulation to communicate data between external hardware and the simulation components. This will allow you to do things like sending the membrane voltage of a neuron out to your hardware, or importing in data values and using that to set the current on a neuron. You are not limited to just interacting with the neural systems though. You can use this for virtually all components in the simulation. For example, you could send out the joint angle of hinge joint as data that your hardware could see. AnimatSerial is built on top of the RemotControl device and uses the standard RemoteControl Linkage idea. To use it you will need to add a remote control and choose Animat Serial. Then you will need to set the name, port (example: COM10 on Windows), baud rate, and then press the edit button next to the Links property (shown as ...). This will open the editor for adding, removing, and editing your linkages. You can add input links from the hardware to the simulation, or output links from the simulation back to the hardware. You can also choose to use a pass through linkage or a pulsed linkage. Pass through linkages should be used when you have a continuous stream of data coming in. Pulsed links should be used when you discrete data events that occur. One difference between the linkages for the serial system and the XBee controller is that if you create an input linkage then you can simply type in the name of the source property instead of choosing it from a drop down. You can set this to whatever you like. Similarly, if you choose an output link then you can type in the target property. A second difference is that for all serial linkages you must specify a unique Data ID. This is the ID that it uses to sync up with the hardware on the serial protocol. So the ID that is listed here must match the ID that the hardware knows about. For example, if you want to send the membrane voltage from a neuron to your hardware then you would set it's data ID to be some value, say 0. Any time that the membrane voltage changes then this will be transmitted to the hardware over the serial link and be associated with an ID of 0. Each time the hardware sees data come in with an ID of 0 it needs to understand that this is the membrane voltage from neuron X. Essentially, you must make sure the data between the hardware and simulation are in synch. Here is an attachment that describes the serial communications protocol so you can implement it with your hardware: AnimatSerial ICD.

I have also included a library and test sketch for an Arduino to demonstrate how to use the AnimatSerial communications. It also includes a test project file. You can download this here: AnimatSerialTest.zip. Basically, you create an AnimatSerial object and pass it a pointer to the Serial line you want it to use. You also need to specify the maximum input and output ID values you will be expecting. Then you call begin with the baud rate you want to use. After that you can call animat.readMsgs() to read any incoming messages. You check the animat.isChanged() property to see if any data values have changed in the last read. If they are then you can loop through them to get the new value. To send data you need to call animat.addData(ID, value). You use this to buffer up all your changes for this run of the update loop, then you call animat.writeMsgs() to send them all to the simulation. Here is the code for the sketch for you to look over. It sends a sine wave of data continuously on ID 0, and sends a spike of data each time the sine wave completes on ID 1.

 

#include "AnimatSerial.h"

AnimatSerial animat(&Serial1, 10, 10);

#define PI 3.14159
#define PI2 2*3.14159

float x=0;
int counter=0;
int counterror=0;
AnimatData data;

void setup() {
  Serial.begin(57600);
  while(!Serial);
  Serial.println("Starting setup");

  animat.begin(38400);  // 115200
}

void loop() {
  
  animat.readMsgs();

  if(animat.isChanged())
  {
    for(int i=0; i<animat.getindatatotal(); if(counter="=" if(counterror="=100)" counterror="0;" val1="10*sin(x)," val2="0;" +="0.01;"> PI2)
    {
      val2=1;
      //Serial.println("Pulsing Val2");
    }
      
    //Serial.print("Adding data: ");
    //Serial.println(val1);
    animat.addData(0, val1);
    animat.addData(1, val2);
  
    //Serial.println("Writing data");
    animat.writeMsgs();
    
    if(x > PI2)
      x = 0;
      
    counter = 0;
  }
}
</animat.getindatatotal();>