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 }