![]() |
Can't transmit serial fast Python to Arduino pyserial - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Can't transmit serial fast Python to Arduino pyserial (/thread-25412.html) |
Can't transmit serial fast Python to Arduino pyserial - mRKlean - Mar-29-2020 Hello, I've been working on developing an auto-turret with two stepper motor axes and an electric solenoid, either on or off. In order to control my Arduino, I have decided on using a laptop or raspberry pi which has joysticks plugged into it and transmits those values via serial USB to my Arduino. The message is transmitted as follows: "<xxx, yyy, z>" to the Arduino, where it then parses this into three different values, xxx, yyy, and z. However, I can't transmit very fast, only about 3 times per second. If I try to transmit my data faster, my Arduino stops running, and the built-in LED pin on 13 stays constantly on, however, this LED also flashes when a new serial connection is made for a split second. My Arduino also has a built-in LED indicating whether the TX and RX pins are active. The RX LED flashes nominally, with whatever transmission rate I put in python, it flashes with it, even if my Arduino is disabled. I've been working hard on how to fix this issue, but I haven't found a solution yet, and I'm coming here for help. My code is below. Thanks! Python code: import serial, time import pygame from pygame.locals import * import math turret_axis = 0 pitch_axis = 1 serialData = '' solenoidState = False arduino = serial.Serial('COM4', 115200, timeout=0) pygame.init() joystick_count = pygame.joystick.get_count() for i in range(joystick_count): joystick = pygame.joystick.Joystick(i) joystick.init() print("Joystick{}".format(i)) print(joystick.get_name()) print(joystick.get_numaxes()) def getXVal(): global turretVal turretVal = joystick.get_axis(turret_axis) turretVal = round(turretVal, 2) turretVal = turretVal*100 turretVal = turretVal + 200 turretVal = str(turretVal) turretVal = turretVal[:3] def getYVal(): global pitchVal pitchVal = joystick.get_axis(pitch_axis) pitchVal = round(pitchVal, 2) pitchVal = pitchVal*100 pitchVal = pitchVal + 200 pitchVal = str(pitchVal) pitchVal = pitchVal[:3] def getSolenoidState(): global serialSolenoidState solenoidState = joystick.get_button(1) if solenoidState == True: serialSolenoidState = "1" return serialSolenoidState elif solenoidState == False: serialSolenoidState = "0" def writeToSerial(): time.sleep(.1) getXVal() getYVal() getSolenoidState() serialData = ('<'+turretVal+", "+pitchVal+", "+serialSolenoidState+">") print(serialData) arduino.write(serialData) while True: pygame.event.pump() writeToSerial()Arduino code: #include <AccelStepper.h> const byte numChars = 32; char receivedChars[numChars]; char tempChars[numChars]; boolean newData = false; //Stored Values from serial int xInt = 0; int yInt = 0; int solenoidState = 0; boolean solenoidEnable = false; //Stepper motor control pins const int tStep = 54; const int tDir = 55; const int tEnable = 38; const int pStep = 60; const int pDir = 61; const int pEnable = 56; //Stepper MS Pins const int tMS1 = 5; const int tMS2 = 6; const int pMS1 = 59; const int pMS2 = 58; //Solenoid Pin const int sPin = 8; //Wired to heatbed pin //create stepper objects AccelStepper tStepper(1, tStep, tDir); AccelStepper pStepper(1, pStep, pDir); //============ void setup() { Serial.begin(115200); //Setup serial initializeComponents(); } //============ void loop() { recvWithStartEndMarkers(); if (newData == true) { strcpy(tempChars, receivedChars); // this temporary copy is necessary to protect the original data // because strtok() used in parseData() replaces the commas with \0 parseData(); processData(); maybeShootTurret(); newData = false; } //runSteppers(); } //============ void recvWithStartEndMarkers() { static boolean recvInProgress = false; static byte ndx = 0; char startMarker = '<'; char endMarker = '>'; char rc; while (Serial.available() > 0 && newData == false) { rc = Serial.read(); if (recvInProgress == true) { if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string recvInProgress = false; ndx = 0; newData = true; } } else if (rc == startMarker) { recvInProgress = true; } } } //============ void parseData() { // split the data into its parts char * strtokIndx; // this is used by strtok() as an index strtokIndx = strtok(tempChars,","); // this continues where the previous call left off xInt = atoi(strtokIndx); // convert this part to an integer strtokIndx = strtok(NULL, ","); yInt = atoi(strtokIndx); // convert this part to a float strtokIndx = strtok(NULL, ","); solenoidState = atoi(strtokIndx); } //============ void processData() { xInt = (xInt-200)*-10; yInt = (yInt-200)*-10; if(solenoidState == 1){ solenoidEnable = true; } else if(solenoidState == 0){ solenoidEnable = false; } } void initializeComponents() { pinMode(sPin, OUTPUT); //Solenoid Pin pinMode(tEnable, OUTPUT); pinMode(pEnable, OUTPUT); pinMode(tMS1, OUTPUT); pinMode(tMS2, OUTPUT); pinMode(pMS1, OUTPUT); pinMode(pMS2, OUTPUT); //Enable Steppers digitalWrite(tEnable, LOW); digitalWrite(pEnable, LOW); //Configure for 1/4 microstepping digitalWrite(tMS1, LOW); digitalWrite(tMS2, HIGH); digitalWrite(pMS1, LOW); digitalWrite(pMS2, HIGH); //set stepper speeds and accel tStepper.setMaxSpeed(2000); pStepper.setMaxSpeed(100); tStepper.setAcceleration(4000); pStepper.setAcceleration(1000); } void runSteppers(){ pStepper.moveTo(yInt); tStepper.moveTo(xInt); Serial.println(xInt); Serial.println(yInt); tStepper.run(); pStepper.run(); } void maybeShootTurret(){ if(solenoidEnable == true){ digitalWrite(sPin, HIGH); Serial.println("shooting"); } if(solenoidEnable == false){ digitalWrite(sPin, LOW); Serial.println("off"); } } |