Arduino Mega - Digital Pin Question

Thread Starter

CoachKalk

Joined Sep 20, 2011
141
Hello everyone. This is my first stop in this section as I have just lumped into the land of the Arduino.

I have added a circuit that will be 1 of up to 12 I plan to use/control. I have been trying to get up to speed on the programming side of things and I have already hit my first snag.

First, here is the circuit.


I have tried to write a simple sketch assigning 1 digital pin as an input "written" to LOW and 1 digital output pin written to LOW.

For some reason, as soon as the unit powers up, the digital output pin is HIGH - even if nothing is connected at the input pin.
//Laser Maze Program
//Assign laser units to pins
const int laser1 = 22;
const int pbeasy = 51; //This PB, when HIGH will turn on laser1 to
//start the game.

void setup()
{
pinMode(laser1, OUTPUT);
pinMode(pbeasy, INPUT);
digitalWrite(pbeasy, LOW);
digitalWrite(laser1, LOW);
}

void loop()
{
if(pbeasy == HIGH);
digitalWrite(laser1, HIGH);
delay(2000);
digitalWrite(laser1, LOW);
}

I am just starting out and I am not sure when items should be at the top of the program, in the setup or loop sections. Do i have something wrong?

Eventually I plan to feed the voltage divider into an analog pin and hopefully control the corresponding laser accordingly. But that will wait until I can get the laser to come on with the press of a PB.

One other potential issue I am wondering about is when more lasers get online. My plan is to use 1 initial press of the PB to set multiple lasers to high (say 4 total). Then, depending on when the laser is tripped, it will shut off for a set time and then go back on. Needless to say I will be back with more programming questions when I get that far!

My other question involves using an output pin to close the 2n2222 transistor. Is that acceptable? The current over the laser/LDR circuit was measured at 25mA @ 5.1V. It is unclear to me if the Arduino will only be sourcing the fractional current necessary to close the transistor or potentially see the larger amount. Obviously I do not want to fry it? Sorry about digressing into non-programming things ...

Thanks in advance for your help.
 
Last edited:

ErnieM

Joined Apr 24, 2011
8,377
I don't do Arduinos so I can't help with the code much, but...

You don't show how you drive the input pin

There is an LDR circuit in parallel with the laser, and I wonder why it is there.

10 ohms in the base of the 2N2222 will draw near half an amp into the base from the Arduino (which it can't supply). You need to recompute that. Something closer to 2K would work better.

Finally, the way your code is written you can turn the laser on forever just by holding the button down. Only if you release the button in the first 2 secs will the laser only be on for 2 secs, otherwise it stays on for chunks of 2 secs. That may be what you want but it seems weird.
 

Thread Starter

CoachKalk

Joined Sep 20, 2011
141
You don't show how you drive the input pin
My plan is/was to drive the input pin via an output on the arduino.

There is an LDR circuit in parallel with the laser, and I wonder why it is there.
The LDR circuit will be used with the laser. My plan was to keep each laser/ldr unit powered together so each "unit" could be turned on/off at the same time. Laser 1 would then be lighting ldr 1, etc ... (with the values read by an alanog pin)

10 ohms in the base of the 2N2222 will draw near half an amp into the base from the Arduino (which it can't supply). You need to recompute that. Something closer to 2K would work better.
So I had a long description of what I did so you could help me understand where I went wrong and in the process I realized I used the full current I measured across the load instead of 1/10th. Is the 1/10th a standard I should assume for typical transistors? My electronics is only slightly ahead of my arduino programming so that may seem like a stupid question.

Finally, the way your code is written you can turn the laser on forever just by holding the button down. Only if you release the button in the first 2 secs will the laser only be on for 2 secs, otherwise it stays on for chunks of 2 secs. That may be what you want but it seems weird.
My overall plan is to use a laser start button with a SCR so that 1 press/release of the NO button will keep the input HIGH - yes the laser would stay on - room ready for play. Then, as one of the kids blocks the laser (LDR goes dark), I was going to use the arduino to write the input pin low (I thought that would turn the laser/ldr circuit off) for 2 seconds - then back on.

The Vcc2 shown is from an arduino output pin. The planned "start" button would feed into a different arduino input pin in order to power the Vcc2.

I guess it seems silly as drawn because I only have one laser/ldr unit, but eventually I will have more so the one start button would feed more "units".

I will try another go on the programming side.
 

ErnieM

Joined Apr 24, 2011
8,377
OK, I see more of where you're going now. I don't think you need the SCR (which is easy to turn ON but you'll have trouble turning OFF) on the START button, the Arduino should be able to "remember" a button press anyway.

Also, why switch the LDR? Just leave it always on. If nothing else it will tell you when it should be dark but is lit anyway (fault detection).

Up the base resistor and the transistor should handle the current. If your load is 25mA then around 2.5mA is good in the base: the "rule of thumb" is base = 1/10 the collector current for a god saturation voltage (makes it as on as it can be), but you don't have to hit that exactly. Higher or lower is OK.

Minor point: don't call the pin output "VCC2" as it looks like a voltage source to anyone else (and you too one day). "LASER-X" or something more description to it's function works better.
 

BillO

Joined Nov 24, 2008
999
Hi,

1) That 2N2222 will not sink 4 amps. If the laser supply is indeed 4 amps you will need a bigger transistor to turn it on. I would suggest a MOSFET as they will not load the microcontroller as much as a transistor and are easier to deal with. Something like a IRF9Z34 used as a source switch (rather than sink as we see here). It's rated at 18 amps and would not need a heat sink to switch a 4 amp supply. In this case the laser will be turned on when the gate of the MOSFET is low.

2) The Arduino's absolute maximum output per pin is 40ma. I would advise, generally, to not go too far beyond about 10ma per pin, as the whole device can only source 200ma in total. So, as you add things to this, you still want to have some drive capability left. For controls like this then keep the drive current low. In this case 470 ohms is about as low a base resistor as I would use. Consider using the p-channel MOSFET as suggested above.

3) Was pin 51 (pbeasy) left floating during your tests? That might cause unexpected results. If you want it low, then pull it low with a 10K resistor. Then hook the momentary switch to Vcc and the input pin so that it pulls the input high when the button is pressed.

4) Are you aware that, the way you have the circuit drawn, the LDR will only be useful (active) when the transistor is conducting? Is this what you want?

See the attached schematic to cover these points.

 

Attachments

Thread Starter

CoachKalk

Joined Sep 20, 2011
141
Bill,

Thanks for your input. It is possible that my lack of experience using proper notation may be causing problems. Take a look at my comments and see if you still anticipate an issue.

Hi,

1) That 2N2222 will not sink 4 amps. If the laser supply is indeed 4 amps you will need a bigger transistor to turn it on. I would suggest a MOSFET as they will not load the microcontroller as much as a transistor and are easier to deal with. Something like a IRF9Z34 used as a source switch (rather than sink as we see here). It's rated at 18 amps and would not need a heat sink to switch a 4 amp supply. In this case the laser will be turned on when the gate of the MOSFET is low.
The reason I have the laser supply noted at 5V - 4A is because each laser draws 25mA @ 3V. Eventually, I plan to have up to 12 in use so I wanted to make sure I had a power supply that could handle the anticipated total current. When I was struggling with the transistors, I actually read some on MOSFET's, but the main issue I found was the increased V required to fulling "open". I had just starting investigating logic driven MOSFET's (suggested on another thread), but I "thought" the 2n2222 could handle the current of 1 laser at a time.

2) The Arduino's absolute maximum output per pin is 40ma. I would advise, generally, to not go too far beyond about 10ma per pin, as the whole device can only source 200ma in total. So, as you add things to this, you still want to have some drive capability left. For controls like this then keep the drive current low. In this case 470 ohms is about as low a base resistor as I would use. Consider using the p-channel MOSFET as suggested above.
Based on the transistor sinking 1/10th of the 25mA per laser unit, isn't the arduuino then only seeing the 2.5mA per unit? If/when I get 12 set up, the total should still be only 30mA? (all 12 units @ 2.5 mA each?)

3) Was pin 51 (pbeasy) left floating during your tests? That might cause unexpected results. If you want it low, then pull it low with a 10K resistor. Then hook the momentary switch to Vcc and the input pin so that it pulls the input high when the button is pressed.
After the link provided above and additonal reading, it is quite possible I had incorrectly "wrote" it LOW when I should not have. I will revisit my setup tonight.

When I was having problems with the program, I ended up using the Pin 22 to an resistor - led - ground. As soon as the arduino was powered up, the led lit up. Even when I tried to write it low. The issue may again have been with my incorrect designation of pin 51 though.

4) Are you aware that, the way you have the circuit drawn, the LDR will only be useful (active) when the transistor is conducting? Is this what you want?
I suppose it looks strange. I am not "married" to the current structure, but I thought if I could treat each "laser/ldr unit" as a stand alone circuit, it would minimize the number of pins I used on the arduino. If the laser is off, it is completely fine for the LDR circuit to be off as well - for playing purposes anyway.

I have started thinking about the intial start up/stop set up and I would like to throw out a question if I may.

It is part programming question and part design suggestion question. I will start off with what I would like to happen and what I am thinking.

The kids will select 1 of 3 start buttons. 1 - easy (maybe 5 lasers power up) 2 - Medium - (maybe 9 lasers) and 3 - Ninja (all 12 lasers). All of these buttons would be NO PB's and depending on which one is selected the corresponding lasers would light up and the room would be ready. Based on my plan before arduino, I figured because all of my PB's were either NO or NC, I would have to use some of switch that could take the signal from the Start PB and stay on (powering the lasers) - hence the SCR's.

But, I really only need the Start button to power up the laser/ldr portion of the program one time at the beginning. Once the lasers have power, I would keep them powered except when the analogRead falls below the target (kid blocks the laser). If/when the analogRead values drops below the target, the laser pin would be turned LOW (laser off?) for 1-2 seconds, then be turned HIGH again.

After the kids get across the room and back with the treasure, they would hit a STOP PB that would shut down ALL lasers (and hopefully the timer display as well eventually).

It was suggested above that the arduino could remember button pushed and I may not need 2 buttons and/or SCR's. I am not sure what the best way is to use/setup the Level Select Start buttons to mesh with what the arduino will see.
 

BillO

Joined Nov 24, 2008
999
Okay, some differences then...

1) Sure, a 2N2222 will handle 25ma just fine. The 10 ohm resistor you show on the laser diode seems a little low then. If the voltage drop of the laser is 3V and we know the voltage drop across the 2N2222 is typically negligible during saturation, then that resistor should be about 80 ohms to limit the current to 25 ma.

2) No, the circuit is in through the base and out the emitter. The base current in this case is limited only by the base resistor. The collector current has no effect on the base current in common emitter circuits. It is actually the other way around. The collector current is limited to Gain * Base current. Given that the you need 25 ma through the base and that you can safely assume the 2N2222 has a gain of at least 80 (typically ~200) at 25ma through the collector, then the base resistor would not need to be any less than 10K to ensure the transistor sufficiently saturated. That would reduce the current draw out of the Arduino to about 0.4ma given that the output voltage is typically around 4.7V and voltage drop across the transistor from base to emitter is about .7V. You could use 1K, or 2K or 4K7 or anything up to about 10K, but not 10 ohms. As was stated before, that will try to draw near a half amp out of the MCU and will kill that pin or worse.

3) Not sure what you mean here. However, speaking generally, if the I/O pin has been set to input and you write a low to it, you actually disconnect the internal pull-up resistor. In this case, you cannot leave the pin floating. You need to use an external resistor to either pull it high, or low, depending on what you want it's normal logic level to be.

As to your question(s). What you want to do is actually really easy. Yes, writing a high to a I/O pin that is in output mode will keep that pin high until you expressly write a low to it.

It actually sounds like a pretty neat project and the code would be almost trivial. I see you biggest headache as setting up the laser diodes and the LDRs so that they are aligned.

Coding wise, I'd take this approach:
Rich (BB code):
/*

Begin by declaring all your variables and functions
I would create a function for each action.  Look at
the examples

*/
void easy (void);  //Function for 'easy' game play
void hard (void);  //Function for 'hard' game play
// ..and so on...

int pbEasy = 20;
int pbHard = 21;
int pbNinja = 22;
int pbStop = 23;
int pbRestart = 24;
int laser1 = 30;
int laser2 =31;
// ..and so on...


void setup () {
  /*
  
  Initialize everything here.  Just set everything
  up the way you want it before one of the game start
  buttons is pressed
  
  */
}

void loop (){
  /*
  
  I would just use loop() to detect switch inputs
  and call the appropriate function to handle the
  required action
  
  */
  if (digitalRead(pbEasy)){
    easy();
  }
  if (digitalRead(pbHard)) {
    hard();
  }
  //..and so on...
}

void easy () {
  /*
  
  Do the things here to set up and run the easy game
  like turn on lasers, set timers, look for beam
  breaks, etc...
  
  */
  digitalWrite (laser1, HIGH);
  digitalWrite (laser2, HIGH);
  //..and so on...
}

void hard () {
  /*
  
  Just like the easy () function with the appropriate
  changes
  
  */
}
 
Top