As mentioned some time ago, the analog channels seem to shift with time. The input connected to channel 3 (ain3) for instance shifts to ain4 after some time (maybe days.) Rebooting the beaglebone seems to restore correct operation. This shifting makes the board analog inputs worthless for reading sensors, due to the unreliability.
I tried various workarounds, and the latest is to read each channel twice in a row, separated by an 'lseek()' on the channel. It works so far.
Here's the code (tcl) for a library with two functions that read 7 analog inputs, returning either raw bits (0-4095) or voltages (0-1.8V):
;# Read 7 analog inputs of beaglebone board and
;# return as either list of 8 decimal values as voltages,
;# or list of raw bit values from 0-4095.
;# Note pin on P9 vs ain* and return list index correspondence:
;#
;# 0 ain1 Not connected to pin
;# 1 ain2 P9-39
;# 2 ain3 P9-40
;# 3 ain4 p9-37
;# 4 ain5 p9-38
;# 5 ain6 p9-33
;# 6 ain7 p9-36
;#...
package provide beagleio 0.1
namespace eval beagleio {
variable initialized 0
variable fds
# Open all analog 'channels' (actually files in Angstrom)
proc init {} {
variable fds
for {set i 1} {$i < 7} {incr i} {
set fds($i) [open /sys/devices/platform/tsc/ain$i r]
}
}
proc beaglearead_v {} {
variable fds
variable initialized
if {$initialized == 0} {
beagleio::init
set initialized 1
}
set vl {}
for {set i 1} {$i < 7} {incr i} {
;# Who the hell knows why we need to do this twice to read the right channel
;# consistently? But we do...
seek $fds($i) 0
set val [read $fds($i)]
seek $fds($i) 0
set val [read $fds($i)]
;#puts "Debug: beaglearead_b: read (length [string length $val]) value $val from channel $i"
;# delete characters = 0x0 ,since these get sent back when analog file is read.
regexp {(\d+)} $val all val
;#puts "Debug: beaglearead_b: modified value (length [string length $val]) is $val from channel $i"
;# Convert to voltages: 0-4095 full scale = 1.8 volts.
lappend vl [format %6.3f [expr 1.8 * $val/4096]]
}
return $vl
}
proc beaglearead_b {} {
variable fds
variable initialized
if {$initialized == 0} {
beagleio::init
set initialized 1
}
set vl {}
for {set i 1} {$i < 7} {incr i} {
# Who the hell knows why we need to do this twice to read the right channel
# consistently? But we do...
seek $fds($i) 0
set val [read $fds($i)]
seek $fds($i) 0
set val [read $fds($i)]
#puts "Debug: beaglearead_b: read (length [string length $val]) value $val from channel $i"
;# delete characters = 0x0 ,since these get sent back when analog file is read.
regexp {(\d+)} $val all value
;#regsub -all {\x000} $val {} val
;#puts "Debug: beaglearead_b: modified value (length [string length $val]) is $val from channel $i"
lappend vl $value
}
return $vl
}
}
No comments:
Post a Comment