求这个函数式的意义-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1983|回复: 7

[未解决] 求这个函数式的意义

[复制链接]
发表于 2020-10-31 11:29 | 显示全部楼层 |阅读模式
void sample() {
  int prev[4] = {raw[0], raw[1], raw[2], raw[3]};
  raw[0] = analogRead(pin[0]);
  raw[1] = analogRead(pin[1]);
  raw[2] = analogRead(pin[2]);
  raw[3] = analogRead(pin[3]);
  for (int i=0; i<4; ++i)
    level[i] = abs(raw[i] - prev[i]);
}
求这一段函数的意义,按道理raw[i]不是等于prev[i]么,这样循环减4次是为了什么哦

发表于 2020-10-31 14:36 | 显示全部楼层
个人理解,最后一句应该是写成:level[i] = abs(raw[i] - prev[i+1]);  
level表示阶梯意思,程序用来对比读取0123的值的变化值,呈现LEVEL的状态。
 楼主| 发表于 2020-10-31 16:40 | 显示全部楼层
#include <Keyboard.h>

const int min_threshold[4] = {20, 20, 20, 20};
const long cd_length = 8000;
const long cd_antireso_length = 8000;
const float k_antireso = 0.85;
const float k_decay = 0.96;

const long cd_stageselect = 200000;
bool stageselect = false;
bool stageresult = false;

float threshold[4] = {20, 20, 20, 20};
int raw[4] = {0, 0, 0, 0};
int level[4] = {0, 0, 0, 0};
long cd[4] = {0, 0, 0, 0};
bool pressed[4] = {false, false, false, false};
int t0 = 0;
int dt = 0, sdt = 0;
const int pin[4] = {A0, A1, A2, A3};
const int key[4] = {'d', 'f', 'j', 'k'};
int led[4] = {6,5,10,11};

void sample() {
  int prev[4] = {raw[0], raw[1], raw[2], raw[3]};
  raw[0] = analogRead(pin[0]);
  raw[1] = analogRead(pin[1]);
  raw[2] = analogRead(pin[2]);
  raw[3] = analogRead(pin[3]);
  for (int i=0; i<4; ++i)
    level[i] = abs(raw[i] - prev[i]);
}

void sampleSingle(int i) {
  int prev = raw[i];
  raw[i] = analogRead(pin[i]);
  level[i] = abs(raw[i] - prev);
}

void setup() {
  analogReference(DEFAULT); // use internal 1.1v as reference voltage
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  Keyboard.begin();
  t0 = micros();
  Serial.begin(9600);
}

void parseSerial() {
  static char command = -1;
  if (Serial.available() > 0) {
    char c = Serial.read();
    if (command == -1)
      command = c;
    else {
      switch (command) {
      case 'C':
        Serial.write('C');
        Serial.write(c);
        Serial.flush();
        break;
      case 'S':
        stageselect = (c == '1');
        digitalWrite(LED_BUILTIN, stageselect ? HIGH : LOW);
        break;
      case 'R':
        stageresult = (c == '1');
        digitalWrite(LED_BUILTIN, stageresult ? HIGH : LOW);
        break;
      }
      command = -1;
    }
  }
}

void loop() {
  static int si = 0;

  parseSerial();
  
  int t1 = micros();
  dt = t1 - t0;
  sdt += dt;
  t0 = t1;
  
  while (sdt >= 1000) {
    sdt -= 1000;
    for (int i = 0; i != 4; ++i)
      threshold[i] *= k_decay;
  }

  for (int i = 0; i != 4; ++i) {
    if (cd[i] > 0) {
      cd[i] -= dt;
      if (cd[i] <= 0) {
        cd[i] = 0;
        if (pressed[i]) {
          Keyboard.release(stageresult ? KEY_ESC : key[i]);
          pressed[i] = false;
        }
      }
    }
  }
  
  int i_max = 0;
  int level_max = 0;
  
  for (int i = 0; i != 4; ++i) {
    if (level[i] > level_max && level[i] > threshold[i]) {
      level_max = level[i];
      i_max = i;
    }
  }

  if (i_max == si && level_max > min_threshold[i_max]) {
    if (!pressed[i_max]) {
      if (stageresult) {
        Keyboard.press(KEY_ESC);
      } else {
        Keyboard.press(key[i_max]);
  
      }
      pressed[i_max] = true;
    }
    for (int i = 0; i != 4; ++i)
      cd[i] = cd_antireso_length;
    cd[i_max] = (stageselect ? cd_stageselect : cd_length);
    for (int i = 0; i != 4; ++i)
      threshold[i] = max(threshold[i], level_max * k_antireso);
    threshold[i_max] = level_max;
    sdt = 0;
   
  }

  sampleSingle(si);
  si = (si + 1) & 3;
  
}
这个是全段代码
 楼主| 发表于 2020-10-31 16:42 | 显示全部楼层
qqkkdok 发表于 2020-10-31 14:36
个人理解,最后一句应该是写成:level = abs(raw - prev);  
level表示阶梯意思,程序用来对比读取0123的值 ...

i+1确实可以理解呢,可是下载的别人的代码确实是这个,这个是一个震动感应键盘的代码,有点看不懂。。。。。
 楼主| 发表于 2020-10-31 16:42 | 显示全部楼层
qqkkdok 发表于 2020-10-31 14:36
个人理解,最后一句应该是写成:level = abs(raw - prev);  
level表示阶梯意思,程序用来对比读取0123的值 ...

我把整个程序代码贴出来了
发表于 2020-10-31 18:17 | 显示全部楼层
这有啥看不懂的,raw[i] 是本次调用 sample 的状态,prev[i] 是上次调用 sample 的状态,两次有差异代表着按键状态有改变
发表于 2020-11-1 13:12 | 显示全部楼层
本帖最后由 shouzama 于 2020-11-1 13:16 编辑
void sample() {
  int prev[4] = {raw[0], raw[1], raw[2], raw[3]};
  raw[0] = analogRead(pin[0]);
  raw[1] = analogRead(pin[1]);
  raw[2] = analogRead(pin[2]);
  raw[3] = analogRead(pin[3]);
  for (int i=0; i<4; ++i)
    level = abs(raw - prev);
}

OK,依程式內容來看,raw[]會保存pin[]的讀取值,其結果
為 0~1023
一開始,由 prev[] 先儲存先前的 raw[] 記錄值,然後重新
讀取一次將 raw[] 記錄值刷新
接下來計算 raw[]-prev[] 的絕對值(變化量)並存入 level[]

不過 for 迴圈雖然定義由 0 開始,但 ++i 是先將 i=i+1
算完才進行後續處理,也就是說這個迴圈會計算 level[1]
~[4],而且是用 raw[1]~[4] 及 prev[1]~[4] 來算? 這跟
前面用 [0]~[3] 的運作又對不上...是我理解錯了嗎?
发表于 2020-11-2 12:14 | 显示全部楼层
暂且不管for的写法对不对,一楼这段代码给人的感觉就是想检测每次raw[i]的变化量(也就是A0~A4的变化量)并保存于level[i],而纵观整个程序,实际并没有调用到这段代码。你这个程序估计是键盘程序,这段的写法都用的模拟输入,我猜这段有可能原来是用于摇杆的代码段(当然也有可能用于方向按钮的),一般会用在四向控制信号上,比如双轴云台之类,只是之后用abs()取了绝对值就看不懂了,这样就无法分辨变化的方向了。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-29 20:37 , Processed in 0.206201 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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