В основе этой необычной конструкции — контроллер Arduino UNO, который управляет тремя дюжинами сервомашинок при помощи трёх 16-канальных модулей управления PWM.
Для отображения движения, на вал сервомашинок закреплены палочки от эскимо.
Таким образом, используя 36 сервомашинок, можно создавать различные рисунки, а можно управлять ими в интерактивном режиме (они будут следовать за руками пользователя, отслеживая их при помощи ультразвуковых датчиков).
Код скетча (ServosArt Software for Arduino Uno):
Данный код, управляет сервомашинками и обеспечивает повторяемое трёхминутное шоу.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
#include <math.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x42);
#define SERVOMIN 150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 588 // this is the 'maximum' pulse length count (out of 4096)
byte curPos [36]; // stores 50 - 196 repr pulselen/3 of curr pos
byte tarPos [36]; // stores 50 - 196 repr pulselen/3 of target pos
// defines pins numbers
const int trigPin5 = 9;
const int echoPin5 = 10;
const int trigPin4 = 7;
const int echoPin4 = 8;
const int trigPin3 = 5;
const int echoPin3 = 6;
const int trigPin2 = 3;
const int echoPin2 = 4;
const int trigPin1 = 11;
const int echoPin1 = 12;
long duration;
int distance1, distance2, distance3, distance4, distance5;
int mypos=3;
int counter=0;
// input is row, col
// this table provides the servo number
const byte findNum[8][8] = {
{0, 36, 36, 36, 36, 36, 36, 36},
{1, 2, 36, 36, 36, 36, 36, 36},
{3, 4, 5, 36, 36, 36, 36, 36},
{6, 7, 8, 9, 36, 36, 36, 36},
{10, 11, 12, 13, 14, 36, 36, 36},
{15, 16, 17, 18, 19, 20, 36, 36},
{21, 22, 23, 24, 25, 26, 27, 36},
{28, 29, 30, 31, 32, 33, 34, 35}
};
const byte track[8][5] = {
{175,150,125,90,65},
{165,145,125,95,70},
{155,140,125,100,75},
{150,137,125,105,83},
{145,135,125,108,90},
{140,133,125,112,97},
{135,130,125,115,105},
{130,127,125,118,110}
};
const byte positions[5][36]={
{184,174,180,162,169,177,150,162,170,175,140,153,162,169,174,131,144,154,162,168,172,125,136,154,155,162,167,171,119,130,140,149,156,162,167,171},
{171,153,169,136,155,167,125,143,157,166,117,132,147,158,166,111,125,138,149,158,165,107,119,138,142,151,159,165,105,114,125,135,144,153,159,165},
{125,109,140,102,125,147,99,115,134,150,96,109,125,140,153,95,105,118,131,144,149,94,102,118,125,136,147,155,93,100,109,119,130,140,149,157},
{78,80,96,82,94,113,83,92,106,125,83,91,102,117,132,84,91,100,111,125,138,84,90,100,107,119,130,142,84,90,96,105,114,125,135,144},
{65,69,75,72,78,87,74,79,87,99,75,80,87,96,109,77,81,87,95,105,118,78,82,87,94,102,113,125,78,82,87,93,100,109,119,130}
};
const byte spiral[36] = {0,1,3,6,10,15,21,28,29,30,31,32,33,34,35,27,20,14,9,5,2,4,7,11,16,22,23,24,25,26,19,13,8,12,17,18};
void setup() {
pinMode(trigPin1, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin1, INPUT); // Sets the echoPin as an Input
pinMode(trigPin2, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin2, INPUT); // Sets the echoPin as an Input
pinMode(trigPin3, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin3, INPUT); // Sets the echoPin as an Input
pinMode(trigPin4, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin4, INPUT); // Sets the echoPin as an Input
pinMode(trigPin5, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin5, INPUT); // Sets the echoPin as an Input
pwm.begin();
pwm2.begin();
pwm3.begin();
pwm.setPWMFreq(60);
pwm2.setPWMFreq(60);
pwm3.setPWMFreq(60);
delay(10);
// set all servos to midpoint pos and intialize tables
for (int myservo = 0; myservo < 36; myservo++) {
if (myservo < 15) pwm.setPWM(myservo, 0, 375);
if (myservo > 14 && myservo < 28) pwm2.setPWM(myservo - 15, 0, 375);
if (myservo > 27) pwm3.setPWM(myservo - 28, 0, 375);
curPos[myservo] = 125;
tarPos[myservo] = 125;
}
}
void loop() {
for (int count = 0; count < 5; count=count+2) {
for (int myservo = 0; myservo < 36; myservo++) {
setServo2(spiral[myservo], count);
goToTargets(12, 2);
}
/* for (int myservo = 35; myservo > -1; myservo--) {
if (count<4){
setServo2(spiral[myservo], count+1);
goToTargets(5, 3);
}
}*/
}
for (int count = 3; count > 0; count=count-2) {
for (int myservo = 0; myservo < 36; myservo++) {
setServo2(spiral[myservo], count);
goToTargets(12, 2);
}
/* for (int myservo = 35; myservo > -1; myservo--) {
if (count>1){
setServo2(spiral[myservo], count-1);
goToTargets(5, 3);
}
}*/
}
// interesting effects using the diagonals but with variable angles
for (int count2 = 0; count2 < 2; count2++) {
for (int count = 0; count < 8; count++) {
rightDiag2(count + 1 , 14);
goToTargets(20, 2 - count / 4);
}
delay(500);
for (int count = 0; count < 8; count++) {
leftDiag2(count + 1 , 15);
goToTargets(20, 2 - count / 4);
}
delay(500);
}
for (int count2 = 0; count2 < 4; count2++) {
for (int count = 0; count < 8; count++) {
rightDiag2(count + 1 , 14);
}
goToTargets(15, 8);
for (int count = 0; count < 8; count++) {
leftDiag2(count + 1 , 15);
}
goToTargets(15, 8);
}
// now just using regular diagonls where all along diagonal are the same
for (int count = 7; count > -1; count--) {
rightDiag(count + 1 , 4);
goToTargets(20, 2 - count / 4);
}
for (int count = 7; count > -1; count--) {
rows(count + 1 , 1);
goToTargets(20, 2 - count / 4);
}
for (int count = 7; count > -1; count--) {
leftDiag(count + 1 , 0);
goToTargets(20, 2 - count / 4);
}
for (int count = 7; count > -1; count--) {
rows(count + 1 , 3);
goToTargets(20, 2 - count / 4);
}
for (int count = 0; count < 8; count++) {
leftDiag(count + 1 , 1);
goToTargets(20, 2 - count / 4);
}
delay(300);
for (int count = 0; count < 8; count++) {
if (count % 2) rightDiag(count + 1 , 3);
goToTargets(20, 2 - count / 4);
}
for (int myservo = 0; myservo < 36; myservo++) {
setTarget(myservo, 4);
}
// Wave routine
for (int count = 0; count < 120; count++) {
for (int myservo = 0; myservo < 36; myservo++) {
if (curPos[myservo] < 51 && tarPos[myservo] == 50) tarPos[myservo] = 196;
if (curPos[myservo] > 195 && tarPos[myservo] == 196) tarPos[myservo] = 50;
}
goToTargets(0, 0);
}
for (int myservo = 0; myservo < 36; myservo++) {
setServo2(myservo, 2);
}
goToTargets(36, 0);
//Setup for first wave
for (int servoNum = 0; servoNum < 36; servoNum++) {
tarPos[servoNum] = 50 + servoNum * 2;
}
goToTargets(36, 0);
for (int myservo = 0; myservo < 36; myservo++) {
setTarget(myservo, 4);
}
// Wave routine
for (int count = 0; count < 120; count++) {
for (int myservo = 0; myservo < 36; myservo++) {
if (curPos[myservo] < 51 && tarPos[myservo] == 50) tarPos[myservo] = 196;
if (curPos[myservo] > 195 && tarPos[myservo] == 196) tarPos[myservo] = 50;
}
goToTargets(0, 0);
}
// set all to pos 0
for (int myservo = 0; myservo < 36; myservo++) {
setServo2(myservo, 0);
}
goToTargets(36, 0);
for (int count = 0; count < 8; count++) {
if (count % 2) rightDiag(count + 1 , 3);
else rightDiag(count + 1 , 1);
goToTargets(20, 2 - count / 4);
}
for (int myservo = 0; myservo < 36; myservo++) {
setServo2(myservo, 4);
}
goToTargets(36, 0);
for (int count = 0; count < 8; count++) {
if (count % 2) leftDiag(count + 1 , 1);
else leftDiag(count + 1 , 3);
goToTargets(20, 2 - count / 4);
}
for (int myservo = 0; myservo < 36; myservo++) {
setServo2(myservo, 0);
}
goToTargets(36, 0);
for (int count = 0; count < 8; count++) {
if (count % 2) rows(count + 1 , 1);
else rows(count + 1 , 3);
goToTargets(20, 2 - count / 4);
}
for (int count = 0; count < 8; count++) {
if (count % 2) rows(count + 1 , 3);
else rows(count + 1 , 1);
goToTargets(20, 2 - count / 4);
}
for (int count = 0; count < 8; count++) {
if (count % 2) rows(count + 1 , 1);
else rows(count + 1 , 3);
goToTargets(20, 2 - count / 4);
}
for (int count = 0; count < 8; count++) {
if (count % 2) rows(count + 1 , 3);
else rows(count + 1 , 1);
goToTargets(20, 2 - count / 4);
}
piramid ();
for (int count = 0; count < 8; count++) {
rightDiag(count + 1 , 3);
goToTargets(20, 2 - count / 4);
}
for (int count = 0; count < 8; count++) {
leftDiag(count + 1 , 1);
goToTargets(20, 2 - count / 4);
}
for (int count = 0; count < 8; count++) {
rows(count + 1 , 0);
goToTargets(20, 2 - count / 4);
}
// set up for the Ts wave
for (int count = 0; count < 8; count++) {
if (count % 2 == 0)rows(count + 1 , 4);
}
goToTargets(15, 3);
//wave routine
for (int count = 0; count < 240; count++) {
for (int myservo = 0; myservo < 36; myservo++) {
if (curPos[myservo] < 51 && tarPos[myservo] == 50) tarPos[myservo] = 196;
if (curPos[myservo] > 195 && tarPos[myservo] == 196) tarPos[myservo] = 50;
}
goToTargets(0, 0);
}
setForWave(); // set up for second wave
delay(300);
//wave routine
for (int count = 0; count < 240; count++) {
for (int myservo = 0; myservo < 36; myservo++) {
if (curPos[myservo] < 51 && tarPos[myservo] == 50) tarPos[myservo] = 196;
if (curPos[myservo] > 195 && tarPos[myservo] == 196) tarPos[myservo] = 50;
}
goToTargets(0, 0);
}
setAllZero();
delay(300);
triangles();
triangles();
for (int count = 0; count < 36; count++) {
setServo2(count, 3);
}
goToTargets(21, 15);
for (int count = 0; count < 36; count++) {
setServo2(count, 1);
}
goToTargets(36, 0);
for (int count = 0; count < 36; count++) {
setServo2(count, 3);
}
goToTargets(36, 0);
for (int count = 0; count < 36; count++) {
setServo2(count, 1);
}
goToTargets(20, 0);
}
// this is the primary routine for moving the servos, movint them from there current position toward their target postions
void goToTargets(int reps, int mydelay) {
for (int count = 0; count < 5 + 5 * reps; count++) {
for (int myservo = 0; myservo < 36; myservo++) {
if (curPos[myservo] > tarPos[myservo]) curPos[myservo]--;
if (curPos[myservo] < tarPos[myservo]) curPos[myservo]++;
if (curPos[myservo] != tarPos[myservo]) {
if (myservo < 15) pwm.setPWM(myservo, 0, 3 * curPos[myservo]);
if (myservo > 14 && myservo < 28) pwm2.setPWM(myservo - 15, 0, 3 * curPos[myservo]);
if (myservo > 27) pwm3.setPWM(myservo - 28, 0, 3 * curPos[myservo]);
}
}
delay(mydelay);
}
// this is where we check if hand is over the center distance sensor; if so we go into tracker mode
digitalWrite(trigPin3, LOW);
delayMicroseconds(2);
// Sets the trigPin3 on HIGH state for 10 micro seconds
digitalWrite(trigPin3, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin3, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin3, HIGH, 2500);
if (duration > 0) {
counter = 0;
trackRoutine();
}
}
// this sets the target of a servo to one of five preset positions
void setTarget(int myservo, int pos) {
tarPos[myservo] = pos * 38 + 50;
if (tarPos[myservo] > 196)tarPos[myservo] = 196;
}
// this sets all servos to their minimum positions
void setAllZero() {
for (int myservo = 0; myservo < 36; myservo++) {
tarPos[myservo] = 50;
}
for (int count = 0; count < 30; count++) {
goToTargets(0, 0);
}
}
// set target position of servo in rows 1-8
// and coluumns 1-8, addressing them by row and column
// to one of the 5 preset positions
void setServo(int row, int col, int myPos) {
int servoNum = findNum[row - 1][col - 1];
if (myPos == 0) tarPos[servoNum] = 50;
else if (myPos == 4) tarPos[servoNum] = 196;
else if (myPos == 2) tarPos[servoNum] = 125;
else if (myPos == 1) tarPos[servoNum] = 93;
else if (myPos == 3) tarPos[servoNum] = 153;
}
// set target position of servo by servo #
// this is a duplicate of setTarget
void setServo2(int servoNum, int myPos) {
if (myPos == 0) tarPos[servoNum] = 50;
else if (myPos == 4) tarPos[servoNum] = 196;
else if (myPos == 2) tarPos[servoNum] = 125;
else if (myPos == 1) tarPos[servoNum] = 93;
else if (myPos == 3) tarPos[servoNum] = 153;
}
// set target position of servo in rows 1-8 and coluumns 1-8
// special version used by rightdiag2 and leftdiag2
void setServo3(int row, int col, int num, int mult2) {
int servoNum = findNum[row - 1][col - 1];
if (mult2 % 2 == 0)tarPos[servoNum] = 180 - num * mult2;
else tarPos[servoNum] = 60 + num * mult2;
}
// sets servo to point to target at row 0 and targetX
// this uses arctan to point servo at a preset position above the board
void setServo4(int row, int col, int targetX) {
int servoNum = findNum[row - 1][col - 1];
int trueCol = col + 8 - row;
double angle = 1.57 + atan2(targetX - trueCol, row);
tarPos[servoNum] = int(188 - 138 * angle / 3.14);
}
//setup for wave; not very efficient way to do it
void setForWave() {
int mult = 50;
tarPos[0] = 50 + 0;
for (int myservo = 1; myservo < 3; myservo++) { // row 1
tarPos[myservo] = 50 + (myservo - 1) * mult / 3;
}
for (int myservo = 3; myservo < 6; myservo++) { // row 2
tarPos[myservo] = 50 + (myservo - 3) * mult / 3;
}
for (int myservo = 6; myservo < 10; myservo++) { // row 3
tarPos[myservo] = 50 + (myservo - 6) * mult / 3;
}
for (int myservo = 10; myservo < 15; myservo++) { // row 4
tarPos[myservo] = 50 + (myservo - 10) * mult / 3;
}
for (int myservo = 15; myservo < 21; myservo++) { // row 5
tarPos[myservo] = 50 + (myservo - 15) * mult / 3;
}
for (int myservo = 21; myservo < 28; myservo++) { // row 6
tarPos[myservo] = 50 + (myservo - 21) * mult / 3;
}
for (int myservo = 28; myservo < 36; myservo++) { // row 7
tarPos[myservo] = 50 + (myservo - 28) * mult / 3;
}
goToTargets(36, 0);
for (int myservo = 0; myservo < 36; myservo++) {
tarPos[myservo] = 196;
}
}
// the triagle patterns
void triangles () {
setServo2(0, 0);
setServo2(1, 0);
setServo2(2, 0);
setServo2(3, 0);
setServo2(4, 0);
setServo2(5, 0);
setServo2(6, 2);
setServo2(7, 2);
setServo2(8, 2);
setServo2(9, 2);
setServo2(10, 0);
setServo2(11, 2);
setServo2(12, 2);
setServo2(13, 2);
setServo2(14, 0);
setServo2(15, 0);
setServo2(16, 0);
setServo2(17, 2);
setServo2(18, 2);
setServo2(19, 0);
setServo2(20, 0);
setServo2(21, 0);
setServo2(22, 0);
setServo2(23, 0);
setServo2(24, 2);
setServo2(25, 0);
setServo2(26, 0);
setServo2(27, 0);
for (int count = 28; count < 36; count++) {
setServo2(count, 0);
}
goToTargets(15, 0);
delay(500);
setServo2(0, 2);
setServo2(1, 2);
setServo2(2, 2);
setServo2(3, 2);
setServo2(4, 2);
setServo2(5, 2);
setServo2(6, 0);
setServo2(7, 0);
setServo2(8, 0);
setServo2(9, 0);
setServo2(10, 2);
setServo2(11, 0);
setServo2(12, 0);
setServo2(13, 0);
setServo2(14, 2);
setServo2(15, 2);
setServo2(16, 2);
setServo2(17, 0);
setServo2(18, 0);
setServo2(19, 2);
setServo2(20, 2);
setServo2(21, 2);
setServo2(22, 2);
setServo2(23, 2);
setServo2(24, 0);
setServo2(25, 2);
setServo2(26, 2);
setServo2(27, 2);
for (int count = 28; count < 36; count++) {
setServo2(count, 2);
}
goToTargets(15, 0);
delay(500);
}
// way to progressively do something along right diagonal
void rightDiag(int num, int pos) {
if (num == 1) {
setServo(8, 8, pos);
}
if (num == 2) {
setServo(7, 7, pos);
setServo(8, 7, pos);
}
if (num == 3) {
setServo(6, 6, pos);
setServo(7, 6, pos);
setServo(8, 6, pos);
}
if (num == 4) {
setServo(5, 5, pos);
setServo(6, 5, pos);
setServo(7, 5, pos);
setServo(8, 5, pos);
}
if (num == 5) {
setServo(4, 4, pos);
setServo(5, 4, pos);
setServo(6, 4, pos);
setServo(7, 4, pos);
setServo(8, 4, pos);
}
if (num == 6) {
setServo(3, 3, pos);
setServo(4, 3, pos);
setServo(5, 3, pos);
setServo(6, 3, pos);
setServo(7, 3, pos);
setServo(8, 3, pos);
}
if (num == 7) {
setServo(2, 2, pos);
setServo(3, 2, pos);
setServo(4, 2, pos);
setServo(5, 2, pos);
setServo(6, 2, pos);
setServo(7, 2, pos);
setServo(8, 2, pos);
}
if (num == 8) {
setServo(1, 1, pos);
setServo(2, 1, pos);
setServo(3, 1, pos);
setServo(4, 1, pos);
setServo(5, 1, pos);
setServo(6, 1, pos);
setServo(7, 1, pos);
setServo(8, 1, pos);
}
}
// way to progressively do something along the left diagonal
void leftDiag(int num, int pos) {
if (num == 1) {
setServo(8, 1, pos);
}
if (num == 2) {
setServo(7, 1, pos);
setServo(8, 2, pos);
}
if (num == 3) {
setServo(6, 1, pos);
setServo(7, 2, pos);
setServo(8, 3, pos);
}
if (num == 4) {
setServo(5, 1, pos);
setServo(6, 2, pos);
setServo(7, 3, pos);
setServo(8, 4, pos);
}
if (num == 5) {
setServo(4, 1, pos);
setServo(5, 2, pos);
setServo(6, 3, pos);
setServo(7, 4, pos);
setServo(8, 5, pos);
}
if (num == 6) {
setServo(3, 1, pos);
setServo(4, 2, pos);
setServo(5, 3, pos);
setServo(6, 4, pos);
setServo(7, 5, pos);
setServo(8, 6, pos);
}
if (num == 7) {
setServo(2, 1, pos);
setServo(3, 2, pos);
setServo(4, 3, pos);
setServo(5, 4, pos);
setServo(6, 5, pos);
setServo(7, 6, pos);
setServo(8, 7, pos);
}
if (num == 8) {
setServo(1, 1, pos);
setServo(2, 2, pos);
setServo(3, 3, pos);
setServo(4, 4, pos);
setServo(5, 5, pos);
setServo(6, 6, pos);
setServo(7, 7, pos);
setServo(8, 8, pos);
}
}
// like the diagonals except progressively through the rows
void rows(int num, int pos) {
if (num == 1) {
setServo(1, 1, pos);
}
if (num == 2) {
setServo(2, 1, pos);
setServo(2, 2, pos);
}
if (num == 3) {
setServo(3, 1, pos);
setServo(3, 2, pos);
setServo(3, 3, pos);
}
if (num == 4) {
setServo(4, 1, pos);
setServo(4, 2, pos);
setServo(4, 3, pos);
setServo(4, 4, pos);
}
if (num == 5) {
setServo(5, 1, pos);
setServo(5, 2, pos);
setServo(5, 3, pos);
setServo(5, 4, pos);
setServo(5, 5, pos);
}
if (num == 6) {
setServo(6, 1, pos);
setServo(6, 2, pos);
setServo(6, 3, pos);
setServo(6, 4, pos);
setServo(6, 5, pos);
setServo(6, 6, pos);
}
if (num == 7) {
setServo(7, 1, pos);
setServo(7, 2, pos);
setServo(7, 3, pos);
setServo(7, 4, pos);
setServo(7, 5, pos);
setServo(7, 6, pos);
setServo(7, 7, pos);
}
if (num == 8) {
setServo(8, 1, pos);
setServo(8, 2, pos);
setServo(8, 3, pos);
setServo(8, 4, pos);
setServo(8, 5, pos);
setServo(8, 6, pos);
setServo(8, 7, pos);
setServo(8, 8, pos);
}
}
// a particular sequence of patterns
void piramid () {
setServo(2, 1, 1);
setServo(2, 2, 3);
goToTargets(10, 3);
setServo(3, 1, 1);
setServo(3, 3, 3);
goToTargets(10, 3);
setServo(4, 1, 1);
setServo(4, 3, 3);
setServo(4, 2, 1);
setServo(4, 4, 3);
goToTargets(10, 3);
setServo(5, 1, 1);
setServo(5, 4, 3);
setServo(5, 2, 1);
setServo(5, 5, 3);
goToTargets(10, 3);
setServo(6, 1, 1);
setServo(6, 2, 1);
setServo(6, 3, 1);
setServo(6, 4, 3);
setServo(6, 5, 3);
setServo(6, 6, 3);
goToTargets(10, 3);
setServo(7, 1, 1);
setServo(7, 2, 1);
setServo(7, 3, 1);
setServo(7, 5, 3);
setServo(7, 6, 3);
setServo(7, 7, 3);
goToTargets(10, 3);
setServo(8, 1, 1);
setServo(8, 2, 1);
setServo(8, 3, 1);
setServo(8, 4, 1);
setServo(8, 5, 3);
setServo(8, 6, 3);
setServo(8, 7, 3);
setServo(8, 8, 3);
goToTargets(10, 3);
delay (500);
setServo(1, 1, 1);
setServo(3, 2, 1);
setServo(5, 3, 1);
setServo(7, 4, 1);
goToTargets(20, 3);
setServo(1, 1, 3);
setServo(3, 2, 3);
setServo(5, 3, 3);
setServo(7, 4, 3);
goToTargets(20, 3);
setServo(1, 1, 1);
setServo(3, 2, 1);
setServo(5, 3, 1);
setServo(7, 4, 1);
goToTargets(20, 3);
setServo(4, 3, 1);
setServo(5, 4, 1);
setServo(6, 4, 1);
setServo(7, 5, 1);
setServo(8, 5, 1);
goToTargets(20, 3);
setServo(6, 5, 1);
setServo(7, 6, 1);
setServo(8, 6, 1);
setServo(8, 7, 1);
goToTargets(20, 3);
setServo(2, 2, 1);
setServo(3, 3, 1);
setServo(4, 4, 1);
setServo(5, 5, 1);
setServo(6, 6, 1);
setServo(7, 7, 1);
setServo(8, 8, 1);
goToTargets(20, 3);
}
void rightDiag2(int num, int mult) {
if (num == 1) {
setServo3(8, 8, 1, mult);
}
if (num == 2) {
setServo3(7, 7, 1, mult);
setServo3(8, 7, 2, mult);
}
if (num == 3) {
setServo3(6, 6, 1, mult);
setServo3(7, 6, 2, mult);
setServo3(8, 6, 3, mult);
}
if (num == 4) {
setServo3(5, 5, 1, mult);
setServo3(6, 5, 2, mult);
setServo3(7, 5, 3, mult);
setServo3(8, 5, 4, mult);
}
if (num == 5) {
setServo3(4, 4, 1, mult);
setServo3(5, 4, 2, mult);
setServo3(6, 4, 3, mult);
setServo3(7, 4, 4, mult);
setServo3(8, 4, 5, mult);
}
if (num == 6) {
setServo3(3, 3, 1, mult);
setServo3(4, 3, 2, mult);
setServo3(5, 3, 3, mult);
setServo3(6, 3, 4, mult);
setServo3(7, 3, 5, mult);
setServo3(8, 3, 6, mult);
}
if (num == 7) {
setServo3(2, 2, 1, mult);
setServo3(3, 2, 2, mult);
setServo3(4, 2, 3, mult);
setServo3(5, 2, 4, mult);
setServo3(6, 2, 5, mult);
setServo3(7, 2, 6, mult);
setServo3(8, 2, 7, mult);
}
if (num == 8) {
setServo3(1, 1, 1, mult);
setServo3(2, 1, 2, mult);
setServo3(3, 1, 3, mult);
setServo3(4, 1, 4, mult);
setServo3(5, 1, 5, mult);
setServo3(6, 1, 6, mult);
setServo3(7, 1, 7, mult);
setServo3(8, 1, 8, mult);
}
}
void leftDiag2(int num, int mult) {
if (num == 1) {
setServo3(8, 1, 1, mult);
}
if (num == 2) {
setServo3(7, 1, 1, mult);
setServo3(8, 2, 2, mult);
}
if (num == 3) {
setServo3(6, 1, 1, mult);
setServo3(7, 2, 2, mult);
setServo3(8, 3, 3, mult);
}
if (num == 4) {
setServo3(5, 1, 1, mult);
setServo3(6, 2, 2, mult);
setServo3(7, 3, 3, mult);
setServo3(8, 4, 4, mult);
}
if (num == 5) {
setServo3(4, 1, 1, mult);
setServo3(5, 2, 2, mult);
setServo3(6, 3, 3, mult);
setServo3(7, 4, 4, mult);
setServo3(8, 5, 5, mult);
}
if (num == 6) {
setServo3(3, 1, 1, mult);
setServo3(4, 2, 2, mult);
setServo3(5, 3, 3, mult);
setServo3(6, 4, 4, mult);
setServo3(7, 5, 5, mult);
setServo3(8, 6, 6, mult);
}
if (num == 7) {
setServo3(2, 1, 1, mult);
setServo3(3, 2, 2, mult);
setServo3(4, 3, 3, mult);
setServo3(5, 4, 4, mult);
setServo3(6, 5, 5, mult);
setServo3(7, 6, 6, mult);
setServo3(8, 7, 7, mult);
}
if (num == 8) {
setServo3(1, 1, 1, mult);
setServo3(2, 2, 2, mult);
setServo3(3, 3, 3, mult);
setServo3(4, 4, 4, mult);
setServo3(5, 5, 5, mult);
setServo3(6, 6, 6, mult);
setServo3(7, 7, 7, mult);
setServo3(8, 8, 8, mult);
}
}
// this routine reads five distance sensors and points all servos at the position where hand is sensed
// it senses positions over each of the 5 sensors and 4 postitions between them for 9 possible postitions
void trackRoutine() {
int mydelay = 5;
int mycount = 5;
int mytime = 2000;
for (int myservo = 0; myservo < 36; myservo++) {
tarPos[myservo] = positions[2][myservo];
}
goToTargets(36, 0);
while (counter < 25) {
distance1 = 0; distance2 = 0; distance3 = 0; distance4 = 0; distance5 = 0;
for (int count = 0; count < 10; count++) {
digitalWrite(trigPin1, LOW);
delayMicroseconds(2);
// Sets the trigPin3 on HIGH state for 10 micro seconds
digitalWrite(trigPin1, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin1, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin1, HIGH, mytime);
if (duration == 0)duration = 2941;
// Calculating the distance
distance1 = distance1 + duration * 0.034 / 2;
digitalWrite(trigPin2, LOW);
delayMicroseconds(2);
// Sets the trigPin3 on HIGH state for 10 micro seconds
digitalWrite(trigPin2, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin2, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin2, HIGH, mytime);
if (duration == 0)duration = 2941;
// Calculating the distance
distance2 = distance2 + duration * 0.034 / 2;
digitalWrite(trigPin3, LOW);
delayMicroseconds(2);
// Sets the trigPin3 on HIGH state for 10 micro seconds
digitalWrite(trigPin3, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin3, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin3, HIGH, mytime);
if (duration == 0)duration = 2941;
// Calculating the distance
distance3 = distance3 + duration * 0.034 / 2;
digitalWrite(trigPin4, LOW);
delayMicroseconds(2);
// Sets the trigPin1 on HIGH state for 10 micro seconds
digitalWrite(trigPin4, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin4, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin4, HIGH, mytime);
// Calculating the distance
if (duration == 0)duration = 2941;
distance4 = distance4 + duration * 0.034 / 2;
digitalWrite(trigPin5, LOW);
delayMicroseconds(2);
// Sets the trigPin1 on HIGH state for 10 micro seconds
digitalWrite(trigPin5, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin5, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin5, HIGH, mytime);
if (duration == 0)duration = 2941;
// Calculating the distance
distance5 = distance5 + duration * 0.034 / 2;
}
distance1 = 49 - distance1 / 10;
distance2 = 49 - distance2 / 10;
distance3 = 49 - distance3 / 10;
distance4 = 49 - distance4 / 10;
distance5 = 49 - distance5 / 10;
int score = 0;
if (distance1 > 0 and distance2 == 0) score = 1;
else if (distance1 > 0 and distance2 > 0) score = 2;
else if (distance2 > 0 and distance3 == 0) score = 3;
else if (distance2 > 0 and distance3 > 0) score = 4;
else if (distance3 > 0 and distance4 == 0) score = 5;
else if (distance3 > 0 and distance4 > 0) score = 6;
else if (distance4 > 0 and distance5 == 0) score = 7;
else if (distance4 > 0 and distance5 > 0) score = 8;
else if (distance5 > 0) score = 9;
if (score > 0) {
counter = 0;
for (int myservo = 0; myservo < 36; myservo++) {
if (score % 2 == 1) tarPos[myservo] = positions[score / 2][myservo];
else tarPos[myservo] = (positions[score / 2][myservo] + positions[ score / 2 - 1][myservo]) / 2;
}
for (int count = 0; count < 5 + 5 * mycount; count++) {
for (int myservo = 0; myservo < 36; myservo++) {
if (curPos[myservo] > tarPos[myservo]) curPos[myservo]--;
if (curPos[myservo] < tarPos[myservo]) curPos[myservo]++;
if (curPos[myservo] != tarPos[myservo]) {
if (myservo < 15) pwm.setPWM(myservo, 0, 3 * curPos[myservo]);
if (count<25 && myservo > 14 && myservo < 28) pwm2.setPWM(myservo - 15, 0, 3 * curPos[myservo]);
if (count <20 && myservo > 27) pwm3.setPWM(myservo - 28, 0, 3 * curPos[myservo]);
}
}
delay(mydelay);
}
}
counter++;
}
}
Ссылки
Servo Motor Artwork
По теме
Particle Flow — инсталляция на базе Arduino
Узнать запах картины при помощи устройства на Arduino
Sneaky — интерактивный змееподобный робот
Arduino
Ардуино что это и зачем?
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)
