首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arduino项目--用发光二极管表示土壤湿度

Arduino项目--用发光二极管表示土壤湿度
EN

Code Review用户
提问于 2019-07-18 09:45:33
回答 2查看 85关注 0票数 4

我最近开始阅读“头第一C”一书。我想在写好的、习惯的、现代的C方面跟上速度。我也读过现代C书的前几章,但我发现Head首先是对语言的更好的介绍。

下面的代码是第一个更大的,arduino任务。这是一个非常直接的任务,LED应该用来指示植物的土壤湿度。我已经超越了基本的任务,使用3色LED,其中引脚11应该是高的绿色,12高的红色和两个高的橙色。

这给创建一个抽象这些细节的好的、一致的api带来了一些挑战。我想在解决方案中使用指针和指针算术,只是为了了解它们。我可能可以使用数组重写,并避免使用0最后的元素,尽管我仍然需要处理指针衰减。

任何指点:-)什么可以改变,把它变成一个好的,惯用的,现代的解决方案?不管指针使用与否。

代码语言:javascript
复制
int const RED[] = { 12, 0 };
int const GREEN[] = { 11, 0 };
int const ORANGE[] = { 11, 12, 0 };
int const DEFAULT_DURATION = 1000;
int const DEFAULT_COUNT = 1;

void blink(int color[]);
void blink(int color[], int duration, int count);
void blinkSequence(int* color[]);
void blinkSequence(int* color[], int duration, int count);
void on(int color[]);
void off(int color[]);

void setup() {
  // initialize LED Pins as output
  Serial.begin(9600);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
  pinMode(13, OUTPUT);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
}

void loop() {
  int m = analogRead(0);
  int interval = 2000;
  Serial.print("Moisture is: ");
  Serial.println(m);
  if (m <= 580) {
    //Really Dry!: 580-
    int* seq[] = { RED, ORANGE, 0 };
    blinkSequence(seq, 150, 2);
    interval = 0;
  } else if (m <= 700) {
    //Needs water: 700 - 581
    blink(RED, 500);
    interval = 500;
  } else if (m <= 740) {
    //Could be wetter: 740 - 701
    blink(ORANGE, 4000);   
    interval = 50;
  } else if (m <= 870) {
    //Happy range: 870 - 741
    blink(GREEN, 5000);
    interval = 50;
  } else {
    //Overwatered: 870+
    int* seq[] = { GREEN, ORANGE, 0 };
    blinkSequence(seq, 200, 5);
    interval = 3000;
  }

  delay(interval);
}

void blinkSequence(int* colors[], int duration, int count) {
  for (int i = count; i > 0; i--) {
    int** inner = colors;
    for(;*inner;inner++) {
      blink(*inner, duration);
    }
  }
}

void blink(int color[], int duration) {
  on(color);
  delay(duration);
  off(color);
}

void blinkSequence(int* colors[]) {
  for(;*colors;colors++) {
    blink(*colors);
  }
}

void blink(int color[]) {
  on(color);
  delay(DEFAULT_DURATION);
  off(color);
}

void on(int color[]) {
  for(;*color;color++) {
    digitalWrite(*color, HIGH);
    //Serial.print("HIGH:");
    //Serial.println(*color);
  }
}

void off(int color[]) {
  for(;*color;color++) {
    digitalWrite(*color, LOW);
    //Serial.print("LOW:");
    //Serial.println(*color);
  }
}
EN

回答 2

Code Review用户

发布于 2019-07-18 17:37:38

您编写了几个没有空格的for循环。请不要这样做,因为它使代码更难阅读。

而不是

代码语言:javascript
复制
  for(;*colors;colors++) {
    blink(*colors);
  }

你可能更喜欢

代码语言:javascript
复制
  while (*colors) {
    blink(*colors++);
  }

loop()移动到文件底部将为您节省一些前向声明。

添加一个Serial.print()标志可能会使您的debug语句受益,因此不需要对它们进行注释。

像计数和持续时间这样的事情不会变成负数。我看不到delay()digitalWrite()的签名,但你的一些ints可能想成为uint

票数 2
EN

Code Review用户

发布于 2019-07-18 19:14:54

首先,这可能是C++而不是C,C编程语言不支持函数重载(例如眨眼)。

幻数

在编程中,幻数是代码中的一个数值常量,它不确定是什么。神奇的数字使代码更难理解、调试和维护。当魔术数字被用作数组的基础时,这意味着代码可能需要在多个地方进行编辑,而不仅仅是在一个位置。

示例:

代码语言:javascript
复制
int *colors[10];

for (c = 0; c < 10; c++)
{
    do_something_with_color(colors[c]);
}

如果定义了符号常量,这将更容易修改和维护。

代码语言:javascript
复制
int const MAX_COLORS = 10;
int *colors[MAX_COLORS];

for (c = 0; c < MAX_COLORS; c++)
{
    do_something_with_color(colors[c]);
}

程序中有大量的数字常量,很少情况下是使用int const SYMBOLIC_NAME = value定义的。如果以这种方式定义所有数字常量,可能会更好。这些数值常量的一些例子是700、581、500、2000、4000等。

是500毫秒、2000毫秒和4000毫秒?

评论

评论

代码语言:javascript
复制
    //Really Dry!: 580-
    //Needs water: 700 - 581
    //Could be wetter: 740 - 701

在这种情况下并不是很有意义。如果您想要创建一个块注释来描述LED的用途,然后将常量的符号名建立在这个块注释上,这可能会更有帮助。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/224393

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档