Arduino Accelerometer to Python Output

I'm trying to take my arduino code, have it output a character, then have my python code take in that character and do a function (press up, down, left, or right). Right now my arduino code is giving me an output of the letter I want, and I see that output when I run python, but python is still not pressing the buttons like I need it to. Any help would be great!

Arduino Code:

int  xmin=250,xmax=330;
int  ymin=264,ymax=330;
int  zmin=268,zmax=400;
int n=0, nx=0, ny=0, nz=0, a=0;
int x,y,z;
String cad="";

void setup() {
  Serial.begin(115200);
}


void loop() {
 

  nx=1;ny=1;nz=1;a=1;
  x=analogRead(1);
  y=analogRead(2);
  z=analogRead(3);
  x=9-map(x,xmin,xmax,0,9);
  y=map(y,ymin,ymax,0,9);
  z=map(z,zmin,zmax,0,9);
 

  if (x<3) nx=0;
  if (x>5) nx=2;
  if (y<3) ny=0;
  if (y>5) ny=2;
  if (z<3) nz=0;
  if (z>5) nz=2;


  a=1+9*nz+nx+3*ny;

  if (a==25){
    Serial.write('A'); //Release
  }
  else if (a==18){
    Serial.write('B'); //Duck
  }
  else if (a==26){
    Serial.write('C'); //Move right
  }
  else if (a==10){
    Serial.write('D'); //Left
  }
  else if (a==22){
    Serial.write('D');
  }
  else if (a==16){
    Serial.write('E'); //Jump
  }
  delay(200);  
  
 
}

Python Code:

import serial
import time
import pyautogui


str_up="up"    
str_down="down"
str_left="left"
str_right="right"


ArduinoSerial = serial.Serial(port='/dev/tty.usbmodem14501', baudrate=115200)
time.sleep(2)

while 1:
  incoming =  str (ArduinoSerial.read(1)) #Read one byte from serial port
  print(incoming)

  if 'D' == incoming:
    pyautogui.keyDown(str_left)  # Press left and ...
    pyautogui.keyUp(str_left)    # release
  elif 'A' in incoming:
   pyautogui.keyUp(str_right) ## release and ...
   pyautogui.keyUp(str_right)   # release
  elif 'C' == incoming:
    pyautogui.keyDown(str_right) # Press right and ...
    pyautogui.keyUp(str_right)   # release
  elif 'B' == incoming:
    pyautogui.keyDown(str_down) ## Press down and ...
    pyautogui.keyUp(str_down)   # release
  elif 'E' == incoming:
    pyautogui.keyDown(str_up) ## Press up and ...
    pyautogui.keyUp(str_up)   # release 


  ArduinoSerial.reset_input_buffer()  # Flush the serial port

shawnjayne:
Right now my arduino code is giving me an output of the letter I want, and I see that output when I run python, but python is still not pressing the buttons like I need it to. Any help would be great!

If your Python program is correctly getting the data from your Arduino program then the problem is within your Python code and I reckon you need to ask your question on a Forum that deals with Python programming.

...R

Sounds like a Python question instead of an Arduino question. Perhaps asking in Stack Exchange will yield better results.

Regardless, you might be interested in a more reliable connection between your Arduino and Python. You can use the compatible libraries SerialTransfer.h (Arduino) and pySerialTransfer (Python). These libraries automatically packetize and parse serial packets so you can reliably communicate between multiple Arduinos and between an Arduino and Python.

SerialTransfer.h is installable through the Arduino IDE's Libraries Manager and pySerialTransfer is pip-installable.

Example Python:

from time import sleep
from pySerialTransfer import pySerialTransfer as txfer

if __name__ == '__main__':
    try:
        link = txfer.SerialTransfer('COM13')
        
        link.open()
        sleep(2) # allow some time for the Arduino to completely reset
    
        link.txBuff[0] = 'h'
        link.txBuff[1] = 'i'
        link.txBuff[2] = '\n'
        
        link.send(3)
        
        while not link.available():
            if link.status < 0:
                print('ERROR: {}'.format(link.status))
            
        print('Response received:')
        
        response = ''
        for index in range(link.bytesRead):
            response += chr(link.rxBuff[index])
        
        print(response)
        link.close()
        
    except KeyboardInterrupt:
        link.close()

Example Arduino:

#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  myTransfer.begin(Serial);
}

void loop()
{
  myTransfer.txBuff[0] = 'h';
  myTransfer.txBuff[1] = 'i';
  myTransfer.txBuff[2] = '\n';
  
  myTransfer.sendData(3);
  delay(100);

  if(myTransfer.available())
  {
    Serial.println("New Data");
    for(byte i = 0; i < myTransfer.bytesRead; i++)
      Serial.write(myTransfer.rxBuff[i]);
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");
    Serial.println(myTransfer.status);
  }
}

I am not a Python expert, but I am using it now and then.

I can see some problems with your python code as I am trying to get it running.

  1. There is
    if 'D' == incomming
    versus
    if 'A' in incomming
    the second version does work like you would expect, but the first does not.

  2. When you test for 'A' you have two times "keyUp" but no "keyDown".

With some minor changes the (Python) code works on my computer like it should:

import serial
import time
import pyautogui

str_up="up"    
str_down="down"
str_left="left"
str_right="right"

ArduinoSerial = serial.Serial(port='/dev/tty.usbmodem14501', baudrate=115200)
time.sleep(4)

while 1:
  incoming =  str (ArduinoSerial.read(1)) #Read one byte from serial port
  print(incoming)

  if 'D' in incoming:       # changed '==' to 'in' 
    pyautogui.keyDown(str_left)  
    pyautogui.keyUp(str_left)    
  elif 'A' in incoming:
    pyautogui.keyDown(str_right)   # changed keyUp to keyDown
    pyautogui.keyUp(str_right) 
  elif 'C' in incoming:       # changed '==' to 'in'
    pyautogui.keyDown(str_right)
    pyautogui.keyUp(str_right)   
  elif 'B' in incoming:       # changed '==' to 'in'
    pyautogui.keyDown(str_down) 
    pyautogui.keyUp(str_down)   
  elif 'E' in incoming:       # changed '==' to 'in'
    pyautogui.keyDown(str_up)
    pyautogui.keyUp(str_up)   

  ArduinoSerial.reset_input_buffer()

As I do not have your hardware on the Arduino side so I just used some simple buttons on the arduino to generate letters A to E as serial output.