How can I use an 8-Channel Line-Following Sensor Module with LEDs to make a device that reads music notes coded as holes in a paper strip?
// On an Arduino Mega, hardware serial can be used, but keeping SoftwareSerial on pins 2 & 3
// maintains direct drop-in pin compatibility with the SparkFun Musical Instrument Shield.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX = Pin 2, TX = Pin 3
const byte resetMIDI = 4; // Tied to VS1053 Reset line
const byte ledPin = 13; // MIDI traffic indicator
// Pin assignments for the 8 active-low IR sensors (adjust pin numbers to match your wiring)
const byte sensorPins[8] = {22, 23, 24, 25, 26, 27, 28, 29};
// G Major Scale starting at G3 (MIDI note numbers):
// G3 (55), A3 (57), B3 (59), C4 (60), D4 (62), E4 (64), F#4 (66), G4 (67)
const byte scaleNotes[8] = {55, 57, 59, 60, 62, 64, 66, 67};
// Track current and previous trigger states
bool notePlaying[8] = {false, false, false, false, false, false, false, false};
void setup() {
Serial.begin(57600);
pinMode(ledPin, OUTPUT);
// Configure sensor pins with internal pull-ups (ensures HIGH when unlit/blocked)
for (byte i = 0; i < 8; i++) {
pinMode(sensorPins[i], INPUT_PULLUP);
}
// MIDI communication setup at 31250 baud
mySerial.begin(31250);
// Reset the VS1053 chip
pinMode(resetMIDI, OUTPUT);
digitalWrite(resetMIDI, LOW);
delay(100);
digitalWrite(resetMIDI, HIGH);
delay(100);
// Set default bank: GM1
talkMIDI(0xB0, 0x00, 0x00);
// Set channel 0 volume to max (127)
talkMIDI(0xB0, 0x07, 127);
// Instrument selection: 19 = Church Organ
talkMIDI(0xC0, 19, 0);
Serial.println("Paper tape IR reader ready.");
}
void loop() {
for (byte i = 0; i < 8; i++) {
// Sensor output is active-low: LOW indicates light detected through hole
bool isTriggered = (digitalRead(sensorPins[i]) == LOW);
// Hole detected: start note if not already sounding
if (isTriggered && !notePlaying[i]) {
noteOn(0, scaleNotes[i], 90);
notePlaying[i] = true;
}
// Hole passed / blocked: end note
else if (!isTriggered && notePlaying[i]) {
noteOff(0, scaleNotes[i], 60);
notePlaying[i] = false;
}
}
// Small debounce / scan interval
delay(5);
}
void noteOn(byte channel, byte note, byte attack_velocity) {
talkMIDI((0x90 | (channel & 0x0F)), note, attack_velocity);
}
void noteOff(byte channel, byte note, byte release_velocity) {
talkMIDI((0x80 | (channel & 0x0F)), note, release_velocity);
}
void talkMIDI(byte cmd, byte data1, byte data2) {
digitalWrite(ledPin, HIGH);
mySerial.write(cmd);
mySerial.write(data1);
if ((cmd & 0xF0) <= 0xB0 || (cmd & 0xF0) >= 0xE0) {
mySerial.write(data2);
}
digitalWrite(ledPin, LOW);
}
------------------------------------
To read punched holes in a paper strip using an 8-channel line-tracking sensor array (such as an 8-channel TCRT5000 board or similar IR reflectance array), the core principle relies on differential reflectance: infrared light bounces off solid paper back to the phototransistor, but escapes when passing over a punched hole.
1. Optical & Mechanical Sensing Architecture
Because reflectance sensors require light to bounce back to detect a surface:
The "Hole" Detection Principle:
- Solid Paper: White/light cardstock reflects the IR beam back to the sensor phototransistor (Sensor Output = LOW or HIGH, depending on module active logic; onboard indicator LED illuminates).
- Punched Hole: When a hole passes directly over the sensor pair, the IR beam passes completely through the paper and does not reflect back (Sensor Output flips state; onboard indicator LED turns off).
- If you place a solid plate directly underneath the paper strip, light passing through a punched hole will reflect off that plate and produce false readings.
- Solution: Create an optical dark cavity or slot directly beneath the sensor array. Use a matte black backing well (lined with non-reflective black felt, matte black PLA, or an open slot at least 15–20 mm deep) underneath the tape slot so that IR light going through the hole is completely absorbed or lost.
- Focal Distance:
- Maintain a strict 2.5 mm to 4.0 mm gap between the sensor faces and the paper surface. If the paper bulges or lifts, reflection drops and causes ghost notes. Use a clear acrylic pressure runner or dual guide rails to keep the punched strip completely flat across the read line.
2. Wiring & Hardware Setup
Connect the 8 sensor channels directly to digital I/O pins on your microcontroller (e.g., Arduino Mega or Uno). If your module features an IR / EN pin, tie it directly to 5V (or control it via a digital pin) to power the IR emitter array.
3. Firmware Architecture: Polyphony & State Edge Detection
To play notes properly without continuously retriggering or buzzing, your code must:
1. Detect state transitions (edges): Trigger a noteOn only when a channel transitions from Paper to Hole.
2. Trigger a noteOff when the channel transitions back from Hole to Paper.
3. Handle multiple simultaneous channels (chords/polyphony).
4. Strip Layout & Alignment Guidelines
1. Pitch Matching: Measure the exact center-to-center pitch of the optical sensors on your 8-channel PCB (standard boards typically have 9.5 mm or 10 mm spacing). Your paper strip punching template must match this center-to-center distance exactly across the width.
2. Hole Geometry:
o Circular holes punched with a standard hand punch (3 mm to 4.5 mm diameter) align cleanly with TCRT5000 lenses.
o For longer sustained notes, punch consecutive overlapping holes to form elongated slots. The transition logic will hold the note active until the paper returns solid.
3. Paper Selection: Use thick, matte white cardstock (65 lb to 110 lb / ~175–250 gsm). Avoid glossy coated stock, which creates specular glares and unpredictable reflection angles.

No comments:
Post a Comment