Here’s a little Expect script for getting a control stream into Pure Data, in my case from a butchered Genius serial mouse that I wrote an interrupt-driven Arduino driver for.  The driver sends a “+” or “-” down the serial line each time the optical rotary encoder in the mouse guts moves a click.  This assumes the Arduino is connected on /dev/ttyUSB0 (e.g. on Linux).  Use a [netreceive 3000] (or whatever port you like) in Pure Data to receive.
Note: this only uses one mouse axis, requiring two interrupts.  Apparntley the Arduino Mega has six interrupt lines externally available, so I'll be adding another axis of control soon.
#!/usr/bin/expect
# Take Arduino mouse '+'/'-' stream and convert into Pure Data FUDI format, without buffering.
# To run:
# expect mouse-pd.expect | pdsend 3000
# TODO: this should probably use Expect's stty command to set the serial port up to match the Arduino program.
eval spawn -noecho cat /dev/ttyUSB0
log_user 0
while (true) {
 expect {
  + {send_user "1;\n"}
  -- {-} {send_user -- "-1;\n"}
 }
}
Here’s the Arduino code:
// Simple interrupt-driven driver for quadrature encoder input (e.g. from a disassembled photoelectric ball mouse).
// Many Arduino boards provide only two interrupts, I believe: INT0 (on pin 2) and INT1 (on pin 3):
const int intA = 0, intAPin = 2;
const int intB = 1, intBPin = 3;
volatile int A = 0, B = 0;  // For storing the pin states for future reference to determine rotation direction
int A_Prev = 0, B_Prev = 0;  // Should these be volatile, too?
void setup()
{
  // Configure digital input pins for interrupt-driven timing:
  pinMode(intAPin, INPUT); digitalWrite(intAPin, LOW);
  pinMode(intBPin, INPUT); digitalWrite(intBPin, LOW);
  
  Serial.begin(115200);
  
  // Read initial state of the pins:
  A_Prev = digitalRead(intAPin);
  B_Prev = digitalRead(intBPin);
  A = digitalRead(intAPin);
  B = digitalRead(intBPin);
  attachInterrupt(intA, changeA, CHANGE);
  attachInterrupt(intB, changeB, CHANGE);
}
void changeA()
{
  A = !A;
  output();
  A_Prev = A;
}
void changeB()
{
  B = !B;
  output();
  B_Prev = B;
}
void output()
{
  if (A == B_Prev)
    Serial.print("+");
  else if (B == A_Prev)
    Serial.print("-");
  else
    Serial.print('?');
}
void loop() {}
Microcontroller programming is fun, BTW!  I’d never written a driver or an interrupt handler until two days ago.