Menu
Examples
Receiving data from Arduino:
In this example, a distance sensor (SHARP 2Y0A2) will be used to edit a Slicer linear transformation. The transformation can be used to translate whatever model/volume in Slicer.
Exemplary Slicer scene can be downloaded from here.
The code for Arduino is the following (sensor connected to pin A0):
int sensorpin = 0; // analog pin used to connect the sharp sensor
int val = 0; // variable to store the values from sensor(initially zero)
float scalefactor = 10.0; // this depends on the specific slicer scene
void setup()
{
Serial.begin(9600); // starts the serial monitor
}
void loop()
{
val = analogRead(sensorpin); // reads the value of the sharp sensor
Serial.println(val * scalefactor); // prints the value of the sensor to the serial monitor
delay(200); // wait for this much time before printing next value
}
The code to be written into the Python shell embedded in Slicer is the following (set the proper transformation node ID according to the specific Slicer scene):
class ExternalTransformationController():
"""
Class for probe control.
"""
def __init__(self):
# Get Arduino node from Slicer scene
self.ArduinoNode = slicer.mrmlScene.GetFirstNodeByName("arduinoNode")
# Add observer to Arduino node and define the function to execute when an parameter is modified
sceneModifiedObserverTag = self.ArduinoNode.AddObserver(vtk.vtkCommand.ModifiedEvent,
self.editTransformation)
# Get Transformation node from the scene
self.transform = slicer.mrmlScene.GetNodeByID("vtkMRMLLinearTransformNode7")
# Initialize identity matrix to be used for probe translation
self.matrix = vtk.vtkMatrix4x4()
def editTransformation(self, caller, event):
"""
Function ran when an parameter into the Arduino node is modified.
"""
# Edit matrix according to the data read from the distance sensor
self.matrix.SetElement(2, 3, float(self.ArduinoNode.GetParameter("Data")))
# Update transformation node
self.transform.SetMatrixTransformToParent(self.matrix)
# Refresh Slicer views
slicer.util.resetSliceViews()
# Instantiate object, this will enable the quasi-real time probe control
controller = ExternalTransformationController()
Once the link has been established by using of SlicerArduino, the data coming from the sensor (move a hand back and forward) will edit the transformation node that, in turn, will move the associated model/volume.
Send data to Arduino:
In this example a linear servomotor (Actuonix L16 Actuator 50mm) is controlled by using a translation computed by Slicer. The example mimics a radiotherapy couch correction on basis of the alignment of daily and planning CTs.
The Arduino code is (sensor connected to pin 9):
/*
* range servo ms 1000 -- 2000 -> 0 -- 4.8 cm
* 1 ms -> 0.0048 cm
* 1 cm -> 208.3 ms
*/
//Includes
#include <Servo.h>
//Defines
#define LINEARACTUATORPIN 9 //Linear Actuator Digital Pin
Servo LINEARACTUATOR; // create servo objects to control the linear actuator
int minValue = 1000;
int maxValue = 2000;
float translation;
void setup()
{
Serial.begin(9600);
//initialize servo/linear actuator objects
LINEARACTUATOR.attach(LINEARACTUATORPIN, minValue, maxValue); // attaches/activates the linear actuator as a servo object
//use the writeMicroseconds to set the linear actuators to their default positions
LINEARACTUATOR.writeMicroseconds(minValue);
delay(1000);
}
void loop()
{
delay(100);
if (Serial.available() > 0)
{
translation = Serial.parseFloat() * 0.1; // Slicer use mm
//Serial.println(translation);
if (translation <= 4.8) // max displacement
{
LINEARACTUATOR.writeMicroseconds(minValue + (translation*208.3));
}
}
}
The code to be written into the Python shell embedded in Slicer is the following (set the proper transformation node ID according to the specific Slicer scene):
# Get transformation node from Slicer scene
transformation_node = slicer.mrmlScene.GetNodeByID("vtkMRMLLinearTransformNode4")
# Get transformation matrix from node
transformation_matrix = transformation_node.GetMatrixTransformFromParent()
# Get z translation
z_translation = transformation_matrix.GetElement(2,3)
# Send translation to Arduino board
slicer.modules.arduinoconnect.widgetRepresentation().self().logic.sendMessage("%.3f" % (z_translation))