ircommander/doc/verslag.tex

88 lines
8.2 KiB
TeX
Raw Permalink Normal View History

2019-07-30 15:08:45 +00:00
\documentclass[twocolumn]{article}
\usepackage[utf8]{inputenc}
\usepackage[dutch]{babel}
\usepackage{enotez}
\usepackage[hidelinks]{hyperref}
\usepackage{graphicx}
\usepackage{caption}
%Instellingen
\DeclareTranslation{Dutch}{enotez-title}{\section{Verwijzingen}}
\graphicspath{ {images/} }
\title{Verslag IRCommander}
\author{Frank Wibbelink}
\date{\today}
\setcounter{tocdepth}{3}
\begin{document}
\maketitle
\begin{abstract}
\end{abstract}
\tableofcontents
\section{Opdracht}
Dit verslag behandelt de eindopdracht van CAO2. Het doel van de opdracht is kennismaken met microcontrollers en digitale signaalverwerking. Ik heb deze opdracht ingevuld met het uitlezen van een afstandsbediening op een \emph{BeagleBone Black} (BBB).
\section{Achtergrond}
\subsection{PRU}
De PRU (2 aanwezig op de BBB) is een realtimeprocessor die los van de CPU (en daarmee de kernel) draait op 200 MHz. Deze processor doet niet aan pipelining en de instructieset bestaat uit load/store, branching, bit shifts en optellen/aftrekken, waarvan de meeste 1 klokcyclus kosten om uit te voeren. Er zijn 32 registers beschikbaar (geen ingebouwde stack of window) en een tabel met veelgebruikte offsets en verder vindt alle communicatie via I\textsuperscript{2}C plaats. Dit betekent voor de PRU-code dat er specifieke geheugenadressen --uit de voorgenoemde tabel-- gebruikt moeten worden om naartoe te schrijven of van te lezen. Hoewel er een C-compiler voor de PRU door TI wordt geleverd, is het aanvankelijk handiger voor dit project om code in PASM te schrijven, om zeker te zijn van de timing.\\
De I/O-pinnen op het bord zijn op meerdere manieren te gebruiken, waaronder GPIO --pin wordt gekoppeld aan een geheugenadres-- en rechtstreeks naar r30 (output) of r31 (input) op een van de PRU's. De modus voor een pin kan worden ingesteld met een \emph{device tree overlay}. Ik heb hier een simpele editor voor gemaakt, \emph{tools/pinselect.html}, op basis van de tabel van Derek Molloy\endnote{http://derekmolloy.ie/beaglebone/beaglebone-gpio-programming-on-arm-embedded-linux/}.
\subsection{Device Tree}
De Flattened Device Tree\endnote{https://en.wikipedia.org/wiki/Device\_tree} is een datastructuur om onderdelen van de hardware van een computer te beschrijven. Het is bedoeld als een nieuwe abstractielaag waardoor drivers los komen te staan van de kernel, opdat er niet voor elke SoC of andere hardware een nieuwe kernel geleverd hoeft te worden.\\
Bijkomend voordeel is dat er \emph{overlay}s --extra stukken device tree-- ingeladen kunnen worden terwijl het systeem draait. Voor de BBB betekent dit dat de I/O-pinnen die normaal voor HDMI worden ingezet, ook te gebruiken zijn voor GPIO door de overlay uit te laden en een andere in te laden.
\subsection{Infraroodsensor}
De gebruikte infraroodsensor (\emph{TSOP1238}) bestaat hoofdzakelijk uit een 38 KHz band-pass-filter met wat componenten om basisstraling te filteren en het signaal te normaliseren. Dit wordt vervolgens aan een transistor gehangen die open gaat als het signaal hoog is. De output-pin is met een grote weerstand verbonden aan de 3,3 V en wordt geaard als de transistor geleidt (open is). Zie \emph{doc/TSOP1138.pdf} voor de datasheet van een vergelijkbare sensor.\\
Er is voor gekozen om het signaal niet te inverteren met nog een weerstand en transistor, maar om in de PRU-code met het geïnverteerde signaal te werken.
\begin{figure}[h]
\begin{center}
\includegraphics[width=1\columnwidth]{tsop1138_block_diagram}
\end{center}
\caption{Diagram TSOP1138}
\end{figure}
\subsection{Infraroodprotocol}
Infraroodprotocollen bestaan uit een digitaal signaal dat met \emph{on-off keying} op een draaggolf van ongeveer 38KHz wordt gezet. Praktisch elke fabrikant of zelfs elke productlijn heeft een eigen techniek om het digitale signaal op te bouwen. In dit geval is het protocol van een afstandsbediening van Panasonic bestudeerd.\\
Met \emph{rawtiming} is gekeken hoe de knopcodes worden gemoduleerd. Uit analyse (zie \emph{doc/rawtiming\_analyse.xlsx}) volgt dat on-off keying op een schaal van >0,1ms gebeurt en er grofweg 3 categorieën voor zijn: kort, lang en "begin". Verder is een hoog signaal altijd kort, wat erop neerkomt dat alleen de duur van een laag signaal informatie draagt. Tot slot bestaat een pakket altijd uit 48 lage en 49 hoge signalen. Dit komt overeen met het protocol zoals beschreven in Arduino-IRremote\endnote{https://github.com/shirriff/Arduino-IRremote/blob/master/IRremote.cpp}.\\
Met de indeling in 3 categorieën kunnen pakketten worden uitgelezen. De basis hiervoor is te zien in \emph{read\_signal}. Dit programma leest IR-pakketten en toont ze op het scherm.
\section{Programma}
\subsection{Compilatie}
Voor het compileren van de C-code zijn gcc, glib en make nodig. Om te cross-compileren vanaf andere architecturen is de variabele \emph{CROSS\_COMPILE=arm-arago-linux-gnueabi-} en de SDK van TI nodig.\\
Voor de PRU-code zijn make en pasm nodig, waarvan de laatste beschikbaar is via de am335x\_pru\_package\endnote{https://github.com/beagleboard/am335x\_pru\_package/ tree/master/pru\_sw/utils/pasm\_source}.
Om de Device Tree Overlay (\emph{BB-BONE-IRMUX-00A0.dts}) te compileren is de Device Tree Compiler nodig. Het programma heeft in sommige distributies een patch nodig.\endnote{https://eewiki.net/display/linuxonarm/BeagleBone+Black\# BeagleBoneBlack-Upgradedistro\%22device-tree-compiler\%22package}
\subsection{Werking}
Allereerst moet de device tree overlay voor de I/O-pinnen (1 pin in dit geval) en de PRU ingeladen worden. Dit wordt gedaan door "BB-BONE-IRMUX" naar \emph{/sys/devices/bone\_capemgr.*/slots} te sturen. Zie ook \emph{tools/laad\_overlay}.\\
Hierna kan \emph{ircommander} worden opgestart. Dit programma laadt het configuratiebestand en de PRU-driver in. Vervolgens wordt het PRU-programma ingeladen en uitgevoerd. Dit programma leest continu de IR-sensor uit tot er een volledig pakket is gelezen, waarna hij het als een uint64 in de buffer zet. De buffer is een eenvoudige cyclische array van 256 elementen. Zodra de buffer is geüpdatet (of er gebleken is dat hij vol zit), verstuurt de PRU een interrupt naar de CPU.\\
Ondertussen wacht het hoofdprogramma op interrupts van de PRU en zoekt de bijbehorende tekst voor de nieuwe pakketten in de buffer. Als er geen tekst te vinden is en de configuratie bevat \emph{assignNewCommands=true}, vraagt het programma om een nieuwe tekst in te voeren.\\
Door als tekst een commando op te geven en de uitvoer te pipen naar de shell (of naar een shell over SSH), is de afstandsbediening te gebruiken voor het opstarten van programma's en voor mediatoetsen. Dit is te zien in \emph{config/ircommander.example.conf}, \emph{tools/ircommander\_groepscomputer} en de demovideo.
\begin{figure}[h]
\begin{center}
\includegraphics[width=1\columnwidth]{flow_diagram}
\end{center}
\caption{Gegevensstroom in een voorbeeldopstelling (\emph{tools/ircommander\_groepscomputer})}
\end{figure}
\section{Toekomstige verbeteringen}
Er kan op een aantal punten verbetering gebracht worden in het programma:
\begin{itemize}
\item Lopend gemiddelde: de PRU-code leest de gemiddelde waarde momenteel uit door de pin een aantal keer uit te lezen in vaste blokken. Door ruis (vooral bij zonlicht) lezen kleine blokken wel eens de verkeerde waarde uit, terwijl grote blokken geen signalen kunnen herkennen als de afstandsbediening het signaal verandert halverwege een blok. Met een lopend gemiddelde kan het exacte moment worden bepaald waarop de sensor van hoog naar laag wisselt en vice versa. Als alternatief kan natuurlijk ook een analoog circuit worden gebouwd.
\item Meerdere modi: het C-programma staat nu één commando per knopcode toe. Door knoppen (of commando's op de standaardinvoer) toe te wijzen aan het wisselen van de modus, kan een knop meerdere resultaten geven. Hoewel deze functie ook kan worden vervuld door het programma waar naar gepiped wordt, leidt dit tot onduidelijke commando's in de huidige opzet, waarin gepiped wordt naar bash.
\item Het omzetten van knopcodes naar commando's outsourcen: het stateless knopcodes omzetten naar tekst kan ook met \emph{sed} uitgevoerd worden. Hierdoor wordt het programma compacter en de afhankelijkheid van glib vervalt. Om het bovenstaande punt ook te verwerken, is \emph{sed} alleen niet voldoende.
\end{itemize}
\printendnotes
\end{document}