简体   繁体   English

串口无法正常工作?

[英]Serial port not working?

I made a program that sends out data to my arduino which detects what was sent and then turns on the correct pin according to what key is pressed. 我制作了一个程序,将数据发送到我的arduino,检测发送的内容,然后根据按下的键打开正确的引脚。

When using the arduino software from my windows computer the arduino sketch works fine, I can make each pin turn on and off by sending either WAS Or D. 当我从我的Windows计算机上使用arduino软件时,arduino草图工作正常,我可以通过发送WAS或D来打开和关闭每个引脚。

When sending via node the RX light on the arduino flashes but nothing else happens. 当通过节点发送时,arduino上的RX灯闪烁,但没有其他任何事情发生。

Can anyone help? 有人可以帮忙吗?

Node.js program: Node.js程序:

var httpServer = require('http').createServer(function(req, response){ /* Serve your static files */ })
httpServer.listen(8080);

var nowjs = require("now");
var everyone = nowjs.initialize(httpServer);

everyone.now.logStuff = function(msg){
    console.log(msg);
}

var SerialPort = require('serialport2').SerialPort;
var assert = require('assert');

var portName;

if (process.platform == 'win32') {
  portName = 'COM4';
} else if (process.platform == 'darwin') {
  portName = '/dev/cu.usbserial-A800eFN5';
} else {
  portName = '/dev/ttyUSB0';
}

var readData = '';
var sp = new SerialPort();

sp.on('close', function (err) {
  console.log('port closed');
});

sp.on('error', function (err) {
  console.error("error", err);
});

sp.on('open', function () {
  console.log('port opened... Press reset on the Arduino.');
});

sp.open(portName, {
  baudRate: 9600,
  dataBits: 8,
  parity: 'none',
  stopBits: 1,
  flowControl: false
});

everyone.now.forward = function() {
sp.write("w");
}

everyone.now.back = function() {
sp.write("s");
}

everyone.now.left = function() {
sp.write("a");
}

everyone.now.right = function() {
sp.write("d");
}

sp.on('data', function(data) {
  console.log(data.toString());
});

Arduino Program: Arduino计划:

void setup(){
  Serial.begin(9600);
  Serial.write("READY");
  //Set all the pins we need to output pins
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
}

void loop (){
  if (Serial.available() > 0) {

    //read serial as a character
    char ser = Serial.read();
    Serial.write(ser);
    //NOTE because the serial is read as "char" and not "int", the read value must be compared to character numbers
    //hence the quotes around the numbers in the case statement
    switch (ser) {
      case 'w':
        move(8);
        break;
      case 's':
        move(9);
        break;
      case 'a':
        move(10);
        break;
      case 'q':
        move(10);
        move(8);        
        break;
      case 'd':
        move(11);
        break;
      case 'e':
        move(11);
        move(8);
        break;
    }
  }
}

void move(int pin){
  Serial.print(pin);  
  digitalWrite(pin, HIGH);
  delay(1);
  digitalWrite(pin, LOW);
}

I recently dabbled into this. 我最近涉足了这个问题。 The Arduino automatically resets when it receives serial communication from most things other than the Arduino IDE. 当Arduino从Arduino IDE以外的大多数东西接收串行通信时,它会自动重置。 This is why you can send from the IDE but not node.js. 这就是您可以从IDE而不是node.js发送的原因。

I have an Uno and put a capacitor between Reset and Ground.Here's a page with some good info on the subject. 我有一个Uno并在Reset和Ground之间放一个电容器。这是一个有关该主题的一些好信息的页面。
Good luck. 祝好运。 http://arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection http://arduino.cc/playground/Main/DisablingAutoResetOnSerialConnection

On the capacitor and reset issue... There is a small capacitor between one of the serial control lines and reset on the Arduino in the later models. 关于电容和复位问题......其中一条串行控制线之间有一个小电容,后面的型号中Arduino复位。 This capacitor causes the Arduino to reset when the port is opened but otherwise does not interfere with normal serial operation. 当端口打开时,该电容会导致Arduino复位,但不会干扰正常的串行操作。

This reset trick allows the code upload to reset the Arduino as part of the upload process. 这种重置技巧允许代码上传在上传过程中重置Arduino。 When the Arduino starts up the code boot loader runs first for a short time before the loaded code runs. 当Arduino启动时,代码引导加载程序在加载的代码运行之前首先运行一小段时间。

The upload process is: Reset the Arduino which starts the boot loader, start the upload process in the Arduino IDE, establish communications, upload, then run the loaded code. 上传过程是:重置启动引导加载程序的Arduino,在Arduino IDE中启动上传过程,建立通信,上传,然后运行加载的代码。 When the Arduino starts up it waits for uploads for a short period of time, if none are received, it moves on to running the code. 当Arduino启动时,它会等待很短一段时间的上传,如果没有收到,它会继续运行代码。

I find this very useful as it allows us to effectively reset the Arduino just by closing and opening the port. 我发现这非常有用,因为它允许我们通过关闭和打开端口来有效地重置Arduino。 In the old Arduino's, without this capacitor, you had to press the reset button at the right time to get the code to upload. 在旧的Arduino中,如果没有这个电容器,您必须在正确的时间按下重置按钮以获取要上载的代码。 And the timing was such that the Arduino spent much more time waiting before it started with the uploaded code. 而且时间安排使得Arduino在开始上传代码之前花了更多的时间等待。

In the problem described here, I do not believe he was having any troubles due to the reset trick used. 在这里描述的问题中,由于使用了重置技巧,我不相信他有任何麻烦。 It should have had only the effect of resetting the Arduino when he opened the serial port, and from the looks of his information, this is a desired side-effect. 它应该只有在打开串口时重置Arduino的效果,从他的信息看起来,这是一个理想的副作用。

I use node on a daily basis to send actions to my Arduino via usb or via bt and it works great in both cases. 我每天都使用节点通过usb或bt向我的Arduino发送动作,它在两种情况下都很有用。 I think your problem comes from sending letters. 我认为你的问题来自寄信。 You should send a buffer instead, with the ascii value of the letter, just like that: 您应该使用字母的ascii值发送缓冲区,就像这样:

myPort.write(Buffer([myValueToBeSent]));

also, for this, I think you would be better with some "logic" interface, with data headers, number of actions, stuff like that. 另外,对于这一点,我认为你会更好地使用一些“逻辑”界面,包括数据标题,动作数量等等。 It is no required for you but it will make your code more robust and easier to modify in the future. 它不是必需的,但它将使您的代码更加强大,并且将来更容易修改。

Here is an example of how I do it. 这是我如何做的一个例子。 First, Node: 首先,节点:

var dataHeader = 0x0f, //beginning of the data stream, very useful if you intend to send a batch of actions
myFirstAction = 0x01,
mySecondAction = 0x02,
myThirdAction = 0x03;

You then call them like you did: 然后你像他们一样打电话给他们:

everyone.now.MyBatchOfActions = function() {
    sp.write(Buffer([dataHeader]));

    sp.write(Buffer([0x03])); // this is the number of actions for the Arduino code

    sp.write(Buffer([myFirstAction]));
    sp.write(Buffer([mySecondAction]));
    sp.write(Buffer([myThirdAction]));
}

This way it is easy on the Arduino to Serial.read() the data: (Note that you need to define data header and data footer somewhere) 这样就可以很容易地将Arduino传递给Serial.read()数据:(注意你需要在某处定义数据头和数据页脚)

void readCommands(){
    while(Serial.available() > 0){

        // Read first byte of stream.
        uint8_t numberOfActions;
        uint8_t recievedByte = Serial.read();

        // If first byte is equal to dataHeader, lets do
        if(recievedByte == DATA_HEADER){
            delay(10);

            // Get the number of actions to execute
            numberOfActions = Serial.read();

            delay(10);

            // Execute each actions
            for (uint8_t i = 0 ; i < numberOfActions ; i++){

                // Get action type
                actionType = Serial.read();

                if(actionType == 0x01){
                    // do you first action
                }
                else if(actionType == 0x02{
                    // do your second action
                }
                else if(actionType == 0x03){
                    // do your third action
                }
            }
        }
    }
}

I hope I'm clear and I hope it helps! 我希望我很清楚,我希望它有所帮助! Cheers! 干杯!

In my case the issue was the reset, but that the serial port was opened - but not available for write until the reset has finished. 在我的情况下,问题是重置,但串口已打开 - 但在重置完成之前无法写入。 Putting a 3s delay before writing to the port fixed the issue. 在写入端口之前放置3秒延迟修复了问题。 Writing ASCII was not an issue. 编写ASCII不是问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM