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

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

MZ-24用DIY的DSM2高频头玩MCPX

  [复制链接]
跳转到指定楼层
楼主
发表于 2013-12-6 22:39 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 xuwh008 于 2013-12-6 22:41 编辑

    用上了mz-24,尽管爽,但无法继续操我的mcpx。以前用T8FG的时候为了玩mcpx按照C2PO的帖子DIY了一个DSM2高频头,现在换了遥控后本以为直接插遥控上就能用,结果发现有些问题,要么就是对频失败,要么就是飞起来十字盘跑偏。于是花了几天时间分析原因,经过不懈的努力,对C2PO的程序作了稍微的修改。终于成功搞定了MZ-24上能用的DSM2高频头。
    元件清单:
    Arduino pro mini 3.3v 8Mhz 板一个
    ASM1117 3.3V 稳压芯片
    一个发光二极管
    两个开关
    一个470欧姆电阻和一个560uf的电容
    一个DX4E或者DX5E高频头
    以及一些线头和一小块洞洞板。
    这个就是DX5E高频头,用DX4E的也可以。
   
    下面是电路图:
   
    一下几张是C2PO的图片,借鉴一下,大家也可以根据这个图片看管脚的对应。
   
   
    MZ-24上需要做如下设置:
    BASE->TX CTL里面要选择PPM16;
   
   
    BASE->out.Swap需要修改对外的通道顺序
   
   
    BASE->EPA要相应的减少副翼,升降和螺距的行程量
   
   
    BASE->Reverse里面保持原样
   
   
    FUNCTION->trainner里面选择DSC-S,也就是玩模拟器的设置方法
   
这是我做出来的东东,找不到合适的盒子,感觉特丑,等以后找到外壳再搬家。
  
  用法:
    先接通mcpx电源,等电源灯闪烁。然后按住高频头的BIND开关通电,蓝灯会开始闪。蓝灯闪说明在开始对频,如果正常的话大约几秒后就能对上频。
    如果高频头没有接收到PPM信号会蓝灯慢闪。
  下面是程序代码:
//dsm2_mz_24.pde
#include "WProgram.h"
#include <avr/interrupt.h>
typedef enum {
    NULL_ST = -1, NOT_SYNCHED, ACQUIRING, READY, FAILSAFE
} State_t;
#define PRESCALE       0x42            
#define TICKS_PER_uS   1            
#define MAX_CHANNELS   8
#define MIN_IN_PULSE  (750 * TICKS_PER_uS)
#define MAX_IN_PULSE  (2250 * TICKS_PER_uS)
#define SYNC_GAP_LEN  (5000 * TICKS_PER_uS)
#define VALID_FRAMES   10                 
#define BIND_TIME      10000              
#define BINDinterval   50
#define ERRORinterval  250
#define DSM2_CHANNELS  6            
// "Pro mini" pinout
#define BINDING_PIN    2
#define BINDING_LED    5
#define FLASH_LED      10
#define PPM_PIN        8
static int Pulses[MAX_CHANNELS + 1];
static int Failsafe[MAX_CHANNELS + 1];
static byte ChannelNum;
static byte ChannelCnt;
static State_t State;
static byte stateCount;
volatile long ICR1Cn;
static byte DSM2_Header[2];
static byte DSM2_Channel[DSM2_CHANNELS*2] = {0x00,0xAA,0x05,0xFF,0x09,0xFF,0x0D,0xFF,0x13,0x54,0x14,0xAA};
static byte DSM2_Sent = 0;
static byte ChanIndex[] = {3,1,2,4,5,6,7,8};    //PPM to DSM2 Channel Mapping Table
static byte PPMwaitCount;
static int pulse;
long previousMillis = 0;
long ERRORpreviousMillis = 0;
long interval = 500;
byte DisFlash = LOW;
int LEDbrightness = 100;
int LEDfadeAmount = 5;
/* ---------- ---------- ---------- Sync ---------- ---------- ---------- */
static void processSync() {
  if(State == READY) {                     
    if( ChannelNum != ChannelCnt)
    {
      State = FAILSAFE;
    }      
  }                                         
  else {                                    
    if(State == NOT_SYNCHED) {              
      State = ACQUIRING;
      stateCount = 0;      
    } else {                                
      if( State == ACQUIRING) {            
        if(++stateCount > VALID_FRAMES) {
          State = READY;
          ChannelCnt = ChannelNum;
        }                                   
      } else                                
        if( State == FAILSAFE) {            
          if(ChannelNum == ChannelCnt)
          {
           State = READY;  
          }         
        }                                   
    }                                       
  }                                         
  ChannelNum = 0;
}
/* ---------- ---------- ---------- Interrupt Handerling---------- ---------- ---------- */
ISR(TIMER1_OVF_vect) {
  if(State == READY) {
    State = FAILSAFE;
    ChannelNum = 0;
  }                                         
}                                          
ISR(TIMER1_CAPT_vect) {
  ICR1Cn = ICR1;
  TCNT1 = 0X00;
  if(ICR1Cn >= SYNC_GAP_LEN)
  {
    processSync();
  }   
  else                                      
    if(ChannelNum < MAX_CHANNELS) {
      if((ICR1Cn >= MIN_IN_PULSE) && (ICR1Cn <= MAX_IN_PULSE))
        Pulses[++ChannelNum] = ICR1Cn / TICKS_PER_uS;
      else
        if(State == READY) {
          State = FAILSAFE;
          ChannelNum = 0;
        }
    }
}
/* ---------- ---------- ---------- PPM Class ---------- ---------- ---------- */
class PPM_Decode {
public:
  PPM_Decode() {                            // Constructor                           
  }                                         
                                            
  void begin() {
    pinMode(8, INPUT);
    ChannelNum = 0;                        
    State = NOT_SYNCHED;
    TIMSK1 = 0x21;
    TCCR1A = 0x00;
    TCCR1B = PRESCALE;
   
    for(byte ch = 1; ch <= MAX_CHANNELS; ch++) {
      Failsafe[ch] = Pulses[ch] = 1500;
    }
    Failsafe[3] = Pulses[3] = 1100;
  }
  
  void stop() {
    State   = NOT_SYNCHED;
    TIMSK1 = 0x00;
    TCCR1A = 0x00;
    TCCR1B = 0x00;
  }
  State_t getState() {
    return State;
  }
  byte getChannelCnt() {
    return ChannelCnt;
  }
  void  setFailsafe(byte ch, int value) {
    if((ch > 0) && (ch <= MAX_CHANNELS))
      Failsafe[ch] = value;
  }
  void  setFailsafe() {
    if(State == READY)
      for(byte ch = 1; ch <= MAX_CHANNELS; ch++)
        Failsafe[ch] = Pulses[ch];
  }
  int getChannelData(uint8_t channel) {
    int result = 0;
    if(channel <= MAX_CHANNELS)  {
      if((State == FAILSAFE) && (Failsafe[channel] > 0 ))
        result = Failsafe[channel];
      else
        if((State == READY) || (State == FAILSAFE)) {
          cli();
          result = Pulses[channel];
          sei();
        }
    }
    return result;
  }
};
PPM_Decode Receiver = PPM_Decode();
void setup() {
  Serial.begin(125000);
  pinMode(BINDING_PIN, INPUT);
  digitalWrite(BINDING_PIN, HIGH);
  pinMode(BINDING_LED, OUTPUT);
  digitalWrite(PPM_PIN, HIGH);
  DSM2_Header[0] = 0;
  DSM2_Header[1] = 0;
  
  if(digitalRead(BINDING_PIN) == LOW) {
    digitalWrite(BINDING_LED, HIGH);      
    BindDSM2();
  }
  digitalWrite(BINDING_LED,LOW);
  Receiver.begin();
  PPMwaitCount = 30;
  while(Receiver.getState() != READY && PPMwaitCount-- > 0)
  delay(100);
}
void loop() {
  if(Receiver.getState() == READY || Receiver.getState() == FAILSAFE) {
    if(ChannelNum == 0 || ChannelNum == ChannelCnt) {
      if(DSM2_Sent == 0) {
        for (byte i=0; i<DSM2_CHANNELS; i++) {
          pulse = Receiver.getChannelData(ChanIndex) - 980;
          pulse = constrain(pulse, 0, 0x3FF);
          DSM2_Channel[i*2]   = (byte)(i<<2) | highByte(pulse);
          DSM2_Channel[i*2+1] = lowByte(pulse);
        }
        sendDSM2();
        DSM2_Sent = 1;
      } else {
        if(Receiver.getState() == FAILSAFE) {
          delay(20);
          DSM2_Sent = 0;
        }
      }
    } else {
      if(ChannelNum == 1)
        DSM2_Sent = 0;
    }
  }

if (State == READY){
  digitalWrite(BINDING_LED,HIGH);  
}else{
    unsigned long currentMillis = millis();            
    if(currentMillis - ERRORpreviousMillis >= ERRORinterval)
    {
       ERRORpreviousMillis = millis();
       if(DisFlash == LOW)
       {
         digitalWrite(BINDING_LED,LOW);  // PPM TX LED
         DisFlash = HIGH;
       }
       else
       {
         digitalWrite(BINDING_LED,HIGH);  // PPM TX LED
         DisFlash = LOW;
       }
    }
}
}

void sendDSM2() {
    Serial.write(DSM2_Header, 2);
    Serial.write(DSM2_Channel, DSM2_CHANNELS*2);
}
void BindDSM2(){
  delay (250);
  DSM2_Header[0] = 0x80;
  unsigned long currentMillis = BIND_TIME + millis();        
  while(currentMillis > millis()){
    unsigned long currentMillis = millis();            
    if(currentMillis - previousMillis > BINDinterval)
    {            
       previousMillis = currentMillis;               
       if (DisFlash == LOW)
       {
          digitalWrite(BINDING_LED,LOW);  
          DisFlash = HIGH;
        }
        else
        {
           digitalWrite(BINDING_LED,HIGH);  
           DisFlash = LOW;               
         }
    }
    sendDSM2();
    delay(20);
  }
  DSM2_Header[0] = 0;
  digitalWrite(BINDING_LED, LOW);
}



评分

参与人数 2威望 +4 收起 理由
wjm99316 + 2 很给力!
A24 + 2 赞一个!

查看全部评分

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

沙发
发表于 2013-12-6 22:46 | 只看该作者
顶  下次给你2个DX10T高频头玩玩
3
发表于 2013-12-6 22:49 | 只看该作者
好像很牛逼的样子,你知道得太多了
4
发表于 2013-12-6 23:03 | 只看该作者
厉害~!~
5
发表于 2013-12-6 23:32 | 只看该作者
xu老师的MZ不是出嫁了么
6
发表于 2013-12-6 23:37 | 只看该作者
强人一个。。。。。。。。。。。
7
发表于 2013-12-6 23:45 | 只看该作者
看着很复杂,做完电路,开始编程序,然后是改遥控。楼主技术男
8
发表于 2013-12-7 00:05 | 只看该作者
整部了 楼主你干哈的
9
发表于 2013-12-7 00:06 | 只看该作者
头文件呢??
10
发表于 2013-12-7 00:17 | 只看该作者
火钳刘明
11
 楼主| 发表于 2013-12-7 00:34 | 只看该作者
蚊子飞飞 发表于 2013-12-7 00:06
头文件呢??

我用ARDUINO 0023版本,不需要,直接新建下载就行。
12
 楼主| 发表于 2013-12-7 00:36 | 只看该作者
目前使用的3.3v稳压芯片用1S供电不稳妥,当电池电压低于3.8V之后输出就完蛋了。
输出低于3V高频头完全罢工,好烦。
换个RT9193T试试。
13
发表于 2013-12-7 00:51 | 只看该作者
擦,高手在民间啊,牛逼
14
发表于 2013-12-7 00:56 | 只看该作者
虽然不知道你这个老家伙说的什么,看起来很厉害的样子
15
发表于 2013-12-7 01:06 | 只看该作者
比较牛 硬件我会做 程序还不会 是用的阿德伟诺吧

16
发表于 2013-12-7 01:45 | 只看该作者
徐神老师,MZ24是不是24个通道?
17
发表于 2013-12-7 01:48 | 只看该作者
你是老餘?
18
发表于 2013-12-7 01:54 | 只看该作者
yeweijin 发表于 2013-12-7 01:48
你是老餘?

他正是传说中的老除

19
发表于 2013-12-7 02:31 | 只看该作者
厉害,佩服
20
发表于 2013-12-7 07:43 | 只看该作者
牛逼
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

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

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