Python Forum
Can't transmit serial fast Python to Arduino pyserial
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Can't transmit serial fast Python to Arduino pyserial
#1
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");
  }
}
  
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Serial loopback with Arduino doesn't work ThomasS 3 275 Sep-19-2020, 12:47 PM
Last Post: deanhystad
  Lib PySerial Pelathaon 2 334 Jul-07-2020, 12:41 PM
Last Post: DashOrion
  pySerial why do i need \r Mad_Max 1 376 May-26-2020, 01:29 AM
Last Post: Larz60+
  About Arduino and Python usb webcam tuts Simurg 1 399 Mar-20-2020, 07:25 PM
Last Post: Larz60+
  Help Graphing Arduino Data Real Time in Python nschulz 0 574 Mar-12-2020, 06:15 PM
Last Post: nschulz
  Serial to telnet using Python Charles_Linquist 2 1,869 Jun-17-2019, 04:37 PM
Last Post: DeaD_EyE
  Arduino / Python Environment Setup - PIP stevealbright 0 675 Feb-24-2019, 10:48 PM
Last Post: stevealbright
  Arduino Read Update Datetime from Python jambuna35 0 888 Feb-03-2019, 05:13 PM
Last Post: jambuna35
  assign the variable to every value received serial from Arduino barry76 4 908 Feb-01-2019, 10:19 AM
Last Post: barry76
  Python Read/Write serial dlizimmerman 0 2,209 Jan-31-2019, 03:12 AM
Last Post: dlizimmerman

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020