The Alternate DC board for AudioScope.sh.

Hi guys...

Well I have entered an area of partial insnity... ;o)
Below is a photo of the 'ALTDC' board for AudioScope.sh...

I have decided to incorporate all three methods for obtaining DC into this MBP via the MIC input.

1) VFO.
2) CHOPPER.
3) COUNTER.

The controller for the COUNTER is not yet done but this board can now do 1) and 2).

I have started properly coding for the VFO section first but and I have decided just to do an accuracy of 4 bit depth for this. That is 0 - +2V to an accuracy of 0.125V.

I have an example basic piece of code that checks ranges of values so as to create each of the 16 values possible. The problem is it is ugly and 16 conditional "if"s is not the way to go. Again I can't find any info how to create a look up table where each lookup is a range of values. The EXAMPLE code below DOES work mighty fine but looks so ugly and primitive.

Any other ideas guys?

#!/bin/bash
# lookup
while true
do
	read -p "Number, 100 to 499:- " num
	if [ $num -ge 100 ] && [ $num -le 199 ]
	then
		echo "1) $num"
	fi
	if [ $num -ge 200 ] && [ $num -le 299 ]
	then
		echo "2) $num"
	fi
	if [ $num -ge 300 ] && [ $num -le 399 ]
	then
		echo "3) $num"
	fi
	if [ $num -ge 400 ] && [ $num -le 499 ]
	then
		echo "4) $num"
	fi
done

This simulates 2 bit depth but looks SOOO ugly...

Now the photo...
Top Left:
The CHOPPER with the option of the diode DC offset removing the blue link.

Bottom Left:
The 9V PP3 input to 5.1V supply.

Middle:
4 transistor VFO used for the first part of the DC code.

Top Right:
The VFO test circuit using the two black links connected and transistor input for measurement when links disconnected.

Bottom Right:
3 terminals, top terminal multivibrator output for 3) and for detection.
Middle terminal for the DC input.
Bottom terminal is one of the ground terminals.
To keep this simple it took some working out...

Enjoy. Bazza...

Divide by 100?

R=$((VAL/100))

Hi C'688...

I can't as the real values will eventually be determined by trial and error on the initial build and calibration phases. the V to F relationship is none linear and will range from about 700Hz to 2800Hz; (anywhere in that region depending on the voltage).
As I have pointed out the longhand method works but it is not a lookup table and looks mighty ugly...
Each of the 16 possible values will have its own frequency range as its lookup.

Here is your script with two additional ways to produce the same results. Maybe you'll like one of these alternatives better than your current code...

#!/bin/bash
range_lows=(100 200 300 400 500)
# lookup
while true
do
	read -p "Number, 100 to 499:- " num
	echo 'Using original if statements:'
	if [ $num -ge 100 ] && [ $num -le 199 ]
	then
		echo "1) $num"
	fi
	if [ $num -ge 200 ] && [ $num -le 299 ]
	then
		echo "2) $num"
	fi
	if [ $num -ge 300 ] && [ $num -le 399 ]
	then
		echo "3) $num"
	fi
	if [ $num -ge 400 ] && [ $num -le 499 ]
	then
		echo "4) $num"
	fi
	printf '\nUsing if-else sequence:\n'
	if [ "$num" -lt 100 ]
	then :
	elif [ "$num" -le 199 ]
	then	echo "1) $num"
	elif [ "$num" -le 299 ]
	then	echo "2) $num"
	elif [ "$num" -le 399 ]
	then	echo "3) $num"
	elif [ "$num" -le 499 ]
	then	echo "4) $num"
	fi
	printf '\nUsing array lookup:\n'
	for((i=0; i < ${#range_lows[@]}; i++))
	do 	[ "$num" -lt ${range_lows} ] && break
	done
	[ $i -gt 0 ] && [ $i -lt ${#range_lows[@]} ] && echo "$i) $num"
done

All of these could be simplified considerably if you know that $num will expand to a number within your known ranges. All of these will fail if $num does not expand to a numeric string.

1 Like

Hi Don...

Thanks a lot.

It was the array method I wanted but I couldn't get my version to work.
I will try your version out tonight when I am home from work...

And yes, $num will AWLAYS be an integer number that will default to 0, (zero), before any call.

I will code for errors anyhow...

Again thanks, I will let you know how I get on...

Bazza.

---------- Post updated at 09:13 AM ---------- Previous update was at 07:49 AM ----------

Hi Don...
(Oops, at work.)
You are a star...
DEMO code that works, I couldn't work my own out...
This will be modified to suit my requirements in AudioScope.sh...

#!/bin/bash
# lookup
range_lows=(100 200 300 400 500)
voltage=(0 0.000 0.125 0.250 0.375 0.500)
while true
do
	read -p "Number, 100 to 499:- " num
	printf '\nUsing array lookup:\n'
	for ((i=0; i < ${#range_lows[@]}; i++))
	do
		[ "$num" -lt ${range_lows} ] && break
	done
	[ $i -gt 0 ] && [ $i -lt ${#range_lows[@]} ] && V="${voltage[$i]}"
	echo "$V Volts DC..."
done

Results just as I require.

Last login: Wed Jun 24 09:03:07 on ttys000
AMIGA:barrywalker~> cd Desktop/Code/Shell
AMIGA:barrywalker~/Desktop/Code/Shell> ./lookup
Number, 100 to 499:- 0

Using array lookup:
 Volts DC...
Number, 100 to 499:- 99

Using array lookup:
 Volts DC...
Number, 100 to 499:- 100

Using array lookup:
0.000 Volts DC...
Number, 100 to 499:- 199

Using array lookup:
0.000 Volts DC...
Number, 100 to 499:- 200

Using array lookup:
0.125 Volts DC...
Number, 100 to 499:- 299

Using array lookup:
0.125 Volts DC...
Number, 100 to 499:- 400

Using array lookup:
0.375 Volts DC...
Number, 100 to 499:- 499

Using array lookup:
0.375 Volts DC...
Number, 100 to 499:- ^C
AMIGA:barrywalker~/Desktop/Code/Shell> _

Oh yes, he's a wiz, isn't he?

Speaking about your earlier code, which you won't need any more but might be interested in anyways:

if [ $num -ge 100 ] && [ $num -le 199 ]

What you do here is: call /usr/bin/test with the arguments "$num -ge 100" and - if this returns TRUE - call /usr/bin/test again with the arguments "$num -le 199". You can save one open process by calling test once instead of twice because test is able to do logical calculations itself:

if [ $num -ge 100 -a $num -le 199 ]

You can even manipulate operator precedence by using brackets:

if [ \( $num -ge 100 \) -a \( $num -le 199 \) ]

I hope this helps.

bakunin

1 Like

You probably either want to make the final echo dependent on having found a value in range, or clear the value of V at the start of processing each time through the loop. I would probably just change the lines:

	[ $i -gt 0 ] && [ $i -lt ${#range_lows[@]} ] && V="${voltage[$i]}"
	echo "$V Volts DC..."

to:

	[ $i -gt 0 ] && [ $i -lt ${#range_lows[@]} ] && V="${voltage[$i]}" && \
		echo "$V Volts DC..."

I'm also not sure that this will print what you wanted if you enter a value >= the last entry in the range_lows[] array. (And, I don't know what you want in that case.) Note that in your original code, 100 was the lowest expected value, 499 was the highest expected value, and the code didn't produce any output for out of range values.

1 Like

Hi bakunin...
Thanks I will use that method in future code.
I used what I knew would work as my starting point but I wanted a lookup array instead and Don gave me what I wanted...

Don...
I was aware of $V remaining and I will take any errors into account by initialising $V to 0 per call. I will initialise $num too and ensure that is always present.
I will be using a _re-usable_variable_ for $V as once it has been used it will not be needed again until the routine is called and can be used elsewhere. (yeah I know try not to use re-usable variables, but I only have 4 and I know what they are and commented on them inside AudioScope.sh)...

Thanks muchly for tour guidance...

Bazza.

The test -a and -o binary operators aren't required on all POSIX systems (but are currently required on a UNIX branded systems). With some expressions -a and -o can lead to ambiguities in the grammar; so they are likely to be deprecated in the next revision of the POSIX standards. (That doesn't mean that they'll every actually be removed from the shells, but the shell developers all advise against using them.)

Fortunately, test and [ are built-ins in current shells so you don't actually have to fork and exec /usr/bin/test twice so the penalty for using test twice isn't nearly as high as it was in early shells.

On OS X (which is what wisecracker is using), both bash and ksh support the command:

if [[ num >= 100 && num <= 199 ]]

which is handled as part of the shell's grammar, not as a built-in utility (which makes it even faster and gets rid of the ambiguity in the test syntax). This form isn't in the standards yet, but is also likely to be added in the next revision.

1 Like

Right guys...

The code below is a working example of the real DC voltage input with the output read off of a professional frequency counter. (The builtin counter inside AudioScope.sh works just as well but I needed to work out the calibration method so I tested the board on the bench at work. [ Shhhh, don't tell anyone... ;o) ]
The values of '$freq' were rounded up or down to the nearest 0 or 5...
The board has had one very minor modification, a 1M resistor added.
The code below is working a dream, thank you Don...
A highly mofified version will be incorporated into the main code over the WE...

#!/bin/bash
# lookup
freq=( 0 860 945 1025 1110 1190 1275 1355 1445 1520 1605 1685 1770 1855 1940 2025 2110 2200 4000 )
voltage=( 0.000 0.000 0.125 0.250 0.375 0.500 0.625 0.750 0.875 1.000 1.125 1.250 1.375 1.500 1.625 1.750 1.875 2.000 0.000 )
while true
do
	read -p "Simulate frequency from AudioScope builtin counter, 0 to 3999:- " num
	for ((i=0; i < ${#freq[@]}; i++))
	do
		[ "$num" -lt ${freq} ] && break
	done
	[ $i -gt 0 ] && [ $i -lt ${#freq[@]} ] && V="${voltage[$i]}"
	echo "$V Volts DC..."
done