Arduino 在与计算机串行通信 40 秒后停止工作
Arduino stops working after 40 sec of serial communication with the computer
我正在尝试设置一条从 pi
到 arduino
的通信线路来控制电机。经过 40 45 秒的通信后,我的 arduino mega 2560
(可能是克隆)停止发送数据或做任何事情(包括写入 esc 驱动程序)。重新启动 python script
又解决了 40 秒的问题。 Tx
指示灯闪烁,没有其他工作。
Arduino代码:
#include <StringSplitter.h>
#define RELAY 40
void setup() {
Serial.begin(38400);
pinMode(RELAY, OUTPUT);
}
bool relaysCurrState = false;
String inData = "";
void loop() {
delay(50);
}
int* inputParser(String input){
static int data[4];
if(input.length() < 7){
for(int i = 0; i < 4; i++) data[i] = 0;
return data;
}
// Parsing the input that are connected by commas.
StringSplitter *splitter = new StringSplitter(input, ',', 8);
int itemCount = splitter->getItemCount();
for(int i = 0; i < itemCount; i++) {
String item = splitter->getItemAtIndex(i);
data[i] = item.toInt();
}
return data;
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == 't') {
Serial.read();
int* data = inputParser(inData);
int value = data[3];
// Relay is to change the rotating direction of the motor. Nothing too fancy
if(value < -50) {
if(!relaysCurrState) {
delay(150);
}
digitalWrite(RELAY, HIGH);
relaysCurrState = true;
}
else if(value > 50) {
if(relaysCurrState) {
delay(200);
}
digitalWrite(RELAY, LOW);
relaysCurrState = false;
}
// Sending back the data to the pi
Serial.println(value);
inData = "";
}
else {
inData += inChar;
}
}
}
我删除了所有关于伺服的行,但问题仍然存在。
Python
代码:
import time
from Joystick import Joystick
import serial
def main():
ser = serial.Serial('/dev/ttyUSB0', 38400, timeout = .2)
js = Joystick()
cal_flag = False
time.sleep(1.5)
while True:
if(js.option == 'fly'):
values = js.axis_values
ser.write(bytes(values + 't', 'ascii'))
print('Sending... ', values)
time.sleep(.1)
print(ser.readline().decode('ascii'), end = '')
elif(js.option == 'calibrate' and not cal_flag):
ser.write(bytes('c', 'ascii'))
print('Calibrating...\n')
time.sleep(5)
print('Done')
js.option = 'fly'
time.sleep(.2)
if __name__ == '__main__':
main()
我用 pygame:
编码的操纵杆模块
import pygame
import time
class Joystick(object):
def __init__(self):
pygame.init()
if pygame.joystick.get_count() > 0:
print('Joystick is connected.')
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
else:
print('Could not find any joysticks. Trying again...')
while pygame.joystick.get_count() == 0:
time.sleep(1)
pygame.event.pump()
print('Joystick is connected.')
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
self.curr_opt = 'hold_on'
@property
def axis_values(self):
max_val = 1000
vals = list()
pygame.event.pump()
for i in range(5):
if i == 1 or i == 4:
val = -self.joystick.get_axis(i)
else:
val = self.joystick.get_axis(i)
if i != 2:
vals.append(val)
str_vals = ','.join([str(int(x * max_val)) for x in vals])
return str_vals
@property
def calibrate_button(self):
button_num = 1
pygame.event.pump()
start = time.time()
curr_time = time.time()
while self.joystick.get_button(button_num) and curr_time - start < .3:
pygame.event.pump()
curr_time = time.time()
if curr_time - start >= .3:
return 1
else:
return 0
@property
def fly_button(self):
button_num = 7
pygame.event.pump()
start = time.time()
curr_time = time.time()
while self.joystick.get_button(button_num) and curr_time - start < .3:
pygame.event.pump()
curr_time = time.time()
if curr_time - start >= .3:
return 1
else:
return 0
@property
def hold_on_button(self):
button_num = 6
pygame.event.pump()
start = time.time()
curr_time = time.time()
while self.joystick.get_button(button_num) and curr_time - start < .3:
pygame.event.pump()
curr_time = time.time()
if curr_time - start >= .3:
return 1
else:
return 0
@property
def option(self):
if self.calibrate_button and self.curr_opt != 'calibrate':
self.curr_opt = 'calibrate'
return 'calibrate'
if self.fly_button and self.curr_opt != 'fly':
self.curr_opt = 'fly'
return 'fly'
if self.hold_on_button and self.curr_opt != 'hold_on':
self.curr_opt = 'hold_on'
return 'hold_on'
return self.curr_opt
@option.setter
def option(self, opt):
self.curr_opt = opt
我使用内存的错误。感谢@Juraj 我想通了。我编写了另一小堆代码来拆分逗号分隔的字符串,并仅使用一个全局 int 数组来保存所有数据。
这是转换部分:
void updateValues(String data, char seperator) {
int nums[6];
int count = 0, last_p = 0;
// Parsing comma seperated values.
int i = 0;
while(i < data.length()) {
if(data[i] == ',') {
nums[count] = data.substring(last_p, i).toInt();
count++;
last_p = i+1;
}
i++;
}
nums[count] = data.substring(last_p, i+1).toInt();
// Evaluation of Shifting Movement and keep track if the robot is shifting.
bool isShifting = false;
for (int i = 0; i < 4; i++) {
int value = nums[i];
if (value > 50 || value < -50) isShifting = true;
escValues[i] = value;
}
// Vertical Motors.
int verticalPower = nums[4];
for (int i = 4; i < 8; i++) {
escValues[i] = verticalPower;
}
// If the robot is not shifting it will be able to rotate.
if (!isShifting){
double sensitivity = 1.0;
int rotationPower = nums[5];
short int sign = 1;
if (rotationPower < 0) sign = -1;
for (int i = 0; i < 4; i++) {
escValues[i] = rotationPower * sign * sensitivity;
sign = -sign;
}
}
}
我正在尝试设置一条从 pi
到 arduino
的通信线路来控制电机。经过 40 45 秒的通信后,我的 arduino mega 2560
(可能是克隆)停止发送数据或做任何事情(包括写入 esc 驱动程序)。重新启动 python script
又解决了 40 秒的问题。 Tx
指示灯闪烁,没有其他工作。
Arduino代码:
#include <StringSplitter.h>
#define RELAY 40
void setup() {
Serial.begin(38400);
pinMode(RELAY, OUTPUT);
}
bool relaysCurrState = false;
String inData = "";
void loop() {
delay(50);
}
int* inputParser(String input){
static int data[4];
if(input.length() < 7){
for(int i = 0; i < 4; i++) data[i] = 0;
return data;
}
// Parsing the input that are connected by commas.
StringSplitter *splitter = new StringSplitter(input, ',', 8);
int itemCount = splitter->getItemCount();
for(int i = 0; i < itemCount; i++) {
String item = splitter->getItemAtIndex(i);
data[i] = item.toInt();
}
return data;
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (inChar == 't') {
Serial.read();
int* data = inputParser(inData);
int value = data[3];
// Relay is to change the rotating direction of the motor. Nothing too fancy
if(value < -50) {
if(!relaysCurrState) {
delay(150);
}
digitalWrite(RELAY, HIGH);
relaysCurrState = true;
}
else if(value > 50) {
if(relaysCurrState) {
delay(200);
}
digitalWrite(RELAY, LOW);
relaysCurrState = false;
}
// Sending back the data to the pi
Serial.println(value);
inData = "";
}
else {
inData += inChar;
}
}
}
我删除了所有关于伺服的行,但问题仍然存在。
Python
代码:
import time
from Joystick import Joystick
import serial
def main():
ser = serial.Serial('/dev/ttyUSB0', 38400, timeout = .2)
js = Joystick()
cal_flag = False
time.sleep(1.5)
while True:
if(js.option == 'fly'):
values = js.axis_values
ser.write(bytes(values + 't', 'ascii'))
print('Sending... ', values)
time.sleep(.1)
print(ser.readline().decode('ascii'), end = '')
elif(js.option == 'calibrate' and not cal_flag):
ser.write(bytes('c', 'ascii'))
print('Calibrating...\n')
time.sleep(5)
print('Done')
js.option = 'fly'
time.sleep(.2)
if __name__ == '__main__':
main()
我用 pygame:
编码的操纵杆模块import pygame
import time
class Joystick(object):
def __init__(self):
pygame.init()
if pygame.joystick.get_count() > 0:
print('Joystick is connected.')
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
else:
print('Could not find any joysticks. Trying again...')
while pygame.joystick.get_count() == 0:
time.sleep(1)
pygame.event.pump()
print('Joystick is connected.')
self.joystick = pygame.joystick.Joystick(0)
self.joystick.init()
self.curr_opt = 'hold_on'
@property
def axis_values(self):
max_val = 1000
vals = list()
pygame.event.pump()
for i in range(5):
if i == 1 or i == 4:
val = -self.joystick.get_axis(i)
else:
val = self.joystick.get_axis(i)
if i != 2:
vals.append(val)
str_vals = ','.join([str(int(x * max_val)) for x in vals])
return str_vals
@property
def calibrate_button(self):
button_num = 1
pygame.event.pump()
start = time.time()
curr_time = time.time()
while self.joystick.get_button(button_num) and curr_time - start < .3:
pygame.event.pump()
curr_time = time.time()
if curr_time - start >= .3:
return 1
else:
return 0
@property
def fly_button(self):
button_num = 7
pygame.event.pump()
start = time.time()
curr_time = time.time()
while self.joystick.get_button(button_num) and curr_time - start < .3:
pygame.event.pump()
curr_time = time.time()
if curr_time - start >= .3:
return 1
else:
return 0
@property
def hold_on_button(self):
button_num = 6
pygame.event.pump()
start = time.time()
curr_time = time.time()
while self.joystick.get_button(button_num) and curr_time - start < .3:
pygame.event.pump()
curr_time = time.time()
if curr_time - start >= .3:
return 1
else:
return 0
@property
def option(self):
if self.calibrate_button and self.curr_opt != 'calibrate':
self.curr_opt = 'calibrate'
return 'calibrate'
if self.fly_button and self.curr_opt != 'fly':
self.curr_opt = 'fly'
return 'fly'
if self.hold_on_button and self.curr_opt != 'hold_on':
self.curr_opt = 'hold_on'
return 'hold_on'
return self.curr_opt
@option.setter
def option(self, opt):
self.curr_opt = opt
我使用内存的错误。感谢@Juraj 我想通了。我编写了另一小堆代码来拆分逗号分隔的字符串,并仅使用一个全局 int 数组来保存所有数据。 这是转换部分:
void updateValues(String data, char seperator) {
int nums[6];
int count = 0, last_p = 0;
// Parsing comma seperated values.
int i = 0;
while(i < data.length()) {
if(data[i] == ',') {
nums[count] = data.substring(last_p, i).toInt();
count++;
last_p = i+1;
}
i++;
}
nums[count] = data.substring(last_p, i+1).toInt();
// Evaluation of Shifting Movement and keep track if the robot is shifting.
bool isShifting = false;
for (int i = 0; i < 4; i++) {
int value = nums[i];
if (value > 50 || value < -50) isShifting = true;
escValues[i] = value;
}
// Vertical Motors.
int verticalPower = nums[4];
for (int i = 4; i < 8; i++) {
escValues[i] = verticalPower;
}
// If the robot is not shifting it will be able to rotate.
if (!isShifting){
double sensitivity = 1.0;
int rotationPower = nums[5];
short int sign = 1;
if (rotationPower < 0) sign = -1;
for (int i = 0; i < 4; i++) {
escValues[i] = rotationPower * sign * sensitivity;
sign = -sign;
}
}
}