Introduction: 3D Printing Over Glass - Glass Validation With IR Sensor


I have an Original Prusa i3 MK2S and I usually print on glass because the PEI is a little damaged and I love the idea of removing the glass and put it in the fridge to remove the piece easily. Also, by printing on a glass surface, the piece’s base is perfectly smooth.

I use an OctoPrint as print server, “OctoPi” image in a Raspberry Pi 3 B+ connected to the printer via USB. I use CURA as my slicer and I have 2 printer profiles there. “MK2S” and “MK2S with glass”. In “MK2S with glass” profile, I have set the following Start GCODE that I’ve modified:

G21 ; set units to millimeters
G90 ; use absolute positioning
M82 ; absolute extrusion mode
G28 W ; home all without mesh bed level
G29; autolevel
G80 ; mesh bed leveling
G1 F600 Z+100 ; raise the print nozzle out of the way
G1 F2000 Y190 ; move bed forward
M300 S1567 P300 ; play a beep
M140 S{material_bed_temperature} ; set bed temp
M190 S{material_bed_temperature} ; wait for bed temp
M104 S{material_print_temperature} ; set extruder temp
M109 S{material_print_temperature} ; wait for extruder temp
G1 Z2.3 ; consider glass thickness measure your glass thickness first
G92 Z0 ; set absolute positioning for remaining print
G1 X60.0 E9.0 F1000.0 ; intro line
G1 X100.0 E12.5 F1000.0 ; intro line

This means that first it goes to home and then it runs the autolevel and mesh bed leveling. It raises the nozzle a little to remove easily the filament stuck to the nozzle. After that the heatbed moves to the front to put the glass easily and it beeps to alert that I should put the glass at that moment. Heat the heatbed first, and later heat the extruder. Follow this order because if the extruder is too hot in idle mode it usually releases the filament while it waits for the heatbed temp.When both temp are set, the nozzle goes to Z2.3 (2.3mm glass) and starts printing.

Sometimes happens that between printings I forget to remove the glass from the heatbed from the previous printing… when it goes to home, the nozzle smashes the glass in the home corner; it pushes down the heatbed and both motors continue forcing until the P.I.N.D.A. detects the bed (which will not happen because the glass is in the middle), then the X-axis goes uneven and the P.I.N.D.A. smashes into the glass and lifts up. ⌐⌐

So, I must manually re-calibrate it and start the printer’s calibration wizard, and for some reason I always forget that the P.I.N.D.A. is not correctly placed… so, in the calibration process the nozzle smashes again into the glass… ⌐⌐

With an IR sensor and a lot of research I solved this problem. The idea is simple: If the IR sensor detects the glass, then it stops the printing process.


  • 3D printer
  • Glass with the heatbed dimensions
  • Raspberry Pi with OctoPi image (OctoPrint)
  • HW-201 IR sensor
  • Arduino (optional)
  • Long Dupont wires female-female

Step 1: Testing the IR Sensor in Arduino

I bought an HW-201 IR sensor and some long Dupont wires female-female

IR Sensor pinout:

OUT----------Digital output (0 and 1)

Optional: First, I tested with an Arduino UNO and the IR sensor was working properly.

I found out that LOW means “detect” and HIGH means “no detect”.

This is the Arduino project that I used to make sure that the IR sensor was working fine:

void setup() {
 pinMode(4, INPUT);// set pin as input
void loop() {
  int detect = digitalRead(4);// read obstacle status and store it into "detect"
  if(detect == LOW){
   Serial.println("Obstacle on the way");
   Serial.println("All clear");

I opened Serial Monitor and selected the proper baud rate to see the readings, I had to manually re-calibrate the sensibility in the IR sensor and I discovered that it can’t read any further than 9 cm approx… my idea was to put the IR sensor at the top of the aluminum frame was discarded…

In this video I also found out that I need to put a sticker in the glass or paint a section in white. Pay attention to the IR sensor led, not to the Arduino UNO leds.

Step 2: Testing in Raspberry Pi

I was ready to test it in the Raspberry Pi, so I connected the IR Sensor’s out-pin to pin 40 or GPIO 21. I tried to search an OctoPrint plugin for this, and obviously I found nothing, so I decided to create my own plugin but it’s too complex for me.

So, as I did with Arduino UNO, I created a script to print on screen the readings. Once it worked, I replaced the print on screen readings for one-time reading shutdown command.

To achieve that, I had to connect via SSH and run the following commands:

sudo apt-get update
sudo apt-get install python3-rpi.gpio

I created a file named “” in /usr/local/bin/ with the following content:


import RPi.GPIO as GPIO
import os

GPIO.setup(21, GPIO.IN)


if sensor==0:
       os.system("sudo shutdown now")

To avoid that the OS request the password every time that I needed to run the shutdown command, I had to run:

sudo visudo

and add the following lines at the bottom:


I tested it running:

python3 /usr/local/bin/

Once it worked, I had to integrate it with OctoPrint.

Step 3: Testing in OctoPrint

After hours of research I found that there is a plugin for OctoPrint that creates
custom GCODES and it can invoke any system command.

So, after install it, and I created the OCTO1 custom GCODE pointing to python3 /usr/local/bin/

and I set OCTO1 at OctoPrint Settings - GCODE Scripts - Before print job starts

I made a IR sensor holder and I put it in a place that does not obstruct the X axis and Z axis

Note: I had to edit my End GCODE removing:

G1 X0 Y210; home X axis and push Y forward

and replacing by:

G1 X0 ; home X axis

between M107 and M84 because the glass was out of range of the sensor like in the image at top

This is my current End GCODE:

M104 S0 ; turn off extruder
M140 S0 ; turn off heatbed
M107 ; turn off fan

G1 X0 ; home X axis
M84 ; disable motors
M300 S900 P300 ; play a beep

Check the final result:

My gratitude to:
- Kantlivelong who made GCODE System Commands plugin and the support from OctoPrint Discord server.
- My friends Franco and Daniel for the help and support with bash and python scripts.

This story was not narrated in chronological order. To make it more readable, there were a lot of back and forth with the python and bash codes, permissions issues, etc.

Step 4: