You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中读取程序输出并发送至Arduino驱动魔方求解器?

如何将C++魔方求解器的输出发送到Arduino控制步进电机?

我正在搭建一款魔方求解器设备,需要读取C程序的输出并传入设备的步进电机。我的C程序会输出求解魔方所需的转动步骤(颜色字符串,比如Yellow、White等),示例输出如下:

________________________| RUBIK'S CUBE SOLVER |________________________ 
Input : enter code here 
White Side : 
Red Side : 
Orange Side : 
Blue Side : 
Green Side : 
Yellow Side : 
------------------------------------------------- 
Turn these sides of the Cube in Clockwise Direction by 90 degrees in this exact order... 
Yellow 
Yellow 
White 
Orange

当前的C++代码片段(处理白色面转动的部分)如下:

if (choice=='w') { 
    cout<<"White"<<endl; 
    swap(white[7],white[3]); 
    swap(white[6],white[4]); 
    swap(white[0],white[2]); 
    swap(white[7],white[5]); 
    swap(white[0],white[4]); 
    // 其他魔方状态更新代码...
}

我希望添加功能,读取cout输出的颜色字符串,直接发送至Arduino以执行相应转动操作。


解决方案思路

核心是让C++程序通过串口把颜色指令发送给Arduino,Arduino接收后解析指令并驱动步进电机。下面分步骤实现:

1. 修改C++程序,添加串口通信功能

我们需要把原本输出到控制台的颜色指令,同时发送到Arduino所在的串口。这里以Windows平台为例(跨平台可以用libserialport库):

首先实现串口打开和发送函数,然后在输出颜色的地方调用发送逻辑:

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

// 打开指定串口
HANDLE openSerialPort(const char* portName) {
    HANDLE hSerial = CreateFileA(portName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hSerial == INVALID_HANDLE_VALUE) {
        std::cerr << "Failed to open serial port!" << std::endl;
        return INVALID_HANDLE_VALUE;
    }

    // 配置串口参数:9600波特率,8N1(8位数据、无校验、1位停止位)
    DCB dcbParams = {0};
    dcbParams.DCBlength = sizeof(dcbParams);
    if (!GetCommState(hSerial, &dcbParams)) {
        std::cerr << "Failed to get serial port state!" << std::endl;
        CloseHandle(hSerial);
        return INVALID_HANDLE_VALUE;
    }
    dcbParams.BaudRate = CBR_9600;
    dcbParams.ByteSize = 8;
    dcbParams.StopBits = ONESTOPBIT;
    dcbParams.Parity = NOPARITY;
    if (!SetCommState(hSerial, &dcbParams)) {
        std::cerr << "Failed to set serial port parameters!" << std::endl;
        CloseHandle(hSerial);
        return INVALID_HANDLE_VALUE;
    }
    return hSerial;
}

// 发送指令到串口,附加换行符作为结束标记
void sendToArduino(HANDLE hSerial, const std::string& cmd) {
    DWORD bytesWritten;
    // 发送指令内容
    WriteFile(hSerial, cmd.c_str(), cmd.size(), &bytesWritten, NULL);
    // 发送换行符,方便Arduino识别单条指令
    WriteFile(hSerial, "\n", 1, &bytesWritten, NULL);
}

int main() {
    // 替换为你的Arduino串口(比如COM3,可在Arduino IDE中查看)
    HANDLE hSerial = openSerialPort("COM3");
    if (hSerial == INVALID_HANDLE_VALUE) {
        return 1;
    }

    // 模拟你的求解逻辑,输出颜色指令并发送到Arduino
    // 这里可以替换成你实际的求解输出代码
    std::string steps[] = {"Yellow", "Yellow", "White", "Orange"};
    for (const auto& step : steps) {
        std::cout << step << std::endl; // 保留原控制台输出
        sendToArduino(hSerial, step);   // 发送到Arduino
        Sleep(500); // 给Arduino留处理时间,避免指令堆积
    }

    CloseHandle(hSerial);
    return 0;
}

在你现有的代码中,比如处理choice=='w'的分支,只需添加发送逻辑:

if (choice=='w') { 
    std::string color = "White";
    cout << color << endl; 
    sendToArduino(hSerial, color); // 新增:发送到Arduino
    // 原有的魔方状态更新代码
    swap(white[7],white[3]); 
    swap(white[6],white[4]); 
    swap(white[0],white[2]); 
    swap(white[7],white[5]); 
    swap(white[0],white[4]); 
    // ...其他代码
}

2. Arduino端:接收指令并控制步进电机

Arduino需要监听串口,接收到颜色指令后执行对应的步进电机转动逻辑。示例代码如下(根据你的硬件连接调整引脚):

// 步进电机引脚定义(根据你的实际接线修改)
#define STEP_PIN 2
#define DIR_PIN 3

// 转动黄色面90度顺时针的函数
void turnYellow() {
    digitalWrite(DIR_PIN, HIGH); // 设置方向为顺时针
    // 假设步进电机需要200步转90度(根据你的电机参数调整)
    for (int i = 0; i < 200; i++) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(500);
        digitalWrite(STEP_PIN, LOW);
        delayMicroseconds(500);
    }
}

// 转动白色面90度顺时针的函数
void turnWhite() {
    digitalWrite(DIR_PIN, HIGH);
    for (int i = 0; i < 200; i++) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(500);
        digitalWrite(STEP_PIN, LOW);
        delayMicroseconds(500);
    }
}

// 转动橙色面90度顺时针的函数
void turnOrange() {
    digitalWrite(DIR_PIN, HIGH);
    for (int i = 0; i < 200; i++) {
        digitalWrite(STEP_PIN, HIGH);
        delayMicroseconds(500);
        digitalWrite(STEP_PIN, LOW);
        delayMicroseconds(500);
    }
}

void setup() {
    Serial.begin(9600); // 和C++程序的波特率保持一致
    pinMode(STEP_PIN, OUTPUT);
    pinMode(DIR_PIN, OUTPUT);
}

void loop() {
    if (Serial.available() > 0) {
        String cmd = Serial.readStringUntil('\n');
        cmd.trim(); // 去除换行符和多余空格
        
        // 调试输出,可在Arduino IDE串口监视器查看
        Serial.println("Received command: " + cmd);

        // 根据指令执行对应转动
        if (cmd == "Yellow") {
            turnYellow();
        } else if (cmd == "White") {
            turnWhite();
        } else if (cmd == "Orange") {
            turnOrange();
        }
        // 在这里添加其他颜色的判断逻辑
    }
}

3. 关键注意事项

  • 串口参数匹配:确保C++程序和Arduino的波特率、数据位、停止位、校验位完全一致(示例中用的是9600, 8N1)。
  • 指令结束标记:发送指令时添加换行符\n,让Arduino能准确区分每条指令,避免粘包。
  • 延迟处理:C++程序发送每条指令后短暂延迟(比如500ms),给Arduino足够的时间完成转动,避免指令堆积。
  • 过滤无关输出:如果你的C++程序还有其他控制台输出(比如标题、提示语),需要在发送前过滤掉,只保留颜色指令字符串。可以通过判断输出内容是否是预设的颜色列表(比如Yellow、White等)来实现。

内容的提问来源于stack exchange,提问作者crispo12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:24:20