TactorBots is controlled by a Arduino board. If you are not familiar with Arduino, you can find the information and instructions from Arduino.cc
.zip
from GitHubTactor
Tactor
folder in your Arduino Libraries
folderTactor-main
to Tactor
#include <Servo.h>
#include <Tactor.h>
#define TACTOR_COUNT 7
const int ledPin[] = {A2, A1, A0, A3, 13, 12, 11, 10};
const int servoPin[] = {2, 3, 4, 5, 6, 7, 8, 9};
int servoFrameMillis = 20; //minimum time between servo updates
float startPos = 0;
bool touch = 0;
bool gap = 0;
unsigned long time_now = 0;
//variables
int tactor_num;
int range_max;
int range_min;
int time_touch;
int time_retreat;
int gap_duration;
int contact_duration;
int touch_randomness;
int run_tactor = 0;
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
//variables from software
int tactor_S;
int maxRange_S;
int minRange_S;
int touchTime_S;
int retreatTime_S;
int gapDuration_S;
int contactDuration_S;
int touchRandom_S;
int runTactor_S;
boolean newData = false;
boolean flag = false;
Servo servos[8];
Tactor tactors[8];
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
for (int i = 0; i < TACTOR_COUNT; i++) {
servos[i].attach(servoPin[i]);
tactors[i].begin(servos[i], servoFrameMillis, startPos, ledPin[i]);
}
servos[5].write(90);
servos[0].write(90);
servos[1].write(40);
servos[3].write(90);
servos[4].write(90);
servos[6].write(90);
//wait 1 sec after initialization
delay(1000);
}
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
parseData();
//showParsedData();
newData = false;
}
tactor_num = tactor_S;
range_max = maxRange_S;
range_min = minRange_S;
time_touch = touchTime_S;
time_retreat = retreatTime_S;
gap_duration = gapDuration_S;
contact_duration = contactDuration_S;
touch_randomness = touchRandom_S;
run_tactor = runTactor_S;
// updateTactors();
if (run_tactor == 1 && tactor_num != 5) {
testTactor(tactor_num);
}
if (tactor_num == 5 && run_tactor == 1) {
stroke();
}
else {
servos[5].write(90);
}
}
void updateTactors() {
for (int i = 0; i < TACTOR_COUNT; i++)
tactors[i].update();
}
void testTactor(int i) {
tactors[i].activate();
tactors[i].start();
//updateTactors();
tactors[i].update();
if (tactors[i].hasArrived() && touch == 0 && gap == 0) {
while (millis() < time_now + gap_duration) {
//wait approx. [period] ms
}
gap = 1;
}
if (tactors[i].hasArrived() && touch == 0 && gap == 1) {
// Telling tactor to move 160 degrees in 4 seconds
tactors[i].moveTo(range_min + random(-1 * touch_randomness, touch_randomness) , time_touch);
touch = 1;
gap = 0;
}
time_now = millis();
if (tactors[i].hasArrived() && touch == 1 && gap == 0) {
while (millis() < time_now + contact_duration) {
//wait approx. [period] ms
}
gap = 1;
}
if (tactors[i].hasArrived() && touch == 1 && gap == 1) {
tactors[i].moveTo(range_max + random(-1 * touch_randomness, touch_randomness) , time_retreat);
touch = 0;
gap = 0;
}
}
void stroke() {
servos[5].write(range_min);
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (Serial.available() > 0 && newData == false) {
rc = Serial.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
}
else {
receivedChars[ndx] = '\\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
}
else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
//tactor from software
Serial.println(tempChars);
strtokIndx = strtok(tempChars, ","); // get the first part - the string
switch (atoi(strtokIndx)) {
case 99:
for (int i = 0; i < 7; i++) {
strtokIndx = strtok(NULL, ",");
bool ledStatus = atoi(strtokIndx);
digitalWrite(ledPin[i], ledStatus);
// if (ledStatus) {
// tactors[i].activate();
// } else
// tactors[i].deactivate();
}
break;
default:
tactor_S = atoi(strtokIndx); // copy it to messageFromPC
//minRange
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
minRange_S = atoi(strtokIndx); // convert this part to an integer
//maxRange
strtokIndx = strtok(NULL, ",");
maxRange_S = atoi(strtokIndx); // convert this part to a float
//touchTime
strtokIndx = strtok(NULL, ",");
touchTime_S = atoi(strtokIndx);
//retreatTime
strtokIndx = strtok(NULL, ",");
retreatTime_S = atoi(strtokIndx);
//touch randomness
strtokIndx = strtok(NULL, ",");
touchRandom_S = atoi(strtokIndx);
//contact duration
strtokIndx = strtok(NULL, ",");
contactDuration_S = atoi(strtokIndx);
//gap duration
strtokIndx = strtok(NULL, ",");
gapDuration_S = atoi(strtokIndx);
//run tactor (play/pause button)
strtokIndx = strtok(NULL, ",");
runTactor_S = atoi(strtokIndx);
}
}