gpt4 book ai didi

C++ Arduino串口连接超时

转载 作者:太空狗 更新时间:2023-10-29 23:07:18 29 4
gpt4 key购买 nike

最初,我使用 AutoHotkey与 Arduino 通信,但我发现在几个小时后没有向 Arduino 发送任何东西(Arduino 每十秒发送一次“心跳”),连接会卡住或失败。

现在我正尝试通过 C++ 程序的串行连接来控制 Arduino the RS-232 library .

但是我遇到了同样的问题。该程序每二十秒对 Arduino 执行一次 ping 操作,然后 Arduino 应该会报告一小串信息。几个小时后,连接断开,而我的 C++ 程序只是坐在那里,没有任何响应。 Arduino 有一个看门狗,我可以验证它在没有连接的情况下仍在工作,所以我相信我的问题在于串行的某种固有超时......除了连接正在被积极使用..

如果能帮助我弄清楚我需要做什么以保持串行连接有效,我将不胜感激,计算机必须能够将数据发送到 Arduino 24/7。

我在 Code::Blocks 上编译,并在 Windows 7 上运行该程序。

我对 C++ 或 C 不是很熟悉,所以如果您发现我在程序中做的其他愚蠢的事情,请告诉我。

main.cpp

/**************************************************

File: main.cpp
Purpose: Simple demo that receives characters from
the serial port and print them on the
screen.

**************************************************/

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

#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

#include "rs232.h"

using namespace std;

int main()
{
int debug = 0;
int i = 0, n,
cport_nr = 5, /* /dev/ttyS5 (COM6 on Windows) */
bdrate = 9600; /* 9600 baud */

unsigned char buf[4096];

if(OpenComport(cport_nr, bdrate))
{
cout << "Can not open comport\n";
return(0);
}

while(1)
{
if (debug)
{
printf("Entering While(1) loop. \n");
}

n = PollComport(cport_nr, buf, 4095);

if(n > 0)
{
buf[n] = 0; /* always put a "null" at the end of a string! */

/* for(i=0; i < n; i++)
{
if(buf[i] < 32) // replace unreadable control-codes by dots
{
buf[i] = '.';
}
} */

//printf("\n\n\nreceived %i bytes: %s\n\n", n, (char *)buf);
cout << endl << endl << endl << (char *)buf;
}

if (SendByte(cport_nr, 83))
{
printf("\n\nSending data didn't work. \n\n");
}
else
{
cout << "\nSent [S]\n";
}

i = 0;

#ifdef _WIN32
Sleep(10000); /* It's ugly to use a sleeptimer, in a real program, change
the while-loop into a (interrupt) timerroutine. */
#else
usleep(10000000); /* Sleep for 100 milliSeconds */
#endif
}
return(0);
}

Arduino 文件

//
// SuiteLock v.2.1a
// By: Chris Bero (bigbero@gmail.com)
// Last Updated: 11.4.2012
//

#include <Servo.h>
#include <avr/wdt.h>

// Pin Constants:
const int servoPin = 9;
const int doorbtn = 3;

// Not sure if I'm still going to use these...
const int ledGND = 4;
const int ledVCC = 5;
const int servDelay = 600; // The delay allowing for the servo to complete an action.

//Variables:
int doorState = 0; // The value returned by the door button (0 or 1).
int servState = 90; // The position of the servo in degrees (0 through 180).
unsigned long prevMillis = 0;
unsigned long progCycles = 0;
int serialByte = 0;
int lastSerial = 0;
int smallBlink = 0;
bool dostatus = false; // Determine whether to send sys status.
Servo serv;

// Set up the environment.
void setup()
{
wdt_enable(WDTO_4S);
pinMode(doorbtn, INPUT);
pinMode(ledGND, OUTPUT);
pinMode(ledVCC, OUTPUT);
pinMode(servoPin, OUTPUT);
digitalWrite(ledGND, LOW);
serv.attach(servoPin);
Serial.begin(9600);
prevMillis = millis();
}

////////////////////////////////////////////////
// Statuser - Sends system status to Serial
/////////////////////////////////////////////
int statuser ()
{
wdt_reset();
Serial.println("[Start]"); //Start Of Transmission
delay(15);
unsigned long currentMillis = millis();
refresh();
Serial.print("\tTime Alive: ");
int hr = ((currentMillis/1000)/3600);
int mn = (((currentMillis/1000)-(hr*3600))/60);
int sc = ((currentMillis/1000)-(hr*3600)-(mn*60));
Serial.print(hr);
Serial.print(":");
Serial.print(mn);
Serial.print(":");
Serial.println(sc);
Serial.print("\tNum of Program Cycles: ");
Serial.println(progCycles);
Serial.print("\tAvg Cycles per Second: ");
int cps = (progCycles/(currentMillis/1000));
Serial.println(cps);
Serial.print("\tDoorState: ");
Serial.println(doorState);
Serial.print("\tServo Position: ");
Serial.println(servState);
Serial.print("\tLast Serial Byte: ");
Serial.println(lastSerial);
delay(15);
Serial.println("[End]"); //End Of Transmission
return(0);
}

////////////////////////
// Lock the door.
/////////////////////
int locker()
{
wdt_reset();

// Check the button states.
refresh();

// Make sure the door is closed.
do
{
wdt_reset();
delay(500);
refresh();
} while(doorState == LOW);

// Turn on the locking LED during the servo movement.
digitalWrite(ledVCC, HIGH);

wdt_reset();

// Tell the servo to turn to 20 degrees.
serv.write(20);

// Give the servo time to complete the turn.
delay(servDelay);

wdt_reset();

// Turn the servo opp direction to reset.
serv.write(90);

// Wait for the servo to reach it's reset point.
delay(servDelay);

// Turn off the cool little LED.
digitalWrite(ledVCC, LOW);

// Call parents for 11pm checkup and tell them everything's A-OK.
return(0);
}

/////////////////////////
// Unlock the door.
//////////////////////
int unlocker ()
{
wdt_reset();

// Check the pin states.
refresh();

// Turn on the status LED.
digitalWrite(ledVCC, HIGH);

wdt_reset();

// Turn servo to 170 degrees to unlock the door.
serv.write(170);

// Wait for servo motion to complete.
delay(servDelay);

wdt_reset();

// Reset the servo to 90 degrees.
serv.write(90);

// Wait for reset motion to complete.
delay(servDelay);

// Turn off LED.
digitalWrite(ledVCC, LOW);

return(0);
}

///////////////////////////////
// Refresh button states.
/////////////////////////////
void refresh ()
{
wdt_reset();
doorState = digitalRead(doorbtn);
servState = serv.read();
}

///////////////////////
// Main function.
////////////////////
void loop()
{
wdt_reset();

// Blink the LED every so many turn overs of the function.
if (smallBlink == 5)
{
smallBlink = 0;
digitalWrite(ledVCC, HIGH);
delay(300);
digitalWrite(ledVCC, LOW);
}

// Status.
if(dostatus == true)
{
unsigned long currentMillis = millis();
if ((currentMillis - prevMillis) > 4000)
{
prevMillis = currentMillis;
statuser();
}
}

// Refresh button states.
refresh();

// Is the door closed and not locked? *Gasp*
if ((doorState == LOW))
{
// Fix it.
while (doorState == LOW)
{
wdt_reset();
delay(500);
refresh();
}
locker();
}

// Check for available communications.
if (Serial.available() > 0)
{
// Reset the serialByte, done for debugging.
serialByte = 0;
wdt_reset();
// Read the serialByte.
serialByte = Serial.read();
lastSerial = serialByte;
}

// Act on the byte data.
if (serialByte == 'U')
{
// Let someone in.
unlocker();
// Wait for the door to change states.
delay(1000);
}
if (serialByte == 'L')
{
locker();
delay(1000);
}
if (serialByte == 'S')
{
statuser();
delay(200);
}

// Clean serialByte for debugging.
serialByte = 0;

// Count through program cycles.
progCycles++;
smallBlink++;
}

我调整了C++程序打开comport,发送'S',然后关闭comport并等待。然后我让它循环程序,这样它就可以继续打开和关闭端口。我希望这可以防止连接达到几个小时的标记和超时或其他任何原因。相反,程序成功循环了一个小时,然后突然无法打开 COM 端口……这让我大吃一惊,我不知道该怎么办……

如果 CrazyCasta 是正确的,只是我的 Arduino 与笔记本电脑的连接有问题,有没有一种方法可以重置连接而无需先重启计算机?

最佳答案

正如 CrazyCasta 所说,这是一个硬件问题。我通过移除 Arduino 和计算机之间的 9 英尺(2.7 米)USB 延长线解决了这个问题。

截至今天上午,连接已连接十个小时,比之前的测试长了七个小时。我希望可以肯定地说这已解决。

关于C++ Arduino串口连接超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13219792/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com