Neither do real analog designers. It's almost a daily exercise for me converting device libraries to upper case so I can tell 1's an l's apart. UNIX people seem to be particularly jerky about lower case ;-)
...Jim Thompson
Neither do real analog designers. It's almost a daily exercise for me converting device libraries to upper case so I can tell 1's an l's apart. UNIX people seem to be particularly jerky about lower case ;-)
...Jim Thompson
I think the fix is a MOSFET for the relay driver and a few gates instead of the 555 for the timer.
I'll work something up tonight and post it tomorrow but, in any case, thanks for the rancorless reality check. :-)
JF
Well... if the supply voltage is a reasonable value for driving the relay, say between 8V and 12V, one could consider turning the
100K pullup into a voltage divider that would float the trigger just above its threshold. Say a 120K/68K split. That would put the trigger voltage at about 0.36*Vcc . The 1.4V pulse should then be sufficient to drop it below the 0.3*Vcc threshold.
I use case for legibility. I certainly don't want the system/compiler/files to be case sensitive.
Yeah, but he comments in uppercase too. Brute.
Grins, James Arthur
ARRGGGHHH!
james
Only if you think being exposed to hardware that balances competing needs well is evil. It's how things sometimes get done even in well done achievements of balancing contending issues. I just worry about what meets the need well and actually feel impressed when a crafted and intelligent balance is successfully struck -- even if it means there happens to be some software issues added to the pile. The converse of that simply sweeps the software burden inordinately onto hardware designers and I tend to enjoy seeing a balance of weight placed on both sides of the fence.
Time have changed some and it's less work to design smaller micros without the bank switching hardware. But it had its place and still does to a degree not only with the PIC but also with the Intel x86 family, as well -- even the newest ones include banks everywhere; segment descriptor tables, which are themselves "banked" by other registers that locate them; page table "banks"; and so on. Advantages are to be used. DSPs have their own contributions here, in spades. And so on.
But some of my fondest memories are in getting an operating system working on a bank-switched z80-based system. ;) Been there, not afraid of it. And yes, I like unbanked systems, too. Everything is good.
Jon
lower case is more readable because the letters are not all boxy-like- they have some bits wot go above the base line and some wot go above the others. The envelope of the word can be enough to allow it to be recognized.
Best regards, Spehro Pefhany
Take this, infidel!
.SBTTL IRQ6 SERVICE
; THE HITLOCK MECHANISM ENFORCES A MINIMUM IRQ-TO-IRQ DELAY SO THAT, IF A USER ; TRIGGERS US AT TOO HIGH A RATE, WE DON'T HOG ALL THE CYCLES FROM THE OPERATE SIDE.
; ON ENTRY, FAIM NAMES THE FRAME JUST FIRED ; FSTATE IS + LIVE, 0 DEAD, - DONE ; FOX IS OUR IRQ DOWN-COUNTER
; THE SETUP CODE PUSHES FRAMES FA AND FA+1 INTO THE FPGA, SO THE FIRST FRAME THAT WE ; UNLOAD IS ACTUALLY FA+2. WE DO THIS EVEN IF IT WILL NEVER BE USED.
; EXECUTION TIME = 38 USEC. ; EXPERIMENT HAS SHOWN THAT THIS ISN'T WORTH CACHING.
UVEC6: BSET.B # 0, PORTF.W ; === RAISE TIMING TP MOVEM.L D0 D1 D2 A0 A1 A2, -(SP) ; SAVE CONTEXT!
TST.W FSTATE.W ; CHECK FRAME MACHINE STATE BLE.S UVOFF ; IF DEAD OR DONE, SHUT DOWN.
SUBQ.W # 1, FOX.W ; TOCK IRQ COUNTER BPL.S UVRUN ; ANY LEFT? IF SO, LOAD ANOTHER FRAME
; FOX HAS DECREMENTED TO -1, SO SHUT DOWN THE SYSTEM...
MOVE.W # -1, FSTATE.W ; SET STATE = DONE BRA.S UVOFF ; AND SHUT DOWN.
; ON NEXT-TO-LAST IRQ, FOX IS ZERO, AND IN THAT CASE WE DON'T WANT TO ; AUTOMATICALLY RE-ARM THE HITLOCK TIMER AT THE NEXT IRQ.
UVRUN: SGT.B FDIE.W ; THAT DOES IT!
MOVE.W FAIM.W, D0 ; FETCH FRAME POINTER ADDQ.W # 1, D0 ; BUMP SAME AND.W FLAST.W, D0 ; MOD TABLE SIZE MOVE.W D0, FAIM.W ; AND REPLACE
ADDQ.W # 1, D0 ; LOAD NEXT FRESH FRAME INTO THE PIPELINE BSR.S FRAGG ; EVEN IF IT MAY NEVER BE USED (LIKE, 1 OR 2 SHOTS)
ST.B FIRQ.W ; ALLOW MORE IRQ6 THINGS BRA.S UVEX ; AND BAIL
; SHUT THINGS DOWN... THE HITLOCK IS STILL ACTIVE, AND WE HAVE NOT AUTHORIZED ANOTHER ; SHOT, SO TRIGGERS ARE DISABLED. THE USER MUST SAY "FRAME OFF" OR "FRAME GO" TO FIX THIS.
UVOFF: CLR.B FIRQ.W ; NO MORE INTERRUPTS!
UVEX: MOVEM.L (SP)+, D0 D1 D2 A0 A1 A2 BCLR.B # 0, PORTF.W ; === DROP TIMING TP === RTE
I just got that to work. I think.
John
I didn't realise that the dollar had fallen quite that far:
It took me ~4 hours from opening the package to finishing and understanding the lessons.
Of course, it will take a bit longer if you've never programmed asm before, but not 6 months. In fact, if it takes 6 days, you're probably not cut out for a technical hobby.
Hang on, I'll be back in bit with the code ;)
IF A USER
OPERATE SIDE.
FRAME THAT WE
PIPELINE
1 OR 2 SHOTS)AUTHORIZED ANOTHER
"FRAME GO" TO FIX THIS.
Here, I've 'fixed' it for you...
Cheers, James
~~~~~~~~~~~~~~~~~~~~~~
.SBTTL IRQ6 SERVICE
; The HITLOCK mechanism enforces a minimum irq-to-irq delay so ; that, if a user triggers us at too high a rate, we don't hog ; all the cycles from the operate side.
; On entry, FAIM names the frame just fired ; FSTATE is + LIVE, 0 DEAD, - DONE ; FOX is our IRQ down-counter
; The setup code pushes frames FA AND FA+1 into the FPGA, so the ; first frame that we unload is actually FA+2. We do this even ; if it will never be used.
; EXECUTION TIME = 38 uSEC. ; Experiment has shown that this isn't worth caching.
UVEC6: BSET.B # 0, PORTF.W ; === Raise timing TP MOVEM.L D0 D1 D2 A0 A1 A2, -(SP) ; Save context!
TST.W FSTATE.W ; Check frame machine state. BLE.S UVOFF ; IF DEAD or DONE, SHUT DOWN.
SUBQ.W # 1, FOX.W ; tock IRQ counter. BPL.S UVRUN ; Any left? IF so, load ; another frame.
; FOX has decremented to -1, so SHUT DOWN the system...
MOVE.W # -1, FSTATE.W ; Set STATE = DONE, BRA.S UVOFF ; and SHUT DOWN.
; On next-to-last IRQ, FOX is zero, and in that case we don't ; want to automatically re-arm the HITLOCK TIMER at the next ; IRQ.
UVRUN: SGT.B FDIE.W ; That does it!
MOVE.W FAIM.W, D0 ; Fetch frame pointer ADDQ.W # 1, D0 ; Bump same AND.W FLAST.W, D0 ; MOD TABLE SIZE, MOVE.W D0, FAIM.W ; and replace.
ADDQ.W # 1, D0 ; Load next fresh frame into ; the pipeline, BSR.S FRAGG ; even if it may never be used ; (like, 1 or 2 shots).
ST.B FIRQ.W ; allow more IRQ6 things, BRA.S UVEX ; and bail.
; Shut things down... the HITLOCK is still active, and we have ; not authorized another shot, so triggers are disabled. The ; user must say "FRAME OFF" or "FRAME GO" to fix this.
UVOFF: CLR.B FIRQ.W ; No more interrupts!
UVEX: MOVEM.L (SP)+, D0 D1 D2 A0 A1 A2 BCLR.B # 0, PORTF.W ; === Drop timing TP === RTE
Well, I got a bit sidetracked (by an phantom button press, which appears to be an artifact of RA3 being used both for the pushbutton and for programming), but the following works (admittedly, a 16F690 is overkill for this, but that's what's in the socket right now).
#include __config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
cblock 0x20 Mode Display Delay SwitchState Ready Delay1 Delay2 Delay3 endc
cblock 0x70 ; put these up in unbanked RAM W_Save STATUS_Save endc
org 0 goto Start nop nop nop
ISR: movwf W_Save movf STATUS,w movwf STATUS_Save
btfss INTCON,T0IF goto ExitISR
bcf INTCON,T0IF ; clear the interrupt flag. (must be done in software) decfsz Delay,f goto NotYet
bsf Ready,0 ; signal the main routine that the Timer has expired movlw 5 movwf Delay NotYet: clrf TMR0 ; Also clears the prescaler
ExitISR: movf STATUS_Save,w movwf STATUS swapf W_Save,f swapf W_Save,w retfie
Start: bsf STATUS,RP0 ; select Register Page 1 movlw 0xFF movwf TRISA ; Make PortA all input clrf TRISC ; Make PortC all output
movlw B'10000111' ; configure Prescaler on Timer0, max prescale (/256) movwf OPTION_REG
bcf STATUS,RP0 ; back to Register Page 0
movlw B'10100000' ; enable Timer 0 and global interrupts movwf INTCON
clrf PORTC clrf Display clrf SwitchState clrf Mode movlw 5 movwf Delay
clrf Delay1 clrf Delay2 movlw 2 movwf Delay3
DelayLoop: decfsz Delay1,f goto DelayLoop decfsz Delay2,f goto DelayLoop decfsz Delay3,f goto DelayLoop
MainLoop: btfsc SwitchState,0 goto CheckSwitchUp
CheckSwitchDown: btfsc PORTA,3 ; switch pressed (= low)? goto SwitchChecked
bsf SwitchState,0 ; mark as pressed
incf Mode,w ; next mode movwf Mode xorlw 3 btfsc STATUS,Z clrf Mode
goto SwitchChecked
CheckSwitchUp: btfsc PORTA,3 ; switch released (= high)? bcf SwitchState,0 ; mark as released
SwitchChecked: movf Mode,w btfsc STATUS,Z goto Mode0
xorlw 1 btfss STATUS,Z goto Mode2
Mode1: bsf PORTC,0 ; mode 1: turn on LED goto MainLoop
Mode0: bcf PORTC,0 ; mode 0: turn off LED goto MainLoop
Mode2: ; mode 2: flash LED btfss Ready,0 ; check for timer goto NoFlip comf Display,f clrf Ready
NoFlip: btfss Display,0 goto TurnOff
bsf PORTC,0 ; turn on LED goto MainLoop
TurnOff: bcf PORTC,0 ; turn off LED goto MainLoop
end
On a sunny day (Wed, 25 Feb 2009 14:38:34 -0800) it happened John Larkin wrote in :
Somebody who hates programming is not a programmer.
In article , To-Email- snipped-for-privacy@My-Web-Site.com says...>
A decent programming editor (e.g. Crimson) can do that in one step.
Hello,
the 555 timer (low power versions are now readily available too) is the classic way to do it precisely with few extra components, the uC
+MosFET is another interesting way, especially if you would like extra functionality and already have a uC programming setup. The direct extension of your initial method is a transistor to buffer the RC timing circuit and let you use a smaller capacitor, however the slow turn off problem will remain, and the component count is not less than the other two methods.In either case so *do not forget* the R/C/D snubber circuit (typcally about 100ohms in series with 100nF, plus a 1A diode in parallel or some resistor series combination) unless you are really certain that they can be omitted in this case. The snubber circuit will protect both your own circuit, and others. Inductive relay circuits often work on their own without them, however they are now substantial radio frequency generators and will can stop other circuits/devices from working when placed in proximity, even a device that is not introduced to the room until years later.
DH
Hello,
the 555 timer (low power versions are now readily available too) is the classic way to do it precisely with few extra components, the uC
+MosFET is another interesting way, especially if you would like extra functionality and already have a uC programming setup. The direct extension of your initial method is a transistor to buffer the RC timing circuit and let you use a smaller capacitor, however the slow turn off problem will remain, and the component count is not less than the other two methods.In either case *do not forget* the R/C/D snubber circuit (typically about 100ohms in series with 100nF, plus a 1A diode in parallel or some resistor series combination, as close to the relay coil as is practical) unless you are really certain that they can be omitted in this case.
The snubber circuit will protect both your own circuit, and others. Inductive relay circuits often work on their own without them, however they are now substantial radio frequency generators and can stop other circuits/devices from working when connected or placed in proximity, even a device that is not introduced to the room until years later.
DH
Hello,
the 555 timer (low power versions are now readily available too) is the classic way to do it precisely with few extra components, the uC
+MosFET is another interesting way, especially if you would like extra functionality and already have a uC programming setup.The direct extension of your initial method is a transistor to buffer the RC timing circuit and let you use a smaller capacitor, however the gradual turn off problem will remain, and the component count is not less than the other two methods. Relatively expensive and large timeout relays also exist with a dial to set the timeout period.
In either case *do not omit* the R/C/D snubber circuit (typically about 100ohms in series with 100nF, plus a 1A diode in parallel or some resistor series combination, as close to the relay coil as is practical) unless you are really certain that they can be omitted in this case.
The snubber circuit will protect both your own circuit, and others. Inductive relay circuits often work on their own without them, however they are now substantial radio frequency generators and can stop other circuits/devices from working when connected or placed in proximity, even a device that is not introduced to the room until years later.
I once made a waterpump circuit switched by a relay with an R/C/D snubber mounted beside the relay coil. This worked well until I introduced an accessory to the same control computer connected by the (supplied) unshielded ribbon cable. It took a while to figure out that the program was crashing because of RF feedback, even with the snubber circuit, to the computer accessory memory via the unshielded cable. Grounded tinfoil on the cable provided a complete temporary fix.
Three bathroom 2kW down-flow heaters have now experienced exactly the same early brownout failure in my house. An examination of the pull cord switch shows that a plastic pin in series with the the pivoting metal plate (showing substantial arcing) gradually melted, shortening each time, until the switch no longer worked. The AC inductive heater coil has no R/C, or R/C/D snubber circuit. I am replacing the pull cord switches with fused wall panel cooker switches (wall panel fuse plates are already present) and will add R/C (available as in single packages for power loads), or maybe even R/C + back-2-back zener diode snubber circuits considering the AC operation in this case.
DH
Have something to add? Share your thoughts — no account required.
Ask the community — no account required