Драйвер мотора Crontrol Grove I2C со скриптом node.js на Raspberry Pi - I2C - writeWord () - PullRequest
0 голосов
/ 01 ноября 2018

Речь идет об отправке байтов по шине I2C в файле node.js srcipt. Настроить: Я использую плату драйверов двигателей Grove I2C для управления через шину I2C с помощью Raspberry Pi 3 и сценария node.js для управления щеточным двигателем постоянного тока.

Официальный код для управления платой предназначен для Arduino:

Пример - официальный Github

ccp-файл с собственными командами i2c

Теперь я хочу, чтобы он работал с Raspberry Pi и скриптом узла, и я использую пакет i2c-bus npm и его метод writeWord () .

В коде Arduino GitHub, похоже, что они просто устанавливают скорость для запуска двигателя - с помощью IC2MotorDriver Method (строка> 113):

    / *****************************DC Motor Function******************************
// Set the speed of a motor, speed is equal to duty cycle here
// motor_id: MOTOR1, MOTOR2
// _speed: -100~100, when _speed>0, dc motor runs clockwise; when _speed<0, 
// dc motor runs anticlockwise
void I2CMotorDriver::speed(unsigned char motor_id, int _speed)
{
    if(motor_id<MOTOR1 || motor_id>MOTOR2) {
        Serial.println("Motor id error! Must be MOTOR1 or MOTOR2");
        return;
    }

    if(motor_id == MOTOR1) {
        if (_speed >= 0) {
            this->_M1_direction = 1; 
            _speed = _speed > 100 ? 100 : _speed;
            this->_speed1 = map(_speed, 0, 100, 0, 255);
        }
        else if (_speed < 0) {
            this->_M1_direction = -1;
            _speed = _speed < -100 ? 100 : -(_speed);
            this->_speed1 = map(_speed, 0, 100, 0, 255);
        }
    }
    else if(motor_id == MOTOR2) {
        if (_speed >= 0) {
            this->_M2_direction = 1;
            _speed = _speed > 100 ? 100 : _speed;
            this->_speed2 = map(_speed, 0, 100, 0, 255);
        }
        else if (_speed < 0) {
            this->_M2_direction = -1;
            _speed = _speed < -100 ? 100 : -(_speed);
            this->_speed2 = map(_speed, 0, 100, 0, 255);
        }
    }
    // Set the direction
    if (_M1_direction == 1 && _M2_direction == 1) direction(BothClockWise);
    if (_M1_direction == 1 && _M2_direction == -1) direction(M1CWM2ACW);
    if (_M1_direction == -1 && _M2_direction == 1) direction(M1ACWM2CW);
    if (_M1_direction == -1 && _M2_direction == -1) direction(BothAntiClockWise);
    // send command
    Wire.beginTransmission(this->_i2c_add); // begin transmission
    Wire.write(MotorSpeedSet);              // set pwm header 
    Wire.write(this->_speed1);              // send speed of motor1
    Wire.write(this->_speed2);              // send speed of motor2
    Wire.endTransmission();                 // stop transmitting
    delay(4);                               // Wait 
}

Так что для меня это решающая часть :

Wire.beginTransmission(this->_i2c_add); // begin transmission
Wire.write(MotorSpeedSet);              // set pwm header 
Wire.write(this->_speed1);              // send speed of motor1
Wire.write(this->_speed2);              // send speed of motor2
Wire.endTransmission();                 // stop transmitting

Однако, как мне сделать это в скрипте узла. Я уверен, что я правильно подключил V3.3 SDA, SCL, GND. i2cdetect -y 1 показывает плату водителя:

pi@raspi:~/i2c_tests $ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- 0f
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Я пробовал это во многих вариантах. Я использовал метод .writeWord, надеясь отправить 2-байтовые значения (100 и 100) в качестве слова. Документы writeWord () метод:

bus.writeWord(addr, cmd, word, cb)
addr - I2C device address
cmd - command code
word - data word
cb - completion callback
Asynchronous SMBus write word. The callback gets one argument (err).

Однако, похоже, ничего не делает:

/*********I2C command definitions****************/
const MotorSpeedSet     =   parseInt(0x82);
const PWMFrequenceSet   =   parseInt(0x84);
const DirectionSet      =   parseInt(0xaa);
const MotorSetA         =   parseInt(0xa1);
const MotorSetB         =   parseInt(0xa5);
const Nothing           =   parseInt(0x01);

/*********Motor ID*****parseInt(*****************/
const MOTOR1                    =   parseInt(1);
const MOTOR2                    =   parseInt(2);

/*********Motor DirectiparseInt(on***************/
const BothClockWise     =   parseInt(0x0a);
const BothAntiClockWise =   parseInt(0x05);
const M1CWM2ACW         =   parseInt(0x06);
const M1ACWM2CW         =   parseInt(0x09);

/*********Motor DirectiparseInt(on***************/
const ClockWise         =   parseInt(0x0a);
const AntiClockWise     =   parseInt(0x05);

/*********Prescaler FreparseInt(quence***********/
const F_31372Hz         =   parseInt(0x01);
const F_3921Hz          =   parseInt(0x02);
const F_490Hz           =   parseInt(0x03);
const F_122Hz           =   parseInt(0x04);
const F_30Hz            =   parseInt(0x05);

/*********I2C Address of the Grove Board*********/
const I2C_ADDRESS       =   parseInt(0x0f);     // 0x0f = default Asdress

var i2c1;

i2c1 = i2c.open(1, ()=>{
    //i2c1.writeByte(I2C_ADDRESS, MotorSpeedSet, 0x01, cb);
    //short int16 = (short)(((0x64 & 0xFF) << 8) | (0x00 & 0xFF));

    //trying with a buffer
    var buffer = new Buffer([0x64,0x64]); // speed values 100 and 100, motor A & B
    //trying with a In16Array
    var int16 = new Int16Array(2);
    int16[0] = 42;
    i2c1.writeWord(I2C_ADDRESS, MotorSpeedSet, int16[0], ()=>{});
    //trying subsequent sendings of 1 byte
    //i2c1.sendByte(I2C_ADDRESS, MotorSpeedSet, ()=>{});
    //i2c1.sendByte(I2C_ADDRESS, 100, ()=>{});
    //i2c1.sendByte(I2C_ADDRESS, 100, ()=>{});
});

Поэтому я здесь, чтобы обратиться за советом или получить новые идеи о том, как решить эту проблему. Похоже, хитрость заключается в том, как обрабатывать и отправлять эти 2 байта скорости для каждого двигателя, как они делают с кодом Arduino. Однако я не знаю, как правильно реализовать это в node.js. Надеюсь, я это объяснил понятно.

...