Three quick questions from a beginner-ish

Status
Not open for further replies.

WShawn

Well-known member
I'm building an LED bar graph type thing for the Proton Pack I built in 1984.

http://marshall-arts.net/ProtonPacks/finished.html

A stack of 15 LEDs grows from the bottom to top, resets, grows etc.

Three questions:

1. I was planning to repurpose code from a Ghostbusters forum that was written for a Arduino Mega Board. Will transposing the relevant pin numbers to a Teensy 3.1 be sufficient to make this work, or are there some libraries or other code that's unique to the Mega that won't work with a Teensy? (Code below-the Power Cell code is my focus for now)

2. I plan to run the system off of 4 AA batteries. I was going to use a 3.3V voltage regulator to drop that 6V down to power the Teensy via its 3.3V input (and one of the GNDs). Is that kosher?

3. I'll be connecting the Digital Write pins of the Teensy to 2N2222 NPN transistors to drive my LEDs. I've calculated the limiting resistor for the LEDs (based on their spec voltage and current draw), but do I need to insert resistors between the digital write pins of the Teensy and the base of the NPN transistors?

I hope to cobble this together by Saturday for the Rose City Comic Con.

Thanks.

Shawn



Code:
///////////////////////////////////////////////////////////////////
// Propcicle's Arduino Code for Proton Pack and Wand Lights
// Feel free to use in your pack along with an Arduino Mega Board
// Developed March 2015
///////////////////////////////////////////////////////////////////

int arrayIndex = 0; //Index variable for powercell lights
int arrayEnd = 15; //Index limiter for powercell lights
int cyclo = 1; //Index variable for cyclotron lights
int powon = 25; //LED On delay for power up sequence, recommend setting to 25
int state = 0; //state = 0 for pack off,state = 1 for startup seq,state = 2 for normal powercell cycle

// the follow variables is a long because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
unsigned long previousMillis = 0; // will store last time LED was updated
unsigned long duration = 40; // interval at which to blink (milliseconds)

void setup() {
// 
pinMode(22, OUTPUT); // Power Cell LED 1 and Wand Bar LED 1
pinMode(23, OUTPUT); // Power Cell LED 2 and Wand Bar LED 2
pinMode(24, OUTPUT); // Power Cell LED 3 and Wand Bar LED 3
pinMode(25, OUTPUT); // Power Cell LED 4 and Wand Bar LED 4
pinMode(26, OUTPUT); // Power Cell LED 5 and Wand Bar LED 5
pinMode(27, OUTPUT); // Power Cell LED 6 and Wand Bar LED 6
pinMode(28, OUTPUT); // Power Cell LED 7 and Wand Bar LED 7
pinMode(29, OUTPUT); // Power Cell LED 8 and Wand Bar LED 8
pinMode(30, OUTPUT); // Power Cell LED 9 and Wand Bar LED 9
pinMode(31, OUTPUT); // Power Cell LED 10 and Wand Bar LED 10
pinMode(32, OUTPUT); // Power Cell LED 11 and Wand Bar LED 11
pinMode(33, OUTPUT); // Power Cell LED 12 and Wand Bar LED 12
pinMode(34, OUTPUT); // Power Cell LED 13
pinMode(35, OUTPUT); // Power Cell LED 14
pinMode(51, OUTPUT); // Cyclo Light LED 1
pinMode(52, OUTPUT); // Cyclo Light LED 2
pinMode(53, OUTPUT); // Cyclo Light LED 3
pinMode(50, OUTPUT); // Cyclo Light LED 4
pinMode(7, OUTPUT); // Vent Light Output
pinMode(11, OUTPUT); // Proton Stream Output
pinMode(8, INPUT); // Pack Power On - "Activate" Switch
pinMode(9, INPUT); // Vent Light On - Bottom Bar Graph Light
pinMode(10, INPUT); // Fire the stream - "Intensify" button
pinMode(40, OUTPUT); // Any wand light that should be constatnt on after startup
}

void loop()
{
// here is where you'd put code that needs to be running all the time.

// check to see if it's time to blink the LED; that is, if the
// difference between the current time and last time you blinked
// the LED is bigger than the interval at which you want to
// blink the LED.
unsigned long currentMillis;
unsigned long elapsedMillis;

//int ledon = 25; //On delay for individual light for normal powercell
//int ledoff = 250; //Off delay for bar of lights

//Code for pack on sequence
if (state == 0 && digitalRead(8) == LOW) //Initial Starting point
{
//Do nothing - all lights off
digitalWrite(22, LOW);
digitalWrite(23, LOW);
digitalWrite(24, LOW);
digitalWrite(25, LOW);
digitalWrite(26, LOW);
digitalWrite(27, LOW);
digitalWrite(28, LOW);
digitalWrite(29, LOW);
digitalWrite(30, LOW);
digitalWrite(31, LOW);
digitalWrite(32, LOW);
digitalWrite(33, LOW);
digitalWrite(34, LOW);
digitalWrite(35, LOW);
digitalWrite(51, LOW);
digitalWrite(52, LOW);
digitalWrite(53, LOW);
digitalWrite(50, LOW);
digitalWrite(40, LOW);
digitalWrite(7, LOW);
state = 0;
}

else if (digitalRead(8) == LOW) //Turn all Lights off
{
digitalWrite(22, LOW);
digitalWrite(23, LOW);
digitalWrite(24, LOW);
digitalWrite(25, LOW);
digitalWrite(26, LOW);
digitalWrite(27, LOW);
digitalWrite(28, LOW);
digitalWrite(29, LOW);
digitalWrite(30, LOW);
digitalWrite(31, LOW);
digitalWrite(32, LOW);
digitalWrite(33, LOW);
digitalWrite(34, LOW);
digitalWrite(35, LOW);
digitalWrite(51, LOW);
digitalWrite(52, LOW);
digitalWrite(53, LOW);
digitalWrite(50, LOW);
digitalWrite(40, LOW);
digitalWrite(7, LOW);
state = 0;
}

else if (state == 0 && digitalRead(8) == HIGH) //Startup Sequence
{
for (int y = 0; y < 14; y = y + 1) {

int x = 1; //Light Loop incrementor
for (int powled = 35; powled > 21 + y; powled = powled - x) {
digitalWrite(powled, HIGH);
delay(powon);
digitalWrite(powled, LOW);
}
digitalWrite(22 + y, HIGH);

}
state = 1;
}
else if (state == 1)
{
//Code for turning on the next cyclo light
digitalWrite(40, HIGH);
switch (cyclo)
{
case 1:
digitalWrite(51, HIGH);
break;
case 2:
digitalWrite(52, HIGH);
break;
case 3:
digitalWrite(53, HIGH);
break;
case 4:
digitalWrite(50, HIGH);
break;
default:
cyclo = 0;
}
//Main Code for incrementing Powercell lights
currentMillis = millis(); // capture current "time"
// all time related variable are unsigned long
elapsedMillis = currentMillis - previousMillis; // see how much time has passed
if (elapsedMillis >= duration) { // time for next occurrence of event?
previousMillis = previousMillis + duration; // set up time for next occurrence of event
arrayIndex = arrayIndex + 1; // increment pointer
if (arrayIndex == arrayEnd) {
arrayIndex = 0; // reset to beginning
digitalWrite(22, LOW);
digitalWrite(23, LOW);
digitalWrite(24, LOW);
digitalWrite(25, LOW);
digitalWrite(26, LOW);
digitalWrite(27, LOW);
digitalWrite(28, LOW);
digitalWrite(29, LOW);
digitalWrite(30, LOW);
digitalWrite(31, LOW);
digitalWrite(32, LOW);
digitalWrite(33, LOW);
digitalWrite(34, LOW);
digitalWrite(35, LOW);
//delay(40); //Optional delay before starting lights again 

switch (cyclo)
{
//Code for turning off the previous cyclo light
case 1:
digitalWrite(51, LOW);
break;
case 2:
digitalWrite(52, LOW);
break;
case 3:
digitalWrite(53, LOW);
break;
case 4:
digitalWrite(50, LOW);
cyclo = 0;
break;
}

cyclo = cyclo + 1;
}

// do action based on value stored at arrayIndex
// This cycles the powercell lights
digitalWrite(21 + arrayIndex, HIGH);

} // end time check

if (state == 1 && digitalRead(9) == HIGH) //Vent Light Activation Loop
{
digitalWrite(7, HIGH);
}
else
{
digitalWrite(7, LOW);
}
if (state == 1 && digitalRead(9) && digitalRead(10) == HIGH) //Proton Stream Activation Loop
{
digitalWrite(11, HIGH);
delay(30);
digitalWrite(11, LOW);
delay(30);
}
else
{
digitalWrite(11, LOW);
}

} // end loop

}
 
"do I need to insert resistors between the digital write pins of the Teensy and the base of the NPN transistors?"

Yes, take 3.3v and subtract about 0.7v for the base-emitter voltage. That leaves 2.6 volts to be dropped by the resistor.
If you want to drive the base with 5 milliamps you would need (2.7v/0.005 mA)= 540 ohms. 560 is a standard value close to that. If you want less base current increase the resistor, if you want more decrease it. Personally I would not go much more than 10ma. If 2 mA is all you need for the base drive a 1.0 or 1.2 k would work well. It the LEDs don't turn off all the way try adding a 10k from base to emitter.

Everyone correct me if I'm wrong here, I'm new to teensy but not to general electronics.
 
Thanks for the quick reply regarding the resistors between the Teensy outputs and the transistors.

To elaborate on my setup, I was planning to use the full 6V to drive the transistors/LED side of the circuit. Am I correct in assuming that that voltage would call for a resistor of around 1K using your formula above?

I dabble in electronics, so I'm not 100% clear on what the resistor between the Teensy output and the base of the transistor does. My Forrest Mims III book isn't being clear at the moment.

FYI, the LEDs I'm using have these specs:

Forward Voltage (I=20mA): 3.2-3.4V
Forward Current: 15-20mA

With a 6V supply I was going to use a resistor around 135 ohms with each LED.

Best,

Shawn
 
Your logic for the LED current limiting resistors is right, though do note that half your battery power will be going up as heat not light. There are various tricks to feed an LED it's target current/voltage mix but they are possibly overkill for this. The resistor for the base is controlling the current b-e. For starters you don't want to have the Teensy driving more than 5mA per pin so you want to limit that, second the actual transistor silicon has current limits that you shouldn't exceed. Finally if doing this properly you would be working with the transistor Q (gain) value and carefully targeting the b/e current to produce your required c/e current. In this application though just winding it as hard 'on' as you can works within the current limits of the two devices is fine since switching speed and c/e limits will not be constraining the design.

To find out more than you want to know on the topic google 'transistor bias'.
 
2N2222 has at least 35 current gain, so for 20 mA in the collector (for the LED), you should need 0.57 mA or more in the base. So any resistor less than 4.56K ought to work. I'd go with 2.2K between each digital pin and transistor base, just to be sure.

That code for Mega looks like it should work, but you will need to make one minor change. It has a variable named "elapsedMillis", which happens to be the name of a special feature on Teensy. Normally that's a very convenient feature, but in this case is happens to conflict with the name of this variable. Just change every "elapsedMillis" to anything else, like "elapsedMsec".
 
Thanks for the replies everyone, I really appreciate it. I think I'm understanding enough of all this to make the thing do I want.

Best.

Shawn
 
A quick followup. I got everything working for the most part, but by the end of the Con I noticed that the lights were not working properly, and then not working at all. I think my 4 AA batteries drained faster than I anticipated (they weren't 100% fresh to start).

I tested the circuit on my circa 1988 Radio Shack Micronta multimeter, and it looks like the Teensy 3.1 is drawing around 40 mA when the lights aren't active. Is this what I should expect? The circuit draws 120-140 mA when all the LEDs are running. I'm using a 3.3V voltage regular to power the Teesny with the full 6V going to the LEDs.

It wouldn't be a big deal to add another switch to cut off power to the entire circuit, but I'd like to know whether there's anything else I should be doing to decrease the power draw when I don't have the lights running.

Once again, thanks for all the help last week. Using the direction above I was able to quickly rework the sketch on Thursday night, and my test breadboard of the circuit worked on the first try! Amazing.

Starting around 11am Friday I worked to disassemble my Proton Pack, remove the old lights (photo attached), adapt the old housing for 15 new LEDs, solder up the circuit (photo attached), test it and button everything down. I probably haven't followed the best electronic practices, but I had to get it working as quickly as possible. I had a few issues sprout up with my plan to share batteries between these lights and another set (I went with separate battery packs for each), and it was harder than I anticipated to put the pack back together. I finished up around 3am the day of the Con. I was wiped out that Saturday, but I'm very happy with the end result; it looks a whole lot better than the lights I built around 1988.

This clip shows the old vs. new lights:

https://youtu.be/KTKXLMRs_cM

Best.

Shawn
 

Attachments

  • OLD Lights.jpg
    OLD Lights.jpg
    185.6 KB · Views: 98
  • Upgrade Lights.jpg
    Upgrade Lights.jpg
    143.3 KB · Views: 115
If I remember correctly, the default setting for the Teensy 3.2 was 96MHz (overclocked). For your task you don't need that much processing power; might wanna lower the SoC clocking to something less (Tools -> CPU Speed ...).
 
Thanks for the quick reply. I'll try lowering it to 24 MHz, which is apparently as low as the 3.1/3.2 can go.

Best.

Shawn
 
The path to maximum battery life is through the snooze library and 'sleeping' between actions. How worthwhile that is varies of course but the 'wake when interupted by button' mode should be getting you close enough to zero current draw for something like this.

The high static current draw is because Teensy keeps all the perihperals running by default which can be disabled with care and a bit of planing for battery powered situations.
 
Thanks, I'll take a look at these Snooze libraries and see if I can figure it out. I'm very much a newbie at this, but it looks like there are some example sketches.

Take care.

Shawn
 
Status
Not open for further replies.
Back
Top