使用串行端口控制LED

时间:2013-04-23 03:22:48

标签: arduino

作为一个简单的自动化项目的一部分,我试图通过串口控制一些LED。我无法使以下代码正常工作

int pin =0;
int state = 0;

void setup() {
    Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {
    // send data only when you receive data:
    if (Serial.available() > 0) {
        // read the incoming byte:
        if(Serial.read() == 'S' && Serial.read() == 'S') {
            // Command to set the pin
            pin  = Serial.read() - 65;
            state = Serial.read() - '0';
            Serial.print("Set State Command received");
            // Set the Pin
            pinMode(pin, OUTPUT);          
            digitalWrite(pin, state == 0? LOW:HIGH);
        }
    }
}

我从我的python程序发送“SSN1”到Arduino串口进行测试,没有任何反应(我在引脚13上连接了一个LED)

SS -  Set State Command
N  - (pin no) + 'A'  - Pin number 13
1  - State ( 0 = LOW, 1= HIGH)

4 个答案:

答案 0 :(得分:2)

您希望等到 4 串行字节累积在串行缓冲区上。

void loop() {
    // polls the serial buffer
    while (Serial.available() < 4);
    if (Serial.read() == 'S' && Serial.read() == 'S') {
       char type = Serial.read();
       char pin = Serial.read() - 65;
       // do something with the results
    }
}

请注意,您可能希望在输入之间实现某种填充(例如,添加固定长度的空格),因为串行缓冲区可能会丢弃一个字节或溢出,这可能会导致意外结果。此外,有些人会抱怨while (Serial.available() < 4)命令,因为计算机科学家已接受过“polling = bad!”的训练,但在Arduino的情况下,它没有任何区别,因为它只运行一项任务。 / p>

顺便说一句,您也可以使用串行数据中断,但这不属于此响应的范围。

答案 1 :(得分:1)

实际上,我也在努力争取类似的东西。由于串行通信遇到的问题(有时消息很慢并且分片发送,ACII代码很难记住)我采用了不同的解决方案。基本上我添加了标题“&gt;”并且发送到串口的消息的尾部“&lt;”并且我使用Arduino代码来考虑&gt;&lt;之间的消息。作为命令。然后我使用ATOI将字符串转换为整数。 在下面的代码中,您将看到我使用以下数字来让Arduino更改pin2和pin13的状态。 以下是与此代码关联的命令:

  

1000℃;设置引脚13 HIGH,   2000&LT;将引脚13置为低电平,   3000 LT;设置引脚2 HIGH,   4000&LT;将引脚2置为低电平

因此,只需将&gt;&lt;之间的数字发送给序列号即可。它应该工作。 我也使用上面的方法来设置PWM速度,只需操作与收到的消息相关的字符串。我没有在这个示例中包含PWM命令,只包括与引脚13和引脚2相关的命令。我认为使用数字和字符串标识符来打开和关闭消息会更加简单和安全。 加载草图,打开串行监视器并发送&gt; 1000&lt;,您应该看到引脚13上的内部LED点亮,依此类推。如果您需要任何其他帮助,请与我们联系。

char inData[10];
int index;
boolean started = false;
boolean ended = false;
String message = "I am ready!, Send your command....";

void setup(){
    Serial.begin(9600);
    Serial.println(message);
    pinMode (13, OUTPUT);
    pinMode (2, OUTPUT);
}

void loop()
{
    while(Serial.available() > 0)
    {
        char aChar = Serial.read();
        if(aChar == '>')
        {
            started = true;
            index = 0;
            inData[index] = '\0';
        }
        else if(aChar == '<')
        {
            ended = true;
        }
        else if(started)
        {
            inData[index] = aChar;
            index++;
            inData[index] = '\0';
        }
    }

    if(started && ended)
    {
        int inInt = atoi(inData);

        // set  pin 13 HIGH
        if (inInt < 1000)
        { 
            digitalWrite(13, HIGH);
        }
        //set pin 13 LOW
        else if (inInt < 2000)
        { 
            digitalWrite(13, LOW); 
        }
        //set  pin 2 HIGH
        else if (inInt < 3000)
        { 
            digitalWrite(2, HIGH);
        }
        //set il pin 2 LOW
        else if (inInt < 4000)
        { 
            digitalWrite(2, LOW);
        }

        started = false;
        ended = false;
        index = 0;
        inData[index] = '\0';
    }
}

答案 2 :(得分:0)

从Arduino的Physical Pixel Tutorial

中查看此示例代码
const int ledPin = 13; // the pin that the LED is attached to
int incomingByte;      // a variable to read incoming serial data into

void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // see if there's incoming serial data:
  if (Serial.available() > 0) {
    // read the oldest byte in the serial buffer:
    incomingByte = Serial.read();
    // if it's a capital H (ASCII 72), turn on the LED:
    if (incomingByte == 'H') {
      digitalWrite(ledPin, HIGH);
    } 
    // if it's an L (ASCII 76) turn off the LED:
    if (incomingByte == 'L') {
      digitalWrite(ledPin, LOW);
    }
  }

确认您在串行监视器上看到SSN1正在通过。

答案 3 :(得分:0)

我改进了我的代码,因为它看起来像这样

int pin =0;
int state = 0;

void setup() {
        Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
}

void loop() {

        // send data only when you receive data:
        if (Serial.available() > 3) { // I am using chunk of 4 characters/bytes as a command 
                // read the incoming byte:
                if(Serial.read() == 'S' && Serial.read() == 'S') {
                  // Command to set the pin
                  pin  = Serial.read() - 65;
                  state = Serial.read() - '0';
                  Serial.print("Set State Command received");
                  // Set the Pin
                  pinMode(pin, OUTPUT);          
                  digitalWrite(pin, state == 0? LOW:HIGH);
                }
                delay(50); 
        }
}

它对我来说非常合适。由于循环频率很高,Arduino无法为连续读取拾取字节。所以我们等待4个字节在缓冲区中累积来读取它们(Arduino的串行缓冲区是64字节)。