Hi:
With the help of others on this and other forums and a friend who's much more adept at coding than I am I'm VERY close to nailing down the code and circuit I need to finalize the electronics for this PKE meter prop I've been working on since, literally, 1993.
My last hurdle is getting my touch switches to work correctly when the circuit is under battery power. My breadboarded prototype works fine when the circuit is powered through USB, but when I power it through my batteries the touch switches stop working when I have a speaker connected to the speaker connections of the prop shield (or I touch one of those contacts). I'm guessing this is a grounding issue of some sort, and I'm hoping that the addition of a diode or capacitor or something somewhere will solve this problem.
I have a Prop Shield LC soldered to a Teensy 3.2. In simplified terms, when activated (either through a touchRead function or mechanical switch) a series of 7 LEDs chase, a pair of servos are sent to a certain angle, and a sound effect plays from the flash memory on the Prop Shield, played through a speaker connected to the Prop Shield's speaker connections.
As a test I modified my breadboard and sketch to use mechanical switches, powered by five 1.2V 2/3A size rechargeable NiMH batteries. These batteries match those used in the original prop, and I like the weight they add to the prop. I'm using a LM340T-5 to step down the 6.2V of those batteries to something more optimal for a Teensy 3.2. Everything works fine under battery power when trigged by mechanical switches.
You can see the setup in action at this link (I can embed only two videos in a post):
https://www.youtube.com/watch?v=n_DcSHE55Uo
The following video shows the system using touch switches (connected to pins 0 and 1, along with ground) to activate the functions, which emulates the actual prop. In this setup the Teensy, Prop Shield and LEDs are driven by the USB power supply while the servos are powered by the NiMH batteries. Again, everything is working as it should. Note that there's an additional touchRead switch attached to pin 23. This allows me to change the way the LED speed is determined, either using preset values or controlled via a pot connected to pin 14.
This is the code we're using to run this setup:
This video shows the same setup using the same code as above but powered entirely by the batteries. As in the version using mechanical pushbuttons the batteries are regulated down to 5V before going into Vin on the Teensy, and all 6V go to the servos. As shown in the video nothing works as long as the speaker is hooked up to the Prop Shield (even if just one lead is connected). As soon as I disconnect both speaker leads the touch switches work, triggering the LED chaser and servos. Touching one of the wires I've soldered to the speaker connections also causes the system to stop working. Clipping a long wire to one of the speaker outputs makes it behave erratically.
As I wrote above, this looks like some sort of grounding issue, but I don't have the electronic chops to troubleshoot this more than I've shown here. I can post a schematic if that would be helpful.
Any thoughts or suggestions would be greatly appreciated.
Thanks.
Shawn Marshall
With the help of others on this and other forums and a friend who's much more adept at coding than I am I'm VERY close to nailing down the code and circuit I need to finalize the electronics for this PKE meter prop I've been working on since, literally, 1993.
My last hurdle is getting my touch switches to work correctly when the circuit is under battery power. My breadboarded prototype works fine when the circuit is powered through USB, but when I power it through my batteries the touch switches stop working when I have a speaker connected to the speaker connections of the prop shield (or I touch one of those contacts). I'm guessing this is a grounding issue of some sort, and I'm hoping that the addition of a diode or capacitor or something somewhere will solve this problem.
I have a Prop Shield LC soldered to a Teensy 3.2. In simplified terms, when activated (either through a touchRead function or mechanical switch) a series of 7 LEDs chase, a pair of servos are sent to a certain angle, and a sound effect plays from the flash memory on the Prop Shield, played through a speaker connected to the Prop Shield's speaker connections.
As a test I modified my breadboard and sketch to use mechanical switches, powered by five 1.2V 2/3A size rechargeable NiMH batteries. These batteries match those used in the original prop, and I like the weight they add to the prop. I'm using a LM340T-5 to step down the 6.2V of those batteries to something more optimal for a Teensy 3.2. Everything works fine under battery power when trigged by mechanical switches.
You can see the setup in action at this link (I can embed only two videos in a post):
https://www.youtube.com/watch?v=n_DcSHE55Uo
The following video shows the system using touch switches (connected to pins 0 and 1, along with ground) to activate the functions, which emulates the actual prop. In this setup the Teensy, Prop Shield and LEDs are driven by the USB power supply while the servos are powered by the NiMH batteries. Again, everything is working as it should. Note that there's an additional touchRead switch attached to pin 23. This allows me to change the way the LED speed is determined, either using preset values or controlled via a pot connected to pin 14.
This is the code we're using to run this setup:
Code:
#include <Servo.h>
#include <ChaseLEDs.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
// GUItool: begin automatically generated code
AudioPlaySerialflashRaw playFlashRaw1; //xy=149,388
AudioMixer4 mixer1; //xy=445,386
AudioOutputAnalog dac1; //xy=591,379
AudioConnection patchCord1(playFlashRaw1, 0, mixer1, 0);
AudioConnection patchCord2(mixer1, dac1);
// GUItool: end automatically generated code
#define NACELLE_RATE 14 // Analog input for reading the nacelle chase rate
#define NACELLE_CHASE_LEN 8 // Length of nacelle chase, 1..6
#define NACELLE_MIN_PERIOD 25 // Minimum time to advance the nacelle chase (milliseconds)
#define NACELLE_MAX_PERIOD 250 // Maximum time to advance the nacelle chase (milliseconds)
#define NACELLE_DIM_VALUE 0 // Value for dimming previous LED in chase, 0..255
// ensure LEDs do not chase by default
boolean chaseOn = false;
// Output pins to use for the nacelle chase
byte nacelleChasePins[8] = {15, 16, 17, 18, 19, 20, 21, 24}; // Pin 24 is not connected to leave blank spot in sequence
// Mode definitions and default
const int CLASSIC = 0;
const int SHAWN = 1;
int currentMode = SHAWN;
// Keep track of the current wing states, don't care about closed state
const int HALF = 0;
const int FULL = 1;
int wingState;
// NacelleChaseLEDs Class definiation based on the ChaseLEDs Class
class NacelleChaseLEDs : public ChaseLEDs
{
public:
NacelleChaseLEDs(const byte *pins, int num)
: ChaseLEDs(pins, num, 0) {}
protected:
void advance(byte prevPin, byte nextPin)
{
digitalWrite(previousPin(2), LOW);
analogWrite(prevPin, NACELLE_DIM_VALUE);
if (chaseOn)
{
digitalWrite(nextPin, HIGH);
}
if (currentMode == CLASSIC)
{
setAdvanceTime(map(analogRead(NACELLE_RATE), 0, 1023, NACELLE_MIN_PERIOD, NACELLE_MAX_PERIOD));
//digitalWrite(13, !digitalRead(13)); // toggle the LED <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}
else // Shawn Mode
{
if (wingState == HALF)
{
setAdvanceTime(250);
}
else
{
setAdvanceTime(25);
}
}
}
};
// Instantiating a NacelleChaseLEDs object named nacelleChase
NacelleChaseLEDs nacelleChase(nacelleChasePins, NACELLE_CHASE_LEN);
// Touch sensor pin definations
const int touchPinFull = 0; // pin for touch FULL
const int touchPinHalf = 1; // pin for touch HALF
const int touchPinMode = 23; // pin for touch MODE switching
// Set the default touch sensor states
int touchStateHalf = 0;
int touchStateFull = 0;
// Mode Touch button state definitions
const int TOUCHED = 1;
const int UNTOUCHED = 0;
int currentModeTouchState = UNTOUCHED;
int previousModeTouchState = UNTOUCHED;
int lastModeToggle = millis();
// create servo object to control a servo
Servo myservoL; // left wing servo
Servo myservoR; // right wing servo
void setup()
{
dac1.analogReference(EXTERNAL); // much louder!
delay(50); // time for DAC voltage stable
Serial.println ("===> DAC1 Enabled");
pinMode(5, OUTPUT);
Serial.println ("PIN 5 SET AS OUTPUT");
digitalWrite(5, HIGH); // turn on the amplifier
delay(10); // allow time to wake up
Serial.println ("PIN 5 SET HIGH");
// Audio connections require memory to work. For more
// detailed information, see the MemoryAndCpuUsage example
AudioMemory(8);
// Set initial volume
mixer1.gain(0, 0.5f);
// Start SerialFlash
if (!SerialFlash.begin(6))
{
while (1)
{
Serial.println ("Cannot access SPI Flash chip");
delay (1000);
}
}
myservoL.attach(9); // left wing servo pin def
myservoR.attach(10); // right wing servo pin def
pinMode(15, OUTPUT); //Wing LED
pinMode(16, OUTPUT); //Wing LED
pinMode(17, OUTPUT); //Wing LED
pinMode(18, OUTPUT); //Wing LED
pinMode(19, OUTPUT); //Wing LED
pinMode(20, OUTPUT); //Wing LED
pinMode(21, OUTPUT); //Wing LED
pinMode(2, OUTPUT); // Status Left LED FUll
pinMode(3, OUTPUT); // Status Right LED HALF
pinMode(touchPinFull, INPUT); //TouchFull
pinMode(touchPinHalf, INPUT); // Touch Half
pinMode(touchPinMode, INPUT); // Touch Mode
Serial.begin(38400); // initialize serial comms
Serial.println("SHAWN mode enabled");
}
void toggleMode()
{
if (currentMode == SHAWN)
{
currentMode = CLASSIC;
Serial.println("CLASSIC mode enabled");
}
else
{
currentMode = SHAWN;
Serial.println("SHAWN mode enabled");
}
}
void loop()
{
touchStateFull = touchRead(touchPinFull);
touchStateHalf = touchRead(touchPinHalf);
if (touchStateFull < 1500) // If no touch (returns below 1500) go to next if statement. If touched (returns over 1500) else (Full Wings) happens WINGS AT HOME, NO LIGHTS
{
if (touchStateHalf < 1500) // If no touch (returns below 1500) this block happens. If touched (returns over 1500) else (Half Wings) happens WINGS AT HOME, NO LIGHTS
{
//Serial.println("Nothing touched");
if (currentModeTouchState == UNTOUCHED) digitalWrite(2, LOW); //Status FULL LEFT LED OFF
digitalWrite(3, LOW); //Status HALF RIGHT LED OFF
digitalWrite(15, LOW); //Wing LED OFF
digitalWrite(16, LOW); //Wing LED OFF
digitalWrite(17, LOW); //Wing LED OFF
digitalWrite(18, LOW); //Wing LED OFF
digitalWrite(19, LOW); //Wing LED OFF
digitalWrite(20, LOW); //Wing LED OFF
digitalWrite(21, LOW); //Wing LED OFF
myservoL.write(20); // Servo home position
myservoR.write(140); // Servo home position
chaseOn = false;
if (playFlashRaw1.isPlaying()) playFlashRaw1.stop();
}
else
{
// TouchPinHalf 1 is touched WINGS HALF UP, LIGHTS
//Serial.println(analogRead(NACELLE_RATE));
digitalWrite(3, HIGH); // Status LED on
myservoL.write(80); // Servo half up
myservoR.write(80); // Servo half up
chaseOn = true;
wingState = HALF;
if (!playFlashRaw1.isPlaying()) playFlashRaw1.play("PKE_HALF.RAW");
}
}
else
{
// TouchPinFull 0 is touched WINGS FULL UP, LIGHTS
//Serial.println(analogRead(NACELLE_RATE));
digitalWrite(2, HIGH); // Status LED on
myservoL.write(140); // Servo Full Up
myservoR.write(20); // Servo Full Up
chaseOn = true;
wingState = FULL;
if (!playFlashRaw1.isPlaying()) playFlashRaw1.play("PKE_FULL.RAW");
}
int touchVal = touchRead(touchPinMode);
if (touchVal > 1500)
{ // Mode Touch Button is TOUCHED during this loop
currentModeTouchState = TOUCHED;
int timeSinceToggle = millis() - lastModeToggle;
// check that timeSinceToggle > 50 to avoid delicate touches from bounching back and forth between modes
if (currentModeTouchState != previousModeTouchState && timeSinceToggle > 50)
{
// state has changed from UNTOUCHED to TOUCHED and we need to take action
//Serial.println("Mode Button Touched");
digitalWrite(2, HIGH);
toggleMode();
lastModeToggle = millis();
}
previousModeTouchState = TOUCHED;
}
else
{
// Mode Touch Button is UNTOUCHED during this loop
currentModeTouchState = UNTOUCHED;
if (currentModeTouchState != previousModeTouchState)
{
// state has changed from TOUCHED to UNTOUCHED and we need to take action
digitalWrite(2, LOW);
lastModeToggle = millis();
}
previousModeTouchState = UNTOUCHED;
//Serial.println(touchVal);
}
nacelleChase.loop();
}
This video shows the same setup using the same code as above but powered entirely by the batteries. As in the version using mechanical pushbuttons the batteries are regulated down to 5V before going into Vin on the Teensy, and all 6V go to the servos. As shown in the video nothing works as long as the speaker is hooked up to the Prop Shield (even if just one lead is connected). As soon as I disconnect both speaker leads the touch switches work, triggering the LED chaser and servos. Touching one of the wires I've soldered to the speaker connections also causes the system to stop working. Clipping a long wire to one of the speaker outputs makes it behave erratically.
As I wrote above, this looks like some sort of grounding issue, but I don't have the electronic chops to troubleshoot this more than I've shown here. I can post a schematic if that would be helpful.
Any thoughts or suggestions would be greatly appreciated.
Thanks.
Shawn Marshall