从Arduino到PC的串行端口噪音

问题描述 投票:0回答:1

我正在尝试将开关连接到Arduino板,然后通过串口将Arduino板连接到我的PC,波特率为9600。想法是,当开关关闭时,之前保存的视频会打开我的电脑可以玩。当开关按下到打开位置时,第二个视频会在第一个正在播放的视频之上播放。

我面临的问题是,当我按下开关时,第二个视频闪烁,时隐时现,表明串口上的信号在0和1之间波动(可能是脉冲的形式)。我想出的解决方案/黑客是在串行输入上应用指数衰减移动平均滤波器。它通过适当的移动平均长度和阈值解决了问题,但当我不按下开关时,它会在停止视频时产生几秒钟的延迟。

有更好的想法/解决方案吗?

这是用于对 Arduino 板进行编程的 Arduino 代码。开关连接到地和引脚 2:

/*
Input Pull-up Serial

This example demonstrates the use of pinMode(INPUT_PULLUP). It reads a digital
input on pin 2 and prints the results to the Serial Monitor.

The circuit:
  - momentary switch attached from pin 2 to ground
  - built-in LED on pin 13

Unlike pinMode(INPUT), there is no pull-down resistor necessary. An internal
20K-ohm resistor is pulled to 5V. This configuration causes the input to read
HIGH when the switch is open, and LOW when it is closed.


This example code is in the public domain.

https://www.arduino.cc/en/Tutorial/BuiltInExamples/InputPullupSerial
*/

void setup() 
{
  //start serial connection
  Serial.begin(9600);
  //configure pin 2 as an input and enable the internal pull-up resistor
  pinMode(2, INPUT_PULLUP);
  pinMode(13, OUTPUT);
}

void loop() 
{
  //read the pushbutton value into a variable
  int sensorVal = digitalRead(2);
  //print out the value of the pushbutton
  Serial.println(sensorVal);

  // Keep in mind the pull-up means the pushbutton's logic is inverted. It goes
  // HIGH when it's open, and LOW when it's pressed. Turn on pin 13 when the
  // button's pressed, and off when it's not:
  if (sensorVal == HIGH) {
    digitalWrite(13, LOW);
  } else {
    digitalWrite(13, HIGH);
  }
}

这是从 Arduino 读取串行输入并将两个视频叠加显示的处理代码:

import processing.video.*;
import processing.serial.*;

Serial myPort;  // The serial port

boolean PlaySecondMovie = false;

final int MovingAvgLength = 50;
float MovingAvg = 0;
final float MovingAvgThreshold = 0.002;

final int NumMovies = 2;
Movie mymovies[] = new Movie[NumMovies];

/*void keyPressed() 
{
  if (key == 'a') 
  {
    PlaySecondMovie=!PlaySecondMovie;
    //mymovies[1].resume();
  }
}*/


void setup() 
{
  // List all the available serial ports:
  printArray(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 9600);
  
  size(640, 480);

  mymovies[0] = new Movie(this, "/Users/macbookpro/Desktop/Shiraz/2 films/2.mp4");
  mymovies[0].loop();
  mymovies[1] = new Movie(this, "/Users/macbookpro/Desktop/Shiraz/2 films/1.mp4");
  mymovies[1].loop();
  //mymovies[1].stop();
}

float approxMovingAverage (float avg, float new_sample, int N) 
{
    avg -= avg / N;
    avg += new_sample / N;
    return avg;
}


/*int calcAvg(Vector)
{
  float sum = 0;
  for (int i: MovingWindow)  sum += i;
  float avg = sum/MovingWindow.length;
  if (avg > 0.5)
    return(1);
  else
    return(0);
}*/



// Step 4. Read new frames from the movie.
void movieEvent(Movie mymovies) 
{
  mymovies.read();
}

// Step 5. Display movie.
void draw() 
{
  while (myPort.available() > 0) 
  {
    String inBuffer = myPort.readString();   
    if (inBuffer != null) 
    {
      inBuffer = trim(inBuffer);
      println(inBuffer);
      if ("0".equals(inBuffer))
      {
        MovingAvg = approxMovingAverage (MovingAvg, 1, MovingAvgLength);      
      }
      else
      {
        MovingAvg = approxMovingAverage (MovingAvg, 0, MovingAvgLength);
      }
      println(MovingAvg);
    }
  }
  
  if (MovingAvg > MovingAvgThreshold) 
    PlaySecondMovie = true;
  else
    PlaySecondMovie = false;
  
  background(0);
  image(mymovies[0], 0, 0, width, height);
  if (PlaySecondMovie) 
  {
    image(mymovies[1], width/2, 0, width/2, height/2);
    mymovies[1].loop();
  }
  else
  {
    mymovies[1].pause();
  }
  //image(m[2], width/4, height/2, 3*width/4.0, height);
}

    

/*void keyPressed() {
  int keyIndex = -1;
  if (key >= 'A' && key <= 'Z') {
    keyIndex = key - 'A';
  } else if (key >= 'a' && key <= 'z') {
    keyIndex = key - 'a';
  }
  if (keyIndex == -1) {
    // If it's not a letter key, clear the screen
    background(0);
  } else { 
    // It's a letter key, fill a rectangle
    fill(millis() % 255);
    float x = map(keyIndex, 0, 25, 0, width - rectWidth);
    rect(x, 0, rectWidth, height);
  }
}*/
arduino switch-statement serial-port noise
1个回答
0
投票

如果您有硬件开关,它可能会弹跳。因此,如果您检测到开关发生变化,请等待给定时间,例如尝试10ms,在Arduino上,那么你在PC端应该不会有延迟。您还可以将输入中的值读取到具有固定采样率的数组中,并将该数组与全零或全一进行比较。还有集成电路可以防止开关弹跳或发出去弹跳信号,但我认为软件解决方案应该可以做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.