Емельянов Эдуард Владимирович (eddy_em) wrote,
Емельянов Эдуард Владимирович
eddy_em

Category:

Продолжаю постигать свой ноутбук

Итак, в поисках возможных решений, как таки заставить ноутбук быть человечнее, я даже создал тему на ЛОРе и в ЖЖ ru_linux.
Помощь зала и гугла дала возможность еще кое-что добавить.

Во-первых, для того, чтобы парковать головки HDD при падении, надо поставить демон hpfall. Настраивается он в файле /etc/conf.d/hpfall, в котором указано, на каких HDD (/dev/sdX) парковать головки при падении. Вроде работает.

Во-вторых, на просторах БХ найден скрипт, позволяющий менять ориентацию экрана при наклоне ноутбука:
while true; do
  sleep 2
  POS=`cat /sys/devices/platform/lis3lv02d/position | sed -e 's/(\([-0-9]\+\).*/\1/'`
  if [ $POS -ge 500 ]; then
        xrandr --output LVDS --rotate left
  elif [ $POS -le -500 ]; then
        xrandr --output LVDS --rotate right
  else
        xrandr --output LVDS --rotate normal
  fi
done

Помониторив /sys/devices/platform/lis3lv02d/position, я обнаружил, что система координат датчика — правовинтовая. Ось X смотрит влево, Y — на тебя, Z — вверх. Сначала я подумал, что координаты ориентации есть проекции некоторого вектора на эти оси. Длина этого вектора непостоянна (видимо, квантователь велик), но примерно она составляет 1150. Вектор этот ориентирован строго перпендикулярно клавиатуре. Таким образом, теоретически даже можно определить угол наклона бука.
ОК, пробуем. А поможет в этом как всегда Octave.
Вот так можно вытащить системные данные в переменные X, Y, Z:
function [X Y Z] = AccelCoords()
%  [X Y Z] = AccelCoords()
% возвращает координаты с акселерометра
%
    [st out] = system("cat /sys/devices/platform/lis3lv02d/position | sed -e 's/(//' -e 's/)//' -e 's/,/ /g'");
    if(st == 0)
        coords = sscanf(out, "%d %d %d");
        X = coords(1);
        Y = coords(2);
        Z = coords(3);
    else
        X = nan; Y = nan; Z = nan;
    endif
endfunction

А вот эта функция измеряет углы наклона ноутбука в плоскостях ZY и ZX относительно вертикали (положительное направление — как обычно, против часовой стрелки в сторону положительного направления оси Y или X):
function [ZY ZX] = AccelAngle()
%  [ZY ZX] = AccelAngle()
% возвращает углы наклона бука в плоскостях ZY и ZX
%
	[X Y Z] = AccelCoords();
	if(isnan(X))
		ZY = nan; ZX = nan;
	else
		ZY = atan2(Y, Z) * 180. / pi;
		ZX = atan2(X, Z) * 180. / pi;
	endif
endfunction

Помониторив вот такой строчкой:
i=0;while(i++<60);[a b]=AccelAngle();printf("ZY=%g,ZX=%g\n",a,b);fflush(1);endwhile
я обнаружил, что определяется положение довольно сносно, с точностью около 1°. Вот, что получается, когда бук просто стоит:
ZY = 0, ZX = 0.924045
ZY = 0, ZX = -0.924045
ZY = 0, ZX = 1.84761
ZY = 0, ZX = 1.84761
ZY = 0, ZX = 0.939191
ZY = -0.924045, ZX = 0
ZY = 0.924045, ZX = 0
ZY = 1.84761, ZX = 0
ZY = 0.924045, ZX = 0.924045
ZY = 0.90938, ZX = 0.90938
ZY = 0, ZX = 0
…
Т.е., судя по всему, АЦП у акселерометра восьмибитный, а шумит он (акселерометр) довольно прилично.

Итак, в первом приближении мне надо использовать угол в плоскости ZY. После некоторого количества проб и ошибок, я родил такой скрипт:
#!/bin/bash
while true; do
	sleep 1
	cat /sys/devices/platform/lis3lv02d/position | sed -e 's/(//' -e 's/)//' -e 's/,/ /g' | while read x y z; do
	echo "x=$x, y=$y, z=$z"
	if [ "$z" -ge 0 ]; then
		if [ "$y" -ge 800 ]; then
			xrandr --output LVDS1 --rotate right
		elif [ "$y" -le -800 ]; then
			xrandr --output LVDS1 --rotate left
		else
			xrandr --output LVDS1 --rotate normal
		fi
	elif [ "$z" -ge -600 ]; then
		if [ "$y" -le 800 ]; then
			xrandr --output LVDS1 --rotate left
		elif [ "$y" -ge -800 ]; then
			xrandr --output LVDS1 --rotate right
		fi
	else
		xrandr --output LVDS1 --rotate inverted
	fi
	done
done

Кручу-верчу ноутбук, а ориентация экранчика остается удобочитаемой. Класс!!!
Запихал этот скрипт в автостарт IceWM. Все отлично!

В-третьих, заставить веб-камеру работать в нормальном режиме можно (как я об этом сразу не подумал):
mplayer tv://  -tv driver=v4l2:width=1280:height=720


Вот с управлением питания wifi у меня вышла незадача. Напрямую — ругается:
iwconfig wlan0 power off
Error for wireless request "Set Power Management" (8B2C) :
    SET failed on device wlan0 ; Operation not supported.
Установил rfkill. Похоже, при помощи него можно делать "софтовую блокировку". Правда, я не понял: отключает ли она питание. Судя по выхлопу iwconfig, питание не отключается: происходит то же самое, что и при вызове iwconfig wlan0 txpower off, т.е. только лишь отключается питание на передачу.
В общем, с wifi я пока так и не разобрался.
Tags: octave, всячина
Subscribe

  • А что, в С так нельзя?

    Пытаюсь передать в функцию цвет как массив. Функция такая: void Pattern_draw3(Img3 *img, Pattern *p, int xul, int yul, uint8_t colr[3]); И…

  • Ардуиноподход

    Вот как ни гляну, большинство народу для считывания данных калибровки в BMP/BME280 использует типичный ардуиноподход, как, например, здесь: зачем-то…

  • Темы-2

    Некоторые испугались, прочитав предыдущие темы. Повторяю: темы для работы в течение всей школы (три года). А вот — их части, которые можно осилить за…

promo eddy_em август 17, 2019 12:33 3
Buy for 10 tokens
Юра намедни напечатал корпус для хронометра. Для первого блина получилось неплохо: И еще немного фотографий:
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

  • 6 comments