Use a rotary encoder input in Python

For a a project I am working on I connected an incremental quadrature rotary encoder (Yumo E6B2-CWZ3E)to my Arduino Mega (2560). With a code I found online I was able to read the rotary encoder signal and print it in the serial monitor window of the Arduino IDE. The ultimate goal is that I can fetch this signal (a counter variable) and implement it in my python code. Here the rotary encoder should then move a dot (programmed with psychopy and pygame) up and down, similar to a scroll wheel.

So far I was able to read the serial input into Python 2.7 (on Windows7) using the PySerial library, with

var.readline()

Since I need to use this variable to calculate things in python I tried to convert it into an integer using rotary = int(var.readline()).

Now here is the problem: For some reason converting the serial input to int, works in the sample code. However, when I use the exact same method to implement it in my original python code I always get the Error: ValueError: invalid literal for int() with base 10: ''

Is there a better way to convert the serial input to an integer in Pyhton, or can I even do that already in the Arduino code and then transmit an integer directly ?

Arduino Code for the rotary encoder:

// Encoder connect to digitalpin 2 and 3 on the Arduino.

int counter = 0;  //This variable will increase or decrease depending on the rotation of encoder

void setup() {
  Serial.begin (9600);
  //Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
  attachInterrupt(0, ai0, RISING);
  
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
  attachInterrupt(1, ai1, RISING);
}

void loop() {
  // Send the value of counter
  Serial.println (counter);
} 

void ai0() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 3 to determine the direction
  if(digitalRead(3)==LOW) {
    counter++;
  }else{
    counter--;
  }
}

void ai1() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 2 to determine the direction
  if(digitalRead(2)==LOW) {
    counter--;
  }else{
    counter++;
  }
}

Sample code:

import serial 
from psychopy import *

s = serial.Serial('COM4',9600)
timer = core.Clock()

while timer.getTime()<25:
    rotary = int(s.readline())
    var = 10000 + rotary
    print var

Thank you.

I suggest you split this line into 2 (or more)

rotary = int(s.readline())

First read the value into a variable without trying to convert it to an int.
That will allow you to print the data and see what you are getting.
Then you can try converting the value in the variable to an int. You may need to use TRY/CATCH to deal with cases where the value cannot be converted.

...R

Thank you. This works quite well. However, I have an issue now that at one point the value switches to negative values. startin at 0 it goes up to 35000 and then switches to -35000 and counts backwards to 0. The value of the rotary encoder is attached to an object in my code and switching from 35000 to -35000 creates issues. Is there a way to circumvent this or at least increase the count to a higher value before it switches ?

Thanks

Is there a way to circumvent this or at least increase the count to a higher value before it switches ?

I'm guessing that it actually counts to 32767 before going negative. 32767 is the largest value that in int can hold. A long can hold larger values.