问题描述
我有一个 WS2812 灯带,我试图通过一个 Teensy 4.0 通过 C++ 程序进行控制(teensy 最终会控制更多,并且需要将消息发送回 PC 以处理其中一些事情,但这就是重点我在)。
如果我通过 teensyduino 使用串行监视器,我的命令效果很好,但是,当我尝试将 Teensy 链接到我的程序时,它会连接,但只有一条消息通过/执行任何操作,然后它停止接收/发送消息,但并没有完全断开连接。
硬件设置是 PC→Teensy4.0→LightStrip(还有一些其他的东西,比如灯带的电源、升压逻辑板和电阻器)。我觉得我在某处遗漏了一个简单的步骤。
我的青少年代码:
#include <FastLED.h>
#define LED_PIN 0
#define NUM_LEDs 80
CRGB stripLEDs[NUM_LEDs];
String computerMessage = "";
char computerCommand = '\0';
enum LEDColor {
RED,ORANGE,YELLOW,GREEN,CYAN,BLUE,PURPLE,magenta,WHITE,OFF
};
LEDColor userColor1 = WHITE;
LEDColor userColor2 = OFF;
LEDColor partyFirstLED = RED;
bool twoColors = false;
bool isWideColors = false;
bool setStrip = true;
char colorChar = '\0';
void setup() {
// put your setup code here,to run once:
Serial.begin(115200);
FastLED.addLeds<WS2812,LED_PIN,GRB>(stripLEDs,NUM_LEDs);
}
void SetLEDColor(int lednumber,LEDColor colorToSet){
switch (colorToSet){
case RED:
stripLEDs[lednumber] = CRGB(255,0);
break;
case ORANGE:
stripLEDs[lednumber] = CRGB(255,50,0);
break;
case YELLOW:
stripLEDs[lednumber] = CRGB(200,100,0);
break;
case GREEN:
stripLEDs[lednumber] = CRGB(0,255,0);
break;
case CYAN:
stripLEDs[lednumber] = CRGB(0,200,150);
break;
case BLUE:
stripLEDs[lednumber] = CRGB(0,255);
break;
case magenta:
stripLEDs[lednumber] = CRGB(255,80);
break;
case PURPLE:
stripLEDs[lednumber] = CRGB(200,255);
break;
case WHITE:
stripLEDs[lednumber] = CRGB(100,100);
break;
case OFF:
default:
stripLEDs[lednumber] = CRGB(0,0);
break;
}
}
void loop() {
// put your main code here,to run repeatedly:
if(Serial.available() != 0)
{
computerMessage = Serial.readStringUntil('\n');
}
computerCommand = computerMessage.charat(0);
if(computerMessage != "")
{
computerCommand = computerMessage.charat(0);
switch (computerCommand){
case 'c':
if(computerMessage.length() > 1)
{
colorChar = computerMessage.charat(1);
}
switch(colorChar){
case 'R':
userColor1 = RED;
Serial.println("Color 1 is red");
break;
case 'A':
userColor1 = ORANGE;
Serial.println("Color 1 is orange");
break;
case 'Y':
userColor1 = YELLOW;
Serial.println("Color 1 is yellow");
break;
case 'G':
userColor1 = GREEN;
Serial.println("Color 1 is green");
break;
case 'C':
userColor1 = CYAN;
Serial.println("Color 1 is cyan");
break;
case 'B':
userColor1 = BLUE;
Serial.println("Color 1 is blue");
break;
case 'P':
userColor1 = PURPLE;
Serial.println("Color 1 is purple");
break;
case 'M':
userColor1 = magenta;
Serial.println("Color 1 is magenta");
break;
case 'W':
userColor1 = WHITE;
Serial.println("Color 1 is white");
break;
case 'F':
default:
userColor1 = OFF;
Serial.println("Color 1 is off");
break;
}
setStrip = true;
break;
case 'C':
if(computerMessage.length() > 1)
{
colorChar = computerMessage.charat(1);
}
switch(colorChar){
case 'R':
userColor2 = RED;
Serial.println("Color 2 is red");
break;
case 'A':
userColor2 = ORANGE;
Serial.println("Color 2 is orange");
break;
case 'Y':
userColor2 = YELLOW;
Serial.println("Color 2 is yellow");
break;
case 'G':
userColor2 = GREEN;
Serial.println("Color 2 is green");
break;
case 'C':
userColor2 = CYAN;
Serial.println("Color 2 is cyan");
break;
case 'B':
userColor2 = BLUE;
Serial.println("Color 2 is blue");
break;
case 'P':
userColor2 = PURPLE;
Serial.println("Color 2 is purple");
break;
case 'M':
userColor2 = magenta;
Serial.println("Color 2 is magenta");
break;
case 'W':
userColor2 = WHITE;
Serial.println("Color 2 is white");
break;
case 'F':
default:
userColor2 = OFF;
Serial.println("Color 2 is off");
break;
}
setStrip = true;
break;
case 'n':
isWideColors = false;
setStrip = true;
break;
case 'o':
twoColors = false;
setStrip = true;
break;
case 't':
twoColors = true;
setStrip = true;
break;
case 'w':
isWideColors = true;
setStrip = true;
break;
default:
break;
}
computerCommand = '\0';
computerMessage = "";
}
if(setStrip)
{
if(twoColors)
{
if(isWideColors)
{
for(int i = 0; i <= NUM_LEDs; i++)
{
if(i % 10 == 0)
{
SetLEDColor(i,userColor1);
}
else if((i-1) % 10 == 0 )
{
SetLEDColor(i,userColor1);
}
else if((i-2) % 10 == 0 )
{
SetLEDColor(i,userColor1);
}
else if((i-3) % 10 == 0 )
{
SetLEDColor(i,userColor1);
}
else if((i-4) % 10 == 0 )
{
SetLEDColor(i,userColor1);
}
else
{
SetLEDColor(i,userColor2);
}
}
}
else
{
for(int i = 0; i <= NUM_LEDs; i++)
{
if(i % 2 == 0)
{
SetLEDColor(i,userColor2);
}
}
}
FastLED.show();
setStrip = false;
}
else
{
for(int i = 0; i <= NUM_LEDs; i++)
{
SetLEDColor(i,userColor1);
}
FastLED.show();
setStrip = false;
}
}
}
我的主要(PC代码):
#include "TeensyMessageHandler.h"
std::string UserCommand;
std::thread* pGetUserCommandsThread;
void CloseUserCommandsThread()
{
if (pGetUserCommandsThread != nullptr)
{
pGetUserCommandsThread->join();
delete pGetUserCommandsThread;
pGetUserCommandsThread = nullptr;
}
}
void GetUserCommands()
{
TeensyMessageHandler* pTeensyMessageHandler = TeensyMessageHandler::GetInstance();
while (true)
{
std::cin >> UserCommand;
pTeensyMessageHandler->GiveTeensyCommand(UserCommand);
}
}
int main()
{
TeensyMessageHandler* pTeensyMessageHandler = TeensyMessageHandler::GetInstance();
Sleep(1000);
pGetUserCommandsThread = new std::thread(&GetUserCommands);
while (true)
{
pTeensyMessageHandler->UpdateTeensyMessageHandler();
Sleep(200);
}
CloseUserCommandsThread();
return 0;
}
#pragma once
#define TEENSY_WAIT_TIME 200
#define MAX_DATA_LENGTH 255
#include <Windows.h>
class TeensySerialPort
{
public:
explicit TeensySerialPort(const char* portName);
~TeensySerialPort();
int readSerialPort(const char* buffer,unsigned int buf_size);
bool writeSerialPort(const char* buffer,unsigned int buf_size);
bool isConnected();
void closeSerial();
private:
HANDLE handler;
bool connected;
COMSTAT status;
DWORD errors;
};
我的连接处理程序代码(PC): (cpp):
#include "TeensySerialPort.h"
#include <iostream>
TeensySerialPort::TeensySerialPort(const char* portName)
{
this->connected = false;
this->handler = CreateFileA(static_cast<LPCSTR>(portName),GENERIC_READ | GENERIC_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_norMAL,NULL);
if (this->handler == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_FILE_NOT_FOUND)
{
std::cout << "Teensy Serial Port Error: Handle not attached. Port Unavailable. Port Name: " << portName << std::endl;
}
else
{
std::cout << "Teensy Serial Port Error. Port Name: " << portName << std::endl;
}
}
else
{
DCB dcbSerialParameters = { 0 };
if (!GetCommState(this->handler,&dcbSerialParameters))
{
std::cout << "Failed to get current serial parameters. Port Name: " << portName << std::endl;
}
else
{
dcbSerialParameters.Baudrate = CBR_115200;
dcbSerialParameters.ByteSize = 8;
dcbSerialParameters.StopBits = OnesTOPBIT;
dcbSerialParameters.Parity = nopARITY;
dcbSerialParameters.fDtrControl = DTR_CONTROL_ENABLE;
if (!SetCommState(handler,&dcbSerialParameters))
{
std::cout << "Could not set serial port parameters. Port Name: " << portName << std::endl;
}
else
{
this->connected = true;
PurgeComm(this->handler,PURGE_RXCLEAR | PURGE_TXCLEAR);
Sleep(TEENSY_WAIT_TIME);
}
}
}
}
TeensySerialPort::~TeensySerialPort()
{
if (this->connected)
{
this->connected = false;
CloseHandle(this->handler);
}
}
int TeensySerialPort::readSerialPort(const char* buffer,unsigned int buf_size)
{
DWORD bytesRead{};
unsigned int toRead = 0;
ClearCommError(this->handler,&this->errors,&this->status);
if (this->status.cbInQue > buf_size)
{
toRead = buf_size;
}
else
{
toRead = this->status.cbInQue;
}
memset((void*)buffer,buf_size);
if (ReadFile(this->handler,(void*)buffer,toRead,&bytesRead,NULL))
{
return bytesRead;
}
return 0;
}
// sending provided buffer to serial port;
// returns true if succeed,false if Failed
bool TeensySerialPort::writeSerialPort(const char* buffer,unsigned int buf_size)
{
DWORD bytesSend;
if (!WriteFile(this->handler,buf_size,&bytesSend,0))
{
ClearCommError(this->handler,&this->status);
return false;
}
return true;
}
//checking if serial port is connected
bool TeensySerialPort::isConnected()
{
if (this != nullptr)
{
if (!ClearCommError(this->handler,&this->status))
{
this->connected = false;
}
return this->connected;
}
else
{
return false;
}
}
void TeensySerialPort::closeSerial()
{
CloseHandle(this->handler);
}
和消息处理程序(PC):标题:
#pragma once
#include <Windows.h>
#include <iostream>
#include <string>
#include <thread>
#include "TeensySerialPort.h"
class TeensyMessageHandler
{
public:
TeensyMessageHandler();
~TeensyMessageHandler();
static TeensyMessageHandler* GetInstance();
static bool DestroyInstance();
void Init();
void UpdateTeensyMessageHandler();
void GiveTeensyCommand(std::string deviceCommand);
private:
static TeensyMessageHandler* m_pTeensyMessageHandler;
std::string m_szTeensyMessage;
void SendMessagetoTeensy(std::string szCommand);
std::string GetTeensyMessage();
TeensySerialPort* Teensy = new TeensySerialPort("\\\\.\\COM7");
char output[MAX_DATA_LENGTH];
char incoming[MAX_DATA_LENGTH];
std::thread* m_pHandleTeensyThread;
void DoHandleTeensyThread();
void CloseTeensyThread();
std::string m_szTeensyPortName;
bool m_bHandleTeensyThreadActive;
bool m_bPauseNeeded;
};
(cpp):
#include "TeensyMessageHandler.h"
#define SEND_DATA_LENGTH 255
#define RECEIVE_DATA_LENGTH 255
#define NL_TEENSY_PORT_NAME "\\\\.\\COM"
TeensyMessageHandler* TeensyMessageHandler::m_pTeensyMessageHandler;
TeensyMessageHandler::TeensyMessageHandler() :
m_szTeensyMessage(""),m_szTeensyPortName(NL_TEENSY_PORT_NAME + 7),incoming(""),m_bHandleTeensyThreadActive(false),m_bPauseNeeded(false)
{
}
TeensyMessageHandler::~TeensyMessageHandler()
{
if (Teensy != nullptr)
{
Teensy->closeSerial();
}
CloseTeensyThread();
}
void TeensyMessageHandler::Init()
{
m_pHandleTeensyThread = new std::thread(&TeensyMessageHandler::DoHandleTeensyThread,this);
}
void TeensyMessageHandler::DoHandleTeensyThread()
{
m_bHandleTeensyThreadActive = true;
int i = 6;
while (!Teensy->isConnected())
{
std::string TeensyPortName = m_szTeensyPortName;
std::cout << "Could Not Connect to Teensy. Port: " << TeensyPortName << std::endl;
delete Teensy;
m_szTeensyPortName = NL_TEENSY_PORT_NAME + std::to_string(i);
Teensy = new TeensySerialPort(m_szTeensyPortName.c_str());
i++;
if (i >= 20)
{
i = 1;
}
}
if (m_bPauseNeeded)
{
Sleep(1000);
m_bPauseNeeded = false;
}
std::string TeensyPortName = m_szTeensyPortName;
std::cout << "Connected to Teensy. Port: " << TeensyPortName << std::endl;
char receivedMessage[RECEIVE_DATA_LENGTH];
std::string receivedMessageAsstring = "";
while (Teensy->isConnected())
{
if (Teensy != nullptr)
{
Teensy->readSerialPort(receivedMessage,RECEIVE_DATA_LENGTH);
receivedMessageAsstring = receivedMessage;
if (receivedMessageAsstring != "")
{
std::cout << receivedMessageAsstring << std::endl;
}
}
}
m_bHandleTeensyThreadActive = false;
}
void TeensyMessageHandler::UpdateTeensyMessageHandler()
{
if (m_bHandleTeensyThreadActive == false)
{
CloseTeensyThread();
m_pHandleTeensyThread = new std::thread(&TeensyMessageHandler::DoHandleTeensyThread,this);
}
}
void TeensyMessageHandler::CloseTeensyThread()
{
if (m_pHandleTeensyThread != nullptr)
{
m_pHandleTeensyThread->join();
delete m_pHandleTeensyThread;
m_pHandleTeensyThread = nullptr;
}
}
void TeensyMessageHandler::GiveTeensyCommand(std::string Message)
{
if (Message == "Red")
{
SendMessagetoTeensy("cR");
}
else if (Message == "Orange")
{
SendMessagetoTeensy("cO");
}
else if (Message == "Yellow")
{
SendMessagetoTeensy("cY");
}
else if (Message == "Green")
{
SendMessagetoTeensy("cG");
}
else if (Message == "Cyan")
{
SendMessagetoTeensy("cC");
}
else if (Message == "Blue")
{
SendMessagetoTeensy("cB");
}
else if (Message == "Purple")
{
SendMessagetoTeensy("cP");
}
else if (Message == "magenta")
{
SendMessagetoTeensy("cM");
}
else if (Message == "White")
{
SendMessagetoTeensy("cW");
}
else if (Message == "Off")
{
SendMessagetoTeensy("cF");
}
else if (Message == "Red2")
{
SendMessagetoTeensy("CR");
}
else if (Message == "Orange2")
{
SendMessagetoTeensy("CO");
}
else if (Message == "Yellow2")
{
SendMessagetoTeensy("CY");
}
else if (Message == "Green2")
{
SendMessagetoTeensy("CG");
}
else if (Message == "Cyan2")
{
SendMessagetoTeensy("CC");
}
else if (Message == "Blue2")
{
SendMessagetoTeensy("CB");
}
else if (Message == "Purple2")
{
SendMessagetoTeensy("CP");
}
else if (Message == "magenta2")
{
SendMessagetoTeensy("CM");
}
else if (Message == "White2")
{
SendMessagetoTeensy("CW");
}
else if (Message == "Off2")
{
SendMessagetoTeensy("CF");
}
else if (Message == "TwoColors")
{
SendMessagetoTeensy("t");
}
else if (Message == "OneColor")
{
SendMessagetoTeensy("o");
}
else if (Message == "Wide")
{
SendMessagetoTeensy("w");
}
else if (Message == "Narrow")
{
SendMessagetoTeensy("n");
}
}
void TeensyMessageHandler::SendMessagetoTeensy(std::string Command)
{
const char* sendString = Command.c_str();
if (Teensy->isConnected())
{
bool hasWritten = false;
hasWritten = Teensy->writeSerialPort(sendString,SEND_DATA_LENGTH);
if (hasWritten)
{
std::cout << "Sent Teensy Message: " << Command << std::endl;
}
else
{
std::cout << "Failed to send Teensy message: " << Command << std::endl;
}
}
}
std::string TeensyMessageHandler::GetTeensyMessage()
{
char receivedString[RECEIVE_DATA_LENGTH];
if (Teensy->isConnected())
{
int hasRead = Teensy->readSerialPort(receivedString,RECEIVE_DATA_LENGTH);
}
return std::string(receivedString);
}
TeensyMessageHandler* TeensyMessageHandler::GetInstance()
{
if (!m_pTeensyMessageHandler)
{
m_pTeensyMessageHandler = new TeensyMessageHandler();
m_pTeensyMessageHandler->Init();
}
return m_pTeensyMessageHandler;
}
bool TeensyMessageHandler::DestroyInstance()
{
bool bSuccess = false;
if (m_pTeensyMessageHandler)
{
delete m_pTeensyMessageHandler;
bSuccess = true;
}
return bSuccess;
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)