Hi all, I am new to blender (though not to Arduino and serial/pySerial) and am trying to get IMU data through pyserial.
Now I was partially successful in that I managed to rotate the basic cube however the response was ultra slow and this is because the controller was always opening and closing the serial port. I have looked around and think that the best way of doing this is by implementing modules/def and calling them from an Always sensor linked to a controller. Now this is what I have tried:
Used 2 sensors, one with no activate true level enabled linked to a python script (run once on game start) and another sensor linked to a controller calling a module with the serial receive routine with the activate true level enabled (always run). This fails as the open serial handle is not a global one and the module which calls the function fails to locate the handle. I read about assigning it to the blender module (doesn’t work with latest version of blender) or to the bge which also fails, I guess I am missing something. Here is an online example:
I setup one sensor, with activate true level linked to a controller calling a module all defined in a single script. This script contains the opening and assigning of the serial port followed by the def of the read routine:
ser = serial.Serial(‘COM7’, 115200, timeout=1)
cont = bge.logic.getCurrentController()
obj = cont.owner
global ax, ay, az
ax = ay = az = 0.0
dot = (b’\x2E’)
line = ser.readline()
angles = line.split(b’\x2C\x20’)
if len(angles) == 3:
ax = float(angles)
ay = float(angles)
az = float(angles)
This also fails as arduino receives but doesn’t reply probably due to garbled data. By debugging I noticed that the serial oirt opening works but there is an empty buffer (in fact arduino doesn’t reply). Mind you this works fine from my Arduino console, when I send a dot, I get the correct reply. It also works in a pyOPENGL test cube very well and fast so the arduino part and pyserial routines are working fine.
What I’d like to do is open the serial port once at game start (and it should the second way I did it, but please confirm) then read the data calling a module which requests from arduino the coordinates and then applies the transformation to the object. At game end, it should call the game.close_append to close the serial. I tried inserting:
from bpy.app.handlers import persistent
However whenever I press Escape this does not work (serial stays open and nothing is printed). This is in the single main script, before the read def.
I tried many further iterations but can’t seem to get a grip on what’s going on. I noticed that many tutorials are pretty outdated so they no longer apply to the current blender (2.77) nor python (3.5.1) versions. I hope someone has some insight on how to properly setup serial input under the Game Logic, meaning, game start -> open serial handle then loop request data from IMU -> apply transformation until game ends where we close the serial port. The serial port must be open only once at the start and closed at the end naturally which is what I am trying to do (I seem to open it but not close it) — but most of all, I seem to be able to send data but not receive any response from arduino. I tried with various timeouts, from non blocking to .1 up to 2 seconds with no difference. As I said, arduino sends a frame of values only after I request it, so I would imagine a flow of replies which I do not see. Additionally, I setup the pySerial by copying the Serial directory under the appropriate blender\python path, I did not specify the path to my external pyserial/python install to keep them seperate. My pyOpenGL test works like a charm so Arduino, pyserial and my basic python 3 installs are fine. I hope I have been sufficiently explanatory - thanks for any heads up!