Arduino 在与计算机串行通信 40 秒后停止工作

Arduino stops working after 40 sec of serial communication with the computer

我正在尝试设置一条从 piarduino 的通信线路来控制电机。经过 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;
    }
  }
}