3
$\begingroup$

I have a potentiometer and I want this to change the location of my cube. My script run is on the cube, connected to an "Always" actuator with True Toggle.

My problem is this line:

ser = serial.Serial('COM6',9600, timeout=1)

The script throws an error: ser is not defined

This line is read every Time, so my arduino must connect every Time. I need to perform a new connect every second, but I want float move.

So I try this, because the serial line is only executed once:

import serial
import time
import bge
import bpy

cont = bge.logic.getCurrentController()
ob = bpy.data.objects["Cube"]
scene = bge.logic.getCurrentScene().objects["Cube"]
own = cont.owner
PSerial=own['SerialVerbunden']

print (PSerial)
if (PSerial==False):
    ser = serial.Serial('COM6',9600, timeout=1)
    time.sleep(1)
    count = 0
    own['SerialVerbunden']=True




a = int(ser.readline().strip())
print (a)
count = count + 1
scene.worldPosition = [a, 0, 0]
ob.location = scene.worldPosition
ob.keyframe_insert(data_path="location", frame=count)

The script throws the error mentioned above: ser is not defined.

Yes this is true, because it is loading and at the end it forgets. The variable count have the same problem. It can't count. But how I can solve it? If I write a while loop, so I cant see my cube is moving, Blender freezes.

$\endgroup$
  • $\begingroup$ I suspect your if block may not be getting executed, as it doesn't look like PSerial is ever False. If you put a print statement inside the if, does it print? $\endgroup$ – gandalf3 Sep 18 '16 at 19:11
  • $\begingroup$ I've edited your question in an attempt to make it easier to understand. If I've misinterpreted anything, please don't hesitate to edit it yourself or roll back my edits. Thanks :) That said, are you trying re-establish the serial connection once a second? Or just once? The latter seems more likely, but I'm afraid I can't quite tell what you meant. $\endgroup$ – gandalf3 Sep 18 '16 at 19:25
  • $\begingroup$ this is correct, my english is only bad ^^ with the PSerial Variable i would like to solve my problem, but i get more problems(ser is not defined). If this script is re-played, then probably all are variable away. Therefore my script does not work, but I want to show with what I plan. By putting the "ser variable", pyserial connects with my Arduino. This requires 1 second. That's why I had to use time.sleep (1). but I want to bypass that and would like to see at least 25 frames per second. If I use a While Loop, then Blender unresponsive and I can not finish the script. $\endgroup$ – Dj EKI Sep 18 '16 at 19:50
2
$\begingroup$

I strongly suggest you separate connecting from communication. Do not forget you should execute a closing when the connection is not needed anymore.

Basically you need this three operations in this order over multiple frames:

  • establish a connection
  • communicate (receive/send) via connection
  • close connection [which seams not to apply at serial)

I suggest to implement it that way:

import serial
import bge

INTERNAL_PROPERTY_CONNECTION = "_connection"

listener = bge.logic.getCurrentController().owner

connection = listener.get(INTERNAL_PROPERTY_CONNECTION)
if not connection:
    connection = serial.Serial('COM6',9600, timeout=0)
    listener[INTERNAL_PROPERTY_CONNECTION] = connection

# your communciation
a = int(connection.readline().strip())
cube = bge.logic.getCurrentScene().objects["Cube"]
cube.worldPosition.x = a
$\endgroup$
  • $\begingroup$ Your script works, but has very strong deceleration and the Cube trembles. But with Errors dj-eki.de/Dateien/StackExchange/blendergamefehler2.jpg $\endgroup$ – Dj EKI Sep 19 '16 at 19:45
  • $\begingroup$ It looks like a conversion problem coming from int(..) which is something you need to solve by yourself. It is just a copy from your original code. I can't tell what serial is providing to you at that stage. $\endgroup$ – Monster Sep 20 '16 at 9:16
  • $\begingroup$ I note that the data are read faster than output. I have tried several scripts in my arduino. 1. Serial.println without delay. 2. Serial.println with delay (1000). So 1 second. at 1 second of delay it writes about 10 seconds, the same number. It reads a lot more than it can Output. $\endgroup$ – Dj EKI Sep 20 '16 at 20:17
  • $\begingroup$ I have this Output dj-eki.de/Dateien/StackExchange/blendergamefehler3.jpg I marked some red. Is this blank line my problem? $\endgroup$ – Dj EKI Sep 20 '16 at 20:46
  • $\begingroup$ This Output is coming from a = connection.readline().decode() $\endgroup$ – Dj EKI Sep 20 '16 at 21:00
0
$\begingroup$

Unfortunately I have no arduino to test with at the moment, but I did something quite similar in the past.

As you've discovered, time.sleep() will freeze the execution of the entire game engine, rather than just the script. Instead of sleeping or running in a loop (don't forget that the game engine is calling our script repeatedly anyway, so in a sense we're already in a loop), try something like this:

import serial

# the bge passes the current controller in as the first argument for us, we'll call it "cont"
def receive(cont): 
    # get current gameobject
    own = cont.owner

    # check for our "reminder property":
    if "ser_init" not in own: 
        # code in here is only run once
        ser = serial.Serial('/dev/ttyUSB0')
        # store a property to remind us later if we've already run the above code
        own["ser_init"] = True 

    # everything else will be executed every logic tic like normal:

    # get data (this is how I was reading in data for my project, you might do it differently)
    data = ser.readline().decode()
    # do something with data
    print(data)

I've put it in a function receive() so that it can be called by a module execution controller:

enter image description here Note the .py extension on the script name. The script won't be executed without it!

$\endgroup$
  • $\begingroup$ I Get Error: link $\endgroup$ – Dj EKI Sep 19 '16 at 19:21
  • $\begingroup$ @DjEKI Hm.. I suspect there might be an error earlier on. Do you get output when running without true level triggering enabled? $\endgroup$ – gandalf3 Sep 19 '16 at 19:41
  • $\begingroup$ I can see a Number as Output, without error $\endgroup$ – Dj EKI Sep 19 '16 at 20:12
  • $\begingroup$ this is my Output. I Get a number and a empty line, how like the post from Monster dj-eki.de/Dateien/StackExchange/blendergamefehler4.jpg $\endgroup$ – Dj EKI Sep 20 '16 at 20:56
  • $\begingroup$ Is that number coming from the serial output? If you remove the print statement, is it still there? $\endgroup$ – gandalf3 Sep 20 '16 at 21:15
0
$\begingroup$

I have solved the problem by "gandalf3" Help. His script was not working, but showed me the function of modules, so that I could be solved it myself thank you! Monster Script also works, but the fault lay with me. Nevertheless, I did not understand his script. My mistake was in Monster script: The output was a huge delay. The Arduino had a too short delay "delay (1)". My Arduino was faster than Blender :) I changed it to "delay (25)". Now I can turn the potentiometer and without delay.

My Script works: This script runs in Module.

import serial


ser = serial.Serial('COM6',9600)

def funktion():
    print (ser.readline().decode())
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.