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

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

[技术交流] 关于arduino舵机扑翼机的全部说明以及教程

[复制链接]
跳转到指定楼层
楼主
发表于 2022-11-20 13:23 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 boyboyboy 于 2022-11-22 23:27 编辑

欢迎大家进来观看哈,好久没上论坛,感觉这个好东西一定要分享给我爱模型,一直在发短视频之类的自媒体,视频很多,喜欢的、感兴趣的大家可以关注一下哈~抖音/西瓜/头条/B站,ID:飞行小匠,如有问题可通过自媒体平台联系到我,纯属爱好、义务发帖


正题:
声明:国内基本上没有关于舵机扑翼机的相关教程,我个人又特别喜欢,所以才做的这个教程类的东西,希望大家多多支持
以下是第一代编程扑翼机的总体规划,最终飞行效果不是很好,见自媒体视频有详细说明
我个人也不是商业使用,纯粹的爱好者,给大家分享出来,希望所有感兴趣的网友可以一起制作,一起玩,有个爱好不容易,模友本来就是应该分享的,这篇文章应该算是干货吧。。。
关于这段代码:每个信号都需要自己的一组中断函数。单个输入来说还可以,但对于多个信号来说,它感觉很笨拙。理想情况下,可以使用单个函数来解码任意数量的 PWM 信号。
能够找到非常接近这个理想的东西:
使用 Arduino 解码 6 个伺服通道输入--最紧凑和简洁的方法。(这段代码是一个国外网友的,哪个国家的我忘记了抱歉,很感谢他,这是第一代代码)
有了这个很好的例子,重命名了一些变量并稍微修改了逻辑,但主要添加的是一个死区过滤器,以解决micros() 函数的不确定性用于对信号进行计时。除此之外,通过一个额外的指数滤波器传递输入,以去除任何未被死区过滤的尖峰。结果是可以操纵以控制伺服系统的非常平滑的输入信号。
其余代码仅创建两个可以由伺服系统解释的振荡 PWM 信号。接收器输入用于执行以下操作:
- 油门控制襟翼幅度;线性变化,因此油门加倍会使振幅加倍。
- 俯仰控制机翼的平面角。两个翅膀被命令同时上升。
- 滚动控制机翼的不对称平面角。一个翼被命令上升,另一个下降。 作者:飞行小匠 https://www.bilibili.com/read/cv18947607 出处:bilibili


扑翼机第一代飞行测试:

扑翼机第三代飞行测试:

尾翼设计制作教程:

舵机扑翼测试:




一下为第一代扑翼机pwm信号代码
[hide=d3000]#include <Servo.h>

// -- Constants:

  // PWM input:

const int N_INPUTS = 3;

const int DEADBAND = 4;

  // PWM output:

const int PWM_CHANGE = 500;

const int PWM_MID = 1500;

const float DECAY_INPUT = 0.1;

  // Amplitude control:

const int AMP_CUTOFF = 10;

const int AMP_OFFSET = 300;

  // Wave signals:

const float WAVE_INT = 150.0; // Half period

const float FREQ = PI/WAVE_INT;

//-- Variables:

Servo servo[2];

volatile int16_t pwm_raw[N_INPUTS] = {0};

int16_t pwm_input[N_INPUTS] = {0};

// -- Pin Change Interrupt to get PWM inputs:

ISR( PCINT0_vect ) {  

  static int32_t change_time[N_INPUTS] = {0};

  uint8_t mask = B00000010;

  for ( uint8_t index = 0 ; index < N_INPUTS ; index += 1 ) {      

    if( (change_time[index] == 0) && (PINB & mask) ) {  

      change_time[index] = micros();

    }

    else if( (change_time[index] != 0) && !(PINB & mask) ) {

      change_time[index] = ( micros() - change_time[index] ) - PWM_MID;



      int16_t diff = change_time[index] - pwm_raw[index];

      if( diff > DEADBAND ) {

        pwm_raw[index] = change_time[index] - DEADBAND;

      }

      if( diff < -DEADBAND ) {

        pwm_raw[index] = change_time[index] + DEADBAND;

      }

      change_time[index] = 0;

    }

    mask = mask << 1;

  }

}

// --

void input_filter( void ) {

  for( int index = 0; index < N_INPUTS; index += 1 ) {

    pwm_input[index] = pwm_raw[index]*DECAY_INPUT + pwm_input[index]*( 1 - DECAY_INPUT );

  }

}

// -- Function to set amplitude via throttle:

int amp_func( int input ) {

  int var = ( input + AMP_OFFSET );

  if( var <= AMP_CUTOFF ) {

    return 0;

  } else {

    return var - AMP_CUTOFF;

  }

}



// -- Wave functions [for wing oscillation]:

float tri_wave( void ) {

  static int last_time = millis();

  int int_time = millis() - last_time;

  if( int_time < WAVE_INT ) {

    return 2*int_time/WAVE_INT - 1;

  } else if ( (int_time > WAVE_INT) && (int_time < 2*WAVE_INT) ) {

    return  3 - 2*int_time/WAVE_INT;

  } else if( int_time > WAVE_INT ) {

    last_time = millis();

   

    return -1;

  }

}

float saw_wave( void ) {

  static int last_time = millis();

  int int_time = millis() - last_time;

  if( int_time < 2*WAVE_INT ) {

    return int_time/WAVE_INT - 1;

  } else {

    last_time = millis();

    return -1;

  }

}

float sin_wave( void ) {

  return sin( millis()*FREQ );

}



// -- Function to combine wing oscillation and dihedral angle:

int flap_func( int amplitude, int offset ) {

  if( amplitude == 0 ) {

    return constrain( offset , -PWM_CHANGE, PWM_CHANGE );

  } else {

    return constrain( offset + sin_wave()*amplitude , -PWM_CHANGE, PWM_CHANGE );

  }

}



// -- Main functions:

void setup() {

  // Enabling interrupt:

  PCICR |= (B00000001 << 0);

  // Setting PWM inputs:

  for ( int index = 0; index < N_INPUTS ; index += 1 ) {

    PCMSK0 = PCMSK0 | (B00000010 << index);

    pinMode( index + 9 , INPUT_PULLUP );

  }

  // Setting servo outputs:

  for( int index = 2; index <= 3 ; index += 1 ) {

    pinMode( index , OUTPUT );

    servo[index - 2].attach( index );

    servo[index - 2].write( PWM_MID );   

  }

  //Default to minimum throttle:

  pwm_raw[2] = -AMP_OFFSET;

  pwm_input[2] = pwm_raw[2];

  //Serial.begin(9600);

}

void loop() {

  input_filter();

  int16_t amp = amp_func( pwm_input[2] );

  servo[0].writeMicroseconds( PWM_MID - flap_func( amp , pwm_input[0] + pwm_input[1] ) );

  servo[1].writeMicroseconds( PWM_MID + flap_func( amp , -pwm_input[0] + pwm_input[1] ) );


关于第一代编程类扑翼机我个人的总体规划:
因为国内外采用舵机驱动的扑翼机基本没有超过100g的(散热、强度、重量等因素)都是超轻设计,所以我采用了计算的方式,大概规划了一下扑翼机的整体参数
翼展:0.9m--舵机单边0.45m
平均弦长:0.3m
飞行重量:45g左右
电池2s100mah,采用降压6.0v给舵机供电
为了减轻重量,机身极简制作
蓝箭5023的堵转扭矩是1.76kg/cm--0.176nm,经计算得知:翅膀在.025m的位置上90度的行程下,轨迹为0.3m左右,计算翅膀重量10g,翼面积为0.15平米,计算空气阻力后,舵机负载后的运动速度是2.4m/s,大概需要0.125s跑完一次,理论状态下,也就是说在1s内,翅膀可以扑翼两回(4下)。
能否飞行还是未知,具体制作与安装过程中遇到问题我还是随时调成这个设计
关于arduino,我是使用了uno进行的测试,nano板比较mini,很合适
关于电路图,连接方式也非常简单,图片我也更改过,在红色位置上9-12口连接接收机即可,注意接收机需要pwm信号支持

关于舵机扭矩、翅膀的扑翼分析与计算:
(理论只涉及到了空气阻力与力学的基本计算;非专业人员,如有错误请指出)








234514rgyyovlb0rrjryyg.jpg (0 Bytes, 下载次数: 0)

234514rgyyovlb0rrjryyg.jpg

234516b4b2v4pv4b44m74v.jpg (0 Bytes, 下载次数: 0)

234516b4b2v4pv4b44m74v.jpg

234518a8eeeb2wzblyv7qe.jpg (0 Bytes, 下载次数: 0)

234518a8eeeb2wzblyv7qe.jpg

234519xc4gggpo8x6izxsb.jpg (0 Bytes, 下载次数: 0)

234519xc4gggpo8x6izxsb.jpg

234521haeuczzu0hlwql90.jpg (0 Bytes, 下载次数: 0)

234521haeuczzu0hlwql90.jpg

234524etptx5tp55kc5nzp.jpg (0 Bytes, 下载次数: 0)

234524etptx5tp55kc5nzp.jpg

234626rfyrw6prri6hwhcf.jpg (0 Bytes, 下载次数: 0)

234626rfyrw6prri6hwhcf.jpg

234632lr11zxjiwr1lnvnp.jpg (0 Bytes, 下载次数: 0)

234632lr11zxjiwr1lnvnp.jpg

234637rambexw7a9h9rbhc.jpg (0 Bytes, 下载次数: 0)

234637rambexw7a9h9rbhc.jpg

234645glkkp7kdawx5lagp.jpg (0 Bytes, 下载次数: 0)

234645glkkp7kdawx5lagp.jpg

234651ebumbblown9o6id3.jpg (0 Bytes, 下载次数: 0)

234651ebumbblown9o6id3.jpg

234654gifddyn7izqdtywi.jpg (0 Bytes, 下载次数: 0)

234654gifddyn7izqdtywi.jpg

微信截图_20221120131242.png (117.36 KB, 下载次数: 164)

微信截图_20221120131242.png

评分

参与人数 1威望 +2 模币 +10 收起 理由
Glider + 2 + 10 很有用!

查看全部评分

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

沙发
发表于 2022-11-21 09:50 | 只看该作者
3
发表于 2022-11-21 10:04 | 只看该作者
厉害厉害,收藏了。
4
发表于 2022-11-21 11:14 | 只看该作者
加油,学习中
5
发表于 2022-11-22 22:00 | 只看该作者
6
发表于 2022-11-23 23:52 | 只看该作者
的确不错
7
发表于 2022-11-24 07:10 | 只看该作者
servo库和ppm库自带了中断设置程序吗?
8
发表于 2022-11-24 09:03 | 只看该作者
这个确实不错
9
发表于 2022-11-24 09:46 | 只看该作者
好多图片没打开
10
发表于 2022-11-24 12:27 | 只看该作者
高手,舵机选择上有没有推荐
11
发表于 2022-11-24 15:39 | 只看该作者
这个有创意
12
发表于 2022-11-25 10:55 | 只看该作者
舵机一直处于高速的正反转切换中 寿命是个问题
13
发表于 2022-12-1 16:07 | 只看该作者
一个字,上链接
14
发表于 2022-12-3 13:04 | 只看该作者
顶,收藏了
15
发表于 2022-12-4 00:38 | 只看该作者
牛!!!
16
发表于 2022-12-5 08:32 | 只看该作者
高人,改用无刷舵机搞个大的吧。
17
发表于 2022-12-9 13:49 | 只看该作者
确实好看了,飞行姿太好看了,有鹰一样的飞行姿态,不像一些高速扑翼的难看样子,像个飞不起来,拼命扑扇翅膀的蛾子
来自安卓客户端来自安卓客户端
18
发表于 2022-12-9 15:49 | 只看该作者
向大师致敬,果断收藏
19
发表于 2022-12-9 15:58 | 只看该作者
楼主许多照片咋打不开了啊
20
发表于 2022-12-9 23:27 | 只看该作者
您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

关闭

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

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