function historie=protokol()
%FCE Summary of this function goes here
%   Detailed explanation goes here
%addpath('mereni infra');
buffer=[];

%krok=400;pocethodnot=1;
%prijtyp={'uint8','uint16','int16','int16','uint8'};prijmsk=[1 2 2 2 1];zobrazeni=@rizeni;
%prijtyp={'uint16','int16','uint8'};prijmsk=[2 2 1];zobrazeni=@srovnanider;
%prijtyp={'uint8','uint16','int64','uint8','uint8'};prijmsk=[1 2 8 1 1];
%prijtyp={'int32'};prijmsk=[4];
%prijtyp={'uint16'};prijmsk=[2];zobrazeni=@ZobrazInfraVGUI;
prijtyp={};prijmsk=[];zobrazeni=@merenidoGUI;
%prijtyp={'single'};
pocethodnot=0;    %pocet bytu
promenych=pocethodnot;
if exist('prijmsk') pocethodnot=sum(prijmsk);promenych=length(prijmsk);end
krok=pocethodnot*20;
meritkoX=200;

zaznam(1:1e6,1:promenych)=NaN;  %prectena cisla
n=0;                            %pozice v zaznamu

%%
prikazy=[
    struct('nazev','napis','fce',@napis,'popis','něco napíše') 
    struct('nazev','tram','fce',@()disp('tamta'),'popis','něco napíše') 
    struct('nazev','konec','fce','quit=1;','popis','ukončí se fce') 
    struct('nazev','perioda','fce',@nastav_per,'popis','nastaví periodu') 
    struct('nazev','pauza','fce','pauza=~pauza','popis','nastavena pauza')
    struct('nazev','bod','fce',@bod,'popis','posila body')
    struct('nazev','pwm','fce',@pwm,'popis','nastavi PWM')
    struct('nazev','atpokyn','fce',@atpokyn,'popis','Odesílá příkaz do AT')
    struct('nazev','atprijemscope','fce',@atprijemscope,'popis','Prijme data pro scope')
    struct('nazev','infrafrekvence','fce',@infrafrekvence,'popis','nastavi frekvenci IR')
    struct('nazev','prubeznyprenos','fce',@nprubeznyprenos,'popis','Zapíná/vypíná průběžený přenos')
    struct('nazev','vybermereni','fce',@vybermereni,'popis','Nastaví proměné k posílání')
    struct('nazev','uloz','fce',@uloz,'popis','Uloží nastavení')  
    struct('nazev','ulozitmereni','fce',@ulozitmereni,'popis','Uloží měření do base')
];

unastaveni=[];
load nastaveni

prijem;
chyba=atodesli('reset;');
if ~chyba %zda pripojeni bylo uspesne

    offline=0;
atodesli('helpm;');%zjisti mozne promene, ktere lze vycist
pause(.1);
mpromene=prijem;
if isempty(mpromene),disp('Neni pripojena MultiUnit nebo komunikace.');return,end
indexy=find(mpromene==13);%najde indexy odstavce
for ni=3:length(indexy)-1,mereni(ni-2).nazev=mpromene(indexy(ni-1)+1:(indexy(ni)-1));end%rozdeli dle odstavcu
for ni=1:length(mereni),
    mereni(ni).napoveda=mereni(ni).nazev(find(mereni(ni).nazev==9)+1:end);
    mereni(ni).nazev=mereni(ni).nazev(1:find(mereni(ni).nazev==9)-1);end%oddeli napovedu za tab
for ni=1:length(mereni),atodesli(['scope ' mereni(ni).nazev ';']);pause(.1),mereni(ni).bytu=length(prijem);end%zjisti pocet bytu kazdeho
for ni=1:length(mereni),mereni(ni).typ='uint8';end %klasika typ
ind=[];
%načtení uložených hodnot z minulé relace. Načítají se: typ,meritko,barva
if isfield(unastaveni,'mereni')
for ni=1:length(mereni),ind=find(strcmp({unastaveni.mereni.nazev},mereni(ni).nazev));
if ~isempty(ind)
    mereni(ni).typ=unastaveni.mereni(ind(1)).typ;
    mereni(ni).meritko=unastaveni.mereni(ind(1)).meritko;
    mereni(ni).barva=unastaveni.mereni(ind(1)).barva;
else
    mereni(ni).meritko=1;
    mereni(ni).barva='Red';
end,end,end


atodesli('help;');%zjisti mozne prikazy, ktere lze zadat
pause(.1);
mpromene=prijem;
indexy=find(mpromene==13);%najde indexy odstavce
for ni=3:length(indexy)-1,atprikazy(ni-2).nazev=mpromene(indexy(ni-1)+1:(indexy(ni)-1));end%rozdeli dle odstavcu
for ni=1:length(atprikazy),
    atprikazy(ni).napoveda=atprikazy(ni).nazev(find(atprikazy(ni).nazev==9)+1:end);
    atprikazy(ni).nazev=atprikazy(ni).nazev(1:find(atprikazy(ni).nazev==9)-1);end%oddeli napovedu za tab

if isfield(unastaveni,'atprikazy')
for ni=1:length(atprikazy)
    ind=find(strcmp({unastaveni.atprikazy.nazev},atprikazy(ni).nazev));
%keyboard
    if ~isempty(ind)
    atprikazy(ni).typ=unastaveni.atprikazy(ind(1)).typ;
    else
    atprikazy(ni).typ='-';
end,end,end

atodesli('helpf;');%zjisti mozne filtry, ktere lze zadat
pause(.1);
fpromene=prijem;
indexy=find(fpromene==13);%najde indexy odstavce
for ni=3:length(indexy)-1,atfiltry(ni-2).nazev=fpromene(indexy(ni-1)+1:(indexy(ni)-1));end%rozdeli dle odstavcu
for ni=1:length(atfiltry),
    atfiltry(ni).napoveda=atfiltry(ni).nazev(find(atfiltry(ni).nazev==9)+1:end);
    atfiltry(ni).nazev=atfiltry(ni).nazev(1:find(atfiltry(ni).nazev==9)-1);end%oddeli napovedu za tab



nastaveni.mereni=mereni;
nastaveni.atprikazy=atprikazy;
nastaveni.atfiltry=atfiltry;
%keyboard

else


    if libisloaded('lib')
    unloadlibrary lib;
    end
offline=1;
atprikazy(1)=struct('nazev','zapni_mustek','napoveda','zapne mustek','typ','-');
atprikazy(2)=struct('nazev','scope','napoveda','precte promenou','typ','-');
atprikazy(3)=struct('nazev','der','napoveda','Nastaví derivační složku','typ','single');

mereni(1)=struct('nazev','der','napoveda','Derivační člen','bytu',4,'typ','single');
mereni(2)=struct('nazev','AD1','napoveda','AD převodník 1','bytu',2,'typ','int16');
mereni(3)=struct('nazev','pwm','napoveda','Výstup','bytu',2,'typ','int16');
%mereni=unastaveni.mereni;
%atprikazy=unastaveni.atprikazy;
nastaveni=unastaveni;
%keyboard
end
%keyboard
%load nastaveni
[hnahled guipokyn]=guiDCmotor('pokyn',@pokyn,'nastaveni',nastaveni);     %otevre gui zobrazeni a uloží jeho handle
% ovladac('pokyn',@pwm,'nazev','Řízení motoru','limity',[0 255 0 -255],'nazevhodnoty','pwm');

%% funkce gpokyn, prida do parametru volane funkce handle gui%%%%%%%%%%%%%%%%%%%%
    function gpokyn(gnazev,gdata)
        if exist('gnazev','var')
            if exist('gdata','var')
            guipokyn(gnazev,hnahled,gdata);
            else
                guipokyn(gnazev,hnahled)
            end
        end
    end
%% inicializace
quit=0; %program bezi dokud je quit=0;
prubeznyprenos=0;
%keyboard
%atodesli('help;')
rawzaznam=uint8(zeros(1,1e7));
doruc=0;vyriz=0;

tic;

% atodesli('PWM_InA_B;');
% %atodesli('PWM_IR;');
% atodesli('vzorkovani 20;');
% %atodesli('stop;');
% %atodesli('odesilatmsk AD0;');
% atodesli('meritAD1;');
% atodesli('fAD0y;');
% atodesli('rpokus;');
% atodesli('povolit;');
%% hlavni smyčka
while ~quit
pause(0.1);
% zpracujprikazy;
%keyboard
if prubeznyprenos
tmpa=prijem(10000);
rawzaznam(doruc+1:doruc+length(tmpa))=tmpa;
doruc=doruc+length(tmpa);
zpracujdata;
end
%keyboard
%if toc>10, quit=1;end  %automatické vypnutí
end
%keyboard
%atodesli('stop;');

if ~offline
atodesli('zakazat;');
end
%% komunikace
    function zpracujprikazy()
index=find(buffer==10);%find(buffer==';');

for i=index
    char(buffer(1:i))
end
buffer=buffer(i+1:end);
%if length(buffer)>20, buffer=buffer(20:end);end
        %keyboard
    end
%___________________________________________________________
function zpracujdata()

if (doruc>=vyriz+pocethodnot)&&pocethodnot  
krok=floor((doruc-vyriz)/pocethodnot);

    vystup = rawzaznam(vyriz+1:vyriz+krok*pocethodnot);
    vyriz=vyriz+krok*pocethodnot;
    if exist('prijtyp')            %sablona prijmanych promenych
    vystup2(promenych)=0;
     for b=1:krok
     for pocetcisel=1:promenych
         pozice=(b-1)*pocethodnot+sum(prijmsk(1:pocetcisel));

         vystup2temp=typecast(uint8(vystup(pozice-prijmsk(pocetcisel)+1:pozice)),char(prijtyp(pocetcisel)));    
        %keyboard
        if (size(vystup2temp)==[1 1])
         vystup2(pocetcisel)=vystup2temp;
        else
        keyboard
        end
     end
        if (size(zaznam(n+b+1,:))==size(vystup2))
            zaznam(n+b,:)=vystup2;
        else
            keyboard
        end
   end
 else

     for b=1:krok
     zaznam(n+b,:)=uint8(vystup((b-1)*pocethodnot+1:b*pocethodnot)');
     end
 
end
n=n+krok;
%x((n/krok),1)=toc-toc2;toc2=toc;
%x((n/krok),2)=s.BytesAvailable;

%plot(y)
%axis([-10*timespan+1*n 1*n+50 0 260])
if exist('zobrazeni')
%zobrazeni((max(1,n-10*krok)):(n),y((max(1,n-10*krok)):(n),1:promenych),h);
zobrazeni((max(1,n-meritkoX)):(n),zaznam((max(1,n-meritkoX)):(n),1:promenych));
else
%plot((max(1,n-10*krok)):(n),y((max(1,n-10*krok)):(n),1:promenych))
plot((max(1,n-meritkoX)):(n),zaznam((max(1,n-meritkoX)):(n),1:promenych))
axis([-inf inf 0 260]);
end

if exist('cas') if n>=cas quit=1; end,end   %automatické vypínaní
  % if n>=cas disp('avaib'),s.BytesAvailableFcn='';end

%     if signal, fprintf(s,'pwm %d;',round(100*sin(pr/10)+140));
%     pr=pr+1;
%      end
  drawnow;
end
end
%% funkce pokyn vyrizuje prichozi prikazy
function pokyn(nazev,hodn)
   %keyboard
   proveden=0;
    for np=1:length(prikazy)
               if  strcmp(nazev,prikazy(np).nazev)
                    proveden=1;
                   try
                    if strcmp(class(prikazy(np).fce),'function_handle')
                        if exist('hodn','var')
                           prikazy(np).fce(hodn);
                        else prikazy(np).fce();
                        end
                        
                    elseif ischar(prikazy(np).fce)
                    eval(prikazy(np).fce);
                    end
                    disp(prikazy(np).popis);
                  catch chybu
                  disp([mfilename '\chyba pri volani fce:']),disp(chybu.message)
                  end
         end 
   end  
    if ~proveden       
disp([mfilename '/Neznam prikaz:' nazev]);
    end
 

end
%% ovladaci funkce tohoto protokolu:
    function ZobrazInfraVGUI(x,y)
        infradata.x=x;
        infradata.y=y;
        gpokyn('infradata',infradata);
    end
    function merenidoGUI(x,y)
%    disp([x(end) y(end,:)])
    d.x=x;
    d.y=y;
    gpokyn('ATdata',d);
    end

    function infrafrekvence(frek)
    atodesli(sprintf('pwm %i;',round(frek)));
    end

    function napis(text)
    disp(text)
    %keyboard
end

function t(str)
       fprintf(s,str)
disp(str);
end
    function dokoncena_cara()
   %keyboard
        gpokyn('dokoncenacara');
    end

    function pwm(a,b,c)
        %   keyboard
        atodesli(sprintf('pwm %i;',round(c)));
        round(c)
    end
function atpokyn(prikaz)
atodesli(prikaz);
disp(prikaz);
end

function atprijemscope(nazev)
d=uint8(prijem);
gpokyn('scope',struct('data',d,'nazev',nazev));
end
    function nprubeznyprenos(a)
    prubeznyprenos=a;
    end

    function vybermereni(d)
    if isempty(d)
        maska='odesilatmsk;';
        prijtyp={};
        prijmsk=[];
        
    else
     v=size(d);
     prijtyp=d(:,2)';
     %keyboard
     prijmsk=[d{:,3}]';
     maska=char(d(1,1));
        for ni=2:v(1)
        maska=[maska ',' char(d(ni,1))];
        end
     maska=['odesilatmsk ' maska ';'];
    end
    pocethodnot=sum(prijmsk);promenych=length(prijmsk);krok=pocethodnot*20;
    n=0;clear zaznam;zaznam(1:1e6,1:promenych)=NaN;
    
    %atpokyn('zakazat 5;');
    atpokyn(maska);pause(.5);prijem(10000)
    %atpokyn('povolit 5;');    
    end

    function uloz(unastaveni)
       %keyboard
        save('nastaveni', 'unastaveni')
    end
    function ulozitmereni(nazev)
      if isempty(zaznam)
      disp([mfilename '\žádná data k odeslání'])
      else
          assignin('base',nazev,zaznam(1:n,:));
      end
    end
%% zavreni protokolu
pause(1)
if ~offline
    if (libisloaded('lib'))
    unloadlibrary lib
    end
    delete(instrfind);
end
%keyboard
historie=zaznam(1:n,:);
end