BeagleBone Home Automation Blueprints

BeagleBone Home Automation Blueprints

Costruisci, installa e sviluppa i tuoi circuiti tramite tutorial passo-passo ed utilizza questa guida piena di esempi pratici per accedere a diversi tipi di periferiche per monitorare e controllare il tuo ambiente domestico.
Il libro è stato scritto dal nostro Co-Chief e Senior Software Engineer Rodolfo Giometti – Feb 2016 – 378 pagine

BeagleBone Home Automation Blueprints

Caratteristiche principali

  • Costruire, installare e sviluppare circuiti tramite tutorial passo-passo ed esempi pratici, dalla configurazione iniziale alla gestione driver di periferica
  • Accedi a diversi tipi di periferiche per computer per monitorare e controllare il proprio ambiente domestico utilizzando questa guida
  • Questo libro si sviluppa attraverso 10 capitoli tutti concentrati su di un unico progetto pratico di automazione domestica

Descrizione libro

La BeagleBone è un mini PC dove gira Linux. Può connettersi a Internet e può eseguire diversi sistemi operativi come Android e Ubuntu. La BeagleBone viene utilizzata per una varietà di scopi diversi, da progetti semplici come la costruzione di un termostato a quelli più avanzati come sistemi di sicurezza della casa.
Ricco di esempi reali, questo libro vi fornirà esempi di come collegare diversi sensori e ed attuatori alla BeagleBone Black. Imparerete come accedere ad essi al fine di realizzare sistemi di monitoraggio e controllo dai più semplici a quelli più complessi che vi permetteranno di prendere il controllo della casa. Troverete anche esempi software per implementare interfacce web utilizzando PHP/HTML e JavaScript, e come utilizzare le API per interagire con un account Google Docs, WhatsApp o Facebook. Questa guida è un tutorial prezioso se si prevede di utilizzare un BeagleBone Black in un progetto di automazione domestica.

Cosa si può imparare

  • Costruire un rilevatore di CO (e di altri gas) con un allarme acustico e LED per segnalare alte concentrazioni
  • Registrare dati ambientali e tracciarli graficamente
  • Sviluppare una semplice interfaccia web con una piattaforma LAMP
  • Preparare interfacce web complesse in JavaScript e come fare un flusso di dati video da una webcam
  • Utilizzare delle API per ottenere l’accesso a un account Google Docs o un account WhatsApp/Facebook per gestire un sistema di automazione domestica
  • Aggiungere un driver personalizzato per gestire un LED con diverse frequenze di lampeggiamento
  • Scoprire come lavorare con vari componenti elettronici per costruire piccoli circuiti
  • Utilizzare un NFS, sensori di temperatura, relè e altre periferiche per monitorare e controllare l’ambiente circostante

Disponibile su: Packt Publishing, Amazon, O’Reilly Media

Simple countdown on terminal

Simple countdown on terminal

In these days I needed a really simple countdown application and, instead of doing a graphical program, I decided to use Bash and some ASCII-art!

The script

First of all we need a Bash script simulating the countdown. We can do it in multiple ways and below is a possible solution:

$ cat clock.sh
#!/bin/bash
NAME=$(basename $0)
if [ $# -lt 2 ] ; then
    echo "usage: $NAME <min> <sec>" >&2
    exit 1
fi
min=$1
sec=$2
while sleep 1; do
    printf "%02d : %02dn" $min $sec
    if [ $sec -eq 0 -a $min -le 0 ] ; then
        break;
    fi
    sec=$(($sec - 1))
    if [ $sec = "-1" ] ; then
        sec=59
        min=$(($min - 1))
    fi
done
echo 'End!!!'
exit 0

The script’s structure is simple and we can see how it works by simply executing it as below:

$ ./clock.sh 1 1
01 : 01
01 : 00
00 : 59
00 : 58
00 : 57
00 : 56
...
00 : 03
00 : 02
00 : 01
00 : 00
End!!!

Now we can enlarge time’s characters by using figlet utility. This tool reads from stdin (or on the command line) a string and reproduces it on stdout using ASCII-art as below:

$ figlet -f big 10 : 30
 __  ___        ____   ___
/_ |/ _  \  _  |___  \/ _ \
 | | | | | (_)   __) | | | |
 | | | | |      |__ <| | | |
 | | |_| |  _   ___) | |_| |
 |_|\___/  (_) |____/ \___/

The option argument -f big it’s used to select larger fonts than the default.

For our purposes we can send the printf ‘s output to figlet and the trick is done!

The result

Below is a screenshot of my terminal where I enlarged my terminal’s font is such a way the time is displayed as a real digital clock.

Below is the complete code of clock.sh script:

#!/bin/bash
NAME=$(basename $0)
if [ $# -lt 2 ] ; then
    echo "usage: $NAME <min> <sec>" >&2
    exit 1
fi
min=$1
sec=$2
while sleep 1; do
    printf "%02d : %02dn" $min $sec | figlet -f big
    if [ $sec -eq 0 -a $min -le 0 ] ; then
        break;
    fi
    sec=$(($sec - 1))
    if [ $sec = "-1" ] ; then
        sec=59
        min=$(($min - 1))
    fi
done
echo 'End!!!' | figlet -f big
exit 0

Setting custom baud rate on serial port

custom baud rate

Serial ports are really important in Industry Automation, in fact they are widely used to communicate between computers and their peripherals (or between computers too). Usually these serial peripherals use standard baud rates but sometimes they not! So how we can force our serial controller to use these non standard speeds?

Looking around into the driver

The Linux kernel is an open-source project so to better answering to the above question we can start by directly looking into the source, in fact if we take a look into file linux/drivers/tty/tty_ioctl.c  we can see the following code for the set_termios()  function:

/* If old style Bfoo values are used then load c_ispeed/c_ospeed
 * with the real speed so its unconditionally usable */
tmp_termios.c_ispeed = tty_termios_input_baud_rate(&tmp_termios);
tmp_termios.c_ospeed = tty_termios_baud_rate(&tmp_termios);

Here we can see that input and output speed is read from the termios  variables by using specific functions. Then if we take a look at one of these functions, for example tty_termios_input_baud_rate() , we see the following code:

speed_t tty_termios_input_baud_rate(struct ktermios *termios)
{
#ifdef IBSHIFT
        unsigned int cbaud = (termios->c_cflag >> IBSHIFT) & CBAUD;
        if (cbaud == B0)
                return tty_termios_baud_rate(termios);
        /* Magic token for arbitrary speed via c_ispeed*/
        if (cbaud == BOTHER)
                return termios->c_ispeed;

Here we notice that the BOTHER  define can be used to specify a generic value for baud rate instead of the classic fixed speed defines like B115200  & friends. In this scenario we can go further searching where BOTHER  is defined and we can discover that everything is into file linux/include/uapi/asm-generic/termbits.h , below is what we can found:

struct termios2 {
        tcflag_t c_iflag;               /* input mode flags */
        tcflag_t c_oflag;               /* output mode flags */
        tcflag_t c_cflag;               /* control mode flags */
        tcflag_t c_lflag;               /* local mode flags */
        cc_t c_line;                    /* line discipline */
        cc_t c_cc[NCCS];                /* control characters */
        speed_t c_ispeed;               /* input speed */
        speed_t c_ospeed;               /* output speed */
};
...
#define    BOTHER 0010000

So we discovered that struct termios2  can be used to specify serial communication parameters from the userland with non standard speeds. Let’s see how.

A practical example

Below is a simple code in C that we can use to set custom baud rate. It’s quite obvious that this code can work if and only if the underlying driver is supporting these advanced settings.

        struct termios2 term2;
        ioctl(fd, TCGETS2, &term2);
        term2.c_cflag &= ~CBAUD;  /* Remove current BAUD rate */
        term2.c_cflag |= BOTHER;  /* Allow custom BAUD rate using int input */
        term2.c_ispeed = speed;   /* Set the input BAUD rate */
        term2.c_ospeed = speed;   /* Set the output BAUD rate */
        ioctl(fd, TCSETS2, &term2);

By using the ioctl()  command TCGETS2  we retrieve from the kernel the current serial port configuration where we remove the (old and) current baud rate and then we enable custom baud rate with BOTHER .

As final note, don’t forget that the above code is just an example so we should add return values checks especially for systems calls!

Generare file binari al volo

firmware emebedded

Vi è mai capitato di dover creare un file binario contente dei valori esadecimali? Ad esempio se dovreste creare un file binario contenente i valori esadecimali della stringa BEBABEBAEFBEADDEBEBABEBAEFBEADDE, come fareste?

Lo so, e un’operazione poco frequente perché, di solito, serve il contrario e cioè poter leggere il contenuto di un file binario; cosa che si può fare ad esempio con il comando od.

Ad esempio per leggere 16 byte casuali si fa:

$ od -tx1 -N 16 < /dev/urandom
0000000 5b 84 9c 38 3b ac e0 95 f3 e4 3f c5 f5 96 f9 35
0000020

Ma per fare l’operazione inversa, cioè creare un file binario contenente dei valori ben definiti, come si fa?

Semplice, si usa il comando xxd come segue:

$ echo "0: BEBABEBAEFBEADDEBEBABEBAEFBEADDE" | xxd -r > /tmp/file.bin
$ od -tx1 < /tmp/file.bin
0000000 be ba be ba ef be ad de be ba be ba ef be ad de
0000020

In pratica questo comando, attraverso una speciale sintassi, permette di fare l’operazione inversa di od.

Installing OpenOCD from sources

linux embedded

Most GNU/Linux distributions offer the possibility to install OpenOCD directly using their packages management system, however these package may refer to not so updated releases of the software and this means that some CPUs may not be supported at all! That’s way could be very useful to know how to install OpenOCD from sources in order to get its latest release!

Downloading the code

First of all we need to download the official GIT source or a related mirror (I’m going to use the Spen’s Official OpenOCD Mirror):

git clone https://github.com/ntfreak/openocd.git

The needed extra packages

Once the sources have been downloaded we need some extra packages in order to get them compiled. On my Ubuntu Xenial I used the following command to install such software:

$ sudo apt-get install libtool automake libhidapi-dev

Compiling OpenOCD

Now we are ready! Just enter into the openocd directory and executing the bootstrap script as follow:

$ cd openocd
$ ./bootstrap

After that we can start configuring the sources by using the usual configure script which is able to auto detect our hardware. However we can force any special feature we want by simply adding one or more option arguments as shown below:

$ ./configure --enable-cmsis-dap

In the command above I force the  CMSIS-DAP compliant debugger support which I need to program my SAME70 based board.

When configure script has finished its job we can start the OpenOCD compilation and installation with the usual UNIX commands:

$ make -j8
$ sudo make install

Please, note that I used the -j8 option argument in order to have 8 compilation threads and the sudo command to be able to install the software into the system without permissions erros.

Testing the code

Once the compilation is finished we can test our new OpenOCD as follow (remeber that for this test I used my SAME70 based board). On a terminal we have to execute OpenOCD specifying the board’s script we wish to manage:

$ sudo openocd -f /usr/local/share/openocd/scripts/board/atmel_same70_xplained.cfg

Note that the sudo command may be mandatory in case you need to use an USB connection!

Note also that the path /usr/local/share/openocd/scripts/board/atmel_same70_xplained.cfg may vary in case you decide to install OpenOCD into a custom directory.

If everything works well you should see something like the following:

$ sudo openocd -f /usr/local/share/openocd/scripts/board/atmel_same70_xplained.cfg
Open On-Chip Debugger 0.10.0+dev-00512-gfd04460 (2018-08-09-18:25)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 1800 kHz
cortex_m reset_config sysresetreq
Info : flash bank command
srst_only separate srst_gates_jtag srst_open_drain connect_deassert_srst
Info : Listening on port 6666 for tcl connections
Info : Listening on port 4444 for telnet connections
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = 02.09.0169
Info : CMSIS-DAP: Serial# = ATML2637010000000000
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 1 TDO = 1 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : clock speed 1800 kHz
Info : SWD DPIDR 0x0bd11477
Warn : Silicon bug: single stepping will enter pending exception handler!
Info : atsame70q21.cpu: hardware has 8 breakpoints, 4 watchpoints
Info : Listening on port 3333 for gdb connections

Now we can use different connections types to control OpenOCD. I use the telnet connection as below:

$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Open On-Chip Debugger
>

Then I can easily reprogram the CPU’s internal flash with the following commands:

> halt
> flash write_image erase unlock /tmp/nuttx.hex 0 ihex
auto erase enabled
auto unlock enabled
device id = 0xa1020e00
erasing lock regions 0-8...
erasing lock region 0
erasing lock region 1
erasing lock region 2
erasing lock region 3
erasing lock region 4
erasing lock region 5
erasing lock region 6
erasing lock region 7
erasing lock region 8
wrote 147456 bytes from file /tmp/nuttx.hex in 3.278660s (43.920 KiB/s)
> reset
> 

Note that file /tmp/nuttx.hex is the new image I wish to program into my CPU.