5iMX宗旨:分享遥控模型兴趣爱好

5iMX.com 我爱模型 玩家论坛 ——专业遥控模型和无人机玩家论坛(玩模型就上我爱模型,创始于2003年)
查看: 3886|回复: 11
打印 上一主题 下一主题

mwc飞控各项功能调试总结,增加si4463和gy91支持,存档备忘

[复制链接]
跳转到指定楼层
楼主
发表于 2018-7-28 00:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 t20109020 于 2018-8-9 02:18 编辑

相信已经没有人玩mwc了,但是我对她依然情有独钟。

未定稿,待更新

电压检测部分(25V量程)

Ra=30kΩ,Rb=7.5kΩ
信号由默认的A3引脚输入
config.h文件
#define VBAT  //取消注释
#define VBATSCALE       131    //缩放系数,不同阻值的分压电路对应不同的值,在这里修改不起作用!!!应当在MultiWiiConf配置程序中修改。30kΩ+7.5kΩ分压电路对应的值为64,1s电池测试准确无误。

功率计部分(30A量程)

信号由默认的A2引脚输入。config.h文件
#define POWERMETER_HARD   //取消注释,开启功率计
功率计用到下面两个参数
#define PSENSORNULL 510      //1/2 Vss
#define PINT2mA 132               //电流转换系数  30量程电流计对应5/1024/0.066*1000≈74
但是MultiWiiConf配置程序中没有找到设置的地方,于是直接在MultiWii.cpp中写死。如果有人知道在哪里修改,希望能留言告知,非常感谢。
powerValue = ( 510 > p ? 510 - p : p - 510);
analog.amperage = ((uint32_t)powerValue * 74) / 100;
pMeter[PMOTOR_SUM] += ((currentTime-lastRead) * (uint32_t)((uint32_t)powerValue*74))/100000;

SI4463部分
def.h文件修改内容
由于需要把2,4,5,6,7引脚解放出来,需要注释掉默认接收机,换行添加SI4463定义
//#define STANDARD_RX #define SI4463_RX

这里飞控计划只用作飞翼使用,将硬件spi接口d10,d11,d12,d13解放出来,需要把舵机修改成1to2,d13默认指示灯引脚改成d4。
  飞翼的舵机定义
  #define PRI_SERVO_FROM   1   //起始舵机默认是4
  #define NUMBER_MOTOR   1   //电机数默认1
  #define PRI_SERVO_TO   2        //结束舵机默认是5

  改指示灯接口

  #define LEDPIN_PINMODE             pinMode (4, OUTPUT);
  #define LEDPIN_TOGGLE              PIND |= 1<<4;     //默认(digital PIN 13)
  #define LEDPIN_OFF                 PORTD &= ~(1<<4);
  #define LEDPIN_ON                  PORTD |= (1<<4);



RX.h文件添加内容
文件结尾添加如下代码
#if defined(SI4463_RX)
        #include <Si446x.h>
        
        #define CHANNEL 20
        #define MAX_PACKET_SIZE 16


        #define PACKET_NONE                0
        #define PACKET_OK                1
        #define PACKET_INVALID        2
        
        #define MAX_CHANNELS 7


        typedef struct{
                uint8_t ready;
                int16_t rssi;
                uint8_t length;
                union {
                        struct {
                                byte checksum;
                                byte notused;
                                union {
                                        short value;
                                        struct {
                                                byte msb;
                                                byte lsb;
                                        };
                                } channels[MAX_CHANNELS];
                        };
                        uint8_t buffer[MAX_PACKET_SIZE];
                };
        } pingInfo_t;
        
        static volatile pingInfo_t pingInfo;
        
        void Init_SI4463();
        void Cycle_SI4463_RC();
        void SI446X_CB_RXCOMPLETE(uint8_t length, int16_t rssi);
        void SI446X_CB_RXINVALID(int16_t rssi);
#endif



RX.cpp文件修改内容
configureReceiver()函数内添加
  #if defined(SI4463_RX)
        Init_SI4463();
  #endif

computeRC()函数修改,作用是不执行mwc自身支持的接收机的运算
#if !defined(OPENLRSv2MULTI) 修改为  #if !defined(OPENLRSv2MULTI) && !defined(SI4463_RX)
文件结尾添加代码
#if defined(SI4463_RX)
void Init_SI4463() {
        Si446x_init();
        Si446x_setTxPower(SI446X_MAX_TX_POWER);
        Si446x_RX(CHANNEL);
}
void Cycle_SI4463_RC() {
        static uint32_t pings;
        static uint32_t invalids;

        if(pingInfo.ready == PACKET_NONE) return;
               
        if(pingInfo.ready != PACKET_OK)
        {
                invalids++;
                pingInfo.ready = PACKET_NONE;
                rcData[PITCH] = map(pingInfo.channels[0].value,0,1023,1000,2000);
                rcData[ROLL] = map(pingInfo.channels[1].value,0,1023,1000,2000);
                rcData[THROTTLE] = map(pingInfo.channels[2].value,0,1023,1000,2000);
                rcData[YAW] = map(pingInfo.channels[3].value,0,1023,1000,2000);
                rcData[AUX1] = map(pingInfo.channels[4].value,0,1023,1000,2000);
                rcData[AUX2] = map(pingInfo.channels[5].value,0,1023,1000,2000);
                rcData[AUX3] = map(pingInfo.channels[6].value,0,1023,1000,2000);
                rcData[AUX4] = 1500;
                Si446x_RX(CHANNEL);
        }
        else
        {
                pings++;
                pingInfo.ready = PACKET_NONE;


                // Send back the data, once the transmission has completed go into receive mode
                Si446x_TX((uint8_t*)pingInfo.buffer, pingInfo.length, CHANNEL, SI446X_STATE_RX);
                rcData[PITCH] = map(pingInfo.channels[0].value,0,1023,1000,2000);
                rcData[ROLL] = map(pingInfo.channels[1].value,0,1023,1000,2000);
                rcData[THROTTLE] = map(pingInfo.channels[2].value,0,1023,1000,2000);
                rcData[YAW] = map(pingInfo.channels[3].value,0,1023,1000,2000);
                rcData[AUX1] = map(pingInfo.channels[4].value,0,1023,1000,2000);
                rcData[AUX2] = map(pingInfo.channels[5].value,0,1023,1000,2000);
                rcData[AUX3] = map(pingInfo.channels[6].value,0,1023,1000,2000);
                rcData[AUX4] = 1500;
        }
}
void SI446X_CB_RXCOMPLETE(uint8_t length, int16_t rssi)
{
        if(length > MAX_PACKET_SIZE)
                length = MAX_PACKET_SIZE;


        pingInfo.ready = PACKET_OK;
        pingInfo.rssi = rssi;
        pingInfo.length = length;


        Si446x_read((uint8_t*)pingInfo.buffer, length);


        // Radio will now be in idle mode
}


void SI446X_CB_RXINVALID(int16_t rssi)
{
        pingInfo.ready = PACKET_INVALID;
        pingInfo.rssi = rssi;
}
#endif



MultiWii.cpp文件修改
  在
  #if defined(OPENLRSv2MULTI)
    Read_OpenLRS_RC();
  #endif

  下面添加
  #if defined(SI4463_RX)
        Cycle_SI4463_RC();
  #endif



GY91部分
config.h文件添加BMP280定义
      /* I2C barometer */
      //#define BMP085
      #define BMP280
      //#define MS561101BA

def.h修改代码

#if defined(BMP085) || defined(MS561101BA)
  #define BARO 1
#else
  #define BARO 0
#endif
修改成
#if defined(BMP280) || defined(BMP085) || defined(MS561101BA)
  #define BARO 1
#else
  #define BARO 0
#endif

Sensors.cpp添加代码
// ************************************************************************************************************
// I2C Barometer BOSCH BMP280
// ************************************************************************************************************
// I2C adress: 0x76 (7bit)
// CHIPID      0x58
// ************************************************************************************************************


#if defined(BMP280)
#define BMP280_ADDRESS 0x76


static struct {
  // sensor registers from the BOSCH BM280 datasheet
  uint16_t dig_T1;
  int16_t  dig_T2,dig_T3;


  uint16_t dig_P1;
  int16_t  dig_P2,dig_P3,dig_P4,dig_P5,dig_P6,dig_P7,dig_P8,dig_P9;


  union {uint32_t val; uint8_t raw[3]; } ut; //uncompensated T
  union {uint32_t val; uint8_t raw[3]; } up; //uncompensated P
  uint8_t  state;
  uint32_t deadline;
} bmp280_ctx;


/* transform a series of bytes from big endian to little
   endian and vice versa. */
void swap_endianness(void *buf, size_t size) {
  /* we swap in-place, so we only have to
  * place _one_ element on a temporary tray
  */
  uint8_t tray;
  uint8_t *from;
  uint8_t *to;
  /* keep swapping until the pointers have assed each other */
  for (from = (uint8_t*)buf, to = &from[size-1]; from < to; from++, to--) {
    tray = *from;
    *from = *to;
    *to = tray;
  }
}


void i2c_BMP280_readCalibration(){
  delay(10);
  //read calibration data in one go
  size_t s_bytes = (uint8_t*)&bmp280_ctx.dig_P9 - (uint8_t*)&bmp280_ctx.dig_T1 + sizeof(bmp280_ctx.dig_T1);
  i2c_read_reg_to_buf(BMP280_ADDRESS, 0x88, (uint8_t*)&bmp280_ctx.dig_T1, s_bytes);
  // now fix endianness
  //int16_t *p;
  //for (p = (int16_t*)&bmp280_ctx.dig_T1; p <= &bmp280_ctx.dig_P9; p++) {
  //  swap_endianness(p, sizeof(*p));
  //}
}


// read uncompensated pressure value: read result bytes
// the datasheet suggests a delay of 25.5 ms (oversampling settings 3) after the send command
void i2c_BMP280_UP_Read () {
  i2c_read_reg_to_buf(BMP280_ADDRESS, 0xF7, (uint8_t*)&bmp280_ctx.up.val, 3);
  swap_endianness(&bmp280_ctx.up.val, 3);
  bmp280_ctx.up.val >>= 4;
}


// read uncompensated temperature value: read result bytes
// the datasheet suggests a delay of 4.5 ms after the send command
void i2c_BMP280_UT_Read() {
  i2c_read_reg_to_buf(BMP280_ADDRESS, 0xFA, (uint8_t*)&bmp280_ctx.ut.val, 3);
  swap_endianness(&bmp280_ctx.ut.val, 3);
  bmp280_ctx.ut.val >>= 4;
}


void i2c_BMP280_Calculate() {
  int32_t var11,var22,t;
  int64_t var1, var2, p;


  //bmp280_ctx.ut.val >>= 4;
  var11  = ((((bmp280_ctx.ut.val>>3) - ((int32_t)bmp280_ctx.dig_T1 <<1))) *
           ((int32_t)bmp280_ctx.dig_T2)) >> 11;


  var22  = (((((bmp280_ctx.ut.val>>4) - ((int32_t)bmp280_ctx.dig_T1)) *
             ((bmp280_ctx.ut.val>>4) - ((int32_t)bmp280_ctx.dig_T1))) >> 12) *
           ((int32_t)bmp280_ctx.dig_T3)) >> 14;


  t = var11 + var22;
  baroTemperature  = (t * 5 + 128) >> 8;
  //baroTemperature /= 100;
  //baroTemperature = (b5 * 10 + 8) >> 4; // in 0.01 degC (same as MS561101BA temperature)
  
  //bmp280_ctx.up.val >>= 4;


  var1 = ((int64_t)t) - 128000;
  var2 = var1 * var1 * (int64_t)bmp280_ctx.dig_P6;
  var2 = var2 + ((var1*(int64_t)bmp280_ctx.dig_P5)<<17);
  var2 = var2 + (((int64_t)bmp280_ctx.dig_P4)<<35);
  var1 = ((var1 * var1 * (int64_t)bmp280_ctx.dig_P3)>>8) +
    ((var1 * (int64_t)bmp280_ctx.dig_P2)<<12);
  var1 = (((((int64_t)1)<<47)+var1))*((int64_t)bmp280_ctx.dig_P1)>>33;


  if (var1 == 0) {
    return;  // avoid exception caused by division by zero
  }
  p = 1048576 - bmp280_ctx.up.val;
  p = (((p<<31) - var2)*3125) / var1;
  var1 = (((int64_t)bmp280_ctx.dig_P9) * (p>>13) * (p>>13)) >> 25;
  var2 = (((int64_t)bmp280_ctx.dig_P8) * p) >> 19;


  p = ((p + var1 + var2) >> 8) + (((int64_t)bmp280_ctx.dig_P7)<<4);
  baroPressure = p;
  //baroPressure = (int)p/256;
  //baroPressure /= 100;
}


void  Baro_init() {
  delay(10);
  i2c_BMP280_readCalibration();
  delay(5);
  i2c_writeReg(BMP280_ADDRESS,0xF4, 0x3F);
  bmp280_ctx.deadline = currentTime+5000;
}


//return 0: no data available, no computation ;  1: new value available  ; 2: no new value, but computation time
uint8_t Baro_update() {                   // first UT conversion is started in init procedure
  if (currentTime < bmp280_ctx.deadline) return 0;
  bmp280_ctx.deadline = currentTime+6000; // 1.5ms margin according to the spec (4.5ms T convetion time)
  if (bmp280_ctx.state == 0) {
    i2c_BMP280_UT_Read();
    bmp280_ctx.state = 1;
    Baro_Common();
    bmp280_ctx.deadline += 21000;   // 6000+21000=27000 1.5ms margin according to the spec (25.5ms P convetion time with OSS=3)
    return 1;
  } else {
    i2c_BMP280_UP_Read();
    i2c_BMP280_Calculate();
    bmp280_ctx.state = 0;
    return 2;
  }
}
#endif













欢迎继续阅读楼主其他信息

沙发
发表于 2018-7-28 01:46 | 只看该作者
带接收?
来自安卓客户端来自安卓客户端
3
发表于 2018-7-28 09:28 | 只看该作者
情怀啊。。。
来自苹果客户端来自苹果客户端
4
 楼主| 发表于 2018-7-28 09:39 | 只看该作者
ahai199823 发表于 2018-7-28 01:46
带接收?

是收发一体,si4463就是433收发模块,小体积、低功耗、距离远、性价比高
来自安卓客户端来自安卓客户端
5
 楼主| 发表于 2018-7-28 09:57 | 只看该作者
昶平 发表于 2018-7-28 09:28
情怀啊。。。

是啊,如今把它用在固定翼上还是不错的
来自安卓客户端来自安卓客户端
6
发表于 2018-7-28 14:03 | 只看该作者
t20109020 发表于 2018-7-28 09:39
是收发一体,si4463就是433收发模块,小体积、低功耗、距离远、性价比高

牛牛逼
来自安卓客户端来自安卓客户端
7
发表于 2018-8-4 07:33 | 只看该作者
优秀
8
发表于 2018-8-12 06:15 | 只看该作者
bmp280得代码也弄进去了,牛了
来自安卓客户端来自安卓客户端
9
发表于 2018-10-26 12:39 | 只看该作者
这个都可以出教程了。楼主有必要写修改传感器的教程。很可惜我还只是在修改硬件熟悉配置当中
10
发表于 2019-1-27 22:44 | 只看该作者
支持楼主!!谢谢分享!!!
11
发表于 2019-2-9 07:30 | 只看该作者
12
发表于 2019-6-21 17:04 | 只看该作者
请问楼主,LED屏的UI是你自己写的吗?能共享一下工程代码吗
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

【站内推荐】上一条 /1 下一条

快速回复 返回顶部 返回列表