Smart candle

alex126

Member
Hello. I tried to reproduce this project of "smart candle" with picaxe. Less pieces and another programming lesson:
(thanks for the author!)
1. So there is a light always on
2. When you blow on the microphone - light goes off for a pause of 5000
3. There is a ldr (with the voltage divider with 10k). You can use a lighter during a pause and the light go on
4. Or the the light go on (after pause 5000)
The question is about the lighting by ldr. I tried to use an interrupt. It doesn’t work. I thought to use the SELECTION and another CASE command. Still the same result. So the question is how to interrupt the light off during the pause by using the LDR. Thank you for some ideas.
(ldr: light - 130 Ohm, dark - 4kOhm)

#PICAXE 18M2
#NO_DATA

symbol V_micro = B.1
symbol d_val = b4

symbol V_ldr = C.1
symbol d_val_ldr = b2
symbol V_min_ldr = 0
symbol V_med_ldr = 25
symbol V_max_ldr = 256

symbol y_led = C.0
symbol V_min = 0
symbol V_med = 25
symbol V_max = 256

main: readadc V_micro, d_val
select d_val
case V_min to V_med
high y_led

case V_med to V_max
low y_led
pause 5000
high y_led
endselect
interrupt: readadc V_ldr, d_val_ldr
if b2 < 1 then interrupt
high C.0
setint %00000010,%00000010,C ; re-activate interrupt
return

goto main
 

kfjl

Member
Hi,

It looks like there's an error in the manual. I tried:

readadc C.7,b2

on a 20X2 and it didn't work.

readadc 3,b2

works.

adcsetup might be worth a look too.
 

steliosm

Senior Member
I think that interrupts only work on digital pins. Given the resistance values for the LDR during light and dark, what is the voltage read by picaxe? Have a look at this link, provides insights on the voltage levels to register either a '1' or '0': http://www.picaxe.com/BASIC-Commands/Digital-InputOutput/inputtype/

TTL (Supply voltage > 4.5V)
Status 'high' if > 2.0V

TTL (Supply voltage < 4.5V)
Status 'high' if > 0.25 * Vsupply + 0.8V

Seems to me that if your voltage at the voltage divider during the light is above 2v (or depending on your voltage supply) you should be able to trigger the interrupt.
 

hippy

Technical Support
Staff member
It looks like there's an error in the manual. I tried:
Not quite an error but a 'known feature' of the X2 chip compilers.

The X2 chips use ADC channel numbers in READADC and READADC10 commands.

When a pin name is specified, for example READADC C.7, the X2 compilers automagically translate that name to an ADC channel and everything works but the compiler cannot do that when the pin name has been specified in a SYMBOL statement. Do that and the READADC ends up reading the wrong channel.

For the 20X2 C.7 is ADC channel 3 so all the following are equivalent -
Code:
ReadAdc C.7, b0
Code:
ReadAdc 3, b0
Code:
Symbol  ADC_CHANNEL = 3
ReadAdc ADC_CHANNEL, b0
So, the bottom line is, if specifying the READADC pin in a SYMBOL statement for an X2, use its ADC channel number not its name.
 

hippy

Technical Support
Staff member
I think that interrupts only work on digital pins.
That is correct, so the voltage applied to the interrupt pin has to be high enough to be seen as a 'logical high value' for the interrupt to be activated.

Added : Ignore the following. For some reason I read the code as being for an 08M2. I did note you are reading ADC on B.1 and C.1 but only on re-reading the code did I realise you do have two ADC inputs, weren't just referring to the same by different names !

The 08M2 does have an on-chip comparator and it should be possible to to route its output to an output pin. If so it may be possible to take the LDR voltage in on C.1, compare with an internal DAC voltage and output on C.2. That digital output can be linked in to C.3 ( or C.4 ) and used as an interrupt source. C.0 can control the LED.

That would mean your circuit stays the same except for linking C.2 to C.3 -

Code:
    .----__----.
   -| V+    0V |-
   -| SI   C.0 |------> LED
   -| C.4  C.1 |<------ LDR
.-->| C.3  C.2 |---.
|   `----------'   |
|                  |
`------------------'
That comparator and setting it to control an output pin would need to be configured using POKESFR commands. I would need to look up the exact commands but they are probably on the forum somewhere.
 
Last edited:

hippy

Technical Support
Staff member
Code:
endselect
interrupt: readadc V_ldr, d_val_ldr
There is a slight bug in the code there - The "goto main" should be after the "endselect" and before the "Interrupt:" routine label.

When not there the code falls through into the interrupt which means it won't be doing what is expected. And, when the interrupt's "return" statement is executed, the behaviour will be unpredictable.
 

AllyCat

Senior Member
Hi,
.... There is a ldr (with the voltage divider with 10k). You can use a lighter during a pause and the light go on ...
(ldr: light - 130 Ohm, dark - 4kOhm)
10k : 4k is rather "marginal" for a digital input, you should assume the potential divider needs to reach at least 2 volts (i.e. <6k pullup) to reliably reach the digital "1" threshold..

As said above, the ADC can't directly generate an interrupt, you either need to poll it in a loop or to use an internal comparator, which can be enabled by POKESFR commands in the 08 and 18M2 chips. The comparator output then still needs to be looped out and back through pins to generate an interrupt on an (interrupt-capable) input pin.

When not there the code falls through into the interrupt which means it won't be doing what is expected. And, when the interrupt's "return" statement is executed, the behaviour will be unpredictable.
Currently the program appears to be relying on the fall-through into the interrupt routine, to enable the interrupts for the first time?

Cheers, Alan.
 
Top