Last edited by Archangel; - 8th May 2009 at 09:35.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
FYI, there's a new DEFINE for that
Code:DEFINE WRITE_INT 1
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
This code;
With the schematic attached - works. It writes 15 to EEPROM after preciselyCode:@ device pic16F690, intrc_osc_noclkout, wdt_off, mclr_off, protect_off K CON 15 ' Calibration factor for flow meter = # pulses per gal ' Setup Timer0 as an 8-bit counter with the clock input on RA2. ' 1:1 TMR0 prescaler ' TMR0 counts on high-to-low transitions OPTION_REG = %00111000 ' A/D & Comparators disabled ANSEL=0 ' all digital ANSELH=0 ' analog module disabled CM1CON0=0 CM2CON0=0 ' Port setup PORTC = 0 ' LEDs off, PULSOUT RC3 provides a high-going pulse PORTA = 0 TRISC = %11110000 ' lower 4 pins outputs TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs TMR0 = 0 ' clear TMR0 count Main: IF TMR0 < K THEN ' Keep the valve open...do nothing..let water flow ELSE PULSOUT PORTC.3,1000 ' Generate required 10 msec pulse to RC3 WRITE 7, TMR0 ' write count if you need to? TMR0 = 0 ' clear TMR0 count HIGH PORTC.0 ' LED toggle stuff PAUSE 500 LOW PORTC.0 ENDIF GOTO Main END
15 press/release actions on the switch.
Tested on the PICkit 2 low pin count demo board.
The cap on RA3 is 0.01uF, which helps eliminate contact bounce from the switch.
The switch on the PICkit 2 demo board connects to RA3, so a wire runs directly from
RA3 to RA2. Remove the cap, and switch bounce causes problems. It's a really simple
fix.
If your circuit is powered from 5V, and you measure 5V between the PIC VDD/VSS pins,
and you only see 3.2V on RA2 with a pull-up to VDD, then check your circuit. There's a
problem somewhere with your wiring or connections.
I don't see this DEFINE listed in Appendix B of the PICBASIC PRO manual, which supposedly lists all DEFINEs.
Can you explain how you would use this to replace the code statements Joe lists to mask interrupts while writing? Do you just precede the WRITE statement with DEFINE WRITE_INT1? After the WRITE, do you still have to re-enable the interrupt? I guess if you have to do all this, I don't see how it is any more efficient than using Joe's 4 statements.
If DEFINE WRITE_INT isn't in your manual, then you probably have an older version of PBP
or an old manual before this new define option was added.
Newer versions of PBP include a check for this in the WRITE library. If you have DEFINE
WRITE_INT 1 declared, it automatically disables interrupts before the write, and re-enables
interrupts immediately after the write is complete.
It just saves you from having to remember to do it yourself.
PROBLEM SOLVED ON THIS THREAD.
Thanks, Bruce, for clarification on DEFINE. I will use this in all future programs where I have write statements.
Joe S., the 0.01 uF capacitor definitely solved my switch bounce problem. The code now works perfectly and always counts exactly 15 pulses when it activates the external pulse to the valve solenoid.
Your guys are stupendous! I learned more in the interchanges during this thread about programming PIC MCUs than I have learned in weeks reading different sources.
Thanks again and keep up the good work!
That should save someone some brain damage. Where did you learn that? Das Book ?
Credit to where credit is due . . . BRUCE . . . always on target.Joe S., the 0.01 uF capacitor definitely solved my switch bounce problem. The code now works perfectly and always counts exactly 15 pulses when it activates the external pulse to the valve solenoid.Maybe not more efficient, but way easier.After the WRITE, do you still have to re-enable the interrupt? I guess if you have to do all this, I don't see how it is any more efficient than using Joe's 4 statements.
Last edited by Archangel; - 8th May 2009 at 19:17.
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
I thought I had this problem licked. Then I purchased PCB PRO and tried to run the same code that ran in PCB. I get all an "Overwriting prrevious address contents" assembly error and many "Symbol not previously defined erros" as related to the ANSEL, ANSELH, CM1CON and CM2CON statements as shown in the attached image. These errors sort of sound like a problem with the CONFIG statement not being commented out in the .inc file. I did make sure I commented out the @ __device statement in the 16F690.incl file that came with PCB PRO so it isn't overwritten by the !__config statement in the code.
Can't figure thwhy this code now won't assemble. Can any of you advise me why my code would run in PCB and won't assemble in PCB PRO??
Here is the current code as adapted from Bruce's "Non-Interrupt version" in his above post.
Code:@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF i var Byte ' Indexer for use in For..Next loop K CON 15 ' Calibration factor for flow meter = # pulses per gal ' Setup Timer0 as an 8-bit counter with the clock input on RA2. ' 1:1 TMR0 prescaler ' TMR0 counts on high-to-low transitions OPTION_REG = %00111000 ' A/D & Comparators disabled ANSEL=0 ' all digital ANSELH=0 ' analog module disabled CM1CON0=0 CM2CON0=0 ' Port setup PORTA = 0 ' Clear the port register latches PORTB = 0 PORTC = 0 ' LEDs off, PULSOUT RC3 provides a high-going pulse ' Set or clear the data direction registers TRISA = %11111111 ' RA2 = TMR0 clock input for simulated meter pulse inputs TRISB = %11111111 TRISC = %11110000 ' lower 4 pins outputs 'VRCON = %00000000 ' turns the Vref Module OFF by clearing bit 7, 6, 4 TMR0 = 0 ' clear TMR0 count Main: IF TMR0 < K THEN ' Keep the valve open...do nothing..let water flow ELSE PULSOUT PORTC.3,1000 ' Generate required 10 msec pulse to RC3..close valve DEFINE WRITE_INT 1 WRITE 7, TMR0 ' write count if you need to during testing TMR0 = 0 ' Clear timer count For i = 1 to 3 ' Blink LED 3x to indicate valve turned off HIGH PORTC.0 PAUSE 500 LOW PORTC.0 Next ENDIF GOTO Main ' Loop to Main to wait for next meter flow input
The first error indicates you have not commented out the __config line if the 16F690.INC
file that's used with the MPASM assembler. Make sure you do before compiling if you insert
the MPASM @ __config directive in your code.
The remaining errors indicate it's not finding the Microchip P16F690.INC file, which defines
register locations/names.
Make sure your path statement includes information on where you have MPLAB installed, or
modify the 16F690.INC file to point directly to it.
INCLUDE "C:\Program Files\Microchip\MPASM Suite\P16F690.INC"
I guess when I upgraded to PB Pro and installed it, MPLAB must have ended up in a different place. Thanks for catching this...I could have spent a long time looking and not thinking of this.
Now I have a different problem. Although I was going to try to do the counting with a NonInterrupt version of using the TMR0 overflow counter as you described above, I discovered as I progressed on my app design that I really need to do the counting with an interrupt and also another interrupt for checking on an external switch closure. I therefore am trying to use the below code where I have the interrupt handler doing two IF..THEN checks of the flag bits to handle either the TMR0 overflow while using RA2 input to TMR0 as switch for counting, or the RABIE on-change-interrupt for the RA3 input from a switch closure to ground. The TMR0 interrupt works in this code, however, the RABIE on-change-interrupt does not. I can't figure out why. Can you see whay the RABIE isn't working??
Code:' -----[ Device Declaration ]---------------------------------------------- ' @ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _CP_OFF ' -----[ Variables & Aliases Intitialization ]----------------------------- ' led1 VAR PORTC.0 ' Set RC0 as LED indicator of valve open..water flowing led2 VAR PORTC.1 ' Set RC1 as LED indicator of low battery valve VAR PORTC.3 ' Set RC3 as valve solenoid open/close command low_bat VAR PortA.0 ' Set RA0 as battery low power monitor meter VAR PORTA.2 ' Set RA2 as input for Hall Sensor meter pulse Interrupt flush VAR PORTA.3 ' Set RA3 as input for sensing flush switch closure Int bat_mon VAR Byte ' bat_mon value when Vtrh multiplied by low_bat ' -----[ Constants Initialization ]---------------------------------------- ' k CON 10 ' Calibration factor for flow meter...# pulses per gal i VAR Byte ' Index used in Gallon counter loop Vthr CON 4 ' Low Battery Monitor threshold ' -----[ Initialization ]-------------------------------------------------- ' 'EEPROM PRESETS 'DATA @0,0 'OSC DEFINE 'DEFINE OSC 4 ' Setup Timer0 as an 8-bit counter with the clock input on RA2. ' 1:1 TMR0 prescaler ' TMR0 counts on high-to-low transitions OPTION_REG = %00111000 'Register Settings Init: TRISA = %11111111 ' Set all PORTA pins to inputs...RA0, RA2 & RA3 are used TRISB = %00000000 ' Set all PORTB and PORTC pins to outputs TRISC = %00000000 PORTC = %00000000 ' Pre-set PORTC pins low, turning LEDs off TMR0 = 256-K ' Preload TMR0 to overflow after k counts 'A/D & Comparators disabled ADCON0 = %01110000 ' Set PORTA to digital I/O & FRC (clock derived from a ADCON1 = %00000000 ' dedicated internal oscillator) ANSEL=0 ' Set PortA to digital I/O ANSELH=0 ' Analog module disabled CM1CON0=0 CM2CON0=0 TRISC.3 = 0 ' Set RC3 as output port for valve latching solenoid control Low Valve ' Initialize RC3 (valve) at Low value TRISA.2 = 1 ' Set RA2 as input port for clock to TMR0 TRISA.3 = 1 ' Set RA3 as input port for sensing METER switch closure High meter ' Initialize RA2 (meter) at High value for METER pulse inputs ' RA2 = TMR0 clock input for simulated meter pulse inputs High flush ' Initialize RA3 (flush) at High value for flush interrupt 'Interrupts Settings FLUSH_INT_FLAG VAR INTCON.0 ' RA3 (FLUSH) On-change-interrupt flag bit TMRO_INT_FLAG VAR INTCON.2 ' Timer0 overflow flag bit INTCON = %10101000 ' Enable global, TMR0 & RABIE (RA3 on-change-INT) IOCA = %00000000 ' Enable RA3 as on-change-INT ' -----[ Main Code ]------------------------------------------------------- 'Set INT Handler ON INTERRUPT GOTO Int_handler 'Start...normal code here MAIN: PORTC = %00000000 ' Turn all LEDs off PAUSE 1 'SLEEP = 65,535 ' Put MC in Sleep state at power up ' Microcontroller is in Sleep State waiting for external FLUSH Interrupt GOTO Main ' Loop to Main to wait for next Flush interrupt DISABLE Int_handler: IF FLUSH_INT_FLAG = 1 Then ' Interrupt was from RA3 on change DEFINE WRITE_INT 1 write 9, flush ' Write RA3 (FLUSH) value during testing PULSOUT valve,1000 ' Generate required 10 msec pulse to RC3 to open valve High led1 ' Light indicator that valve is open & water flowing Low low_bat ' Simulate battery monitor input is low 'Put code here to Wakeup the Microcontroller ' Put code here to start a timer to run for 50 secs as a fail safe ' to prevent overflow of toilet tank in case of sensor failure. 'Goto Shutvalve High flush ' Clear the interrupt FLUSH_INT_FLAG = 0 ' Clear interrupt flag Endif IF TMRO_INT_FLAG = 1 then ' Interrupt was a TMR0 overflow..volume reached PULSOUT valve,6000 ' Generate required 20 msec pulse to RC3..close valve WRITE 5, TMR0 ' Write TMR0 value..remove comment for test only bat_mon = low_bat * Vthr Write 7, bat_mon ' Remove comment for test only If bat_mon < Vthr Then 'Light the low battery monitor light HIGH led2 ENDIF TMR0 = 256-k ' Reload TMR0 to overflow after k counts TMRO_INT_FLAG = 0 ' Clear overflow flag ENDIF LOW led1 Low led2 RESUME ENABLE ' If the user program ends by getting to the last statement of the program ' at an END instruction, the MCU will SLEEP and await a wakeup. END
I discovered one of DT's posts that explained part of my problem was that I wasn't properly clearing the mismatch. When I did that the On-interrupt for RA3 worked. However, I noticed in the same DT post his statement "Keep in mind that you will get an interrupt on both the Press and Release of the button. You will eventually need to change the interrupt handler to determine which Edge occurred." I am using a momentary switch button that grounds RA3 for this On-interrupt and now I see happening what he was warning about...I get an intterupt on press AND release. However, I don't quite grasp how to modify my interrupt handler "to determine which Edge occurred." Obviously I want the interrupt to respond only to the press and not the release. Is there a way to filter out the release action to prevent the 2nd interrupt?
Bookmarks