speed sensor/Reading it/06. The first read
Reading it · 06 of 10

The first read

Three wires, no library, and a sketch that prints each time something enters the slot and leaves it. VCC goes to your board's logic voltage, SIGNAL to the pin the Push Button, Hall Effect and Reed Switch books use: GPIO 4 on an ESP32-S3, GPIO 25 on an ESP32, D2 on an Uno, GP15 on a Pico.

Three wires

Three wires
Your board
VCC to
3V3
SIGNAL to
GPIO 4
pinMode
INPUT
GND to GND, VCC to 3V3, SIGNAL to GPIO 4. Not the 5V pin: the block pulls SIGNAL up to VCC, and the ESP32-S3's pins run at 3.3 V. GPIO 4 is not a strapping pin, so a clear slot holding SIGNAL LOW at power-up cannot change how the board starts.

GND to GND. VCC to your board's logic voltage: 3V3 on an ESP32, an ESP32-S3 or a Pico, 5V on an Uno. SIGNAL to the pin this book uses throughout. NC stays unconnected.

The pins are the Push Button, Hall Effect and Reed Switch books' pins, so one wiring serves all four blocks. None of them is a strapping pin, which matters here: with the slot clear at power-up the comparator holds SIGNAL LOW, and a strapping pin held LOW can change how an ESP32 starts.

The sketch

pinMode(SENSOR_PIN, INPUT) and nothing else: the pull-up is on the board. In loop(), digitalRead gives HIGH while the slot is blocked and LOW while it is clear. The sketch keeps the last reading in last and prints only when the new one differs, so the monitor shows one line per change instead of a hundred a second. Each change to HIGH adds one to passes.

What you should see

At 115200 the serial monitor prints clear once at the start. Push a piece of card into the slot: the red LED goes out and it prints blocked (pass 1). Pull it out: the LED comes back and it prints clear.

The sketch compiles for an ESP32-S3 and an Uno. Here is the block working with the owner's own sketches, which light an XL LED block while the slot is blocked:

The TK61 on a LEGO baseplate, wired to an Uno-format board beside an XL LED block. A card pushed into the slot turns the TK61's red LED off and the sketch lights the XL LED; pulled out, the red LED comes back.
The same two blocks with a Pico 2. With the card in the slot the red LED on the TK61 is dark and the XL LED is lit.

Why this is not yet a speed sensor

The loop looks at SIGNAL every 10 ms. A hand is slow enough for that. A slotted disc on a motor is not: at a few hundred revolutions a minute its pulses are shorter than 10 ms, and most of them fall between two looks. A tachometer counts on an interrupt instead.

The code

No library. digitalRead returns HIGH while something blocks the slot and LOW while it is clear; the sketch prints only when that changes, and counts each time the slot is blocked. Change SENSOR_PIN to the pin you wired SIGNAL to.

ir_speed_first_read.ino
/*
  Infrared Speed Sensor - first read                    TK61 / /p/tk61

  Wiring. Count from the square pad on the TinkerBlock board, parts
  up, header at the bottom:

    GND    -> GND
    VCC    -> 3V3 on an ESP32, ESP32-S3 or Pico; 5V on an Uno.
              Your board's logic voltage: the block pulls SIGNAL
              up to VCC with 10k.
    NC     -> nothing   (unconnected on the board)
    SIGNAL -> GPIO 4 on an ESP32-S3, GPIO 25 on an ESP32,
              D2 on an Uno, GP15 on a Raspberry Pi Pico

  Arduino IDE
    Tools > Board                 your board, e.g. ESP32S3 Dev Module
    Tools > Port                  the one that appears when you plug in
    Tools > USB CDC On Boot       Enabled   (ESP32-S3 only)
    No library needed.
*/

// The pin SIGNAL is wired to.
// Uno: 2. ESP32: 25. ESP32-S3: 4. Pico: 15.
const int SENSOR_PIN = 4;

int last = -1;                // nothing read yet
unsigned long passes = 0;     // times something entered the slot

void setup() {
  Serial.begin(115200);

  // INPUT: the board drives SIGNAL both ways, LOW from its
  // comparator and HIGH through its own 10k pull-up.
  pinMode(SENSOR_PIN, INPUT);
}

void loop() {
  int level = digitalRead(SENSOR_PIN);

  if (level != last) {
    if (level == HIGH) {
      passes++;
      Serial.print("blocked  (pass ");
      Serial.print(passes);
      Serial.println(")");
    } else {
      Serial.println("clear");
    }
    last = level;
  }

  delay(10);
}

pinMode is INPUT: the board drives SIGNAL both ways, LOW from its comparator and HIGH through its own 10 kΩ. The sketch looks every 10 ms, which is fine for a hand and too slow for a motor. It compiles for an ESP32-S3 and an Uno.

View on GitHub · blocks/tk61-ir-speed-sensor/arduino/ir_speed_first_read/ir_speed_first_read.ino @ v1.5

When it does not work

The red LED follows the card but the serial monitor never changes.

Then the block is fine and the level is not reaching the pin you read. Check SIGNAL is on the pin SENSOR_PIN names, and that it is the right-hand pin, not NC beside it.

Nothing happens, and the red LED stays dark with the slot empty.

The block has no power, or the beam is not reaching the sensor. Count from the square pad: GND, VCC, NC, SIGNAL. Then look into the slot for a label, dust or a burr over either window.

The serial monitor stays empty on my ESP32-S3.

Set Tools > USB CDC On Boot to Enabled and upload again. Without it the S3's USB port does not bring up a serial port at boot, so the sketch runs with nowhere to print.

One push of the card prints blocked and clear several times.

The card's edge crossed the beam slowly, and the comparator, which has no hysteresis, flipped at each wobble. For a message this does no harm; the tachometer's sketch ignores edges that come too close together.

Where this goes next

Turning pulses into revolutions a minute.

Slots and rpm →

Edit this page — content/books/ir-speed-sensor/the-first-read.mdx

Community

Questions about this product

See what other owners have asked, and read their solutions.

Ask a question ↗

Infrared Speed Sensor

Loading discussions…

Discuss this article

Ask about this page. The answer stays here, on the page it belongs to, for whoever hits the same wall next.

Browse Modules and blocks on the forum →