Difference between revisions of "EBC Exercise 10a Analog In"

From eLinux.org
Jump to: navigation, search
(Initial Page)
 
m (Analog in - Continuous: Updated path to analogInContinous.py)
 
(21 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
[[Category:ECE497]]
 
[[Category:ECE497]]
 
{{YoderHead}}
 
{{YoderHead}}
== Analog in ==
 
  
(This is based on [https://groups.google.com/forum/?fromgroups#!searchin/beagleboard/AIN/beagleboard/-ClhIXxtOds/rranYdwhS88J this].)
+
== Introduction ==
 +
The Beagle has seven exposed analog inputs, numbered '''AIN0''' to '''AIN6''', on the '''P9''' header.
 +
They are accessed through the Linux Industrial IO (iio) system (https://wiki.analog.com/software/linux/docs/iio/iio).
 +
They can be read either a sample at a time (One Shot) or in blocks of samples (Continous).
 +
One shot can be used to read the setting of a potentiometer, or an analog temperature sensor.
 +
The continuous mode is for reading a microphone or some other analog signal.  With the proper configuration, the continuous input can read
 +
12 bit samples at 200k samples/second.
  
The bone has eight Analog Inputs.  Several are exposed on P9.  They are labeled '''AIN''' in table 11 above. How many do you find?
+
Here's is how to use each.
  
The AIN pins are sampled at 12 bits and 100k samples per second.  The input voltage is between 0 and 1.8V. Fortunately, both voltages are available on P9.
+
== Analog in - One Shot ==
 +
(This is based on [https://groups.google.com/forum/?fromgroups#!searchin/beagleboard/AIN/beagleboard/-ClhIXxtOds/rranYdwhS88J BeagleBone Black Analog Input].)
  
The photo above shows a small potentiometer wired to the bone.  One end goes to the analog ground (pin 34), the other analog 1.8V (pin 32). The wiper is attached to '''AIN5''' which is pin 36.
+
The bone has eight Analog Inputs; seven are exposed on '''P9''', labeled '''AIN''' in table 11 below.
  
You interact with the analog in much like the gpio, but it appears in a different. We have to run a command before the AIN interface appears.  Just run them now, later we'll explain what you did.
+
[[File:HeaderP9.jpg|800px]]
  
  beagle$ '''SLOTS=/sys/devices/bone_capemgr.*/slots'''
+
The AIN pins are sampled at 12 bits and 8k samples per second by default. The input voltage is between 0 and 1.8V.  Fortunately, both analog ground (0V) and
beagle$ '''PINS=/sys/kernel/debug/pinctrl/44e10800.pinmux/pins'''
+
1.8V are available on P9.
beagle$ '''echo cape-bone-iio > $SLOTS'''
 
  
You can now access the analog interface, but where do they appear. Try using the '''find''' command.
+
The photo below shows a small potentiometer wired to the bone.  One end goes to the analog ground (pin 34), the other analog 1.8V (pin 32). The wiper is attached to '''AIN5''' which is pin 36.
  
beagle$ '''find /sys -name "*AIN"'''
+
[[File:Bone gpio.JPG|300px]]
./devices/ocp.2/helper.14/AIN0
+
[[File:BoneGPIO.png|300px]]
./devices/ocp.2/helper.14/AIN1
 
./devices/ocp.2/helper.14/AIN2
 
./devices/ocp.2/helper.14/AIN3
 
./devices/ocp.2/helper.14/AIN4
 
./devices/ocp.2/helper.14/AIN5
 
./devices/ocp.2/helper.14/AIN6
 
./devices/ocp.2/helper.14/AIN7
 
  
You paths may be slightly different. Now explore.
+
You interact with the analog in much like the gpio, but it appears in a different place.  
  
  beagle$ '''cd /sys/devices/ocp.2/helper.14'''
+
  bone$ '''cd /sys/bus/iio/devices/iio:device0'''
  beagle$ '''ls -F'''
+
  bone$ '''ls -F'''
  AIN0 AIN2 AIN4 AIN6 driver@  power/     uevent
+
  buffer/          in_voltage2_raw  in_voltage6_raw power/
  AIN1 AIN3 AIN5 AIN7 modalias subsystem@
+
  dev              in_voltage3_raw in_voltage7_raw scan_elements/
 +
  in_voltage0_raw in_voltage4_raw name            subsystem@
 +
  in_voltage1_raw in_voltage5_raw of_node@         uevent
  
There are the various analog inputs, but watch out.  This interface starts numbering at '''1''' and Table 11 starts at '''0''', so to read AIN5 you need to look at '''AIN6'''!
+
There are the various analog inputs, in_voltage6_raw corresponds with AIN6
  
  beagle$ '''cat AIN6'''
+
  bone$ '''cat in_voltage6_raw'''
 
  1185
 
  1185
  
 
Change the pot and rerun '''cat'''.  What's the min and max value you get?  Is it 12 bits?
 
Change the pot and rerun '''cat'''.  What's the min and max value you get?  Is it 12 bits?
  
=== Challenge ===
+
== Analog in - Continuous ==
Rewrite the scripts from before to read an AIN pin and continuously display it's value.
+
(This is based on information at:  http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/Foundational_Components/Kernel/Kernel_Drivers/ADC.html#Continuous%20Mode)
 +
 
 +
Reading a continuous analog signal requires some set up.  First go to the iio devices directory.
 +
 
 +
bone$ '''cd /sys/bus/iio/devices/iio:device0'''
 +
bone$ '''ls -F'''
 +
buffer/  in_voltage0_raw  in_voltage2_raw  in_voltage4_raw  in_voltage6_raw  name      power/          subsystem@
 +
dev      in_voltage1_raw  in_voltage3_raw  in_voltage5_raw  in_voltage7_raw  of_node@  scan_elements/  uevent
 +
 
 +
Here you see the files used to read the one shot values. Look in '''scan_elements''' to see how to enable continuous input.
 +
bone$ '''ls scan_elements'''
 +
in_voltage0_en    in_voltage1_index  in_voltage2_type  in_voltage4_en    in_voltage5_index  in_voltage6_type
 +
in_voltage0_index  in_voltage1_type  in_voltage3_en    in_voltage4_index  in_voltage5_type  in_voltage7_en
 +
in_voltage0_type  in_voltage2_en    in_voltage3_index  in_voltage4_type  in_voltage6_en    in_voltage7_index
 +
in_voltage1_en    in_voltage2_index  in_voltage3_type  in_voltage5_en    in_voltage6_index  in_voltage7_type
 +
Here you see three values for each analog input, _en (enable), _index (index of this channel in the buffer’s chunks)
 +
and _type (How the ADC stores its data).
 +
(See the link above for details.)
 +
 
 +
Let's use the input at '''P9.40''' which is '''AIN1'''.  To enable this input:
 +
bone$ '''echo 1 > scan_elements/in_voltage1_en'''
 +
Next set the buffer size.
 +
bone$ '''ls buffer'''
 +
data_available  enable  length  watermark
 +
Let's use a 512 sample buffer.  You might need to experiment with this.
 +
bone$ '''echo 512 > buffer/length'''
 +
Then start it running.
 +
bone$ '''echo 1 > buffer/enable'''
 +
Now, just read from '''/dev/iio:device0'''.
 +
 
 +
[[File:Sine1k.png|frame|1KHz sine wave sampled at 8KHz]]
 +
 
 +
An example Python program that does the above and the reads and plot the buffer is here:
 +
[https://github.com/beagleboard/cloud9-examples/blob/v2020.08/BeagleBone/Black/analogInContinuous.py analogInContinuous.py]
 +
Be sure to read the instillation instructions in the comments.  Also note this uses X windows and you need to '''ssh -X bone''' for
 +
X to know where the display is.
 +
 
 +
Run it:
 +
host$ '''ssh -X bone'''
 +
bone$ '''cd /opt/vsx-examples/examples/BeagleBone/Black'''
 +
bone$ '''./analogInContinuous.py'''
 +
Hit ^C to stop
 +
Here's the output of a 1KHz sine wave.
 +
 
 +
It'd be a good idea to disable the buffer when done.
 +
bone$ '''echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable'''
 +
 
 +
== Analog in - Continuous, Change the sample rate ==
 +
The built in ADCs sample at 8k samples/second by default.  They can run as fast as 200k samples/second by editing a device tree. 
 +
 
 +
bone$ '''cd /opt/source/bb.org-overlays'''
 +
bone$ '''make'''
 +
This will take a while the first time as it compiles all the device trees.
 +
bone$ '''vi src/arm/src/arm/BB-ADC-00A0.dts'''
 +
Around line 54 you'll see
 +
ti,chan-step-avg = <16 16 16 16 16 16 16 16>;
 +
ti,chan-step-opendelay = <0x98 0x98 0x98 0x98 0x98 0x98 0x98 0x98>;
 +
The first line says for every sample returned, average 16 values.  This will give you a cleaner signal, but if you want to go fast, change the 16's to 1's.
 +
The second line says to delay 0x98 cycles between each sample.  Set this to 0 to got as fast a possible.
 +
ti,chan-step-avg = <1 1 1 1 1 1 1 1>;
 +
ti,chan-step-opendelay = <0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00>;
 +
Now compile it.
 +
 
 +
 
 +
[[File:Tri10k.png|frame|10KHz triangle wave sampled at 200KHz]]
 +
 
 +
bone$ '''make'''
 +
  DTC    src/arm/BB-ADC-00A0.dtbo
 +
gcc -o config-pin ./tools/pmunts_muntsos/config-pin.c
 +
It knows to only recompile the file you just edited.  Now install and reboot.
 +
bone$ '''sudo make install'''
 +
...
 +
'src/arm/AM335X-PRU-UIO-00A0.dtbo' -> '/lib/firmware/AM335X-PRU-UIO-00A0.dtbo'
 +
'src/arm/BB-ADC-00A0.dtbo' -> '/lib/firmware/BB-ADC-00A0.dtbo'
 +
'src/arm/BB-BBBMINI-00A0.dtbo' -> '/lib/firmware/BB-BBBMINI-00A0.dtbo'
 +
...
 +
bone$ '''reboot'''
 +
 
 +
A number of files get installed, including the ADC file.
 +
Now try rerunning.
 +
bone$ '''cd /var/lib/cloud9/BeagleBone/Black'''
 +
bone$ '''./analogInContinuous.py'''
 +
Hit ^C to stop
 +
Here's the output of a 10KHz sine wave. (The plot is wrong, but eLinux won't let me fix it.)
 +
 
 +
It's still a good idea to disable the buffer when done.
 +
bone$ '''echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable'''
  
 
{{YoderFoot}}
 
{{YoderFoot}}

Latest revision as of 12:43, 20 October 2022

thumb‎ Embedded Linux Class by Mark A. Yoder


Introduction

The Beagle has seven exposed analog inputs, numbered AIN0 to AIN6, on the P9 header. They are accessed through the Linux Industrial IO (iio) system (https://wiki.analog.com/software/linux/docs/iio/iio). They can be read either a sample at a time (One Shot) or in blocks of samples (Continous). One shot can be used to read the setting of a potentiometer, or an analog temperature sensor. The continuous mode is for reading a microphone or some other analog signal. With the proper configuration, the continuous input can read 12 bit samples at 200k samples/second.

Here's is how to use each.

Analog in - One Shot

(This is based on BeagleBone Black Analog Input.)

The bone has eight Analog Inputs; seven are exposed on P9, labeled AIN in table 11 below.

HeaderP9.jpg

The AIN pins are sampled at 12 bits and 8k samples per second by default. The input voltage is between 0 and 1.8V. Fortunately, both analog ground (0V) and 1.8V are available on P9.

The photo below shows a small potentiometer wired to the bone. One end goes to the analog ground (pin 34), the other analog 1.8V (pin 32). The wiper is attached to AIN5 which is pin 36.

Bone gpio.JPG BoneGPIO.png

You interact with the analog in much like the gpio, but it appears in a different place.

bone$ cd /sys/bus/iio/devices/iio:device0
bone$ ls -F
buffer/          in_voltage2_raw  in_voltage6_raw  power/
dev              in_voltage3_raw  in_voltage7_raw  scan_elements/
in_voltage0_raw  in_voltage4_raw  name             subsystem@
in_voltage1_raw  in_voltage5_raw  of_node@         uevent

There are the various analog inputs, in_voltage6_raw corresponds with AIN6

bone$ cat in_voltage6_raw
1185

Change the pot and rerun cat. What's the min and max value you get? Is it 12 bits?

Analog in - Continuous

(This is based on information at: http://software-dl.ti.com/processor-sdk-linux/esd/docs/latest/linux/Foundational_Components/Kernel/Kernel_Drivers/ADC.html#Continuous%20Mode)

Reading a continuous analog signal requires some set up. First go to the iio devices directory.

bone$ cd /sys/bus/iio/devices/iio:device0
bone$ ls -F
buffer/  in_voltage0_raw  in_voltage2_raw  in_voltage4_raw  in_voltage6_raw  name      power/          subsystem@
dev      in_voltage1_raw  in_voltage3_raw  in_voltage5_raw  in_voltage7_raw  of_node@  scan_elements/  uevent

Here you see the files used to read the one shot values. Look in scan_elements to see how to enable continuous input.

bone$ ls scan_elements
in_voltage0_en     in_voltage1_index  in_voltage2_type   in_voltage4_en     in_voltage5_index  in_voltage6_type
in_voltage0_index  in_voltage1_type   in_voltage3_en     in_voltage4_index  in_voltage5_type   in_voltage7_en
in_voltage0_type   in_voltage2_en     in_voltage3_index  in_voltage4_type   in_voltage6_en     in_voltage7_index
in_voltage1_en     in_voltage2_index  in_voltage3_type   in_voltage5_en     in_voltage6_index  in_voltage7_type

Here you see three values for each analog input, _en (enable), _index (index of this channel in the buffer’s chunks) and _type (How the ADC stores its data). (See the link above for details.)

Let's use the input at P9.40 which is AIN1. To enable this input:

bone$ echo 1 > scan_elements/in_voltage1_en

Next set the buffer size.

bone$ ls buffer
data_available  enable  length  watermark

Let's use a 512 sample buffer. You might need to experiment with this.

bone$ echo 512 > buffer/length

Then start it running.

bone$ echo 1 > buffer/enable

Now, just read from /dev/iio:device0.

1KHz sine wave sampled at 8KHz

An example Python program that does the above and the reads and plot the buffer is here: analogInContinuous.py Be sure to read the instillation instructions in the comments. Also note this uses X windows and you need to ssh -X bone for X to know where the display is.

Run it:

host$ ssh -X bone
bone$ cd /opt/vsx-examples/examples/BeagleBone/Black
bone$ ./analogInContinuous.py
Hit ^C to stop

Here's the output of a 1KHz sine wave.

It'd be a good idea to disable the buffer when done.

bone$ echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable

Analog in - Continuous, Change the sample rate

The built in ADCs sample at 8k samples/second by default. They can run as fast as 200k samples/second by editing a device tree.

bone$ cd /opt/source/bb.org-overlays
bone$ make

This will take a while the first time as it compiles all the device trees.

bone$ vi src/arm/src/arm/BB-ADC-00A0.dts

Around line 54 you'll see

ti,chan-step-avg = <16 16 16 16 16 16 16 16>;
ti,chan-step-opendelay = <0x98 0x98 0x98 0x98 0x98 0x98 0x98 0x98>;

The first line says for every sample returned, average 16 values. This will give you a cleaner signal, but if you want to go fast, change the 16's to 1's. The second line says to delay 0x98 cycles between each sample. Set this to 0 to got as fast a possible.

ti,chan-step-avg = <1 1 1 1 1 1 1 1>;
ti,chan-step-opendelay = <0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00>;

Now compile it.


10KHz triangle wave sampled at 200KHz
bone$ make
  DTC     src/arm/BB-ADC-00A0.dtbo
gcc -o config-pin ./tools/pmunts_muntsos/config-pin.c

It knows to only recompile the file you just edited. Now install and reboot.

bone$ sudo make install
...
'src/arm/AM335X-PRU-UIO-00A0.dtbo' -> '/lib/firmware/AM335X-PRU-UIO-00A0.dtbo'
'src/arm/BB-ADC-00A0.dtbo' -> '/lib/firmware/BB-ADC-00A0.dtbo'
'src/arm/BB-BBBMINI-00A0.dtbo' -> '/lib/firmware/BB-BBBMINI-00A0.dtbo'
...
bone$ reboot

A number of files get installed, including the ADC file. Now try rerunning.

bone$ cd /var/lib/cloud9/BeagleBone/Black
bone$ ./analogInContinuous.py
Hit ^C to stop

Here's the output of a 10KHz sine wave. (The plot is wrong, but eLinux won't let me fix it.)

It's still a good idea to disable the buffer when done.

bone$ echo 0 > /sys/bus/iio/devices/iio:device0/buffer/enable




thumb‎ Embedded Linux Class by Mark A. Yoder