Mar-29-2020, 08:12 PM
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:
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");
}
}
