gobot.io/x/gobot/v2@v2.1.0/platforms/dexter/gopigo3/driver.go (about)

     1  // Package gopigo3 is based on https://github.com/DexterInd/GoPiGo3/blob/master/Software/Python/gopigo3.py
     2  // You will need to run the following commands if using a stock raspbian image before this library will work:
     3  // sudo curl -kL dexterindustries.com/update_gopigo3 | bash
     4  // sudo reboot
     5  package gopigo3
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"math"
    12  	"time"
    13  
    14  	"gobot.io/x/gobot/v2"
    15  	"gobot.io/x/gobot/v2/drivers/spi"
    16  )
    17  
    18  // spi address for gopigo3
    19  const goPiGo3Address = 0x08
    20  
    21  // register addresses for gopigo3
    22  const (
    23  	NONE byte = iota
    24  	GET_MANUFACTURER
    25  	GET_NAME
    26  	GET_HARDWARE_VERSION
    27  	GET_FIRMWARE_VERSION
    28  	GET_ID
    29  	SET_LED
    30  	GET_VOLTAGE_5V
    31  	GET_VOLTAGE_VCC
    32  	SET_SERVO
    33  	SET_MOTOR_PWM
    34  	SET_MOTOR_POSITION
    35  	SET_MOTOR_POSITION_KP
    36  	SET_MOTOR_POSITION_KD
    37  	SET_MOTOR_DPS
    38  	SET_MOTOR_LIMITS
    39  	OFFSET_MOTOR_ENCODER
    40  	GET_MOTOR_ENCODER_LEFT
    41  	GET_MOTOR_ENCODER_RIGHT
    42  	GET_MOTOR_STATUS_LEFT
    43  	GET_MOTOR_STATUS_RIGHT
    44  	SET_GROVE_TYPE
    45  	SET_GROVE_MODE
    46  	SET_GROVE_STATE
    47  	SET_GROVE_PWM_DUTY
    48  	SET_GROVE_PWM_FREQUENCY
    49  	GET_GROVE_VALUE_1
    50  	GET_GROVE_VALUE_2
    51  	GET_GROVE_STATE_1_1
    52  	GET_GROVE_STATE_1_2
    53  	GET_GROVE_STATE_2_1
    54  	GET_GROVE_STATE_2_2
    55  	GET_GROVE_VOLTAGE_1_1
    56  	GET_GROVE_VOLTAGE_1_2
    57  	GET_GROVE_VOLTAGE_2_1
    58  	GET_GROVE_VOLTAGE_2_2
    59  	GET_GROVE_ANALOG_1_1
    60  	GET_GROVE_ANALOG_1_2
    61  	GET_GROVE_ANALOG_2_1
    62  	GET_GROVE_ANALOG_2_2
    63  	START_GROVE_I2C_1
    64  	START_GROVE_I2C_2
    65  )
    66  
    67  const (
    68  	WHEEL_BASE_WIDTH           = 117                                                       // distance (mm) from left wheel to right wheel. This works with the initial GPG3 prototype. Will need to be adjusted.
    69  	WHEEL_DIAMETER             = 66.5                                                      // wheel diameter (mm)
    70  	WHEEL_BASE_CIRCUMFERENCE   = WHEEL_BASE_WIDTH * math.Pi                                // circumference of the circle the wheels will trace while turning (mm)
    71  	WHEEL_CIRCUMFERENCE        = WHEEL_DIAMETER * math.Pi                                  // circumference of the wheels (mm)
    72  	MOTOR_GEAR_RATIO           = 120                                                       // motor gear ratio
    73  	ENCODER_TICKS_PER_ROTATION = 6                                                         // encoder ticks per motor rotation (number of magnet positions)
    74  	MOTOR_TICKS_PER_DEGREE     = ((MOTOR_GEAR_RATIO * ENCODER_TICKS_PER_ROTATION) / 360.0) // encoder ticks per output shaft rotation degree
    75  	GROVE_I2C_LENGTH_LIMIT     = 16
    76  	MOTOR_FLOAT                = -128
    77  )
    78  
    79  // GroveMode sets the mode of AD pins on the gopigo3.
    80  type GroveMode byte
    81  
    82  const (
    83  	GROVE_INPUT_DIGITAL          GroveMode = 0
    84  	GROVE_OUTPUT_DIGITAL         GroveMode = 1
    85  	GROVE_INPUT_DIGITAL_PULLUP   GroveMode = 2
    86  	GROVE_INPUT_DIGITAL_PULLDOWN GroveMode = 3
    87  	GROVE_INPUT_ANALOG           GroveMode = 4
    88  	GROVE_OUTPUT_PWM             GroveMode = 5
    89  	GROVE_INPUT_ANALOG_PULLUP    GroveMode = 6
    90  	GROVE_INPUT_ANALOG_PULLDOWN  GroveMode = 7
    91  )
    92  
    93  // Servo contains the address for the 2 servo ports.
    94  type Servo byte
    95  
    96  const (
    97  	SERVO_1 Servo = 0x01
    98  	SERVO_2 Servo = 0x02
    99  )
   100  
   101  // Motor contains the address for the left and right motors.
   102  type Motor byte
   103  
   104  const (
   105  	MOTOR_LEFT  Motor = 0x01
   106  	MOTOR_RIGHT Motor = 0x02
   107  )
   108  
   109  // Led contains the addresses for all leds on the board.
   110  type Led byte
   111  
   112  const (
   113  	LED_EYE_RIGHT     Led = 0x01
   114  	LED_EYE_LEFT      Led = 0x02
   115  	LED_BLINKER_LEFT  Led = 0x04
   116  	LED_BLINKER_RIGHT Led = 0x08
   117  	LED_WIFI          Led = 0x80
   118  )
   119  
   120  // Grove contains the addresses for pins/ports of the AD1/AD2 grove connector.
   121  type Grove byte
   122  
   123  const (
   124  	AD11     string = "AD_1_1"
   125  	AD12     string = "AD_1_2"
   126  	AD21     string = "AD_2_1"
   127  	AD22     string = "AD_2_2"
   128  	AD_1_1_G Grove  = 0x01 // default pin for most grove devices, A0/D0
   129  	AD_1_2_G Grove  = 0x02
   130  	AD_2_1_G Grove  = 0x04 // default pin for most grove devices, A0/D0
   131  	AD_2_2_G Grove  = 0x08
   132  	AD_1_G   Grove  = AD_1_1_G + AD_1_2_G
   133  	AD_2_G   Grove  = AD_2_1_G + AD_2_2_G
   134  )
   135  
   136  // GroveType represents the type of a grove device.
   137  type GroveType int
   138  
   139  const (
   140  	CUSTOM        GroveType = 1
   141  	IR_DI_REMOTE  GroveType = 2
   142  	IR_EV3_REMOTE GroveType = 3
   143  	US            GroveType = 4
   144  	I2C           GroveType = 5
   145  )
   146  
   147  // GroveState contains the state of a grove device.
   148  type GroveState int
   149  
   150  const (
   151  	VALID_DATA GroveState = iota
   152  	NOT_CONFIGURED
   153  	CONFIGURING
   154  	NO_DATA
   155  	I2C_ERROR
   156  )
   157  
   158  // Driver is a Gobot Driver for the GoPiGo3 board.
   159  type Driver struct {
   160  	name       string
   161  	connector  spi.Connector
   162  	connection spi.Connection
   163  	spi.Config
   164  }
   165  
   166  // NewDriver creates a new Gobot Driver for the GoPiGo3 board.
   167  //
   168  // Params:
   169  //
   170  //	a *Adaptor - the Adaptor to use with this Driver
   171  //
   172  // Optional params:
   173  //
   174  //	 spi.WithBusNumber(int):  bus to use with this driver
   175  //		spi.WithChipNumber(int): chip to use with this driver
   176  //	 spi.WithMode(int):    	 mode to use with this driver
   177  //	 spi.WithBitCount(int):   number of bits to use with this driver
   178  //	 spi.WithSpeed(int64):    speed in Hz to use with this driver
   179  func NewDriver(a spi.Connector, options ...func(spi.Config)) *Driver {
   180  	spiConfig := spi.NewConfig()
   181  	// use /dev/spidev0.1
   182  	spiConfig.SetBusNumber(0)
   183  	spiConfig.SetChipNumber(1)
   184  	g := &Driver{
   185  		name:      gobot.DefaultName("GoPiGo3"),
   186  		connector: a,
   187  		Config:    spiConfig,
   188  	}
   189  	for _, option := range options {
   190  		option(g)
   191  	}
   192  	return g
   193  }
   194  
   195  // Name returns the name of the device.
   196  func (g *Driver) Name() string { return g.name }
   197  
   198  // SetName sets the name of the device.
   199  func (g *Driver) SetName(n string) { g.name = n }
   200  
   201  // Connection returns the Connection of the device.
   202  func (g *Driver) Connection() gobot.Connection { return g.connection.(gobot.Connection) }
   203  
   204  // Halt stops the driver.
   205  func (g *Driver) Halt() (err error) {
   206  	g.resetAll()
   207  	time.Sleep(10 * time.Millisecond)
   208  	return
   209  }
   210  
   211  // Start initializes the GoPiGo3
   212  func (g *Driver) Start() (err error) {
   213  	bus := g.GetBusNumberOrDefault(g.connector.SpiDefaultBusNumber())
   214  	chip := g.GetChipNumberOrDefault(g.connector.SpiDefaultChipNumber())
   215  	mode := g.GetModeOrDefault(g.connector.SpiDefaultMode())
   216  	bits := g.GetBitCountOrDefault(g.connector.SpiDefaultBitCount())
   217  	maxSpeed := g.GetSpeedOrDefault(g.connector.SpiDefaultMaxSpeed())
   218  
   219  	g.connection, err = g.connector.GetSpiConnection(bus, chip, mode, bits, maxSpeed)
   220  	if err != nil {
   221  		return err
   222  	}
   223  	return nil
   224  }
   225  
   226  // GetManufacturerName returns the manufacturer from the firmware.
   227  func (g *Driver) GetManufacturerName() (mName string, err error) {
   228  	// read 24 bytes to get manufacturer name
   229  	response, err := g.readBytes(goPiGo3Address, GET_MANUFACTURER, 24)
   230  	if err != nil {
   231  		return mName, err
   232  	}
   233  	if err := g.responseValid(response); err != nil {
   234  		return mName, err
   235  	}
   236  	mf := response[4:23]
   237  	mf = bytes.Trim(mf, "\x00")
   238  	return string(mf), nil
   239  }
   240  
   241  // GetBoardName returns the board name from the firmware.
   242  func (g *Driver) GetBoardName() (bName string, err error) {
   243  	// read 24 bytes to get board name
   244  	response, err := g.readBytes(goPiGo3Address, GET_NAME, 24)
   245  	if err != nil {
   246  		return bName, err
   247  	}
   248  	if err := g.responseValid(response); err != nil {
   249  		return bName, err
   250  	}
   251  	mf := response[4:23]
   252  	mf = bytes.Trim(mf, "\x00")
   253  	return string(mf), nil
   254  }
   255  
   256  // GetHardwareVersion returns the hardware version from the firmware.
   257  func (g *Driver) GetHardwareVersion() (hVer string, err error) {
   258  	response, err := g.readUint32(goPiGo3Address, GET_HARDWARE_VERSION)
   259  	if err != nil {
   260  		return hVer, err
   261  	}
   262  	major := response / 1000000
   263  	minor := response / 1000 % 1000
   264  	patch := response % 1000
   265  	return fmt.Sprintf("%d.%d.%d", major, minor, patch), nil
   266  }
   267  
   268  // GetFirmwareVersion returns the current firmware version.
   269  func (g *Driver) GetFirmwareVersion() (fVer string, err error) {
   270  	response, err := g.readUint32(goPiGo3Address, GET_FIRMWARE_VERSION)
   271  	if err != nil {
   272  		return fVer, err
   273  	}
   274  	major := response / 1000000
   275  	minor := response / 1000 % 1000
   276  	patch := response % 1000
   277  	return fmt.Sprintf("%d.%d.%d", major, minor, patch), nil
   278  }
   279  
   280  // GetSerialNumber returns the 128-bit hardware serial number of the board.
   281  func (g *Driver) GetSerialNumber() (sNum string, err error) {
   282  	// read 20 bytes to get the serial number
   283  	response, err := g.readBytes(goPiGo3Address, GET_ID, 20)
   284  	if err != nil {
   285  		return sNum, err
   286  	}
   287  	if err := g.responseValid(response); err != nil {
   288  		return sNum, err
   289  	}
   290  	return fmt.Sprintf("%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", response[4], response[5], response[6], response[7], response[8], response[9], response[10], response[11], response[12], response[13], response[14], response[15], response[16], response[17], response[18], response[19]), nil
   291  }
   292  
   293  // Get5vVoltage returns the current voltage on the 5v line.
   294  func (g *Driver) Get5vVoltage() (voltage float32, err error) {
   295  	val, err := g.readUint16(goPiGo3Address, GET_VOLTAGE_5V)
   296  	return (float32(val) / 1000.0), err
   297  }
   298  
   299  // GetBatteryVoltage gets the battery voltage from the main battery pack (7v-12v).
   300  func (g *Driver) GetBatteryVoltage() (voltage float32, err error) {
   301  	val, err := g.readUint16(goPiGo3Address, GET_VOLTAGE_VCC)
   302  	return (float32(val) / 1000.0), err
   303  }
   304  
   305  // SetLED sets rgb values from 0 to 255.
   306  func (g *Driver) SetLED(led Led, red, green, blue uint8) error {
   307  	return g.writeBytes([]byte{
   308  		goPiGo3Address,
   309  		SET_LED,
   310  		byte(led),
   311  		byte(red),
   312  		byte(green),
   313  		byte(blue),
   314  	})
   315  }
   316  
   317  // SetServo sets a servo's position in microseconds (0-16666).
   318  func (g *Driver) SetServo(srvo Servo, us uint16) error {
   319  	return g.writeBytes([]byte{
   320  		goPiGo3Address,
   321  		SET_SERVO,
   322  		byte(srvo),
   323  		byte((us >> 8) & 0xFF),
   324  		byte(us & 0xFF),
   325  	})
   326  }
   327  
   328  // ServoWrite writes an angle (0-180) to the given servo (servo 1 or servo 2).
   329  // Must implement the ServoWriter interface of gpio package.
   330  func (g *Driver) ServoWrite(port string, angle byte) error {
   331  	srvo := SERVO_1 // default for unknown ports
   332  	if port == "2" || port == "SERVO_2" {
   333  		srvo = SERVO_2
   334  	}
   335  
   336  	pulseWidthRange := 1850
   337  	if angle > 180 {
   338  		angle = 180
   339  	}
   340  	pulseWidth := ((1500 - (pulseWidthRange / 2)) + ((pulseWidthRange / 180) * int(angle)))
   341  	return g.SetServo(srvo, uint16(pulseWidth))
   342  }
   343  
   344  // SetMotorPower sets a motor's power from -128 to 127.
   345  func (g *Driver) SetMotorPower(motor Motor, power int8) error {
   346  	return g.writeBytes([]byte{
   347  		goPiGo3Address,
   348  		SET_MOTOR_PWM,
   349  		byte(motor),
   350  		byte(power),
   351  	})
   352  }
   353  
   354  // SetMotorPosition sets the motor's position in degrees.
   355  func (g *Driver) SetMotorPosition(motor Motor, position int) error {
   356  	positionRaw := position * MOTOR_TICKS_PER_DEGREE
   357  	return g.writeBytes([]byte{
   358  		goPiGo3Address,
   359  		SET_MOTOR_POSITION,
   360  		byte(motor),
   361  		byte((positionRaw >> 24) & 0xFF),
   362  		byte((positionRaw >> 16) & 0xFF),
   363  		byte((positionRaw >> 8) & 0xFF),
   364  		byte(positionRaw & 0xFF),
   365  	})
   366  }
   367  
   368  // SetMotorDps sets the motor target speed in degrees per second.
   369  func (g *Driver) SetMotorDps(motor Motor, dps int) error {
   370  	d := dps * MOTOR_TICKS_PER_DEGREE
   371  	return g.writeBytes([]byte{
   372  		goPiGo3Address,
   373  		SET_MOTOR_DPS,
   374  		byte(motor),
   375  		byte((d >> 8) & 0xFF),
   376  		byte(d & 0xFF),
   377  	})
   378  }
   379  
   380  // SetMotorLimits sets the speed limits for a motor.
   381  func (g *Driver) SetMotorLimits(motor Motor, power int8, dps int) error {
   382  	dpsUint := dps * MOTOR_TICKS_PER_DEGREE
   383  	return g.writeBytes([]byte{
   384  		goPiGo3Address,
   385  		SET_MOTOR_LIMITS,
   386  		byte(motor),
   387  		byte(power),
   388  		byte((dpsUint >> 8) & 0xFF),
   389  		byte(dpsUint & 0xFF),
   390  	})
   391  }
   392  
   393  // GetMotorStatus returns the status for the given motor.
   394  func (g *Driver) GetMotorStatus(motor Motor) (flags uint8, power uint16, encoder, dps int, err error) {
   395  	message := GET_MOTOR_STATUS_RIGHT
   396  	if motor == MOTOR_LEFT {
   397  		message = GET_MOTOR_STATUS_LEFT
   398  	}
   399  	response, err := g.readBytes(goPiGo3Address, message, 12)
   400  	if err != nil {
   401  		return flags, power, encoder, dps, err
   402  	}
   403  	if err := g.responseValid(response); err != nil {
   404  		return flags, power, encoder, dps, err
   405  	}
   406  	// get flags
   407  	flags = uint8(response[4])
   408  	// get power
   409  	power = uint16(response[5])
   410  	if power&0x80 == 0x80 {
   411  		power = power - 0x100
   412  	}
   413  	// get encoder
   414  	enc := make([]byte, 4)
   415  	enc[3] = response[6]
   416  	enc[2] = response[7]
   417  	enc[1] = response[8]
   418  	enc[0] = response[9]
   419  	e := binary.LittleEndian.Uint32(enc)
   420  	encoder = int(e)
   421  	if e&0x80000000 == 0x80000000 {
   422  		encoder = int(uint64(e) - 0x100000000)
   423  	}
   424  	//get dps
   425  	d := make([]byte, 4)
   426  	d[1] = response[10]
   427  	d[0] = response[11]
   428  	ds := binary.LittleEndian.Uint32(d)
   429  	dps = int(ds)
   430  	if ds&0x8000 == 0x8000 {
   431  		dps = int(ds - 0x10000)
   432  	}
   433  	return flags, power, encoder / MOTOR_TICKS_PER_DEGREE, dps / MOTOR_TICKS_PER_DEGREE, nil
   434  }
   435  
   436  // GetMotorEncoder reads a motor's encoder in degrees.
   437  func (g *Driver) GetMotorEncoder(motor Motor) (encoder int64, err error) {
   438  	message := GET_MOTOR_ENCODER_RIGHT
   439  	if motor == MOTOR_LEFT {
   440  		message = GET_MOTOR_ENCODER_LEFT
   441  	}
   442  	response, err := g.readUint32(goPiGo3Address, message)
   443  	if err != nil {
   444  		return encoder, err
   445  	}
   446  	encoder = int64(response)
   447  	if response&0x80000000 != 0 {
   448  		encoder = encoder - 0x100000000
   449  	}
   450  	encoder = encoder / MOTOR_TICKS_PER_DEGREE
   451  	return encoder, nil
   452  }
   453  
   454  // OffsetMotorEncoder offsets a motor's encoder for calibration purposes.
   455  func (g *Driver) OffsetMotorEncoder(motor Motor, offset float64) error {
   456  	offsetUint := math.Float64bits(offset * MOTOR_TICKS_PER_DEGREE)
   457  	return g.writeBytes([]byte{
   458  		goPiGo3Address,
   459  		OFFSET_MOTOR_ENCODER,
   460  		byte(motor),
   461  		byte((offsetUint >> 24) & 0xFF),
   462  		byte((offsetUint >> 16) & 0xFF),
   463  		byte((offsetUint >> 8) & 0xFF),
   464  		byte(offsetUint & 0xFF),
   465  	})
   466  }
   467  
   468  // SetGroveType sets the given port to a grove device type.
   469  func (g *Driver) SetGroveType(port Grove, gType GroveType) error {
   470  	return g.writeBytes([]byte{
   471  		goPiGo3Address,
   472  		SET_GROVE_TYPE,
   473  		byte(port),
   474  		byte(gType),
   475  	})
   476  }
   477  
   478  // SetGroveMode sets the mode a given pin/port of the grove connector.
   479  func (g *Driver) SetGroveMode(port Grove, mode GroveMode) error {
   480  	return g.writeBytes([]byte{
   481  		goPiGo3Address,
   482  		SET_GROVE_MODE,
   483  		byte(port),
   484  		byte(mode),
   485  	})
   486  }
   487  
   488  // SetPWMDuty sets the pwm duty cycle for the given pin/port.
   489  func (g *Driver) SetPWMDuty(port Grove, duty uint16) (err error) {
   490  	if duty > 100 {
   491  		duty = 100
   492  	}
   493  	duty = duty * 10
   494  	return g.writeBytes([]byte{
   495  		goPiGo3Address,
   496  		SET_GROVE_PWM_DUTY,
   497  		byte(port),
   498  		byte((duty >> 8) & 0xFF),
   499  		byte(duty & 0xFF),
   500  	})
   501  }
   502  
   503  // SetPWMFreq setst the pwm frequency for the given pin/port.
   504  func (g *Driver) SetPWMFreq(port Grove, freq uint16) error {
   505  	if freq < 3 {
   506  		freq = 3
   507  	}
   508  	if freq > 48000 {
   509  		freq = 48000
   510  	}
   511  	return g.writeBytes([]byte{
   512  		goPiGo3Address,
   513  		SET_GROVE_PWM_FREQUENCY,
   514  		byte(port),
   515  		byte((freq >> 8) & 0xFF),
   516  		byte(freq & 0xFF),
   517  	})
   518  }
   519  
   520  // PwmWrite implents the pwm interface for the gopigo3.
   521  func (g *Driver) PwmWrite(pin string, val byte) (err error) {
   522  	var (
   523  		grovePin, grovePort Grove
   524  	)
   525  	grovePin, grovePort, _, _, err = getGroveAddresses(pin)
   526  	if err != nil {
   527  		return err
   528  	}
   529  	err = g.SetGroveType(grovePort, CUSTOM)
   530  	if err != nil {
   531  		return err
   532  	}
   533  	time.Sleep(10 * time.Millisecond)
   534  	err = g.SetGroveMode(grovePin, GROVE_OUTPUT_PWM)
   535  	if err != nil {
   536  		return err
   537  	}
   538  	time.Sleep(10 * time.Millisecond)
   539  	err = g.SetPWMFreq(grovePin, 24000)
   540  	if err != nil {
   541  		return err
   542  	}
   543  	val64 := math.Float64frombits(uint64(val))
   544  	dutyCycle := uint16(math.Float64bits((100.0 / 255.0) * val64))
   545  	return g.SetPWMDuty(grovePin, dutyCycle)
   546  }
   547  
   548  // AnalogRead returns the analog value of the given pin.
   549  func (g *Driver) AnalogRead(pin string) (value int, err error) {
   550  	var (
   551  		grovePin, grovePort Grove
   552  		analogCmd           byte
   553  	)
   554  	grovePin, grovePort, analogCmd, _, err = getGroveAddresses(pin)
   555  	if err != nil {
   556  		return value, err
   557  	}
   558  	err = g.SetGroveType(grovePort, CUSTOM)
   559  	if err != nil {
   560  		return value, err
   561  	}
   562  	time.Sleep(10 * time.Millisecond)
   563  	err = g.SetGroveMode(grovePin, GROVE_INPUT_ANALOG)
   564  	if err != nil {
   565  		return value, err
   566  	}
   567  	time.Sleep(10 * time.Millisecond)
   568  	response, err := g.readBytes(goPiGo3Address, analogCmd, 7)
   569  	if err != nil {
   570  		return value, err
   571  	}
   572  	if err := g.responseValid(response); err != nil {
   573  		return value, err
   574  	}
   575  	if err := g.valueValid(response); err != nil {
   576  		return value, err
   577  	}
   578  	highBytes := uint16(response[5])
   579  	lowBytes := uint16(response[6])
   580  	return int((highBytes<<8)&0xFF00) | int(lowBytes&0xFF), nil
   581  }
   582  
   583  // DigitalWrite writes a 0/1 value to the given pin.
   584  func (g *Driver) DigitalWrite(pin string, val byte) (err error) {
   585  	var (
   586  		grovePin, grovePort Grove
   587  	)
   588  	grovePin, grovePort, _, _, err = getGroveAddresses(pin)
   589  	if err != nil {
   590  		return err
   591  	}
   592  	err = g.SetGroveType(grovePort, CUSTOM)
   593  	if err != nil {
   594  		return err
   595  	}
   596  	time.Sleep(10 * time.Millisecond)
   597  	err = g.SetGroveMode(grovePin, GROVE_OUTPUT_DIGITAL)
   598  	if err != nil {
   599  		return err
   600  	}
   601  	time.Sleep(10 * time.Millisecond)
   602  	err = g.writeBytes([]byte{
   603  		goPiGo3Address,
   604  		SET_GROVE_STATE,
   605  		byte(grovePin),
   606  		byte(val),
   607  	})
   608  	return err
   609  }
   610  
   611  // DigitalRead reads the 0/1 value from the given pin.
   612  func (g *Driver) DigitalRead(pin string) (value int, err error) {
   613  	var (
   614  		grovePin, grovePort Grove
   615  		stateCmd            byte
   616  	)
   617  	grovePin, grovePort, _, stateCmd, err = getGroveAddresses(pin)
   618  	if err != nil {
   619  		return value, err
   620  	}
   621  	err = g.SetGroveType(grovePort, CUSTOM)
   622  	if err != nil {
   623  		return value, err
   624  	}
   625  	time.Sleep(10 * time.Millisecond)
   626  	err = g.SetGroveMode(grovePin, GROVE_INPUT_DIGITAL)
   627  	if err != nil {
   628  		return value, err
   629  	}
   630  	time.Sleep(10 * time.Millisecond)
   631  	response, err := g.readBytes(goPiGo3Address, stateCmd, 6)
   632  	if err != nil {
   633  		return value, err
   634  	}
   635  	if err := g.responseValid(response); err != nil {
   636  		return value, err
   637  	}
   638  	if err := g.valueValid(response); err != nil {
   639  		return value, err
   640  	}
   641  	return int(response[5]), nil
   642  }
   643  
   644  func getGroveAddresses(pin string) (gPin, gPort Grove, analog, state byte, err error) {
   645  	switch pin {
   646  	case "AD_1_1":
   647  		gPin = AD_1_1_G
   648  		gPort = AD_1_G
   649  		analog = GET_GROVE_ANALOG_1_1
   650  		state = GET_GROVE_STATE_1_1
   651  	case "AD_1_2":
   652  		gPin = AD_1_2_G
   653  		gPort = AD_1_G
   654  		analog = GET_GROVE_ANALOG_1_2
   655  		state = GET_GROVE_STATE_1_2
   656  	case "AD_2_1":
   657  		gPin = AD_2_1_G
   658  		gPort = AD_2_G
   659  		analog = GET_GROVE_ANALOG_2_1
   660  		state = GET_GROVE_STATE_2_1
   661  	case "AD_2_2":
   662  		gPin = AD_2_2_G
   663  		gPort = AD_2_G
   664  		analog = GET_GROVE_ANALOG_2_2
   665  		state = GET_GROVE_STATE_2_2
   666  	default:
   667  		err = fmt.Errorf("Invalid grove pin name")
   668  	}
   669  	return gPin, gPort, analog, state, err
   670  }
   671  
   672  func (g *Driver) responseValid(response []byte) error {
   673  	if response[3] != 0xA5 {
   674  		return fmt.Errorf("No SPI response, response not valid")
   675  	}
   676  	return nil
   677  }
   678  
   679  func (g *Driver) valueValid(value []byte) error {
   680  	if value[4] != byte(VALID_DATA) {
   681  		return fmt.Errorf("Invalid value")
   682  	}
   683  	return nil
   684  }
   685  
   686  func (g *Driver) readBytes(address byte, msg byte, numBytes int) (val []byte, err error) {
   687  	w := make([]byte, numBytes)
   688  	w[0] = address
   689  	w[1] = msg
   690  	r := make([]byte, len(w))
   691  	err = g.connection.ReadCommandData(w, r)
   692  	if err != nil {
   693  		return val, err
   694  	}
   695  	return r, nil
   696  }
   697  
   698  func (g *Driver) readUint16(address, msg byte) (val uint16, err error) {
   699  	r, err := g.readBytes(address, msg, 8)
   700  	if err != nil {
   701  		return val, err
   702  	}
   703  	if err := g.responseValid(r); err != nil {
   704  		return val, err
   705  	}
   706  	return uint16(r[4])<<8 | uint16(r[5]), nil
   707  }
   708  
   709  func (g *Driver) readUint32(address, msg byte) (val uint32, err error) {
   710  	r, err := g.readBytes(address, msg, 8)
   711  	if err != nil {
   712  		return val, err
   713  	}
   714  	if err := g.responseValid(r); err != nil {
   715  		return val, err
   716  	}
   717  	return uint32(r[4])<<24 | uint32(r[5])<<16 | uint32(r[6])<<8 | uint32(r[7]), nil
   718  }
   719  
   720  func (g *Driver) writeBytes(w []byte) (err error) {
   721  	return g.connection.WriteBytes(w)
   722  }
   723  
   724  func (g *Driver) resetAll() {
   725  	g.SetGroveType(AD_1_G+AD_2_G, CUSTOM)
   726  	time.Sleep(10 * time.Millisecond)
   727  	g.SetGroveMode(AD_1_G+AD_2_G, GROVE_INPUT_DIGITAL)
   728  	time.Sleep(10 * time.Millisecond)
   729  	g.SetMotorPower(MOTOR_LEFT+MOTOR_RIGHT, 0.0)
   730  	g.SetMotorLimits(MOTOR_LEFT+MOTOR_RIGHT, 0, 0)
   731  	g.SetServo(SERVO_1+SERVO_2, 0)
   732  	g.SetLED(LED_EYE_LEFT+LED_EYE_RIGHT+LED_BLINKER_LEFT+LED_BLINKER_RIGHT, 0, 0, 0)
   733  }