This post has been de-listed
It is no longer included in search results and normal feeds (front page, hot posts, subreddit posts, etc). It remains visible only via the author's post history.
so I have some code setup that reads inputs from serial and uses that to flip a gpio on and off for driving a stepper motor. The code works fine when the joystick is only in one direction, the problem is when I move it in the X axis and a little to the Y axis is makes a big delay and i was hoping one of you guys could think of something to make it a bit more smooth when moves diagonally.
Here is the code im using:
#include <Servo.h>
#define MAX_COMMAND_LEN 7 // max chars in buffer, includes terminator
#define COMMAND_END_CHAR 's' // the command terminator character
#define Xstp 13
#define Xdir 12
#define XMS1 11
#define XMS2 10
#define XEN 9
#define Ystp 8
#define Ydir 7
#define YMS1 6
#define YMS2 5
#define YEN 4
#define Fire 3
#define Feed 2
char CommandBuffer[MAX_COMMAND_LEN]; // assemble command here
int CommandIndex = 0; // index into CommandBuffer for next char
String CommandPosition1;
String CommandPosition;
int End = 0;
int incomingByte = 0;
char Axis;
int Xpos;
int Ypos;
int X;
int Y;
//Servo Xaxis;
//--------------------------------------------------------------
// Gather external command chars, if any.
//
// If a complete command has been received, execute it.
//--------------------------------------------------------------
void do_commands(void)
{
bool overflow = false; // "true" if command buffer overflowed
// gather any commands from the external controller
while (Serial.available() && End == 0)
{
char ch =
Serial.read
();
if (CommandIndex < MAX_COMMAND_LEN)
{
// only add if command not over-length
CommandBuffer[CommandIndex ] = ch;
}
else
overflow = true;
if (ch == COMMAND_END_CHAR) // if end of command, execute it
{
if (overflow)
{
overflow = false;
Serial.println("TOO LONG");
}
else
{
CommandBuffer[CommandIndex - 1] = '\0'; // convert to C string, ignore terminator
//Serial.println
(CommandBuffer[CommandIndex - 1]);
//if (strlen(CommandBuffer).charAt(0) == 'X'){
// Serial.println("command X recieved");
// }
// if (strlen(CommandBuffer)==
// normally you would execute the command in the buffer here
// for now, just send back what we got
if (strlen(CommandBuffer)) { // if there is something to execute
//Serial.print
("Command: '");
//Serial.print
(CommandBuffer);
//Serial.println
("'");
CommandPosition = CommandBuffer;
//End = 1;
}
}
CommandIndex = 0; // prepare for next command
}
}
}
void setup()
{
Serial.begin(9600);
delay(1000); // wait for Serial to initialize
Serial.println("Key in command followed by ENTER.");
//Xaxis.attach
(2);
pinMode(Xstp, OUTPUT);
pinMode(Xdir, OUTPUT);
pinMode(XMS1, OUTPUT);
pinMode(XMS2, OUTPUT);
pinMode(XEN, OUTPUT);
pinMode(Ystp, OUTPUT);
pinMode(Ydir, OUTPUT);
pinMode(YMS1, OUTPUT);
pinMode(YMS2, OUTPUT);
pinMode(YEN, OUTPUT);
pinMode(Fire, OUTPUT);
pinMode(Feed, OUTPUT);
}
void loop() {
// do_commands();
//Serial.println
(CommandPosition);
if (Serial.available() > 0) {
do_commands();
//long number = atol( input ); //notice the function change to atoL
//Serial.println
(CommandPosition);
//CommandPosition = CommandPosition1;
Axis = CommandPosition.charAt(0);
Serial.println(Axis);
if (Axis == 'X') {
CommandPosition.remove(0, 1);
int Position = CommandPosition.toInt();
Xpos = map(Position, 0, 100, 0, 100);
int XDelay = map(Xpos, 0, 40, 1, 50);
int XdELAY = map(Xpos, 55, 100, 50, 1);
//digitalWrite(dir, LOW);
digitalWrite(XMS1, HIGH);
digitalWrite(XMS2, LOW);
if (Xpos <= 40) {
digitalWrite(Xdir, LOW);
digitalWrite(Xstp, HIGH); //Trigger one step forward
delay(XDelay);
digitalWrite(Xstp, LOW); //Pull step pin low so it can be triggered again
delay(XDelay);
}
else if (Xpos >= 55) {
digitalWrite(Xdir, HIGH);
digitalWrite(Xstp, HIGH); //Trigger one step forward
delay(XdELAY);
digitalWrite(Xstp, LOW); //Pull step pin low so it can be triggered again
delay(XdELAY);
}
}
if (Axis == 'Y') {
CommandPosition.remove(0, 1);
int Position = CommandPosition.toInt();
Ypos = map(Position, 0, 100, 0, 100);
int YDelay = map(Ypos, 0, 40, 1, 50);
int YdELAY = map(Ypos, 55, 100, 50, 1);
//digitalWrite(dir, LOW);
digitalWrite(YMS1, HIGH);
digitalWrite(YMS2, LOW);
if (Ypos <= 40) {
digitalWrite(Ydir, LOW);
digitalWrite(Ystp, HIGH); //Trigger one step forward
delay(YDelay);
digitalWrite(Ystp, LOW); //Pull step pin low so it can be triggered again
delay(YDelay);
}
else if (Ypos >= 55) {
digitalWrite(Ydir, HIGH);
digitalWrite(Ystp, HIGH); //Trigger one step forward
delay(YdELAY);
digitalWrite(Ystp, LOW); //Pull step pin low so it can be triggered again
delay(YdELAY);
}
}
if (Axis == 'B') {
CommandPosition.remove(0, 1);
int Position = CommandPosition.toInt();
// if (Position == 3) {
//digitalWrite(YEN, HIGH);
//digitalWrite(XEN, HIGH);
//}
// else {
// digitalWrite(YEN, LOW);
// digitalWrite(XEN, LOW);
//}
}
else {
//digitalWrite(YEN, LOW);
//digitalWrite(XEN, LOW);
}
}
}
I got the code for the Serial parser and help with getting it working from u/glory_road so big thanks to him.
The above code is receiving commands over serial from this python code:
#conda activate TurretM
#python "C:\Users\Kim\Desktop\
TurretM.py
"
#logitec extreme 3d pro button map:
#
# button 0: main trigger (unlabeled on controller)
# button 1: thumb trigger (labeled #2 on controller)
# button 2: bottom left hat (labeled #3 on controller)
# button 3: bottom right hat (labeled #4 on controller)
# button 4: top left hat (labeled #5 on controller)
# button 5: top right hat (labeled #6 on controller)
# button 6: bottom left base (labeled #7 on controller)
# button 7: top left base (labeled #8 on controller)
# button 8: bottom middle base (labeled #9 on controller)
# button 9: top middle base (labeled #10 on controller)
# button 10: bottom right base (labeled #11 on controller)
# button 11: top right base (labeled #12 on controller)
#
#//////////////////////////////////
import pygame
import time
import serial
def MapRange(x, in_min, in_max, out_min, out_max):
return int((x-in_min) * (out_max-out_min) / (in_max-in_min) out_min) #//////////////
#def ArdWrite
#ser = serial.Serial('/dev/tty.usbmodem1d11', 9600) # Establish the connection on a specific port
#ser = serial.Serial('COM4', 9600, timeout=1)
pygame.init()
pygame.joystick.init()
joysticks = [pygame.joystick.Joystick(i) for i in range(pygame.joystick.get_count())]
print(pygame.joystick.get_count())
MinX = 0
MaxX = 0.1
MinY = 0
MaxY = 0.1
MinZ = 0
MaxZ = 0.1
MaxLeft = -1
MaxRight = 1
#////// 1=function /// 0=block //////#
Xaxis = 1
Yaxis = 1
Zaxis = 0
ser = serial.Serial('COM3', 9600, timeout=0)
# Variable to keep the main loop running
running = True
# Main loop
while running:
pygame.event.get()
joystick1 = pygame.joystick.Joystick(0)
joystick1.init()
OldEvent = pygame.event.get()
#if OldEvent != pygame.event.get():
if(Xaxis == 1):
Joy1X = joystick1.get_axis(0)
if MinX > Joy1X:
MinX = Joy1X
print(MinX)
print("")
if MaxX < Joy1X:
MaxX = Joy1X
print(MaxX)
print("")
MapX = MapRange(Joy1X, MinX, MaxX, 0, 100)
X1 = MapX
MapXStr = str(MapX)
enabledX = 0
if enabledX == 1:
Button3 = joystick1.get_button(3)
Button5 = joystick1.get_button(5)
if Button3 == 0 and Button5 == 0:
ser.write('X1' MapXStr 's')
if Button3 == 1 and Button5 == 0:
ser.write('X2' MapXStr 's')
if Button3 == 0 and Button5 == 1:
ser.write('X3' MapXStr 's')
if Button3 == 1 and Button5 == 1:
ser.write('X4' MapYStr 's')
if enabledX == 0:
ser.write('X' MapXStr 's')
#print('X' MapXStr 's')
time.sleep(0.01)
if(Yaxis == 1):
Joy1Y = joystick1.get_axis(1)
if MinY > Joy1Y:
MinY = Joy1Y
print(MinY)
print("")
if MaxY < Joy1Y:
MaxY = Joy1Y
print(MaxY)
print("")
MapY = MapRange(Joy1Y, MinY, MaxY, 0, 100)
Y1 = MapY
MapYStr = str(MapY)
enabledY = 0
if enabledY == 1:
Button3 = joystick1.get_button(3)
Button5 = joystick1.get_button(5)
if Button3 == 0 and Button5 == 0:
ser.write('Y1' MapYStr 's')
if Button3 == 1 and Button5 == 0:
ser.write('Y2' MapYStr 's')
if Button3 == 0 and Button5 == 1:
ser.write('Y3' MapYStr 's')
if Button3 == 1 and Button5 == 1:
ser.write('Y4' MapYStr 's')
if enabledY == 0:
ser.write('Y' MapYStr 's')
#print('Y' MapYStr 's')
time.sleep(0.01)
if(Zaxis == 1):
Joy1Z = joystick1.get_axis(2)
if MinZ > Joy1Z:
MinZ = Joy1Z
print(MinZ)
print("")
if MaxZ < Joy1Z:
MaxZ = Joy1Z
print(MaxZ)
print("")
print(MapRange(Joy1Z, MinZ, MaxZ, 0, 100))
print('Y' MapYStr 's' ' ' 'X' MapXStr 's')
#print('X' MapXStr 's')
#ser.write('X' MapXStr 's')
#ser.write('Y' MapYStr 's')
Joy1Connect = joystick1.get_button(10)
if Joy1Connect == 1:
ser.close()
time.sleep(0.2)
running = False
Joy1Trigger = joystick1.get_button(0)
if Joy1Trigger == 1:
print(Joy1Trigger)
ser.write('B1')
Button1 = joystick1.get_button(1)
if Button1 == 1:
print(Button1)
ser.write('B1')
Button2 = joystick1.get_button(2)
if Button2 == 1:
print(Button2)
ser.write('B2')
Button3 = joystick1.get_button(3)
if Button3 == 1:
print(Button3)
ser.write('B3')
Button4 = joystick1.get_button(4)
if Button4 == 1:
ser.close()
time.sleep(0.5)
running = False
Button5 = joystick1.get_button(5)
if Button5 == 1:
print(Button5)
ser.write('B5')
#Joy1Thumb = joystick1.get_button(0)
#print(Joy1Thumb)
#time.sleep(0.5)
#print("")
# Did the user hit a key?
#if event.type == KEYDOWN:
# Was it the Escape key? If so, stop the loop.
# if event.key == K_ESCAPE:
# running = False
#Did the user click the window close button? If so, stop the loop.
#elif event.type == QUIT:
# running = False
Subreddit
Post Details
- Posted
- 2 years ago
- Reddit URL
- View post on reddit.com
- External URL
- reddit.com/r/arduino/com...