Sensor de temperatura i diagrama de barres amb PiTFT

De wikijoan
Salta a la navegació Salta a la cerca

Introducció

La configuració del mòdul PiTFT per a la Raspberry Pi està a:

NOTA. També es podria utilitzar una pantalla LCD (16x2) per fer dos diagrames de barra (http://www.raspberrypi.org/forums/viewtopic.php?f=32&t=58983)

Per mostrar uns gràfics de barres a la RPi de forma compacta necessitem unes pantalles petites i compactes. Podem utilitzar pantalles LCD (típicament de 16x2), o molt més xulo una pantalla TFT.

En aquest últim cas els diagrames de barra s'haurien de programar amb SDL, que en principi s'ha de poder fer com es mostra en el tercer enllaç. El tema de RPi + SDL ja està abordat en una altra banda. El tema està en què els gràfics es volquin sobre la pantalla TFT. No ha estat fàcil (veure més avall).

Plantejament del problema

Tenim dos feixos de llum infrarroja que incideixen sobre dos vidres. Es tracta de veure com evoluciona la temperatura en els vidres de forma gràfica. Un vidre es calentarà menys que l'altra perquè té un filtre. S'utilitzarà el mòdul PiTFT per al display.

Configuració de la PiTFT

NOTA: quan diem que la PiTFT és 320x240 tan pot ser en mode landscape com en mode vertical. Per defecte seria vertical. Si en la configuració del dispositiu diem rotate=90, que vol dir que tenim mode landscape.

Em descarrego la imatge ... i la cremo en una targeta SD. Les primeres proves les faig amb una RPi model B.

Passos previs:

$ sudo apt-get install joe

Anem directament a la pàg 45 del : How to play videos

$ wget http://adafruit-download.s3.amazonaws.com/bigbuckbunny320p.mp4
$ sudo apt-get install mplayer
$ mplayer -vo fbdev2:/dev/fb1 -x 240 -y 320 -framedrop bigbuckbunny320p.mp4

Per veure imatges, instal.lem fbi' (frame buffer images viewer):

$ sudo apt-get install fbi
$ wget http://adafruit-download.s3.amazonaws.com/adapiluv320x240.jpg
$ sudo fbi -T 2 -d /dev/fb1 -noverbose -a adapiluv320x240.jpg

PiTFT + SDL

Instal.lació de les llibreries:

$ sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-0 libsdl-ttf2.0-dev
$ sudo apt-get install libsdl-gfx1.2-dev

Faig la primera prova amb el programa sensor_temperatura_indo-0.0.1.c i no funciona. Es queda la pantalla en negre (tot i que el programa funciona correctament i no dóna missatges d'error).

Un fitxer de configuració important és /etc/modprobe.d/adafruit.conf, però no he de tocar res aquí.

Canvio totes les opcions possibles de SDL, però res. Les coses no van per aquí.

llegeixo a:

Unfortunately anything which uses the hardware graphics acceleration (e.g. anything SDL based, like most of the supplied emulators!) won't output via the PiTFT, which is a shame. AdvanceMAME doesn't though, so it works well.

The PiTFT display does not allow OpenGL hardware acceleration, which is what RetroPie uses (and most emulators). If you really wanted to try, you could use fbcp which copies the framebuffer back to the PiTFT but it has a lower framerate and the resolution gets somewhat messed up.

I la solució és precisament aquesta, utilitzar fbcp.

llegir

i la clau està a: Framebuffer mirroring:

By mirroring /dev/fb0 onto /dev/fb1, we can take advantage of the GPU for hardware accelrated video playback.

fbcp takes a snapshot of /dev/fb0, copies it to /dev/fb1 and waits 25ms before repeating.

Snapshotting takes ~10ms and with a 25ms delay it gives roughly 1000/(10+25) = 28fps

CPU usage: ~2%

Note: Snapshot and /dev/fb1 driver refresh is not syncronized.

Instal.lació de fbcp:

sudo apt-get install cmake
git clone https://github.com/tasanakorn/rpi-fbcp
cd rpi-fbcp/
mkdir build
cd build/
cmake ..
make
sudo install fbcp /usr/local/bin/fbcp

Load drivers and fbcp

sudo modprobe fbtft dma
sudo modprobe fbtft_device name=tinylcd35 rotate=90 speed=48000000 fps=50

Aquesta línia darrera no cal. En el fitxer /etc/modprobe.d/adafruit.conf ja es carrega el mòdul amb les dades correctes:

options fbtft_device name=adafruitrt28 rotate=90 frequency=32000000

(com veiem, és aquí on es rota la pantalla 90 graus, que de fet és el mode landscape).

Arrenquem el programa que fa tota la màgia:

# Start fb copying process in the background
fbcp &

Per fer una prova: Play video on /dev/fb0, which will also show up on /dev/fb1

omxplayer test_480_320.mpg

Per aturar: Stop framebuffer copy

$ killall fbcp

I puc veure una pista de la feina feta al syslog output

$ tail /var/log/messages
Dec 15 17:38:07 raspberrypi fbcp[4836]: Primary display is 720 x 480
Dec 15 17:38:07 raspberrypi fbcp[4836]: Second display is 480 x 320 16bps

Per tant, en els meus programes SDL no oblidar-se de fer:

$ sudo modprobe fbtft dma
$ fbcp &

Al final del fitxer .profile fico: (a sota de export FRAMEBUFFER=/dev/fb1)

sudo modprobe fbtft dma  
fbcp &   

/dev/fb1 representa la meva pantalla PiTFT (el monitor seria /dev/fb0). Per tal de què sigui el dispositiu per defecte hi ha una variable d'entorn que està definida correctament en el fitxer .profile:

FRAMEBUFFER=/dev/fb1 

La instrucció fbcb & és la que fa que el comportament de la consola de text es faci difícil d'escriure. Ho he de matar per tornar a que funcioni bé la consola.

En resum: els problemes que he tingut són perquè el mòdul PiTFT no suporta acceleració gràfica, i SDL i OpenGL fan servir acceleració gràfica. I per tant es fa necessari la tècnica del Framebuffer mirroring.

Autologin a la RPi

Que no demani login i password.

$ sudo joe /etc/inittab

Disable the getty program. Navigate to the following line in inittab and comment it out (comentar):

#1:2345:respawn:/sbin/getty 115200 tty1

Add login program to inittab. Add the following line just below the commented line:

1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

This will run the login program with pi user and without any authentication. Save and Exit.

Mesura de la temperatura amb el sensor DS18B20

Ja tenia una experiència amb el DS18B20, en un crèdit de síntesi a l'institut: Raspberry_Pi._Sensor_de_temperatura._Domòtica

En el següent enllaç:

veig com es connecten 2 sensors (només cal utiltizar un pin GPIO per als dos sensors, doncs és un protocol 1-wire en què cada sensor té una adreça única). Es necessita una resistència de 4k7.

$ sudo modprobe w1-gpio
$ sudo modprobe w1-therm
$ cd /sys/bus/w1/devices/
$ ls
$ cd 10-000802824e58 -> aquest és el id del dispositiu
$ cat w1_slave

$  cat /sys/bus/w1/devices/28-000004404eb3/w1_slave
b2 01 4b 46 7f ff 0e 10 8c : crc=8c YES
b2 01 4b 46 7f ff 0e 10 8c t=23125

La temperatura és de 23.12C (s'ha de dividir per 1000)

Per llegir la temperatura des de bash:

roomtemp=$(cat /sys/bus/w1/devices/28-xxxxxxxxxxxx/w1_slave | grep  -E -o ".{0,0}t=.{0,5}" | cut -c 3-)
echo $roomtemp

i un petit programet C que llegeixi la temperatura des de bash: llegir_temperatures-0.0.1.c:

// cd /home/joan/projectes/sensor_temperatura_indo/src
// gcc -o llegir_temperatures llegir_temperatures-0.0.1.c

// per llegir el valor de la temperatura que està emmagatzemat en el fitxer es pot fer d'altres maneres. Jo opto per llegir-ho des de la shell (http://www.raspberrypi.org/forums/viewtopic.php?t=54238&p=431812), i el valor que obtinc passar-lo a una variable de C (http://ubuntuforums.org/showthread.php?t=761500)
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> 

int main()
{
	int temp1 = 0;
	double temp1_dec;
    FILE* stream=popen("cat /home/joan/prova | grep  -E -o \".{0,0}t=.{0,5}\" | cut -c 3-","r");
    char* buffer=NULL;
    size_t len=0;

    if(stream && getline(&buffer, &len, stream)){
        temp1=atoi(buffer);
    }else {
        perror("popen");
        exit(errno);
    }

    pclose(stream);
    free(buffer);

    temp1_dec = (double)(temp1) / 1000;
    printf("%d %2.2f\n", temp1, temp1_dec);

    return 0;
}

creat per Joan Quintana Compte, desembre 2014