If you don't want to change your code, what if you add a small NPN transistor to the base of the PNP?
Connect the NPN to GND instead of VDD (all sounds plausible in my head).
Robert
Printable View
If you don't want to change your code, what if you add a small NPN transistor to the base of the PNP?
Connect the NPN to GND instead of VDD (all sounds plausible in my head).
Robert
Please delete this post
Rob,
I'll opt for changing the code... it's only a matter of changing half a dozen lines from how to high :)
But thanks for the input
Yeah, there's no way to change the actual transistor (obviously) so what you need to do is invert the signal which you can do by adding a NPN transistor "in front" of the PNP like Robert says.
Previously I said to put the transistor on the low side but that was when you used a NPN transistor. Now, with a PNP "serviced" by a NPN you'll be better of putting on the high side. It will work with the PNP on the low side as well but only as long the voltage feeding the motor isn't higher than the voltage used to drive the transistors (ie the voltage feeding the PIC) + around 1V for a Darlington. Also, remember that the voltage drop across a Darlington transistor is higher than across a "normal" BJT.
You need to remember that ordinary transistors (BJTs or Bipolar Junction Transistor) are operating on current. Ie, for a NPN transistor we push a certain current into the base which gets "amplified" by the gain of the transistor and "pulled down into" the collector. The base basically behaves as diode connected to the emitter so there will be a voltage drop across it of ~0.6V (for a silicon device) as with any diode. So, IF you put a NPN transistor on the high side of the load with the collector connected to, say 12V, you basically need a voltage of 12.6V in order to be able to "push" current into the base. If you try to push current into the base using 5V the transistor will only partly open (ie it'll operate in its linear region) and it'll disipate a lot of heat. This is what's done in linear amplifiers etc but not what you want when using the transistor as a switch.
OK, so what if we put that NPN on the low side of the load (motor). Now, the emitter is connected to ground so there's plenty of headroom in using 5V to push current into the base and it'll work just fine provided you use a sensible value for the base resistor.
Then you decide to change to a PNP transistor.....
The PNP transistor is "operated" by "pulling" a current out thru the base (as oposed to driving current into the base for a NPN). So, if you put the PNP on the low side of the load its emitter (which is now connected to the load) will "see" the full supply voltage when the transistor is OFF. So, in order to keep the transistor OFF no current can be allowed to flow down thru its emitter and out of the base, right? In order to prevent that from happening the voltage at the base needs to be atleast the same as the voltage feeding the load less one diode drop (or two for a Darlington). If the powersupply voltage is 12V and you're driving that low side PNP with 5V from a PIC it will never turn off completely.
Putting your Darlington PNP on the high side of the load with a small NPN to "pull" current thru the Darlingtons base to ground (thru a resistor of course) is the right way to do it given those particular circumstances.
/Henrik.
Henrik,
Thanks for the explanation. And yes I did find the motor would not actually stop running, it would shut off, then slowly start up again, gradually increasing in speed.
If I've followed your post correctly, and followed the schematic provided by Pedja, would the attached work (using say a 2n3904 and a 1K base resistor) - Note that the motor supply is using 6v with the PIC running at 5v (and I've noticed I've omitted the diode across the relay -Doh !)
Wow. Great explanation Henrik. It answered a few questions I'd been having with a project. Thanks for taking the time.
Scampy,
You have the Darlington PNP upside down, the emitter needs to go to the positive rail. And you need a resistor in the Darlingtons base as well. If you don't put a resistor there you'll basically short out the supply with the base emitter diode(s) in the Darlington - not good. Use 1k or whatever.
EDIT: Oh, and the emitter of the small NPN must go to ground - not to the collector of the Darlington.
AvionicsMaster1,
Thanks, and you're welcome! Perhaps not the best explaination from a purely technical standpoint but never the less.... :-)
/Henrik.
Henrik, Thanks for the info.
I was browsing through my old posts as I recall I did something similar for a model train controller... only this time I used two transistors in a darlington pair. I'll use this as a basis for the output to the motor - via the relay contacts
I have ever used a DPDT relay as a motor direction control instead of an H bridge device.
In some cases the relay takes care of a lot of H-bridge current limitation issues since there is negligible resistance in relay contacts. A 2n7000 mosfet can a drive large number of different relay types nicely.
And the relay only requires one control pin from the PIC.
If speed control is needed, I use a mosfet to pulse current to the motor.
Fun stuff!! :-]
I've just transferred the project from the development board to stripboard. The circuit is running fine in that the RTC is being read and serial comms are working, however the PIC is not driving the relays hard enough to move the contacts (although they can be heard clicking slightly). I've changed the base resistor as I'm now using 5v DIL relays with contacts rated at 2A 30v which should be OK for driving a 6v motor that draws 700mA under load. In the attached circuit R1 is 100 ohm, Q1 is a BC639 NPN and the relay coil has a resistance of 63 ohms. I've also found that when the PIC makes the pin high it's reaching 2.84v and not 5v or near as dammit. Any suggestions ?
Hi,
In the datasheet I looked at the current gain for the BC639 is stated as minimum 40. Your relay coil needs 5V/63ohm=80mA at 5V, with a gain of 40 you need to push 80/40=2mA into the base of the transistor.
There's a drop of 0.6V across the base-emitter junction so if the PIC is powered with 5V you're left with ~4.4V to do it. The base resistor then needs to be 4.4/0.002=2200ohm, I'd go with half that or ~1k.
With a 100ohm base resistor you're overloading the output drivers in the PIC, trying to pull ~44mA from an output rated at 20mA. This is probably why the voltage is clamped to way less than 5V.
Fit a 1k-2k resistor then verify the operation in steps.
1) Measure the voltage at the PIC output, it should be either 0 or 5V (or close to it). If it's not then something is wrong.
2) Measure the voltage at the base of transistor, it should be either 0 or 0.6V (or close to it). If it's not something is wrong.
3) Measure the voltage at the collector of the transistor, it should be 5V when the transitor is OFF and close to 0 when the transitor is ON.
If it doesn't work please do the above measurments and report the results.
/Henrik.
The output drive is current limited to 25mA meaning an internal resistance of about 200 Ohms at 5V. That's why you see the 2.84V at the pin and nothing close to 5V.
Attachment 7242
Also, I would think you only need about a 2K Ohm resistor to drive the NPN that has a min. gain of 40 to drive the 80mA relay load.
LOL - I originally had a 1K base resistor in there and though that was limiting the current / voltage !
The data sheet on the relay does indeed state a current draw of 80ma at 5v - I'll replace the base resistors with 1.5K, being midway between the 1K recommendation and 2K calculated, then follow Henrik's test and I'll report back
Fitted a 1.5K resistor
1) - Voltage out when the pin goes high = 4.52v
2) - Base of transistor voltage measured 0.73v
3) - Voltage at collector when PIC pin was HIGH was 0.03v and 5.01v when PIC pin was LOW
Still the relay contacts didn't switch.
Thinking it might be the regulator as I'm using a 200mA version of the 7805 I changed this for a traditional 1 amp version - still no change.
As the new relays are DIL footprint (16 pin DIL) and I am using sockets, I removed the relays and inserted the pins of the original relay into the contacts on the DIL socket. This relay also has a coil of 68 ohms so would be drawing similar current of around 80mA ? - The contacts changed over just fine. Last test was to attach two wires to the coil and plug this into the DIL socket - still no change, but plugging the coil directly across the 5v switched it hard...
I'm going to re-breadboard the hardware with the DIL relays and see if it switches OK just to rule out a fault on the stripboard (my eyes are not what they used to be - so I could have a dry joint or short somewhere !) - but I don't hold up much hope as any such issues should of resulted in the same thing happening with the original relay when tested with the stripboard.....
Its now working.
I removed all the links to the relays apart from the coils - tested and it appeared to energise. I then googled the datasheet for the relays and found that the contacts where wired differently to the other relay (NO / NC then the comm rather then NO / comm / NC) - rewired the stripboard (now quite a mess) and it works (well I get 5v out to the motor when the pic energises the relays :) )
Thanks to all who contributed - and I'll note that formula for working out the resistances - Cheers Henrik
Well for reference and to aid anyone who may stumble across this thread in future here's the circuit diagram and final code (full of comments to explain how it works)
Ok the code may be very basic, could possibly be written tighter and isn't really rocket science, but it works for me. Likewise the choice of transistor in the schematic might of been better, but it's what I had and after the debuging - works with the relays etc.Code:'****************************************************************
'* Name : Chicken Coop Door Control *
'* Author : Malcolm Crabbe *
'* Date : 30th January 2014 *
'* Version : 1.0 *
'* Notes : Uses PBP 2.60c *
'* : 16F690, int osc 4MHz *
'* : Program uses RTC to turn *
'* : on an electric motor and open a sliding door. *
'* : Door travel controlled by limit switches *
'****************************************************************
ASM
__CONFIG _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF
endasm
DEFINE OSC 4
DEFINE HSER_RCSTA 90h 'Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h 'Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25 '9600 Baud @ 0.16%
DEFINE HSER_CLROERR 1 'Clear overflow automatically
ANSEL = %00000000 'Set all pins digital
ANSELH = %00000000 'Set all pins digital
ADCON0 = %00000000 'AD converter module disabled
OSCCON = %01100101 'bit7 not used, bits 6-4 4mhz default, bit3 int osc, bit2 HS stable (ignored - at 4Mhz), bit1 not stable, bit0 int osc used for system clk
CCP1CON= %00000000 'Turn off CCP module
SSPCON = %00001011 'Ic2 master
TRISA=%00000111 'set PORTA as all output apart from RA0, RA1 and RA2( bits 7&8 unimplimented read as 0)
TRISB=%11110000 'set PORTB as all input ( bits 0-3 unimplimented read as 0)
TRISC=%11111111 'set PORTC as all input (default for POR)
day var byte
RTCMin var byte 'RTC Minutes
RTCHour var byte 'RTC Hours
RTCsec var byte 'RTC Seconds
TimeH var byte 'variable to store Hours
TimeM var byte 'variable to store Minutes
SS VAR Byte 'variable to store Seconds
CounterA var byte 'General purpose Variable
CounterB var byte 'General purpose Variable
TempWD VAR WORD
Counter1 var word 'used to store the current time as a digit. Counts minutes from 0000 at midnight
Char var byte
Relay var PortA.5 'used to activate relay and thus reverse direction
Motor var PortA.4 'used to drive the motor
SW1 VAR PortA.0 'Door open limit switch
SW2 VAR PortA.1 'Door closed limit switch
SW3 var PortA.2 'Manual close button
Tx var PortB.7 'used for sending time value in testing
Rx Var PortB.5 'used for receiveing time value in testing
SetMN var byte 'Used to set time Minutes
SetHR var byte 'Used to set time Hours
SetSS var byte 'Used to set time Seconds
onHR var byte 'Used to set the Opening time (Hrs)
onMN var byte 'Used to set the Opening time (Min)
Ontime var word 'On time value in minutes
RCIF VAR PIR1.5 'USART receive flag
GIE VAR INTCON.7
RCIF=1
SCLpin var PORTB.6 'RTC pin - clk
SDApin var PORTB.4 'RTC pin - data
setHR = 06 'On powerup time set to 00 Hrs
setMN = 44 'On powerup time set to 00 minutes
onHR = 06
onMN = 46
CounterA=SetMN 'convert initial time to BDC and write it to the DS1307
Gosub ConvertBCD
RTCMin=CounterB
CounterA=SetHR
Gosub ConvertBCD
RTCHour=CounterB
I2Cwrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
day=0 ' set mode to night
low Motor ' set motor to off
low relay ' relay off
'*******************************************************************************
Main:
'*******************************************************************************
I2CREAD SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour] ; read DS1307 chip
timeH=(RTCHour>>4) 'convert the BCD format of the hours register and store in variable timeH
timeH=(timeH &$03)*10
timeH=timeH+(RTCHour&$0F)
timeM=(RTCMin>>4) 'convert the BCD format of the mins register and store in variable timeM
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F)
ss=(RTCSec>>4) 'convert the BCD format of the sec register and store in variable ss
ss=(ss &$07)*10
ss=ss+(RTCSec&$0F)
Counter1 = (TimeH *60)+ TimeM 'take hours and multiply it by 60 then add odd minutes to get the total minutes into counter1
Ontime = (onHR*60)+onMN
Hserout["Time: ",#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0,":",#ss DIG 1,#ss DIG 0," Counter = ",#counter1," Ontime = ",#ontime,13,10]
pause 200
FOR TempWD = 0 TO 1000
IF RCIF THEN GOto comms ' Check to see if there is communications on the comm port
PauseUs 1000
NEXT TempWD
if counter1 = ontime and SW2=1 then ' If counter matches on time and A.1 is high then
high Motor ' Turn on the motor
high relay ' Energise the relay
endif
if SW1 = 1 then ' Door open limit switch (A.0) hit and applies 5v to pin
low Motor ' Stop motor
low relay ' de-energise relay
endif
if ontime < counter1 or ontime > counter1 then ' If the counter is anything other than ontime, turn everything off
low SW1
low motor ' Turn on the motor
low relay ' Relay kept off for reverse polarity of motor
endif
If SW3 = 1 then
high motor
low relay
Low SW1
endif
if SW2 = 1 and ontime < counter1 or ontime > counter1 then ' Door closed limit switch hit and applies 5v to pin
low Motor ' Stop motor
endif
goto Main
'*******************************************************************************
'*******************************************************************************
convert:
CounterA=SetMN
Gosub ConvertBCD
RTCMin=CounterB
CounterA=SetHR
Gosub ConvertBCD
RTCHour=CounterB
I2Cwrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour]
return
'*******************************************************************************
comms:
HSERIN [Char]
SELECT CASE Char
CASE "T","t" ' set time
hserout ["Set Time Hour ",10]
HSERIN [#setHR]
hserout ["Set Time minutes ",10]
HSERIN [#setMN]
gosub convert
CASE "O","o"
Hserout["Set Open Time: ",13,10]
hserout ["Set Hour ",10]
HSERIN [#onHR]
hserout ["Set Minutes ",10]
HSERIN [#onMN]
Ontime = (onHR*60)+onMN
CASE "C","c"
Hserout["Time: ",#TimeH DIG 1,#TimeH DIG 0,":",#TimeM DIG 1,#TimeM DIG 0," Counter = ",#counter1,13,10]
pause 500
end select
goto Main
'*******************************************************************************
' convert BDC format to decimal
ConvertBCD:
CounterB=CounterA DIG 1 ' CounterA is the entry variable
CounterB=CounterB<<4 ' CounterB holds the converted BCD result on exit
CounterB=CounterB+CounterA DIG 0
Return
'*******************************************************************************
I would like to thank all those who contributed to this thread and not only provided the support I needed, but also educated me both in PicBasic Pro and electronic component selection. - Thanks guys
Disclaimer:
The usual disclaimer applies, ie I accept no responsibility what-so-ever - anyone uses this code / schematic at their own risk etc etc... lardy dar de dar !! :) -- (sorry to high on pain killers for tooth ache !!)
Just for the fun of it, you may consider playing around with the relay and transistor separate from the PIC. There may be some possibility that a base bias resistor between 5k to 10K may actually switch that relay quite nicely. If so, that would put even less current demand on the output of the PIC. In the future if you are browsing a supplier like allelectronics, look for the 2n7000 N-Channel mosfet. It can handle 400mA and won't require any current at all from a PIC, since it is voltage driven. Just a 1 meg bias resistor holding the gate to ground. I bought a surplus box-of-em on ebay a while ago. Enough to last me the rest of my life ;-D
Great pics my friend!! and a very well done project!!
Congrats!!
Duane :-]