gobot.io/x/gobot@v1.16.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"
    15  	"gobot.io/x/gobot/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            = 2
   142  	IR_EV3_REMOTE           = 3
   143  	US                      = 4
   144  	I2C                     = 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  //      a *Adaptor - the Adaptor to use with this Driver
   170  //
   171  // Optional params:
   172  //      spi.WithBus(int):    	bus to use with this driver
   173  //     	spi.WithChip(int):    	chip to use with this driver
   174  //      spi.WithMode(int):    	mode to use with this driver
   175  //      spi.WithBits(int):    	number of bits to use with this driver
   176  //      spi.WithSpeed(int64):   speed in Hz to use with this driver
   177  //
   178  func NewDriver(a spi.Connector, options ...func(spi.Config)) *Driver {
   179  	spiConfig := spi.NewConfig()
   180  	// use /dev/spidev0.1
   181  	spiConfig.WithBus(0)
   182  	spiConfig.WithChip(1)
   183  	g := &Driver{
   184  		name:      gobot.DefaultName("GoPiGo3"),
   185  		connector: a,
   186  		Config:    spiConfig,
   187  	}
   188  	for _, option := range options {
   189  		option(g)
   190  	}
   191  	return g
   192  }
   193  
   194  // Name returns the name of the device.
   195  func (g *Driver) Name() string { return g.name }
   196  
   197  // SetName sets the name of the device.
   198  func (g *Driver) SetName(n string) { g.name = n }
   199  
   200  // Connection returns the Connection of the device.
   201  func (g *Driver) Connection() gobot.Connection { return g.connection.(gobot.Connection) }
   202  
   203  // Halt stops the driver.
   204  func (g *Driver) Halt() (err error) {
   205  	g.resetAll()
   206  	time.Sleep(10 * time.Millisecond)
   207  	return
   208  }
   209  
   210  // Start initializes the GoPiGo3
   211  func (g *Driver) Start() (err error) {
   212  	bus := g.GetBusOrDefault(g.connector.GetSpiDefaultBus())
   213  	chip := g.GetChipOrDefault(g.connector.GetSpiDefaultChip())
   214  	mode := g.GetModeOrDefault(g.connector.GetSpiDefaultMode())
   215  	bits := g.GetBitsOrDefault(g.connector.GetSpiDefaultBits())
   216  	maxSpeed := g.GetSpeedOrDefault(g.connector.GetSpiDefaultMaxSpeed())
   217  
   218  	g.connection, err = g.connector.GetSpiConnection(bus, chip, mode, bits, maxSpeed)
   219  	if err != nil {
   220  		return err
   221  	}
   222  	return nil
   223  }
   224  
   225  // GetManufacturerName returns the manufacturer from the firmware.
   226  func (g *Driver) GetManufacturerName() (mName string, err error) {
   227  	// read 24 bytes to get manufacturer name
   228  	response, err := g.readBytes(goPiGo3Address, GET_MANUFACTURER, 24)
   229  	if err != nil {
   230  		return mName, err
   231  	}
   232  	if err := g.responseValid(response); err != nil {
   233  		return mName, err
   234  	}
   235  	mf := response[4:23]
   236  	mf = bytes.Trim(mf, "\x00")
   237  	return fmt.Sprintf("%s", string(mf)), nil
   238  }
   239  
   240  // GetBoardName returns the board name from the firmware.
   241  func (g *Driver) GetBoardName() (bName string, err error) {
   242  	// read 24 bytes to get board name
   243  	response, err := g.readBytes(goPiGo3Address, GET_NAME, 24)
   244  	if err != nil {
   245  		return bName, err
   246  	}
   247  	if err := g.responseValid(response); err != nil {
   248  		return bName, err
   249  	}
   250  	mf := response[4:23]
   251  	mf = bytes.Trim(mf, "\x00")
   252  	return fmt.Sprintf("%s", string(mf)), nil
   253  }
   254  
   255  // GetHardwareVersion returns the hardware version from the firmware.
   256  func (g *Driver) GetHardwareVersion() (hVer string, err error) {
   257  	response, err := g.readUint32(goPiGo3Address, GET_HARDWARE_VERSION)
   258  	if err != nil {
   259  		return hVer, err
   260  	}
   261  	major := response / 1000000
   262  	minor := response / 1000 % 1000
   263  	patch := response % 1000
   264  	return fmt.Sprintf("%d.%d.%d", major, minor, patch), nil
   265  }
   266  
   267  // GetFirmwareVersion returns the current firmware version.
   268  func (g *Driver) GetFirmwareVersion() (fVer string, err error) {
   269  	response, err := g.readUint32(goPiGo3Address, GET_FIRMWARE_VERSION)
   270  	if err != nil {
   271  		return fVer, err
   272  	}
   273  	major := response / 1000000
   274  	minor := response / 1000 % 1000
   275  	patch := response % 1000
   276  	return fmt.Sprintf("%d.%d.%d", major, minor, patch), nil
   277  }
   278  
   279  // GetSerialNumber returns the 128-bit hardware serial number of the board.
   280  func (g *Driver) GetSerialNumber() (sNum string, err error) {
   281  	// read 20 bytes to get the serial number
   282  	response, err := g.readBytes(goPiGo3Address, GET_ID, 20)
   283  	if err != nil {
   284  		return sNum, err
   285  	}
   286  	if err := g.responseValid(response); err != nil {
   287  		return sNum, err
   288  	}
   289  	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
   290  }
   291  
   292  // Get5vVoltage returns the current voltage on the 5v line.
   293  func (g *Driver) Get5vVoltage() (voltage float32, err error) {
   294  	val, err := g.readUint16(goPiGo3Address, GET_VOLTAGE_5V)
   295  	return (float32(val) / 1000.0), err
   296  }
   297  
   298  // GetBatteryVoltage gets the battery voltage from the main battery pack (7v-12v).
   299  func (g *Driver) GetBatteryVoltage() (voltage float32, err error) {
   300  	val, err := g.readUint16(goPiGo3Address, GET_VOLTAGE_VCC)
   301  	return (float32(val) / 1000.0), err
   302  }
   303  
   304  // SetLED sets rgb values from 0 to 255.
   305  func (g *Driver) SetLED(led Led, red, green, blue uint8) error {
   306  	return g.writeBytes([]byte{
   307  		goPiGo3Address,
   308  		SET_LED,
   309  		byte(led),
   310  		byte(red),
   311  		byte(green),
   312  		byte(blue),
   313  	})
   314  }
   315  
   316  // SetServo sets a servo's position in microseconds (0-16666).
   317  func (g *Driver) SetServo(srvo Servo, us uint16) error {
   318  	return g.writeBytes([]byte{
   319  		goPiGo3Address,
   320  		SET_SERVO,
   321  		byte(srvo),
   322  		byte((us >> 8) & 0xFF),
   323  		byte(us & 0xFF),
   324  	})
   325  }
   326  
   327  // ServoWrite writes an angle (0-180) to the given servo (servo 1 or servo 2).
   328  func (g *Driver) ServoWrite(srvo Servo, angle byte) error {
   329  	pulseWidthRange := 1850
   330  	if angle > 180 {
   331  		angle = 180
   332  	}
   333  	if angle < 0 {
   334  		angle = 0
   335  	}
   336  	pulseWidth := ((1500 - (pulseWidthRange / 2)) + ((pulseWidthRange / 180) * int(angle)))
   337  	return g.SetServo(srvo, uint16(pulseWidth))
   338  }
   339  
   340  // SetMotorPower sets a motor's power from -128 to 127.
   341  func (g *Driver) SetMotorPower(motor Motor, power int8) error {
   342  	return g.writeBytes([]byte{
   343  		goPiGo3Address,
   344  		SET_MOTOR_PWM,
   345  		byte(motor),
   346  		byte(power),
   347  	})
   348  }
   349  
   350  // SetMotorPosition sets the motor's position in degrees.
   351  func (g *Driver) SetMotorPosition(motor Motor, position int) error {
   352  	positionRaw := position * MOTOR_TICKS_PER_DEGREE
   353  	return g.writeBytes([]byte{
   354  		goPiGo3Address,
   355  		SET_MOTOR_POSITION,
   356  		byte(motor),
   357  		byte((positionRaw >> 24) & 0xFF),
   358  		byte((positionRaw >> 16) & 0xFF),
   359  		byte((positionRaw >> 8) & 0xFF),
   360  		byte(positionRaw & 0xFF),
   361  	})
   362  }
   363  
   364  // SetMotorDps sets the motor target speed in degrees per second.
   365  func (g *Driver) SetMotorDps(motor Motor, dps int) error {
   366  	d := dps * MOTOR_TICKS_PER_DEGREE
   367  	return g.writeBytes([]byte{
   368  		goPiGo3Address,
   369  		SET_MOTOR_DPS,
   370  		byte(motor),
   371  		byte((d >> 8) & 0xFF),
   372  		byte(d & 0xFF),
   373  	})
   374  }
   375  
   376  // SetMotorLimits sets the speed limits for a motor.
   377  func (g *Driver) SetMotorLimits(motor Motor, power int8, dps int) error {
   378  	dpsUint := dps * MOTOR_TICKS_PER_DEGREE
   379  	return g.writeBytes([]byte{
   380  		goPiGo3Address,
   381  		SET_MOTOR_LIMITS,
   382  		byte(motor),
   383  		byte(power),
   384  		byte((dpsUint >> 8) & 0xFF),
   385  		byte(dpsUint & 0xFF),
   386  	})
   387  }
   388  
   389  // GetMotorStatus returns the status for the given motor.
   390  func (g *Driver) GetMotorStatus(motor Motor) (flags uint8, power uint16, encoder, dps int, err error) {
   391  	message := GET_MOTOR_STATUS_RIGHT
   392  	if motor == MOTOR_LEFT {
   393  		message = GET_MOTOR_STATUS_LEFT
   394  	}
   395  	response, err := g.readBytes(goPiGo3Address, message, 12)
   396  	if err != nil {
   397  		return flags, power, encoder, dps, err
   398  	}
   399  	if err := g.responseValid(response); err != nil {
   400  		return flags, power, encoder, dps, err
   401  	}
   402  	// get flags
   403  	flags = uint8(response[4])
   404  	// get power
   405  	power = uint16(response[5])
   406  	if power&0x80 == 0x80 {
   407  		power = power - 0x100
   408  	}
   409  	// get encoder
   410  	enc := make([]byte, 4)
   411  	enc[3] = response[6]
   412  	enc[2] = response[7]
   413  	enc[1] = response[8]
   414  	enc[0] = response[9]
   415  	e := binary.LittleEndian.Uint32(enc)
   416  	if e&0x80000000 == 0x80000000 {
   417  		encoder = int(uint64(e) - 0x100000000)
   418  	}
   419  	encoder = int(e)
   420  	//get dps
   421  	d := make([]byte, 4)
   422  	d[1] = response[10]
   423  	d[0] = response[11]
   424  	ds := binary.LittleEndian.Uint32(d)
   425  	if ds&0x8000 == 0x8000 {
   426  		dps = int(ds - 0x10000)
   427  	}
   428  	dps = int(ds)
   429  	return flags, power, encoder / MOTOR_TICKS_PER_DEGREE, dps / MOTOR_TICKS_PER_DEGREE, nil
   430  }
   431  
   432  // GetMotorEncoder reads a motor's encoder in degrees.
   433  func (g *Driver) GetMotorEncoder(motor Motor) (encoder int64, err error) {
   434  	message := GET_MOTOR_ENCODER_RIGHT
   435  	if motor == MOTOR_LEFT {
   436  		message = GET_MOTOR_ENCODER_LEFT
   437  	}
   438  	response, err := g.readUint32(goPiGo3Address, message)
   439  	if err != nil {
   440  		return encoder, err
   441  	}
   442  	encoder = int64(response)
   443  	if response&0x80000000 != 0 {
   444  		encoder = encoder - 0x100000000
   445  	}
   446  	encoder = encoder / MOTOR_TICKS_PER_DEGREE
   447  	return encoder, nil
   448  }
   449  
   450  // OffsetMotorEncoder offsets a motor's encoder for calibration purposes.
   451  func (g *Driver) OffsetMotorEncoder(motor Motor, offset float64) error {
   452  	offsetUint := math.Float64bits(offset * MOTOR_TICKS_PER_DEGREE)
   453  	return g.writeBytes([]byte{
   454  		goPiGo3Address,
   455  		OFFSET_MOTOR_ENCODER,
   456  		byte(motor),
   457  		byte((offsetUint >> 24) & 0xFF),
   458  		byte((offsetUint >> 16) & 0xFF),
   459  		byte((offsetUint >> 8) & 0xFF),
   460  		byte(offsetUint & 0xFF),
   461  	})
   462  }
   463  
   464  // SetGroveType sets the given port to a grove device type.
   465  func (g *Driver) SetGroveType(port Grove, gType GroveType) error {
   466  	return g.writeBytes([]byte{
   467  		goPiGo3Address,
   468  		SET_GROVE_TYPE,
   469  		byte(port),
   470  		byte(gType),
   471  	})
   472  }
   473  
   474  // SetGroveMode sets the mode a given pin/port of the grove connector.
   475  func (g *Driver) SetGroveMode(port Grove, mode GroveMode) error {
   476  	return g.writeBytes([]byte{
   477  		goPiGo3Address,
   478  		SET_GROVE_MODE,
   479  		byte(port),
   480  		byte(mode),
   481  	})
   482  }
   483  
   484  // SetPWMDuty sets the pwm duty cycle for the given pin/port.
   485  func (g *Driver) SetPWMDuty(port Grove, duty uint16) (err error) {
   486  	if duty < 0 {
   487  		duty = 0
   488  	}
   489  	if duty > 100 {
   490  		duty = 100
   491  	}
   492  	duty = duty * 10
   493  	return g.writeBytes([]byte{
   494  		goPiGo3Address,
   495  		SET_GROVE_PWM_DUTY,
   496  		byte(port),
   497  		byte((duty >> 8) & 0xFF),
   498  		byte(duty & 0xFF),
   499  	})
   500  }
   501  
   502  // SetPWMFreq setst the pwm frequency for the given pin/port.
   503  func (g *Driver) SetPWMFreq(port Grove, freq uint16) error {
   504  	if freq < 3 {
   505  		freq = 3
   506  	}
   507  	if freq > 48000 {
   508  		freq = 48000
   509  	}
   510  	return g.writeBytes([]byte{
   511  		goPiGo3Address,
   512  		SET_GROVE_PWM_FREQUENCY,
   513  		byte(port),
   514  		byte((freq >> 8) & 0xFF),
   515  		byte(freq & 0xFF),
   516  	})
   517  }
   518  
   519  // PwmWrite implents the pwm interface for the gopigo3.
   520  func (g *Driver) PwmWrite(pin string, val byte) (err error) {
   521  	var (
   522  		grovePin, grovePort Grove
   523  	)
   524  	grovePin, grovePort, _, _, err = getGroveAddresses(pin)
   525  	if err != nil {
   526  		return err
   527  	}
   528  	err = g.SetGroveType(grovePort, CUSTOM)
   529  	if err != nil {
   530  		return err
   531  	}
   532  	time.Sleep(10 * time.Millisecond)
   533  	err = g.SetGroveMode(grovePin, GROVE_OUTPUT_PWM)
   534  	if err != nil {
   535  		return err
   536  	}
   537  	time.Sleep(10 * time.Millisecond)
   538  	err = g.SetPWMFreq(grovePin, 24000)
   539  	if err != nil {
   540  		return err
   541  	}
   542  	val64 := math.Float64frombits(uint64(val))
   543  	dutyCycle := uint16(math.Float64bits((100.0 / 255.0) * val64))
   544  	return g.SetPWMDuty(grovePin, dutyCycle)
   545  }
   546  
   547  // AnalogRead returns the analog value of the given pin.
   548  func (g *Driver) AnalogRead(pin string) (value int, err error) {
   549  	var (
   550  		grovePin, grovePort Grove
   551  		analogCmd           byte
   552  	)
   553  	grovePin, grovePort, analogCmd, _, err = getGroveAddresses(pin)
   554  	if err != nil {
   555  		return value, err
   556  	}
   557  	err = g.SetGroveType(grovePort, CUSTOM)
   558  	if err != nil {
   559  		return value, err
   560  	}
   561  	time.Sleep(10 * time.Millisecond)
   562  	err = g.SetGroveMode(grovePin, GROVE_INPUT_ANALOG)
   563  	if err != nil {
   564  		return value, err
   565  	}
   566  	time.Sleep(10 * time.Millisecond)
   567  	response, err := g.readBytes(goPiGo3Address, analogCmd, 7)
   568  	if err != nil {
   569  		return value, err
   570  	}
   571  	if err := g.responseValid(response); err != nil {
   572  		return value, err
   573  	}
   574  	if err := g.valueValid(response); err != nil {
   575  		return value, err
   576  	}
   577  	highBytes := uint16(response[5])
   578  	lowBytes := uint16(response[6])
   579  	return int((highBytes<<8)&0xFF00) | int(lowBytes&0xFF), nil
   580  }
   581  
   582  // DigitalWrite writes a 0/1 value to the given pin.
   583  func (g *Driver) DigitalWrite(pin string, val byte) (err error) {
   584  	var (
   585  		grovePin, grovePort Grove
   586  	)
   587  	grovePin, grovePort, _, _, err = getGroveAddresses(pin)
   588  	if err != nil {
   589  		return err
   590  	}
   591  	err = g.SetGroveType(grovePort, CUSTOM)
   592  	if err != nil {
   593  		return err
   594  	}
   595  	time.Sleep(10 * time.Millisecond)
   596  	err = g.SetGroveMode(grovePin, GROVE_OUTPUT_DIGITAL)
   597  	if err != nil {
   598  		return err
   599  	}
   600  	time.Sleep(10 * time.Millisecond)
   601  	err = g.writeBytes([]byte{
   602  		goPiGo3Address,
   603  		SET_GROVE_STATE,
   604  		byte(grovePin),
   605  		byte(val),
   606  	})
   607  	return err
   608  }
   609  
   610  // DigitalRead reads the 0/1 value from the given pin.
   611  func (g *Driver) DigitalRead(pin string) (value int, err error) {
   612  	var (
   613  		grovePin, grovePort Grove
   614  		stateCmd            byte
   615  	)
   616  	grovePin, grovePort, _, stateCmd, err = getGroveAddresses(pin)
   617  	if err != nil {
   618  		return value, err
   619  	}
   620  	err = g.SetGroveType(grovePort, CUSTOM)
   621  	if err != nil {
   622  		return value, err
   623  	}
   624  	time.Sleep(10 * time.Millisecond)
   625  	err = g.SetGroveMode(grovePin, GROVE_INPUT_DIGITAL)
   626  	if err != nil {
   627  		return value, err
   628  	}
   629  	time.Sleep(10 * time.Millisecond)
   630  	response, err := g.readBytes(goPiGo3Address, stateCmd, 6)
   631  	if err != nil {
   632  		return value, err
   633  	}
   634  	if err := g.responseValid(response); err != nil {
   635  		return value, err
   636  	}
   637  	if err := g.valueValid(response); err != nil {
   638  		return value, err
   639  	}
   640  	return int(response[5]), nil
   641  }
   642  
   643  func getGroveAddresses(pin string) (gPin, gPort Grove, analog, state byte, err error) {
   644  	switch pin {
   645  	case "AD_1_1":
   646  		gPin = AD_1_1_G
   647  		gPort = AD_1_G
   648  		analog = GET_GROVE_ANALOG_1_1
   649  		state = GET_GROVE_STATE_1_1
   650  	case "AD_1_2":
   651  		gPin = AD_1_2_G
   652  		gPort = AD_1_G
   653  		analog = GET_GROVE_ANALOG_1_2
   654  		state = GET_GROVE_STATE_1_2
   655  	case "AD_2_1":
   656  		gPin = AD_2_1_G
   657  		gPort = AD_2_G
   658  		analog = GET_GROVE_ANALOG_2_1
   659  		state = GET_GROVE_STATE_2_1
   660  	case "AD_2_2":
   661  		gPin = AD_2_2_G
   662  		gPort = AD_2_G
   663  		analog = GET_GROVE_ANALOG_2_2
   664  		state = GET_GROVE_STATE_2_2
   665  	default:
   666  		err = fmt.Errorf("Invalid grove pin name")
   667  	}
   668  	return gPin, gPort, analog, state, err
   669  }
   670  
   671  func (g *Driver) responseValid(response []byte) error {
   672  	if response[3] != 0xA5 {
   673  		return fmt.Errorf("No SPI response, response not valid")
   674  	}
   675  	return nil
   676  }
   677  
   678  func (g *Driver) valueValid(value []byte) error {
   679  	if value[4] != byte(VALID_DATA) {
   680  		return fmt.Errorf("Invalid value")
   681  	}
   682  	return nil
   683  }
   684  
   685  func (g *Driver) readBytes(address byte, msg byte, numBytes int) (val []byte, err error) {
   686  	w := make([]byte, numBytes)
   687  	w[0] = address
   688  	w[1] = msg
   689  	r := make([]byte, len(w))
   690  	err = g.connection.Tx(w, r)
   691  	if err != nil {
   692  		return val, err
   693  	}
   694  	return r, nil
   695  }
   696  
   697  func (g *Driver) readUint16(address, msg byte) (val uint16, err error) {
   698  	r, err := g.readBytes(address, msg, 8)
   699  	if err != nil {
   700  		return val, err
   701  	}
   702  	if err := g.responseValid(r); err != nil {
   703  		return val, err
   704  	}
   705  	return uint16(r[4])<<8 | uint16(r[5]), nil
   706  }
   707  
   708  func (g *Driver) readUint32(address, msg byte) (val uint32, err error) {
   709  	r, err := g.readBytes(address, msg, 8)
   710  	if err != nil {
   711  		return val, err
   712  	}
   713  	if err := g.responseValid(r); err != nil {
   714  		return val, err
   715  	}
   716  	return uint32(r[4])<<24 | uint32(r[5])<<16 | uint32(r[6])<<8 | uint32(r[7]), nil
   717  }
   718  
   719  func (g *Driver) writeBytes(w []byte) (err error) {
   720  	return g.connection.Tx(w, nil)
   721  }
   722  
   723  func (g *Driver) resetAll() {
   724  	g.SetGroveType(AD_1_G+AD_2_G, CUSTOM)
   725  	time.Sleep(10 * time.Millisecond)
   726  	g.SetGroveMode(AD_1_G+AD_2_G, GROVE_INPUT_DIGITAL)
   727  	time.Sleep(10 * time.Millisecond)
   728  	g.SetMotorPower(MOTOR_LEFT+MOTOR_RIGHT, 0.0)
   729  	g.SetMotorLimits(MOTOR_LEFT+MOTOR_RIGHT, 0, 0)
   730  	g.SetServo(SERVO_1+SERVO_2, 0)
   731  	g.SetLED(LED_EYE_LEFT+LED_EYE_RIGHT+LED_BLINKER_LEFT+LED_BLINKER_RIGHT, 0, 0, 0)
   732  }