Skip to content
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

gpio(adaptors): fix so now gpiodev is used as default #1112

Merged
merged 1 commit into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions examples/beaglepocket_direct_pin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//go:build example
// +build example

//
// Do not build by default.

package main

import (
"fmt"
"time"

"gobot.io/x/gobot/v2"
"gobot.io/x/gobot/v2/drivers/gpio"
"gobot.io/x/gobot/v2/platforms/adaptors"
"gobot.io/x/gobot/v2/platforms/beaglebone"
)

// Wiring
// PWR Pocket: P1.14, P2.23 (+3.3V, VCC); P1.15, P1.16, P1.22, P2.15, P2.21 (GND)
// GPIO Pocket: header pin P1.34 is input, pin P1.35 is normal output, pin P1.36 is inverted output
// Button: the input pin is wired with a button to GND, an external pull up resistor is needed (e.g. 2kOhm to VCC)
// LED's: the output pins are wired to the cathode of the LED, the anode is wired with a resistor (70-130Ohm for 20mA)
// to VCC
// Expected behavior: always one LED is on, the other in opposite state, if button is pressed the state changes
func main() {
const (
inPinNum = "P1_34"
outPinNum = "P1_35"
outPinInvertedNum = "P1_36"
)

board := beaglebone.NewPocketBeagleAdaptor(adaptors.WithGpiosActiveLow(outPinInvertedNum))

inPin := gpio.NewDirectPinDriver(board, inPinNum)
outPin := gpio.NewDirectPinDriver(board, outPinNum)
outPinInverted := gpio.NewDirectPinDriver(board, outPinInvertedNum)

work := func() {
gobot.Every(500*time.Millisecond, func() {
read, err := inPin.DigitalRead()
fmt.Printf("pin %s state is %d\n", inPinNum, read)
if err != nil {
fmt.Println(err)
}

level := byte(read)

err = outPin.DigitalWrite(level)
fmt.Printf("pin %s is now %d\n", outPinNum, level)
if err != nil {
fmt.Println(err)
}

err = outPinInverted.DigitalWrite(level)
fmt.Printf("pin %s is now not %d\n", outPinInvertedNum, level)
if err != nil {
fmt.Println(err)
}
})
}

robot := gobot.NewRobot("pinBot",
[]gobot.Connection{board},
[]gobot.Device{inPin, outPin, outPinInverted},
work,
)

if err := robot.Start(); err != nil {
panic(err)
}
}
6 changes: 3 additions & 3 deletions platforms/adaptors/analogpinsadaptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"gobot.io/x/gobot/v2/system"
)

type analogPinTranslator func(pin string) (path string, r, w bool, bufLen uint16, err error)
type analogPinTranslator func(pin string) (path string, w bool, readBufLen uint16, err error)

// AnalogPinsAdaptor is a adaptor for analog pins, normally used for composition in platforms.
// It is also usable for general sysfs access.
Expand Down Expand Up @@ -83,11 +83,11 @@ func (a *AnalogPinsAdaptor) analogPin(id string) (gobot.AnalogPinner, error) {
pin := a.pins[id]

if pin == nil {
path, r, w, bufLen, err := a.translate(id)
path, w, readBufLen, err := a.translate(id)
if err != nil {
return nil, err
}
pin = a.sys.NewAnalogPin(path, r, w, bufLen)
pin = a.sys.NewAnalogPin(path, w, readBufLen)
a.pins[id] = pin
}

Expand Down
14 changes: 7 additions & 7 deletions platforms/adaptors/analogpinsadaptor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,23 @@ func initTestAnalogPinsAdaptorWithMockedFilesystem(mockPaths []string) (*AnalogP
return a, fs
}

func testAnalogPinTranslator(id string) (string, bool, bool, uint16, error) {
func testAnalogPinTranslator(id string) (string, bool, uint16, error) {
switch id {
case "read":
return analogReadPath, true, false, 10, nil
return analogReadPath, false, 10, nil
case "write":
return analogWritePath, false, true, 11, nil
return analogWritePath, true, 0, nil
case "read/write":
return analogReadWritePath, true, true, 12, nil
return analogReadWritePath, true, 12, nil
case "read/write_string":
return analogReadWriteStringPath, true, true, 13, nil
return analogReadWriteStringPath, true, 13, nil
}

return "", false, false, 0, fmt.Errorf("'%s' is not a valid id of an analog pin", id)
return "", false, 0, fmt.Errorf("'%s' is not a valid id of an analog pin", id)
}

func TestAnalogPinsConnect(t *testing.T) {
translate := func(id string) (path string, r, w bool, bufLen uint16, err error) { return }
translate := func(id string) (path string, w bool, bufLen uint16, err error) { return }
a := NewAnalogPinsAdaptor(system.NewAccesser(), translate)
assert.Equal(t, (map[string]gobot.AnalogPinner)(nil), a.pins)

Expand Down
17 changes: 8 additions & 9 deletions platforms/adaptors/analogpintranslator.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@ import (
)

type AnalogPinDefinition struct {
Path string
R bool // readable
W bool // writable
BufLen uint16
Path string
W bool // writable
ReadBufLen uint16 // readable if buffer > 0
}

type AnalogPinDefinitions map[string]AnalogPinDefinition
Expand All @@ -26,20 +25,20 @@ func NewAnalogPinTranslator(sys *system.Accesser, pinDefinitions AnalogPinDefini
}

// Translate returns the sysfs path for the given id.
func (pt *AnalogPinTranslator) Translate(id string) (string, bool, bool, uint16, error) {
func (pt *AnalogPinTranslator) Translate(id string) (string, bool, uint16, error) {
pinInfo, ok := pt.pinDefinitions[id]
if !ok {
return "", false, false, 0, fmt.Errorf("'%s' is not a valid id for an analog pin", id)
return "", false, 0, fmt.Errorf("'%s' is not a valid id for an analog pin", id)
}

path := pinInfo.Path
info, err := pt.sys.Stat(path)
if err != nil {
return "", false, false, 0, fmt.Errorf("Error (%v) on access '%s'", err, path)
return "", false, 0, fmt.Errorf("Error (%v) on access '%s'", err, path)
}
if info.IsDir() {
return "", false, false, 0, fmt.Errorf("The item '%s' is a directory, which is not expected", path)
return "", false, 0, fmt.Errorf("The item '%s' is a directory, which is not expected", path)
}

return path, pinInfo.R, pinInfo.W, pinInfo.BufLen, nil
return path, pinInfo.W, pinInfo.ReadBufLen, nil
}
30 changes: 13 additions & 17 deletions platforms/adaptors/analogpintranslator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,28 @@ func TestNewAnalogPinTranslator(t *testing.T) {

func TestAnalogPinTranslatorTranslate(t *testing.T) {
pinDefinitions := AnalogPinDefinitions{
"thermal_zone0": {Path: "/sys/class/thermal/thermal_zone0/temp", R: true, W: false, BufLen: 7},
"thermal_zone1": {Path: "/sys/class/thermal/thermal_zone1/temp", R: true, W: false, BufLen: 7},
"thermal_zone0": {Path: "/sys/class/thermal/thermal_zone0/temp", W: false, ReadBufLen: 7},
"thermal_zone1": {Path: "/sys/class/thermal/thermal_zone1/temp", W: false, ReadBufLen: 7},
}
mockedPaths := []string{
"/sys/class/thermal/thermal_zone0/temp",
"/sys/class/thermal/thermal_zone1/temp",
}
tests := map[string]struct {
id string
wantPath string
wantReadable bool
wantBufLen uint16
wantErr string
id string
wantPath string
wantBufLen uint16
wantErr string
}{
"translate_thermal_zone0": {
id: "thermal_zone0",
wantPath: "/sys/class/thermal/thermal_zone0/temp",
wantReadable: true,
wantBufLen: 7,
id: "thermal_zone0",
wantPath: "/sys/class/thermal/thermal_zone0/temp",
wantBufLen: 7,
},
"translate_thermal_zone1": {
id: "thermal_zone1",
wantPath: "/sys/class/thermal/thermal_zone1/temp",
wantReadable: true,
wantBufLen: 7,
id: "thermal_zone1",
wantPath: "/sys/class/thermal/thermal_zone1/temp",
wantBufLen: 7,
},
"unknown_id": {
id: "99",
Expand All @@ -61,15 +58,14 @@ func TestAnalogPinTranslatorTranslate(t *testing.T) {
_ = sys.UseMockFilesystem(mockedPaths)
pt := NewAnalogPinTranslator(sys, pinDefinitions)
// act
path, r, w, buf, err := pt.Translate(tc.id)
path, w, buf, err := pt.Translate(tc.id)
// assert
if tc.wantErr != "" {
require.EqualError(t, err, tc.wantErr)
} else {
require.NoError(t, err)
}
assert.Equal(t, tc.wantPath, path)
assert.Equal(t, tc.wantReadable, r)
assert.False(t, w)
assert.Equal(t, tc.wantBufLen, buf)
})
Expand Down
Loading
Loading