Introduction: Motorized, Sound Reacting Star Wars At-St Bandai Model, With Arduino.

    Made from Star Wars At-St Model from Bandai.

    Reacts to sound and turns its head towards it.

    Made with Arduino Nano, a 3dprinted custom part, microphones, micro servo.

    This instructable is made to share the modifications required to achieve the sound reaction anche head rotation capabilities. Includes Arduino Coding, 3d STL Files for printing necessary parts, and obiouvsly instructions to make it happen. Intentionally it won't focus on painting & weathering process, which is a matter of model making, there also are several resources for this i'll link later on. n c +

    Enjoy!

    Step 1: Materials

    Model Kit

    • 1 x AT-ST Walker Star Wars Model Scale 1/48 Model Kit Bandai - On eBay Here - € 33,69

    Other Materials

    • 1Kg Plaster "scagliola" (for the base) - from the hobby store - 7,10€
    • Paint (i painted my model, but this instructable doesn't focus on painting process)
    • An Iron Pin (optional)

    Electronic parts

    • 1 x Stainless DPDT OFF/ON White Led switch - On eBay Here - €6,99
    • 2 x Microphone Sound Module for Arduino - On eBay Here - €1,79 x 2
    • 1 x "Arduino Nano" or compatible: Nano V3.0 ATmega328 16M 5V - CH340G board - € 2,70 -On eBay Here
    • 1 x IDE HDD ATA 40-pin 80-wire Hard Drive Data Ribbon Cable 30cm - Harvested form old PC or On eBay Here - € 4,40
    • 2 x Internal audio cable CD / DVD / DVD-RW Drive - Harvested form old PC - or On eBay Here - €3,36 x 2
    • 1 x V Battery Clip T-type Snap On Connector (9v) - On eBay Here - € 1,59
    • 1 x box holder for 2 AA batteries (3.3v) - On eBay Here - € 1
    • 1 x Micro Servo Tower Pro - On eBay Here - € 1,49
    • 2 x CARBON RESISTOR 220K OHM 1/4W +/-5% - On eBay Here - < 0.50€
    • 2 mt PVC insulated 1.2 mm electric wire - Harvested or On eBay Here < 0.50€
    • 1 x LED 5 mm ORANGE On eBay Here - < 0.50€
    • 1 x LED 5 mm Warm White On eBay Here - < 0.50€

      TOT 73,28€

    Step 2: Tools

    Tools for model making

    This Instructable is not focused on model making.
    Let's list the minimal tools necessary for making a model: On Ebay here

    • Plastic Sprue Cutter - for cutting & snipping sprues and parts on plastic kits
    • Mini Flat File - for filing and smoothing off burrs or excess material.
    • Craft Knife - for cutting out shapes, decals and general craft/hobby tasks.
    • Self Healing Cutting Mat - protects work surface

    The Bandai At-St Kit is one of the easiest kit available. Can be built without glue (not for this project). Painting & Weathering is suggested but not strictly necessary to achieve a nice model. This project requires some glueing:

    • Ciano CA super glue On eBay Here
    • Plastic Model Cement (very fluid, works only on not painted plastic)

    General tools

    3d Printing

    • A 3d printer is required:
      • to produce the joint to fix the mini servo inside the head.
      • optionally, also to build the housing inside the base (i'll explain later)
    • Alternatively a kind friend, or a professional 3dprinting service that can print it for you.
    • May be i can make one joint, and ship it to you... send a message to me.

    Electronics tools

    Optional: If you don't own it, get a prototype kit:

    • If the circuit get a little complicated it's very easy to mess around.
      I suggest to always prototype the circuits before soldering using a prototype kit with:

    Step 3: Building the Model: Wire the Legs

    Let's build the model.

    You have to follow the very good instructions that comes with the Bandai model.

    When it comes to Legs building, the first modification is required:

    • Separate two pair of wires from the "80-wire Hard Drive Data Ribbon", longest as possible (30 cm). So you will have one double wire for one leg, and one for the other. Total 4 wires.
    • You have to Insert each of these electric wires into the model form the bottom of the feets, through the legs, to the central body, and then to the head. Leave about 10 cm of wire under the feet.
    • The wire is very thin, but you have to remove some portions of plastic here and there, in order to make room for the wire. Use your Craft Knife to achieve this.

    Sadly i don't have much foto of this phase. So i Made instructions onto kit's user manual, to manage joints and wiring. See pics.

    Attention !!! Wires are very thin, can break and can be damaged by glue (especially by plastic cement that is a solvent) and paint thinner. Be very careful. I had a very bad problem myself of this kind. Always glue the parts AFTER you checked the connection.


    Step 4: Building the Model: Modify the Neck

    If all has gone well, you now should have two 10cm long wires that is coming out from the neck hole into the torso. Each with 2 wires in it. Total 4 wires.

    Neck Preparation

    • This project requires only 3 wires to the head, so lets' abandon one wire here and to cut here and weld a new 20 cm 3 wires ribbon from "80-wire Hard Drive Data Ribbon" to 3 of the 4 wires available. Use your soldering iron and a small "Heat Shrinkable Sleeve" isolate the soldered parts. The "neck" will later be glued to the torso.
    • Prepare the micro servo arm (comes with the servo) , by removing all but the circular ferrule part. Sand it.(see pic)
    • Cut the upper part of the neck (see pic). You have to cut until your section's diameter will be the same diameter as the Servo arm. So there will be no step between the two.
    • (optional) Prepare an Iron Nail, has to fit inside the modified servo arm hole. Will make it stronger. Pay attention: Its head has be filed to the minimum thickness you can, otherwise the servo joint will not have enough room and will not hold.

    Neck Assembly

    • Assemble the two halves of the neck, keeping the Wires inside it, and making a hole in the center where there the slot is. Please see pics to get it.
    • On the upper top you'll glue (wit CA superglue) the Modified servo arm.
    • Optionally you'll make it stronger using the Nail you've prepared.

    Neck Sanding

    • After drying, sand the top of the neck with sanding paper. Has to be smooth because has to have no friction while rotating.
    • Then paint it, if you like...

    Neck glueing

    • You can glue the neck to the torsowhile assembling the two halves (in order to better manage wiring, and not have the need make room for its loop inside the torso). Or you can do it later if you want (as i did). Will be easier to work with the head, but it will be little harder to assemble it later...

    DON'T FORGET TO CHECK THE WIRING WITH THE TESTER

    Step 5: Build the Servo Holder​

    Now we have to modify the head to hold the micro servo and make it fit to the servo arm coming form the neck below. This joint will require no glue. I added 2 led2, and opened only one of the "eyes" as you can see in pics and video.

    3d print the Servo Holder

    • 3d Print the part with any 3d printer
      • STL Available for download

    As you can see the part will perfectly fit with the bottom of the head.
    Glue is almost not required (but i glued it)

    You can now test installing your servo, to see if all is fitting well. Also try to attach the neck and see if all is ok.

    Leave the servo installed but not glued. This will let take the measurements for the next step.

    Step 6: Prepare the Head

    Make room for the Micro-Servo

    • To make room in the rear of the seats i managed to bring the Floor&seats part about 7mm further.
    • To achieve this you'll have to:
      • Cut the front part of the Seats. ( i used Dremel but you can get it with the cutter)
      • Cut some millimetre also to the left and right of the Floor&seats part.
      • Cut the back intermediate wall to make room for the servo
      • Cut the legs and the hands of the pilot.

    Then you have to make it all fitting. I recreated the back wall cutting and repositioning the previous (see pics).

    I didn't install neither the right pilot, nor Chewbacca.

    You really don't have to worry about these mutilations, because very little will be seen for the eye that will be left opened. Test it by yourself, and see pics for details.

    I'll agree that we're loosing accuracy here. But we'll be getting this thing to move!

    Paint the inside of the cockpit (if you like)

    As said not much of the cockpit will be visible. If you d'like to paint it it's time to do it.

    i Suggest to follow this very good tutorial if you want a great guide to paint and weather this particular cockpit and Pilot:Bandai's 1/48th scale AT-ST: Part 5 Video courtesy of Helgan35

    Step 7: Embed the Servo Into the Head

    Micro-servo

    • A little modification has to be made here, in order to conceal the servo wires If you do not want to see the servo wires from the "eye": simply unscrew the servo top cover and make an housing on the right side of the servo, to get wires through it.
    • I also decided do attach to the servo some unused cockpit part
    • A blue servo inside the At-St head, is really not cool. Paint it! with primer or the color you like.
    • Install the two leds: i installed the white warm led at the right of the pilot, and the orange led behind the seat of the pilot. See pictures. While not having much room i directly glued the LEDS on the servo with CA.

    Cable the head

    • Make an hole into the head floor to get our cable inside.
    • This part will move very much so i suggest to Make a long loop to leave all the movement degrees needed.
    • Add a piece of heat shrinkable sleeve where the cable enters the hole, to make it stronger.

    Assemble the head

    • We've our 3 wires inside the At-St head.

    • It is time to solder the wires (See Fritzing Schematics Pic):
      • Leds
      • Resistance
      • Servo
    • Glue all the pieces together with Cement. Use Ca if you're gluing painted parts.
    • Also i glued the top part of the servo onto the 3d part with little CA (note: don't worry if you have to replace servo if gears are broken (as i did) i managed to do it by removing the top 4 screws...

    Step 8: Build the Electronics

    Diagram

    You can find two Fritzing diagrams in this tutorial.

    • the one in this step is for the testing platform, with Arduino UNO that will be attached to a PC through (or MAC)

    The interference problem

    As a premise i say i'm not very confident with electronics. I encountered an interference problem between the servo movement and the Mics... I managed to solve it only by dividing the power source. I know this could be done better. Please feel free to comment end suggest improvements .So i have 2 separate power circuit, one for Arduino Nano (and servo and leds (9v)). the other for microphones only (3,3v).

    Prototype

    I suggest you build this using the prototype set before, and then you replicate it into the model.

    Once you've made it work into your prototype set, you will put into the model with Arduino nano.

    So by now you should have:

    • Your model Fully Assembled and painted
    • Model is Completely wired and attached to the prototype kit
    • the head is detached form the neck.

    Step 9: Program Arduino

    Program

    Time to program our Arduino, you have to connect it to an USB port of your pc, then open the EDI, and upload the Sketch below.

    About this code i made i can say:

    • it Uses Millis and not delays to do its job
    • It has 3 modes:
      • "Scan": It's when the machine is like scanning the environment moving slowly its head left and right.
      • "AfraidSx": It's when a sound is detected on the Left. The machine turns to left, and randomly moves a it's head figuring out if there's something to shoot at.
      • "AfraidDx": Same as above, but on the Right.
    • Sound detection will trigger one of the above modes

    • "Detect noise" (the most difficult part) is always running and its purpose is to differentiate between calls and noise.Before this was introduced, anything triggered the head rotation and was not very cool.
    #include <br>
    Servo servo;
    int center = 115;
    int limitsx = 85;
    int limitdx = 145;
    int Behaviour = 1; //setta behaviuour iniziale
    int pos = 85;
    int Direction=1;
    byte endingAfraid = 0;
    //knock
    const int knockSensor = 5; // the piezo is connected to analog pin 0
    //const int threshold = 100;  // threshold value to decide when the detected sound is a knock or not
    int sensorReading = 0;
    unsigned long millisAtKnockDx = 0;
    //knock sx
    const int knockSensor2 = 3; // the piezo is connected to analog pin 0
    //const int threshold = 100;  // threshold value to decide when the detected sound is a knock or not
    int sensorReading2 = 0;
    unsigned long millisAtKnockSx = 0;
    //verboselog
    const int VelocityCiclo1 = 1000;
    int CountCiclo1 = 0;
    unsigned long previousMillis1;
    //afraiddx
    const int StartVelocityCiclo2 = 100;
    const int EndVelocityCiclo2 = 500;
    int CountCiclo2 = 0;
    unsigned long previousMillis2;
    byte servoSweep2 = 0;
    //afraidsx
    const int StartVelocityCiclo4 = 100;
    const int EndVelocityCiclo4 = 500;
    int CountCiclo4 = 0;
    unsigned long previousMillis4;
    byte servoSweep4 = 0;
    //ledloop
    const int VelocityCiclo5 = 200;
    int CountCiclo5 = 0;
    unsigned long previousMillis5;
    byte servoSweep5 = 0;
    //scan
    const int VelocityCiclo3 = 130;
    int CountCiclo3 = 0;
    unsigned long previousMillis3;
    int pos3 = 0;
    //DetectnOise
    int KnockDetected = 0;
    int PreviousKnockDetected = 0;
    const int VelocityCiclo6 = 500; //lentezza del ciclo di detect rumore
    int CountCiclo6 = 0;
    unsigned long previousMillis6;
    int NoiseTresh = 2; //soglia. abbassare per rendere meno sensibile al casino. se ho almeno 3 knock in 1000 msec allora non è un tirgeer....
    int NoiseDetected = 0;
    //DDelayUscita da noise
    const int VelocityCiclo7 = 1000; //lentezza dolp la quale tornare alla normalità...
    int CountCiclo7 = 0;
    unsigned long previousMillis7;
    void setup(){
      servo.attach(6);
      Serial.begin(9600);  // initialize the serial communications 4 debug 
      //pinMode(ControlSwitch, INPUT); //
      //pinMode(Led5, OUTPUT); 
      pos3 = limitsx;
     
    //IntLed----------------------
     //led
       pinMode(12, OUTPUT);
       pinMode(11, OUTPUT);
       pinMode(10, OUTPUT);
       pinMode(9, OUTPUT);
       pinMode(8, OUTPUT);
       pinMode(7, OUTPUT);
    //IntLed----------------------
      
    }
    void loop(){
      switch (Behaviour){
      case 1:
        Scan();
        //AfraidFr();
        break;
      case 2:
        if ((millis() <= millisAtKnockDx)) {  // cicli dopo i quali tornare in scan
          AfraidDx();
        } 
        else {
          Direction=0;
          Behaviour = 1;
          endingAfraid = 1;
        }
        break;
      case 3:
        if ((millis() <= millisAtKnockSx))  {  // cicli dopo i quali tornare in scan
          AfraidSx();
        } 
        else {
          Direction=1;
          Behaviour = 1;
          endingAfraid = 1;
        }
        break;
      } 
      KnockTriggerDx();
      KnockTriggerSx();
      VerboseLog();
      DetectNoise();
      
      digitalWrite(12, HIGH);
      digitalWrite(11, HIGH);
      digitalWrite(10, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(8, HIGH);
      digitalWrite(7, HIGH);
    }
    void KnockTriggerDx() {
      // read the sensor and store it in the variable sensorReading:
      sensorReading = digitalRead(knockSensor);    
      // if the sensor reading is greater than the threshold:
      if (sensorReading == 1) {
        // toggle the status of the ledPin:
        Serial.println("Knock DX !!!!!!!!!!!");
        KnockDetected++; // setto per riconoscere parlato.
        millisAtKnockDx = millis() + random(3000,10000); // azzero counter afraid dx
        if (NoiseDetected == 0){
        Behaviour = 2; //vado in afraid dx
        }
        delay(200);
      }
    }
    void KnockTriggerSx() {
      // read the sensor and store it in the variable sensorReading:
      sensorReading2 = digitalRead(knockSensor2);    
      // if the sensor reading is greater than the threshold:
      if (sensorReading2 == 1) {
        // toggle the status of the ledPin:
        Serial.println("Knock SX !!!!!!!!!!!");
        KnockDetected++; // setto per riconoscere parlato.
        millisAtKnockSx = millis() + random(3000,10000); // azzero counter afraid dx
        if (NoiseDetected == 0){
        Behaviour = 3; //vado in afraid sx
        }
        delay(200);
      }
    }
    void AfraidDx(){
      if (millis() >= previousMillis2){
        CountCiclo2++;
        previousMillis2 = previousMillis2+random(StartVelocityCiclo2,EndVelocityCiclo2); // each case gets 100ms
        servoSweep2 = random(1,4); //seleziona caso random tra 1 e 3
        /*if (servoSweep == 7){ //cicla tutti i casi
         servoSweep = 1;
         }*/
      }
      switch (servoSweep2){
      case 1:
        pos = limitdx-3;
        servo.write(pos);
        break;
      case 2:
        pos = limitdx-6;
        servo.write(pos);
        break;
      case 3:
        pos = limitdx;
        servo.write(pos);
        break;
      } // end of sweep
    }
    void AfraidSx(){
      if (millis() >= previousMillis4){
        CountCiclo4++;
        previousMillis4 = previousMillis4+random(StartVelocityCiclo4,EndVelocityCiclo4); // each case gets 100ms
        servoSweep4 = random(1,4); //seleziona caso random tra 1 e 3
        /*if (servoSweep == 7){ //cicla tutti i casi
         servoSweep = 1;
         }*/
      }
      switch (servoSweep4){
      case 1:
        pos = limitsx+3;
        servo.write(pos);
        break;
      case 2:
        pos = limitsx+6;
        servo.write(pos);
        break;
      case 3:
        pos = limitsx;
        servo.write(pos);
        break;
      } // end of sweep
    }
    void LedLoop(){
    }
    void Scan(){
      if (millis() >= previousMillis3){
        if (endingAfraid == 1) { //se to uscendao da afraid resetto la pos per fluidità
          endingAfraid = 0;
          if (Direction == 0) {
            previousMillis3 = previousMillis2;
            pos3 = limitdx - 6 ;
          }
          else{
            previousMillis3 = previousMillis4;
            pos3 = limitsx + 6 ;
          }
        }
        CountCiclo3++;
        //debug// Serial.println(pos3);
        previousMillis3 = previousMillis3+VelocityCiclo3 ;
        if (Direction % 2) { //se dispari (da basso a alto) (da limit sx a limit dx)
          if(pos3 < limitdx) { 
            pos3++;
            servo.write(pos3); 
          } 
          else {
            Direction++;  // se ho raggiunto il limite aumenta di 1 direzione, invertendola
          }
        } 
        else //se pari
        if(pos3 > limitsx) { 
          pos3--;
          servo.write(pos3); 
        } 
        else {
          Direction++;  // se ho raggiunto il limite aumenta di 1 direzione, invertendola
        }
      }
    }
    void DetectNoise()
    {
      if (millis() >= previousMillis6){
        CountCiclo6++;
        //se dopo un po di tempo/VelocityCiclo6)...
        previousMillis6 = previousMillis6+VelocityCiclo6 ; 
        // ho accumulato troppi knokkeddx ed sx....
        
        if (PreviousKnockDetected <= KnockDetected){ // per capirlo sottracco quelli di ora - quelli previus ciclo (lento) se > x sono in noise...
        PreviousKnockDetected =  KnockDetected+NoiseTresh; // Azzer.... NoiseTresh = soglia che vado a aggiugnere...
          Serial.println();
          Serial.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!noise detected!!! chi parla?????????????????"); //triggero log
          Serial.println();
          
          Behaviour = 1; //e vado in modalità idonea...
          
          NoiseDetected = 1; //qs variabile impedisce ad altri knoc di cambiare behaviour x un po'....
          previousMillis7 = previousMillis6+VelocityCiclo7 ;   //setto dalay per rientro varaibile NoiseDetected
        }else{
        if (millis() >= previousMillis7){  //dopo xx ulteirori millisecondi..
        CountCiclo7++;  
        NoiseDetected = 0; //vado via dastato di noisedetected...
      }
      }
        PreviousKnockDetected =  KnockDetected+NoiseTresh;
        //debug//  Serial.print("trigger rilevati in unità di tempo= ");
        //debug//  Serial.println(PreviousKnockDetected-KnockDetected);  
      }
    }
    void VerboseLog()
    {
      if (millis() >= previousMillis1){
        CountCiclo1++;
        previousMillis1 = previousMillis1+VelocityCiclo1 ; // each case gets 100ms
        //fun Verboselog
        Serial.print("| CountCiclo1= ");
        Serial.print(CountCiclo1);
        Serial.print("| knockDX= ");
        Serial.print(millisAtKnockDx);
        Serial.print("PreviousKnocKDetected= ");
        Serial.print(PreviousKnockDetected);
        Serial.print("KnocKDetected= ");
        Serial.print(KnockDetected);
        
         Serial.print("NoiseDetectedStatus= ");
        Serial.print(NoiseDetected);
        
      
       
        Serial.println("end");
      }
    }

    Step 10: Calibrating

    As you code is uploaded you should see this thing working for the first time!

    I suggest not to attach the head before checking the servo center position.

    The servo Should be swiping form left to right.

    Calibrating the servo

    You must set (in Arduino code) your limits and center position by setting these variables:

    • int center = 115;
    • int limitsx = 85;
    • int limitdx = 145;

    NOW you can assemble the head...

    ...with the rest of the body, at the center servo position.

    Consider not to use glue for this. If you need to use glue, be extremely careful not to weld the servo and cause it to get stuck.

    Calibrating the Microphones.

    Microphones has one screw on ht little board on with there mounted. This is to set the threshold limit after the Sensor tell to the arduino that a sound is detected.

    You now have to find the exact threshold for each of the two.

    You can achieve this by reading the monitor on the serial log on the ARDUINO IDE. Anytime a sound is detected you'll read "Knock SX !!!!!!!!!!!" or "Knock DX !!!!!!!!!!!"

    If there is to much noise to trigger the pics, the "Detect noise" function will ignore the call and consider it a "noise".

    Find the correct balance.

    Step 11: Build the Base

    Speaking about base building, there is no right way to do it as long as:

    • you get the room for the batteries the electronics, the power switch
    • you provide A way to keep the At-st standing on its feet
    • you get the 2 microphones onto the base, one on the left, and one on the right.

    Here is my way:

    • Find what you want to do (studied the positions before)
    • 3d print the external mould (dimensions will fit Makerbot replicator 2) (file attached)
    • 3d print the Inner core (file attached)
    • Cover the inner core cavities. You don't want the plaster to go inside.
    • Fix the External Mould to a Wooden base.
    • Position the inner core and put a weight on it (otherwise il will float into plaster).
    • Prepare the plaster
    • Pour the plaster into the mould

    Let it dry ( for some days )

    Step 12: Complete the Work

    Build the final circuit

    You can see above the final Fritzing circuit. As said before it has 2 batteries to solve the interference problem.

    In the diagram you can see 6 leds that are supposed to light up the base. These are optional.

    Do all the soldering required. And Weld all the components to the Arduino Nano.

    I used this wonderful frontal Metal Led button. Check its instructions to wire it correctly.

    Set the Model to the base Using 2 screws form below the base and join the wires.

    Install the microphones

    My base design has forced me to get to the surface of the base only with the 2 mics, and not with the entire sound detection board. So i had to Stretch the Mics wiring.To do it i detached the mic form its board and re-soldered using the two 20 cm Cd-rom audio cabled (they are shielded).

    After that i put some rocks on it to conceal the two mics. And painted all in white (i know that it's an unpopular diorama design, but i like it this way)

    Power it up & Enjoy it!