I have a very basic setup with a potentiometer hooked up to my Arduino analog 0 pin with it spamming output to the serial monitor. I am attempting to get the output in blender to match the arduino output by using the following code:

from time import sleep as wait
import serial

ser = serial.Serial("COM4",9600)
    while 1==1:

This code freezes the main window and also outputs whatever the initial value for the potentiometer was despite rotating it so the output gets stuck outputting something like


I realise that these issues are mainly due to the fact that my loop is endless but I'm not really sure how to create a coroutine in python and all the tutorials I've tried either don't work or require extra modules. I'd also like to know why it is outputting differently from the arduino serial monitor and how I can solve that.

This is the arduino code/output

void setup() {

void loop() {

  • $\begingroup$ look this, maybe is what you need. https://blender.stackexchange.com/questions/80971/blender-game-controller-using-arduino-not-working-properly $\endgroup$ Sep 16, 2017 at 6:47
  • $\begingroup$ That should solve the looping problem, but what about the outputs not matching? $\endgroup$ Sep 16, 2017 at 6:54
  • $\begingroup$ Did you try it already and check if that the outputs match? $\endgroup$ Sep 16, 2017 at 6:56
  • $\begingroup$ Yes. It still prints out the b'\r\n' bits which I could use string manipulation to get rid of but that's not really ideal. Also this method executes the script as a whole repeatedly right? What is the delay in that and how would I only re-execute parts of my script? It doesn't exactly seem ideal or scale-able to continuously import modules. $\endgroup$ Sep 16, 2017 at 7:39

1 Answer 1


You're reading binary data from the serial port, so that is why you have a bytes string (indicated by the b'' style of quoting). To convert it to a string, use

as_bytes = ser.readline()
line = as_bytes.decode('utf-8')

To get a repeated call to a "loop" function, it's easiest to start a modal operator with a high-frequency timer.

import bpy

class SERIAL_OT_arduino_read(bpy.types.Operator):
    bl_idname = "serial.arduino_read"
    bl_label = "Read From Arduino"

    def execute(self, context):
        as_bytes = self.ser.readline()
        line = as_bytes.decode('utf-8').strip()
        print('Serial line:', line)

        return {'FINISHED'}

    def modal(self, context, event):
        if event.type == 'TIMER':
        elif event.type == 'LEFTMOUSE':  # Confirm
            return {'FINISHED'}
        elif event.type in ('RIGHTMOUSE', 'ESC'):  # Cancel
            return {'CANCELLED'}

        return {'RUNNING_MODAL'}

    def invoke(self, context, event):
        self.ser = serial.Serial("COM4", 9600)
        self.timer = context.window_manager.event_timer_add(0.01, context.window)
        return {'RUNNING_MODAL'}

    def _finish(self):


# test call

This will read the serial port approximately 100x per second. Blender can still be used while this operator is running.

I haven't tested this code, just copied parts of the documentation and mixed it with your code.

  • $\begingroup$ Calling operator "bpy.ops.object.modal_operator" error, could not be found $\endgroup$ Sep 17, 2017 at 7:54
  • $\begingroup$ That was a copy-paste error. It should have been the actual operator being defined in the script, i.e. bpy.ops.serial.arduino_read. $\endgroup$
    – dr. Sybren
    Sep 17, 2017 at 8:21
  • $\begingroup$ No errors now but also no additional output. Thanks for the speedy replies btw. $\endgroup$ Sep 17, 2017 at 8:25
  • $\begingroup$ I would suggest sprinkling print() statements through the code, to see what gets executed and what doesn't. $\endgroup$
    – dr. Sybren
    Sep 17, 2017 at 9:02

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.