A 3D printer was obtained and built. Printing however required either a laptop tethered to the
machine, or printing from SD card which is difficult to supervise. The panel control
is also annoying.
Some functionality also requires running scripts directly communicating with the printer controller. Additional sensors and tools also may have to be attached, and easy changes of tools are needed.
A standalone server, capable of feeding G-code to the printer, and also running all sorts
of scripts directly communicating with the controller, was desired.
A Raspberry Pi board was sacrificed to the 3D printing gods.
Minibian
distro was used as the basis of the system,
with OctoPrint
as the printer control software.
The Minibian image was downloaded and written to a 8GB SD card (4GB would be enough, though). The board with the card was attached to the Ethernet network and powered up. Default password "raspberry" was used to log in as root.
The card was repartitioned to this result:
Device Boot Start End Blocks Id System /dev/mmcblk0p1 16 97727 48856 b W95 FAT32 /dev/mmcblk0p2 97728 14900000 7401136+ 83 Linux /dev/mmcblk0p3 14900001 15759359 429679+ 82 Linux swap / Solaris
fdisk /dev/mmcblk0...and then issue commands
d 2n<cr>2<cr>14900000n<cr>3<cr><cr>t382wqThe computer was rebooted with the new partition table, and the filesystem was resized to its full size:
resize2fs /dev/mmcblk0p2The SSH key was added to the card.
mkdir .ssh cd .ssh;wget http://<wherever_they_are>/authorized_keys; chmod 600 authorized_keys;cdNow set up the basics:
apt-get updateapt-get install mc strace usbutils sudo lsof psmisc raspi-gpio wiringpi mlocate setserial apt-file tcpdump tsharkapt-get install python git
install pip: https://pip.pypa.io/en/latest/installing/
wget https://bootstrap.pypa.io/get-pip.py python get-pip.py(Newer systems do not require installing pip separately.)
got:
/tmp/tmpTgcbsP/pip.zip/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.pip install requests[security]got failure after a while with gcc not available, so...
apt-get install gcctried again,
pip install requests[security]and got
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DUSE__THREAD -I/usr/include/ffi -I/usr/include/libffi -I/usr/include/python2.7 -c c/_cffi_backend.c -o build/temp.linux-armv6l-2.7/c/_cffi_backend.o c/_cffi_backend.c:2:20: fatal error: Python.h: No such file or directory compilation terminated. error: command 'gcc' failed with exit status 1so did
apt-get install python-devpip install requests[security]...aaaand got
building '_cffi_backend' extension gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -DUSE__THREAD -I/usr/include/ffi -I/usr/include/libffi -I/usr/include/python2.7 -c c/_cffi_backend.c -o build/temp.linux-armv6l-2.7/c/_cffi_backend.o c/_cffi_backend.c:13:17: fatal error: ffi.h: No such file or directory compilation terminated. error: command 'gcc' failed with exit status 1...soooo,
apt-get install libffi-dev...and, again...
pip install requests[security] apt-get install python git gcc python-dev libffi-dev wget https://bootstrap.pypa.io/get-pip.py python get-pip.py pip install requests[security]We have to set the user for the OctoPrint; it doesn't like to run as root.
mkdir /home/pi useradd -d /home/pi -m -s /bin/bash -U pi chown pi:pi /home/piSet the user to the groups for devices access.
usermod -a -G tty pi usermod -a -G dialout pi usermod -a -G video piPrepare the tools we will need in a moment.
apt-get install python-pip python-setuptools python-virtualenv git libyaml-dev build-essential
https://github.com/foosel/OctoPrint/wiki/Setup-on-a-Raspberry-Pi-running-Raspbian
su pi cd git clone https://github.com/foosel/OctoPrint.git cd OctoPrint virtualenv --system-site-packages venv ./venv/bin/python setup.py install...and OctoPrint is installed. Now, let's run it...
~/OctoPrint/venv/bin/octoprint...and it works. So,
exitNow, to allow supervising the printouts, install mjpg-streamer...
apt-get install subversion libjpeg8-dev imagemagick libav-tools cmakeand let's do this as the pi user, so...
su pi cd git clone https://github.com/jacksonliam/mjpg-streamer.git cd mjpg-streamer/mjpg-streamer-experimental make /home/pi/mjpg-streamer/mjpg-streamer-experimental/plugins/input_raspicam/input_raspicam.c:44:22: fatal error: bcm_host.h: No such file or directory compilation terminated. apt-get install libfreeimage-dev apt-get install libraspberrypi-dev apt-get install apt-file apt-file update apt-file search bcm_host libraspberrypi-dev: /opt/vc/include/bcm_host.h libraspberrypi0: /opt/vc/lib/libbcm_host.so python-picamera: /usr/lib/python2.7/dist-packages/picamera/bcm_host.py python-picamera: /usr/share/pyshared/picamera/bcm_host.py python3-picamera: /usr/lib/python3/dist-packages/picamera/bcm_host.py...so retrying...
apt-get install libraspberrypi-dev make apt-get install subversion libjpeg8-dev imagemagick libav-tools cmake libraspbrerrypi-dev su pi cd git clone https://github.com/jacksonliam/mjpg-streamer.git cd mjpg-streamer/mjpg-streamer-experimental makeSo, as root:
make install...and streamer works:
./mjpg_streamer -i "./input_uvc.so" -o "./output_http.so"So, to test the webcam, fswebcam was installed:
apt-get install fswebcam fswebcam -v -r 640x480 -d /dev/video0 /tmp/output.jpegedited file plugins/input_uvc/input_uvc.c replaced line
int width = 640, height = 480, fps = -1, format = V4L2_PIX_FMT_MJPEG, i; int width = 640, height = 480, fps = -1, format = V4L2_PIX_FMT_YUYV, i; make clean make int width = 352, height = 288, fps = 4, format = V4L2_PIX_FMT_YUYV, i; ./mjpg_streamer -i ./input_uvc.so --resolution=QVGA -o ./output_http.soThese may be useful:
Installing Cura: https://github.com/foosel/OctoPrint/wiki/Cura-Integration
We need to upgrade stock gcc to version 4.8, from the v4.6:
edit /etc/apt/sources.list, add line
deb http://mirrordirector.raspbian.org/raspbian/ jessie main contrib non-free rpicreate file /etc/apt/preferences.d/0Jessie with content:
Package: * Pin: release n=wheezy Pin-Priority: 900Package: * Pin: release n=jessie Pin-Priority: 300
Package: * Pin: release o=Raspbian Pin-Priority: -10
...then...
apt-get update apt-get install -t jessie gcc g++...and decided against continuing as raspi slicer would take too long time, not worth it, better run it on a way stronger machine
If the hot-end fan fails, filament softens too early, then fold and jams in the upper part of the hot end, like a pushed rope.
Note: Running the workpiece cooling fan on full overcools the hot end and trips thermal runaway!
as root:
cp scripts/octoprint.init /etc/init.d/octoprint chmod +x /etc/init.d/octoprint cp scripts/octoprint.default /etc/default/octoprintedit /etc/default/octoprint:
NICELEVEL=-2 NICELEVEL=-18 DAEMON=/home/pi/OctoPrint/venv/bin/octoprint update-rc.d octoprint defaultsSet up mjpg streamer:
/home/pi/scripts/raspi_streamer #!/bin/bash # from here: https://github.com/foosel/OctoPrint/issues/441 RES=QVGA PlugPath=/usr/local/lib Daemon=mjpg_streamer DaemonBase=/usr/local DaemonArgs="-i \"./input_raspicam.so\" -o \"./output_http.so\"" case "$1" in start) mjpg_streamer -b -i "$PlugPath/input_uvc.so --resolution=QVGA" -o "$PlugPath/output_http.so" echo "$0: started" ;; stop) pkill -x ${Daemon} echo "$0: stopped" ;; *) echo "Usage: $0 {start|stop}" >&2 ;; esacShut down octoprint (or it would overwrite its configuration file we just edited):
service octoprint stopand edit /home/pi/.octoprint/config.yaml:
system: {}change to:
system: actions: - action: streamon command: /home/pi/scripts/raspi_streamer start confirm: false name: Start video stream - action: streamoff command: /home/pi/scripts/raspi_streamer stop confirm: false name: Stop video stream -action: dividerand
temperature: {}change to:
temperature: profiles: - name: ABS extruder: 210 bed: 100 - name: PLA extruder: 180 bed: 60
Setting up Octocmd, octoprint commandline control: http://octocmd.readthedocs.org/en/latest/
pip install https://github.com/vishnubob/octocmd/archive/master.zipSo,
cd /home/pi wget https://github.com/vishnubob/octocmd/archive/master.zip unzip master.zip rm master.zip chmod 755 /home/pi/octocmd-master/scripts/octocmd ln -s /home/pi/octocmd-master/scripts/octocmd /usr/bin/initialize:
octocmd init > Octorpint URL: http://127.0.0.1:5000/ > Octoprint API key: <key>Uploaded gcode files are at /home/pi/.octoprint/uploads
It was decided to build a more functional API control. curl and bash were used instead of python the octocmd is written in, due to much faster start.
The whole project was move to its own page, sw_8control.
The controller needs to be reset by hardware. Examples are aborted print, tripped thermal protection, or upload of new firmware.
Install script for pulsing DTR to reset arduino, from https://github.com/brandonedens/jukebox/blob/master/bin/arduino-pulse-dtr
#!/usr/bin/python """ Script to pulse the DTR line prior to firmware upload. """ import serial import time import sys ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1) ser.setDTR(1) time.sleep(0.5) ser.setDTR(0) ser.close()put it to /home/pi/scripts/ardureset, then
chmod 755 /home/pi/scripts/ardureset ln -s /home/pi/scripts/ardureset /usr/bin/...and it fails,
Traceback (most recent call last): File "/usr/bin/ardureset", line 6, in <module> import serial ImportError: No module named serial pip install pyserialAnd because stty often does not support 250000 bps, here is a setup script, /home/pi/scripts/gsetport
#!/usr/bin/python import serial import sys ser = serial.Serial('/dev/ttyACM0', 250000, timeout=1) ser.close()add symlinks...
ln -s /home/pi/scripts/gsetport /usr/bin/
According to https://github.com/foosel/OctoPrint/wiki/OctoPrint-support-for-250000-baud-rate-on-Raspbian
there can be a problem with some older pyserial libraries with this speed.
The octoprint distro has a working version.
For other versions, there is a patch for the serialposix.py file, located at /usr/local/lib/python2.7/dist-packages/serial/serialposix.py
and the patch is here: http://sourceforge.net/p/pyserial/patches/_discuss/thread/ed3fb0de/f4fd/attachment/pyserial.patch
add to /home/pi/.octoprint/config.yaml, to the System: section:
- action: divider - action: ardureset command: /home/pi/scripts/ardureset confirm: "Are you sure you want to reset the controller?" name: Reset controller boardcreated script for showing messages on the display via the M117 g-code: /home/pi/scripts/gmessage
#!/usr/bin/python """ Script to show messages on attached display via g-code Do not use during active print jobs! Todo: add checks. """ import serial import time import sys if len(sys.argv) < 2 : print 'Shows messages on display via g-code' print 'Usage: ',sys.argv[0],' <message>' exit() ser = serial.Serial('/dev/ttyACM0', 250000, timeout=1) ser.write('\nM117 '+sys.argv[1]+'\n') ser.close()and to beep via g-code: /home/pi/scripts/gbeep
#!/usr/bin/python """ Script to beep via g-code Do not use during active print jobs! Todo: add checks. """ import serial import sys ser = serial.Serial('/dev/ttyACM0', 250000, timeout=1) ser.write('\nM300\n') ser.close()add symlinks...
ln -s /home/pi/scripts/gmessage /usr/bin/ ln -s /home/pi/scripts/gbeep /usr/bin/
octoprint API: http://docs.octoprint.org/en/master/api/index.html
export API=CAFEBABE.... export OCTOHOST=http://127.0.0.1:5000connection:
get API version:
curl -H "X-Api-Key: $API" http://127.0.0.1:5000/api/versionget status:
curl -H "X-Api-Key: $API" http://127.0.0.1:5000/api/connection curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "connect" }' http://127.0.0.1:5000/api/connection curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "disconnect" }' http://127.0.0.1:5000/api/connectionexecute arbitrary g-code command (here, a beep):
curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "M300" }' http://127.0.0.1:5000/api/printer/command curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "commands": ["M300","M117 test","M300"] }' http://127.0.0.1:5000/api/printer/commandget print job status:
curl -H "X-Api-Key: $API" http://127.0.0.1:5000/api/jobstart, restart, pause/unpause, cancel job: (also, it is /api/job, not /api/control/job)
curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "start" }' http://127.0.0.1:5000/api/job curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "restart" }' http://127.0.0.1:5000/api/job curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "pause" }' http://127.0.0.1:5000/api/job curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "cancel" }' http://127.0.0.1:5000/api/jobhome the tool head:
curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "home" }' http://127.0.0.1:5000/api/printer/printhead curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "jog", "x": 10, "y": 20, "z": -30 }' http://127.0.0.1:5000/api/printer/printheadset tool head temperature for tool 0 and 1 (here, 180 and 210 'C):
curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "target", "targets": { "tool0": 180, "tool1": 210" } }' http://127.0.0.1:5000/api/printer/tool curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "select", "tool": "tool0" }' http://127.0.0.1:5000/api/printer/tool curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "extrude", "amount": 5 }' http://127.0.0.1:5000/api/printer/tool curl -H "X-Api-Key: $API" -H "Content-Type: application/json" -X POST -d '{ "command": "target", "target": 60 }' http://127.0.0.1:5000/api/printer/bedget bed temperature/status:
curl -H "X-Api-Key: $API" http://127.0.0.1:5000/api/printer/bed curl -H "X-Api-Key: $API" http://127.0.0.1:5000/api/printer/tool
REVERSE-ENGINEERED:
run tshark -x port 5000|tee x.txt, run example commands; the justniffer tool is better here though
streaming on and off (streamon, streamoff)
curl -H "X-Api-Key: $API" -H "Content-Type: application/x-www-form-urlencoded" -X POST -d 'action=streamon' http://127.0.0.1:5000/api/system curl -H "X-Api-Key: $API" -H "Content-Type: application/x-www-form-urlencoded" -X POST -d 'action=streamoff' http://127.0.0.1:5000/api/systemattempt to get interactive command: failed, will need to go through log files (monitored a parametric command)
- name: Reporting type: section children: - command: M114 name: Get Position type: feedback_command regex: "X:([0-9.]+) Y:([0-9.]+) Z:([0-9.]+) E:([0-9.]+)" template: "Position: X={0}, Y={1}, Z={2}, E={3}"result: a /api/printer/command request is done, with 204 no-data response. Apparently the response data are taken from logs streamed via websocket.
The printer can have several values of its status:
Installing arduino for development of firmware:
apt-get install arduino-core arduino-mkinstalls stuff to /usr/share/arduino
Also, install picocom to test stuff directly over serial line:
apt-get install picocom
But this one does not work at 250000 bps speed, so maybe better use the sw_picocom-shad one.
Controller board runs on ATmega2560.
avrdude -p atmega2560 -P /dev/ttyACM0 -b 115200 -c arduino avrdude: stk500_recv(): programmer is not responding avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00So let's try something different:
ardureset; avrdude -p atmega2560 -P /dev/ttyACM0 -b 115200 -c avrispv2 avrdude: stk500v2_ReceiveMessage(): timeout avrdude: stk500v2_getsync(): found AVRISP programmer avrdude: ser_recv(): programmer is not respondingUse lsof -n|grep ttyACM0 to find the culprit.
After killing the offending process it will start running smoothly.
(todo: automate this in arduread/arduwrite scripts; use killall to kill the processes, or an API call to disconnect the printer daemon)
Install arduino dev tools, namely ino:
apt-get install python-dev&&python-setuptools cd /home/pi git clone git://github.com/amperka/ino.git cd ino python setup.py installNow where we have the arduino dev env installed, let's use it.
cd /home/piscp MarlinDev... directory from the other machine (or wget it from its site, or git clone the directory)
cd /home/pi/MarlinDev-dev-20150910-ShadConfig/Marlinino list-models: indicates we should use mega2560
ino build -m mega2560 No project found in this directory. cd .. ln -s Marlin src ino build -m mega2560 .build/mega2560/src/Marlin.cpp:5:35: fatal error: LiquidCrystal_I2C.h: No such file or directory compilation terminated. .build/mega2560/Makefile:367: recipe for target '.build/mega2560/src/Marlin.o' failed make: *** [.build/mega2560/src/Marlin.o] Error 1 Make failed with code 2...so,
cd /usr/share/arduino/libraries/ git clone git://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library cd - ino build -m mega2560 cd - git clone git://github.com/kiyoshigawa/LiquidCrystal_I2C cd - ino build -m mega2560 strace -f -o /tmp/x ino build -m mega2560 grep LiquidCrystal_I2C.h /tmp/x cd /usr/share/arduino/libraries/LiquidCrystal_I2C/LiquidCrystal_I2C mv * .. cd .. rmdir LiquidCrystal_I2C cd /home/pi/MarlinDev-dev-20150910-ShadConfig/ ino build -m mega2560 cp -av /usr/share/arduino/libraries/LiquidCrystal_I2C lib/strace shows that it looks in the /usr/share/arduino/libraries/LiquidCrystal/ so let's put it there (don't actually do this, because the missing step is the ino clean step):
mv /usr/share/arduino/libraries/LiquidCrystal_I2C/* /usr/share/arduino/libraries/LiquidCrystal/ ino build -m mega2560 .build/mega2560/src/Marlin.cpp:7:28: fatal error: LiquidTWI2.h: No such file or directory compilation terminated. .build/mega2560/Makefile:373: recipe for target '.build/mega2560/src/Marlin.o' failed make: *** [.build/mega2560/src/Marlin.o] Error 1 git clone git://github.com/lincomatic/LiquidTWI2 mv LiquidTWI2 /usr/share/arduino/libraries/ ino build -m mega2560 strace -f -o /tmp/x ino build -m mega2560 grep LiquidTWI2.h /tmp/x ino clean ino build -m mega2560 .build/mega2560/src/Marlin.cpp:8:101: fatal error: U8glib.h: No such file or directory compilation terminated. .build/mega2560/Makefile:396: recipe for target '.build/mega2560/src/Marlin.o' failed make: *** [.build/mega2560/src/Marlin.o] Error 1 Make failed with code 2 cp -av ./ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/libraries/U8glib /usr/share/arduino/libraries/ ino clean ino build -m mega2560 .build/mega2560/src/Marlin.cpp:13:29: fatal error: TMC26XStepper.h: No such file or directory compilation terminated. .build/mega2560/Makefile:1097: recipe for target '.build/mega2560/src/Marlin.o' failed make: *** [.build/mega2560/src/Marlin.o] Error 1 Make failed with code 2 cp -av ./ArduinoAddons/Arduino_1.6.x/libraries/TMC26XStepper/ /usr/share/arduino/libraries/ cp -av ./ArduinoAddons/Arduino_1.6.x/libraries/L6470/ /usr/share/arduino/libraries/ ino clean ino build -m mega2560 ..... arduino/Tone.cpp arduino/HID.cpp Linking libarduino.a Linking firmware.elf Converting to firmware.hex find .|grep firmware.hexSo, let's try to flash it...
service octoprint stop ardureset; avrdude -p atmega2560 -P /dev/ttyACM0 -b 115200 -c avrispv2 -U flash:w:./.build/mega2560/firmware.hex avrdude: Device signature = 0x1e9801 avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed To disable this feature, specify the -D option. avrdude: erasing chip avrdude: stk500v2_command(): command failed ardureset; avrdude -p atmega2560 -P /dev/ttyACM0 -b 115200 -c stk500 -D -U flash:w:./.build/mega2560/firmware.hex service octoprint start <edit file> ino build -m mega2560 cd /home/piscp MarlinDev... directory from the other machine (or wget it from its site, or git clone the directory)
cd /home/pi/MarlinDev-dev-20150910-ShadConfig ln -s Marlin src git clone git://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library mv Arduino-LiquidCrystal-I2C-library /usr/share/arduino/libraries/ git clone git://github.com/lincomatic/LiquidTWI2 mv LiquidTWI2 /usr/share/arduino/libraries/ cp -av ./ArduinoAddons/Arduino_1.6.x/hardware/marlin/avr/libraries/U8glib /usr/share/arduino/libraries/ cp -av ./ArduinoAddons/Arduino_1.6.x/libraries/TMC26XStepper/ /usr/share/arduino/libraries/ cp -av ./ArduinoAddons/Arduino_1.6.x/libraries/L6470/ /usr/share/arduino/libraries/ ino build -m mega2560Getting rid of an annoyance that appeared sometime along installing the packages.
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LANGUAGE = (unset), LC_ALL = (unset), LANG = "en_GB.UTF-8" are supported and installed on your system. perl: warning: Falling back to the standard locale ("C").put this to /etc/default/locale:
LANG=en_US.UTF-8 LANGUAGE=en_US LC_ALL=en_US...but doesn't work.
tried apt-get install locales, and failed:
Reading package lists... Done Building dependency tree Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: locales : Depends: glibc-2.13-1 Depends: debconf (>= 0.5) but it is not going to be installed or debconf-2.0 E: Unable to correct problems, you have held broken packages.Decided to not bother, put "C" as local language: /etc/default/locale:
LANG=CSet up GPIOs on the Raspi board:
apt-get install wiringpicreate directory for scripts:
mkdir /home/pi/scripts/gpiocreate pin list /home/pi/scripts/gpio/gpio_defs.sh, with content
PIN_ATXPWR=23create script for setting the pins and setting output permissions for the pi user, /home/pi/scripts/gpio/setpins.sh:
#!/bin/bash . /home/pi/scripts/gpio/gpio_defs.sh setinput (){ echo $1 > /sys/class/gpio/export echo "in" > /sys/class/gpio/gpio$1/direction gpio -g mode $1 in gpio -g mode $1 up } setoutput (){ echo $1 > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio$1/direction chown -R pi:pi /sys/class/gpio/gpio$1/value } setoutput $PIN_ATXPWRCreate script for powering up the ATX PSU, disabling reset on connect, and connecting controller to server, /home/pi/scripts/gpio/atx_on.sh:
#!/bin/bash . /home/pi/scripts/gpio/gpio_defs.sh setpin() { echo $2 > /sys/class/gpio/gpio$1/value } setpin $PIN_ATXPWR 1 sleep 2 stty -F /dev/ttyACM0 hupcl- 8connectCreate script for powering down the ATX PSU, /home/pi/scripts/gpio/atx_on.sh:
#!/bin/bash . /home/pi/scripts/gpio/gpio_defs.sh setpin() { echo $2 > /sys/class/gpio/gpio$1/value } 8msg Disconnecting... 8disconnect sleep 2 setpin $PIN_ATXPWR 0name script to start with Kxx, put to /etc/rc6.d
as described here: http://ccm.net/faq/3348-ubuntu-executing-a-script-at-startup-and-shutdown
One of the GPIOs of the host computer board was connecte to the base of a NPN transistor. The transistor was connected between the power-control line of the ATX PSU connector (the green wire) and ground. High level on the GPIO now powers up the ATX PSU.
The controller and the webcam aren't needed when the printer is depowered. The host computer would however feed them via the USB. A USB hub was therefore used; its USB power wire was cut and attached instead to the non-standby 5V rail of the ATX PSU. This automatically powers and depowers the controller and all the auxiliary equipment when the printer is powered on or off..
A switch is added to allow selection between the standby and non-standby power, to facilitate development without having to power the whole machine.
This may be handier than using /dev/ttyACM0, for the cases when there are more than one Arduino-based serial controller attached to the machine.
In /etc/rc.local, add
ln -s /dev/serial/by-id/usb-Arduino__www.arduino.cc_<your-serial-number>-if00 /dev/3dprinterapt-get install httpry...and httpry works, but shows just the requests, but for debugging the API the whole requests and headers are needed. So...
So let's try justniffer, http://justniffer.sourceforge.net/
The way via apt repository using ppa:oreste-notelli/ppa repo did not work.
cd /usr/src git clone git://github.com/onotelli/justniffer cd justniffer ./configure
...and it failed, on inability to run config.sub
...which points to /usr/share/automake-1.14/config.sub
...but there's no such version, we have /usr/share/automake-1.11/config.sub, so relink for that and for config.guess
...and retry...
checking for Boost headers version >= 1.46.0... no configure: error: cannot find Boost headers version >= 1.46.0 apt-get install libboost-iostreams1.49 libboost-iostreams1.49-dev checking for boost/program_options.hpp... yes checking for the Boost program_options library... no configure: error: cannot find the flags to link with Boost program_options apt-file find libboost-program-options apt-get install libboost-program-options1.49.0 libboost-program-options1.49-dev apt-get install libpcap0.8-dev ./configure make CDPATH="${ZSH_VERSION+.}:" && cd . && aclocal-1.14 /bin/bash: aclocal-1.14: command not found make: *** [aclocal.m4] Error 127 In file included from /usr/include/boost/python/detail/prefix.hpp:13:0, from /usr/include/boost/python/args.hpp:8, from /usr/include/boost/python.hpp:11, from python.h:15, from formatter.cpp:19: /usr/include/boost/python/detail/wrap_python.hpp:50:23: fatal error: pyconfig.h: No such file or directory # include <pyconfig.h> # include <python3.2/pyconfig.h> #include <patchlevel.h> #include <python3.2/patchlevel.h> # include <Python.h> # include <python3.2/Python.h> apt-get install python3.2-dev make make[1]: Entering directory `/usr/src/justniffer/src' /bin/bash ../libtool --tag=CXX --mode=link g++ -g -O2 -o justniffer justniffer-main.o justniffer-formatter.o justniffer-utilities.o justniffer-regex.o justniffer-prog_read_file.o -L../lib/libnids-1.21_patched/src -lnids2 -lpcap -lboost_regex-mt -lboost_program_options-mt -l libtool: link: g++ -g -O2 -o justniffer justniffer-main.o justniffer-formatter.o justniffer-utilities.o justniffer-regex.o justniffer-prog_read_file.o -L../lib/libnids-1.21_patched/src -lnids2 -lpcap -lboost_regex-mt -lboost_program_options-mt -l g++: error: missing argument to '-l' make[1]: *** [justniffer] Error 1 make[1]: Leaving directory `/usr/src/justniffer/src' make: *** [all-recursive] Error 1 PYTHON_LIB = python3.2mu make make install cd /home/pi git clone git://github.com/onotelli/justniffer cd justniffer apt-get install libboost-iostreams1.49 libboost-iostreams1.49-dev libboost-program-options1.49.0 libboost-program-options1.49-dev libpcap0.8-dev apt-get install automake ./configure...failed on config.sub symlinked to automake 1.14, replaced with 1.11:
rm config.sub config.guess;ln -s /usr/share/automake-1.11/config.sub .;ln -s /usr/share/automake-1.11/config.guess . ./configure make CDPATH="${ZSH_VERSION+.}:" && cd . && aclocal-1.14 /bin/bash: aclocal-1.14: command not found Makefile:409: recipe for target 'aclocal.m4' failed make: *** [aclocal.m4] Error 127 configure.ac:54: error: possibly undefined macro: AC_PROG_LIBTOOL apt-get install libtool make...so for now just intercept the comm and analyze it elsewhere...
tcpdump -w /tmp/file.cap -s0 port 5000...and let's continue...
./configure: line 5435: AC_PROG_LIBTOOL: command not found cd .. rm -rvf justniffer git clone git://github.com/onotelli/justniffer cd justniffer rm config.sub config.guess;ln -s /usr/share/automake-1.11/config.sub .;ln -s /usr/share/automake-1.11/config.guess . ./configure...and, we're successful, so...
make make installGET /api/plugin/status_line ==> {"status_line": "OctoPrint connected"}
GET /plugin/printhistory/history ==> {"history": {"0": {"filamentLength": 2004.615320000079, "filamentVolume": 4.821664896354753, "fileName": "RaspiB1frame.gcode", "note": ""}, "1446143472159": {"filamentLength"...
GET /api/timelapse ==> {"config": {"type": "off"}, "files": []}
GET /plugin/softwareupdate/check ==> {"information": {"customcontrol": {"check": {"current": "0.2.1", "displayName": "Custom Control Editor Plugin", "displayVersion": "0.2.1", "pip": "https://git..."
GET /api/logs ==> {"files": [{"date": 1446710839, "name": "octoprint.log", "refs":...
GET /api/plugin/pluginmanager ==> {"octoprint": "1.2.7", "os": "linux", "pip": {"additional_args": null, "available": true, "command": "/home/pi/OctoPrint/venv/bin/pip", "use_sudo": false, "version": "1.1"},...
POST /api/files/local/KosselXL-tubeholder.gcode
GET /api/printer/command/custom ==> {"controls": [{"children": [{"command": "M106 S%(speed)s", "input": [{"default": 255, "name": "Speed (0-255)", "parameter": "speed"}], "name": "Enable Fan", "type": "parametric_command"}, {"command": "M107", "name": "Disable Fan", "type": "command"}], "name": "Fan", "type": "section"}, {"children": [{"command": "M114", "key": "94e9bd395ef599fbe33e42c344ae9ced", "name": "Get Position", "regex": "X:([0-9.]+) Y:([0-9.]+) Z:([0-9.]+) E:([0-9.]+)", "template": "Position: X={0}, Y={1}, Z={2}, E={3}", "template_key": "5d54d9c91f6e9cf73978708bfa400d3c", "type": "feedback_command"}], "name": "Reporting", "type": "section"}]}
GET /api/settings ==> {"api": {"allowCrossOrigin": false, "enabled": true, "key":...
GET /api/printerprofiles ==> {"profiles": {"_default": {"axes": {"e": {"inverted": false, "speed": 300}, "x": ...
GET /sockjs/213/_3zjc4ry/websocket HTTP/1.1 Host: 10.0.0.110:5000 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache Upgrade: websocket Origin: http://10.0.0.110:5000 Sec-WebSocket-Version: 13 DNT: 1 User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.80 Safari/537.36 Accept-Encoding: gzip, deflate, sdch Accept-Language: en-US,en;q=0.8,cs;q=0.6,sk;q=0.4,fi;q=0.2,it;q=0.2,ru;q=0.2 Cookie: session=.eJyrVorPTFGyqlZSSFKyUvJ1ca2MDPct9zUKyvHLci2PyvU18s31rfALCTX2M_I1jArxyvFzcTSICg-1VarVUcpMSc0rySyp1EssLcmIL6ksSFWyyivNyUGSQTI9yiOsJCkiG6izFgDnTSbT.CRyisQ.mlVLY d27OMDgk127y171dY_VE6c Sec-WebSocket-Key: TA37E8MJqIDd6SrbQjLjZQ== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: xp/dciJo2gSfFoK5itfcmvRK1SU=
<81>^Ao<81>~^@a[{"connected":{"display_version":"1.2.7 (master branch)","apikey":"D567207981A64C368074EC43E9117E95","version":"1.2.7","branch":"master","plugin_hash":"3d63630e210bb671f2dc2e8e16fd0a1d"}}]<81>~7^Da[{"history":{"logs":["Connecting to: /dev/3dprinter","Changing monitoring state from 'Offline' to 'Opening serial port'","Connected to: Serial (port='/dev/3dprinter', baudrate=250000, bytesize=8, parity='N', stopbits=1, timeout=10.0, xonxoff=False, rtscts=False, dsrdtr=False), starting monitor","Changing monitoring state from 'Opening serial port' to 'Connecting'","Send: M110"
The octoprint user interface uses the websocket protocol. So tools for connecting to those are needed.
There are several, the wssh one was chosen as it does not rely on a monstrous framework like node.js
nor it does require some obscure language like go.
git clone git://github.com/progrium/wssh cd wssh python setup.py install...and it fails on gcc not finding event.h, so we used...
apt-file find include/event.h apt-get install libevent-dev python setup.py install Searching for ws4py==0.2.4 Reading https://pypi.python.org/simple/ws4py/ Reading http://www.defuze.org/oss/ws4py/ Reading https://github.com/Lawouach/WebSocket-for-Python Reading https://pypi.python.org/pypi/ws4py No local packages or download links found for ws4py==0.2.4 error: Could not find suitable distribution for Requirement.parse('ws4py==0.2.4') pip install ws4py install_requires=['ws4py==0.2.4','gevent==0.13.6'], install_requires=['ws4py==0.3.4','gevent==0.13.6'], Traceback (most recent call last): File "/usr/local/bin/wssh", line 9, in <module> load_entry_point('wssh==0.1.0', 'console_scripts', 'wssh')() File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 558, in load_entry_point return get_distribution(dist).load_entry_point(group, name) File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2682, in load_entry_point return ep.load() File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2355, in load return self.resolve() File "/usr/local/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 2361, in resolve module = __import__(self.module_name, fromlist=['__name__'], level=0) File "build/bdist.linux-armv6l/egg/wssh/__init__.py", line 9, in <module> File "build/bdist.linux-armv6l/egg/wssh/server.py", line 6, in <module> ImportError: cannot import name UpgradableWSGIHandler...which is because that bloody ws4pi requiring the 0.2.4 version. fuck!
...so,
apt-get install python-ws4py=0.2.4 Reading package lists... Done Building dependency tree Reading state information... Done E: Version '0.2.4' for 'python-ws4py' was not found...no dice.
...so let's pip it right from the git, using the painfully found @version trick...
pip install git+git://github.com/Lawouach/WebSocket-for-Python/@v0.2.4 python setup.py install apt-get install libevent-dev pip install git+git://github.com/Lawouach/WebSocket-for-Python/@v0.2.4 git clone git://github.com/progrium/wssh cd wssh python setup.py installso, run on two machines:
wssh -l 0.0.0.0:8888/websocket wssh -v octo:8888/websocketNow, how to connect to the octoprint...
wssh 127.0.0.1:5000/sockjs/x/y/websocketSystem section in /home/pi/.octoprint/config.yaml:
system:
actions:
- action: stream
command: /home/pi/scripts/raspi_streamer start
confirm: false
name: Start video stream 320x240
- action: streamvga
command: /home/pi/scripts/raspi_streamer start VGA
confirm: false
name: Start video stream 640x480
- action: streamoff
command: /home/pi/scripts/raspi_streamer stop
confirm: false
name: Stop video stream
- action: divider
- action: "on"
command: /home/pi/scripts/gpio/atx_on.sh
confirm: false
name: Power ON the printer
- action: "off"
command: /home/pi/scripts/gpio/atx_off.sh
confirm: Power off the printer - are you sure?
name: Power OFF the printer
- action: divider
- action: reset
command: /home/pi/scripts/ardureset
confirm: Are you sure you want to reset the controller?
name: Reset controller board
"on" and "off" have to be quoted, otherwise yaml parser converts them to true and false.
events: enabled: true subscriptions: - command: echo "OctoPrint disconnected" > /dev/3dprinter event: Disconnected type: system - command: - M117 OctoPrint connected event: Connected type: gcode - command: - M117 Upload:{file} event: Upload type: gcode - command: - M117 do:{filename} event: FileSelected type: gcode - command: - M117 Start:{filename} event: PrintStarted type: gcode - command: - M117 FAIL:{filename} event: PrintFailed type: gcode - command: - M117 Printing finished! event: PrintDone type: gcode - command: - M117 Cancelled event: PrintCancelled type: gcode - command: - M117 --PAUSED-- event: PrintPaused type: gcode - command: - M117 Resumed:{filename} event: PrintResumed type: gcode - command: - M117 --Waiting-- event: Waiting type: gcode