Interrupt to non volatile memory

marzan

Senior Member
#1
Hello. Can anyone tell me if I am on the right track here. I saw a post from a few years back by Jeremy Harris. He talked about being able to detect the high side of a voltage regulator to see if the power has been switched off. The pin it is polling is c.2 on a 14M2. what I am trying to do is store in memory the WORD value of the position of a stepper motor before the power dies In the circuit. I have a diode on the 12V side of the regulator with a large Cap between it and the VREG, and another large Cap on the 5v side, so the on LED stays lit for a second or so. C.2 is connected on the power side of the diode with a voltage divider. Is this code correct, or have I not understood something? (wouldn't surprise me!)
Code:
SYMBOL PULSECOUNT = W1
SETINT %00000000,%00000100

Interrupt:
               WRITE 255, WORD PULSECOUNT
               END
Thanks for looking.
Marz
 

PhilHornby

Senior Member
#2
With a working assumption that your real code doesn't just drop through to 'Interrupt' on start up :)

If the intention is to store the value of W1 in the top 2 bytes of EEPROM, then the location used should be 254, not 255. (255 will try and use 255 and 256; the latter doesn't exist - so (presumably) would write to 255 and 0 instead)
 
Last edited:

marzan

Senior Member
#4
With a working assumption that your real code doesn't just drop through to 'Interrupt' on start up :)

If the intention is to store the value of W1 in the top 2 bytes of EEPROM, then the location used should be 254, not 255. (255 will try and use 255 and 256; the latter doesn't exist - so (presumably) would write to 255 and 0 instead)
@PhilHornby Thanks for the heads up. That will save me a lot of head scratching!
 

marzan

Senior Member
#5
I have started to write some code. I don`t think space is a problem, but if anyone sees a better way of getting it done that would be great.
Here is the code:
Code:
SYMBOL pulseactual = W1
symbol heightto = b3
symbol pulseto = W3
symbol pulsemove = w4
symbol direction = c.1
symbol steppulse = c.2
symbol voltcheck = c.3
symbol enabl = c.4
wait 1

READ 254, WORD pulseactual     ;load previous position befoe shutdown  
SETINT %00000000,%00000100    ;set interrupt to write to memory the position of the stepper if the power shuts down

main:
high enabl
serin c.0, n2400, ("abc"),heightto   ;recieve position info from wireless remote
select case heightto     ;set position to move to
 case 1 pulseto = 100
 case 2 pulseto = 1100
 case 3 pulseto = 2100
 case 4 pulseto = 3100
 case 5 pulseto = 4100
 else goto main
Endselect
if pulseto = pulseactual then goto main      ;decide to go up or down
if pulseto > pulseactual then goto Go_down
if pulseto < pulseactual then goto go_up

goto main
go_down:
high direction      
pulsemove = pulseactual - pulseto   ;decide how far to move
low enabl
pause 50
for w5 = 1 to pulsemove     ;move to new position
 pulsout steppulse, 2
 dec pulseactual     ;keep track of position
 pauseus 5
next
goto main

go_up:
low c.1
pulsemove = pulseto - pulseactual   ;decide how far to move
low enabl
pause 50
for w5 = 1 to pulsemove     ;move to new position  
 pulsout steppulse, 2
 inc pulseactual     ;keep track of position
 pauseus 5
 next
goto main       ;go back and wait for new height
return
interrupt:
     
               WRITE 254, WORD pulseactual
     high b.3
               END
Thanks.
Marz
 

Aries

New Member
#6
A couple of thoughts:

(1) The return at the end of the main program is incorrect. As it follows a goto, it can never be reached. If you want to be sure you never "fall through", use "end" at this point. You should never have a return without a gosub.

(2) As has already been suggested, the interrupt routine might be triggered by a temporary condition, and the Picaxce might not actually stop. In that case, you probably want to exit the interrupt routine as though nothing had happened. So:
(a) put a return at the end of the interrupt routine
(b) put another SETINT within the routine, so that a future power failure is still picked up.
 

marzan

Senior Member
#7
A couple of thoughts:

(1) The return at the end of the main program is incorrect. As it follows a goto, it can never be reached. If you want to be sure you never "fall through", use "end" at this point. You should never have a return without a gosub.

(2) As has already been suggested, the interrupt routine might be triggered by a temporary condition, and the Picaxce might not actually stop. In that case, you probably want to exit the interrupt routine as though nothing had happened. So:
(a) put a return at the end of the interrupt routine
(b) put another SETINT within the routine, so that a future power failure is still picked up.
Thanks @Aries. The return was a typo, I just forgot to take I out, and I did forget about resetting the interrupt in case of a fluctuation. I am going to run a test with the interrupt to see if it does trigger prematurely. hopefully I will have a prototype board sorted out today.
Marz.
 

marzan

Senior Member
#8
Well I have working code :D

Code:
SYMBOL pulse_actual = W0
symbol height_to = b3
symbol pulse_to = W3
symbol pulsemove = w4

symbol fault = b.3
symbol direction = c.1
symbol step_pulse = c.2
symbol voltcheck = c.3
symbol enabl = c.4

setfreq M16
;SETINT %00000000,%00000100                ;set interrupt to write to memory the position of the stepper if the power shuts down

main:
high enabl
serin b.1, n2400_16,("abc"),height_to        ;recieve position info from wireless remote

high fault                           ;signal recieved check
pause 500
low fault

select case height_to                    ;set position to move to
    case 1 pulse_to = 500
    case 2 pulse_to = 1000
    case 3 pulse_to = 1500
    case 4 pulse_to = 2000
    case 5 pulse_to = 2500
    else goto main
Endselect

if pulse_to = pulse_actual then goto main         ;decide to go up or down
if pulse_to > pulse_actual then goto Go_up

;go_down:
high direction
pause 50                        
pulsemove =  pulse_actual - pulse_to        ;decide how far to move
debug
low enabl
pause 50
for w5 = 1 to pulsemove                 ;move to new position
    pulsout step_pulse,1
    dec pulse_actual                   ;keep track of position
    pauseus 10
next
debug  
goto main


go_up:
low direction
pause 50
pulsemove = pulse_to - pulse_actual          ;decide how far to move
low enabl
pause 50
for w5 = 1 to pulsemove                 ;move to new position      
    pulsout step_pulse,1
    inc pulse_actual                   ;keep track of position
    pauseus 10
next
debug
goto main                           ;go back and wait for new height


       

;interrupt:
           
               WRITE 254, W0
           high b.4
               RETURN
I want to change the serin to hserin to see if that makes it more reliable. For an X2 part it says : HSERIN spaddress, count {,(qualifier)}
For an M2 part it says : HSERIN var
There is no mention that I can see for a qualifier with the M2 part. Is that correct?
I understand I have to put in hsersetup beforehand.
Thanks.
Marz.
 

lbenson

Senior Member
#9
There is no qualifier with HSERIN on the M2. You would have to build it byte by byte and compare. What are you finding to be unreliable about SERIN with qualifier?

I'm not sure how this is "working code" when the interrupt routine label is a comment, there's no checking in the interrupt routine to make sure that power before the regulator really has dropped out, and no resetting of the interrupt, so that it's possible that if there was a power glitch, the chip would RETURN and continue, and with no interrupt enabled, subsequently die without saving values which have been received in the meantime.
 

AllyCat

Senior Member
#10
Hi,

I want to change the serin to hserin to see if that makes it more reliable .
Unless you understand exactly how to use HSERIN (with an M2), it won't.

No, there is no qualifier because the M2s have only a two-byte input buffer with no "intelligence". Also, it only accepts "TTL" (idle-high) "P" polarity serial data but you appear to be using idle-low (N).

Qualifiers and the like will very probably require an(other) interrupt structure and in my experience (there is quite a long thread on the topic for an 08M2) it may be better to use direct PEEKSFRs of the HSERIN hardware than the HSERIN command itself.

Cheers, Alan.
 
Last edited:

marzan

Senior Member
#11
Sounds like I will just have to use the normal serin then. I need the qualifier because there could be more than one of these systems in a small space. It was worth a shot
There is no qualifier with HSERIN on the M2. You would have to build it byte by byte and compare. What are you finding to be unreliable about SERIN with qualifier?

I'm not sure how this is "working code" when the interrupt routine label is a comment, there's no checking in the interrupt routine to make sure that power before the regulator really has dropped out, and no resetting of the interrupt, so that it's possible that if there was a power glitch, the chip would RETURN and continue, and with no interrupt enabled, subsequently die without saving values which have been received in the meantime.
@alan it is working except for the rem`d out interrupt which I think still needs work on the hardware end. With just a voltage divider I think it fluctuates too much. I think maybe a circuit on the voltage supply side with a Zener diode might be a bit more stable, or even a small separate VREG without the big caps to give me 5 volts on the pin.
As for what I want it to do when the buttons are pressed, it works as expected. enhancements can happen afterwards. At this stage I have a prototype board, so now I need the get the mechanical side built.
Marz.
 
#12
Sounds like I will just have to use the normal serin then. I need the qualifier because there could be more than one of these systems in a small space. It was worth a shot

@alan it is working except for the rem`d out interrupt which I think still needs work on the hardware end. With just a voltage divider I think it fluctuates too much. I think maybe a circuit on the voltage supply side with a Zener diode might be a bit more stable, or even a small separate VREG without the big caps to give me 5 volts on the pin.
As for what I want it to do when the buttons are pressed, it works as expected. enhancements can happen afterwards. At this stage I have a prototype board, so now I need the get the mechanical side built.
Marz.
You may just need a suitably sized capacitor at the ADC pin, after the voltage divider. Something like 100n should calm the power supply noise.
 

PhilHornby

Senior Member
#14
You may just need a suitably sized capacitor at the ADC pin, after the voltage divider.
ADC Pin? - I thought we just relying on detection of a logic 0 @ C.2 ?
I`ll try that first.
Out of curiousity, what are the resistor values for your 'divider'?

Obviously, they must never produce more than 5V, with a 12V input - but the closer the voltage to logic '0', the more responsive/prone to false triggering the circuit will become. You can probably change the logic '0' voltage somewhat by setting the Pin C.2 to be a Schmitt input, rather than TTL.

I say probably, because Schmitt inputs didn't behave the way I expected, when I experimented with them...
See: https://picaxeforum.co.uk/threads/schmitt-trigger-characteristics-of-pin-c-2-on-picaxe-08m2.28395/
(C.2 is always a Schmitt input on 08M2 ... you can choose on 14M2)
 

marzan

Senior Member
#15
ADC Pin? - I thought we just relying on detection of a logic 0 @ C.2 ?

Out of curiousity, what are the resistor values for your 'divider'?

Obviously, they must never produce more than 5V, with a 12V input - but the closer the voltage to logic '0', the more responsive/prone to false triggering the circuit will become. You can probably change the logic '0' voltage somewhat by setting the Pin C.2 to be a Schmitt input, rather than TTL.

I say probably, because Schmitt inputs didn't behave the way I expected, when I experimented with them...
See: https://picaxeforum.co.uk/threads/schmitt-trigger-characteristics-of-pin-c-2-on-picaxe-08m2.28395/
(C.2 is always a Schmitt input on 08M2 ... you can choose on 14M2)
22K high side, 10K low side gives me 4.7V on the pin. I will try the cap when I get a chance.
Marz.
 

AllyCat

Senior Member
#16
Hi,
22K high side, 10K low side gives me 4.7V on the pin.
IMHO that's too high. The Microchip data sheet tells us that the "TTL" digital threshold voltage is between 0.8 and 2.0 volts (and in practice will probably be quite close to the centre of those, say 1.4 volts). So the (5 volt) regulator will have fallen out of stabilisation before the interrupt is even triggered. Of course the PICaxe will keep running (unstabilised) down to around 2 volts Vdd, but that's not really an optimum situation.

The corresponding Schmitt limit input levels are specified as 1.0 and 4.0 volts (20% and 80% of Vdd), but in practice the threshold may be not very different to the TTL levels (AFAIK the hysteresis is only a few hundred mV). So using a Schmitt input is likely to just increase the amount of "uncertainty".

An "accurate" method is to use one of the internal analogue comparator(s) which are available in all M2 chips (accessed via SFR commands), perhaps associated with the "DAC" (internal resistor divider chain) and/or the FVR. But this does require additional pins, externally linking the comparator output pin to an available interrupt input pin (and of course a more complex program).

Cheers, Alan.
 

marzan

Senior Member
#17
@ALLAN. Looks like i have a lot of reading to do. Extra pins is easy. I have 20m2's here so an sasy upgrade. I think i need to do a schematic so everyone can see what i have done, and i am far from an expert so it probably could be improved. What i lack in talent, i make up for with enthusiasm hehe.
Marz
 
Last edited:

hippy

Technical Support
Staff member
#18
So the (5 volt) regulator will have fallen out of stabilisation before the interrupt is even triggered.
Though, if we are reading the voltage supplied to the unit which has disappeared, that should instantly drop to zero while the reservoir cap is still full and the PICAXE still getting full voltage.

I didn't understand the "With just a voltage divider I think it fluctuates too much" problem reported because there shouldn't be any fluctuation at all. It's either high when the voltage is present or pulled low when it isn't.

This also leads into choosing a resistor divider which keeps the input close to 5V as much as possible so small fluctuations don't cause it to be detected as a low.
 

marzan

Senior Member
#19
Though, if we are reading the voltage supplied to the unit which has disappeared, that should instantly drop to zero while the reservoir cap is still full and the PICAXE still getting full voltage.

I didn't understand the "With just a voltage divider I think it fluctuates too much" problem reported because there shouldn't be any fluctuation at all. It's either high when the voltage is present or pulled low when it isn't.

This also leads into choosing a resistor divider which keeps the input close to 5V as much as possible so small fluctuations don't cause it to be detected as a low.
@ Hippy i think there may be some confusion in how it is wired up. It is as you say on the high side of the Vreg between a diode and the battery. I havent put a scope on it, but i am using a stepper motor drawing about an amp, and i think that might be causing a voltage drop at the battery, even with a large cap between theVreg and the diode.does that make sense?
Marz
 

AllyCat

Senior Member
#20
Hi,
that should instantly drop to zero while the reservoir cap is still full and the PICAXE still getting full voltage.

Generally, there will be reservoir capacitors on both the input and output terminals of the regulator (with values of 100 nF up to hundreds of uF, depending on the data sheet and/or the designer's whim) and to be honest probably almost whatever you choose may work fine. ;)

But for a Keep It SimpleS approach, I would monitor the regulator's input capacitor voltage directly, being relatively "spike free". Then you shouldn't even need a capacitor on the PICaxe's input pin (which potentially introduces an additional delay).

For this application, the use of a comparator is probably an unnecessary complication; I would just select a voltage divider ratio such that the expected digital threshold (~ 1.4 volts) occurs just before the regulator is due to drop out (say 7 - 8 volts input). Thus a divider ratio of around 1/5 , say 39k : 10k or 22k : 5k6 , or convenient values such as 10k : 2k2 .

Cheers, Alan.
 

hippy

Technical Support
Staff member
#22
You circuit looks like it should work to me. The 5V regulator probably has a 2V overhead so should deliver 5V when input is 7V or more. Even if lower than that it should still deliver some voltage, down to 5v input I would guess.

If you are getting false triggering when running the motor that would suggest the stepper is pulling the 12V supply down to 7V or below.

I guess that is possible. If it is you seem to have a few choices; disable your interrupt during every step so you don't abort on that, add a delay within the interrupt so it doesn't abort on short power losses, have the interrupt save the data but continue anyway, monitor the input into the 12V supplying PSU, or forego the power loss detection and just keep tack of counts some other way.
 
#23
Thanks for you input Hippy. Took a while to do th e scematic, so i ran out if time to try some of the suggestions. Hopefully in the next couple of days i will be sble to get bak to it, but unfortunately lifes priorities get in the way.
Marz.
 
#24
Hi,



Generally, there will be reservoir capacitors on both the input and output terminals of the regulator (with values of 100 nF up to hundreds of uF, depending on the data sheet and/or the designer's whim) and to be honest probably almost whatever you choose may work fine. ;)

But for a Keep It SimpleS approach, I would monitor the regulator's input capacitor voltage directly, being relatively "spike free". Then you shouldn't even need a capacitor on the PICaxe's input pin (which potentially introduces an additional delay).

For this application, the use of a comparator is probably an unnecessary complication; I would just select a voltage divider ratio such that the expected digital threshold (~ 1.4 volts) occurs just before the regulator is due to drop out (say 7 - 8 volts input). Thus a divider ratio of around 1/5 , say 39k : 10k or 22k : 5k6 , or convenient values such as 10k : 2k2 .

Cheers, Alan.
@AllyCat hopefully i will get to try some of these options in the next couple of days. Thanks for the ideas.
Marz
 
Last edited:
Top