GOW Lancer MOD with arduino and waveshield...

Lopan

New Member
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...
2011-11-13%25252017.09.46.jpg


2011-11-13%25252017.09.55.jpg


Little molds...
2011-11-13%25252022.09.53.jpg


The worst dremel job on the planet... hopefully I can fix it...
2011-11-13%25252017.10.16.jpg


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.
2011-11-21%25252020.14.48.jpg


I made molds of the rear parts of the gun where the lights are supposed to go (before the ugliest dremel job ever above ).
2011-11-23%25252020.34.35.jpg


Used rubber bands to attach the molds and filled with Alumilite clear urethane casting resin..
2011-11-23%25252022.04.10.jpg


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...
2011-11-24%25252010.42.38.jpg


Test run with the LED attached...
2011-11-24%25252013.09.33.jpg


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...

2011-11-26%25252014.43.09.jpg

2011-11-26%25252014.43.30.jpg

2011-11-26%25252014.44.11.jpg


Test fitting, of course wires will be inside when project is finished
2011-11-26%25252014.44.34.jpg



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:
So, very interested in this project as I've wanted to do the same to mine but lack the electronic skills.
 
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.
 
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:
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...

2011-11-29%25252000.52.26.jpg
 
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?
 
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.
 
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,
tip120.jpg


Thanks Raddar!
 
Last edited:
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:
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!
 
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

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.

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:
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!

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!
 
Updates...

Wiring, I have to clean this mess up...
2011-12-01%2B23.28.40.jpg


Got the charge port/kill switch wired up as well.
2011-12-01%2B23.29.05.jpg


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).
2011-12-01%2B23.29.33.jpg


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.
 
More updates...

Got the rear cover dremeled and speaker grate installed.
2011-12-04%2B09.50.29.jpg



Finished both sides.
2011-12-04%2B09.50.37.jpg

2011-12-04%2B09.51.04.jpg



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.
2011-12-04%2B09.51.48.jpg


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...
 
This thread is more than 12 years old.

Your message may be considered spam for the following reasons:

  1. This thread hasn't been active in some time. A new post in this thread might not contribute constructively to this discussion after so long.
If you wish to reply despite these issues, check the box below before replying.
Be aware that malicious compliance may result in more severe penalties.
Back
Top