Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help testing code and setting result in ADRESL

Status
Not open for further replies.

No1Daemon

New Member
Hi all

A member of this forum kindly wrote this code for me and now I need to test it. The original thread is here https://forum.allaboutcircuits.com/showthread.php?p=368578#post368578 and I consider it complete.
However it does not entirely function as I originally intended. I need to make sure I understand the flow of the data.

The complete code is at the end of the thread.
Originally I wanted to power the device on while holding swB and that would trigger the adc to read the voltage attached to the circuit which would be a variable power supply set to the desired low voltage and this would then be saved to EEPROM so if the device was powered on without the button held it would poll an2 for the voltage level all the time and switch off the relay when the value in EEPROM was reached.

Also as far as the switches I was going to set it up so swA incremented the timer by 5 minutes and as a result the single led would flash the corresponding number of times. and swB would be just a start button to initiate the timer function set by swA

The way I read the code it is now set up so that swA increments offtime and swB increments ontime but both seem to flash the led and I cannot see why that is necessary
swB also seems to only set a timer up to a minute and it turns off the relay however I am not sure of its purpose as the turn on codecovers activating the relay for the required time.

The way I originally intended it the psuedo code was
Is swB held while device powered on
if so do adc conversion and store result in EEPROM
if not read EEPROM for lvc setting and monitor voltage. Cutoff circuit below this value. Also read EEPROM for timer setting and led flashes and flash led to indicate timer setting.
if swA pressed increment timer by 5 minutes and flash led a number of times to represent the time interval set. Copy both timer setting and led flashes to EEPROM and save for future use next time device powered on.
if swA incremented past 6 go back to 1
if swB pressed then start 1 minute timer to allow moving device into water then start timer interval for relay afterwards
if swB held again turn device off

The way it has now been set up seems to be
Read EEPROM for flashes, time on and time off and put display results on led
If swA pressed increment flashes and use same value to increment timer and store in EEPROM then flash led corresponding number of times and debounce button
If swB pressed then setup 6 minute timer? and copy to EEPROM and then flash led again?

There seem to be a few issues as I see it
Can someone confirm, all the EEPROM locations read at the beggining seem to be the same address. How does the code differentiate between reading flashes, offtimer and on timer?
What is the purpose of the ontimer and how long is it set for?
I have built the circuit and tested it and it seems to increment the timer and flashes each time I power on and off.
If it does the adc conversion at the start of the code as it presently does then it will keep setting the current battery voltage as the low voltage cutoff point and never run the timer wont it?

I need to sort this out and also get help setting up the first low voltage cutoff setting. I have a dc power pack that outputs 8.9V so I was going to use that as the first setting point for the low voltage cutoff.

Any help with this would be appreciated.
 
Last edited:
Hi.

Your last link for your latest code is not accessable without logging on to that forum, also no sign of your circuit / sim diagram -can you post them here so we can see what you have done.

While your objective are reasonable, seems like you have run too fast into things, as mentioned in those early posts, you need to do things in small steps then stitch them together when you have proven and understood them.

At the moment you seem a bit overwhelmed with all the things going on, eeprom, ADC and Interrupt can be hard to take onboard.

Although you listed you objectives have you made a flow chart of how you will do all of that ? - try doing one, it give you a clear path to work from and it soon shows up any flaws in your logic
 
Hi.

At the moment you seem a bit overwhelmed with all the things going on, eeprom, ADC and Interrupt can be hard to take onboard.
You are correct. I meant to post this link here https://www.electro-tech-online.com/threads/too-many-timers.119508/#post982916 as you will see Colin took the ball and ran with it and wrote some almost completed code for me and I don't want to waste the effort so I am trying to see if the code still fits the purpose as I don't believe it is exactly what I wanted but may still work.
 
Last edited:
Hi,

Yes its a difficult one, as you don't want to waste that code.

Perhaps if you have the time, and with everything thats been thrown at you so far, now might be the right time to go back to the beginning and start with those simple flasher tutorials again , understanding each line of code properly and build things up for yourself.

Most folk go through a leanring curve where they become totally baffled by all the code example there are around and wonder how you will ever make sense of it - but it will suddenly all start falling into place and you will be wondering why you were struggling.

The folk who have been helping you are masters of the coding game so theres no shame if you cannot keep up with them.
 
Hi,

Perhaps if you have the time, and with everything thats been thrown at you so far, now might be the right time to go back to the beginning and start with those simple flasher tutorials again , understanding each line of code properly and build things up for yourself.

I am certainly not ashamed to admit I don't know everything, however I do understand completely most of the code.
I can see where he is moving a value into the various registers and then decrementing it and flashing the led accordingly.
I can understand how to set up the inputs and outputs and set them to digital or analog. Also how to do the a/d conversion and how to write to and read from EEPROM as I can see where the data is being moved to however the exact details of the way the code is written is eluding me.
I no doubt would have written the code far differently and it is much more compact and tidy the way he has written it.

As I said in my first post though if you look at this section
Code:
time_on
		movlw	1
		bsf		STATUS,RP0			
		movwf	EEADR									
		bsf		EECON1,0	;starts EEPROM read operation. Result in EEDATA						
		movf	EEDATA,w	;move read data into w
		bcf		STATUS,RP0
		movwf	on_time     ;will be 1-5
							;convert each value of "on_time" to 5 minutes
							;327mS x 16 x 58 = 5 minutes 
		swapf  	on_time,f	;rlf x 4 = 16 = swap nibbles	
		movlw   .58
		movwf	loops					
		bsf		GPIO,1		;turn on relay
        call    _327mS
        btfss	GPIO,5        ;test switchA
		goto	SwA_Pressed
		btfss	GPIO,4        ;test switchB
		goto	SwB_Pressed 
		decfsz  loops,f
		goto	$-6          
		decfsz  on_time,f
		goto	$-.11
		retlw   00
I cannot see what the purpose of on_time is. Mostly because it wasn't my idea I think so I do not understand the intent of it.
It doesn't appear to be the 1 minute timer before starting the off-time and activating the relay I was going for or is it?

Also if you do an a/d conversion right at the start of the main code how do you prevent the result being stored as the new low voltage cutoff section that I wanted to implement?
If the a/d is done each time then when you connect the 12v battery supply to the circuit then won't it set a new low voltage cutoff at 12v and therefore never function?
or is there a piece of code in there I am missing the point of?
Does it poll the voltage input pin constantly and reference it to an earlier set lower voltage point?
Code:
Main    	
    	call    time_on
		call    time_off
		
		bsf		ADCON0,GO		;GO = bit 1 = Start A/D conversion
 
    	btfsc	ADCON0,GO	
		goto	$-1			;Wait until A/D conversion is complete
 
		bsf		STATUS,RP0		;Switch to Bank1
		movf	ADRESL,W		;Move A/D conversion result to w
		bcf		STATUS,RP0		;Switch to Bank0
		movwf	A_Dvalue       ;save A/D value in A_Dvalue
		goto    Main
 
I would do this different I would set a constant for the adc value to turn on and one with turn off value. That solves the unknown if not like you said it will keep the new value which could be anything.

Next I would break this down to blocks of code

1.switch code if button pressed do this if not do that

2.storage code if called lets write the value and return

3.storage read code if called read the value and return

4. timer code set a preset timer that can be scaled

5 timer action code

6. control code that starts and stops the relay

Then put the calls in a loop and let the chip run.
 
Last edited:
Hi,

What does everyone use to write their flowcharts?

Well I still use pen and paper, you can doodle with it anywhere, I don't carry a notebook around with me.
As you can see here there are many pc programs around if you must.
https://en.wikipedia.org/wiki/Flowchart

You can do a couple of charts, first take your description and break that down into blocks, then you can even chart each block down to a much more detailed logic flow - its surprising how you soon you see the catches in doing things certain ways before you even start coding.

As you can see from be80be's post, you can almost create a flow chart by just putting boxes around his clear description entries.


Re the points about the code, think you have a classic example of how difficult it can be to follow someone elses logic flow.
This is why I was suggesting you perhaps go back and create you own program now that you know a lot more than you did when you first started. you could start with a much simpler version adding in things like the adc voltage check at a later stage , so keeping the code simple.


Out of interest can you posy your full latest code, I was looking at this version which seems a lot different to what you have just posted.
Code:
;************************
;* Main                 *
;************************

main        
        call    time_on
        call    time_off
        goto    main
                
;*

Also have not yet totally followed your original logic flow, just wondered why you need to use eeprom in the first place.
 
Code

Sorry here is the latest version

View attachment SimpleTimer-2.asm.txt

The reason for reading and writing to EEPROM is because the batteries will be regularly disconnected from the circuit to recharge and I do not want to have to re set the timer every time the circuit is reconnected so if the settings are saved to EEPROM then it can simply be plugged in again and then push the start button and it can be sent out to sea.
 
1.switch code if button pressed do this if not do that
Alright lets do that then. The first section would be if Switch A which is GP4 is pressed advance timer and w by 5 mins and flash led the number of the value in w up to 6. ie if Switch A pressed 5 times then 5x5 equals 25 minutes, set timer for 25 minutes and flash led on GP0 5 times to represent 25 minutes. If w goes above 6 then reset to 1.
Then there would be if Switch B on GP5 pressed start a 1 minute timer to allow time to get Kontiki into the water then activate the relay on GP1 for the number of minutes set and light led steady.
If Switch B held for 2 seconds then set low voltage cutoff setting according to voltage connected to AN2 by doing adc.
That is all for the switch code so I think the code should be something like the following.
I am not 100% sure of the button held code.
Code:
;****************************************************
;SimpleTimer.asm                                     *
;
;14-6-2011                                          *
;****************************************************
;
	list	p=12F683
	radix	dec
	include	"p12f683.inc"
	
		errorlevel	-224	; Don't complain about tris
		errorlevel	-302	; Don't complain about BANK 1 Registers


	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin 

;****************************************************************
; variables - names and files
;****************************************************************
temp1		equ 20h	;
temp2		equ	21h	; 
pushes		equ	22h	
flashes		equ	23h
on_time     equ 24h
off_time    equ 25h
minutes     equ 26h
loops       equ 27h
A_Dvalue    equ 28h
delA		equ	29h
delB		equ	30h
countdown	equ	31h
count		equ	32h
count2		equ	33h

;****************************************************************
;Equates
;****************************************************************
status		equ	0x03
rp1			equ	0x06
rp0			equ	0x05
option_reg	equ 81h
;****************************************************************
;Beginning of program
;****************************************************************
		org		0x00		
		nop
		nop
		nop
		nop
		nop
SetUp	bsf		STATUS, RP0 	;Bank 1			
       	movlw	b'11111100'		;Set TRIS  GP0,1 out   GP2(AN2), 3,4,5 input
;****************************
;* Sub Routines 			*
;****************************
			
SwA_Pressed
		
		incf	flashes,f			
		movlw   07
		xorwf   flashes,w     ;if flashes=7
		btfss   STATUS,Z  ;z=1 if flashes=7
		goto    $+3
		clrf    flashes
		goto    $-6
			    
		;flash LED 1-6 times
		
 		movf	flashes,w
		movwf	temp1     ;save flashes in temp1 for decrementing
		bsf		GPIO,0   ;turn on LED	
		call    _327mS
		bcf		GPIO,0   ;turn off LED	
		call    _327mS
		decfsz  temp1,f
		goto	$-5		
		btfss	GPIO,5	;loop until SwA is released
		goto	$-1
		retlw	00
		
time_on
		movlw	1
		bsf		STATUS,RP0			
		movwf	EEADR									
		bsf		EECON1,0	;starts EEPROM read operation. Result in EEDATA						
		movf	EEDATA,w	;move read data into w
		bcf		STATUS,RP0
		movwf	on_time     ;will be 1-5
							;convert each value of "on_time" to 5 minutes
							;327mS x 16 x 58 = 5 minutes 
		swapf  	on_time,f	;rlf x 4 = 16 = swap nibbles	
		movlw   .58
		movwf	loops
		
SwB_Pressed					
		bsf		GPIO,1		;turn on relay
        call    _327mS
        btfss	GPIO,5        ;test switchA
		goto	SwA_Pressed
		btfss	GPIO,4        ;test switchB
		goto	SwB_Pressed 
		decfsz  loops,f
		goto	$-6          
		decfsz  on_time,f
		goto	$-.09
		retlw   00
		
;********************
;* Delays 			*
;********************

_50uS  movlw   .15
       movwf   delA
       decfsz 	delA,f
	   goto 	$-1
	   retlw 	00


_327mS	goto	$+1
		decfsz 	delA,f
		goto 	$-2
		decfsz 	delB,f
		goto 	$-4	
		retlw 	00		
		
delay20ms				;19693 cycles
		movlw	0x61
		movwf	count
		movlw	0x10
		movwf	count2
		retlw	00
		
		movlw	d'100'
		movwf	countdown
		
testSwitchA					;see if Switch A held for 2 seconds
		call 	delay20ms	;debounce
		btfsc	GPIO,4
		goto	SwA_Pressed	;normal press
		decfsz	countdown,f
		goto	testSwitchA
		
testSwitchA2				;has been pressed for 2 seconds
		btfss 	GPIO,4
		goto	testSwitchA2;wait for release
			bsf		ADCON0,GO		;GO = bit 1 = Start A/D conversion
 
    	btfsc	ADCON0,GO	
		goto	$-1			;Wait until A/D conversion is complete
 
		bsf		STATUS,RP0		;Switch to Bank1
		movf	ADRESL,W		;Move A/D conversion result to w
		bcf		STATUS,RP0		;Switch to Bank0
		movwf	A_Dvalue       ;save A/D value in A_Dvalue
		goto    Main
		

;************************
;* Main 				*
;************************

Main    			

;************************
;*EEPROM     	    	*
;************************
								
		org		2100h			
		de      1,  2, 3		;1=flashes   2=time_on   3=time _off	
							
		END
 
I have had a rethink

I started doing my code again
I want to add this code which makes the switch multitasking and allows a long press to trigger another function

Here is the code I have added
Firstly this is the mSecDelays4MHz that is linked to the main asm file

Code:
StartDelayCount movwf WaitCounter2		;1    

BackWaitLoop2   movlw d'163'			;1
                call WaitWx4Cycles
				movlw d'163'			;1
                call WaitWx4Cycles
				nop
				nop
                decf WaitCounter2,f		;1
                btfss Zero				;1
                goto BackWaitLoop2		;2
                return					;2

WaitWx4Cycles   movwf WaitCounter
BackWaitLoop    decfsz WaitCounter,f
                goto BackWaitLoop
                return

Wait1mSec       movlw d'1'
                goto StartDelayCount
Wait2mSec       movlw d'2'
                goto StartDelayCount
Wait4mSec       movlw d'4'
                goto StartDelayCount
Wait10mSec      movlw d'10'
                goto StartDelayCount
Wait100mSec      movlw d'100'
                goto StartDelayCount
Wait250mSec     movlw d'250'
                goto StartDelayCount

Wait500mSec     call Wait250mSec
                goto Wait250mSec

Wait1Sec		call Wait250mSec
				call Wait250mSec
				call Wait250mSec
				goto Wait250mSec

And this is the new code I have plagerised to try to add the press and hold function to my code
Code:
;****************************************************
;SimpleTimer.asm                                     *
;
;14-6-2011                                          *
;****************************************************
;
	list	p=12F683
	radix	dec
	include	"p12f683.inc"

	errorlevel -224		; Don't complain about tris
	errorlevel -302    	; switches off Message [302]: Register in operand not in bank 0.

	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin 

;****************************************************************
; variables - names and files
;****************************************************************
temp1				equ 20h	;
temp2				equ	21h	; 
pushes				equ	22h	
flashes				equ	23h
on_time     		equ 24h
off_time    		equ 25h
minutes     		equ 26h
loops       		equ 27h
A_Dvalue    		equ 28h
delA				equ	29h
delB				equ	30h

; Definitions -------------------------------------------------------------
#Define	ButtonInput			GPIO,4
#Define	LngClickOutput		GPIO,4
option_reg		equ		81h

; RAM preserved -----------------------------------------------------------
	cblock 0x20
		WaitCounter,WaitCounter2
		IntervalCounter
	endc

; Conastants --------------------------------------------------------------
GLLongClick_Interval	=	d'80'	;mSec x 10

;****************************************************************
;Equates
;****************************************************************

status		equ	0x03
rp1			equ	0x06
rp0			equ	0x05


status		equ	03h
option_reg	equ 81h


		
		;bits
				
rp0		equ	5			;bit 5 of the status register

; -------------------------------------------------------------------------
; Microcontroller initialization
init            
				include init_normal.inc	;Include the PIC Initialization routine

MainLoop
		bcf LngClickOutput
		btfss ButtonInput
		goto MainLoop
				
			
CheckForLongClick
		call Wait10mSec
		btfss ButtonInput		;Check if it is a long click
		goto NoLongClick
		decfsz IntervalCounter,f
		goto CheckForLongClick

				;It WAS a long click
		goto Run_Long_Click

NoLongClick								;It was NOT a long click
		goto Run_Single_Click			;Then it was a single click.

Run_Single_Click
		bsf ButtonInput
		call Wait1Sec
		bcf ButtonInput
		goto WaitForKeyReleaseBeforeReturn

Run_Long_Click
		bsf LngClickOutput
		call Wait1Sec
		bcf LngClickOutput
;				goto WaitForKeyReleaseBeforeReturn	;This instrruction is not really nesecary here!

WaitForKeyReleaseBeforeReturn
		call Wait4mSec
		btfsc ButtonInput
		goto WaitForKeyReleaseBeforeReturn
		call Wait10mSec
		goto MainLoop

		include mSecDelays4MHz.inc

		 end             ; end of program
I intend to have a short press of Switch A increment my timer by 5 minutes and flash the led and a short press of Switch B starts a 1 minute timer then activates my relay for the timer period set by Switch A
A long press of nearly a second enters the low voltage cutoff setting and records the voltage input to the adc as the new low voltage cutoff point.
The code doesn't seem to work though. When I use Stimulus and fire GP4 which is Switch A it goes into the mSecDelays4MHz page and gets stuck in a loop at backwait counter.
Also, The rest of my code is ay 8mhz I believe so how can I alter the code for my oscillator settings?
Thanks
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top