/* Enterprise Blinkies
Flashes and fades multiple LEDs in sequence, connected to PWM pins, to emulate the strobe lights on the JJ Abrams Reboot starship enterprise.
Also controls motors for bussard collectors. Display modes cycled with capacitive touch sensor.
created 2015
by Hugh Beauchamp
This code is in the public domain
*/
// include library for capacative sensing (available from http://playground.arduino.cc/Main/CapacitiveSensor)
#include <CapacitiveSensor.h>
// configure capacitive sensor (single wire soldered to brass name plate)
CapacitiveSensor cs_16_19 = CapacitiveSensor(16,19); // 1 megaohm resistor between pins 16 & 19, pin 19 is sensor pin, connect wire and nameplate
// set LED pins
const int doubleblink = 10; //double blinking strobes on pin 10
const int pulse = 2; //pulsing light on pin 2
const int nav = 9; //navigation lights on pin 9
const int demark = 4; //demarkation lights on pin 4
const int saucerflood = 6; //saucer floodlights on pin 6
const int impulse = 7; //impulse engines on pin 7
const int interior = 11; //interior lights on pin 11
const int flood = 8; //flood lights on pin 8
const int engine = 3; //main engines on pin 3
const int dish = 5; //deflector dish on pin 5
// set motor control pins (for L293D motor driver ic)
const int bussardenable = 13; //motor enable on pin 13
const int bussardpin1 = 20; //control 1 on pin 20
const int bussardpin2 = 21; //control 2 on pin 21
// set variables
int blinkstate = LOW;
long previousMillis = 0; // stores last time LED updated
long blinkDuration = 30; // blinking strobe on time
long blinkInterval = 120; // blinking strobe time between short blinks
long blinkWait = 3000; // blinking strobe time between cycles
long pulseWait = 1500; // pulsing strobe time between cycles
long pulseSpeed = 3; // pulsing strobe delay for each fade level. Shorter times mean a faster fade
long pulseOn = 0; // pulsing strobe time to hold at maximum brightness
int blinkno = 0; // blink counter stores the number of elapsed flashes
int brightness = 0; // how bright the pulse LED is
int maxbrightness = 255; // what the maximum brightness of the pulsing strobe is
int fadeAmount = 5; // how many points to fade the LED by
// set lighting circuit brightnesses
int navbrightness = 4;
int demarkbrightness = 127;
int saucerfloodbrightness = 10;
int interiorbrightness = 255;
int floodbrightness = 255;
int enginebrightness = 255;
int dishbrightness = 255;
// set impulse engine pulse maximum and minimum brightnesses and sine wave speed
int maximpulsebrightness = 255;
int minimpulsebrightness = 63;
float impulsespeed = 0.00025;
// set motor speed
int bussardspeed = 255;
// set the display mode
int modecycle = 0;
long captime = 0;
long lastcaptime = 0;
void setup() {
// configure pin modes
pinMode (doubleblink, OUTPUT);
pinMode (pulse, OUTPUT);
pinMode (nav, OUTPUT);
pinMode (demark, OUTPUT);
pinMode (saucerflood, OUTPUT);
pinMode (impulse, OUTPUT);
pinMode (interior, OUTPUT);
pinMode (flood, OUTPUT);
pinMode (engine, OUTPUT);
pinMode (dish, OUTPUT);
pinMode (bussardenable, OUTPUT);
pinMode (bussardpin1, OUTPUT);
pinMode (bussardpin2, OUTPUT);
// configure capacitive sensor instance
cs_16_19.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate
Serial.begin(9600); // serial comms for debugging capacitive sensor
}
void loop() {
captime = cs_16_19.capacitiveSensor(30); // measure time for capacitive sensor pin to go high
if (captime > 500 && lastcaptime < 500) { // look for state change with capacitive sensor and increment display mode
modecycle++;
}
if (modecycle > 2) { // if display mode goes above 2, reset to 0
modecycle = 0;
}
lastcaptime = captime;
// Serial.println(modecycle); // serial comms for debugging capacitive sensor
// Serial.println(captime);
if (modecycle == 1 || modecycle == 2 ){ //lights on in mode 1 or 2
static float in = 4.712;
float out;
// set current time to time since sketch began running
unsigned long currentMillis = millis();
// check if time elapsed is greater than strobe time between cycles
if(currentMillis - previousMillis > blinkWait && blinkno == 0) {
previousMillis = currentMillis; // save the time the LED switched
blinkstate = HIGH; // set LED state
digitalWrite(doubleblink, blinkstate); // set the LED
blinkno = blinkno + 1; // increment blink counter
}
// check if time elapsed is greater than strobe on time
if(currentMillis - previousMillis > blinkDuration && blinkno == 1) {
previousMillis = currentMillis;
blinkstate = LOW;
digitalWrite(doubleblink, blinkstate);
blinkno = blinkno + 1;
}
// check if time elapsed is greater than strobe interval
if(currentMillis - previousMillis > blinkInterval && blinkno == 2) {
previousMillis = currentMillis;
blinkstate = HIGH;
digitalWrite(doubleblink, blinkstate);
blinkno = blinkno + 1;
}
// check if time elapsed is greater than strobe on time - might be able to reuse statement above
if(currentMillis - previousMillis > blinkDuration && blinkno == 3) {
previousMillis = currentMillis;
blinkstate = LOW;
digitalWrite(doubleblink, blinkstate);
blinkno = blinkno + 1;
}
// check if time elapsed is greater than pulse interval
if(currentMillis - previousMillis > pulseWait && blinkno == 4) {
// fade up pulse LED
for(brightness = 0; brightness <=maxbrightness; brightness+=fadeAmount) {
analogWrite(pulse, brightness); // set pulse LED brightness
delay (pulseSpeed); // wait to see fade effect
}
delay (pulseOn); // wait while LED is at maximum brightness
// fade down pulse LED
for(brightness = maxbrightness; brightness >=0; brightness-=fadeAmount) {
analogWrite(pulse, brightness);
delay (pulseSpeed);
}
blinkno = 0; // reset blink counter to zero
}
// write static light brightnesses
analogWrite(nav, navbrightness);
analogWrite(demark, demarkbrightness);
analogWrite(saucerflood, saucerfloodbrightness);
analogWrite(interior, interiorbrightness);
analogWrite(flood, floodbrightness);
analogWrite(engine, enginebrightness);
analogWrite(dish, dishbrightness);
// sine wave pulsing for impulse engine light
in = in + impulsespeed;
if (in > 10.995)
in = 4.712;
out = sin(in) * ((maximpulsebrightness-minimpulsebrightness)/2) + ((maximpulsebrightness+minimpulsebrightness)/2);
analogWrite(impulse,out);
}
else { // turn all lights off if mode does not equal 1 or 2
analogWrite(nav, 0);
analogWrite(demark, 0);
analogWrite(saucerflood, 0);
analogWrite(interior, 0);
analogWrite(flood, 0);
analogWrite(engine, 0);
analogWrite(dish, 0);
analogWrite(doubleblink, 0);
analogWrite(pulse, 0);
analogWrite(impulse, 0);
}
if (modecycle == 2) { // turn on engine motors in mode 2
analogWrite (bussardenable, bussardspeed);
digitalWrite (bussardpin1, 1); // reverse the 1 and 0 on the bussard pins 1 & 2 to reverse the motor direction
digitalWrite (bussardpin2, 0);
}
else { // turn off the engine motors in modes 0 and 1
analogWrite (bussardenable, 0);
digitalWrite (bussardpin1, 0);
digitalWrite (bussardpin2, 0);
}
} // end of loop