středa 9. března 2016

Remote web monitoring of 3D printers through Pronterface

I have recently dug into Pronterface code and realized that there is simple RPC server built-in. It listens on localhost and it's really cool feature for remote monitoring, so I hacked KISS (Keep It Simple and Stupid) PHP code that allows querying the RPC server through the web. The code can query multiple running Pronterfaces and it's no problem to monitor multiple 3D printers which are connected to the same host. Running instances of Pronterface are automatically detected. It also queries all connected V4L compatible webcameras, which means that you can check progress of printers visually. With the current code you can check temperatures (bed, extruder), Z position, status of the current print task including task/file name, ETA, finished percentage.

The code with instructions is available from github: Feel free to pull request patches.

pátek 18. září 2015

How to get Chinese 2.4 TFT LCD ILI9341 based Arduino Uno shield working

These Chinese Arduino Uno TFT LCD shields are neat and very cheap, so I couldn't resist and got one from Banggood. As with nearly everything Chinese, there are several versions and revisions around and it's usually surprise which one you will recieve. It seems my shield came with ILI9341 controller although there is written ILI9340 on the board (I didn't disassemble it, but I assume it according to the shield behaviour). I tried to get it working with Adafruit TFTLCD-Library, but it ended with "Unknown LCD driver chip: C0C0" and white screen. So I dug a bit deep into this problem. It quickly turned out that the chip needs a bit longer delay for reset to start responding. For my shield it seems that additional 5 milliseconds are enough. Then it correctly identified itself as ILI9341. But it still didn't display anything, there was only the whitescreen.

I read both ILI9340 and ILI9341 datasheets and found out that my chip has extended registers which are not handled by the original code. I verified content of these registers with the datasheet and it revealed that the "Pump ratio control" register is set to 0x0 after the reset. According to the datasheet this is 'reserved' value and after the reset the content of this register should be set to 0x20 (which means 2xVCI). Maybe my chip revision is newer than my datasheet or maybe this is some HW glitch but this again validated the basic rule known to embedded developers: "never ever rely on the default values after the reset". So I added initialization for the extended registers. I also improved chip select (CS) handling in the code which allows sharing of the data ports with other peripherals. I did some other minor improvements and bug fixes to the code. All of the changes should be harmless to older HW. Even the initialization of the extended registers should work on chips without extended registers, because according to the datasheet, such initialization should be handled as NOP commands. I pull requested the changes to Adafruit, there is the direct link to the related commit. It seems the shield has different orientation of the display than the Adafruit library expects, thus you need to uncomment #define ILI9341_MIRROR_X 1 and comment #define ILI9341_MIRROR_Y 1 in Adafruit_TFTLCD.h to fix the orientation.

Regarding the touchscreen it's classic 4 wire resistive digitizer which can be handled by e.g. Adafruit TouchScreen library. The only thing that you need to setup is which pins the touchscreen is connected to. Unfortunately it is not written on the kit, but it's possible to locate the connections visually and with the multimeter. The wiring of my shield is following:


Unfortunately my shield came with broken electrode, so my touchscreen didn't work, but I checked the correct functionality of the code on my friend's shield. I was refunded by Banggood without problems, so I ordered another shield and will keep this broken shield for projects that do not require touchscreen. You can see the detail of the broken electrode here:

There is picture of the working shield kindly lent me by my friend:

I downloaded the code for this simple painting application somewhere on the internet and modified it to work with my shield. The modified code is available for download. There was no licensing information in the original code, so hopefully the license status of this code is OK (free/public domain). If not, please let me know. In the application you can draw by your stylus/finger, select colors on the side and clear the display by tapping on the opposite display side.

Update 2015/10/07
I received replacement display and the shipment was pretty fast. This time there is written ILI9341 on the PCB. It again proved that the development runs pretty fast in China and they usually finish new iteration sooner than you receive your previous order. The display works correctly now. But it seems the digitizer X/Y pins are reversed in comparison with the previous display. I am not sure whether it is wanted feature of the new PCB or bug, but it doesn't matter. The digitizer wiring is now following:


středa 15. července 2015

Fix Internet Explorer dowloading .EXE files as _EXE

I encountered it on Windows 8.1 Pro 64 bit, but the following observations may apply to other versions as well. It seems to be quite common issue, but I wasn't able to find any resolution for it on the Internet not counting disabling of the IE Protected Mode (PM) or creation of new user profile. Disabling of the PM is not good way to go, because it needlessly increases number of potential attack vectors. Creation of new user profile is easy fix for single user, but pain in case there are dozens user accounts facing this issue. That's why I dug deeper into it.

I quickly realised that this problem is mostly faced by users whose profile have been moved/copied to different drive. At first I compared registry dumps for user not facing the problem (let's call her/him "good user") and user facing the problem (let's call her/him "bad user"). Initially I thought that this obviously over-engineered PM feature stores drives UUIDs in registry hives, but the comparison of registry hives didn't reveal anything supporting this assumption.

Next I moved to Process Monitor to observe what's going there. I noticed a lot of "access denied" return codes from the CreateFile calls, all of them ending somewhere in the PM InetCache under %LOCALAPPDATA%\Packages\windows_ie_ac_001\AC. This also caused a bit delay when the download was initiated. Then after some delay, the Internet Explorer showed dialog box that it cannot download the file. If "retry" button was clicked, it used some different, probably backup directory and the file was saved with _exe suffix instead of .exe.

I checked ACL of the InetCache path, but it seemed OK. Even so I tried to give full access to everyone for this directory and sub-directories (it is generally not good idea, but I wonder what will happen). But it didn't help. Really strange, so I tried comparing ACLs of "good user" with "bad user". It revealed that there is SID of otherwise non-existent user S-1-15-2-1430448594-2639229838-973813799-439329657-1197984847-4069167804-1277922394 with full access rights on the path. I always enjoy such hacks :). I used the following command to fix the problem (I ran it multiple times with %LOCALAPPDATA% replaced by the user LOCALAPPDATA path, e.g. C:\users\user1\AppData\Local):

icacls %LOCALAPPDATA%\Packages\windows_ie_ac_001\AC /grant
"*S-1-15-2-1430448594-2639229838-973813799-439329657-1197984847-4069167804-1277922394":(OI)(CI)F /c

Unfortunately there still persisted some user accounts that weren't fixed by this command. I rechecked one such account with the Process Monitor and it revealed that Internet Explorer created its InetCache on virtualised path which broke the PM. It seems that for correct PM function it's not enough if Users group or the group user is member of have full access to user profile, but it requires the user to be explicitly listed on the ACL of the profile directory and it's subdirectories. So I finally used the following command to fix the rest of affected user accounts (again ran multiple times):

icacls %USERPROFILE% /grant %USERNAME%:(OI)(CI)F /c /t

Later I realized that in my case the problem was probably caused by relocation script used for moving of user profiles. This script called robocopy command without the /copyall parameter. But there can be probably more sources of this problem (e.g. filesystem / ACL corruption caused by machine crash or installation of buggy drivers/SW, etc.).

pátek 29. srpna 2014

Firefox: Re-enable prompt asking you whether you want to save your tabs on exit

Firefox usually asks whether you want to save your tabs on exit if you have browser.showQuitWarning = true in your about:config. If you check "Do not ask next time" it will not ask you again. The question is how to re-enable this prompt. You already set the following:

browser.showQuitWarning = true
browser.tabs.warnOnClose = true
browser.tabs.warnOnCloseOtherTabs = true
browser.warnOnQuit = true

But it still doesn't show the prompt. The corresponding setting is hidden behind Just locate it in about:config, right click on it and select "Reset". Restart Firefox and viola, the prompt is back. You can also re-enable this through the UI, go to "Edit -> Preferences -> General -> When Firefox starts" and change "Show my windows and tabs from last time" to "Show my home page" or "Show a blank page". A bit illogical on the first sight, but it works. This was tested on Firefox 31.0.

pondělí 1. července 2013

HW mod: Increase USB power on Raspberry Pi early rev. 1 boards

The early Raspberry PI (RPI) boards had polyfuses on the USB ports. They are electronic resettable 140 mA fuses. The problem is that they do not have zero ohm resistance. This means that by increasing the power drawn from the USB port the voltage drop across the polyfuse increases. By drawing approx. 100 mA and more from the USB port the voltage drops bellow the value allowed by the USB specification and the connected USB devices may behave incorrectly. I encountered this when I was backporting the R820T tuner driver to the kernel 3.9 (needed for some RTL2832 based DVB-T dongles). Some of the DVB-T cards I had worked OK, some exhibited random failures during I2C writes to the R820T registers which resulted in occasional kernel panics.

You can workaround this by using a USB powered hub or you can fix the RPI PCB. The fix is simple - just bypass the F1 and F2 polyfuses. This fix is already implemented on the later rev. 1 and rev. 2 boards, so the later boards don't exhibit this problem. You can remove the polyfuses and short the pins, but an easier approach is to leave the polyfuses on the PCB and just short them out by wire or just by tin. You will still have the protection from the main F3 polyfuse (0.7 A). The other advantage of this mod is that it will allow you to power the RPI from the USB hubs / devices that provide power upstream.

The F1 and F2 polyfuses are green (at least on my RPI boards) and are located near the status LEDs. This modification is applicable only to the early rev. 1 boards. They probably have the HW revision code 2 or less. You can get the HW revision code by running:

cat /proc/cpuinfo

If your HW revision code is 3 or above this problem is already fixed on your board.

pátek 14. června 2013

Use Windows screensavers in Linux for screen locking

This arise from the discussion with one person who we tried to migrate to Linux. Her argument was that she would miss the Bubble screensaver :). No doubt, the new D3D Windows screensavers are cool and especially for the Bubbles screensaver there is currently no Linux counterpart. But the argument doesn't stand, here is the quick and dirty solution - the Wine:

  • Copy the screensaver, e.g. for the bubble screensaver copy the \Windows\System32\Bubbles.scr to the /opt/screensavers/ directory (or elsewhere).
  • Install the xlockmore package
  • Run the screensaver by:
    xlock -mode blank -geometry 0x0 \
    -startCmd "wine /opt/screensavers/Bubbles.scr /s"

The trick is to instruct the xlock to blank the screen area consisting of zero number of pixels, so the display is let unmodified for the screensaver. This was tested on the Fedora 18 and Xfce and worked OK. If you need to configure the screensaver, you can run it with the /c parameter. Unfortunately the Bubbles screensaver doesn't have implemented the configuration dialog and the command will fail, but there are still some hidden settings you can alter through the registry. I focused only on the technical side of the problem, not the legal one, but I think it shouldn't be problem in case there is valid Windows license for the machine (e.g. machine with dual-boot).

neděle 7. dubna 2013

Tip: using oath-toolkit for HOTP/TOTP authentication

I packaged oath-toolkit for Fedora and it is currently submitted for the merge review. The toolkit provides oathtool which can be used as a generator for HOTP/TOTP (e.g. to authenticate against LinOTP). Usage is very simple, for HOTP:
$ oathtool -c COUNTER SEED
And for TOTP:
$ oathtool --totp SEED
The package also provides library and header files and more complex applications/GUIs can be easily based on it. There is also PAM module included that allows you to use your HOTP/TOTP HW/SW token for authentication against your machines (e.g. sshd). To enable it for sshd add the following line to the top of your /etc/pam.d/sshd:
auth sufficient usersfile=/etc/users.oath window=20 digits=6
This will setup the SSH for 6 digits HOTP/TOTP and will check through the 20 values (the tolerance). Then create the /etc/users.oath file and add there a list of allowed users together with their prefix passwords (PINs) and seeds, e.g.:
HOTP/T30 root pw 00
HOTP user1 - 01
In the example above, the user root is configured for 30 seconds TOTP with the prefix password (PIN) pw and seed 00, the user user1 has no prefix password and uses the seed 01. As the file contains seeds and plain text PINs, do not forget to chown it to root:root and chmod it to 600. For correct function the "UsePAM yes" and "PasswordAuthentication yes" also needs to be specified in your /etc/ssh/sshd_config. Currently it may not work correctly with the SELinux (for details see the merge review).