Arduino伺服代码重置到位置0

Arduino servo code resetting to positon 0

(请原谅我的英文) 你好。我是编码初学者,开始尝试使用 Arduino 和 C++(因为 Arduino)。最近我刚刚了解到你可以通过串行监视器写入 Arduino 板,因此通过你的 PC 通过你的 COM 端口,所以我试图找到一种通过 Arduino 的串行监视器从 cmd 控制伺服电机旋转的方法。我复制了在 Arduino 网站上作为示例给出的代码,并通过来自 youtube 的人获得了一段有效的代码。

因为你看到这段代码的工作原理是它通过 windows(任何 ide)上的 c++ 程序写入串行监视器,但是当我发送命令时,它 运行s 正确,然后再次 运行s 但将输入设置为 0 度,从而将伺服头移动到 0 度。如果输入为 0 但它 运行 是草图中的所有其他内容,我通过防止伺服旋转来临时“修复”它。 (我已经包含了下面的代码,但它真的很长而且我不知道如何包含大块代码(如果我包含错误的东西我很抱歉)同时仍然包含最小可重现的示例。如果被告知我会很乐意更改它到)

主要代码:

#include <iostream>
#include <string>
#include <stdlib.h>
#include <string>

#include "SerialPort.h"


char output[MAX_DATA_LENGTH];
char incomingData[MAX_DATA_LENGTH];

using namespace std;


char temp[] = "\\.\COM4";
char* port = temp;

float Scalar = 0.8888;

int main() {
    SerialPort arduino(port);
    if (arduino.isConnected()) {
        cout << "Connection established" << endl << endl;
    }
    else {
        cout << "Error in port name" << endl << endl;
    }
    while (arduino.isConnected()) {
        while (true) {
            cout << "Enter your command (degrees 0 to 180 in integers): " << endl;
            string data;
            cin >> data;
            if (data == "exit")
                return 0;
            /*if (stoi(data) != 90) {
                data = to_string(
                    round((stof(data) - 90) * Scalar + 90)
                );
            }*/
            //cout << data << endl;

            char* charArray = new char[data.size() + 2];
            copy(data.begin(), data.end(), charArray);
            charArray[data.size()] = '\n';
            charArray[data.size() + 1] = '[=10=]';
            cout << "char array: " << charArray << endl;

            arduino.writeSerialPort(charArray, MAX_DATA_LENGTH);
            arduino.readSerialPort(output, MAX_DATA_LENGTH);

            cout << ">> " << output << endl;
            cout << "----------\n" << endl;
            delete[] charArray;

        }
    }
    return 0;
}

.ino 草图文件:

#include <Servo.h>

Servo servo1;
int LED = 13;
int servoPos = 90; //to store servo's position

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(LED, OUTPUT);
  servo1.attach(11);
  servo1.write(servoPos);
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(15);
  if(Serial.available() > 0) {
    String info;
    String return_text;
    info = Serial.readStringUntil('\n');

    return_text = "info variable string is: " + info;
    Serial.println(return_text);
    
    if(info.toInt() < servoPos && info.toInt() != 0) {
      for( 0; servoPos > info.toInt(); servoPos-=1) {
        servo1.write(servoPos); 
        delay(5);
      }
    }
    else if(info.toInt() > servoPos) {
      for( 0; servoPos < info.toInt(); servoPos+=1) {
        servo1.write(servoPos);
        delay(5);
      }
    }
    digitalWrite(LED, HIGH);
    delay(20);
    digitalWrite(LED, LOW);
    
    //Serial.println("");
    //Serial.print("Servo position: ");
    //Serial.println(servoPos);
  }
}

header:

#ifndef SERIALPORT_H
#define SERIALPORT_H

#define ARDUINO_WAIT_TIME 2000
#define MAX_DATA_LENGTH 255

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class SerialPort
{
private:
    HANDLE handler;
    bool connected;
    COMSTAT status;
    DWORD errors;
public:
    SerialPort(char* portName);
    ~SerialPort();

    int readSerialPort(char* buffer, unsigned int buf_size);
    bool writeSerialPort(char* buffer, unsigned int buf_size);
    bool isConnected();
};

#endif // SERIALPORT_H

以及包含函数的 cpp 文件:

#include "SerialPort.h"

SerialPort::SerialPort(char* portName)
{
    this->connected = false;

    this->handler = CreateFileA(static_cast<LPCSTR>(portName),
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (this->handler == INVALID_HANDLE_VALUE) {
        if (GetLastError() == ERROR_FILE_NOT_FOUND) {
            printf("ERROR: Handle was not attached. Reason: %s not available\n", portName);
        }
        else
        {
            printf("ERROR!!!");
        }
    }
    else {
        DCB dcbSerialParameters = { 0 };

        if (!GetCommState(this->handler, &dcbSerialParameters)) {
            printf("failed to get current serial parameters");
        }
        else {
            dcbSerialParameters.BaudRate = CBR_9600;
            dcbSerialParameters.ByteSize = 8;
            dcbSerialParameters.StopBits = ONESTOPBIT;
            dcbSerialParameters.Parity = NOPARITY;
            dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;

            if (!SetCommState(handler, &dcbSerialParameters))
            {
                printf("ALERT: could not set Serial port parameters\n");
            }
            else {
                this->connected = true;
                PurgeComm(this->handler, PURGE_RXCLEAR | PURGE_TXCLEAR);
                Sleep(ARDUINO_WAIT_TIME);
            }
        }
    }
}

SerialPort::~SerialPort()
{
    if (this->connected) {
        this->connected = false;
        CloseHandle(this->handler);
    }
}

int SerialPort::readSerialPort(char* buffer, unsigned int buf_size)
{
    DWORD bytesRead;
    unsigned int toRead = 0;

    ClearCommError(this->handler, &this->errors, &this->status);

    if (this->status.cbInQue > 0) {
        if (this->status.cbInQue > buf_size) {
            toRead = buf_size;
        }
        else toRead = this->status.cbInQue;
    }

    if (ReadFile(this->handler, buffer, toRead, &bytesRead, NULL)) return bytesRead;

    return 0;
}

bool SerialPort::writeSerialPort(char* buffer, unsigned int buf_size)
{
    DWORD bytesSend;

    if (!WriteFile(this->handler, (void*)buffer, buf_size, &bytesSend, 0)) {
        ClearCommError(this->handler, &this->errors, &this->status);
        return false;
    }
    else return true;
}

bool SerialPort::isConnected()
{
    return this->connected;
}

发生了什么: 因此,当我 运行 它时,首先伺服旋转到 90 度,然后当我给它一个整数输入时 Arduino 运行 将伺服转向所需的输入,打开和关闭 LED,同时发生这种情况 cpp 主代码打印我发送给 Arduino 的内容(或者至少是没有 \n[=15=] e.t.c 的可见内容)以及串行监视器写入并返回的内容要求我发送输入。 问题 再次是 Arduino 代码 运行s 并将伺服器移动到 0 度并点亮和关闭 LED,就像以前一样,没有我的要求。

如果 data == 0,我去阻止伺服移动,但 .ino 草图的其余部分仍然 运行s,所以我怀疑它可能与 char 相关cpp 文件发送到监视器..?但是我太聪明了,无法弄清楚,因此寻求任何建议。控制台显示输出,但在第二次发生 arduino 循环时不显示任何内容。 如果我在控制台中写了一些东西,而第二次(不需要的)迭代发生,那么 arduino 不会响应我的输入,并且在接下来的 运行s 期间它也会从串行监视器中弄乱 output要么不显示文本,要么完全弄乱文本 and/or 显示奇怪的乱码,例如“³ô¦ò»]½R↨ùýº§»⌂2{²à_Ú◄/4ý¾ı”等等。

(如果由于不当行为、礼仪或 e.t.c 需要添加、删除或更改任何内容,那么正如我所说,我将非常乐意) 提前致谢。

看这里:Serial monitoring tool

这是一个简化串口监控的工具。您可以view/plot 数据、发送命令、存储参数以及使用 3D 视图绑定数据。

这里有通用 C 代码的文件和 Arduino 的文件 (cpp) Arduino files

抱歉没有更新。我找到了解决方案。只是当我向它提供发送的长度时,我要求在线代码中的函数发送一个 255 个字符的字符数组。由于 function/header 的任务是发送 255 个字符,它以某种方式组成了随机数据,arduino 串行 COM reader 读取为 0。我只是通过更改 [= 告诉函数要发送多少数据来修复它14=] in arduino.writeSerialPort(charArray, MAX_DATA_LENGTH); 只是要发送的字符串中的字符数。