3
$\begingroup$

I was trying to receive some integer data from arduino and rotate the cube based on the value, but when the script was run, it gives the following error.

blender error shown in console window

Can someone help me with this?

The python code:

import bpy
from bpy import context
import serial
from time import sleep
from bpy.props import IntProperty, FloatProperty


value = 0
i=0
j=0
degree = 0
ser = serial.Serial("COM77", 9600)

class ModalOperator(bpy.types.Operator):
    bl_idname = "object.modal_operator"
    bl_label = "Simple Modal Operator"

    x = IntProperty()

    def modal(self, context, event):
       self.x = ser.read()
       if x >0:
         value = int(self.x)
         value += 10
         degree = value * 3.14/180
         bpy.context.object.rotation_euler[0] = degree
         print(degree)

       if event.type  == 'LEFTMOUSE':
           return {'FINISHED'}

       return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        if context.object:

            print("hi")

            context.window_manager.modal_handler_add(self)
            return {'RUNNING_MODAL'}
        else:
            self.report({'WARNING'}, "No active object, could not finish")
            return {'CANCELLED'}


def register():
    bpy.utils.register_class(ModalOperator)


def unregister():
    bpy.utils.unregister_class(ModalOperator)


if __name__ == "__main__":
    register()

    # test call
    bpy.ops.object.modal_operator('INVOKE_DEFAULT')

The arduino code:

void setup()
 {
    Serial.begin(9600);


 }

 void loop()
 {
    for(int i=0; i<350;i++)
    {
        Serial.print(i);
        delay(100);
    }
 }
$\endgroup$
2
$\begingroup$

There are two problems with your code on in the sending and one in the receiving part.

You get from serial.read() a bytes object, but your self.x should be an integer, so you have to use int() before the assignment (see at the bottom for the code).
The next thing is, that you receive exactly one byte, but your string with the number can have more bytes, to overcome that you could use serial.readline() to read a whole line and modify the sending code as follows.

You send the integer from the arduino as sting, but you can't know how long it is on the receiving end. So you should terminate the string with a newline: Serial.println(i) will automatically append an \r\n for you.

The whole code would have to be modified like so:
receiving:

# ...
def modal(self, context, event):
    self.x = int(ser.readline(10))  # read a maximum of ten digits (only because 
                                    # there could be an error in the sending code)
    # ...

sending:

# ...
void loop()
{
    for(int i=0; i<350;i++)
    {
        Serial.println(i);
        delay(100);
    }
}
$\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.