Hello,
I've been working on a stepper motor controlled turret, and in order to control it via a joystick, I use a laptop to read my joystick values, and transmit them over serial to the Arduino. The data is transmitted in the format <xxx, yyy>, where xxx and you are greater than 100 and below 300.
Although the serial communication works, I have to run it very slowly, putting a delay of .5 seconds inside of my transmit function in python, or else the stepper motors disable themselves and nothing happens. Is there any way to fix this?
Python code:
import serial, time
import pygame
from pygame.locals import *
import math
turret_axis = 0
pitch_axis = 1
serialData = ''
arduino = serial.Serial('COM4', 115200, timeout=.1)
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]
return turretVal
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]
return pitchVal
def writeToSerial():
time.sleep(.5)
getXVal()
getYVal()
serialData = ('<'+turretVal+", "+pitchVal+">")
print(serialData)
arduino.write(serialData)
while True:
pygame.event.pump()
writeToSerial()
And here's the code running on my Arduino(atmega2560)
#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;
//Stepper motor control pins
const int tStep = 46;
const int tDir = 48;
const int tEnable = 62;
const int pStep = 36;
const int pDir = 34;
const int pEnable = 30;
//Stepper MS Pins
const int tMS1 = 22;
const int tMS2 = 39;
const int pMS1 = 57;
const int pMS2 = 4;
AccelStepper tStepper(1, tStep, tDir);
AccelStepper pStepper(1, pStep, pDir);
//============
void setup() {
Serial.begin(115200); //Setup serial
initializeSteppers();
}
//============
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();
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
}
//============
void processData() {
xInt = (xInt-200)*-10;
yInt = (yInt-200)*-10;
}
void initializeSteppers() {
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();
}
Any help would be appreciated. Thanks
Update March 27:
I've found that whenever I transmit from my laptop too fast, my pin 13 LED becomes stuck on, and my whole program gets disabled as if the Arduino is constantly initializing itself without stopping. I've also moved from transmitting two pieces of data to three (<data, data, data>)