9

EDIT FOR T KINTER:

IDE is Visual Studio Code

Traceback call is printed below scripts

TkinterTest.py

#!/usr/bin/env python3

from tkinter import *
from tkinter import ttk
import Ev3_Motor

ev3 = Ev3_Motor.Ev3_Motor()

def calculate(*args):
    ev3.TestFunction("SUCCESSS YAHOOOOOO")
    print("command to robot >>>>")

root = Tk()
root.title("TEST TKINTER")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

ttk.Button(mainframe, text="TEST BUTTON", command=calculate).grid(column=3, row=3, sticky=W)

#ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

root.bind('<Return>', calculate)
root.mainloop()

Ev3_Motor.py

#!/usr/bin/env python3
from ev3dev.ev3 import *
import os
import sys
from time import sleep
import shutil 
import fileinput

os.system('setfont Lat15-TerminusBold14')

## FUNCTIONS ##

def __init(self):
    debug_print("Constructor Ev3")

def TestFunction(randomString):
    debug_print("Connection established: " + randomString)

TRACEBACK ERROR:

Starting: brickrun --directory="/home/robot/vscode-hello-python-master/Ev3" "/home/robot/vscode-hello-python-master/Ev3/TkinterTest.py"
Started.
----------
Traceback (most recent call last):
  File "/usr/lib/python3.5/tkinter/__init__.py", line 36, in <module>
    import _tkinter
ImportError: No module named '_tkinter'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/robot/vscode-hello-python-master/Ev3/TkinterTest.py", line 3, in <module>
    from tkinter import *
  File "/usr/lib/python3.5/tkinter/__init__.py", line 38, in <module>
    raise ImportError(str(msg) + ', please install the python3-tk package')
ImportError: No module named '_tkinter', please install the python3-tk package
----------
Exited with error code 1.

** ORIGINAL QUESTION: What I'm trying to do:**

I'm trying to create a program design where a UI program created with the Turtle Graphics Library in Python communicates directly with an EV3 Python Program that exists on the LEGO EV3 brick.

What I have so far:

  1. FrontEnd.py - An object oriented program that senses unique button clicks based on mouse pointer x and y and the shapes used to draw out button like objects
  2. RobotInstruction.py - An EV3 program that turns motors based on function calls

What happened when I tried to get it to work:

It seemed like there's a clash in dependencies. Like turtle and ev3 are not compatible. What it seemed to me was that the FrontEnd.py file was trying to load into the RobotInstruction.py file and end up on the brick, which is not what I wanted.

Important Note:

Independently, these scripts work fine. For example, RobotInstruction.py can receive keyboard input to act on the motors. I just want to get that "command" firing from the graphical program instead

My first attempt at a Janky Super Inefficient Workaround:

-- THE EXISTING CODE EXCERPTS ARE ATTACHED AT THE END --

Use FrontEnd.py to write a string command to a file and have RobotInstruction.py constantly reading that file for a command and then based on the command, call the relevant function to turn motors.

What Worked:

Can successfully write to file with a command from FrontEnd.py

Can successfully read the command from the same file

BUT

It doesn't happen in real time. I'm not super familiar with file reading / writing with Python so much...so very possible that I may be doing something awkward...

My Question:

Is what I'm trying to do, possible? Can you click a turtle graphics created button to send a command to an ev3 robot? If so, how would I go about forming the CONNECTION between the 2 separate scripts?

CODE "EXCERPTS"

FrontEnd.py

def TurnTier(ButtonName):
   if ButtonName == "TurnT1":
      fileName = open("file1.txt", "w+")
      fileName.write("TurnT1")
      fileName.close()

RobotInstruction.py

while (not blnTierFound):
   # file1.txt is written to from FrontEnd.py through a button click
   # We are writing "TurnT1" into file1.txt
   # Here we are opening the same file for reading to check for changes

   fileName = open("file1.txt", "r+")
   ButtonName = fileName.read()
   fileName.close()

   ButtonName = str(ButtonName)
   if (ButtonName == "TurnT1"):
        blnTierFound = True
        strMotor = 'A'

   # In the main part of the code 
   motorLeft = fncStartMotor(strMotor)
shecodesthings
  • 1,218
  • 2
  • 15
  • 33
  • 1
    If you're running both these scripts on the same device, why don't you just include a third script that passes those commands from your UI to the RobotInstruction.py programmatically? Reading and writing from a file isn't really the correct tool to be using here... – Henry Prickett-Morgan Dec 18 '18 at 21:53
  • 1
    Is there any specific requirement to use Turtle Graphics? I mean there are other libraries that I believe can do the job. For eg. with the `tkinter` library you can design a desktop app with buttons. Each button can make a call to the respective function in `RobotInstruction.py`. I also agree with the above comment, you do not need file R/W for this use-case. – amanb Dec 19 '18 at 05:26
  • 1
    You may also check out the [python-ev3dev](https://ev3dev-lang.readthedocs.io/projects/python-ev3dev/en/stable/) library. – amanb Dec 19 '18 at 06:02
  • @amanb - Thank you for your comment! I'm looking into Tkinter now and it's definitely a much easier implementation than turtle. However when I try to directly call a function from my RobotInstruction.py script, the script that uses tkinter complains and says that the ev3 module is not found ... – shecodesthings Dec 21 '18 at 17:40
  • 1
    You could pip install the ev3 module. Make sure that the library is installed along with its dependencies. If you could share a code snippet of what you have tried along with the Trace back error, it would be easier to debug and resolve this problem. – amanb Dec 21 '18 at 18:06
  • @amanb added an edit to show you the scripts and traceback error message. Thank you for your advice so far! – shecodesthings Dec 21 '18 at 18:40
  • 1
    You need python3-tk, run `sudo apt-get install python3-tk` and try again.Source: https://askubuntu.com/questions/815874/importerror-no-named-tkinter-please-install-the-python3-tk-package – amanb Dec 21 '18 at 18:59
  • @amanb - Does that work in a windows environment? Or do I need to use something like chocolatey (https://superuser.com/questions/947220/how-to-install-packages-apt-get-install-in-windows) – shecodesthings Dec 21 '18 at 19:02
  • That solution will only work in a Linux distro such as Ubuntu. I haven't used Chocolatey so cannot confirm if that would work. I guessed yours must be a Linux distro by looking at the file paths in the error. – amanb Dec 21 '18 at 19:05
  • @amanb Got pip installed on windows. got tkinter installed for python 3.7 32 bit. Set up an env variable to point to our python version from CMD on windows. Did python -m pip install python-ev3dev and successfully installed Pillow 5.3.0 and python ev3-dev-1.2.0 ... In the Ev3Motor script, what import statement do i need for ev3? (Ever since tkinter worked, ev3 motor stopped) ...Again thank you for your help! – shecodesthings Dec 21 '18 at 21:06
  • 1
    I'd suggest to get everything working, you could put all the code in one script. That way you wouldn't have to import one script to the other. For example, put the code for Ev3 motor inside the tkinter code and do a test run to seed of it works. – amanb Dec 22 '18 at 06:49

1 Answers1

3

Important information:

Typically the EV3 is programmed with a block-based programming language from Lego. The default operating system is programmed with this language. In order to use a text-based programming language like Python to communicate with the robot, you must install a new operating system called ev3dev which is Linux based using a dual boot SD card. The complete setup instructions are available here. This setup is mandatory prior to running the below scripts.

After the discussion in the comments section, I've put together a solution that may work for you. This makes use of the Tkinter script in the question(which has been tested to work) and the Ev3_Motor script has been modified to include an Ev3_Motor class(which makes it easy to import the script and create an object of this class). However, this script is untested and may produce other errors as I do not have an Ev3 robot. These errors can be debugged later. Make sure Ev3_Motor.py is in the same directory as TkinterTest.py.

Ev3_Motor.py

#!/usr/bin/env python3
from ev3dev.ev3 import *
import os
import sys
from time import sleep
import shutil 
import fileinput
import debug_print

os.system('setfont Lat15-TerminusBold14')

## Main Ev3 Motor Class ##
class Ev3_Motor:

    def __init__(self):
        debug_print("Constructor Ev3")

    def TestFunction(randomString):
        debug_print("Connection established: " + randomString)

TkinterTest.py

#!/usr/bin/env python3
from tkinter import *
from tkinter import ttk
import Ev3_Motor

ev3 = Ev3_Motor.Ev3_Motor()

def calculate(*args):
    ev3.TestFunction("SUCCESSS YAHOOOOOO")
    print("command to robot >>>>")

root = Tk()
root.title("TEST TKINTER")

mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
root.columnconfigure(0, weight=1)
root.rowconfigure(0, weight=1)

ttk.Button(mainframe, text="TEST BUTTON", command=calculate).grid(column=3, row=3, sticky=W)

#ttk.Label(mainframe, text="feet").grid(column=3, row=1, sticky=W)
for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

root.bind('<Return>', calculate)
root.mainloop()
amanb
  • 5,276
  • 3
  • 19
  • 38
  • I'm still working on getting the motor connected. You've posted my last edit as an answer, but it's not the working answer quite yet. I'm still doing some testing and will report back as soon as I make more progress. Thank you for your help thus far, but posting this as an answer is a little confusing to any news eyes seeing this question I think. – shecodesthings Dec 28 '18 at 20:52
  • The tkinter script in your edit works fine, I've tested it. However, there could be a simpler implementation. The Ev3 motor script needed some modification in the way it was being called and I was hoping it would work after that. The question itself should be edited to: connect Ev3 robot to a Python script with a Frontend control. As you know more about the problem, it wouldn't be right for me to edit the question. Python errors are quite descriptive, if you paste the Trace back, we can try and debug them. We can also continue the conversation on a chat. – amanb Dec 29 '18 at 04:34