The first reading
Three wires, no library, and a sketch that prints the infrared level five times a second. VCC goes to your board's logic voltage, SIGNAL to an analog pin: GPIO 4 on an ESP32-S3, GPIO 34 on an ESP32, A0 on an Uno, GP26 on a Pico. Covered, it reads 0; a TV remote pressed at it makes the number jump. digitalRead works only in strong infrared.
Three wires
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 an analog pin. NC stays unconnected.
The sketch
No pinMode: analogRead sets the pin up itself. Each pass through loop()
takes 16 readings, prints their mean and waits 200 ms. Averaging steadies
the number against the ADC's own noise.
What you should see
At 115200 the monitor prints a number five times a second. Cover the dome with a finger and it falls to 0 or near it. Point a TV remote at it from 10 cm and hold a button: the number jumps and flickers as the remote flashes. Hold it by a window or a filament bulb and it climbs, and in strong light it stops at the ceiling while the red LED lights.
The number means nothing on its own. It is not calibrated in any unit, and two blocks differ: the maker promises at least 0.7 mA in its test light and quotes 2 mA as typical, so one part can read three times another. Compare readings from the same block.
digitalRead, and why not
SIGNAL is a voltage, so digitalRead will return something. Whether that is
useful depends on how strong the infrared is.
Pick your board and move the slider. A digital pin is only promised to read HIGH above one voltage and LOW below another, and between the two it may return either. On an ESP32-S3 HIGH needs about 2.5 V, which this block reaches only past the LED's knee, at about 0.7 mA: strong infrared. A Pico calls 2.0 V HIGH, so it gets there sooner; an Uno on 5V needs 3.0 V and about 1.3 mA.
So digitalRead can tell "a beam at close range" from "dark", and nothing in
between. analogRead shows a weak beam arriving long before HIGH does, and
lets your sketch choose the threshold. This book uses it throughout.
The code
No library. analogRead returns a count that rises with the infrared: 0 to 1023 on an Uno and a Pico, 0 to 4095 on an ESP32 or S3. The sketch prints the mean of 16 reads every 200 ms. Change IR_PIN to the analog pin you wired SIGNAL to.
/*
Infrared Receiver - first reading TK64 / /p/tk64
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: strong infrared takes
SIGNAL to about VCC - 0.4 V.
NC -> nothing (unconnected on the board)
SIGNAL -> GPIO 4 on an ESP32-S3, GPIO 34 on an ESP32,
A0 on an Uno, GP26 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 analog pin SIGNAL is wired to.
// Uno: A0. ESP32: 34. ESP32-S3: 4. Pico: 26.
const int IR_PIN = 4;
void setup() {
Serial.begin(115200);
}
void loop() {
// The mean of 16 reads, to steady the number.
long sum = 0;
for (int i = 0; i < 16; i++) {
sum += analogRead(IR_PIN); // more infrared, higher
}
Serial.println(sum / 16);
delay(200);
}Open the Serial Plotter instead of the monitor to see it as a line. The sketch compiles for an ESP32-S3 and an Uno; on an Uno, IR_PIN is A0.
View on GitHub · blocks/tk64-ir-photodiode/arduino/ir_photodiode/ir_photodiode.ino @ v1.5The same reading in MicroPython, for an ESP32, an ESP32-S3 or a Pico. read_u16 returns 0 to 65535 on all three, rising with the infrared.
"""
Infrared Receiver - first reading, MicroPython TK64 / /p/tk64
Wiring. Count from the square pad on the TinkerBlock board, parts
up, header at the bottom:
GND -> GND
VCC -> 3V3 (never 5V: strong infrared takes SIGNAL to
about VCC - 0.4 V)
NC -> nothing (unconnected on the board)
SIGNAL -> GPIO 4 on an ESP32-S3, GPIO 34 on an ESP32,
GP26 on a Raspberry Pi Pico
Thonny
Run > Configure interpreter MicroPython (ESP32) or
MicroPython (Raspberry Pi Pico)
Save it to the board as main.py to run it on every power-up.
Nothing to install: machine, sys and time are built in.
"""
import sys
import time
from machine import ADC, Pin
# The GPIO number SIGNAL is wired to. ESP32: 34. ESP32-S3: 4. Pico: 26.
IR_PIN = 4
adc = ADC(Pin(IR_PIN))
if sys.platform == "esp32": # ESP32 and ESP32-S3
adc.atten(ADC.ATTN_11DB) # the full range, to about 3.1 V
while True:
total = 0
for _ in range(16): # the mean of 16 reads
total += adc.read_u16() # more infrared, higher
print(total // 16)
time.sleep_ms(200)There is no Uno here: an Uno cannot run MicroPython. On the ESP32s, ATTN_11DB lets the ADC read up to about 3.1 V, above this block's 2.9 V ceiling. Stop it with Ctrl-C in Thonny's shell.
View on GitHub · blocks/tk64-ir-photodiode/micropython/ir_photodiode.py @ v1.5When it does not work
Check VCC first: with no VCC there is no current and it looks exactly like darkness. Then check SIGNAL is on the pin IR_PIN names, and test with an infrared source, not a phone torch: a TV remote held at the dome with a button down should make the number jump.
SIGNAL is at the ceiling. Sunlight, a filament or halogen lamp, or an emitter held too close will do it, and the red LED will be lit. Turn the sensor away from the light or shade it with a short black tube.
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.
IR_PIN is 4 for the ESP32-S3. On an Uno write A0: to the Uno's analogRead a plain 4 means analog input 4, a different pin. On an ESP32 write 34, on a Pico 26.
Edit this page — content/books/ir-photodiode/the-first-reading.mdx
Questions about this product
See what other owners have asked, and read their solutions.
Infrared Receiver
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.