【问题标题】:Arduino Digital Update Pins Instead of Write?Arduino 数字更新引脚而不是写入?
【发布时间】:2014-12-20 13:48:05
【问题描述】:

我正在做一个有趣的项目(至少对我来说),以提高我使用 Arduino 和 C 的技能。使用 8 通道继电器板和 Arduino Uno,我将我的圣诞树变成了一个简单的均衡器。

我遇到的问题是,每次我将 HIGH 数字写入已点亮的引脚时,它都会闪烁,从而产生频闪效果。循环越快、越准确,这种效果就越明显。我怀疑我的问题是我冗长的代码。我宁愿更新需要更新的引脚,而不是不断地写所有的高或低。有数字更新吗?是否有一个现有功能可以记住或检查我可以在我自己的更新功能中使用的引脚状态?还是我应该简单地为每个通道创建和使用变量?

int DO = 2; //Pin for Digital Output - DO
int DA = A0; // Pin for Analog Output - AO
int mult = 5;
int threshold1 = 1 * mult; //Set minimum threshold for LED lit
int threshold2 = 2 * mult; //Set minimum threshold for LED lit
int threshold3 = 3 * mult; //Set minimum threshold for LED lit
int threshold4 = 4 * mult; //Set minimum threshold for LED lit
int threshold5 = 5 * mult; //Set minimum threshold for LED lit
int threshold6 = 6 * mult; //Set minimum threshold for LED lit
int threshold7 = 7 * mult; //Set minimum threshold for LED lit
int threshold8 = 8 * mult; //Set minimum threshold for LED lit
int threshold9 = 9 * mult; //Set minimum threshold for LED lit
int sensorvalue = 0;

//pinout
int white1 = 3;
int white2 = 4;
int white3 = 5;
int white4 = 6;
int blue1  = 7;
int blue2  = 8;
int blue3  = 9;
int red1   = 10;

void loop() {
    sensorvalue = ReadSens_and_Condition();  //Read the analog value

    //Troubleshooting
    //sensorvalue = 3;
    Serial.print("Analog: ");
    Serial.print(sensorvalue);  //Print the analog value
    Serial.print("  ");
    Serial.print("Threshold: ");
    Serial.print(threshold1);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold2);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold3);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold4);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold5);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold6);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold7);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold8);  //Print the analog value
    Serial.print("  ");
    Serial.print(threshold9);  //Print the analog value
    Serial.print("  ");
    Serial.print('\n');
    Serial.print('\n');

//mode 3 is best so far
int mode = 3;

int ReadSens_and_Condition(){
  int i;
  int sval = 0;

  for (i = 0; i < 50; i++){
    sval = sval + analogRead(DA);    // sensor on analog pin 0
  }

  sval = sval / 50;    // average
  sval = sval / 4;    // scale
  return sval;
}

void setup() {
  Serial.begin(9600);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);

}

//equalizer
if(mode == 3){

    //delay
    int pause = 5;

    if(sensorvalue >= threshold9){
      digitalWrite(white3, HIGH);
      digitalWrite(blue3, HIGH);
      digitalWrite(white2, HIGH);
      digitalWrite(blue2, HIGH);
      digitalWrite(white1, HIGH);
      digitalWrite(blue1, HIGH);
      digitalWrite(white4, HIGH);
      digitalWrite(red1, HIGH);
      delay(pause);
    }

    else if(sensorvalue >= threshold8){
      digitalWrite(white3, HIGH);
      digitalWrite(blue3, HIGH);
      digitalWrite(white2, HIGH);
      digitalWrite(blue2, HIGH);
      digitalWrite(white1, HIGH);
      digitalWrite(blue1, HIGH);

      delay(pause);

      digitalWrite(white4, LOW);
      digitalWrite(red1, LOW);

    }

    else if(sensorvalue >= threshold6){
      digitalWrite(white2, HIGH);
      digitalWrite(blue2, HIGH);
      digitalWrite(white1, HIGH);
      digitalWrite(blue1, HIGH);

      delay(pause);

      digitalWrite(white3, LOW);
      digitalWrite(blue3, LOW);
      digitalWrite(white4, LOW);
      digitalWrite(red1, LOW);
    }

    else if(sensorvalue >= threshold4){
      digitalWrite(white1, HIGH);
      digitalWrite(blue1, HIGH);

      delay(pause);

      digitalWrite(white2, LOW);
      digitalWrite(blue2, LOW);
      digitalWrite(white3, LOW);
      digitalWrite(blue3, LOW);
      digitalWrite(white4, LOW);
      digitalWrite(red1, LOW);

    }



    else if(sensorvalue >= threshold2){
      digitalWrite(white1, LOW);
      digitalWrite(white2, LOW);
      digitalWrite(white3, LOW);
      digitalWrite(white4, LOW);
      digitalWrite(blue1, LOW);
      digitalWrite(blue2, LOW);
      digitalWrite(blue3, LOW);
      digitalWrite(red1, LOW);
      delay(pause);

    }

  else {
      digitalWrite(white1, LOW);
      digitalWrite(white2, LOW);
      digitalWrite(white3, LOW);
      digitalWrite(white4, LOW);
      digitalWrite(blue1, LOW);
      digitalWrite(blue2, LOW);
      digitalWrite(blue3, LOW);
      digitalWrite(red1, LOW);
      delay(pause);
  }
}


}

【问题讨论】:

    标签: c arduino


    【解决方案1】:

    我遇到的问题是,每次我将 HIGH 数字写入已点亮的引脚时,它都会闪烁,从而产生频闪效果。

    Atmel(或 AFAIK 任何其他)微控制器并非如此。如果您将一个已经很高的输出设置为高电平,那么它将保持高电平而不会出现任何故障。此外,设置输出只需要几个周期,所以如果它是毛刺,那么如果没有示波器,您将看不到它 - 将 LED 闪烁 0.00001 秒太快而无法注意到。

    我已将您的代码(稍作修改,因此它是有效的 - 您已将一些函数定义放入循环函数中)加载到 arduino ng 中,没有任何其他连接,并且所有输出在使用范围探测时都是稳定的(除了对于串行输出,其中有数据)。通过在 5V、GND 和模拟输入之间连接一个电位器,我可以使每个输出打开或关闭,并且当它们这样做时,它们不会出现故障或频闪。

    我怀疑您在模拟信号中看到了噪声的结果,这导致状态来回变化。尝试平滑迭代之间的值。此外,您在设置输出值的过程中也有延迟;只需在循环中放置一次延迟,时间就不会那么混乱了。

    【讨论】:

    • 感谢您对这些组件如何工作的精彩解释。我实际上怀疑 Atmel 会识别出输出很高而不是故障,但我仍然看到频闪。
    • 我最终还是自己解决了这个问题。我实际上是回来更新帖子的。你是对的。这是模拟信号中的噪声。我玩了我的时机和延迟一点,一切都很好。对我来说,除了学习体验和乐趣之外没什么特别的:youtu.be/jkI-5WdBZIM?list=UUFUY0-QPkLLdw_7Vr6ERNFQ
    • 只是出于好奇,您知道我的 ReadSens_and_Condition() 函数中的 for 语句运行需要多快吗?没有它,我得到了很多 0 值读取,即使它显然不应该是 0。增加样本数量似乎确实会减慢函数的速度。应该吗?
    • @Front_End_Dev arduino.cc/en/Reference/AnalogRead 大约需要 100 微秒,而你调用了 50 次,所以整个过程大约需要 5 毫秒。其他语句是几个时钟周期,所以不会影响它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多