I am trying to program a Teensy 3.2 to act as a lightsaber controller. My code works perfectly but I can't select a port. How should I fix this problem?
Here is my code:
/* Presented without warranty, guarantee and support.
By Bob Clagett - I Like To Make Stuff
This is the code to accompany the lightsaber project at http://www.iliketomakestuff.com/make-lightsaber/
Expected hardware is listed in post (Teensy 3.2, Prop Shield, DotStar LEDs)
This is functional v1 of this code. Lots more I want to add to it including crash detection/sounds.
This code is dirty, bulky, poorly documented and ugly but I finally got it all functional.
Cleanup to come later in v2.
*/
#include <SerialFlash.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
// GUItool: begin automatically generated code
// GUItool: end automatically generated code
#include <Adafruit_DotStar.h>
#include <NXPMotionSense.h>
NXPMotionSense imu;
NXPSensorFusion filter;
int motionThreshold = 2;
float lastPitch = 0, lastRoll = 0, lastHeading = 0;
int buttonState = HIGH;
int bladeState = 0; //0 off, 1, fading up, 2 on, 3 fading down
int fadeStep = 0;
int fadeStepSize = 6;
int selectedColor = 0;
int lastSelectedColor = 0;
bool isAnimating = 0;
bool bladeOn = 0;
long lastDebounceTime = 0; // the last time the output pin was toggled
long debounceDelay = 50;
int lastButtonState = HIGH;
int pendingPress = 0;
//BC = Blade Color
int BCbuttonState = HIGH;
long BClastDebounceTime = 0; // the last time the output pin was toggled
long BCdebounceDelay = 50;
int BClastButtonState = HIGH;
int BCpendingPress = 0;
int pendingColorPress = 0;
#define COLOR_BUTTON_PIN 1
#define POWER_BUTTON_PIN 0
#define COLOR_ORDER BGR
#define CHIPSET APA102
#define NUMPIXELS 252
#define BRIGHTNESS 100
#define FRAMES_PER_SECOND 70
#define PROP_AMP_ENABLE 5
#define FLASH_CHIP_SELECT 6
#define LED_BUFFER_SELECT 7
#define VOLUME_POT 15
#define LED_PIN 7
Adafruit_DotStar strip = Adafruit_DotStar(
NUMPIXELS, DOTSTAR_BRG);
int outputValue = 0;
int presetColors[] = {0x0000FF, 0x00FF00, 0xFF0000, 0xFFFFFF};
int totalPresetColors = (sizeof(presetColors) / sizeof(int));
int selectedColorIndex = 0;
int swingSounds = 4;
int lastSwingSound = swingSounds;
int clashSounds = 0;
void setup() {
delay(500); // sanity delay
imu.begin();
filter.begin(100);
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif
strip.begin(); // Initialize pins for output
strip.show(); // Turn all LEDs off ASAP
pinMode(POWER_BUTTON_PIN, INPUT);
pinMode(COLOR_BUTTON_PIN, INPUT);
pinMode(LED_PIN, OUTPUT);
digitalWrite(POWER_BUTTON_PIN, HIGH);
digitalWrite(COLOR_BUTTON_PIN, HIGH);
digitalWrite(LED_PIN, LOW);
Serial.begin(9600);
// wait up to 3 seconds for the Serial device to become available
long unsigned debug_start = millis ();
while (!Serial && ((millis () - debug_start) <= 3000))
;
Serial.println ("Start prop shield RAW player");
SPI.begin();
// Enable the amplifier on the prop shield
pinMode(PROP_AMP_ENABLE, OUTPUT);
digitalWrite(PROP_AMP_ENABLE, HIGH);
pinMode(LED_BUFFER_SELECT, OUTPUT);
digitalWrite(LED_BUFFER_SELECT, HIGH);
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
// Set initial volume
// Start SerialFlash
if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
while (1)
{
Serial.println ("Cannot access SPI Flash chip");
delay (3000);
}
}
}
void powerUpBlade() {
isAnimating = 1;
bladeState = 1;
Serial.println("Turn on blade");
bladeOn = 1;
}
void powerDownBlade() {
//animate DOWN
bladeState = 3;
fadeStep = NUMPIXELS;
isAnimating = 1;
Serial.println("Turn off blade");
bladeOn = 0;
}
void bladeIsOn() {
}
//nothing needed here unless adding animation
void bladeIsAnimatingUp() {
//Serial.println("bladeIsAnimatingUp");
int midpoint = NUMPIXELS / 2;
int newSection = fadeStep + fadeStepSize;
for ( int j = fadeStep; j < newSection; j++) {
strip.setPixelColor(j, selectedColor);
strip.setPixelColor(NUMPIXELS - j, selectedColor);
}
Serial.println(newSection);
fadeStep = newSection;
if (fadeStep >= midpoint + fadeStepSize) {
fadeStep = NUMPIXELS;
isAnimating = 0;
bladeState = 2;
// delay(200);
Serial.println("blade up complete");
}
}
void bladeIsAnimatingDown() {
//Serial.println("bladeIsAnimatingDown");
int midpoint = NUMPIXELS / 2;
int newSection = fadeStep - fadeStepSize;
for ( int j = fadeStep; j > newSection; j--) {
strip.setPixelColor(j - midpoint, 0x000000);
strip.setPixelColor(midpoint + NUMPIXELS - j, 0x000000);
}
//Serial.println(fadeStep);
fadeStep = newSection;
if (fadeStep <= midpoint - fadeStepSize) {
fadeStep = 0;
isAnimating = 0;
bladeState = 0;
}
}
void detectMotion() {
float ax, ay, az;
float gx, gy, gz;
float mx, my, mz;
float roll, pitch, heading;
if (imu.available()) {
// Read the motion sensors
imu.readMotionSensor(ax, ay, az, gx, gy, gz, mx, my, mz);
// Update the SensorFusion filter
filter.update(gx, gy, gz, ax, ay, az, mx, my, mz);
// print the heading, pitch and roll
roll = filter.getRoll();
pitch = filter.getPitch();
heading = filter.getYaw();
// does it need a time threshold too?
float headingDiff = abs(lastHeading - heading);
float pitchDiff = abs(lastPitch - pitch);
if (lastHeading != 0) {
if (pitchDiff > motionThreshold || headingDiff > motionThreshold) {
//cyle through swing sounds
lastSwingSound++;
if (lastSwingSound > swingSounds) {
lastSwingSound = 1;
}
String swingFile = "saberswingX.raw";
char charBuf[50];
swingFile.toCharArray(charBuf, 50);
triggerSwing(charBuf); // needs sequence to iterate through
}
}
lastHeading = heading;
lastPitch = pitch;
}
}
void loop() {
// Add entropy to random number generator; we use a lot of it.
// random16_add_entropy( random() );
//handle color selector button
int BCreading = digitalRead(COLOR_BUTTON_PIN);
if (BCreading != BClastButtonState) {
// reset the debouncing timer
BClastDebounceTime = millis();
}
if ((millis() - BClastDebounceTime) > BCdebounceDelay) {
if (BCreading != BCbuttonState) {
BCbuttonState = BCreading;
if (BCbuttonState == HIGH) {
nextColor();
}
}
}
BClastButtonState = BCreading;
selectedColor = presetColors[selectedColorIndex];
if (selectedColor != lastSelectedColor && bladeState != 0) {
Serial.print("COLOR CHANGE");
Serial.println(selectedColorIndex);
for ( int j = 0; j < NUMPIXELS; j++) {
strip.setPixelColor(j, selectedColor);
}
}
lastSelectedColor = selectedColor;
//handle blade on/off
int reading = digitalRead(POWER_BUTTON_PIN);
//debounce
if (reading != lastButtonState) {
// reset the debouncing timer
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
}
}
lastButtonState = reading;
if ( pendingPress == 1 && buttonState != LOW) {
buttonState = HIGH;
pendingPress = 0;
Serial.print("execute pending blade press");
if (bladeOn) {
powerDownBlade();
} else {
powerUpBlade();
}
}
if (buttonState == LOW && !isAnimating) {
Serial.println("BLADE BUTTON IS PRESSED");
pendingPress = 1;
}
switch (bladeState) {
case 0:
//blade is off
break;
case 1:
//blade is animating up
bladeIsAnimatingUp();
break;
case 2:
//blade is on
bladeIsOn();
break;
case 3:
//blade is animating down
bladeIsAnimatingDown();
break;
}
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
digitalWrite(LED_PIN, HIGH); // enable access to LEDs
strip.show(); // Refresh strip
digitalWrite(LED_PIN, LOW);
SPI.endTransaction(); // allow other libs to use SPI again
delay(10);
if (bladeState == 2) {
detectMotion();
}
}
void nextColor() {
selectedColorIndex++;
if (selectedColorIndex >= totalPresetColors) {
selectedColorIndex = 0;
}
}
void triggerSound(const char *filename) {
}
void triggerSwing(const char *filename) {
}
void startHum() {
//Serial.println("startHum");
}