Skip to content

Instantly share code, notes, and snippets.

@CRTified
Created January 5, 2022 03:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CRTified/c1fd0ec813e6674904f1b2587b4ac5ec to your computer and use it in GitHub Desktop.
Save CRTified/c1fd0ec813e6674904f1b2587b4ac5ec to your computer and use it in GitHub Desktop.
RasPi3b+ OctoPrint config with GPIO
{ config, pkgs, lib, ... }:
{
imports = [
./hardware-configuration.nix
./update-uboot.nix
./secrets.nix # Only sets `services.octoprint.extraConfig.api.key`
./octoprint.nix
];
boot.kernelPackages = pkgs.linuxKernel.packages.linux_rpi3;
boot.kernelParams = [ "cma=256M" ];
boot.loader.raspberryPi.enable = true;
boot.loader.raspberryPi.version = 3;
boot.loader.raspberryPi.uboot.enable = true;
boot.loader.raspberryPi.firmwareConfig = ''
gpu_mem=256
'';
boot.loader.grub.enable = false;
boot.loader.generic-extlinux-compatible.enable = true;
boot.extraModprobeConfig = ''
options cf680211 ieee80211_regdom="DE"
'';
hardware.enableRedistributableFirmware = true;
hardware.firmware = [ pkgs.wireless-regdb ];
networking.hostName = "octonix"; # Define your hostname.
networking.wireless = {
enable = false;
interfaces = [ "wlan0" ];
};
environment.systemPackages = with pkgs; [ libraspberrypi libgpiod ];
networking.useDHCP = false;
networking.interfaces.eth0.useDHCP = true;
networking.interfaces.wlan0.useDHCP = true;
users.groups."gpio" = { };
services.udev.extraRules = ''
SUBSYSTEM=="gpio", KERNEL=="gpiochip*", GROUP="gpio", MODE="0660"
'';
system.stateVersion = "21.05";
}
{ config, lib, pkgs, modulesPath, ... }:
{
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot.initrd.includeDefaultModules = false; # Needed because the ahci module is not available for _rpi* kernel
boot.initrd.availableKernelModules = [ "usbhid" "mmc_block" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" = {
device = "/dev/disk/by-label/NIXOS_SD";
fsType = "ext4";
};
swapDevices = [ ];
powerManagement.cpuFreqGovernor = lib.mkDefault "ondemand";
}
{ config, pkgs, lib, ... }: {
# TODO: Split file
networking.firewall = {
allowedTCPPorts = [ config.services.octoprint.port 5050 ];
};
systemd.services.octoprint = {
path = [ pkgs.libraspberrypi ];
serviceConfig.AmbientCapabilities = [ "CAP_NET_BIND_SERVICE" ];
};
users.users.octoprint.extraGroups = [ "gpio" "dialout" ];
services = {
octoprint = {
enable = true;
port = 80;
extraConfig = {
serial = {
port = "/run/klipper/tty";
baudrate = "250000";
autoconnect = true;
disconnectOnErrors = false;
};
plugins = {
pi_support = {
vcgencmd_throttle_check_command =
"${pkgs.libraspberrypi}/bin/vcgencmd get_throttled";
};
dashboard = { showWebCam = true; };
psucontrol = {
autoOn = true;
disconnectOnPowerOff = true;
enablePseudoOnOff = true;
offSysCommand = "${pkgs.libgpiod}/bin/gpioset -l 0 4=0";
onSysCommand = "${pkgs.libgpiod}/bin/gpioset -l 0 4=1";
postOnDelay = "2";
switchingMethod = "SYSTEM";
};
marlingcodedocumentation = {
include_source_reprap = false;
show_sources_checkboxes = false;
};
};
webcam = {
snapshot = "http://127.0.0.1:5050/?action=snapshot";
stream = "http://192.168.10.6:5050/?action=stream";
};
temperatures.profiles = [
{
name = "PETG";
extruder = 230;
bed = 80;
chamber = 0;
}
{
name = "PLA";
extruder = 180;
bed = 60;
chamber = 0;
}
];
};
plugins = p:
with p; [
abl-expert
displayprogress
displaylayerprogress
marlingcodedocumentation
titlestatus
octoprint-dashboard
psucontrol
printtimegenius
octoklipper
(buildPlugin rec {
pname = "FirmwareUpdater";
version = "1.12.0";
src = pkgs.fetchFromGitHub {
owner = "OctoPrint";
repo = "OctoPrint-${pname}";
rev = version;
sha256 = "1xjxjblxvqzqb5nn4ixygyzmxcw2wl5c2zdzfxx4xr26adq2dhhq";
};
meta = with pkgs.lib; {
description =
"The Firmware Updater plugin can be used to flash pre-compiled firmware images to your printer from a local file or URL.";
homepage =
"https://github.com/OctoPrint/OctoPrint-FirmwareUpdater#supported-boards";
license = licenses.agpl3Plus;
};
})
(buildPlugin rec {
pname = "BedLevelingWizard";
version = "0.2.4";
src = pkgs.fetchFromGitHub {
owner = "jneilliii";
repo = "OctoPrint-${pname}";
rev = version;
sha256 = "149rnkvqvjxgxv99sqjmkw3w4jmlz8mr25c7rsyyamgcjbl0w663";
};
meta = with pkgs.lib; {
description =
"This plugin implements a guided leveling approach to manual bed leveling.";
homepage =
"https://github.com/jneilliii/OctoPrint-BedLevelingWizard";
};
})
(buildPlugin rec {
pname = "CalibrationCompanion";
version = "1.0.1";
src = pkgs.fetchFromGitHub {
owner = "iFrostizz";
repo = "OctoPrint-${pname}";
rev = version;
sha256 = "1abx7h7fzcdmrgmp01b91gaqig5dh84rrjx0gh9fpy12a197nv6w";
};
meta = with pkgs.lib; {
description =
"This plugin was created to calibrate 3D printer settings easily.";
homepage =
"https://github.com/iFrostizz/OctoPrint-CalibrationCompanion";
};
})
(buildPlugin rec {
pname = "BedLevelVisualizer";
version = "1.1.0";
src = pkgs.fetchFromGitHub {
owner = "jneilliii";
repo = "OctoPrint-${pname}";
rev = version;
sha256 = "1ixm780n631wy4xp0m3kfvrq53yxghn5s0k51vdyn3mj66sy3aj8";
};
propagatedBuildInputs = with pythonPackages; [ numpy flask ];
meta = with pkgs.lib; {
description = "Displays 3D mesh of bed topography report";
homepage =
"https://github.com/jneilliii/OctoPrint-BedLevelVisualizer";
license = licenses.agpl3;
};
})
(buildPlugin rec {
pname = "GCodeSystemCommands";
version = "1.0.1";
src = pkgs.fetchFromGitHub {
owner = "kantlivelong";
repo = "OctoPrint-GCodeSystemCommands";
rev = "${version}";
sha256 = "07nvc5l0q9n7cbdrw40ljkwv9b85d2kpbh3ziza1f28mh6y7iszg";
};
meta = with pkgs.lib; {
description =
"This OctoPrint plugin adds the ability to define GCode commands that execute local system commands.";
homepage =
"https://github.com/kantlivelong/OctoPrint-GCodeSystemCommands";
license = licenses.agpl3Only;
};
})
];
};
mjpg-streamer = { enable = true; };
klipper = {
enable = true;
octoprintIntegration = config.services.octoprint.enable;
settings = let
rotDist =
{ steps_per_mm, microsteps ? 16, full_steps_per_rotation ? 200 }:
(full_steps_per_rotation * microsteps / steps_per_mm);
buildMultiLineStr = l: "\n " + lib.concatStringsSep "\n " l;
in {
mcu = {
serial =
"/dev/serial/by-id/usb-Klipper_stm32f103xe_33FFDB054E43383415522043-if00";
};
printer = {
kinematics = "cartesian";
max_velocity = 300;
max_accel = 3000;
max_z_velocity = 5;
max_z_accel = 100;
};
"static_digital_output usb_pullup_enable" = { pins = "!PC13"; };
board_pins = {
aliases = ''
EXP1_1=PA15, EXP1_3=PA9, EXP1_5=PA10, EXP1_7=PB8, EXP1_9=<GND>, EXP1_2=PB6, EXP1_4=<RST>, EXP1_6=PB9, EXP1_8=PB7, EXP1_10=<5V>
'';
};
display = {
lcd_type = "st7920";
cs_pin = "EXP1_7";
sclk_pin = "EXP1_6";
sid_pin = "EXP1_8";
encoder_pins = "^EXP1_5, ^EXP1_3";
click_pin = "^!EXP1_2";
};
"output_pin beeper".pin = "EXP1_1";
fan.pin = "PA8";
gcode_arcs.resolution = 1.0;
heater_bed = {
heater_pin = "PC9";
sensor_type = "EPCOS 100K B57560G104F";
sensor_pin = "PC3";
control = "pid";
# PID-Tuning with
# $ PID_CALIBRATE HEATER=heater_bed TARGET=80
pid_Kp = 66.136;
pid_Ki = 1.263;
pid_Kd = 865.552;
min_temp = 0;
max_temp = 90;
};
extruder = {
step_pin = "PB0";
dir_pin = "!PC5";
enable_pin = "!PB1";
microsteps = "16";
nozzle_diameter = "0.400";
filament_diameter = "1.750";
heater_pin = "PC8";
sensor_type = "NTC 100K beta 3950";
sensor_pin = "PA0";
control = "pid";
rotation_distance = rotDist { steps_per_mm = 100.2; };
pid_Kp = 11.56;
pid_Ki = 0.72;
pid_Kd = 46.32;
min_temp = 0;
max_temp = 260;
};
"tmc5160 extruder" = {
cs_pin = "PD2";
run_current = 0.7;
hold_current = 0.5;
stealthchop_threshold = 999999;
spi_bus = "spi3";
sense_resistor = 7.5e-2;
};
stepper_x = {
step_pin = "PC6";
dir_pin = "!PB15";
enable_pin = "!PC7";
microsteps = 16;
rotation_distance = rotDist { steps_per_mm = 80; };
endstop_pin = "tmc5160_stepper_x:virtual_endstop";
position_min = -20;
position_endstop = -20;
position_max = 235;
homing_speed = 30;
};
"tmc5160 stepper_x" = {
cs_pin = "PC10";
run_current = 0.6;
hold_current = 0.4;
stealthchop_threshold = 999999;
spi_bus = "spi3";
sense_resistor = 7.5e-2;
driver_SGT = 5; # Sensitivity
diag1_pin = "^!PC1";
};
stepper_y = {
step_pin = "PB13";
dir_pin = "!PB12";
enable_pin = "!PB14";
microsteps = 16;
rotation_distance = rotDist { steps_per_mm = 80.523; };
endstop_pin = "tmc5160_stepper_y:virtual_endstop";
position_min = -38;
position_endstop = -38;
position_max = 190;
homing_speed = 30;
};
"tmc5160 stepper_y" = {
cs_pin = "PC11";
run_current = 0.6;
hold_current = 0.4;
stealthchop_threshold = 999999;
spi_bus = "spi3";
sense_resistor = 7.5e-2;
driver_SGT = 5; # Sensitivity
diag1_pin = "^!PC0";
};
stepper_z = {
step_pin = "PB10";
dir_pin = "PB2";
enable_pin = "!PB11";
microsteps = 16;
rotation_distance = rotDist { steps_per_mm = 400; };
endstop_pin = "^PC15";
position_endstop = 0;
#endstop_pin = "probe:z_virtual_endstop";
#position_min = -3;
position_max = 200;
};
"tmc5160 stepper_z" = {
cs_pin = "PC12";
run_current = 0.6;
hold_current = 0.4;
stealthchop_threshold = 999999;
spi_bus = "spi3";
sense_resistor = 7.5e-2;
driver_SGT = 6; # Sensitivity
};
pause_resume = { };
"gcode_macro PARK" = {
gcode = buildMultiLineStr [
"G91"
"G1 E-30 F2100"
"G1 Z10"
"G90"
"G1 X-15 Y-20 F6000"
];
};
"gcode_macro FILAMENT_LOAD" = {
gcode = buildMultiLineStr [ "G91" "G1 E49 F500" "G90" ];
};
"gcode_macro FILAMENT_UNLOAD" = {
gcode = buildMultiLineStr [
"G91"
"G1 E0.5 F1000"
"G1 E-0.5 F1000"
"G1 E1.0 F1000"
"G1 E-1.0 F1000"
"G1 E1.5 F1000"
"G1 E-1.5 F1000"
"G1 E2.0 F1000"
"G1 E-2 F500"
"G1 E-49 F3000"
"G90"
];
};
"gcode_macro M600" = {
gcode = buildMultiLineStr [
"SAVE_GCODE_STATE NAME=M600_state"
"PARK"
"FILAMENT_UNLOAD"
"PAUSE" # Swap filament here, then do FILAMENT_LOAD and RESUME
"FILAMENT_LOAD"
"G91"
"G1 Z-10"
"G90"
"RESTORE_GCODE_STATE NAME=M600_state"
];
};
};
};
};
}
{ pkgs, ... }: {
fileSystems."/boot/firmware" = {
device = "/dev/disk/by-label/FIRMWARE";
fsType = "vfat";
};
systemd.services."uboot-updater" = {
enable = true;
description = "u-boot updater";
wantedBy = [ "multi-user.target" ];
after = [ "multi-user.target" "boot-firmware.mount" ];
serviceConfig.Type = "oneshot";
path = [ pkgs.diffutils ];
script = ''
CURRENT="/boot/firmware/u-boot-rpi3.bin"
UPDATE="${pkgs.ubootRaspberryPi3_64bit}/u-boot.bin"
cmp --silent -- "$CURRENT" "$UPDATE";
if [ "$?" == "1" ]; then
echo "Updating u-boot with $UPDATE";
cp -v -- "$UPDATE" "$CURRENT";
else
echo "No update required (Version: ${
toString pkgs.ubootRaspberryPi3_64bit.version
})"
fi
'';
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment