Создание собственной системы стабилизации

SergDoc

Немного заглядывая вперёд:
STM32F405RGT6
MPU6000
bmp180 ?
HMC5883L ?
FGPMMOPA6B - GPS модуль на MT3329
как-то так

SergDoc

Из приятного, CP2102 дружит с линуксом определяется как TTYUSB 0 без всяких извращений, так что теперь оба контроллера под одной ОС запускаются…

SergDoc

в фотике CANON PC1475 стоят две гиры ENC-03 SMD 😃

IvanDeft
SergDoc:

MPU6000

Заказал себе 6050. Жду когда придет, начну мучать )))

SergDoc

Хватит, и можно клон NAZE 32 сварганить, я просто хочу по SPI, после СС чёт I2C не вставляет, хотя на данный момент вроде без ошибок работает…

Gapey

ну так ставте 6000 и будет SPI … правда они в отличии от 6050 пока в дефиците …

SergDoc

Первый запуск драйвера ничего не дал, не определилась LSMка 😦

SergDoc

аааа, а в автодетект кто править будет:)

SergDoc

Чёт я не могу въехать

 bool ack = false;
    uint8_t sig = 0;

    ack = i2cRead(ADXL345_ADDRESS, 0x00, 1, &sig); // вот тут немогу разобратся что вычитывается из акселя, я так понимаю что и ack и sig присваивается значение 0хЕ5 это id устройства, к чему привязатся в LSM?
    if (!ack || sig != 0xE5) // но тут же неack
        return false;

Аксель определился, но читатся отказывается…

# statusshow
System Uptime: 863 seconds, Voltage: 0 * 0.1V (2S battery)
Detected sensors: ACC BARO MAG   ACCHW: lsm330acc
Cycle Time: 1150, I2C Errors: 0

# 
SergDoc

Беда с автоопределением, я подцепился к первому регистру (он единственный с ненулевыми показаниями) - определился, но что бы аксель заработал, этот регистр программировать надо, а так как я его щас запрограммировал, аксель уже не определяется, бядааа… 😦

да проверил свою догадку, надо искать другой способ автоопределения…

придумал, оси всегда включены, значит надо вычитать, только три младших байта из регистра, они будут всегда постоянны, вопрос как это сделать?

вычитать регистр, сместить <<5 получим число E0 его и примем за сигнатуру?

Можно ли так записать?


ack = i2cRead(LSM330ACC_ADDRESS, LSM330_CTRL_REG1_A << 5, 1, &sig);
rual

Что то у вас всё сложно. В чём смысл идентификации акселя? В том чтобы не заточенную под железо прошиву определить при старте?
Умолчательное значение 00000111b

bool ack = false;
    uint8_t sig = 0;

    ack = i2cRead(ADXL345_ADDRESS, 0x20, 1, &sig); // если я правильно понимаю параметры функции читаем аксель по адресу 0x20

    if (!ack || sig != 0x07) // тут либо NACK, либо  считанное занчение не равно 7
        return false;  

вот вроде так
ps точнее так
ack = i2cRead(LSM330ACC_ADDRESS, LSM330_CTRL_REG1_A, 1, &sig);
сдвигать внутренний адрес акселя не нужно!

SergDoc

Решил проблему так:


bool LSM330ACCDetect(sensor_t *acc)
{
    bool ack = false;
    uint8_t sig = 0;

    ack = i2cRead(LSM330ACC_ADDRESS, LSM330_CTRL_REG1_A , 1, &sig);
	  ack = ack <<5;
	  sig = sig <<5;
    if (!ack || sig != LSM330ACC_DEVICE_SIGNATURE)
        return false;

    acc->init = LSM330ACCInit;
    acc->read = LSM330ACCRead;
    acc->align = LSM330ACCAlign;
    return true;
}

Я просто потом перезаписываю регистр как мне надо, и всё приплыли нет аксела на следующем старте, сейчас всё заработало 😃

Сгирой постораюсь обойтись проще, типа есть такой аксель значит и гира такая же…

rual:

В чём смысл идентификации акселя? В том чтобы не заточенную под железо прошиву определить при старте?

у Таймкопа автоопределение датчиков написано - типа какие установлены, так вот я туда lsm-ку и пристраиваю

rual

у переменной ack булевый тип, некрасиво его сдигать )

SergDoc

зато работает 😃 определяется аксель без проблем 😃

а в булеву переменную, всякую бяку засовывать, типа чип id, то ж некрасиво

rual
SergDoc:

а в булеву переменную, всякую бяку засовывать, типа чип id, то ж некрасиво

нее, не так. в ack функция выгружает наличие/отсутсвие ответа от ведмого устройства. Т.е. если ack = true, то устройство ответило, если false что ответа не было.

SergDoc
SergDoc:

if (!ack || sig != LSM330ACC_DEVICE_SIGNATURE)
return false;

тогда вот это загадка…

в таком случае надо


bool LSM330ACCDetect(sensor_t *acc)
{
    bool ack = false;
    uint8_t sig = 0;

    ack = i2cRead(LSM330ACC_ADDRESS, LSM330_CTRL_REG1_A , 1, &sig);
	  sig = sig <<5;
    if ( sig != LSM330ACC_DEVICE_SIGNATURE)
        return false;

    acc->init = LSM330ACCInit;
    acc->read = LSM330ACCRead;
    acc->align = LSM330ACCAlign;
    return true;
}
SergDoc

Вот что вышло


#include "board.h"



#define LSM330ACC_ADDRESS  0x19

#define LSM330ACC_DEVICE_SIGNATURE    0xE0

#define LSM330_CTRL_REG1_A		0x20 /* rw */
#define LSM330_CTRL_REG2_A		0x21 /*rw */
#define LSM330_CTRL_REG3_A		0x22 /*rw */
#define LSM330_CTRL_REG4_A		0x23 /*rw */
#define LSM330_CTRL_REG5_A		0x24 /*rw */
#define LSM330_CTRL_REG6_A		0x25 /*rw */
#define LSM330_REF_DCAPTURE_A	0x26 /*rw */
#define LSM330_STATUS_REG_A		0x27 /*r */
#define LSM330_OUT_X_L_A		0x28 /*r */
//#define LSM330_OUT_X_H_A		0x29 /*r */
//#define LSM330_OUT_Y_L_A		0x2A /*r */
//#define LSM330_OUT_Y_H_A		0x2B /*r */
//#define LSM330_OUT_Z_L_A		0x2C /*r */
//#define LSM330_OUT_Z_H_A		0x2D /*r */
#define LSM330_FIFO_CTRL_REG_A	0x2E /*rw */
#define LSM330_FIFO_SRC_REG_A	0x2F /*r */
#define LSM330_INT1_CFG_A		0x30 /*rw */
#define LSM330_INT1_SRC_A		0x31 /*r */
#define LSM330_INT1_THS_A		0x32 /*rw */
#define LSM330_INT1_DURATION_A	0x33 /*rw */
#define LSM330_INT2_CFG_A		0x34 /*rw */
#define LSM330_INT2_SOURCE_A	0x35 /*r */
#define LSM330_INT2_THS_A		0x36 /*rw */
#define LSM330_INT2_DURATION_A	0x37 /*rw */
#define LSM330_CLICK_CFG_A		0x38 /*rw */
#define LSM330_CLICK_SRC_A		0x39 /*rw */
#define LSM330_CLICK_THS_A		0x3A /*rw */
#define LSM330_TIME_LIMIT_A		0x3B /*rw */
#define LSM330_TIME_LATENCY_A	0x3C /*rw */
#define LSM330_TIME_WINDOW_A	0x3D /*rw */



/* LSM330_CTRL_REG1_A */
#define LSM330_A_ODR_PDN	0x0		/* Power-down mode */
#define LSM330_A_ODR_1		0x10 	/* Normal / low-power mode (1 Hz) */
#define LSM330_A_ODR_10		0x20	/* Normal / low-power mode (10 Hz) */
#define LSM330_A_ODR_25		0x30	/* Normal / low-power mode (25 Hz) */
#define LSM330_A_ODR_50		0x40	/* Normal / low-power mode (50 Hz) */
#define LSM330_A_ODR_100	0x50	/* Normal / low-power mode (100 Hz) */
#define LSM330_A_ODR_200	0x60	/* Normal / low-power mode (200 Hz) */
#define LSM330_A_ODR_400	0x70	/* Normal / low-power mode (400 Hz) */
#define LSM330_A_ODR_LP162	0x80 	/* Low-power mode (1.620 kHz) */
#define LSM330_A_ODR_HI		0x81 	/* Normal (1.344 kHz) / low-power mode (5.376 kHz) */
#define LSM330_A_Acsis     0X7


/* CTRL_REG2_A */
#define LSM330_A_HPM0		0		/* Normal mode (reset reading HP_RESET_FILTER)*/
#define LSM330_A_HPM1		0x40	/* Reference signal for filtering */
#define LSM330_A_HPM2		0x80	/* Normal mode	*/
#define LSM330_A_HPM3		0xc0	/* Autoreset on interrupt event */
#define LSM330_A_HPCF0		0		/* High-pass filter cutoff frequency selection	*/
#define LSM330_A_HPCF1		0x10	/* High-pass filter cutoff frequency selection	*/
#define LSM330_A_HPCF2		0x20	/* High-pass filter cutoff frequency selection	*/
#define LSM330_A_HPCF3		0x30	/* High-pass filter cutoff frequency selection	*/
#define LSM330_A_FDS		0x08	/* Filtered data selection. Default value: 0 (0: internal filter bypassed; 1: data from internal filter sent to output register and FIFO) */

/* CTRL_REG3_A */
#define LSM330_A_I1_CLICK 	0x80	/* CLICK interrupt on INT1_A. Default value 0. (0: Disable; 1: Enable) */
#define LSM330_A_I1_AOI1 	0x40 	/* AOI1 interrupt on INT1_A. Default value 0. (0: Disable; 1: Enable) */
#define LSM330_A_I1_DRDY1 	0x10	/* DRDY1 interrupt on INT1_A. Default value 0.(0: Disable; 1: Enable) */
#define LSM330_A_I1_DRDY2 	0x08	/* DRDY2 interrupt on INT1_A. Default value 0.(0: Disable; 1: Enable) */
#define LSM330_A_I1_WTM 	0x04	/* FIFO watermark interrupt on INT1_A. Default value 0.(0: Disable; 1: Enable)*/
#define LSM330_A_I1_OVERRUN 0x02	/* FIFO overrun interrupt on INT1_A. Default value 0. (0: Disable; 1: Enable) */

	/*CTRL_REG4_A */
#define LSM330_BDU	 		0x80	/* Block data update. Default value: 0(0: continuous update; 1: output registers not updated until MSB and LSB reading) */
#define LSM330_BLE	 		0x40	/* Big/little endian data selection. Default value 0.(0: Data LSB at lower address; 1: Data MSB at lower address) */

/*FS1-FS0 Full-scale selection. default value: 00 (00: +/- 2G; 01: +/- 4G; 10: +/- 8G; 11: +/- 16G) */
#define LSM330_A_FS2G		0
#define LSM330_A_FS4G		0x10
#define LSM330_A_FS8G		0x20
#define LSM330_A_FS16G		0x30
#define LSM330_A_HR 		0x08	/*Normal mode: default value: 0(0: normal mode disable; 1: normal mode enable */
#define LSM330_SIM 			0x01	/* SPI serial interface mode selection. Default value: 0(0: 4-wire interface; 1: 3-wire interface) */

/* CTRL_REG5_A */
#define LSM330_A_BOOT 		0x80	/* Reboot memory content. Default value: 0 (0: normal mode; 1: reboot memory content) */
#define LSM330_A_FIFO_EN	0x40	/* FIFO enable. Default value: 0(0: FIFO disable; 1: FIFO enable) */
#define LSM330_A_LIR_INT1 	0x08	/* Latch interrupt request on INT1_SRC_A register, with INT1_SRC_A register cleared by reading INT1_SRC_A itself. Default value: 0.(0: interrupt request not latched; 1: interrupt request latched) */
#define LSM330_A_D4D_INT1 	0x04	/* 4D enable: 4D detection is enabled on INT1_A when 6D bit on INT1_CFG_A is set to 1. */

/* CTRL_REG6_A */
#define LSM330_A_I2_CLICKen 0x80	/* Click interrupt on INT2_A. Default value 0.	*/
#define LSM330_A_I2_INT1	0x40	/* Interrupt 1 function enabled on INT2_A. Default 0. */
#define LSM330_A_BOOT_I2	0x10	/* Boot on INT2_A. */
#define LSM330_A_H_LACTIVE	0x02	/* 0: interrupt active high; 1: interrupt active low. */

/* STATUS_REG_A */
#define LSM330_A_ZYXOR		0x80	/* X-, Y- and Z-axis data overwrite. Default value: 0 (0: no overwrite has occurred; 1: a new set of data has overwritten the previous ones) */
#define LSM330_A_ZOR		0x40	/* Z-axis data overwrite. Default value: 0(0: no overrun has occurred; 1: a new data for the Z-axis has overwritten the previous one) */
#define LSM330_A_YOR		0x20	/* Y-axis data overwrite. Default value: 0 (0: no overwrite has occurred;1: new data for the Y-axis has overwritten the previous data) */
#define LSM330_A_XOR		0x10	/* X-axis data overwrite. Default value: 0 (0: no overwrite has occurred;1: new data for the X-axis has overwritten the previous data) */
#define LSM330_A_ZYXDA		0x08	/* X-, Y- and Z-axis new data available. Default value: 0(0: a new set of data is not yet available; 1: a new set of data is available) */
#define LSM330_A_ZDA		0x04	/* Z-axis new data available. Default value: 0(0: new data for the Z-axis is not yet available;1: new data for the Z-axis is available) */
#define LSM330_A_YDA		0x02 	/* Y-axis new data available. Default value: 0 (0: new data for the Y-axis is not yet available;1: new data for the Y-axis is available) */
#define LSM330_A_XDA		0x01 	/* X-axis new data available. Default value: 0 (0: new data for the X-axis is not yet available;1: new data for the X-axis is available) */


extern uint16_t acc_1G;

static void LSM330ACCInit(void);
static void LSM330ACCRead(int16_t *accelData);
static void LSM330ACCAlign(int16_t *accelData);

bool LSM330ACCDetect(sensor_t *acc)
{
    bool ack = false;
    uint8_t sig = 0;

    ack = i2cRead(LSM330ACC_ADDRESS, LSM330_CTRL_REG1_A , 1, &sig);

	  sig = sig <<5;
    if (!ack || sig != LSM330ACC_DEVICE_SIGNATURE)
        return false;

    acc->init = LSM330ACCInit;
    acc->read = LSM330ACCRead;
    acc->align = LSM330ACCAlign;
    return true;
}

static void LSM330ACCInit(void)
{

    i2cWrite(LSM330ACC_ADDRESS, LSM330_CTRL_REG1_A, LSM330_A_ODR_100 | LSM330_A_Acsis );

    i2cWrite(LSM330ACC_ADDRESS, LSM330_CTRL_REG4_A, LSM330_A_FS4G  );



    acc_1G = 512;
}

static void LSM330ACCRead(int16_t *accelData)
{
    uint8_t buf[6];

    i2cRead(LSM330ACC_ADDRESS, LSM330_OUT_X_L_A, 6, buf);
    accelData[0] = (buf[1] << 8) | buf[0];
    accelData[1] = (buf[3] << 8) | buf[2];
    accelData[2] = (buf[5] << 8) | buf[4];

    accelData[0] >>= 2;
    accelData[1] >>= 2;
    accelData[2] >>= 2;
}

static void LSM330ACCAlign(int16_t *accelData)
{
    int16_t temp[2];
    temp[0] = accelData[0];
    temp[1] = accelData[1];

    // official direction is RPY
    accelData[0] = temp[1] / 32;
    accelData[1] = -temp[0] / 32;
    accelData[2] = accelData[2] / 32;
}

но бяка полная 😦

soliada
SergDoc:

#define LSM330ACC_ADDRESS 0x19

А почему именно такой адрес? Вроде,если верить инструкции на чтение либо 0Х30,либо 0Х32 в зависимости от подключения.