Project tutorial

In Servo We Trust! © MIT

Let's control 135 servos with a single Arduino!

  • 7,888 views
  • 1 comment
  • 46 respects

Components and supplies

Apps and online services

About this project

I want to share with you a little story about a challenging experiment, that shows how open source technologies, do indeed, open venues for expansion and learning that otherwise wouldn’t have been possible. Uraiqat architects, an Amman based design firm, talked to me about their vision of implementing a cube that is 100% fully reflective, and designed as a tessellated surface that provides a smooth motion, with a clear wave, live effect. It was their participation for Amman Design Week, last October.

Technically speaking, everything is possible, and realistically speaking it is doable to control over 500 motors at once, to end up in individual movements of each triangle, which shall together drive a geometrical effect.

As an architect turned interaction designer, I am always consciously aware of the borderline between fascination with technology, versus using technology to achieve what couldn’t be achieved in an analogue way. In some cases the conceptual statement could be achieved by any other of analogue method, but the designers would choose to take the extra complicated approach “because we can!” and there is a learning curve tied to understand why you are doing, what you are doing.

The timeframe was 6 weeks. In six weeks, I was supposed to engineer a cubic structure to allow free movements of its 550 pieces, where the movement and interaction scenarios are supposed to reveal the concept of how you see yourself within the city. I took me a week, to think of whether I should say yes or no. Tempted by the fact of building something big, which is borderline architecture work, and by the fact that nearly no components existed in the country, and nobody (probably including the architects themselves) believed that this thing could actually be built. I ended up saying, Yes. And, the journey began.

So I need find a way to control 134 triangles (8 rows of 17 traingales in each cube face) in a sync motion, and through those motions, I need to design scenarios that reveal citizens' interaction with the city and oneself.

Each facade side was 3 x 3 meters , and the project is displayed in a public place. Creating an interaction that depends on moving when you move, which was the initial scenario designed for the cube, was not going to be meaningful in the crowd. The other option was to provide an individual experience, so it is you, amongst the crowd, against this reflective creature, which at times, you can’t control its movement, at other times, you are the centre of the movement, and there are moments where you look at others thinking that we see the same image, but we are getting exactly opposite views.

Designed with this vision, the 4 sides of the cube had different movement scenarios that revealed different meanings.

Installing has been challenging, in every single phase. For example, servo motors had to be oriented on 90 degrees, before the brackets are installed, in order to align the visiual and the relative horizontal positioning of the motors. First of all, motors were aligned and market, with a line that extends from the shaft to the motor body, then brackets where installed, while that worked, in some cases, the team installing the piece, would move the shaft orientation while installing the bracket to the motor, and it was sol tricky to troybleshoot, so I decided to have motors powered, and getting a signal of 90 degrees, while the brackets where installed.

Servos are an interesting kind of motors, with less that 1 amp of power consumptions you can end up with versatile angular movements. In favour of time, budget and the lack of trusted fabricators, the decision was made to use of servos, with the standard tilting brackets —the type used for robotic arms. In stores, I could only find a dozen of those brackets, all over the country so even testing a row of these working together wasn’t possible. The most available power supplies in town where 24V while servos need 5.5V-6V ,and using stepping down voltage isn’t a good option in terms of performance, mind you, the price and the reliability of using batteries was not an option. Winston, a China based company, costume manufactured a 6V-20 Amps power suppies for my request (those were great IP7 supplies). Each facade used 5 supplies with a total of 100 DC amps.

A tree connection was designed to provide power from both sides to compensate for the mild voltage drop. Each motor was connected to a small pref-board fabricated small connector board (picture below) providing a line of 17 connectors per each row in each facade (you do the math!) 1.6mm wires were used for power, while signal wires were connected to an CAT8 data cable.

DC power connectors, each costs around 15 EUR in Jordan, with a tree connection, this meant 2 plugs per each row; due to budget restrictions, the tree connection was designed, with an end terminal of an MK plug for AC installations. Looks weird, but it worked well!

Controlling 134 servos at once, had different options, a) to use the same signal for multiple servos, resulting in a identical servo movement of multiple Arduinos, or b) use multiple servos as master and slave [but that was my least favorable option] or c) use a driver, for a complete control over each individual motion. This was the most logical and most technically sane option, and which eventually I ended up using. The PCA9685, from Adafruit, uses I2C protocol, and eventually controls PWM signal to each motor individually. The shield hosts 16 motors and you can cluster a number as many shields as you want, which provides a versatile way to move a large number of motors synchronically, in a very smooth way. Each line of 17 motors was connected to a shield, then all shields where connected to a single Arduino, and literally that's it. The one important tweak that killed the jitter is to make sure the motor frequency of the motor is the same as the code (the sample code is 60hz which corresponds to most analoge servos), so mind that in your code. Another trick, which I unfortunatly didn't have the time to try but would have love to explore is to use Timer1, instead of Timer0, I believe this would have allowed for better speed control, but, well, maybe I can test it for the next project, because you know..you build 544 servos every day :)

I respect the boldness of the architects in how they wanted to move further with an idea that is byond their comfort zone. I immensly respect opensource technologies, without which none of us, would have wittnessed the piece in action. It was such an experience.

Team: Most Arduino code has been collabortively produced with Loay Ghannam (a big shout out to his fast work!). Thanks to the wonderful team of volunteers and friends who have actually soldered, installed and built this piece: Zaid Marji (without him, this piece wouldn't have been built I guess), Laila Atalla (my legal consultant friend, who also is a greta solderer), Zaid Saleh (who got soldering iron in his eyes and continued to work!), May Abrash and Abdalla Hamad. A great thanks to everyone.

Well, I had this account since 5 years, as an anonymous Maya, but actually am Moushira :)

Moushira Elamrawy

Design Technologist

Schematics

PWM driver to arduino wiring, image from Adafriut.com
Driver pdbfpqyzvi

Code

Arduino Code to control 8 Adafruit servo drivers to adjust them to 90 degreesArduino
#include "Arduino.h"
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

//numbering works in binary. Check here if you get confused http://www.allspectrum.com/store/all-spectrum-electronics-binary-decimal-hex-reference-card-free-p-8251.html

Adafruit_PWMServoDriver pwm0 = Adafruit_PWMServoDriver(0x40); //in this one you don't solder the board
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x41); //in this one you solder one register.  Check adafruit tutorial for details https://learn.adafruit.com/16-channel-pwm-servo-driver/chaining-drivers
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x42);
Adafruit_PWMServoDriver pwm7 = Adafruit_PWMServoDriver(0x43); 
Adafruit_PWMServoDriver pwm6 = Adafruit_PWMServoDriver(0x44);
Adafruit_PWMServoDriver pwm5 = Adafruit_PWMServoDriver(0x45);
Adafruit_PWMServoDriver pwm4 = Adafruit_PWMServoDriver(0x46);
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x47);




int C = 500; //delay variable
int x = 250; //through testing we found pwm 250 to look visiually as 90 degrees



void setup() {



           pwm0.begin();
  pwm0.setPWMFreq(50);    //add frequency based on your motor datasheet, otherwise, do NOT complain of the jitter :)
             pwm1.begin();
  pwm1.setPWMFreq(50);
             pwm2.begin();
  pwm2.setPWMFreq(50);
             pwm3.begin();
  pwm3.setPWMFreq(50);


               pwm4.begin();
  pwm4.setPWMFreq(50);
               pwm5.begin();
  pwm5.setPWMFreq(50);
               pwm6.begin();
  pwm6.setPWMFreq(50);
               pwm7.begin();
  pwm7.setPWMFreq(50);
}

void loop () {
  
 for (int i = 0; i <= 15; i++) {  //according to the driver library i is the number of motors 
      pwm7.setPWM(i, 0, x);
      pwm6.setPWM(i, 0, x);
      pwm5.setPWM(i, 0, x);
      pwm4.setPWM(i, 0, x);
      pwm3.setPWM(i, 0, x);
      pwm2.setPWM(i, 0, x);
      pwm1.setPWM(i, 0, x);
      pwm0.setPWM(i, 0, x);
      delay(50);

  
}

delay (C);
}

Comments

Similar projects you might like

Plant Communicator

Project tutorial by Arduino

  • 140 views
  • 0 comments
  • 0 respects

The Nerd

Project tutorial by Arduino

  • 108 views
  • 1 comment
  • 0 respects

LED Matrix Display Badge

Project tutorial by FabLabAQ

  • 599 views
  • 0 comments
  • 2 respects

PICASO 4.0 The Infinite X- Axis CNC Wall Engraver

Project tutorial by Arnab Kumar Das

  • 122 views
  • 1 comment
  • 1 respect

Object Tracker and Updater

by Rupin Chheda

  • 146 views
  • 1 comment
  • 1 respect

Temperature Control

Project tutorial by reteprelleum

  • 1,188 views
  • 1 comment
  • 7 respects
Add projectSign up / Login