What am I missing here???

radiogareth

Senior Member
Its a simple project to illustrate outputting a binary word derived from a pot on the input ADC C.1. The ADC word is used to control 2 CMOS 4511 BCD to 7 segment drivers.
But it just counts up disregarding the value of B0!!
Even after ignoring it for the weekend I still can't see WHY it outputs each in sequence rather than skipping to the actual value in B0?

What am I missing here??

Thanks

Code:
 #picaxe 18m2
 #no_data
 dirsb=255
 
main: 
 readadc C.1, b0
 'debug
 
 if b0<5 then let outpinsb=%00000000  end if      '0.0
 pause 200
 if b0<10 then let outpinsb=%00010000 end if '0.1
 pause 200
 if b0<15 then let outpinsb=%00100000 end if '0.2
 pause 200
 if b0<20 then let outpinsb=%00110000 end if '0.3
 pause 200
 if b0<25 then let outpinsb=%01000000 end if '0.4
 pause 200
 if b0<30 then let outpinsb=%01010000 end if '0.5
 pause 200
 if b0<30 then let outpinsb=%01100000 end if '0.6
 pause 200
 if b0<35 then let outpinsb=%01110000 end if '0.7
 pause 200
 if b0<40 then let outpinsb=%10000000 end if '0.8
 
 goto main:
 
Last edited:

Technical

Technical Support
Staff member
b0 = 3
which is less than 5, also less than 10, also less than 15 etc.

A select case would be better /clearer here:

select case b0
case 1 to 5

case 6 to 10
etc.
end select
 

SAborn

Senior Member
For starters you are missing a forum subject title that relates to your question.

Secondly you also need to add a "goto or gosub" to each statement so the program is directed to another function and not drop through to the next line of program

Example.

if b0<5 then let outpinsb=%00000000 '0.0
pause 200
goto main
end if

if b0<10 then let outpinsb=%00010000 '0.1
pause 200
goto main
end if
 

bfgstew

Senior Member
Try this -

Code:
 #no_data
 dirsb=255
 
main: 
 readadc C.1, b0
 'debug
 
 select case b0
case 1 to 5
outpinsb=%00000000
case 6 to 10 
outpinsb=%00010000
case 11 to 15
outpinsb=%00100000
case 16 to 20
outpinsb=%00110000
case 21 to 25
outpinsb=%01000000
case 26 to 30
outpinsb=%01010000
case 31 to 35
outpinsb=%01100000
case 36 to 40
outpinsb=%01110000
case 41 to 45
outpinsb=%10000000
end select
 goto main:
 

marks

Senior Member
Hi radiogareth,
Does this achieve what your after?
Code:
#picaxe 18m2
 #no_data
 dirsb=255
 
main: 
 readadc C.1, b0
 'debug

 
  pinsb=b0/17*16
 

marks

Senior Member
thanks Ibenson,
after you posted I thought i better check not quite sure what you meen by underflow
,maybe this ,perhaps what i should have posted lol. goes to show you should test these things.
Code:
picaxe 18m2
 #no_data
 dirsb=255
 
main: 
 readadc C.1, b0
 'debug

 
  pinsb=b0/16*16
 

radiogareth

Senior Member
thanks Ibenson,
after you posted I thought i better check not quite sure what you meen by underflow
,maybe this ,perhaps what i should have posted lol. goes to show you should test these things.
Code:
picaxe 18m2
 #no_data
 dirsb=255
 
main: 
 readadc C.1, b0
 'debug

 
  pinsb=b0/16*16
What am I missing #2. What does dividing it by 16 and then multiplying it by 16 achieve?

Thanks for the multiple solutions. I like the 'case' statement and can see it living on in all sorts of other similar tasks.
 

marks

Senior Member
hi radiogareth,
i'm asuming your pot is returning a valu of 0 to 255
if we divide this by 16
we get 16 even groups betwee 0 and 255 ie
0 to 15 = 0
16 to 31 =1
240 to 255 = 15
which would normaly be represented by bits 0 - 3(b.0,b.1,b.2,b.3)
by multiplying by 16 we move this up >4
it will then be represented by bits 4 - 7(b.4,b.5,b.6,b.7)
 

radiogareth

Senior Member
Aahh, Light came on. As bfgstew said, 'elegant solution'. This forum continues to amaze with neat solutions.

Thanks again all.
 

lbenson

Senior Member
thanks Ibenson,
after you posted I thought i better check not quite sure what you meen by underflow
,maybe this ,perhaps what i should have posted lol. goes to show you should test these things.
Code:
picaxe 18m2
 #no_data
 dirsb=255
 
main: 
 readadc C.1, b0
 'debug

 
  pinsb=b0/16*16
"Underflow" was not the right term; what I meant was that in the original code:
Code:
 if b0<5 then let outpinsb=%00000000  end if      '0.0
 pause 200
 if b0<10 then let outpinsb=%00010000 end if '0.1
 pause 200
 if b0<15 then let outpinsb=%00100000 end if '0.2
 pause 200
dividing b0 by 17 will result in 0 in each of these cases, so the difference between them will be lost. However, if the adc values can be adjusted so that they fall into discrete blocks of 16 values, then something like what you have posted could work.

Or with the present values:
Code:
readadc C.1, b0
if b0 > 0 then
  b0 = b0 - 1 / 5 * 16 ' if b0<45, results in values 0-8, shifted left 4 bits
endif
outpinsb = b0
Or perhaps:
Code:
readadc C.1, b0
b0 = b0 min 1 - 1 / 5 * 16 ' if b0<45, results in values 0-8, shifted left 4 bits
outpinsb = b0
You can try it in the simulator.
 
Last edited:

lbenson

Senior Member
Full code for simulator:
Code:
dirsb=%11110000 
do
  readadc C.1, b0
  b0 = b0 min 1 - 1 / 5 * 16 ' if b0<45, results in values 0-8, shifted left 4 bits
  outpinsb = b0
  pause 4000
loop
Adjust the ADC value of C.1.
 

radiogareth

Senior Member
I was going to try padding down the 5 volts input to give 250 on the ADC when 5 volts inputed (250/255) using a precision potentiomenter or resistor string.

Thanks again :)
 

Rick100

Senior Member
Since
Code:
pinsb=b0/16*16
just mask off the lower 4 bits, it could be changed to
Code:
pinsb = b0 & %11110000
It might run a little faster.
 

radiogareth

Senior Member
This select case has been very useful - I just re-used it for this little project :)

Code:
'Simple Temperature indicator for PC fan outlet
'For James march 2014
'Using 08M2 with Dallas DS18B20 on C.4
'Red LED on C.2 Green LED on C.1 Blue LED on C.0
'Thanks to the PICAXE forum for guidance on Select command

#picaxe 08m2	
#no_data
dirsc=255
 
main: 
	readtemp c.4,b0 
		select case b0
		case 1 to 15
			outpinsc=%00000111	'white
		case 16 to 17 
			outpinsc=%00000011	'cyan
		case 18 to 19 
			outpinsc=%00000001	'blue
		case 20 to 21
			outpinsc=%00000010	'green	
		case 22 to 23 
			outpinsc=%00000101	'purple
		case 24 to 30 
			outpinsc=%00000100	'red
	endselect
 	goto main:
 

radiogareth

Senior Member
Since
Code:
pinsb=b0/16*16
just mask off the lower 4 bits, it could be changed to
Code:
pinsb = b0 & %11110000
It might run a little faster.
As its for a 'digital voltmeter' project its going to need a pause in there somewhere anyway so speed is not an issue. Fascinating though how many ways things can be solved. If only windows worked the same way instead of asking for more memory etc....

The posted code is only the first part - there will be 50 decisions to make to display 0.0 up to 5.0 volts.

Thanks anyway :)
 
Top