-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RSDK-7152 Analog Reader API rdk changes #3946
Changes from 19 commits
0405c93
120a4cc
a1d80bf
28cef10
20ac1c5
3a723a4
c07588c
4b3f36a
ec95030
fde443f
ad58c9b
805fb53
036df4a
f825659
3829674
f63d1fe
6b85674
dc02a7d
1aea02c
97c6b63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -117,6 +117,8 @@ type numatoBoard struct { | |
sent map[string]bool | ||
sentMu sync.Mutex | ||
workers rdkutils.StoppableWorkers | ||
|
||
productID int | ||
} | ||
|
||
func (b *numatoBoard) addToSent(msg string) { | ||
|
@@ -354,12 +356,43 @@ type analog struct { | |
pin string | ||
} | ||
|
||
func (a *analog) Read(ctx context.Context, extra map[string]interface{}) (int, error) { | ||
// Read returns the analog value with the range and step size in V/bit. | ||
func (a *analog) Read(ctx context.Context, extra map[string]interface{}) (board.AnalogValue, error) { | ||
res, err := a.b.doSendReceive(ctx, fmt.Sprintf("adc read %s", a.pin)) | ||
if err != nil { | ||
return 0, err | ||
return board.AnalogValue{}, err | ||
} | ||
reading, err := strconv.Atoi(res) | ||
if err != nil { | ||
return board.AnalogValue{}, err | ||
} | ||
return strconv.Atoi(res) | ||
var max float32 | ||
var stepSize float32 | ||
switch a.b.productID { | ||
case 0x805: | ||
// 128 channel usb numato has 12 bit resolution | ||
max = 3.3 | ||
stepSize = max / 4096 | ||
case 0x802: | ||
// 32 channel usb numato has 10 bit resolution | ||
max = 3.3 | ||
stepSize = max / 1024 | ||
case 0x800: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Mild preference to sort the cases in the switch statement, so it's easier to find the one you care about. |
||
// 8 and 16 pin usb versions have the same product ID but different voltage ranges | ||
// both have 10 bit resolution | ||
if a.b.pins == 8 { | ||
max = 5.0 | ||
} else if a.b.pins == 16 { | ||
max = 3.3 | ||
} | ||
stepSize = max / 1024 | ||
case 0xC05: | ||
// 1 channel usb relay module numato - 10 bit resolution | ||
max = 5.0 | ||
stepSize = max / 1024 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussion question: none of these ever change, right? Would it be simpler to calculate them once on initialization, and then just use the stored values within There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah that makes sense to me, ill do this at the start instead. |
||
default: | ||
} | ||
return board.AnalogValue{Value: reading, Min: 0, Max: max, StepSize: stepSize}, nil | ||
} | ||
|
||
func (a *analog) Write(ctx context.Context, value int, extra map[string]interface{}) error { | ||
|
@@ -384,6 +417,24 @@ func connect(ctx context.Context, name resource.Name, conf *Config, logger loggi | |
path = devs[0].Path | ||
} | ||
|
||
// Find the numato board's productid | ||
products := getSerialDevices() | ||
|
||
var productID int | ||
for _, product := range products { | ||
if product.ID.Vendor != 0x2a19 { | ||
continue | ||
} | ||
// we can safely get the first numato productID we find because | ||
// we only support one board being used at a time | ||
productID = product.ID.Product | ||
oliviamiller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
break | ||
} | ||
|
||
if productID != 0x800 && productID != 0x802 && productID != 0x805 && productID != 0xC05 { | ||
logger.Warnf("analog range and step size is not supported for numato with product id %d", productID) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Change |
||
} | ||
|
||
options := goserial.OpenOptions{ | ||
PortName: path, | ||
BaudRate: 19200, | ||
|
@@ -396,12 +447,12 @@ func connect(ctx context.Context, name resource.Name, conf *Config, logger loggi | |
if err != nil { | ||
return nil, err | ||
} | ||
|
||
b := &numatoBoard{ | ||
Named: name.AsNamed(), | ||
pins: pins, | ||
port: device, | ||
logger: logger, | ||
Named: name.AsNamed(), | ||
pins: pins, | ||
port: device, | ||
logger: logger, | ||
productID: productID, | ||
} | ||
|
||
b.analogs = map[string]*pinwrappers.AnalogSmoother{} | ||
|
@@ -419,6 +470,5 @@ func connect(ctx context.Context, name resource.Name, conf *Config, logger loggi | |
return nil, multierr.Combine(b.Close(ctx), err) | ||
} | ||
b.logger.CDebugw(ctx, "numato startup", "version", ver) | ||
|
||
return b, nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
//go:build darwin | ||
|
||
package numato | ||
|
||
import "go.viam.com/utils/usb" | ||
|
||
// getSerialDevices returns all devices connected by USB on a mac. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment doesn't really match code: I think this returns descriptions of devices, not devices themselves. and yet, I can get that from the function signature, so it doesn't necessarily need to be in the comment, too. but I still don't easily see what this function is for. I think the point is that we use it to find the productID of the numato board plugged in, and use that to figure out what capabilities the board has? That's the part that really belongs in a comment: supply the "why" that isn't easily gotten from the code (which supplies the "what"). Same suggestion in linux_utils.go, too. |
||
func getSerialDevices() []usb.Description { | ||
oliviamiller marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return usb.Search(usb.NewSearchFilter("AppleUSBACMData", "usbmodem"), func(vendorID, productID int) bool { | ||
return true | ||
}) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
//go:build linux | ||
|
||
package numato | ||
|
||
import "go.viam.com/utils/usb" | ||
|
||
// getSerialDevices returns all devices connected by USB on a linux machine. | ||
func getSerialDevices() []usb.Description { | ||
return usb.Search(usb.SearchFilter{}, func(vendorID, productID int) bool { | ||
return true | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Thanks for this comment!