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 }