I’m using a photo interrupter module (looks identical to this one: KY-010 Photo Interrupter Module - ArduinoModulesInfo but isn’t the exact same) to measure the speed of a wheel. The wheels hangs loose in the air. The plan is to have the speed of the wheel control a synth. I’ve taped bits of paper to the wheel that passes through the photo interrupter.
Now, my problem is that something in the chain doesn’t keep up with the speed of the wheel. At high speed the numbers are not consistent, giving me 10 ms between interruptions at the fastest and jumps around between 10 and about 50 ms at random, sometimes lapsing to 100 or more. I can also see that the led on the Arduino is blinking inconsistently.
The chain is: Interrupter -> Arduino Uno -> Pure Data -> Software synth. I know that every bit of paper passes through the interrupter. I know that my pure data-patch can handle the speed. It has to be the photo interrupter or my code that messes thing up. Does my code look reasonable? Does the interrupter have any limitations? Arduino should be able to handle way faster streams then 10 ms, I read 4 micros somewhere. I’m using the digital input on the arduino board.
One thing that has me confused is that the number stream that I get on high speeds is always a multiple of 10 (10 being the lowest). This is not true for slower speeds. This is data from Pure Data. In the serial monitor of Arduino IDE the ms-timestamps doesn’t make any sense to me, as it looks like this:
int state;
int Led = 13; // define LED pin
int buttonpin = 3; // define photo interrupter signal pin
int val; //define a numeric variable
void setup() {
pinMode(Led, OUTPUT); // LED pin as output
pinMode(buttonpin, INPUT); //photo interrupter pin as input
Serial.begin(9600); //Communication setup
}
void loop() {
val = digitalRead(buttonpin); //read the value of the sensor
if (val == HIGH) // turn on LED when sensor is blocked
{
digitalWrite(Led, HIGH);
state = 1;
} else {
digitalWrite(Led, LOW);
state = 0;
}
Serial.println(state); //send to PD
}
I’m on a macOS 13.4 Mac mini.
Using Arduino Uno
IDE version 2.1.1
Don’t know the manufacturer if the interrupter since I bought it in a kit and it's unmarked. Sorry.
It takes 1 millisecond to print a single character at that glacial Baud rate. Increase it to 115200. The timestamps ARE meaningless, because they tell you when a USB buffer packet is decoded on the PC.
To debug the circuitry, use an oscilloscope to examine the waveform on the optocoupler output.
Hmm, don't have have one of those. But isn't it odd that its always multiples of 10? Could that relay be the interrupter it self? It's such a digital-looking problem...?
Sorry, new to this, don't know the proper language. I'm talking about the Pure Data results. I measure the timing i PD and print it in the monitor. That's the numbers I'm talking about. Looks like this:
Your interrupter uses IR LEDs and the IR light will probably go right through your bits of paper. IF not, they will cause "fringing" of the light, meaning there NOT an abrupt change from on to off, etc.
Had this problem before switching to thicker paper. But the fringe-thing could still be a factor, I guess. But that shouldn't give me such consistent results, right? And there are clearly other problems here as well. I might try changing the material but that will be a later project. Have bigger fish to fry atm.
Don't trust the timestamps on the data logger--the buffering in the logger likely doesn't give reliable millisecond-scale timestamps.
Try printing millis() to check the performance of the serial system and the accuracy of the logger timestamping relative to the Arduino timestamping:
int state;
int Led = 13; // define LED pin
int buttonpin = 3; // define photo interrupter signal pin
int val; //define a numeric variable
void setup() {
pinMode(Led, OUTPUT); // LED pin as output
pinMode(buttonpin, INPUT); //photo interrupter pin as input
Serial.begin(115200); //Communication setup
}
void loop() {
val = digitalRead(buttonpin); //read the value of the sensor
if (val == HIGH) // turn on LED when sensor is blocked
{
digitalWrite(Led, HIGH);
state = 1;
} else {
digitalWrite(Led, LOW);
state = 0;
}
Serial.print(millis());
Serial.print(" ");
Serial.println(state); //send to PD
}
Getting late over here, bed is calling. I'll try out all your suggestions tomorrow. Thanks for all the help so far! Seems like a really great place, this!
I’ve moved on with another solution on the Pure Data-end of things, rendering my above problems irrelevant. For those who have similar questions and might find this in the future:
I ended up using Pduino. Its a Pure Data extension that is design to be used with arduino. It is used together with firmata uploaded to the arduino. Here is a good resource: Getting started with Pduino ([arduino]) | Guitar Extended
I had some problems with the PD extension. Most PD extensions work right out of the gate but this one you hade to create a path for it manually in PD. See this for instructions: Pd Manual 4