using System;
using System.IO;
using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectInput;
using System.Net.Sockets;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using Touchless.Vision.Camera;
using CsharpUSBJoystick;

namespace Ovladani_voziku
{
    public partial class Form1 : Form
    {
        USB_Joystick joystick;
        Graphics platno;
        const int ROZSAH_JOYSTICKU = 255, STRANA_PAINTBOXU = 150;
        bool RizeniPovoleno = false, MereniPovoleno = false;
        int XminuleWIFI, YminuleWIFI, ZminuleWIFI; //minule hodnoty X,Y,Z (pozice joysticku prijata pres wifi); 
        int Xminule, Yminule, uhelMinule=0;       //minula pozice X,Y a Uhel - pro vykresleni odometrie

        protected UdpClient prichoziKlient, odchoziKlient;
        protected byte[] prijataData;
        protected object oKlic = new object(), oKlicObraz = new object(), oKlicUZ=new object(); //klice pro lock dat
        byte wifiWatchdog = 0, i2cWatchdog = 0;                  //inkrementalni registr pro watchdog

        CameraFrameSource _kamera;        //kamera
        static Bitmap _posledniFrame;     //posledni zachyceny obraz

        Byte FLVzdalenost = 255, FRVzdalenost = 255, RLVzdalenost = 255, RRVzdalenost = 255;

        int iMeritko = 10;

        enum srf08_Pozice : byte { LP = 0xE2, PP = 0xE8, PZ = 0xE6, LZ = 0xE4 };   //adresy senzorů

        enum smeryJoysticku : byte { LN = 1, N, PN, L, STOP, P, LD, D, PD };       //enum - smer vychyleni joysticku
        byte smerJoysticku = (byte)smeryJoysticku.STOP;     //smer vychyleni

        byte tempSledovanaVzdalenost = 120, tempKritickaVzdalenost = 20;

        public Form1()
        {
            InitializeComponent();

            prichoziKlient = new UdpClient(Convert.ToInt32(labelPrichoziPort.Text));
            odchoziKlient = new UdpClient();

            IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());     //ziska lokalni hostitelske adresy
            labelMistniIP.Text = "IP:      " + localIPs[0].ToString();

            platno = pictureBoxOdometrie.CreateGraphics();  //vytvoreni grafiky pictureboxu

            //naplneni seznamu portu
            foreach (string port in SerialPort.GetPortNames())
            {
                comboBoxPortSelection.Items.Add(port);
                comboBoxI2CPortSelection.Items.Add(port);
            }

            if (comboBoxPortSelection.Items.Count != 0)
                comboBoxPortSelection.SelectedIndex = 0;

            if (comboBoxI2CPortSelection.Items.Count != 0)
                comboBoxI2CPortSelection.SelectedIndex = 0;

            comboBoxZpusobRizeni.SelectedIndex = 0;
            comboBoxVstupniZarizeni.SelectedIndex = 0;

            prichoziKlient.BeginReceive(CallbackPrijmi, this);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            XminuleWIFI = ROZSAH_JOYSTICKU / 2;         //inicializace techto promenych, nez prijdou prvni data pres WiFi
            YminuleWIFI = ROZSAH_JOYSTICKU / 2;
            ZminuleWIFI = ROZSAH_JOYSTICKU / 2;

            Xminule = pictureBoxOdometrie.Width / 2;
            Yminule = pictureBoxOdometrie.Height / 2;

            try     //inicializace instance tridy USB_Joystick
            {
                joystick = new USB_Joystick(0, ROZSAH_JOYSTICKU, 0.2, this);
                joystick.PresetValues();
                VykresliPoziciJoysticku();
            }
            catch (Exception)
            {
                MessageBox.Show("Nebylo možno inicializovat joystick", "Pozor!", MessageBoxButtons.OK);
                comboBoxVstupniZarizeni.Enabled = false;        //zakazeme pouzivani tohoto comboboxu, aby nebylo mozno zvolit joystick
                comboBoxVstupniZarizeni.SelectedIndex = 1;      //jako vstup zvolime wifi
                VykresliPoziciJoysticku(XminuleWIFI, YminuleWIFI, ZminuleWIFI, ZminuleWIFI);   //vykreslime pozici
                buttonRefreshVstupniZarizeni.Visible = true;    //zviditelni tlacitko pro pripadny refresh pripojeni joysticku
            }

            comboBoxWebkamera.Items.Clear();        //naplneni comboboxu dostupnymi kamerami

            foreach (Camera kamera in CameraService.AvailableCameras)
                comboBoxWebkamera.Items.Add(kamera);

            if (comboBoxWebkamera.Items.Count > 0)
                comboBoxWebkamera.SelectedIndex = 0;

            timerJoystick.Start();

            timerObraz.Interval = Convert.ToInt16(numericUpDownIntervalObrazu.Value);

            labelMeritko.Text = (2 * iMeritko).ToString() + " m";
        }

        protected static void CallbackPrijmi(IAsyncResult IAR)
        {
            Byte[] prijataData;

            Form1 tempForm = (Form1)(IAR.AsyncState);
            IPEndPoint IPep = new IPEndPoint(0, 0);

            try
            {
                prijataData = tempForm.prichoziKlient.EndReceive(IAR, ref IPep);  // ukončení přijímání a uložení přijatých dat do bufferu (ep - end point = adresa a port od koho zpráva přišla)

                lock (tempForm.oKlic)                                            // zamknout data pro ostatní vlákna
                {
                    tempForm.prijataData = prijataData;
                }
            }
            catch (System.Net.Sockets.SocketException exception)
            {
                MessageBox.Show(exception.Message.ToString() + ".", "Vyjímka SocketException!", MessageBoxButtons.OK);
            }
        }

        private void timer1_Tick(object sender, EventArgs e)        //vyhodnoti pohyb joysticku, prekresli grafiku a vysle povel motorum
        {
            int tempX, tempY, tempZ, tempZred;

            if (comboBoxVstupniZarizeni.SelectedIndex == 0)         //zvoli, zda se budou data prijimat z joysticku nebo z WiFi
            {
                joystick.GetData();

                tempX = joystick.State.X;
                tempY = joystick.State.Y;
                tempZ = joystick.State.Z;
            }
            else
            {
                if (prijataData != null)
                {
                    wifiWatchdog = 0;       //vynulovani wifi watchdogu
                    pictureBoxWifiWatchdog.BackColor = Color.White;     //vypne kontrolku watchdogu

                    lock (oKlic)            //zamkne data pro ostatni thready
                    {
                        tempX = prijataData[0];
                        tempY = prijataData[1];
                        tempZ = prijataData[2];

                        prijataData = null;
                    }
                    prichoziKlient.BeginReceive(CallbackPrijmi, this);  //obnovi odposlech

                    XminuleWIFI = tempX;        //ulozeni hodnot
                    YminuleWIFI = tempY;
                    ZminuleWIFI = tempZ;


                }
                else
                {
                    if (wifiWatchdog++ < 20)    //pokud 20x za sebou neprijdou data, aktivuje se watchdog
                    {
                        tempX = XminuleWIFI;
                        tempY = YminuleWIFI;
                        tempZ = ZminuleWIFI;
                    }
                    else
                    {
                        tempX = ROZSAH_JOYSTICKU / 2;        //nastaveni neutralni pozice joysticku - > zastaveni voziku; pozice Z zustava nemenna, aby ukazatel nekmital
                        tempY = ROZSAH_JOYSTICKU / 2;
                        tempZ = ZminuleWIFI;

                        XminuleWIFI = ROZSAH_JOYSTICKU / 2;  //ulozeni do pameti minule pozice joysticku
                        YminuleWIFI = ROZSAH_JOYSTICKU / 2;

                        wifiWatchdog = 0;
                        pictureBoxWifiWatchdog.BackColor = Color.Crimson;   //rozsviceni kontrolky watchdogu

                        tiskniCas();
                        textBoxLog.AppendText("WIFI WATCHDOG AKTIV." + Environment.NewLine);
                    }
                }
            }

            if (JoystickXUvnitrThreshold(tempX) == true)       //kontrolka thresholdu osy X
                pictureBoxThresholdX.BackColor = Color.LimeGreen;
            else
                pictureBoxThresholdX.BackColor = Color.White;

            if (JoystickYUvnitrThreshold(tempY) == true)       //kontrolka thresholdu osy Y
                pictureBoxThresholdY.BackColor = Color.LimeGreen;
            else
                pictureBoxThresholdY.BackColor = Color.White;

            #region Smer
            //urcuje zamysleny smer voziku dle polohy joysticku

            if ((JoystickXUvnitrThreshold(tempX) || JoystickYUvnitrThreshold(tempY)) == false)
            {
                if (tempX < 127)
                {
                    if (tempY < 127)
                        smerJoysticku = (byte)smeryJoysticku.LN;
                    else
                        smerJoysticku = (byte)smeryJoysticku.LD;
                }
                else
                {
                    if (tempY < 127)
                        smerJoysticku = (byte)smeryJoysticku.PN;
                    else
                        smerJoysticku = (byte)smeryJoysticku.PD;
                }
            }
            else
            {
                if (JoystickXUvnitrThreshold(tempX))
                {
                    if (tempY < 127)
                        smerJoysticku = (byte)smeryJoysticku.N;
                    else
                        smerJoysticku = (byte)smeryJoysticku.D;

                    if (JoystickYUvnitrThreshold(tempY))
                        smerJoysticku = (byte)smeryJoysticku.STOP;
                }
                else
                {
                    if (tempX < 127)
                        smerJoysticku = (byte)smeryJoysticku.L;
                    else
                        smerJoysticku = (byte)smeryJoysticku.P;
                }
            }

            switch (smerJoysticku)
            {
                case 1: labelSmer.Text = "Směr:\nLN"; break;
                case 2: labelSmer.Text = "Směr:\nN"; break;
                case 3: labelSmer.Text = "Směr:\nPN"; break;
                case 4: labelSmer.Text = "Směr:\nL"; break;
                default: labelSmer.Text = "Směr:\nN/A"; break;
                case 6: labelSmer.Text = "Směr:\nP"; break;
                case 7: labelSmer.Text = "Směr:\nLD"; break;
                case 8: labelSmer.Text = "Směr:\nD"; break;
                case 9: labelSmer.Text = "Směr:\nPD"; break;
            }

            #endregion

            #region UpravaGainu
            //snizuje gain podle dat z UZ senzoru

            byte tempFL, tempFR, tempRR, tempRL;

            tempFL = (FLVzdalenost <= numericUpDownSledovanaVzdalenost.Value) ? (byte)(255 * ((float)(FLVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))) : (byte)255;    //plynule snizovani gainu, pokud je detekovan objekt ve sledovane vzdalenosti
            tempFR = (FRVzdalenost <= numericUpDownSledovanaVzdalenost.Value) ? (byte)(255 * ((float)(FRVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))) : (byte)255;
            tempRL = (RLVzdalenost <= numericUpDownSledovanaVzdalenost.Value) ? (byte)(255 * ((float)(RLVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))) : (byte)255;
            tempRR = (RRVzdalenost <= numericUpDownSledovanaVzdalenost.Value) ? (byte)(255 * ((float)(RRVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))) : (byte)255;

            if (FLVzdalenost <= numericUpDownKritickaVzdalenost.Value)  //pokud je objekt blize, nez kriticka vzdalenost, stahne gain na 0
                tempFL = 0;
            if (FRVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                tempFR = 0;
            if (RRVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                tempRR = 0;
            if (RLVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                tempRL = 0;


            switch (smerJoysticku)
            {
                case 1: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * (tempFL / 255.0)); break;
                case 2: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * ((tempFL < tempFR ? tempFL : tempFR) / 255.0)); break;
                case 3: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * (tempFR / 255.0)); break;
                case 4: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * ((tempFL < tempRL ? tempFL : tempRL) / 255.0)); break;
                default: tempZred = ROZSAH_JOYSTICKU - tempZ; break;
                case 6: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * ((tempFR < tempRR ? tempFR : tempRR) / 255.0)); break;
                case 9: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * (tempRL / 255.0)); break;     //pri vychyleni joysticku do pozice LD ma vozik tendenci jet do PD!!!
                case 8: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * ((tempRL < tempRR ? tempRL : tempRR) / 255.0)); break;
                case 7: tempZred = (int)((ROZSAH_JOYSTICKU - tempZ) * (tempRR / 255.0)); break;     //prohozeno s PD, viz. dva radky vyse!!!
            }

            #endregion

            if (Math.Abs(tempX - Convert.ToInt16(labelX.Text)) >= numericUpDownRozliseniJoysticku.Value ||    //pokud se zmenily pozicni parametry joysticku
                Math.Abs((ROZSAH_JOYSTICKU - tempY) - Convert.ToInt16(labelY.Text)) >= numericUpDownRozliseniJoysticku.Value ||
                Math.Abs((ROZSAH_JOYSTICKU - tempZ) - Convert.ToInt16(labelZ.Text)) >= numericUpDownRozliseniJoysticku.Value ||
                (tempZred != Convert.ToInt16(labelZred.Text)) ||
                labelRychlostA.Text != labelOdeslanoRychlostA.Text ||
                labelRychlostB.Text != labelOdeslanoRychlostB.Text)
            {
                VykresliPoziciJoysticku(tempX, tempY, tempZ, tempZred);

                if (RizeniPovoleno)
                    OdesliPovelyMotorum(tempX, tempY, tempZred);
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)     //vykresluje pozicni kriz
        {
            Graphics platno = e.Graphics;
            Pen pero = new Pen(Color.Black), pero2 = new Pen(Color.OrangeRed, 4f);
            int tempX, tempY, tempZ;

            if (comboBoxVstupniZarizeni.SelectedIndex == 0)
            {
                tempX = joystick.State.X;
                tempY = joystick.State.Y;
                tempZ = joystick.State.Z;
            }
            else
            {
                tempX = XminuleWIFI;
                tempY = YminuleWIFI;
                tempZ = ZminuleWIFI;

            }

            //osa z
            platno.DrawLine(pero2, STRANA_PAINTBOXU - pero2.Width, STRANA_PAINTBOXU, STRANA_PAINTBOXU - pero2.Width,
                    (float)((tempZ / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU));
            //vodorovna linka pozicniho krize
            platno.DrawLine(pero, (float)((tempX / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU) - 5, (float)((tempY / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU),
                    (float)((tempX / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU) + 5, (float)((tempY / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU));
            //svisla linka pozicniho krize
            platno.DrawLine(pero, (float)((tempX / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU), (float)((tempY / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU) - 5,
                    (float)((tempX / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU), (float)((tempY / (float)ROZSAH_JOYSTICKU) * STRANA_PAINTBOXU) + 5);

        }

        private void comboBoxPortSelection_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (serialPort.IsOpen == false)
                    serialPort.PortName = comboBoxPortSelection.Text;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message.ToString(), "Pozor!", MessageBoxButtons.OK);
            }
        }

        private void buttonOpenPort_Click(object sender, EventArgs e)
        {
            if (!serialPort.IsOpen)
            {
                try
                {
                    serialPort.Open();
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message.ToString(), "Pozor!", MessageBoxButtons.OK);
                }

                if (serialPort.IsOpen)
                {
                    comboBoxPortSelection.Enabled = false;
                    labelPortStatus.Text = comboBoxPortSelection.Text + " otevřen";
                    buttonOpenPort.BackColor = Color.MediumSpringGreen;
                    buttonOpenPort.Text = "ZAVŘÍT";

                    timerWatchdog.Enabled = true;
                    buttonWatchDogOnOff.Text = "Vypnout";
                    buttonWatchDogOnOff.Enabled = true;

                    buttonOdometrieStartStop.Text = "START";
                    buttonOdometrieStartStop.Enabled = true;

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxPortSelection.Text + " otevřen" + Environment.NewLine);
                }
                else
                {
                    labelPortStatus.Text = comboBoxPortSelection.Text + " otevření se nezdařilo";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxPortSelection.Text + " otevření se nezdařilo" + Environment.NewLine);
                }
            }
            else
            {
                serialPort.Close();

                if (!serialPort.IsOpen)
                {
                    comboBoxPortSelection.Enabled = true;
                    labelPortStatus.Text = comboBoxPortSelection.Text + " zavřen";
                    buttonOpenPort.BackColor = Color.Red;
                    buttonOpenPort.Text = "OTEVŘÍT";

                    timerWatchdog.Enabled = false;
                    buttonWatchDogOnOff.Enabled = false;

                    if (buttonStartStop.Text == "STOP")      //zastavi odesilani ridicich povelu
                        buttonStartStop_Click(this, e);

                    buttonOdometrieStartStop.Enabled = false;
                    buttonOdometrieStartStop.Text = "START";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxPortSelection.Text + " zavřen" + Environment.NewLine);
                }
                else
                {
                    labelPortStatus.Text = comboBoxPortSelection.Text + " zavření se nezdařilo";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxPortSelection.Text + " zavření se nezdařilo" + Environment.NewLine);
                }
            }
        }

        private void UARTposli(byte[] data)        //posila data pres seriovy port
        {
            if (!serialPort.IsOpen)
            {
                tiskniCas();
                textBoxLog.AppendText(" data neodeslána, zavřený port" + Environment.NewLine);
                return;
            }

            byte[] tempData = new byte[4];
            tempData[0] = data[0];
            tempData[1] = data[1];
            tempData[2] = data[2];
            tempData[3] = (byte)(data[0] + data[1] + data[2]);

            tiskniCas();            //tisk dat do logu
            textBoxLog.AppendText(" ODESLÁNO: " + tempData[0].ToString() + " " + tempData[1].ToString() + " " + tempData[2].ToString() + " " + tempData[3].ToString() + Environment.NewLine);

            System.Threading.Thread.Sleep(50);
            serialPort.Write(tempData, 0, 4);
        }

        private void tiskniCas()       //tiskne cas do logu
        {
            textBoxLog.AppendText(DateTime.Now.Hour.ToString() + ":" + DateTime.Now.Minute.ToString() + ":" + DateTime.Now.Second.ToString() + " ");
        }

        private void buttonStartStop_Click(object sender, EventArgs e)
        {
            if (buttonStartStop.Text == "START")
            {
                if (!serialPort.IsOpen)
                {
                    MessageBox.Show("Port " + serialPort.PortName.ToString() + " zavřen, nelze započít řízení!", "Port zavřen!");
                    tiskniCas();
                    textBoxLog.AppendText(" port zavřen, nelze započít řízení" + Environment.NewLine);
                }
                else
                {
                    RizeniPovoleno = true;
                    buttonStartStop.Text = "STOP";
                    tiskniCas();
                    textBoxLog.AppendText(" řízení odstartováno" + Environment.NewLine);

                    progressBarA.Value = 127;
                    progressBarB.Value = 127;
                    labelRychlostA.Text = "127";
                    labelRychlostB.Text = "127";

                    numericUpDownKritickaVzdalenost.Enabled = false;    //znepristupni nastaveni vzdalenosti, kvuli automatickemu zvysovani pri vzrustajici rychlosti
                    numericUpDownSledovanaVzdalenost.Enabled = false;
                    tempKritickaVzdalenost = (byte)numericUpDownKritickaVzdalenost.Value;
                    tempSledovanaVzdalenost = (byte)numericUpDownSledovanaVzdalenost.Value;
                }


            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                RizeniPovoleno = false;

                for (int i = 0; i < 2; i++)     //pozadavek na zastaveni, kvuli moznosti poruchy vyslan opakovane
                {
                    vystupniBuffer[0] = 0xC0;
                    vystupniBuffer[1] = 0x00;
                    vystupniBuffer[2] = 0x7F;
                    UARTposli(vystupniBuffer);

                    vystupniBuffer[0] = 0xC1;
                    vystupniBuffer[1] = 0x00;
                    vystupniBuffer[2] = 0x7F;
                    UARTposli(vystupniBuffer);

                    System.Threading.Thread.Sleep(100);
                }

                buttonStartStop.Text = "START";

                progressBarA.Value = 0;
                progressBarB.Value = 0;
                labelRychlostA.Text = "-";
                labelRychlostB.Text = "-";
                labelOdeslanoRychlostA.Text = "-";
                labelOdeslanoRychlostB.Text = "-";

                numericUpDownKritickaVzdalenost.Enabled = true;    //zpristupni nastaveni vzdalenosti, nastaveni hodnot pred zapocetim rizeni
                numericUpDownSledovanaVzdalenost.Enabled = true;
                numericUpDownSledovanaVzdalenost.Value = tempSledovanaVzdalenost;
                numericUpDownKritickaVzdalenost.Value = tempKritickaVzdalenost;

                tiskniCas();
                textBoxLog.AppendText(" STOP" + Environment.NewLine);
            }
        }

        private void timerWatchdog_Tick(object sender, EventArgs e)
        {
            byte[] vystupniBuffer = new byte[3];

            vystupniBuffer[0] = 0x00;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);
        }

        private void buttonNastavPrumerA_Click(object sender, EventArgs e)
        {
            int prumerA;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            prumerA = Convert.ToInt16(textPrumerA.Text);
            if (prumerA > 2000) prumerA = 2000;
            if (prumerA < 1) prumerA = 1;

            vystupniBuffer[0] = 0xE0;
            vystupniBuffer[1] = (byte)(prumerA / 256);
            vystupniBuffer[2] = (byte)(prumerA % 256);
            UARTposli(vystupniBuffer);


            System.Threading.Thread.Sleep(50);      //pockat a odeslat pozadavek na prepocitani
            vystupniBuffer[0] = 0xE4;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavPrumerB_Click(object sender, EventArgs e)
        {
            int prumerB;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            prumerB = Convert.ToInt16(textPrumerB.Text);
            if (prumerB > 2000) prumerB = 2000;
            if (prumerB < 1) prumerB = 1;

            vystupniBuffer[0] = 0xE1;
            vystupniBuffer[1] = (byte)(prumerB / 256);
            vystupniBuffer[2] = (byte)(prumerB % 256);
            UARTposli(vystupniBuffer);

            System.Threading.Thread.Sleep(50);      //pockat a odeslat pozadavek na prepocitani
            vystupniBuffer[0] = 0xE4;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavRozchod_Click(object sender, EventArgs e)
        {
            int rozchod;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            rozchod = Convert.ToInt16(textRozchod.Text);
            if (rozchod > 20000) rozchod = 20000;
            if (rozchod < 1) rozchod = 1;

            vystupniBuffer[0] = 0xE2;
            vystupniBuffer[1] = (byte)(rozchod / 256);
            vystupniBuffer[2] = (byte)(rozchod % 256);
            UARTposli(vystupniBuffer);

            System.Threading.Thread.Sleep(50);      //pockat a odeslat pozadavek na prepocitani
            vystupniBuffer[0] = 0xE4;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavImpulsy_Click(object sender, EventArgs e)
        {
            int impulsy;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            impulsy = Convert.ToInt16(textImpulsy.Text);
            if (impulsy > 20000) impulsy = 20000;
            if (impulsy < 1) impulsy = 1;

            vystupniBuffer[0] = 0xE3;
            vystupniBuffer[1] = (byte)(impulsy / 256);
            vystupniBuffer[2] = (byte)(impulsy % 256);
            UARTposli(vystupniBuffer);

            System.Threading.Thread.Sleep(50);      //pockat a odeslat pozadavek na prepocitani
            vystupniBuffer[0] = 0xE4;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavOmezeniAkcelerace_Click(object sender, EventArgs e)
        {
            int akcelerace;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            akcelerace = Convert.ToInt16(textAkcelerace.Text);
            if (akcelerace > 255) akcelerace = 255;
            if (akcelerace < 1) akcelerace = 1;

            vystupniBuffer[0] = 0xE5;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = (byte)akcelerace;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavKd_Click(object sender, EventArgs e)
        {
            int K;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            K = Convert.ToInt16(textKD.Text);
            if (K > 255) K = 255;
            if (K < 1) K = 1;

            vystupniBuffer[0] = 0xE7;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = (byte)K;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavKp_Click(object sender, EventArgs e)
        {
            int K;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            K = Convert.ToInt16(textKp.Text);
            if (K > 255) K = 255;
            if (K < 1) K = 1;

            vystupniBuffer[0] = 0xE6;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = (byte)K;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonNastavKi_Click(object sender, EventArgs e)
        {
            int K;
            byte[] vystupniBuffer = new byte[3];

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            K = Convert.ToInt16(textKi.Text);
            if (K > 255) K = 255;
            if (K < 1) K = 1;

            vystupniBuffer[0] = 0xE8;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = (byte)K;
            UARTposli(vystupniBuffer);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private int UARTprijmi(byte instrukce, ref byte[] pole)
        {
            byte[] tempPole = new byte[12];
            byte[] vystupniBuffer = new byte[3];

            if (!serialPort.IsOpen)
            {
                tiskniCas();
                textBoxLog.AppendText(" data nepřijata, port zavřen" + Environment.NewLine);
                return -1;
            }

            serialPort.DiscardInBuffer();

            vystupniBuffer[0] = instrukce;       //odeslani pozadavku
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);

            System.Threading.Thread.Sleep(50);

            if (serialPort.BytesToRead != 12)   // musi prijit 12 bytu
            {
                tiskniCas();
                textBoxLog.AppendText(" paket nekompletni, prijato " + serialPort.BytesToRead + "B" + Environment.NewLine);
                return -1;
            }

            serialPort.Read(pole, 0, 12);

            tiskniCas();
            textBoxLog.AppendText(" PŘIJATO: " + pole[0].ToString() + "  " + pole[1].ToString() + "  " + pole[2].ToString() + "  " + pole[3].ToString() + "  " + pole[4].ToString() + "  " + pole[5].ToString() + "  " + pole[6].ToString() + "  " + pole[7].ToString() + "  " + pole[8].ToString() + "  " + pole[9].ToString() + "  " + pole[10].ToString() + "  " + pole[11].ToString() + Environment.NewLine);

            byte soucet = (byte)(pole[0] + pole[1] + pole[2] + pole[3] + pole[4] + pole[5] + pole[6] + pole[7] + pole[8] + pole[9] + pole[10]);

            if (soucet != pole[11])
            {
                tiskniCas();
                textBoxLog.AppendText(" neplatny kontrolni soucet: " + soucet.ToString() + " != " + pole[11].ToString() + Environment.NewLine);
                return -1;
            }

            return 1;
        }

        private void buttonNactiOdometrii_Click(object sender, EventArgs e)
        {
            byte[] vstupniBuffer = new byte[12];
            int temp;

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            temp = UARTprijmi(0xF0, ref vstupniBuffer);

            if (temp != 1)      //pokud prijdou spatna data (chybova hlaska je generovana v ramci metody UARTprijmi)
            {
                if (buttonStartStop.Text == "STOP")
                    RizeniPovoleno = true;     //obnoveni prenosu informace k motorum

                return;
            }

            labelPolohaX.Text = (vstupniBuffer[0] * 256 + vstupniBuffer[1] - 0x7FFF).ToString() + " mm";
            labelPolohaY.Text = (vstupniBuffer[2] * 256 + vstupniBuffer[3] - 0x7FFF).ToString() + " mm";
            labelUhel.Text = (vstupniBuffer[4] * 256 + vstupniBuffer[5]).ToString() + " mRad" + Environment.NewLine + ((vstupniBuffer[4] * 256 + vstupniBuffer[5]) * 0.05729).ToString() + " °";
            labelNapeti.Text = (vstupniBuffer[6] * 256 + vstupniBuffer[7]).ToString() + " mV";
            labelRychlostA.Text = vstupniBuffer[9].ToString();
            labelRychlostB.Text = vstupniBuffer[10].ToString();

            tiskniCas();
            textBoxLog.AppendText(" odometrie aktualizována" + Environment.NewLine);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void button1_Click(object sender, EventArgs e)
        {
            byte[] vstupniBuffer = new byte[12];
            int temp;

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            temp = UARTprijmi(0xF1, ref vstupniBuffer);

            if (temp != 1)      //pokud prijdou spatna data (chybova hlaska je generovana v ramci metody UARTprijmi)
            {
                if (buttonStartStop.Text == "STOP")
                    RizeniPovoleno = true;     //obnoveni prenosu informace k motorum

                return;
            }

            labelPrumerKolaA.Text = (vstupniBuffer[0] * 256 + vstupniBuffer[1]).ToString() + " mm";
            labelPrumerKolaB.Text = (vstupniBuffer[2] * 256 + vstupniBuffer[3]).ToString() + " mm";
            labelRozchod.Text = (vstupniBuffer[4] * 256 + vstupniBuffer[5]).ToString() + " mm";
            labelImpulsuNaOtacku.Text = (vstupniBuffer[6] * 256 + vstupniBuffer[7]).ToString();
            labelDrahaNaImpuls.Text = (vstupniBuffer[8] * 256 + vstupniBuffer[9]).ToString() + " um";

            tiskniCas();
            textBoxLog.AppendText(" Konfigurace podvozku aktualizována" + Environment.NewLine);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void button2_Click(object sender, EventArgs e)
        {
            byte[] vstupniBuffer = new byte[12];
            int temp;

            RizeniPovoleno = false;     //pozastaveni prenosu informace k motorum

            temp = UARTprijmi(0xF2, ref vstupniBuffer);

            if (temp != 1)      //pokud prijdou spatna data (chybova hlaska je generovana v ramci metody UARTprijmi)
            {
                if (buttonStartStop.Text == "STOP")
                    RizeniPovoleno = true;     //obnoveni prenosu informace k motorum

                return;
            }

            labelAkcelerace.Text = vstupniBuffer[0].ToString();
            labelKp.Text = vstupniBuffer[1].ToString();
            labelKd.Text = vstupniBuffer[2].ToString();
            labelKi.Text = vstupniBuffer[3].ToString();
            labelRealRychlostA.Text = ((vstupniBuffer[4] * 256 + vstupniBuffer[5]) - 0x7FFF).ToString();
            labelRealRychlostB.Text = ((vstupniBuffer[6] * 256 + vstupniBuffer[7]) - 0x7FFF).ToString();

            switch (vstupniBuffer[10])
            {
                case 0: { labelTypRegulace.Text = "A:mom B:mom"; break; }
                case 1: { labelTypRegulace.Text = "A:reg B:mom"; break; }
                case 2: { labelTypRegulace.Text = "A:mom B:reg"; break; }
                case 3: { labelTypRegulace.Text = "A:reg B:reg"; break; }
            }

            tiskniCas();
            textBoxLog.AppendText(" Data regulátoru aktualizována" + Environment.NewLine);

            if (buttonStartStop.Text == "STOP")
                RizeniPovoleno = true;     //obnoveni prenosu informace k motorum
        }

        private void buttonVymazLog_Click(object sender, EventArgs e)
        {
            textBoxLog.Clear();
        }

        private void buttonVypnoutVystupy_Click(object sender, EventArgs e)
        {
            byte[] vystupniBuffer = new byte[3];

            vystupniBuffer[0] = 0xB0;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);

            //prebarveni tlacitek
            buttonVystup1.BackColor = Color.Red;
            buttonVystup2.BackColor = Color.Red;
            buttonVystup3.BackColor = Color.Red;
            buttonVystup4.BackColor = Color.Red;
            buttonVystup5.BackColor = Color.Red;
            buttonVystup6.BackColor = Color.Red;
            buttonVystup7.BackColor = Color.Red;
            buttonVystup8.BackColor = Color.Red;
        }

        private void buttonWatchDogOnOff_Click(object sender, EventArgs e)
        {
            if (buttonWatchDogOnOff.Text == "Vypnout")
            {
                timerWatchdog.Enabled = false;
                buttonWatchDogOnOff.Text = "Zapnout";
            }
            else
            {
                timerWatchdog.Enabled = true;
                buttonWatchDogOnOff.Text = "Vypnout";
            }
        }

        private void comboBoxZpusobRizeni_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxZpusobRizeni.SelectedIndex == 1)
            {
                label15.Enabled = false;
                numericUpDownRampaAkcelerace.Enabled = false;
            }
            else
            {
                label15.Enabled = true;
                numericUpDownRampaAkcelerace.Enabled = true;
            }
        }

        private void VykresliPoziciJoysticku(int tempX, int tempY, int tempZ, int tempZred)  //vykresli hodnoty prectene z joysticku na progressbary (pretizeno pro pripad prijeti dat z WiFi)
        {
            progressBarX.Value = tempX;
            progressBarY.Value = ROZSAH_JOYSTICKU - tempY;
            progressBarZ.Value = ROZSAH_JOYSTICKU - tempZ;
            progressBarZred.Value = tempZred;
            labelX.Text = (tempX).ToString();
            labelY.Text = (ROZSAH_JOYSTICKU - tempY).ToString();
            labelZ.Text = (ROZSAH_JOYSTICKU - tempZ).ToString();
            labelZred.Text = tempZred.ToString();
            pictureBoxPoziceJoysticku.Refresh();
        }

        private void VykresliPoziciJoysticku()  //vykresli hodnoty prectene z joysticku na progressbary
        {
            joystick.GetData();

            progressBarX.Value = joystick.State.X;
            progressBarY.Value = ROZSAH_JOYSTICKU - joystick.State.Y;
            progressBarZ.Value = progressBarZred.Value = ROZSAH_JOYSTICKU - joystick.State.Z;
            labelX.Text = (joystick.State.X).ToString();
            labelY.Text = (ROZSAH_JOYSTICKU - joystick.State.Y).ToString();
            labelZ.Text = labelZred.Text = (ROZSAH_JOYSTICKU - joystick.State.Z).ToString();
            pictureBoxPoziceJoysticku.Refresh();
        }

        private void OdesliPovelyMotorum(int X, int Y, int Z)      //podle prijatych hodnot vypocita povely, ktere odesle motorum
        {
            int offset = ROZSAH_JOYSTICKU / 2, tempX, tempY, tempA_minula, tempB_minula;
            byte[] vystupniBuffer = new byte[3];
            float tempA, tempB, zesileni;

            if (labelOdeslanoRychlostA.Text == "-")
            {      //zjisteni minule rychlosti A kvuli vypoctu omezeni akcelerace
                tempA_minula = 127;
            }
            else
            {
                tempA_minula = Convert.ToInt16(labelOdeslanoRychlostA.Text);
            }

            if (labelOdeslanoRychlostB.Text == "-")
            {      //zjisteni minule rychlosti B kvuli vypoctu omezeni akcelerace
                tempB_minula = 127;
            }
            else
            {
                tempB_minula = Convert.ToInt16(labelOdeslanoRychlostB.Text);
            }

            zesileni = (Z / (float)ROZSAH_JOYSTICKU);

            #region vypocet rychlosti A,B
            if ((JoystickXUvnitrThreshold(X) && JoystickYUvnitrThreshold(Y)) == false)   //pokud lezi hodnota v pasmu necitlivosti joysticku, je nastavena na 127
            {
                if (JoystickXUvnitrThreshold(X) == true)
                    X = 127;
                if (JoystickYUvnitrThreshold(Y) == true)
                    Y = 127;

                tempX = X - offset;
                tempY = (ROZSAH_JOYSTICKU - Y) - offset;

                tempA = ((tempY + tempX) * zesileni) + offset;
                tempB = ((tempY - tempX) * zesileni) + offset;

                if (tempA > ROZSAH_JOYSTICKU) tempA = ROZSAH_JOYSTICKU;
                if (tempB > ROZSAH_JOYSTICKU) tempB = ROZSAH_JOYSTICKU;
                if (tempA < 0) tempA = 0;
                if (tempB < 0) tempB = 0;
            }
            else
            {
                tempA = 127;
                tempB = 127;
            }

            progressBarA.Value = (int)tempA;
            progressBarB.Value = (int)tempB;
            labelRychlostA.Text = ((int)tempA).ToString();
            labelRychlostB.Text = ((int)tempB).ToString();
            #endregion

            #region vypocet_vzdalenosti_sledovane_UZ    
            //vypocitava prirustek sledovane a kriticke vzdalenosti pro UZ, dle rychlosti

            int bDoprednaRychlost = Math.Abs((((int)tempA - ROZSAH_JOYSTICKU / 2) + ((int)tempB - ROZSAH_JOYSTICKU / 2)) / 2);

            try
            {
                numericUpDownSledovanaVzdalenost.Value = tempSledovanaVzdalenost + (int)((255 - tempSledovanaVzdalenost) * ((bDoprednaRychlost / (float)(ROZSAH_JOYSTICKU / 2))));
                numericUpDownKritickaVzdalenost.Value = numericUpDownSledovanaVzdalenost.Value - (tempSledovanaVzdalenost - tempKritickaVzdalenost);
            }
            catch (System.ArgumentOutOfRangeException)
            {
                numericUpDownSledovanaVzdalenost.Value = 255;
                numericUpDownKritickaVzdalenost.Value = numericUpDownSledovanaVzdalenost.Value - (tempSledovanaVzdalenost - tempKritickaVzdalenost);
            }
            #endregion

            if (comboBoxZpusobRizeni.SelectedIndex == 0)
            {
                #region momentove rizeni
                //vypocet ramp

                bool aZpomaluje = false, bZpomaluje = false;    //nabyva hodnoty true kdyz vozik zpomaluje

                if (tempA - tempA_minula < 0 && tempA_minula > 127) aZpomaluje = true;
                if (tempA - tempA_minula > 0 && tempA_minula < 127) aZpomaluje = true;
                if (tempB - tempB_minula < 0 && tempB_minula > 127) bZpomaluje = true;
                if (tempB - tempB_minula > 0 && tempB_minula < 127) bZpomaluje = true;

                if (aZpomaluje == false)
                {
                    if (Math.Abs(tempA - tempA_minula) > ((float)numericUpDownRampaAkcelerace.Value / 10f))
                    {
                        if (tempA - tempA_minula >= 0)
                        {
                            tempA = (float)(tempA_minula + (float)numericUpDownRampaAkcelerace.Value / 10f);
                        }
                        else
                        {
                            tempA = (float)(tempA_minula - (float)numericUpDownRampaAkcelerace.Value / 10f);
                        }
                    }
                }

                if (bZpomaluje == false)
                {
                    if (Math.Abs(tempB - tempB_minula) > ((float)numericUpDownRampaAkcelerace.Value / 10f))
                    {
                        if (tempB - tempB_minula >= 0)
                        {
                            tempB = (float)(tempB_minula + (float)numericUpDownRampaAkcelerace.Value / 10f);
                        }
                        else
                        {
                            tempB = (float)(tempB_minula - (float)numericUpDownRampaAkcelerace.Value / 10f);
                        }
                    }
                }

                //vypocet ramp
                vystupniBuffer[0] = 0xC0;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = (byte)tempA;
                UARTposli(vystupniBuffer);

                vystupniBuffer[0] = 0xC1;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = (byte)tempB;
                UARTposli(vystupniBuffer);
                #endregion
            }
            else
            {
                #region rychlostni rizeni
                float tempRychlostA, tempRychlostB;

                tempRychlostA = tempA * (float)(0xFFFF / ROZSAH_JOYSTICKU);  //OxFFFF = maximalni mozna nastavitelna rychlost A
                tempRychlostB = tempB * (float)(0xFFFF / ROZSAH_JOYSTICKU);  //OxFFFF = maximalni mozna nastavitelna rychlost B

                if (tempRychlostA > 0xFFFF) tempRychlostA = 0xFFFF;
                if (tempRychlostB > 0xFFFF) tempRychlostB = 0xFFFF;
                if (tempRychlostA < 0) tempRychlostA = 0;
                if (tempRychlostB < 0) tempRychlostB = 0;

                vystupniBuffer[0] = 0xC2;
                vystupniBuffer[1] = (byte)(tempRychlostA / 256);
                vystupniBuffer[2] = (byte)(tempRychlostA % 256);
                UARTposli(vystupniBuffer);

                vystupniBuffer[0] = 0xC3;
                vystupniBuffer[1] = (byte)(tempRychlostB / 256);
                vystupniBuffer[2] = (byte)(tempRychlostB % 256);
                UARTposli(vystupniBuffer);
                #endregion
            }

            labelOdeslanoRychlostA.Text = ((int)tempA).ToString();
            labelOdeslanoRychlostB.Text = ((int)tempB).ToString();
        }

        private void buttonResetX_Click(object sender, EventArgs e)
        {
            byte[] vystupniBuffer = new byte[3];

            vystupniBuffer[0] = 0xA0;
            vystupniBuffer[1] = 0x7F;
            vystupniBuffer[2] = 0xFF;
            UARTposli(vystupniBuffer);
        }

        private void buttonResetY_Click(object sender, EventArgs e)
        {
            byte[] vystupniBuffer = new byte[3];

            vystupniBuffer[0] = 0xA1;
            vystupniBuffer[1] = 0x7F;
            vystupniBuffer[2] = 0xFF;
            UARTposli(vystupniBuffer);
        }

        private void buttonResetUhel_Click(object sender, EventArgs e)
        {
            byte[] vystupniBuffer = new byte[3];

            vystupniBuffer[0] = 0xA2;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);
        }

        private void buttonResetVse_Click(object sender, EventArgs e)
        {
            byte[] vystupniBuffer = new byte[3];

            vystupniBuffer[0] = 0xA3;
            vystupniBuffer[1] = 0x00;
            vystupniBuffer[2] = 0x00;
            UARTposli(vystupniBuffer);
        }

        private void buttonOdometrieStartStop_Click(object sender, EventArgs e)
        {
            if (buttonOdometrieStartStop.Text == "START")   //odstartuje odometrii on-line
            {
                byte[] vstupniBuffer = new byte[12];

                VykresliPocatek();

                //pocatecni nacteni polohy X a Y a uhlu
                int i = UARTprijmi(0xF0, ref vstupniBuffer);

                if (i != 1)      //spatna data
                {
                    return;
                }

                Xminule = (int)(vstupniBuffer[0] * 256 + vstupniBuffer[1] - 0x7FFF);
                Yminule = (int)(vstupniBuffer[2] * 256 + vstupniBuffer[3] - 0x7FFF);
                Xminule = (pictureBoxOdometrie.Height / 2) + (int)((0.001 * Xminule) * (pictureBoxOdometrie.Width / 2));
                Yminule = (pictureBoxOdometrie.Width / 2) - (int)((0.001 * Yminule) * (pictureBoxOdometrie.Height / 2));
                uhelMinule = (int)(vstupniBuffer[4] * 256 + vstupniBuffer[5]);
                //pocatecni nacteni polohy X a Y a uhlu

                buttonOdometrieStartStop.Text = "STOP";
                timerOdometrie.Enabled = true;
            }
            else
            {
                buttonOdometrieStartStop.Text = "START";
                timerOdometrie.Enabled = false;
            }
        }

        private void numericUpDownIntervalObnoveniOdometrie_ValueChanged(object sender, EventArgs e)
        {
            timerOdometrie.Interval = Convert.ToInt16(numericUpDownIntervalObnoveniOdometrie.Value) * 1000;
        }

        private void timerOdometrie_Tick(object sender, EventArgs e)
        {
            byte[] vstupniBuffer = new byte[12];
            int X, Y, Uhel;

            int i = UARTprijmi(0xF0, ref vstupniBuffer);

            if (i != 1)      //spatna data
            {
                return;
            }

            X = (int)(vstupniBuffer[0] * 256 + vstupniBuffer[1] - 0x7FFF);
            Y = (int)(vstupniBuffer[2] * 256 + vstupniBuffer[3] - 0x7FFF);
            Uhel = (int)(vstupniBuffer[4] * 256 + vstupniBuffer[5]);

            VykresliTrajektorii(X, Y, Uhel);

            textBoxUhel.Text = Uhel.ToString();
            textBoxOdometrie.AppendText(X + "    " + Y + "    " + Uhel + Environment.NewLine);
        }

        private void VykresliTrajektorii(int X, int Y, int Uhel)
        {
            Pen pero = new Pen(Color.Black, 1f);
            int tempX, tempY;

            tempX = (pictureBoxOdometrie.Height / 2) + (int)((/*meritko*/(1 / (float)iMeritko) * 0.001 * X) * (pictureBoxOdometrie.Width / 2));
            tempY = (pictureBoxOdometrie.Width / 2) - (int)((/*meritko*/(1 / (float)iMeritko) * 0.001 * Y) * (pictureBoxOdometrie.Height / 2));

            platno.DrawLine(pero, Xminule, Yminule, tempX, tempY);

            Xminule = tempX;
            Yminule = tempY;
            uhelMinule = Uhel;

            if (tempX < 0 || tempX > pictureBoxOdometrie.Width || tempY < 0 || tempY > pictureBoxOdometrie.Height)  //pokud je zobrazovany bod mimo picturebox, zvetsi meritko
                buttonMeritkoPlus_Click(new object(), new EventArgs());
        }

        private void VykresliPocatek()      //smaze platno
        {
            pictureBoxOdometrie.Refresh();
        }

        private void VykresliVozik(int X, int Y, int Uhel)     //x,y,uhel v miliradianech
        {
            Pen pero = new Pen(Color.Red, 2f);
            int tempUhel;

            tempUhel = Uhel / 1000;

            platno.DrawLine(pero, X, Y, X + (float)(10 * Math.Cos(tempUhel)), Y - (float)(10 * Math.Sin(tempUhel)));
        }

        private void buttonVymazPBOdometrie_Click(object sender, EventArgs e)
        {
            VykresliPocatek();
        }

        private void buttonZobrazVozik_Click(object sender, EventArgs e)
        {
            VykresliVozik(Xminule, Yminule, uhelMinule);
        }

        private void pictureBoxOdometrie_MouseMove(object sender, MouseEventArgs e)
        {
            labelPoziceKurzoruX.Text = "X: " + Math.Round(((MousePosition.X - (pictureBoxOdometrie.Left + (pictureBoxOdometrie.Width / 2) + this.Left + 7.5)) / ((1 / (float)iMeritko)/*meritko*/* (float)(pictureBoxOdometrie.Width / 2))), 3).ToString() + " m";
            labelPoziceKurzoruY.Text = "Y: " + (-1 * Math.Round(((MousePosition.Y - (pictureBoxOdometrie.Top + (pictureBoxOdometrie.Height / 2) + this.Top + 51.5)) / ((1 / (float)iMeritko)/*meritko*/* (float)(pictureBoxOdometrie.Width / 2))), 3)).ToString() + " m ";
        }

        private void pictureBoxOdometrie_MouseLeave(object sender, EventArgs e)
        {
            labelPoziceKurzoruX.Text = "X: ";
            labelPoziceKurzoruY.Text = "Y: ";
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            textBoxOdometrie.Clear();
        }

        private bool JoystickXUvnitrThreshold(int X)     //zjisti, zda je osa X joysticku uvnitr pasma necitlivosti
        {
            int threshold = (int)((ROZSAH_JOYSTICKU / 2) * ((float)numericUpDownThresholdPerc.Value / 100.0));

            if ((ROZSAH_JOYSTICKU / 2 - threshold) > X || (ROZSAH_JOYSTICKU / 2 + threshold) < X)
                return false;

            return true;
        }

        private bool JoystickYUvnitrThreshold(int Y)     //zjisti, zda je osa Y joysticku uvnitr pasma necitlivosti
        {
            int threshold = (int)((ROZSAH_JOYSTICKU / 2) * ((float)numericUpDownThresholdPerc.Value / 100.0));

            if ((ROZSAH_JOYSTICKU / 2 - threshold) > Y || (ROZSAH_JOYSTICKU / 2 + threshold) < Y)
                return false;

            return true;
        }

        private void buttonWebkameraStart_Click(object sender, EventArgs e)
        {
            buttonNastaveniKamery.Enabled = true;
            checkBoxOdeslatObraz.Enabled = true;
            checkBoxOdeslatObraz.Checked = true;

            if (_kamera != null && _kamera.Camera == comboBoxWebkamera.SelectedItem)    //return kdyz vybereme stejnou kameru
                return;

            wcDeaktivujKameru();
            wcZacitSnimat();
        }

        private void buttonWebkameraStop_Click(object sender, EventArgs e)
        {
            buttonNastaveniKamery.Enabled = false;
            checkBoxOdeslatObraz.Enabled = false;
            checkBoxOdeslatObraz.Checked = false;

            timerObraz.Enabled = false;
            buttonZacitOdesilatObraz.Text = "Zahájit přenos";

            wcDeaktivujKameru();
        }

        private void wcZacitSnimat()      //zacne snimat obrazy z webkamery
        {
            try
            {
                Camera kamera = (Camera)comboBoxWebkamera.SelectedItem;
                wcNastavZdrojovouKameru(new CameraFrameSource(kamera));
                _kamera.Camera.CaptureWidth = 320;
                _kamera.Camera.CaptureHeight = 240;
                _kamera.Camera.Fps = 15;
                _kamera.NewFrame += wcEventZachycenFrame;

                pictureBoxWebmamera.Paint += new PaintEventHandler(wcVykresliPosledniFrame);
                _kamera.StartFrameCapture();
            }
            catch (Exception ex)
            {
                comboBoxWebkamera.Text = "Je nutno zvolit kameru";
                MessageBox.Show(ex.Message.ToString(), "Pozor!", MessageBoxButtons.OK);
            }
        }

        private void wcVykresliPosledniFrame(object sender, PaintEventArgs e)       //vykresli do pictureboxu posledni obraz zachyceny kamerou
        {
            if (_posledniFrame != null)
            {
                // Vykreslit posledni zachyceny obrazek z kamery
                e.Graphics.DrawImage(_posledniFrame, 0, 0, pictureBoxWebmamera.Width, pictureBoxWebmamera.Height);
            }
        }

        private void wcDeaktivujKameru()        //odalokuje udalosti kamery
        {
            if (_kamera != null)
            {
                _kamera.NewFrame -= wcEventZachycenFrame;
                _kamera.Camera.Dispose();
                wcNastavZdrojovouKameru(null);
                pictureBoxWebmamera.Paint -= new PaintEventHandler(wcVykresliPosledniFrame);
            }
        }

        public void wcEventZachycenFrame(Touchless.Vision.Contracts.IFrameSource frameSource, Touchless.Vision.Contracts.Frame frame, double fps)       //udalost, ktera nastava pri prichozim framu
        {
            lock (oKlicObraz)
            {
                _posledniFrame = frame.Image;
                pictureBoxWebmamera.Invalidate();
            }
        }

        private void wcNastavZdrojovouKameru(CameraFrameSource zdrojovaKamera)      //vyber kamery, ze ktere budeme snimat
        {
            if (_kamera == zdrojovaKamera)
                return;

            _kamera = zdrojovaKamera;
        }

        private void timerObraz_Tick(object sender, EventArgs e)
        {
            try
            {
                if (checkBoxOdeslatObraz.Checked == true)
                {
                    if (_posledniFrame != null)
                    {
                        byte[] dataObraz;
                        MemoryStream ms = new MemoryStream();

                        lock (oKlicObraz)
                        {
                            _posledniFrame.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                        }

                        dataObraz = ms.ToArray();

                        byte[] dataUltrazvuk = new byte[10 + dataObraz.Length];      //delka obrazu + 8 bytu na data UZ

                        dataUltrazvuk[0] = (byte)(1 + 2 * Convert.ToByte(checkBoxOdeslatUZData.Checked));    //1-odesila se jenom obraz, 2-odesilaji se jenom data z UZ, 3-odesila se oboji 
                        
                        lock (oKlicUZ)
                        {
                            dataUltrazvuk[1] = FLVzdalenost;
                            dataUltrazvuk[2] = FRVzdalenost;
                            dataUltrazvuk[3] = RRVzdalenost;
                            dataUltrazvuk[4] = RLVzdalenost;
                        }

                        dataUltrazvuk[5] = (byte)(Convert.ToInt32(textBoxUhel.Text) & 0x000000ff);
                        dataUltrazvuk[6] = (byte)((Convert.ToInt32(textBoxUhel.Text) & 0x0000ff00) >> 8);
                        dataUltrazvuk[7] = (byte)(numericUpDownThresholdPerc.Value);
                        dataUltrazvuk[8] = (byte)(numericUpDownSledovanaVzdalenost.Value);
                        dataUltrazvuk[9] = (byte)(numericUpDownKritickaVzdalenost.Value);

                        for (int i = 10; i < dataUltrazvuk.Length; i++)
                            dataUltrazvuk[i] = dataObraz[i - 10];

                        odchoziKlient.Send(dataUltrazvuk, dataUltrazvuk.Length, textBoxIP.Text, Convert.ToInt32(numericUpDownOdchoziPort.Value));  //odesle obraz pres wifi
                    }
                }
                else
                {
                    byte[] dataUltrazvuk = new byte[10];

                    dataUltrazvuk[0] = (byte)2;    //1-odesila se jenom obraz, 2-odesilaji se jenom data z UZ, 3-odesila se oboji 
                    
                    lock (oKlicUZ)
                    {
                        dataUltrazvuk[1] = FLVzdalenost;
                        dataUltrazvuk[2] = FRVzdalenost;
                        dataUltrazvuk[3] = RRVzdalenost;
                        dataUltrazvuk[4] = RLVzdalenost;
                    }

                    dataUltrazvuk[5] = (byte)(Convert.ToInt32(textBoxUhel.Text) & 0x000000ff);
                    dataUltrazvuk[6] = (byte)((Convert.ToInt32(textBoxUhel.Text) & 0x0000ff00) >> 8);
                    dataUltrazvuk[7] = (byte)(numericUpDownThresholdPerc.Value);
                    dataUltrazvuk[8] = (byte)(numericUpDownSledovanaVzdalenost.Value);
                    dataUltrazvuk[9] = (byte)(numericUpDownKritickaVzdalenost.Value);

                    odchoziKlient.Send(dataUltrazvuk, dataUltrazvuk.Length, textBoxIP.Text, Convert.ToInt32(numericUpDownOdchoziPort.Value));  //odesle obraz pres wifi                                  
                }
            }
            catch (System.Net.Sockets.SocketException exception)     //zachyceni vyjimky z duvodu poruseni sitoveho protokolu (napr. preteceni velikosti UDP ramce)
            {
                timerObraz.Enabled = false;
                buttonZacitOdesilatObraz.Text = "Zahájit přenos";

                MessageBox.Show(exception.Message.ToString() + ".", "Vyjímka SocketException!", MessageBoxButtons.OK);
            }
        }

        private void buttonZacitOdesilatObraz_Click(object sender, EventArgs e)
        {
            if (timerObraz.Enabled == false)
            {
                timerObraz.Enabled = true;
                buttonZacitOdesilatObraz.Text = "Ukončit přenos";
            }
            else
            {
                timerObraz.Enabled = false;
                buttonZacitOdesilatObraz.Text = "Zahájit přenos";
            }
        }

        private void numericUpDownIntervalObrazu_ValueChanged(object sender, EventArgs e)
        {
            timerObraz.Interval = Convert.ToInt32(numericUpDownIntervalObrazu.Value);
        }

        private void buttonNastaveniKamery_Click(object sender, EventArgs e)
        {
            if (_kamera != null)
                _kamera.Camera.ShowPropertiesDialog();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            wcDeaktivujKameru();
        }

        private void buttonVystup1_Click(object sender, EventArgs e)
        {
            if (buttonVystup1.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB1;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup1.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB1;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup1.BackColor = Color.Red;
            }
        }

        private void buttonVystup2_Click(object sender, EventArgs e)
        {
            if (buttonVystup2.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB2;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup2.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB2;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup2.BackColor = Color.Red;
            }
        }

        private void buttonVystup3_Click(object sender, EventArgs e)
        {
            if (buttonVystup3.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB3;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup3.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB3;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup3.BackColor = Color.Red;
            }
        }

        private void buttonVystup4_Click(object sender, EventArgs e)
        {
            if (buttonVystup4.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB4;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup4.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB4;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup4.BackColor = Color.Red;
            }
        }

        private void buttonVystup5_Click(object sender, EventArgs e)
        {
            if (buttonVystup5.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB5;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup5.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB5;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup5.BackColor = Color.Red;
            }
        }

        private void buttonVystup6_Click(object sender, EventArgs e)
        {
            if (buttonVystup6.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB6;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup6.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB6;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup6.BackColor = Color.Red;
            }
        }

        private void buttonVystup7_Click(object sender, EventArgs e)
        {
            if (buttonVystup7.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB7;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup7.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB7;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup7.BackColor = Color.Red;
            }
        }

        private void buttonVystup8_Click(object sender, EventArgs e)
        {
            if (buttonVystup8.BackColor == Color.Red)
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB8;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x01;
                UARTposli(vystupniBuffer);

                buttonVystup8.BackColor = Color.MediumSpringGreen;
            }
            else
            {
                byte[] vystupniBuffer = new byte[3];

                vystupniBuffer[0] = 0xB8;
                vystupniBuffer[1] = 0x00;
                vystupniBuffer[2] = 0x00;
                UARTposli(vystupniBuffer);

                buttonVystup8.BackColor = Color.Red;
            }
        }

        private void pictureBoxOrientaceVoziku_Paint(object sender, PaintEventArgs e)
        {
            Graphics platno = e.Graphics;

            platno.Clear(this.BackColor);
            platno.FillEllipse(new SolidBrush(Color.White), 0, 0, pictureBoxOrientaceVoziku.Width, pictureBoxOrientaceVoziku.Height);       //vnejsi kruznice
        }

        private void buttonMeritkoPlus_Click(object sender, EventArgs e)
        {
            if (iMeritko < 10000)
            {
                iMeritko *= 10;

                Xminule = (int)(((Xminule - pictureBoxOdometrie.Width / 2) / 10.0) + pictureBoxOdometrie.Width / 2);
                Yminule = (int)(((Yminule - pictureBoxOdometrie.Height / 2) / 10.0) + pictureBoxOdometrie.Height / 2);

                labelMeritko.Text = (2 * iMeritko).ToString() + " m";

                VykresliPocatek();
            }
        }

        private void buttonMeritkoMinus_Click(object sender, EventArgs e)
        {
            if (iMeritko > 1)
            {
                iMeritko /= 10;

                Xminule = (int)(((Xminule - pictureBoxOdometrie.Width / 2) * 10) + pictureBoxOdometrie.Width / 2);
                Yminule = (int)(((Yminule - pictureBoxOdometrie.Height / 2) * 10) + pictureBoxOdometrie.Height / 2);

                labelMeritko.Text = (2 * iMeritko).ToString() + " m";

                VykresliPocatek();
            }
        }

        private void comboBoxI2CPortSelection_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                if (serialPortUltrazvuk.IsOpen == false)
                    serialPortUltrazvuk.PortName = comboBoxI2CPortSelection.Text;
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message.ToString(), "Pozor!", MessageBoxButtons.OK);
            }

        }

        private void buttonOpenI2CPort_Click(object sender, EventArgs e)
        {
            if (!serialPortUltrazvuk.IsOpen)
            {
                try
                {
                    serialPortUltrazvuk.Open();
                }
                catch (Exception exc)
                {
                    MessageBox.Show(exc.Message.ToString(), "Pozor!", MessageBoxButtons.OK);
                }

                if (serialPortUltrazvuk.IsOpen)
                {
                    comboBoxI2CPortSelection.Enabled = false;
                    labelI2CPortStatus.Text = comboBoxI2CPortSelection.Text + " otevřen";
                    buttonOpenI2CPort.BackColor = Color.MediumSpringGreen;
                    buttonOpenI2CPort.Text = "ZAVŘÍT";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxI2CPortSelection.Text + " otevřen" + Environment.NewLine);
                }
                else
                {
                    labelI2CPortStatus.Text = comboBoxI2CPortSelection.Text + " otevření se nezdařilo";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxI2CPortSelection.Text + " otevření se nezdařilo" + Environment.NewLine);
                }
            }
            else
            {
                serialPortUltrazvuk.Close();

                if (!serialPortUltrazvuk.IsOpen)
                {
                    buttonUltrazvukStartStop.Text = "Začít měřit";

                    comboBoxI2CPortSelection.Enabled = true;
                    labelI2CPortStatus.Text = comboBoxI2CPortSelection.Text + " zavřen";
                    buttonOpenI2CPort.BackColor = Color.Red;
                    buttonOpenI2CPort.Text = "OTEVŘÍT";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxI2CPortSelection.Text + " zavřen" + Environment.NewLine);
                }
                else
                {
                    labelI2CPortStatus.Text = comboBoxI2CPortSelection.Text + " zavření se nezdařilo";

                    tiskniCas();
                    textBoxLog.AppendText(comboBoxI2CPortSelection.Text + " zavření se nezdařilo" + Environment.NewLine);
                }
            }
        }

        private void buttonUltrazvukStartStop_Click(object sender, EventArgs e)
        {
            if (buttonUltrazvukStartStop.Text == "Začít měřit")
            {
                if (!serialPortUltrazvuk.IsOpen)
                {
                    MessageBox.Show("Port " + serialPortUltrazvuk.PortName.ToString() + " zavřen, nelze započít měření!", "Port zavřen!");
                    tiskniCas();
                    textBoxLog.AppendText(" port zavřen, nelze započít měření" + Environment.NewLine);
                }
                else
                {
                    if (SRF08_ProvedSelfTest() == true)
                    {
                        MereniPovoleno = true;

                        checkBoxOdeslatUZData.Enabled = true;
                        checkBoxOdeslatUZData.Checked = true;

                        i2cWatchdog = 0;

                        buttonUltrazvukStartStop.Text = "Ukončit měření";
                        tiskniCas();
                        textBoxLog.AppendText(" meření odstartováno" + Environment.NewLine);
                    }
                    else
                        MessageBox.Show("Self test modulů SRF-08 nebyl úspěšný!", "Pozor!");
                }
            }
            else
            {
                MereniPovoleno = false;

                checkBoxOdeslatUZData.Enabled = false;
                checkBoxOdeslatUZData.Checked = false;

                textBoxFLVzdalenost.Text = "255";
                textBoxFRVzdalenost.Text = "255";
                textBoxRLVzdalenost.Text = "255";
                textBoxRRVzdalenost.Text = "255";

                buttonUltrazvukStartStop.Text = "Začít měřit";
                tiskniCas();
                textBoxLog.AppendText(" Měření ukončeno" + Environment.NewLine);
            }
        }

        private void SRF08_ZapisDoRegistru(byte adresaZarizeni, byte adresaRegistru, byte prikaz)
        {
            if (adresaRegistru < 0 || adresaRegistru > 2)   //lze zapsat jen do registru 0-2
                return;

            byte[] bOdchoziData = new byte[5];

            bOdchoziData[0] = (byte)0x55;      //zarizeni s jednobytovou adresou registru (prikaz I2C_AD1)
            bOdchoziData[1] = adresaZarizeni;
            bOdchoziData[2] = adresaRegistru;
            bOdchoziData[3] = (byte)0x01;       //zapsat lze vzdy jen jeden byte
            bOdchoziData[4] = prikaz;

            serialPortUltrazvuk.Write(bOdchoziData, 0, bOdchoziData.Length);
        }

        private void SRF08_CtiZRegistru(byte adresaZarizeni, byte adresaRegistru, byte pocetBytu)
        {
            if (adresaRegistru < 0 || adresaRegistru > 35)   //lze cist jen z registru 0-35
                return;

            byte[] bOdchoziData = new byte[4];

            bOdchoziData[0] = (byte)0x55;      //zarizeni s jednobytovou adresou registru (prikaz I2C_AD1)
            bOdchoziData[1] = (byte)(adresaZarizeni + 1);   //pro cteni se pouziva adresa + 1
            bOdchoziData[2] = adresaRegistru;
            bOdchoziData[3] = (byte)pocetBytu;       //zapsat lze vzdy jen jeden byte

            serialPortUltrazvuk.Write(bOdchoziData, 0, bOdchoziData.Length);
        }

        private void SRF08_ZmerVzdalenost()
        {
            byte[] bPrijataData = new byte[5];

            serialPortUltrazvuk.ReadTimeout = 500;

            try
            {
                SRF08_ZapisDoRegistru((byte)srf08_Pozice.LP, 0x00, 0x51);    //0x51=vzdalenost v centimetrech

                serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                    throw new Exception();


                SRF08_ZapisDoRegistru((byte)srf08_Pozice.PP, 0x00, 0x51);    //0x51=vzdalenost v centimetrech

                serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                    throw new Exception();


                SRF08_ZapisDoRegistru((byte)srf08_Pozice.PZ, 0x00, 0x51);    //0x51=vzdalenost v centimetrech

                serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                    throw new Exception();


                SRF08_ZapisDoRegistru((byte)srf08_Pozice.LZ, 0x00, 0x51);    //0x51=vzdalenost v centimetrech

                serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                    throw new Exception();

                i2cWatchdog = 0;
            }
            catch
            {
                if (i2cWatchdog++ == 2)
                {
                    MereniPovoleno = false;

                    checkBoxOdeslatUZData.Enabled = false;
                    checkBoxOdeslatUZData.Checked = false;

                    buttonUltrazvukStartStop.Text = "Začít měřit";

                    if(buttonStartStop.Text=="STOP")    //pokud je aktivní řízení
                        buttonStartStop_Click(new object(), new EventArgs());    //zastavi rizeni

                    MessageBox.Show("I2C Watchdog aktivován, překontrolujte spojení a nastavení portu!", "I2C Watchdog Alert");
                }
                return;
            }

            SRF08_CtiZRegistru((byte)srf08_Pozice.LP, 0x02, 0x02);

            Thread.Sleep(30);

            try
            {
                serialPortUltrazvuk.Read(bPrijataData, 0, 2);
                textBoxFLVzdalenost.Text = ((bPrijataData[0] << 8) + bPrijataData[1]).ToString();
            }
            catch
            {
                textBoxFLVzdalenost.Text = "1";
            }

            SRF08_CtiZRegistru((byte)srf08_Pozice.PP, 0x02, 0x02);

            Thread.Sleep(30);

            try
            {
                serialPortUltrazvuk.Read(bPrijataData, 0, 2);
                textBoxFRVzdalenost.Text = ((bPrijataData[0] << 8) + bPrijataData[1]).ToString();
            }
            catch
            {
                textBoxFRVzdalenost.Text = "1";
            }

            SRF08_CtiZRegistru((byte)srf08_Pozice.PZ, 0x02, 0x02);

            Thread.Sleep(30);

            try
            {
                serialPortUltrazvuk.Read(bPrijataData, 0, 2);
                textBoxRRVzdalenost.Text = ((bPrijataData[0] << 8) + bPrijataData[1]).ToString();
            }
            catch
            {
                textBoxRRVzdalenost.Text = "1";
            }

            SRF08_CtiZRegistru((byte)srf08_Pozice.LZ, 0x02, 0x02);

            Thread.Sleep(30);

            try
            {
                serialPortUltrazvuk.Read(bPrijataData, 0, 2);
                textBoxRLVzdalenost.Text = ((bPrijataData[0] << 8) + bPrijataData[1]).ToString();
            }
            catch
            {
                textBoxRLVzdalenost.Text = "1";
            }

            if (Convert.ToInt32(textBoxFLVzdalenost.Text) == 0 || Convert.ToInt32(textBoxFLVzdalenost.Text) > 255)      //zajistime, aby byla data ve spravnem rozsahu
                textBoxFLVzdalenost.Text = "255";
            if (Convert.ToInt32(textBoxFRVzdalenost.Text) == 0 || Convert.ToInt32(textBoxFRVzdalenost.Text) > 255)      //zajistime, aby byla data ve spravnem rozsahu
                textBoxFRVzdalenost.Text = "255";
            if (Convert.ToInt32(textBoxRLVzdalenost.Text) == 0 || Convert.ToInt32(textBoxRLVzdalenost.Text) > 255)      //zajistime, aby byla data ve spravnem rozsahu
                textBoxRLVzdalenost.Text = "255";
            if (Convert.ToInt32(textBoxRRVzdalenost.Text) == 0 || Convert.ToInt32(textBoxRRVzdalenost.Text) > 255)      //zajistime, aby byla data ve spravnem rozsahu
                textBoxRRVzdalenost.Text = "255";

        }

        private void timerUltrazvuk_Tick(object sender, EventArgs e)
        {
            if (serialPortUltrazvuk.IsOpen && MereniPovoleno == true)
                SRF08_ZmerVzdalenost();

            lock(oKlicUZ)
            {
            FLVzdalenost = Convert.ToByte(textBoxFLVzdalenost.Text);
            FRVzdalenost = Convert.ToByte(textBoxFRVzdalenost.Text);
            RLVzdalenost = Convert.ToByte(textBoxRLVzdalenost.Text);
            RRVzdalenost = Convert.ToByte(textBoxRRVzdalenost.Text);
            }

            textBoxUhel.Text = uhelMinule.ToString();

            VykresliOrientaciVoziku();
        }

        private void buttonRefreshPort_Click(object sender, EventArgs e)
        {
            if (serialPort.IsOpen == false)
            {
                comboBoxPortSelection.Items.Clear();

                foreach (string port in SerialPort.GetPortNames())
                    comboBoxPortSelection.Items.Add(port);

                if (comboBoxPortSelection.Items.Count != 0)
                    comboBoxPortSelection.SelectedIndex = 0;                
            }

            if (serialPortUltrazvuk.IsOpen == false)
            {
                comboBoxI2CPortSelection.Items.Clear();

                foreach (string port in SerialPort.GetPortNames())
                    comboBoxI2CPortSelection.Items.Add(port);

                if (comboBoxI2CPortSelection.Items.Count != 0)
                    comboBoxI2CPortSelection.SelectedIndex = 0;
            }
            

        }

        private void VykresliOrientaciVoziku()
        {
            Color barvaFL, barvaFR, barvaRL, barvaRR;

            if (MereniPovoleno == false)    //pokud se nemeri, jsou laloky vykresleny sede, jinak se jejich barva meni ze zelene pres zlutou do cervene, dle namerenych hodnot 
            { 
                barvaFL = barvaFR = barvaRL = barvaRR = Color.Gray; 
            }
            else
            {
                if (FLVzdalenost <= numericUpDownSledovanaVzdalenost.Value)
                {
                    if (FLVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                        barvaFL = Color.Red;
                    else
                        barvaFL = Color.FromArgb(255 - (int)(255 * ((float)(FLVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))), 255, 0);   //prechod zelena->zluta dle vzdalenosti
                }
                else
                    barvaFL = Color.FromArgb(0, 255, 0);

                if (FRVzdalenost <= numericUpDownSledovanaVzdalenost.Value)
                {
                    if (FRVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                        barvaFR = Color.Red;
                    else
                        barvaFR = Color.FromArgb(255 - (int)(255 * ((float)(FRVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))), 255, 0);   //prechod zelena->zluta dle vzdalenosti
                }
                else
                    barvaFR = Color.FromArgb(0, 255, 0);

                if (RLVzdalenost <= numericUpDownSledovanaVzdalenost.Value)
                {
                    if (RLVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                        barvaRL = Color.Red;
                    else
                        barvaRL = Color.FromArgb(255 - (int)(255 * ((float)(RLVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))), 255, 0);   //prechod zelena->zluta dle vzdalenosti
                }
                else
                    barvaRL = Color.FromArgb(0, 255, 0);

                if (RRVzdalenost <= numericUpDownSledovanaVzdalenost.Value)
                {
                    if (RRVzdalenost <= numericUpDownKritickaVzdalenost.Value)
                        barvaRR = Color.Red;
                    else
                        barvaRR = Color.FromArgb(255 - (int)(255 * ((float)(RRVzdalenost - numericUpDownKritickaVzdalenost.Value) / (float)(numericUpDownSledovanaVzdalenost.Value - numericUpDownKritickaVzdalenost.Value))), 255, 0);   //prechod zelena->zluta dle vzdalenosti
                }
                else
                    barvaRR = Color.FromArgb(0, 255, 0);
            }

            Bitmap bitmapaTemp = new Bitmap(pictureBoxOrientaceVoziku.Width, pictureBoxOrientaceVoziku.Height);     //kresli se do teto  bitmapy a ne rovnou do pictureboxu, kvuli blikani obrazu
            Graphics platno = Graphics.FromImage(bitmapaTemp), platno2 = pictureBoxOrientaceVoziku.CreateGraphics();

            if (checkBoxAntiAliasing.Checked == true)
                platno.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;  //antialiasing

            Rectangle rect = new Rectangle(110, 110, 36, 36);
            Point[] FLtriagle = { new Point(110, 110), new Point(110 - 44, 0), new Point(1, 1), new Point(0, 110 - 44) };
            Point[] FRtriagle = { new Point(110 + 36, 110), new Point(255, 110 - 44), new Point(254, 1), new Point(110 + 36 + 44, 0) };
            Point[] RLtriagle = { new Point(110, 110 + 36), new Point(110 - 44, 255), new Point(1, 254), new Point(0, 110 + 36 + 44) };
            Point[] RRtriagle = { new Point(110 + 36, 110 + 36), new Point(255, 110 + 36 + 44), new Point(254, 254), new Point(110 + 36 + 44, 255) };

            System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();  //transformacni matice

            matrix.RotateAt((float)(((Convert.ToInt32(textBoxUhel.Text) / -1000.0) * (180 / Math.PI))+90), new PointF(128, 128));       //rotace voziku
            matrix.Scale((float)(1 / Math.Sqrt(2)), (float)(1 / Math.Sqrt(2)), System.Drawing.Drawing2D.MatrixOrder.Append);                 //zmenseni o odm. ze 2, aby se veslo do pictureboxu
            matrix.Translate((float)(pictureBoxOrientaceVoziku.Width * (1 - (1 / Math.Sqrt(2))) / 2.0), (float)(pictureBoxOrientaceVoziku.Height * (1 - (1 / Math.Sqrt(2))) / 2.0), System.Drawing.Drawing2D.MatrixOrder.Append);    //posunuti na stred 

            platno.Clear(this.BackColor);             //vymazani
            platno.FillEllipse(new SolidBrush(Color.White), 0, 0, pictureBoxOrientaceVoziku.Width, pictureBoxOrientaceVoziku.Height);       //vnejsi kruznice

            platno.Transform = matrix;
            platno.FillRectangle(new SolidBrush(Color.Black), rect);
            platno.DrawLine(new Pen(Color.Crimson, 2), new Point(110 + 36 / 2, 110 + 35), new Point(110 + 36 / 2, 111));  //sipka urcujici smer voziku
            platno.DrawLine(new Pen(Color.Crimson, 2), new Point(111, 110 + 10), new Point(110 + 36 / 2, 111));
            platno.DrawLine(new Pen(Color.Crimson, 2), new Point(110 + 35, 110 + 10), new Point(110 + 36 / 2, 111));


            platno.FillClosedCurve(new SolidBrush(barvaFL), FLtriagle);
            platno.FillClosedCurve(new SolidBrush(barvaFR), FRtriagle);
            platno.FillClosedCurve(new SolidBrush(barvaRR), RRtriagle);
            platno.FillClosedCurve(new SolidBrush(barvaRL), RLtriagle);

            platno2.DrawImage(bitmapaTemp, 0, 0);

            if (barvaFL == Color.Red || barvaFR == Color.Red || barvaRL == Color.Red || barvaRR == Color.Red)  //pokud je detekovan predmet blize nez kriticka vzdalenost, pipne
                Console.Beep(800, 20);
        }

        private void numericUpDownKritickaVzdalenost_ValueChanged(object sender, EventArgs e)
        {
            numericUpDownSledovanaVzdalenost.Minimum = numericUpDownKritickaVzdalenost.Value;
        }

        private void checkBoxOdeslatUZData_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxOdeslatObraz.Checked == false && checkBoxOdeslatUZData.Checked == false)
            {
                if (timerObraz.Enabled == true)
                    buttonZacitOdesilatObraz_Click(new object(), new EventArgs());

                buttonZacitOdesilatObraz.Enabled = false;
                numericUpDownIntervalObrazu.Enabled = false;
                label43.Enabled = false;    //label "interval odesilani obrazu"
                label44.Enabled = false;    //label "[ms]"
            }
            else
            {
                buttonZacitOdesilatObraz.Enabled = true;
                numericUpDownIntervalObrazu.Enabled = true;
                label43.Enabled = true;    //label "interval odesilani obrazu"
                label44.Enabled = true;    //label "[ms]"
            }
        }

        private void checkBoxOdeslatObraz_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBoxOdeslatObraz.Checked == false && checkBoxOdeslatUZData.Checked == false)
            {
                if (timerObraz.Enabled == true)
                    buttonZacitOdesilatObraz_Click(new object(), new EventArgs());

                buttonZacitOdesilatObraz.Enabled = false;
                numericUpDownIntervalObrazu.Enabled = false;
                label43.Enabled = false;    //label "interval odesilani obrazu"
                label44.Enabled = false;    //label "[ms]"
            }
            else
            {
                buttonZacitOdesilatObraz.Enabled = true;
                numericUpDownIntervalObrazu.Enabled = true;
                label43.Enabled = true;    //label "interval odesilani obrazu"
                label44.Enabled = true;    //label "[ms]"
            }
        }

        private void buttonNastavRozsahUZ_Click(object sender, EventArgs e)
        {
            if (serialPortUltrazvuk.IsOpen == true)
            {
                byte[] bPrijataData = new byte[5];

                serialPortUltrazvuk.ReadTimeout = 500;

                try
                {
                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.LP, 0x02, (byte)numericUpDownRozsahUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.LP).ToString());


                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.LZ, 0x02, (byte)numericUpDownRozsahUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.LZ).ToString());


                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.PP, 0x02, (byte)numericUpDownRozsahUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.PP).ToString());


                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.PZ, 0x02, (byte)numericUpDownRozsahUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.PZ).ToString());

                    MessageBox.Show("Nastavení proběhlo úspěšně!", "OK");
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Nezdařilo se, opakujte prosím akci!\n" + exc.Message, "Chyba!");
                }
            }
            else
            {
                MessageBox.Show("Není otevřen port!", "Pozor!");
            }
        }

        private void numericUpDownRozsahUZ_ValueChanged(object sender, EventArgs e)
        {
            labelRozsahUZmm.Text = "= " + (numericUpDownRozsahUZ.Value + 1) * 43 + " mm";
        }

        private void buttonNastavZesileniUZ_Click(object sender, EventArgs e)
        {
            if (serialPortUltrazvuk.IsOpen == true)
            {
                byte[] bPrijataData = new byte[5];

                serialPortUltrazvuk.ReadTimeout = 500;

                try
                {
                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.LP, 0x01, (byte)numericUpDownZesileniUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.LP).ToString());


                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.LZ, 0x01, (byte)numericUpDownZesileniUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.LZ).ToString());


                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.PP, 0x01, (byte)numericUpDownZesileniUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.PP).ToString());


                    SRF08_ZapisDoRegistru((byte)srf08_Pozice.PZ, 0x01, (byte)numericUpDownZesileniUZ.Value);

                    serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                    if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                        throw new Exception("Wrong respond from SRF08 module " + (srf08_Pozice.PZ).ToString());

                    MessageBox.Show("Nastavení proběhlo úspěšně!", "OK");
                }
                catch (Exception exc)
                {
                    MessageBox.Show("Nezdařilo se, opakujte prosím akci!\n" + exc.Message, "Chyba!");
                }
            }
            else
            {
                MessageBox.Show("Není otevřen port!", "Pozor!");
            }
        }

        private void buttonRefreshPrichoziIP_Click(object sender, EventArgs e)
        {
            IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());     //ziska lokalni hostitelske adresy
            labelMistniIP.Text = "IP:      " + localIPs[0].ToString();
        }

        private void numericUpDownIntevalMereniUZ_ValueChanged(object sender, EventArgs e)
        {
            timerUltrazvuk.Interval = (int)numericUpDownIntevalMereniUZ.Value;
        }

        private void comboBoxVstupniZarizeni_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (comboBoxVstupniZarizeni.SelectedIndex == 1)    //zvolen vstuo z WiFi
            {
                labelWifiwatchdog.Visible = true;
                pictureBoxWifiWatchdog.Visible = true;
            }
            else
            {
                labelWifiwatchdog.Visible = false;
                pictureBoxWifiWatchdog.Visible = false;
            }
        }

        private bool SRF08_ProvedSelfTest()
        { 
            //pred zacatkem mereni provede test pripojeni tim, ze se pokusi nastavi hodnoty zesileni a rozsahu
                byte[] bPrijataData = new byte[5];

                serialPortUltrazvuk.ReadTimeout = 500;

                try
                {
                    //nejprve zkusi nastavit zesileni
                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.LP, 0x01, (byte)numericUpDownZesileniUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.LZ, 0x01, (byte)numericUpDownZesileniUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.PP, 0x01, (byte)numericUpDownZesileniUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.PZ, 0x01, (byte)numericUpDownZesileniUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                    //nasleduje nastaveni rozsahu
                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.LP, 0x02, (byte)numericUpDownRozsahUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.LZ, 0x02, (byte)numericUpDownRozsahUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.PP, 0x02, (byte)numericUpDownRozsahUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;

                        SRF08_ZapisDoRegistru((byte)srf08_Pozice.PZ, 0x02, (byte)numericUpDownRozsahUZ.Value);

                        serialPortUltrazvuk.Read(bPrijataData, 0, 1);

                        if (bPrijataData[0] == 0)   //nezdaril se zapis do registru
                            return false;
                }
                catch (Exception)
                {
                    return false;
                }

            return true;    //v pripade uspechu vraci true
        }

        private void comboBoxPortSelection_EnabledChanged(object sender, EventArgs e)
        {
            if (comboBoxPortSelection.Enabled == false && comboBoxI2CPortSelection.Enabled == false)
                buttonRefreshPort.Enabled = false;
            else
                buttonRefreshPort.Enabled = true;
        }

        private void comboBoxI2CPortSelection_EnabledChanged(object sender, EventArgs e)
        {
            if (comboBoxPortSelection.Enabled == false && comboBoxI2CPortSelection.Enabled == false)
                buttonRefreshPort.Enabled = false;
            else
                buttonRefreshPort.Enabled = true;
        }

        private void buttonRefreshVstupniZarizeni_Click(object sender, EventArgs e)
        {
            try     //pokusi se znovu inicializovat joystick
            {
                joystick = new USB_Joystick(0, ROZSAH_JOYSTICKU, 0.2, this);
                joystick.PresetValues();
                buttonRefreshVstupniZarizeni.Visible = false;
                comboBoxVstupniZarizeni.Enabled = true;
            }
            catch (Exception)
            {
                MessageBox.Show("Nebylo možno inicializovat joystick", "Pozor!", MessageBoxButtons.OK);
                comboBoxVstupniZarizeni.Enabled = false;        //zakazeme pouzivani tohoto comboboxu, aby nebylo mozno zvolit joystick
                comboBoxVstupniZarizeni.SelectedIndex = 1;      //jako vstup zvolime wifi
                VykresliPoziciJoysticku(XminuleWIFI, YminuleWIFI, ZminuleWIFI, ZminuleWIFI);   //vykreslime pozici
                buttonRefreshVstupniZarizeni.Visible = true;    //zviditelni tlacitko pro pripadny refresh pripojeni joysticku
            }
        }
    }
}
