-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tinkerboard2: introduce adapter for Asus Tinker Board 2 (#1108)
- Loading branch information
1 parent
29893b1
commit c1a11a6
Showing
45 changed files
with
1,236 additions
and
1,507 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
//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/tinkerboard/tinkerboard2" | ||
) | ||
|
||
// Wiring | ||
// PWR Tinkerboard-2: 1 (+3.3V, VCC), 2(+5V), 6, 9, 14, 20 (GND) | ||
// GPIO Tinkerboard-2: header pins 3, 5, 7, 11 used as inverted output | ||
// LED's: the output pins are wired to the cathode of a LED, the anode is wired with a resistor (70-130Ohm for 20mA) | ||
// to +3.3V (use >150Ohm if connected to +5V) | ||
// Expected behavior: the 4 LED's on normal output counts up binary | ||
func main() { | ||
const ( | ||
outPinBit0Num = "3" | ||
outPinBit1Num = "5" | ||
outPinBit2Num = "7" | ||
outPinBit3Num = "11" | ||
) | ||
|
||
board := tinkerboard2.NewAdaptor(adaptors.WithGpiosActiveLow(outPinBit0Num, outPinBit1Num, outPinBit2Num, | ||
outPinBit3Num)) | ||
outPinB0 := gpio.NewDirectPinDriver(board, outPinBit0Num) | ||
outPinB1 := gpio.NewDirectPinDriver(board, outPinBit1Num) | ||
outPinB2 := gpio.NewDirectPinDriver(board, outPinBit2Num) | ||
outPinB3 := gpio.NewDirectPinDriver(board, outPinBit3Num) | ||
|
||
work := func() { | ||
value := byte(0) | ||
|
||
gobot.Every(500*time.Millisecond, func() { | ||
b0 := value & 0x01 | ||
b1 := (value & 0x02) / 0x02 | ||
b2 := (value & 0x04) / 0x04 | ||
b3 := (value & 0x08) / 0x08 | ||
|
||
if err := outPinB0.DigitalWrite(b0); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
fmt.Printf("pin %s is now %d\n", outPinBit0Num, b0) | ||
} | ||
|
||
if err := outPinB1.DigitalWrite(b1); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
fmt.Printf("pin %s is now %d\n", outPinBit1Num, b1) | ||
} | ||
|
||
if err := outPinB2.DigitalWrite(b2); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
fmt.Printf("pin %s is now %d\n", outPinBit2Num, b2) | ||
} | ||
|
||
if err := outPinB3.DigitalWrite(b3); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
fmt.Printf("pin %s is now %d\n", outPinBit3Num, b3) | ||
} | ||
|
||
value++ | ||
if value > 15 { | ||
value = 0 | ||
} | ||
}) | ||
} | ||
|
||
robot := gobot.NewRobot("pinBot", | ||
[]gobot.Connection{board}, | ||
[]gobot.Device{outPinB0, outPinB1, outPinB2, outPinB3}, | ||
work, | ||
) | ||
|
||
if err := robot.Start(); err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//go:build example | ||
// +build example | ||
|
||
// | ||
// Do not build by default. | ||
|
||
package main | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"time" | ||
|
||
"gobot.io/x/gobot/v2" | ||
"gobot.io/x/gobot/v2/drivers/i2c" | ||
"gobot.io/x/gobot/v2/platforms/tinkerboard/tinkerboard2" | ||
) | ||
|
||
func main() { | ||
// Wiring | ||
// PWR Tinkerboard 2: 1 (+3.3V, VCC), 6, 9, 14, 20 (GND) | ||
// I2C1 Tinkerboard 2: 27 (SDA), 28 (SCL) | ||
// YL-40 module: wire AOUT --> AIN2 for this example, set all jumpers for temp, LDR and variable resistor | ||
// | ||
// Note: temperature measurement is often buggy, because sensor is not properly grounded | ||
// fix it by soldering a small bridge to the adjacent ground pin of brightness sensor | ||
board := tinkerboard2.NewAdaptor() | ||
yl := i2c.NewYL40Driver(board, i2c.WithBus(7)) | ||
|
||
work := func() { | ||
// the LED light is visible above ~1.7V | ||
writeVal, _ := yl.AOUT() | ||
|
||
gobot.Every(1000*time.Millisecond, func() { | ||
if err := yl.Write(writeVal); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf(" %.1f V written", writeVal) | ||
writeVal = writeVal + 0.1 | ||
if writeVal > 3.3 { | ||
writeVal = 0 | ||
} | ||
} | ||
|
||
if brightness, err := yl.ReadBrightness(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Brightness: %.0f [0..1000]", brightness) | ||
} | ||
|
||
if temperature, err := yl.ReadTemperature(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Temperature: %.1f °C", temperature) | ||
} | ||
|
||
if ain2, err := yl.ReadAIN2(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Read back AOUT: %.1f [0..3.3]", ain2) | ||
} | ||
|
||
if potiState, err := yl.ReadPotentiometer(); err != nil { | ||
fmt.Println(err) | ||
} else { | ||
log.Printf("Resistor: %.0f %% [-100..+100]", potiState) | ||
} | ||
}) | ||
} | ||
|
||
robot := gobot.NewRobot("yl40Bot", | ||
[]gobot.Connection{board}, | ||
[]gobot.Device{yl}, | ||
work, | ||
) | ||
|
||
if err := robot.Start(); err != nil { | ||
panic(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package adaptors | ||
|
||
import ( | ||
"fmt" | ||
|
||
"gobot.io/x/gobot/v2/system" | ||
) | ||
|
||
type AnalogPinDefinition struct { | ||
Path string | ||
R bool // readable | ||
W bool // writable | ||
BufLen uint16 | ||
} | ||
|
||
type AnalogPinDefinitions map[string]AnalogPinDefinition | ||
|
||
type AnalogPinTranslator struct { | ||
sys *system.Accesser | ||
pinDefinitions AnalogPinDefinitions | ||
} | ||
|
||
// NewAnalogPinTranslator creates a new instance of a translator for analog pins, suitable for the most cases. | ||
func NewAnalogPinTranslator(sys *system.Accesser, pinDefinitions AnalogPinDefinitions) *AnalogPinTranslator { | ||
return &AnalogPinTranslator{sys: sys, pinDefinitions: pinDefinitions} | ||
} | ||
|
||
// Translate returns the sysfs path for the given id. | ||
func (pt *AnalogPinTranslator) Translate(id string) (string, bool, 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) | ||
} | ||
|
||
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) | ||
} | ||
if info.IsDir() { | ||
return "", false, false, 0, fmt.Errorf("The item '%s' is a directory, which is not expected", path) | ||
} | ||
|
||
return path, pinInfo.R, pinInfo.W, pinInfo.BufLen, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package adaptors | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
|
||
"gobot.io/x/gobot/v2/system" | ||
) | ||
|
||
func TestNewAnalogPinTranslator(t *testing.T) { | ||
// arrange | ||
sys := &system.Accesser{} | ||
pinDef := AnalogPinDefinitions{} | ||
// act | ||
pt := NewAnalogPinTranslator(sys, pinDef) | ||
// assert | ||
assert.IsType(t, &AnalogPinTranslator{}, pt) | ||
assert.Equal(t, sys, pt.sys) | ||
assert.Equal(t, pinDef, pt.pinDefinitions) | ||
} | ||
|
||
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}, | ||
} | ||
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 | ||
}{ | ||
"translate_thermal_zone0": { | ||
id: "thermal_zone0", | ||
wantPath: "/sys/class/thermal/thermal_zone0/temp", | ||
wantReadable: true, | ||
wantBufLen: 7, | ||
}, | ||
"translate_thermal_zone1": { | ||
id: "thermal_zone1", | ||
wantPath: "/sys/class/thermal/thermal_zone1/temp", | ||
wantReadable: true, | ||
wantBufLen: 7, | ||
}, | ||
"unknown_id": { | ||
id: "99", | ||
wantErr: "'99' is not a valid id for an analog pin", | ||
}, | ||
} | ||
for name, tc := range tests { | ||
t.Run(name, func(t *testing.T) { | ||
// arrange | ||
sys := system.NewAccesser() | ||
_ = sys.UseMockFilesystem(mockedPaths) | ||
pt := NewAnalogPinTranslator(sys, pinDefinitions) | ||
// act | ||
path, r, 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) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package adaptors | ||
|
||
import "fmt" | ||
|
||
type BusNumberValidator struct { | ||
validNumbers []int | ||
} | ||
|
||
// NewBusNumberValidator creates a new instance for a bus number validator, used for I2C and SPI. | ||
func NewBusNumberValidator(validNumbers []int) *BusNumberValidator { | ||
return &BusNumberValidator{validNumbers: validNumbers} | ||
} | ||
|
||
func (bnv *BusNumberValidator) Validate(busNr int) error { | ||
for _, validNumber := range bnv.validNumbers { | ||
if validNumber == busNr { | ||
return nil | ||
} | ||
} | ||
|
||
return fmt.Errorf("Bus number %d out of range %v", busNr, bnv.validNumbers) | ||
} |
Oops, something went wrong.