Reading ADC then delaying switch

lxlramlxl

New Member
A quick overview of what the program should be doing.
Basically on pin C.2 I have the input voltage between 0-5 that is varied using a variable resistor.
Depending on the voltage that is on pin C.2 there will be a delay which will activate the output C.1.
I'm pretty sure that it is my code that has an issue and not the hardware itself.

Code:
Main:

ReadADC c.2 , b0				; read in pot value

if B0 < 20 then				; 
	wait 0
	
elseif b0 < 40 then
	low C.1
	wait 1
	high c.1

elseif b0 < 60 then
      low C.1
      wait 2
      high c.1
      
elseif b0 < 80 then
      low C.1
      wait 3
      high c.1
      
elseif b0 < 100 then
      low C.1
      wait 4
      high c.1
      
elseif b0 < 120 then
      low c.1
      wait 5
      high c.1
      
elseif b0 < 140 then
      low c.1
      wait 6
      high c.1
      
elseif b0 < 160 then
      low c.1
      wait 7
      high c.1
      
elseif b0 < 180 then
      low c.1
      wait 8
      high c.1
      
elseif b0 < 200 then
      low c.1
      wait 9
      high c.1
      
elseif b0 < 220 then
      low c.1
      wait 10
      high c.1
      
elseif b0 < 240 then
      low c.1
      wait 11
      high c.1
          
elseif b0 < 260 then
      low c.1
      wait 12
      high c.1
      
	
endif 




goto main
 

BESQUEUT

Senior Member
To my mind this code is OK.
try debuging the hardware :
Code:
	low C.1
	wait 2
	high c.1 ' to be sure that the output is OK


Main:

ReadADC c.2 , b0				; read in pot value
[COLOR="#FF0000"]sertxd ("B0=",#b0,13,10)[/COLOR]

if B0 < 20 then				; 
	wait 0
	
elseif b0 < 40 then
	low C.1
	wait 1
	high c.1
Equivalent code :
Code:
DO
      ReadADC c.2 , b0				; read in pot value


     if B0 >19 then
              low C.1
              b0=b0-20/20
              wait b0	
              high c.1		; 
     endif
LOOP
 
Last edited:

AllyCat

Senior Member
Hi,

Try putting in a SERTXD(#b0,cr,lf) in the line after the READADC to see if your hardware really is working.

The code looks alright, but could be simpler as :
Code:
main:
do
	ReadADC c.2 , b0				; read in pot value
	w1 = b0 * 50				; delay in milliseconds	 
	low c.1
	pause w1					; or could use pulsout c.1,w1
	high c.1					;
loop
Cheers, Alan.

PS: My post was later than Besqueut's while I checked why WAIT bo is an "error" !
 

BESQUEUT

Senior Member
Depending on the voltage that is on pin C.2 there will be a delay which will activate the output C.1.
With your code if pot>19, C.1 is quasi-always low so it is not possible to see the timing !
Try this (thanks to AllyCat) :
Code:
main:
do
	ReadADC c.2 , b0				; read in pot value
        [S]w1 = b0 -20/20 [/S]
	w1 = b0*50				; delay in milliseconds	 
	low c.1
	pause w1					; or could use pulsout c.1,w1
	high c.1	
	pause w1
        low c.1
				;
loop
 
Last edited:

lxlramlxl

New Member
Thanks for your reply. I will be testing the code tomorrow.
What is the "-20/20" for after reading the value in b0?
 

AllyCat

Senior Member
Hi,

Yes, I think your "bug" was that there was no PAUSE or WAIT to define the "gap" between your output "pulses".

-20/20 subtracts 20 and then divides by 20, so I think BQ was trying to ensure a "zero" delay at one end of the pot. But IMHO this is doubly wrong. Firstly, it may produce a "negative" wraparound to a large (positive) number, and secondly PAUSE works in milliseconds whilst WAIT is in seconds (but strangely cannot be used with a variable such as b0), so I believe my *50 is correct.

Cheers, Alan.
 

BESQUEUT

Senior Member
But IMHO this is doubly wrong. Firstly, it may produce a "negative" wraparound to a large (positive) number, and secondly PAUSE works in milliseconds whilst WAIT is in seconds (but strangely cannot be used with a variable such as b0), so I believe my *50 is correct.

Cheers, Alan.
I agree.
......................................................
 

lxlramlxl

New Member
Hi,

Yes, I think your "bug" was that there was no PAUSE or WAIT to define the "gap" between your output "pulses".

-20/20 subtracts 20 and then divides by 20, so I think BQ was trying to ensure a "zero" delay at one end of the pot. But IMHO this is doubly wrong. Firstly, it may produce a "negative" wraparound to a large (positive) number, and secondly PAUSE works in milliseconds whilst WAIT is in seconds (but strangely cannot be used with a variable such as b0), so I believe my *50 is correct.

Cheers, Alan.
Do you know how the ADC reads the voltage? Is it in millivolts or volts? e.g 1 volt would read as 1000 (mV) or 1
This is significant due to the *50. If it reads in Volts it'd be just 50ms but if it reads in mV then it'd be 50seconds (Based on 1volt)
 

lxlramlxl

New Member
255 = Vref (Vref is probably 5V)
Sorry about this, but where you do you get that information? I can't find it in the help documents (I might of just missed it)
And in picaxe itself you cannot right click the +ve pin to check the value.

Edit: I'm guessing its 255 since that is the maximum value that can be given on the pin?
So going on that basis 51 would be 1volt?
 
Last edited:

BESQUEUT

Senior Member
Sorry about this, but where you do you get that information?
Picaxe Manual section 2 page 29 : adcconfig

The default Vref+signal for the ADC is the power supply (V+)

+ Appendix 5 & 6 : Picaxes variations
Voltage Range (V) for 20 X2 = 1.8-5.5

With Picaxes M2, you also have FVR ; see fvrsetup...

Your power supply is probably 5V, but can be anything from 2V to 5V...
So going on that basis 51 would be 1volt?
YES
 

lxlramlxl

New Member
Picaxe Manual section 2 page 29 : adcconfig

The default Vref+signal for the ADC is the power supply (V+)

+ Appendix 5 & 6 : Picaxes variations
Voltage Range (V) for 20 X2 = 1.8-5.5

With Picaxes M2, you also have FVR ; see fvrsetup...

Your power supply is probably 5V, but can be anything from 2V to 5V...
YES
Thanks alot for your help. I will be testing the program tomorrow. This is what I have
Code:
main:
do
	ReadADC c.2 , b0			; read in pot value
	w1 = b0/10*196			; delay in milliseconds (Divided by 10 then multiplied by 196 to make it more accurate.)
	low c.1
	pause w1				; or could use pulsout c.1,w1
	high c.1	
	pause w1
      low c.1
	
		;
loop
If im right this should give me 1 second delay per volt.
 

srnet

Senior Member
I don't mean to be ignorant but isn't it the same?
No, work through your example, assume say b0 = 128.

When you do a 'b0/10' you end up with 12 as the 0.8 is dropped, since this is integer only maths.

Now do it the way BQ suggested.
 

lxlramlxl

New Member
I just did it with 255.
255*196/10=4998
255/10*196=4998

51/10*196=999.6
51*196/10=999.6

I'm pretty sure the maths is correct. Unless its a way the picaxe works with decimals (I think it doesn't work with decimals)

So am I right thinking 51/10 = 5.1
Picaxe reads as 5
5 * 196 =980
 

hippy

Technical Support
Staff member
N / 10 * 196

By dividing first, 0 to 9 gives a result of zero, 10 to 19 gives a result of 196, 20 to 29 gives a result of 392.

By multiplying then dividing you will have fewer jumps, a much smoother progression as the pot value changes. For example 15 would give a result of 294
 

BESQUEUT

Senior Member
To be accurate with integer math, it is better to write :
w1 = b0*196/10
With your code, w0 will be by 196 increments,
with mine, 19 or 20 increments.

I just did it with 255.
255*196/10=4998 : OK
255/10*196=4998 KO : Integer result is 4900

51/10*196=999.6 KO : Integer result is 980
51*196/10=999.6 KO : Integer result is 999
So am I right thinking 51/10 = 5.1
Picaxe reads as 5
5 * 196 =980
YES
Also, be aware that :
355*296=39544
This is because w0 is a 16 bits number, so when result > 65535 you have to substract 65536...
This is true for intermediate calculations, so :
355*296/10=3954
No problem with readADC, but be carefull if using readADC10...
 
Last edited:
Top