GOW Lancer MOD with arduino and waveshield...

Discussion in 'Replica Props' started by Lopan, Nov 26, 2011.

  1. Lopan

    Lopan New Member

    Trophy Points:
    3
    I'm posting this because I kind of wanted to share this with someone... anyone :)...

    I'm not new to modding, I kind of wanted to share this with people who like myself might be looking for alternatives to blaster core (not that what I've done even compares to blaster core), but I honestly didn't want to wait however long for blaster core to be available, but also, I was hoping more people with programming skills might have their interest sparked as I am not a developer and there is a lot of potential with arduino/wave shield... or what I'm using which is a lightduino board from Azulmedia. So it's all open source... Not sure what the rules are about name dropping with products here... so I'll leave it at that as I definitely don't want to step on any toes.

    Anyway I'm still hacking away at this thing and will update with my progress, but all go ahead and start with my progress to date...

    So just getting the thing apart required much dremeling... all the little details that hide the screw holes on my lancer were glued in pretty good... so I made molds so I could recreate them...
    [​IMG]

    [​IMG]

    Little molds...
    [​IMG]

    The worst dremel job on the planet... hopefully I can fix it...
    [​IMG]

    Here is the lightduino board... I have it set with 4 buttons so far, one for fire, one for chainsaw, one clip detect and a selector that goes between triple fire and full auto. I also have a jumper going from one of the volume resistors into one of the analog pins that detects volume, I have an output pin to a amber luxeon rebel star so basically it's set for just the machine gun fire, when it reaches a certain volume the luxeon flashes simulating machine gun fire... the luxeon is connected to the arduino output pin and a tip 120 resistor... There's also six accent led's with a pretty cool looking throb effect, and a speaker stuck in a piece of sink tubing.... which I'll actually fix more permanently as this project moves along.
    [​IMG]

    I made molds of the rear parts of the gun where the lights are supposed to go (before the ugliest dremel job ever above ).
    [​IMG]

    Used rubber bands to attach the molds and filled with Alumilite clear urethane casting resin..
    [​IMG]

    It turned out pretty good, a few small air bubbles in the clear resin, but that's pretty much unavoidable unless I'd rigged up some kind of vacuum chamber and basically vacuum cast the whole thing...
    [​IMG]

    Test run with the LED attached...
    [​IMG]

    I'm using 3mm fiber optic, I basically use metal flashing tape to stick it to the clear plastic parts, I do this to basically not have any bright spots and have even smooth light accross the whole plastic piece.

    I'd originally tried to use the stock "button thingie" with some pretty terrible results.... So I made a mold, dremeled the whole thing out and started casting some replacement pieces and came up with a better plan for lighting...

    [​IMG]
    [​IMG]
    [​IMG]

    Test fitting, of course wires will be inside when project is finished
    [​IMG]


    Anyway... this is as far as I've gotten! I'll post updates as I make progress...

    I need to post my arduino code as well, I'll do that later...

    Anyway, what do you guys think?
     
    Last edited: Nov 28, 2011
    Garthok and hydin like this.
  2. Finnlock

    Finnlock Active Member

    Trophy Points:
    331
    Looking really good. love the idea.
     
  3. Gee2

    Gee2 Sr Member RPF PREMIUM MEMBER

    Trophy Points:
    1,041
    So, very interested in this project as I've wanted to do the same to mine but lack the electronic skills.
     
  4. Lopan

    Lopan New Member

    Trophy Points:
    3
    Well, I've been soldering stuff for a long time, but I have no electronic skills either, I'll hack together stuff if I have an EASY to read schematic... But I have to be honest, after this I'm hooked bigtime on Arduino, I'd never played with it before this, but there is so much information online, tutorials, sample code, etc... and you can do just about anything with it, and in most cases someone already has code available. The code for my project was hacked together from 3 or 4 different projects. Took a while to get it just right, but I've got it controlling a rebel star, machine gun fire, selector for triple and full auto, clip detect and chainsaw, and it's also controlling all the LED's... so needless to say, I'm now a huge fan of arduino.
     
  5. Lopan

    Lopan New Member

    Trophy Points:
    3
    I wanted to post the arduino code I'm using, this is a combination of code from adafruit.com, some code from http://www.cero-uno.com (where I got the lightduino board I'm using, Lino's been a huge help) and some basic code from some of the arduino tutorials that are floating around for the LED throb effect...

    Code:
    #include <FatReader.h>
    #include <SdReader.h>
    #include <avr/pgmspace.h>
    #include "WaveUtil.h"
    #include "WaveHC.h"
    
    
    SdReader card;    // This object holds the information for the card
    FatVolume vol;    // This holds the information for the partition on the card
    FatReader root;   // This holds the information for the filesystem on the card
    FatReader f;      // This holds the information for the file we're play
    
    WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time
    
    #define DEBOUNCE 5  // button debouncer
    int ledPin = 8;             // Two LED's connected to digital pin 8
    int ledPin1 = 6;           // Two LED's connected to pin 6
    int ledPin2 = 7;           // Two LED's connected to pin 7
    int cycleTime = 65;             // the total duration of a PWM cycle
    int changeSpeed = 1;            // throb speed, or the number of milliseconds to change the onTimePerCycle per Cycle
    boolean brightnessGoingUp = true;     // whether the brightness is going up or down
    int onTimePerCycle = 0;      // the number of milliseconds to turn the LED within a cycle
    int luxLed = 9;                 // Luxeon controlled with pin 9
    int redLed = A2;              // Power indicator on pin A2
    
    
    // here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
    byte buttons[] = {19, 18, 17, 14, 14, 19};
    // This handy macro lets us determine how big the array up above is, by checking the size
    #define NUMBUTTONS sizeof(buttons)
    // we will track if a button is just pressed, just released, or 'pressed' (the current state
    volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];
    
    // this handy function will return the number of bytes currently free in RAM, great for debugging!   
    int freeRam(void)
    {
      extern int  __bss_end; 
      extern int  *__brkval; 
      int free_memory; 
      if((int)__brkval == 0) {
        free_memory = ((int)&free_memory) - ((int)&__bss_end); 
      }
      else {
        free_memory = ((int)&free_memory) - ((int)__brkval); 
      }
      return free_memory; 
    } 
    
    void sdErrorCheck(void)
    {
      if (!card.errorCode()) return;
      putstring("\n\rSD I/O error: ");
      Serial.print(card.errorCode(), HEX);
      putstring(", ");
      Serial.println(card.errorData(), HEX);
      while(1);
     }
    
    
    
    void setup() {
      byte i;
      
      // set up serial port
      Serial.begin(9600);
      putstring_nl("WaveHC with ");
      Serial.print(NUMBUTTONS, DEC);
      putstring_nl("buttons");
      
      putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
      Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
      
      // Set the output pins for the DAC control. This pins are defined in the library
      pinMode(2, OUTPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(5, OUTPUT);
     
      // pin13 LED
      pinMode(6, OUTPUT);
      pinMode(7, OUTPUT);
      pinMode(8, OUTPUT);
      pinMode(9, OUTPUT);
      pinMode(A2, OUTPUT);
     
      // Make input & enable pull-up resistors on switch pins
      for (i=0; i< NUMBUTTONS; i++) {
      pinMode(buttons[i], INPUT);
      digitalWrite(buttons[i], HIGH);
      }
      
      //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
      if (!card.init()) {         //play with 8 MHz spi (default faster!)  
        putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
        sdErrorCheck();
        while(1);                            // then 'halt' - do nothing!
      }
      
      // enable optimize read - some cards may timeout. Disable if you're having problems
      card.partialBlockRead(true);
     
    // Now we will look for a FAT partition!
      uint8_t part;
      for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
        if (vol.init(card, part)) 
          break;                             // we found one, lets bail
      }
      if (part == 5) {                       // if we ended up not finding one  :(
        putstring_nl("No valid FAT partition!");
        sdErrorCheck();      // Something went wrong, lets print out why
        while(1);                            // then 'halt' - do nothing!
      }
     // Lets tell the user about what we found
      putstring("Using partition ");
      Serial.print(part, DEC);
      putstring(", type is FAT");
      Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
      
     // Try to open the root directory
      if (!root.openRoot(vol)) {
        putstring_nl("Can't open root dir!"); // Something went wrong,
        while(1);                             // then 'halt' - do nothing!
      }
      // Whew! We got past the tough parts.
      putstring_nl("Ready!");
      
      TCCR2A = 0;
      TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;
    
      //Timer2 Overflow Interrupt Enable
      TIMSK2 |= 1<<TOIE2;
    playfile("Powerup.WAV");
    
    }
    
    SIGNAL(TIMER2_OVF_vect) {
      check_switches();
    }
    
    void check_switches()
    {
      static byte previousstate[NUMBUTTONS];
      static byte currentstate[NUMBUTTONS];
      byte index;
      for (index = 0; index < NUMBUTTONS; index++) {
        currentstate[index] = digitalRead(buttons[index]);   // read the button
        /*    
        Serial.print(index, DEC);
        Serial.print(": cstate=");
        Serial.print(currentstate[index], DEC);
        Serial.print(", pstate=");
        Serial.print(previousstate[index], DEC);
        Serial.print(", press=");
        */
        if (currentstate[index] == previousstate[index]) {
          if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
              // just pressed
              justpressed[index] = 1;
               }
          else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
              // just released
              justreleased[index] = 1;
               }
          pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
        }
        //Serial.println(pressed[index], DEC);
        previousstate[index] = currentstate[index];   // keep a running tally of the buttons
      }
    }
    void loop() {
      digitalWrite(redLed, HIGH);
      digitalWrite(ledPin, HIGH);        // sets the LED on
      digitalWrite(ledPin1, HIGH); 
      digitalWrite(ledPin2, HIGH);
      delay(onTimePerCycle);             // wait for onTimePerCycle milliseconds
      digitalWrite(ledPin, LOW);         // sets the LED off
      digitalWrite(ledPin1, LOW);
      digitalWrite(ledPin2, LOW);
      delay(cycleTime - onTimePerCycle); // waitfor the rest of the complete cycle   
      // Now adjust the brightness up or down depending the the current state
      if (brightnessGoingUp) {  
        onTimePerCycle += changeSpeed;
      } 
      else {
        onTimePerCycle -= changeSpeed;
      }   
    // if we are at full brightness, where the LED is on for the complete cycle
      if (onTimePerCycle >= cycleTime) {
        brightnessGoingUp = false;       // switch mode to brightness going down
        onTimePerCycle = cycleTime;      // make sure brightness did not go over
      }
      // if we are at zero brightness, where the LED is not on at all in a cycle 
      if (onTimePerCycle <= 0) {        
        brightnessGoingUp = true;      // switch mode to brightness going up
        onTimePerCycle = 1;            // make sure the onTime didn't go bellow zero      
      }
      byte i;
      static byte playing = -1; 
    
       if (pressed[0]) {
        if (playing != 0) {
          playing = 0; 
          playcomplete("Lancerfa.WAV");
         }   
       }
      else if (pressed[1]) {
        if (playing != 1) {
          playing = 1;
          playcomplete("Lancertf.WAV");
        }   
       }
      else if (pressed[2]) {
        if (playing != 2) {
          playing = 2;
          playfile("Chainsaw.WAV");
          digitalWrite(luxLed, LOW);
         }   
       }
      else if (pressed[3]) {
        if (playing != 3) {
          playing = 3;
          playfile("Clip.WAV");
         }   
       }
      else if (pressed[4]) {
        if (playing != 4) {
          playing = 4;
          playfile("Auto.WAV");
        }   
       }
      else if (pressed[5]) {
        if (playing != 5) {
          playing = 5;
          playfile("Trifire.WAV");
        }   
       }
            
      if (! wave.isplaying) {
        playing = -1;
       }
      }
    
    // Plays a full file from beginning to end with no pause.
    void playcomplete(char *name) {
      uint8_t volume;
      int v2;
      playfile(name);
      while (wave.isplaying) {
       volume = 0; {
         v2 = analogRead(1) - 512;
         if (v2 < 0) 
            v2 *= -1;
         if (v2 > volume)
           volume = v2;
         delay(1);
       }
       if (volume > 250) {
         digitalWrite(ledPin, HIGH);
         digitalWrite(ledPin1, HIGH);
         digitalWrite(ledPin2, HIGH);
         digitalWrite(luxLed, HIGH);
         
         } else {
         digitalWrite(ledPin, LOW);
         digitalWrite(ledPin1, LOW);
         digitalWrite(ledPin2, LOW);
         digitalWrite(luxLed, LOW);
         }
       }
      }
    void playfile(char *name) {
      // see if the wave object is currently doing something
      if (wave.isplaying) {// already playing something, so stop it!
        wave.stop(); // stop it
      }
      // look in the root directory and open the file
      if (!f.open(root, name)) {
        putstring("Couldn't open file "); Serial.print(name); return;
      }
      // OK read the file and turn it into a wave object
      if (!wave.create(f)) {
        putstring_nl("Not a valid WAV"); return;
      }
      // ok time to play! start playback
      wave.play();
      }
    As stated earlier, I suck at programming, even basic stuff... so if you see anything that could be done better, or just plain bad... please feel free to chime in. I'm open to any and all pointers and feedback!
     
    Last edited: Nov 30, 2011
  6. Lopan

    Lopan New Member

    Trophy Points:
    3
    Finished one side, hooked all the LED's up and did a video, it's a little dark so I apologize...
    YouTube video
     
    Last edited: Nov 27, 2011
  7. Lopan

    Lopan New Member

    Trophy Points:
    3
    Made some progress tonight, got all the components moved inside, still have to figure out how to mount the buttons (specifically the clip detect)... got all the led's on one side permanently attached. I also modified the battery box to house the Lightduino and the usb connection for easy programming and easy access to the SD card...

    [​IMG]
     
  8. Lopan

    Lopan New Member

    Trophy Points:
    3
    I have a question to any and all electronics people... It's probably a really silly question but here goes...

    I have one output pin left on my Lightduino board and I want to control the motor that was in this thing as force feedback/rumble... with a TIP120 transistor, as with the luxeon, the gun was originally wired up to 3 1.5v C batteries. so 4.5v total...

    I'm currently wiring this thing up with 2 18650 batteries should be around 7.4 volts at full charge.. at that voltage I'm affraid I'll burn it up, and even if it's ok it's pretty violent...

    The question is, what would be the best way to ramp the current going to this thing down? Just a resistor? and if so what kind? Would it just be easier to get a different motor?
     
  9. Raddar

    Raddar New Member

    Trophy Points:
    2
    My jaw hit the floor with every updated picture. Excellent work.
     
  10. phez

    phez Sr Member

    Trophy Points:
    1,487
    You could put a resistor in there but I do not think you will need it, that transistor can switch up to 5Amps. (just tweak the motor speed in your Arduino code to where you want it and you should be good. You could post a schematic of what you intend to do to be sure.

    I would put a diode (any standard diode should do) between the emitter and the collector of the TIP120 transistor. (Diode stripe pointed towards the the collector of the TIP120 transistor). When the motor is slowing down (or turning in the opposite direction) it turns into a generator and the diode will prevent any damage to the transistor caused by the voltage reversal. You may already be doing this so disregard if you are.
     
  11. Lopan

    Lopan New Member

    Trophy Points:
    3
    Thanks Phez! That makes sense... I have no clue how to do that in code (only messed with the waveshield stuff and LED's so far, but I'm sure there is some example code to be found somewhere out there! I knew I needed a diode, this was the diagram I was going off of,
    [​IMG]

    Thanks Raddar!
     
    Last edited: Nov 30, 2011
  12. phez

    phez Sr Member

    Trophy Points:
    1,487
    Here is what you are looking for to control the motor.

    Arduino - SecretsOfArduinoPWM

    The pulse width modulated pins will allow you to set the voltage going to the base of the TIP120 to control the motor speed. It works slick.

    Just use

    analogWrite(pin, dutyCycle)

    Start at about analogWrite(pin#, 128)

    That should be about the middle speed and then tweak dutyCycle up or down between 0 -255 to taste :lol

    You might want to stick about a 220nF capacitor between the Arduino pin and the base of the TIP120 for decoupling (it will stop voltage spikes) but I have used it without the cap with no noticeable problems.

    By the way, beatiful work on the gun.
     
    Last edited: Nov 30, 2011
  13. Garthok

    Garthok Sr Member

    Trophy Points:
    1,046
    Wow it's looking really good. I have thought about doing this as well and molding the parts, but I never thought to cast them in place. You have some great ideas and the build is coming along nicely. Can't wait to see it finished!
     
  14. Robot Monster

    Robot Monster Sr Member

    Trophy Points:
    1,671
    I have just started using the boards myself and I am looking forward to what applications they can be used for with props.
     
  15. Lopan

    Lopan New Member

    Trophy Points:
    3
    So bear with me here, if I have the output pin for the motor on analog pin 1 A1 my code would look something like this?

    void playcomplete(char *name) {
    uint8_t volume;
    int v2;
    playfile(name);
    while (wave.isplaying) {
    volume = 0; {
    v2 = analogRead(7) - 512;
    if (v2 < 0)
    v2 *= -1;
    if (v2 > volume)
    volume = v2;
    delay(1);
    }
    if (volume > 250) {
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin1, HIGH);
    digitalWrite(ledPin2, HIGH);
    digitalWrite(luxLed, HIGH);
    analogWrite(A1, 128);

    } else {
    digitalWrite(ledPin, LOW);
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
    digitalWrite(luxLed, LOW);
    analogWrite(A1, 0);
    }
    }
    }

    It can't be that easy can it? :)


    WOW! It really is that easy, just tried it and it works perfect... thanks Phez!
     
    Last edited: Dec 1, 2011
  16. Lopan

    Lopan New Member

    Trophy Points:
    3
    Yeah... about that :) it's not for the faint of heart, if your molds aren't up to snuff or you get pressure in the wrong angle with your rubber bands, plastic tends to go where you don't want it... neither one of the sides turned out 100%... but luckily it's not too noticeable. Not to mention if you cast it this way there's no way (for me at least) to pressure cast... Clear plastics are a pain to cast without getting bubbles.

    But thanks!
     
  17. Lopan

    Lopan New Member

    Trophy Points:
    3
    Updates...

    Wiring, I have to clean this mess up...
    [​IMG]

    Got the charge port/kill switch wired up as well.
    [​IMG]

    I don't have the plug end installed on the knob yet, but once I do it'll act as a kill switch (just like like with some of the sabers out there).
    [​IMG]

    Sorry about the picture quality, I have to get better lighting in my work area.

    I was going to try and wire up the rest of the switches tonight, however I was surfing sparkfun and opted to buy a reed switch for the clip detect. That should be cool as I wont have to poke any more holes, I can just glue a magnet in the clip somewhere and use the reed switch to set off the sound.
     
  18. Zegen

    Zegen New Member

    Trophy Points:
    2
    Awesome build!
     
  19. Hazz

    Hazz New Member

    Trophy Points:
    17
    Looking awesome man!
     
  20. Lopan

    Lopan New Member

    Trophy Points:
    3
    More updates...

    Got the rear cover dremeled and speaker grate installed.
    [​IMG]


    Finished both sides.
    [​IMG]
    [​IMG]


    Also, I didn't really just want a black plastic switch hanging out for the fire select, so I took a cast of one of the gun screws and attached it to the switch. Also got the chainsaw button installed.
    [​IMG]

    As you can see in the pictures both sides go back together perfectly, had to do a little creative arranging on the inside.

    So now just waiting for the reed switch from sparkfun, and still have to get all the screw covers and pegs cast...
     
  21. Lopan

    Lopan New Member

    Trophy Points:
    3
    So I originally had one regular red LED hooked up, I'd planned on using it for power indicator or something. But I realized I hadn't done anything with the site...

    I originally just drilled a hole and stuck the red LED up in there, but the direction of the light wasn't spectacular, and I needed something that would illuminate cast acrylic (reason and explanation as to why I needed cast acrylic is below)... I went to see if I could mod it with two LED's, but alas I was all out of red's, except for a batch of super tiny surface mount LED's (when I say tiny I mean seriously tiny, 1mm x .5mm) rediculously small, I'd got them by accident instead of regular LED's (wasn't paying attention when ordering). I've soldered surface mount before but never this small, but I figured they'd be easy to tuck away, I was right.
    [​IMG]
    I wanted to do something kind of special with it, my buddy has a laser engraver so I knew I wanted to use cast acrylic (it catches light a lot better than regular acrylic when being lit). So we had a little creative planning session, I knew I wanted to do something like a gears logo reticle, so I bought a gear generating application (I'd wanted to get it anyway to make stuff with my soon to be built CNC mill).. Anyway I showed him the GOW gear logo I'd created and he went crazy in corel draw churning out reticle's.

    So which one looks best?

    This one?
    [​IMG]

    Or this one?
    [​IMG]

    And finally all finished and screwed together (just need to add the detail/screw covers)...
    [​IMG]
     
    Last edited: Dec 6, 2011
  22. Finnlock

    Finnlock Active Member

    Trophy Points:
    331
    Looking great!
    I think I like the 1st one better personally.
     
  23. Wes R

    Wes R Legendary Member

    Trophy Points:
    6,750
    I like the first one better too.
     
  24. Lopan

    Lopan New Member

    Trophy Points:
    3
    I appreciate the feedback... number 1 it is! (I was leaning that way myself)
     
  25. Lopan

    Lopan New Member

    Trophy Points:
    3
    GOW Lancer MOD with arduino and waveshield... Updated with lighted base

    Just wanted to share the laser cut stand I made for my Lancer, I had my friend cut all the parts.

    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]

    The LED's actually are a lot more redish in color... not pink like in the pictures, need to get a better camera.

    I used cast acrylic, particle board and had the artwork printed at an online printshop (too big for the inkjet and I was concerned the inkjet paper would stick to the acrylic).
     
  26. Finnlock

    Finnlock Active Member

    Trophy Points:
    331
    Very nice, the base really makes it come across as a pro job. You should be very happy.
    Now your next task is to make it into a full functioning airsoft gun too!
     
  27. Lopan

    Lopan New Member

    Trophy Points:
    3
    Thanks! Actually I think my next project is going to be a dead space pulse rifle... never actually built anything from scratch (modified a bunch of stuff, but I've been inspired by a lot of stuff I've seen here).
     

Share This Page