torstai 7. tammikuuta 2021

Touch sensing for Arduino

I made a small christmas project (from which I might make a post later) in which I ended up using an Arduino Pro Micro (or rather a clone, Open-Smart Pro Micro). I also wanted to have two capacitive touch sensors to set brightness of a light, but the Atmega32U4 in that Arduino board does not have touch sensing circuitry build in.

I know that it is possible to still implement a capacitive touch sensing using the built-in I/O ports so I tested some methods and write about my experience here. I ended up using a method I haven't seen around so I will also explain that and link to the code.

Concept 1

The first concept is what is built-in (or at least easily installed) as a library in the Arduino IDE. The library is called CapacitiveSensor and is rather easy to use. One sensor needs two I/O pins and a large value resistor, in addition to the sensor itself (which can be a piece of aluminium foil, for example).

The basic connection is according to figure below. The left side shows circuitry internal to the microcontroller.

 

The touch sensor is connected to one I/O pin (the "drive" pin) via a resistor, which is typically mega ohm or tens of mega ohms. The sensor is also directly connected to another I/O pin (the "sense" pin).

The operation is depicted in following figure.

The drive pin on the top is configured as an output. The sense pin on the bottom is configured as an input, without pull-up resistor. With this circuit, the touch is sensed based on the time constant of the resistor and the capacitor formed by the touch pad and possibly the finger. Touching the sensor increases the capacitance to the circuit ground, which increases the time constant and that can be sensed. The operation of the circuit is as follows:

  • The drive pin is set to output a high level (red line)
  • The sense pin (blue line) is read until the pin status changes to indicate a high level in input
  • Timer is started (or current time is read)
  • The drive pin is set to output a low level (green line)
  • The sense pin (blue line) is read until the pin status changes to indicate a low level in input
  • Timer is stopped (or current time is read)
  • The time between the input state transitions is calculated

It is recommended to read the time from high-to-low and from low-to-high and calculate the average to increase the robustness of the circuit.

By monitoring the time between state transitions a change can be detected which indicates that the sensor is touched or touch is removed. At least in theory. In my tests, the sensitivity was very poor and it was difficult to detect touch robustly. Especially if any other electrical equipment was close to the sensor. I tried to add some grounded (to the circuit ground) plates near the sensor but that did not help at all.

Concept 2

This concept is very similar to the previous one but might allow getting rid of the external resistor and would use only one I/O pin per sensor. This could be achieved using the internal pull-up resistor of the microcontroller, according to figure below.

 Again, the internal parts are on the left. Rpu is the internal pull-up resistor, value of which is 20...50 kOhm in the Atmega32u40 (so quite small). The basic idea of this circuit is the same as previous one, but implementation would be a bit different.

  • Configure the I/O pin as output and drive it low to discharge the touch pad capacitance (green line)
  • After a (short) delay, start the timer
  • Configure the pin as input with pull-up resistor (red line)
  • Read the state of the input pin until it indicates a high level in input (blue line)
  • Stop the timer and calculate the time it took to charge the touch pad capacitance

I did  not try this, and the pull-up resistor value might be too low to make this circuit feasible (i.e. the time to charge the capacitance would be too short to measure accurately). It would be quite easy to test though, maybe some day...

Concept 3

The third concept I tested was something I came up with from reading how the real touch sensor chips work. I have not seen this concept used with Arduino, but I might be wrong. It uses only one pin per sensor and only needs the sensor connected to the pad. I didn't test the concept with single sensor, but at least with two it works well and probably is easy to expand to more sensors. One downside is that the sensors must be connected to analog input pins.

The concept looks like this:

The left side shows again the microcontroller internals, and this time I drew also the analog input sample and hold capacitor Csh, which is 14 pF in Atmega32U4 and the sampling resistor which is 1...100 kOhm (and is not important). I also drew the parasitic capacitance between the two touch sensors, value of which changes when a finger is brought close to the sensors.

The operation can be explained as follows when reading the upper touch sensor:

  • The lower (other) sensor pin is configured as output and driven low (green line)
  • The measurement pin (upper) is configured as output and driven high (red line). This charges the touch pad capacitance to the supply voltage level
  • The measurement pin (upper) is changed to analog input and read. This triggers the sample-and-hold circuit which charges the capacitor (blue line) and then reads it value with the ADC (orange line)
  • A change in the analog value read indicates whether the touch pad is touched or not (higher value means touch)

The key here is that the sample-and-hold capacitor is 14 pF and the touch sensor capacitance is typically in the same range, maybe tens of pF. When the touch pad is first charged to the supply voltage level and then the analog circuitry is connected, the charge in the touch pad capacitance is divided between the touch pad and the sample-and-hold capacitor. This means that the voltage is also divided in the ratio of the capacitances. Touching the sensor increases the capacitance of the sensor, which means the voltage that is sampled will be higher.

Driving the other sensor low also increases the sensitivity, as there will be capacitance between the sensor measured and the other sensor, especially when the sensor is touched. I tried driving the other sensor high also, but driving it low gives the best result.

I uploaded the code for this sensor stuff to GitHub here. Feel free to try it out and comment if there is something to improve.

Here is also a picture of the method in operation. In the figure below the green line is the raw ADC value (sensor is read 20 times with 1 ms in between to get rid of 50 Hz mains hum, and the values are summed together), blue is low-pass filtered signal and red is the threshold value where the low-pass filtered value is compared.

There are 4 touch events where the signal goes significantly higher than the base line. There is roughly 20 % increase in the reading when the sensor is touched and when it is not, and there was a thick (several millimeters) insulator between my finger and the sensor.

Conclusion

I ended up using this ADC based capacitive divider method which might be something not used before with Arduino. I got very good results with it so I want to share it to others to test and improve upon. Maybe it helps people to create even better projects :)
 






lauantai 12. syyskuuta 2020

Salora Äänimerkkilaite for VR

Some years ago a neighbour of mine got his hands on a little box, which was marked "Salora Oy Äänimerkkilaite" and it had something to do with old VR trains (VR is a Finnish railway company). His relative has a thing for trains, so he thought that the device might make a good present for him, so he asked me to check what the device does, does it work and would it be possible to turn it into a present.

I'm writing this post because I thought this might be of interest for other train hobbyists also.


Background

The device was a little black box with text "Salora Oy", "Äänimerkkilaite" (sound signaling device) and a serial number. On one end there was several pins for connection to some kind of backplane. In a figure below, the device is shown together with my wires connected to some pins.

 


Luckily, the device came with a paper which had the schematic and layout, so there was no need to reverse-engineer the device! From the schematic, it was obvious what the device was and how to operate it. Only thing left was to verify whether it works or not.

 

The device is a sound generator, which creates a familiar "ping-pong-ping" sound which can be heard before announcements are made from the train's loudspeakers. The device only consists of three oscillators creating the tones, a trigger circuit, and an summing amplifier to produce the output signal. Everything is analog. There is also an internal 8.2 V regulator for power supply;  the device is intended to run from 15 V DC.

 

Operation

Here I'll explain the device's operation with annotated schematic. I did this in LTspice, and all the component values are not the same as in the real device to keep simulation time short. For example, some time constants are much shorter in this version.



First, the blocks circled with green are the oscillators. According to the paper schematic, the desired frequencies are, from top to bottom, 659 Hz, 523 Hz and 784 Hz. All the blocks have a trimmer resistor which can be used to fine-tune the frequency. Output of each block is a square wave with the desired frqeuency, going from 0 V to 8.2 V.

 

The device is triggered with trigger circuits marked with blue squares. Each channel has its own trigger with an RC delay on the left, then two inverters with a hysteresis resistor. Whenever the input goes high, the inverters create a clean rising edge, and input going low, the output also goes low. The trigger circuits are chained so that top one triggers first, and then starts charging the RC delay of the middle one, which finally starts to charge the RC circuit of the last one. The time constant of the delay is roughly one second.

 

The first, topmost, trigger circuit is triggered from one of the input pins through a 1 k resistor, yellow block. Whenever the signal should not sound, the pin is pulled down. When the pin floats, the trigger circuits operate and a sound is played.

 

The red blocks are high-pass circuits which create a short, exponentially decaying pulse. The pulse goes high when the device is triggered, and the decays to 0 V with about 1 second time constant.

 

The exponentially decaying pulse is used as the volume signal for each oscillator. Exponentially decaying waveform gives a bell like sound. The "mixing" is done with two diodes, marked with purple squares.

 When the output pulse from the high-pass filter, red squre, is positive, one of the diodes in the mixed (purple square) conducts. When the oscillator (green) is low, it is the diode to the left which conducts and no current flows from the mixer to the output. When the oscillator is high, the left side diode is blocking and current flows through the right side diode. The current amplitude depends on the exponentially decaying voltage of the high pass filter (red). I think this is quite an elegant solution.


The rest of the circuit is just filtering of the square wave outputs of the oscillators and mixing them together with an audio amplifier. Finally, the sum of each oscillator is passed through a DC-blocking capacitor and a potentiometer for setting the volume. This is shown with brown square.

 

Checking the operation

Now that I knew what the device does, it was time to verify whether it works or not. I attached a laboratory power supply to the power pins, a pushbutton between the trigger and ground and using oscilloscope I probed the oscillators, trigger signals etc., and finally, as everything looked ok, also the output. I saved the output waveform as csv, and on my computer I converted it to wav, and it sounds like this.

 

As the device seemed to work, I added some circuitry around it. First, because my pushbutton was a normally open, I needed to do a simple transistor inverter for it. This way, when the button is pressed, the trigger is let float and otherwise the trigger input is pulled down by the transistor.

Second, I added a mono audio amplifier circuit and a speaker. The amplifier was very simple, needing only minimal amount of components around it. I think the amplifier was LM386, high voltage version, in DIP-8 case.

Third, I added a DC jack so that I could use an old laptop power brick, outputing 15 V to power the circuit. Here is a picture of the final working device.



Finished device

My neighbor did a nice case for the device, so that he could give it away as a gift. Here is a video showing the case and operation of the device.




 

perjantai 10. huhtikuuta 2020

Installing linux on Asus TF101

Years ago I bought myself an Asus Eee Pad Transformer TF101, which is an Android tablet with an (optional) keyboard dock. In the keyboard dock there is additional battery and two USB ports. I bought it as I- thought it could be used as a replacement for a laptop, but it turned out that Android is not very suitable for that. I never had any good use for the tablet..

Many years ago I rooted the tablet and installed a custom, newer Android ROM made by Timduru. It was nice, but still I didn't find much use for the tablet.

Some weeks ago I found out, that it is possible to install Linux on the tablet. It had been possible for many years already, and significant development had happened until 2016 or so. So I decided to go for it, and it turns out, the process was very easy with the already-rooted tablet!

In this post I present the process I used since the guides were scattered around multiple posts.

Sources

Main sources for the process were following:
  1. [Linux] [IMG] [Dev] [WIP] *Ubuntu images for Rootbind [TF101 / TF101G]
  2. [KERNEL/MOD] [LINUX] [Rootbind] [Native EMMC/all TF101&TF101G/fast/tested] [2-Jul-13]
  3. [GUIDE][Dual Boot][TheEasyway] How to setup Linux RootBind Method [Updated May 16th]

Preparation

To prepare for the installation, one needs an empty micro-SD card, at least some 2 GB or so. It is necessary to download to the SD card (root) following files:
  • tf101-14.04-Lubuntu-Tegra-armaf.tar.gz from the first source link and
  • Ubuntu-3.1.10-12-rootbind-oc1.2GHz.zip from the second source link
it may not be necessary, but I also downloaded
  • modules-3.1.10-12.tar.gz from the second link 
Note that in the first link there is also other distributions that can be used. I assume their installation is similar, but I used the lubuntu one.

Also in the second link there is different kernels. I understood that the difference is that 1.0GHz is the standard processor speed, while 1.2GHz is a bit overclocked and 1.5GHz is rather high overclock. I used the slightly overclocked 1.2 GHz version.

Make sure you have latest TWRP recovery on the tablet. It is needed to flash the kernel. You also need SuperSU or similar and a terminal emulator.

Installing the distribution

When all the necessary files are downloaded (or installed), it is time to uncompress the linux distribution. With these versions, they can reside side by side with Android, so it is possible to have both installed and run either one by just flashing the correct kernel.

In Android terminal run the following commands to uncompress the Linux distribution to /data/linuxroot: 
su

mkdir -p /data/linuxroot
busybox chmod 755 /data/linuxroot
cd /data/linuxroot
tar -xpjf /storade/6E20-1C26/lubuntu-14.04.tar.bz2
the external micro-SD card where I put all the files was in the path /storage/6E20-1C26/ so that needs to be changed to match where the SD-card is located.

It may be also necessary to copy the necessary kernel modules, at least for some kernel versions:
cd /data/linuxroot/lib/modules
tar -xzf /storage/6E20-1C26/modules-3.1.10-12.tar.gz
That is all for now, next is time to install the kernel.

Installing the kernel

To install the kernel, it is necessary to reboot to the recovery with the external micro-SD card still installed.

In the recovery, select Install. From the menu select SD card as the source directory, and then select the kernel zip file, Ubuntu-3.1.10-12-rootbind-oc1.2GHz.zip. Confirm flashing the image by swiping right.

After a moment the flash process is done and it is time to reboot the system.

Booting

After reboot, there was quite a long time with black screen, and then...

Two penguins! This is promising... waiting a bit more...

Linux boot messages! And no errors so far! And finally login screen! From the top right menu (after a few clicks) it was possible to get the on-screen keyboard.

Easy! The installation was a success on the first try!

Issues


There are several issues, some of which can be fixed and some do not at the moment seem to have a fix.
  • The tablet cannot be booted with the dock connected. Remove the dock before turning the tablet on!
  • Do not run apt-get update && apt-get upgrade. It seems to break something and the system no longer boots. Upgrade only the necessary packages.
  • Sometimes the mouse/GTK would hang if moving/resizing a window. It seemed to be fixed by upgrading anything libgtk-2.0 and libgtk-3.0 related (~6 packages or so).
  • Network-manager (wifi) icon is broken, fix is to re-install icon themes, as described here.
  • Lock-key in the upper right corner can be made to be delete key by adding /usr/sbin/mapdeletekey to startup applications.

Dock battery issue

There is a quite major issue with the keyboard and touchpad stopping working if dock battery goes low. My tablet had broken battery which I removed (and later installed a new one) so the dock could never be used. The issue seems to be related to the system reading the battery status, and it starts to spam the (i2c?) bus which also has keyboard and touchpad.

I found a workaround which seems to work somewhat well. The key is to remove anything that tries to read the battery status. I've not encountered the issue since doing following:

  • Remove lxde4-power-manager and upower: sudo apt-get remove upower lxde4-power-manager
  • Remove  anything battery related from conky (or disable conky altogether) by editing ~/.conkyrc
If and when you still want a battery gauge, use my version of batterymon-clone. It is necessary to force usage of battery capacity and prevent reading "present" status to work around the bugs:
batterymon --use-capacity --no-present
 I also like to have separate gauges for tablet and dock batteries, which can be achieved by running
batterymon --use-capacity --no-present --show-all --no-total
I recommend adding one of those commands to startup applications.

For some background, I noticed that the issues with the dock installed start to appear if one reads either "energy" or "charge" values of EITHER the dock battery or the tablet battery. Reading the capacity (and status) seems to work just fine. So I think the bug is related to those variables, and so it is necessary to prevent (remove) all programs that might read those values and use only ones that use the capacity.

Lid close fix

When Upower is removed, the fixlidclose.py in the original lubuntu package stops working. For a workaround, I made another set of scripts to achieve the same functionality. The scrips can be found from my github repository. From the repository, it is necessary to copy both python scripts to /usr/local/bin/. Then add
python /usr/local/bin/tf101monitor.py &
to /etc/rc.local before the exit statement to launch the script at boot. Also it is necessary to create /etc/dbus-1/system.d/tf101.conf with following content:

   <busconfig>
        <policy user="root">
            <allow own="org.tf101" />
        </policy>
        <policy group="tf101">
            <allow send_destination="org.tf101" />
        </policy>
    </busconfig>

which allows the script to run. Then just add /usr/local/bin/fixlidclose.py to startup applications list.

There still seems to be a bug, at least with updated xorg and its drivers, that the screen stays blach when the lid is opened. Picture comes back on by pressing ctrl+alt+f1 (which opens a text console) and the ctrl+alt+f7 (to go back to graphical console). Alt key is the magnifying glass key, and f1 to f7 are in the top row (bluetooth toggle etc buttons). I have an idea on how to work around this and will update the script if it works.


keskiviikko 1. tammikuuta 2020

Using Raspberry PI zero W as an USB wlan adapter

Background

My desktop computer is located so that it is difficult to route an ethernet cable cleanly to my modem. To have an internet connection I have tried several usb wlan adapters as well as phone tethering.

Earlier I used a Netgear one, it might have been a WNA3100 (N300), which somewhat worked with ndiswrapper. I think it had poor throughput and occasionally dropped the connection.

Some time ago I bought an Asus USB-N10 nano which claimed to have Linux support (Linux was written on the box). It didn't really work properly; there was a driver for an old kernel version and the new kernel had some kind of support built in. Depending on the driver I tried, either I did not even see my network, could not connect (authentication failed) or the connection dropped very often.

In the end I compiled the experimental version of rtl8xxxu which worked the best. The connection was rather stable, but the throughput was very poor, only 1 Mbps. My laptop can easily get over 40 Mbps...

Best results I got by using my mobile phone (connected to the wifi) and enabling usb tethering. However that has its own issues. First, I cannot use my phone anywhere else while it is sharing the connection and second, it is necessary to turn on the tethering always when connecting the cable (maybe some app could enable it automatically but...).

Solution

I had some spare Raspberry PI zero Ws lying around, and I've been playing with its usb gadget mode earlier. So I tought, why not make the PI look like an USB ethernet adapter, and bridge its wlan connection to the USB connection? I had all the pieces available, I just needed to put them together!

So, I made a script to
  1. make the PI to be an CDC/ECM USB ethernet gadget using configfs
  2. enable ipv4 port forwarding and NAT, forwarding usb0 to wlan0
  3. enable forwarding from wlan0 to the usb0
  4. enable DHCP server, serving address 192.168.20.10

I would have used CDC/NCM since I think it is the fastest protocol, but the stock Raspbian does not have built-in support for that. So I went with ECM, which works well on Linux. If the gadget is to be used with Windows, one should select RNDis (by replacing ecm with rndis in the script).

To enable gadget mode, dtoverlay=dwc2 should be added to /boot/config.txt.

Following script should be placed in /usr/local/bin/usb_wifi_gadget.sh and made executable (ug+x).

#!/bin/sh
#
# This script creates an Ethernet gadget using the
# CDC / ECM (Ethernet Control Model) interface and
# then shares the wlan0 to usb0 (with NAT)
# and starts a dhcp server on usb0

# Load libcomposite
modprobe libcomposite

# Create a gadget called usb-gadgets
cd /sys/kernel/config/usb_gadget/
mkdir -p usb-gadgets
cd usb-gadgets

# Configure the gadget
# ==========================

# Configure our gadget details
echo 0x1d6b > idVendor # Linux Foundation
echo 0x0104 > idProduct # Multifunction Composite Gadget
echo 0x0100 > bcdDevice # v1.0.0
echo 0x0200 > bcdUSB # USB2
mkdir -p strings/0x409

# Set serial number, manufacturer and product name here
echo "0123456789abcdef" > strings/0x409/serialnumber
echo "Pi Zero USB Gadget" > strings/0x409/manufacturer
echo "Pi Zero USB Gadget" > strings/0x409/product
mkdir -p configs/c.1/strings/0x409

# This describes the only configuration, free text
echo "Config 1: Test gadget" > configs/c.1/strings/0x409/configuration
echo 250 > configs/c.1/MaxPower

# =====================================
# Create gadget functions

# Ethernet gadget
# -------------------------
F_TYPE=ecm      # ECM gadget
F_NAME=usb0     # Freely selectable name

mkdir -p functions/$F_TYPE.$F_NAME

# Set configuration, see e.g.
# https://github.com/torvalds/linux/blob/master/Documentation/ABI/testing/configfs-usb-gadget-ecm

# MAC addresses, comment out for random addresses
# first byte of address must be even
HOST="32:70:05:18:ff:7a" # "HostPC"
SELF="32:70:05:18:ff:7b" # "Ethernet Gadget"
#echo $HOST > functions/$F_TYPE.$F_NAME/host_addr
#echo $SELF > functions/$F_TYPE.$F_NAME/dev_addr

# Interface name, by default will be usb0
#echo usb0 > functions/$F_TYPE.$F_NAME/ifname

# Link the function under the (only) configuration
ln -s functions/$F_TYPE.$F_NAME configs/c.1/

# End ethernet gadget
# ------------------------

# End functions
# ========================

# Enable gadgets
ls /sys/class/udc > UDC

 

# Internet connection shating
# Shares wlan0 over other connections

# Enable ipv4 forwarding
sysctl -w net.ipv4.ip_forward=1
sysctl -p

# Flush rules (flush all / flush only nat related)
#iptables -X
#iptables -F
iptables -t nat -X
iptables -t nat -F

# Enable NAT forwarding
iptables -I INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -I FORWARD  -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -I POSTROUTING -o wlan0 -j MASQUERADE


# Configure static IP address for the usb interface
ifconfig usb0 up
ifconfig usb0 192.168.20.1 netmask 255.255.255.0

# Enable incoming connections for DHCP
iptables -I INPUT -p udp --dport 67 -i usb0 -j ACCEPT

# Forward all TCP ports, except 22 (ssh), from wlan0 to usb0
iptables -t nat -A PREROUTING -p tcp -i wlan0 --dport 1:21 -j DNAT --to 192.168.20.10
iptables -t nat -A PREROUTING -p tcp -i wlan0 --dport 23:65535 -j DNAT --to 192.168.20.10


# Flush dhcp lease cache
if [ -f "/var/lib/dhcp/dhcpd.leases~" ]; then rm /var/lib/dhcp/dhcpd.leases~; fi
echo "" > /var/lib/dhcp/dhcpd.leases

# Launch (Restart) DCHP server
#systemctl restart isc-dhcp-server
if [ -f "/var/run/dhcpd.pid" ]; then kill `cat /var/run/dhcpd.pid`; fi
dhcpd -q -4 -cf /etc/dhcp/dhcpd.conf usb0
 

To launch this script at boot time, I added command usb_wifi_gadget.sh & to /etc/rc.local, before the exit 0 statement.


The dhcp server requires isc-dhcp-server package. The service should be disable by default, by running sudo systemctl disable isc-dhcp-server and sudo systemctl mask isc-dhcp-server.


The following minimalistic dhcp server configuration in /etc/dhcp/dhcpd.conf seems to work:
 

# dhcpd.conf
# Very basic dhcp daemon configuration for the USB interface

default-lease-time 600;
max-lease-time 7200;

# The ddns-updates-style parameter controls whether or not the server will
# attempt to do a DNS update when a lease is confirmed. We default to the
# behavior of the version 2 packages ('none', since DHCP v2 didn't
# have support for DDNS.)
ddns-update-style none;

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;

# Use this to send dhcp log messages to a different log file (you also
# have to hack syslog.conf to complete the redirection).
log-facility local7;

# Subnet declaration
subnet 192.168.20.0 netmask 255.255.255.0 {
        option routers                  192.168.20.1;
        option subnet-mask              255.255.255.0;

        option domain-name-servers      192.168.0.20;
        range   192.168.20.10   192.168.20.10;
}


I run pi-hole on my local server at 192.168.0.20 so I pointed the name server to that. One could also use some other, like Comodo DNS server at 8.26.56.26. See for example this page for information.

Now this seems to work properly, when plugging the Raspberry PI (using the USB port, not the PWR port) the computer gets IP address, and can access the internet just fine. Note that on the desktop computer it may be necessary to add following to /etc/network/interfaces:

allow-hotplug usb0
iface usb0 inet dhcp

Notes

My home network is by default 192.168.0.0/24, and the PI creates 192.168.20.0/24. It seems that the routing works so that I can access the home network from the desktop computer just fine via the PI.

I added the routing through wlan0 to usb0 so that it is possible to run server(s) on the desktop computer and they are accessible by using the IP that the PI has over the wlan.

The PI should not be abruptly powered off, but rather one should ssh into it and shut it down with sudo shutdown -h now.

Speed test

When I got the gadget to work, I run some speed tests using iperf3. The server was my Raspberry PI 3B server that has wired connection to my router.
  • Asus USB-N10 nano: 4-6 Mbps (surprisingly good, right after boot & connection)
  • USB tethering with mobile phone: 15-28 Mbps
  • Raspberry PI gadget: 20 Mbps
So my conclusion is that the Raspberry PI gadget works very well as a WLAN adapter.

torstai 27. kesäkuuta 2019

How I got S.T.A.L.K.E.R.: Clear Sky and Call of Pripyat to work on Devuan Linux

Introduction

This is a very short guide on how I got S.T.A.L.K.E.R.: Clear Sky and Call of Pripyat to work on my Linux computer. I had bought them on Steam earlier, and thanks to Steam Play and Proton, it was very easy even though the game did not work out of the box.

Steam settings

Like in the previous post, it is necessary to enable Steam Play for all titles so that S.T.A.L.K.E.R. can be installed on Linux. It is simply a check box in Steam preferences, follow e.g. this guide.

After that the game can be installed, but it did not launch properly but crashed; A BugTrap window appeared with some magic numbers in it.

In this case the solution was simple. In the WineHQ AppDB page, there is some mentions about DX10 not being tested/not working, and the solution is to use DX9.

In the bottom of the README.md in Proton Github page, environment variables are listed. There is variables to disable D3D11 and D3D10. The game works perfectly with Proton (4.0 I think currently) as soon as those two are disabled. So add the following to the startup parameters of the games in Steam:
PROTON_NO_D3D11=1 PROTON_NO_D3D10=1 %command%

You can see the parameters in screenshot below:






After using these parameters, the game can be launched from Steam and works just fine (though I have not yet played very long...)

EDIT 7/2021: After two years I got back to this game and since then Proton has been updated many times. Latest version is 6.3-5 and the game did not launch with that. Changing Proton version for these games to 4.11-13 made the game lauch fine and it works properly. I only tried Clear Sky again so far.

Also I'm not sure whether ProtonDB existed when I wrote this article. The game pages for Clear Sky and Call of Pripyat have probably more information on how to get the games run and with which Proton versions and settings.