Multi-mode pen light: ATTiny85 with RGB LED

0926171326

This is a bread board prototype of a multi-mode pen light. It shines white, red, green, and blue light. Intensity is adjustable. Strobe, emergency flasher, ‘psychedelic,’ and candle simulation functions. It’s powered by a USB phone battery charger pack and uses an ATTiny85 as the microcontroller.

Here it is in action:

Here’s the schematic:

RLM 85

UPDATE:  And here’s a sketch of what the completed flashlight might look like:

rlm 85 pen light

 

Advertisements
Posted in Uncategorized | Tagged , , , , | 1 Comment

Beyond the Blink: RGB LED multiple lighting effects with arduino, push button, and potentiometer

Ever want to do more with an LED than just blink? This circuit and source code demonstrates some creative possibilities for lighting effects with an RGB LED.

CC has descriptive subtitles. Sorry for the poor phone video quality.

Here’s a circuit diagram (for common anode LED):

Here’s the source code:

/*
Blink_Shift
version 9.1 / September 2017

Written by Joe Schembrie aka Engineer Zero.
In the public domain.
No attribution necessary.
Alter as you see fit.

Controls an RGB LED in multiple modes. A push button changes
the mode and a potentiometer is used to adjust intensity,
rate, and color.

***IMPORTANT ByTheWay:

I used a common anode RGB, for which
analogWrite() goes HIGH for 0 and LOW for 255. You'll have
to revise your code accordingly if you use a common cathode RGB.

Lighting Mode Descriptions:

0 OFF
1 Candle
2 Red
3 Blue
4 Green
5 Tricolor
6 Strobe
7 Pure White
8 Broken Light
9 Yellow flashing (caution)
10 Psychedelic
11 Pulse

See my blog, http://engineerzero.blog for more fun stuff.

*/

// here are the pin number assignments

int blue = 11;
int green = 10;
int red = 9;
int potpin = 3; // the pin the potentiometer is on
int button = 7; // the pin the button is on.

// various variables

int potval = 0; // adjusts for magnitude and rate
int choice = 0; // your mode selection

// these 'prev' values are for the psychedelic choice

long rprev = 128;
long gprev = 128;
long bprev = 128;

void setup() {

// initialize the pwm pins as outputs.
pinMode(red, OUTPUT);
pinMode(green, OUTPUT);
pinMode(blue, OUTPUT);
pinMode(button,INPUT);

analogWrite(red,255);
analogWrite(green,255);
analogWrite(blue,255);

// seed the random number generator
randomSeed(100);

}

void loop() {

// read the pushbutton to see if it's been pushed
int val;
val = digitalRead(button);

// val = HIGH means the button has been pushed
// and the mode is to be changed.

// SELECT CHOICE //////////////////////////////////////////////////
if(val==HIGH){
choice = choice + 1;

analogWrite(blue,255);
analogWrite(green,255);
analogWrite(red,255);
delay(500);

// indicate mode transition with blue flashes
for(int i = 0; i<5; i++){
analogWrite(blue,125);
delay(20);
analogWrite(blue,255);
delay(40);
}

delay(500);

// change this if you want more modes

if (choice == 12){
choice = 0;
}
}

//TIME TO LIFT BUTTON //////////////////////////////
// (for debounce)

while (val == HIGH){
delay(100);
val = digitalRead(button);
}

//////////////////////////////

// read the potentiometer value
potval = analogRead(potpin);

// OFF
if(choice==0){
analogWrite(red,255);
analogWrite(green,255);
analogWrite(blue,255);
}

// CANDLE FLAME
if(choice==1){
flicker();
}

// RED

if(choice==2){
analogWrite(red,255 - potval/4);
analogWrite(green,255);
analogWrite(blue,255);

}

// GREEN
if(choice==3){
analogWrite(red,255);
analogWrite(green,255 - potval/4);
analogWrite(blue,255);
}

// BLUE

if(choice==4){
analogWrite(red,255);
analogWrite(green,255);
analogWrite(blue,255 - potval/4);
}

// tricolor
if(choice==5){
analogWrite(red,255);
analogWrite(blue,255);
analogWrite(green,255);
int tricolor;
for(int j = 0; j<4; j++){
if(j==0){
tricolor = red;
}
if(j==1){
tricolor = green;
}
if(j==2){
tricolor = blue;
}
analogWrite(tricolor,0);
delay(522-potval/2);
analogWrite(tricolor,255);
delay(522-potval/2);

}

} // end of tricolor

// STROBE

if(choice==6){
analogWrite(red,0);
analogWrite(green,0);
analogWrite(blue,0);
delay(10);
analogWrite(red,255);
analogWrite(green,255);
analogWrite(blue,255);
delay(1023-potval);
}

//this is white
if(choice==7){
analogWrite(red,255 - potval/4);
analogWrite(green,255 - potval/4);
analogWrite(blue,255 - potval/4);
}

// Oh no, your light is broken!
if(choice==8){
int mag8 = random(0,255);
analogWrite(red,mag8);
analogWrite(green,mag8);
analogWrite(blue,mag8);
int d8 = random(0,100);
delay(d8);
if(random(0,30)==0){
analogWrite(red,255);
analogWrite(green,255);
analogWrite(blue,255);
delay(500);
}
}

// Caution-warning yellow flashing light
if(choice==9){
analogWrite(red,0);
analogWrite(green,125);
analogWrite(blue,255);
delay(100);
analogWrite(red,255);
analogWrite(green,255);
analogWrite(blue,255);
delay(1200);

}

// Psychedelic
if(choice==10){

// When tweaking code, careful with variable types.

long rnew = random(256);
long gnew = random(256);
long bnew = random(256);
long rval;
long gval;
long bval;

for(int i; i<101; i++){
rval = rprev + long(i *(rnew - rprev)/100);
analogWrite(red,rval);
delay(5);
}
for(int i; i<101; i++){
gval = gprev + long(i *(gnew - gprev)/100);
analogWrite(green,gval);
delay(5);
}
for(int i; i300){
p = blue;
}
if(potval>600){
p = green;
}
for(int i = 0; i<256; i++){
analogWrite(p,255-i);
delay(4);
}
for(int i = 0; i<256; i++){
analogWrite(p,i);
delay(4);
}
delay(500);

} // end of choice 11

} // end of loop, loop, loopy-doop!

////////////////////////////////////////////////////////////

void flicker(){

// makes a flickering candle light

int k = random(0,100);
potval = analogRead(potpin);
float p = float(potval)/1023;

int rmag = 255 - (15 + 155 * k/100)*p;
int gmag = 255 - (10 + 55 * k/100)*p;

analogWrite(red,rmag);
analogWrite(green,gmag);

int d = 50+300 * random(0,100)/300;

delay(d);

}

////////////////////////////////////////////////

void tricolor(){

// transitions between red, blue, and green lights

analogWrite(red,255);
analogWrite(blue,255);
analogWrite(green,255);

analogWrite(red,0);
delay(500);
analogWrite(red,255);
delay(500);

analogWrite(green,0);
delay(500);
analogWrite(green,255);
delay(500);

analogWrite(blue,0);
delay(500);
analogWrite(blue,255);
delay(500);

}

Posted in Uncategorized | Tagged , , , , , , , , | 1 Comment

Making a flickering candle with an RGB LED and an ATTiny85 chip

Normally you don’t use an ATTiny85 to drive an RGB LED, because an RGB LED needs three pulse width modulation pins and the ATTiny85 only has two.  However, for the application of a flickering candle, you need only two PWM pins, the red and the green, and for that the ATTiny85 does the job just fine.

Unfortunately, my smartphone camera doesn’t do the color and intensity changes justice, but here’s the video:

Here’s a photo of the setup in the video:

0824171341a_Burst01

As you can see, the through-hole chip is puny compared to the LED.

And here is an Arduino Nano pressed into service as an ATTiny85 programmer:

0824171341_Burst01

In case you’re familiar with using Arduino but unfamiliar with how to use an ATTiny85, Matt Richardson made a great video on the topic here:

To avoid the hassle of shuttling the ATTiny85 chip back and forth between the programmer and application breadboards, I recommend first testing your program (aka sketch) on your Arduino until it’s debugged, then moving the program from the Arduino to the ATTiny85 .

When converting a program from the Arduino to an ATTiny85, remember that you have to translate pin numbers.   I made a conversion chart here for doing just that.

_________________________________________________________________________________

If you like reading science fiction and fantasy, you might enjoy my ebook trilogy beginning with The Wizard from Earth.

Posted in Uncategorized | Tagged , , , , | 5 Comments

Controlling Multiple RGB LEDs with Smartphone via Bluetooth

dscn2815

Many people have done projects similar to this where they use their smartphone to control an RGB LED. My project has some twists. First, I traded color variation for intensity variation. Second, I routed the Arduino PWM signal pins through power transistors so that I could drive multiple LEDs. Third (for now), I’m using phone charger battery packs so that eventually this thing can be mobile.

Here’s a video, I apologize for the quality, but it’s short and gets across the idea:

Here are some photos of the apparatus in close up. We’ll start with my smartphone, an LG K8V, as ordinary as they come:

dscn2818

The app is called ‘color control’ for the current icon. I used app inventor to create it, and also referenced a lot of online examples. App Inventor is a great resource that makes programming apps easy, and it’s great that so many people are willing to share their code! I have some tweaks to my code, which I’ll get around to sharing once it’s stable and if anyone is interested.

And here is what the app screen looks like:

dscn2819

Connecting to Bluetooth is simply a matter of touching the button, then selecting the Bluetooth device from a list. Oh, and remember to turn on your phone’s Bluetooth!

Here’s the Bluetooth hardware set-up:

dscn2820

The Bluetooth device is an HC-06. Note the resistors, the receive pin can only take 3.3 volts while the Arduino is sending 5 volts, meaning that you have to use a resistor bridge.

You all recognize the Arduino:

dscn2821

I’m using an Uno R3 here, but I’m planning to go to a Nano, which is smaller and less expensive and, I hope, less at risk of instability when supplied power is limited to five volts. We shall see . . . .

Here are the power transistors:

dscn2822

They are BD139s, NPNs that allow 1.5 amps through the collector-emitter path, or enough to power 25 RGB LEDs. The Arduino pins by themselves could only power one LED, while ordinary transistors would only power three or so. Power transistors are cheap, so no big deal.

The green patch in the upper right hand corner of the breadboard is the USB power breakout. A very handy thing to have, I wish I’d known about them when I was working on Project Grisbot (my robot) many years ago, I could have used phone charger battery packs in lieu of 9 volt batteries back then.

And here are the RGB LEDs:

dscn2823

I used common-anode RGB LEDs because I wanted the transistor at the ‘bottom’ of the circuit branch. Thus current pours in from the battery pack into the LED, then branches into the resistors, and then the resistor branches of red, green, and blue respectively combine to enter the collector node of the respective transistor, where the signals are modulated by the Arduino at the base.

BTW, all the resistors here are 200 ohm. I calculated that to keep the current through the LEDs down to 20 ma.

Anyhow, that’s the project as it stands. The goal is to make this prototype into something that is truly compact and mobile. Plans include using an Arduino Nano and a real circuit board. The big changes, though, will come in the programming as I intend to make it possible to save and replay files that are sync with music.

Posted in Uncategorized | Tagged , , , , , | Leave a comment

Ultrasonic Toggle Switch Source Code (Arduino)


// ultrasonic toggle switch
// Joe Schembrie aka 'Engineer Zero'
// comments 6-23-2016

// the circuit for this sketch consists of a yellow and green LED and an ultrasonic distance sensor (pinger).
// when a hand approaches the pinger, the yellow light comes on with the approach.
// when the hand gets close enough, the value of green is toggled.  
// IE, if the green LED was off, it turns on.  If it was on, it turns off.

// to see this in action, visit https://engineerzero.wordpress.com/2014/06/01/ultrasonic-toggle-switch/

// The green LED toggles only once while the hand is near. 
// IMPORTANT
// The hand must be retracted far enough so that the yellow light goes off
// for the green LED to be toggled again.  This prevents 'bouncing.'  

// NOTE:  In some respects, this device seems to work best when the yellow light is disconnected.
// NOTE ON NOTE:  I wrote the above note a couple years ago AND DON'T REMEMBER WHY.

// Now for inclusion of the library.  
// the NewPing.h library is available on the Internet.
// I did not write it.  I cannot answer questions about it.
// It comes with documentation on the Internet.  
// Google away!

#include <NewPing.h> 

#define TRIGGER_PIN  11  // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN     10  // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

// now to stuff that I wrote.
// here are some very important variables

// dis is distance of hand to sensor.  greenstate is state of green light.
// toggle is a variable that gives approval to toggle.
// Note that 'toggle' does not by itself trigger a toggle.  
// It only gives 'approval to toggle.'  

unsigned int dis;
int greenstate = 0;
int toggle = 10;


void setup() {
  // put your setup code here, to run once:

pinMode(2,OUTPUT);  // yellow is 2
pinMode(3,OUTPUT);  // green is 3
pinMode(11,OUTPUT); // pins 10 and 11 are used by NewPing
pinMode(10,INPUT);    

digitalWrite(2,LOW);
digitalWrite(3,LOW);

}

void loop() {
  // put your main code here, to run repeatedly:
  
// NewPing stuff . . . 

delay(50);

unsigned int uS;
uS = sonar.ping();

dis = (uS/US_ROUNDTRIP_CM);

// . . . end of NewPing stuff.  Now onto my stuff:

// the following code sets the zone value according to distance.
//
// after toggling, toggle approval is de-activated but 
// is re-activated if the hand is retracted to zone 0.
// this prevents nuisance toggling (bouncing).

int zone;

// zone = 0 means the hand is far enough away that the sensor doesn't react to it.
// toggle approval is granted.  
// I set the distance at 40 cm.  You can experiment with distances as you please.

if(dis>=40){
  zone = 0;
  toggle=10;
}

// zone = 1 means the hand is close enough to turn on yellow light.

if(dis<40){
  zone = 1;
}

// zone = 2 means the hand is close enough to toggle the green light.
// the 10 cm distance is open to your choice.  

if (dis<10){
  zone = 2;
}

// Now, I vaguely remember that the reason for the following test had something
// to do with the quirkiness of the sensor.  Sometimes it fails to read and
// reports a zero distance.  The following test prevents that from causing problems.

if(dis<2){
  zone = 0;
  toggle = 10;
}


// now we take care of yellow light.  
// It's pretty simple.  If you're within a certain distance, it's on.  Otherwise, off.
// 

if(zone==0){
  digitalWrite(2,LOW);
}

if(zone>0){
  digitalWrite(2,HIGH);
}


// we toggle the variable greenstate (and, most importantly, the green light)
// if we're in zone 2 and toggle is 10.
// 
// why these values?  It will become apparent in later context.  
//
// zone 2 means we're close enough to toggle.
//
// toggle = 10 means go ahead and toggle.
// toggle = 0 means don't toggle.
// 
// greenstate = 0 means the green light is OFF.
// greenstate = 100 means the green light is ON.
//
// 'toggle' is a variable that 'approves' toggling the green light
// only ONCE when you're close to the sensor.  It's then set to 0
// and your hand has to move away in order for it to reset to 10.
// this prevents bouncing.


int k = 0;

// now, you're probably also wondering about this 'k' business.
// the k variable is a handy way to avoid making a complex IF statement.
// Maybe it's me, but sometimes I just can't get multi-condition IF statements
// to work on the Arduino.
//
// So instead, I use individual IF statements to create flag variables
// and then add the flag variables together to create a 'master flag variable'
// which I can then test in a simple one-variable conditional statement.
//
// So k is for 'kludge.'  But it works . . . .

k = toggle + zone + greenstate;

// k = 112 means that the toggle (=10) is approved, we're in toggle zone (=2) , 
// and the greenstate (=100) indicates the green light is ON.

if(k==112){
  greenstate = 0;
  digitalWrite(3,LOW);
  toggle = 0;
}

// k = 12 means that the toggle (=10) is approved, we're in toggle zone (=2) , 
// and the greenstate (=0) indicates the green light is OFF.

if(k==12){
  greenstate = 100;
  digitalWrite(3,HIGH);
  toggle = 0;
}

// these two statements then toggle the green light 
// (and circuits activated by the same pin).
//
// note that for all other values of k, no action is taken.  

// And that's all there is to it!!!

}






 
  


Posted in Uncategorized | 1 Comment

Orbital Hydrogen Collector

Orbital Hydrogen Collector (OHC) with docking spacecraft

Orbital Hydrogen Collector (OHC) with docking spacecraft

Deep space missions will require the placement of large quantities of hydrogen in low earth orbit for use as spacecraft propellant. Procuring hydrogen in low earth orbit from the surface of the earth via chemical rocket booster can be relatively expensive.

The Orbital Hydrogen Collector (OHC) offers an alternative method of obtaining hydrogen propellant in low earth orbit. The OHC ‘scoops’ the hydrogen that exists in minute amounts in the near vacuum of the upper atmosphere at altitudes of low earth orbit. This hydrogen propellant can then be accessed by docking spacecraft to the OHC.

FIGURE 1 (not to scale) shows the basic design of an Orbital Hydrogen Collector. The direction of orbit is from right to left, as shown. The ‘flow’ of atmospheric hydrogen is thus from left to right.

ohc 2

Hydrogen molecules enter the scoop (a) and are compressed into higher-pressure gaseous and/or liquid form by the compressor unit (b). The hydrogen is then pumped into storage tanks (c). Spacecraft can access the stored hydrogen by docking with the propellant transfer boom (d).

The collection of atmospheric hydrogen causes the OHC to lose momentum and experience orbital decay. To compensate, the OHC can utilize electric propulsion to provide orbital boost. In the figure, photovoltaic panels (e) provide electric power to engine (f) while propellant is pumped from storage tanks (c) to engine (f).

The operational exhaust velocity of the engine must be higher than orbital velocity, or the engine will not be able to compensate for momentum lost to atmospheric drag. Plasma engines are the logical candidates for OHC propulsion.

At $5000/kg to ship payloads into orbit using expendable rocket boosters, it could cost tens to hundreds of billions of dollars to place into orbit the hydrogen propellant needed for just one human expedition to Mars. Informal calculations indicate that the OHC could collect the same amount of hydrogen in orbit for as little as one percent of that cost.

line break

wizard cover 12

The Wizard from Earth, a science fiction novel by S.J. Ryan (aka, Me), available on Amazon as an ebook

Posted in Uncategorized | Tagged , , | Leave a comment

Eye Robot, the Continuing Saga

0422051730

My original plan for making a robot with visual pattern recognition was to connect a camera to the raspberry pi, and then the raspberry pi to my laptop, and then I would run the raspberry pi ‘headless.’ That means, I would open up a remote terminal program on my laptop to access the raspberry pi’s desktop. The advantages of this are that I wouldn’t need a separate monitor or mouse or keyboard or wi-fi for the pi.

But this turned out to be one hassle after another. It turns out that you can’t configure a pi to be headless unless you first have it ‘headed.’ So you need all that stuff, in order to not need all that stuff. And then I couldn’t get the remote terminal program to work, and I would have to modify several files on the pi that I knew nothing about, let alone how to modify them in the first place . . . .

My second plan was to just do the pattern recognition programming on my laptop. It’s in python, and python is portable, right? So whatever I do on my laptop can be ported over to the pi, even though one is Windows and the other is Linux. Easy as. Nope, the webcam I got for the laptop has a mini-CD disk that clatters in the drive, and I couldn’t get SimpleCV to download at first, and then it wouldn’t work . . . and this got too complicated too.

So then I ended up getting all the peripherals for the pi after all. Today I connected the monitor, only to discover that the power supply that I ordered from Amazon is wrong. I bought the CanaKit power supply, thinking that since it was on the Tontec monitor page, that it was for the Tontec monitor. No, it’s for the raspberry pi, and because people who buy the Tontec monitor also buy the raspberry pi (of course), they also buy the CanaKit power supply for the raspberry pi. And that’s why it ends up on the Tontec monitor page even though it doesn’t connect to it. My fault.

This is what you see in the picture. I still can’t get the thing up and running because I need a power supply for the monitor. That will come next week. I suppose I’m in no hurry.

Anyhow, here are the links for the Tontec monitor and the correct power supply, in case you want to check them out:

Tontec 7″ LCD display screen for raspberry pi

Tontec power supply for the above

Until I get the power supply, I can’t vouch how this stuff works, but you can see the ratings on the Amazon pages.

BTW, I saw a demonstration of the Pixy(cam) Pet robot on Saturday, and it’s a good example of what can be done with robot vision. Here is a Youtube video of the Pixy Pet robot:

Posted in Uncategorized | Tagged , | Leave a comment