Operácie

Jednoduchá meteostanica s BMP180: Rozdiel medzi revíziami

Z SensorWiki

(Zadanie)
(Algoritmus a program)
 
(31 medziľahlých úprav od rovnakého používateľa nie je zobrazených.)
Riadok 4: Riadok 4:
 
|Študijný odbor:  || Aplikovaná mechatronika a elektromobilita || 1. Ing.  ('''2016''')  
 
|Študijný odbor:  || Aplikovaná mechatronika a elektromobilita || 1. Ing.  ('''2016''')  
 
|}
 
|}
 +
 +
__TOC__
  
 
== Zadanie ==
 
== Zadanie ==
  
Treba popísať ako funguje samotný senzor, ako sa pripojí k mikropočítaču a čo vlastne meria.  
+
Vytvoriť jednoduchú meteorologickú stanicu, ktorá bude merať atmosferický relatívny a absolutný tlak vzduchu a teplotu prostredia. Stanica bude pozostváť z digitálneho tlakového senzora BMP180, ktorý bude komunikovať prostredníctvom I2C rozhrania s embedded systémom RaspberryPI. Pomocou grafického použivateľského rozhrania bude používateľ informovaný o aktuálnej meteorogickej situácii.  
Vymyslieť vzorovú aplikáciu s vizualizáciou na PC.  
 
  
 
[[Súbor:senzor_bmp180.jpg|center|300px]]
 
[[Súbor:senzor_bmp180.jpg|center|300px]]
  
* Nájdite si k senzorom datasheet
 
* Nájdite si schémy zapojenia dosky
 
* Na základe predošlých vedomostí navrhnite spôsob pripojenia k riadiacej jednotke
 
* Napíšte základný demonštračný program využívajúci vaše funkcie
 
* Vymyslite a demonštrujte vhodnú aplikáciu
 
* Dokumentáciu odovzdajte prostredníctvom tejto wiki stránky.
 
  
 +
'''Literatúra:'''
 +
[https://cdn-shop.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf Datasheed BMP180]
 +
 +
 +
 +
== Analýza ==
 +
 +
'''BMP180'''
 +
 +
Senzor BMP180 vyrába firma Bosch, ide o nástupcu veľmi obľúbeného senzora BMP085. Senzor disponuje meraním atmosferického absolútného tlaku v rozsahu 300 až 1100 hPa. Pre kompenzáciu tepelných vplyvov na meranie atmosferického tlaku, má senzor integrovaný teplomer (merací rozsah -40 až +85°C), ktorý je taktiež možno vyčítať. Komunikácia je digitalná prostredníctvom I2C zbernice.
 +
 +
''' Jeho základné informácie: '''
 +
* Rozsah meracieho tlaku: 300 až 1100hPa (+9000m až -500m nad morom)
 +
* Napájacie napätie: 1.8 až 3.6 V (VDD), 1.62V až 3.6V (VDDIO)
 +
* Púzdro: LGA, Small footprint: 3.6mm x 3.8mm
 +
 +
* Nízka spotreba: 5μA pri 1 vzorke / sekundu (standard mode)
 +
* Nízky šum:
 +
**0.06hPa (0.5m) - ultra low power mode
 +
**0.02 hPa (0.17m) - advanced resolution mode
 +
 +
 +
* Vstavané teplotné čidlo
 +
* I2C rozhranie
 +
* plne kalibrovaný
 +
* Pb-free, halogen-free and RoHS compliant
 +
 +
''' Typické využitie '''
 +
* rozšírenie GPS navigácie
 +
* vnútorná-vonkajšia navigácia
 +
* voľnočasové aktivy/ šport
 +
* vertikálny ukazovateľ rýchlosti
 +
 +
 +
'''Popis komunikačnej zbernice'''
 +
 +
Tlakový senzor komunikuje prostredníctvom ľ2C zbernice, jeho adresa je:
 +
 +
* '''0xEF''' pre režím čitania
 +
* '''0xEE''' pre režím zápisu 
 +
 +
[[Súbor:add_bmp180_pins.jpg|300px]]
 +
 +
 +
'''Voľba režimov prevodu'''
 +
 +
Senzor môže pracovať v niekoľkých meracích režimov. Voľbou jednotlivých režimov senzora sa volí presnosť dosiahnutého výslednu (šum signálu) a zároveň sa volí rýchlosť prevodu. Nasledujúci obrázok zobrazuje jednotlivé režímy. 
 +
 +
[[Súbor:mode_bmp180.jpg|600px]]
 +
 +
Senzor disponuje vnútornou 176bit EEPROM pamäťou v ktorej je uložených 11 kalibračných koeficientov. Každý senzor má jedinečné koeficienty. Tieto koeficienty sú nahraná do senzora v procese výroby. Algoritmus pred prvým výpočtom tlaku a teploty vyčíta obsah tejto EEPROM pamäte, následne pomocou korečných výpočtov dopočíta korektné výsledky. Nasledujúci obrázok zobrazuje adresu jednotlivých adries kalibračných koeficientov. 
 +
 +
[[Súbor:calib_bmp180.jpg|250px]]
  
  
[http://www.example.com link title]
+
'''Algoritmus merania'''
  
[[Súbor:MojObrazok2.jpg|center|300px]]
+
Pre výpočet je dostupný ANSI C kód od Bosch Sensortec ("BMP180_API").
 +
Mikrokontrolér najskôr pošle start sekvenciu k inicializácii merania teploty a tlaku. Následne po uplynutí času prevodu, výsledné konštanty (UP alebo UT) sa môžu vyčítat prostredníctvom I2C rozhrania. Pre prepočet tlaku na hPa a teploty na °C, sa využijú kalibračné dáta z EEPROM pamäte.
 +
Vzorkovacia perióda senzora je do 128 vzoriek za sekundu (štandartný mód).     
  
[[Médiá:MojZdrojak.c]]
+
[[Súbor:algoritmus_bmp180.jpg|250px]]
  
 +
'''Prepočet RAW dát na unifikované jednotky [hPa/ °C]'''
  
'''Literatúra:'''
+
Nasledujúci obrázok zobrazuje prepočet RAW dát senzora  a unifikované jednotky
* Zoznam použitej literatúry, vrátane katalógových údajov (datasheet), internetových odkazov a pod.
+
 
 +
[[Súbor:calculation_bmp180.jpg|250px]]
 +
 
 +
 
 +
''' Priebehy I2C signálov
 +
 
 +
[[Súbor:i2c_1.jpg|400px]]
 +
 
 +
[[Súbor:i2c_2.jpg|400px]]
  
__TOC__
+
[[Súbor:i2c_3.jpg|400px]]
  
== Analýza ==
 
  
V tejto časti popíšete ako idete daný problém riešiť. Uvediete sem aj všetky potrebné technické údaje,
+
'''Zapojenie vývodov senzora'''
ktoré sú potrebné na úspešné vyriešenie projektu. Napríklad:
 
  
* popis komunikačnej zbernice (i2c, 1-wire, RS-232 a pod.)
+
[[Súbor:senzor_bmp180_pins.jpg|350px]]
* obrázok zapojenia vývodov použitej súčiastky
 
* odkaz na katalógový list
 
* priebehy dôležitých signálov
 
* este jedna polozka
 
  
 
== Popis riešenia ==
 
== Popis riešenia ==
  
Sem opíšete ako konkrétne ste problém vyriešili. Začnite popisom pripojenia k procesoru
+
Senzor BMP180 je osadený na doske plošného spoja spolu so stabilizátorom napätia (7133). Tento stabilizátor stabilizuje vstupné napätie (5 V) na 3,3 V, ktoré napája celý tlakový senzor. Ďalej na doske sú obsiahnuté pull-up rezistory R1, R2 pre I2C rozhranie. Senzor sa pripája k RaspberryPi pomocou konektora J1, ktorý obsahuje napájanie senzora VCC a GND, zbernicovú komunikáciu pre I2C rozhranie - SDA, SDL, signál pre povolenie senzora EOC.
(nezabudnite na schému zapojenia!) a zdôraznite ktoré jeho periférie ste pritom využili.  
 
  
 
'''Schéma zapojenia snímača'''
 
'''Schéma zapojenia snímača'''
[[Súbor:Zapojenie.png]]
 
  
[[Súbor:Example.jpg]]
 
  
Pozn.: Názov obrázku musí byť jedinečný, uvedomte si, že Obr1.jpg už pred vami skúsilo
 
nahrať už aspoň 10 študentov.
 
  
[[Súbor:MojObrazok.jpg|center|250px]]
+
[[Súbor:zapojenie_bmp180.png]]
 +
 
  
 
=== Algoritmus a program ===
 
=== Algoritmus a program ===
  
Uveďte stručný popis algoritmu, v akom jazyku a verzii vývojového prostredia ste ho vytvorili.  
+
Algoritmus pre komunikáciu so senzorom je naprogramovaný v jazyku Python. Najskôr je pripojená knižnica senzora ''"Adafruit_BMP.BMP085"'', ďalej systémové knižnice pre podporou sériového rozhrania (UART) - ''"serial"'' a knižnica pre systémový časovač ''"time"''. Nasleduje otvorenie komunikačného rozhrania ''"/dev/ttyAMA0"'' a nastavenie komunikačnej rýchlosti na 9600 Baud, ďalej vytvorenie triedy senzora (BMP180) pre nasledujúcu komunikaciu.
Je vhodné nakresliť aspoň hrubú štruktúru programu napríklad vo forme vývojového diagramu.  
+
Program obsahuje hlavnú cyklickú slučku, ktorá sa neustále vykonáva v 1 sekundovom intervale. V tejto slučke je načítanie teploty a tlaku senzora, ďalej jeho prepočet na celočiselnú sústavu INTEGER a jeho rozdelenie na 2-bajtové čislo.
Rozsiahly program pre lepšiu prehľadnosť rozdeľte do viacerých súborov.
+
Nakoniec program posiela tieto hodnoty v tvare 5 bajtovej správy na sériový komunikačný port v tvare: ''<teplota_horný_bajt>, <teplota_dolný_bajt>, <tlak_horný_bajt>, <tlak_dolný_bajt>, <synchronizačný_bajt = vždy 0xff>.''
 +
 
 +
<source lang="python">
 +
#!/usr/bin/python
 +
 
 +
import Adafruit_BMP.BMP085 as BMP085
 +
import time
 +
import serial
 +
 
 +
port = serial.Serial("/dev/ttyAMA0", baudrate=9600)
 +
 
 +
sensor = BMP085.BMP085()
  
Vyberte podstatné časti zdrojového kódu, použite na to prostredie ''source'':
+
while 1:
 +
        temp = sensor.read_temperature()*10
 +
        pressure = sensor.read_pressure()/10.0
  
<source lang="c">
+
        print 'Temp = {0:0.2f} *C'.format(temp)
/* A nezabudnite zdroják hojne komentovať  */
+
        print 'Pressure = {0:0.2f} Pa'.format(pressure)
  
int main(void) {
+
        temp_h = int(temp/255)
   
+
        temp_l = int(temp%255)
    printf("Hello, World!\n")
+
        press_h = int(pressure/255)
    return(0)
+
        press_l = int(pressure%255)
}
+
 
 +
        port.write("%s" % chr(temp_h) + chr(temp_l) + chr(press_h) + chr(press_l) + chr(255) )
 +
        time.sleep(1)
 +
port.close
 
</source>
 
</source>
  
Nezabudnite však nahrať aj kompletné zdrojové kódy vášho programu!
+
Zdrojový kód: [[Médiá:main22.c|main.py]]
  
Zdrojový kód: [[Médiá:Serial.h|serial.h]] a [[Médiá:Pip.c|main.c]]
+
Zobrazovanie načítaných hodnôt v interaktívnej podobe sme realizovali vytvorením jednoduchej Windows Form aplikácie v jayzku C#. Komunikácia prebieha načítavaním dát zo sériového komunikačného portu. Nosná časť programu, kde sa nachádzajú obsluhy udalostí prijatia dát zo sériového komunikačného portu a obsluhy kliknutí myšou na tlačítka sa nachádza v triede Form1.cs.
  
[[Médiá:MojProgram.c|program.c]]
+
<source lang="csharp">
  
 +
namespace COM_Reader
 +
{
 +
    public partial class Form1 : Form
 +
    {
 +
        public Form1()
 +
        {
 +
            InitializeComponent();
 +
        }
  
 +
        // globalne premenne pre zasobnik
  
 +
        int RxString;
 +
        List<int> RxBuf = new List<int>();
  
=== Overenie ===
+
        private void Form1_Load(object sender, EventArgs e)
 +
        {
 +
 
 +
            // nastavenie transparentnosti obrazka ukazovatela
 +
 
 +
            pictureBox1.Controls.Add(pictureBox2);
 +
            pictureBox2.Location = new Point(0, 5);
 +
            pictureBox2.BackColor = Color.Transparent;
 +
 
 +
            pictureBox3.Controls.Add(pictureBox4);
 +
            pictureBox4.Location = new Point(0, 5);
 +
            pictureBox4.BackColor = Color.Transparent;
 +
 
 +
            pictureBox6.Controls.Add(pictureBox5);
 +
            pictureBox5.Location = new Point(0, 5);
 +
            pictureBox5.BackColor = Color.Transparent;
 +
 
 +
            //predvolene hodnoty
 +
 
 +
            textBox1.Text = "9600";
 +
            comboBox1.SelectedItem = "COM3";
 +
 
 +
           
 +
            if (serialPort1.IsOpen)
 +
            {
 +
                //vycistenie zasobnika serioveho portu(windows zasobnik)
 +
 
 +
                serialPort1.DiscardInBuffer();
 +
                serialPort1.DiscardOutBuffer();
 +
 
 +
            }
 +
        }
 +
        private void serialPort1_DataReceived
 +
 
 +
        //udalost prijatia dat na seriovy port
 +
 
 +
        (object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
 +
            {
 +
                RxString = (serialPort1.ReadByte());
 +
                if((uint)RxString != 255)
 +
                {
 +
                    RxBuf.Add(RxString);
 +
                }
 +
                else this.Invoke(new EventHandler(DisplayText));
 +
 
 +
        }
 +
 
 +
        private void DisplayText(object sender, EventArgs e)
 +
        {
 +
 
 +
            //funkcia aktualizacie cislenych a analogovych vykreslovanych udajov
 +
 
 +
            if (RxBuf.Count != 4)
 +
            {
 +
                RxBuf.Clear();
 +
                return;
 +
            }
 +
 
 +
            string first = ((float)(RxBuf[0] * 255 + RxBuf[1])/10).ToString();
 +
            string second = ((float)(RxBuf[2] * 255 + RxBuf[3])/10).ToString();
 +
            string third = ((float)((RxBuf[2] * 255 + RxBuf[3])+250 )/ 10).ToString();
 +
 
 +
            label1.Text = first;
 +
            label2.Text = second;
 +
            label6.Text = third;
 +
 
 +
            int angle1 = (int)(((float)(RxBuf[0] * 255 + RxBuf[1]) / 500) * 240);
 +
            int angle2 = (int)(((float)((RxBuf[2] * 255 + RxBuf[3])-9800) / 400) * 240);
 +
            int angle3 = (int)(((float)((RxBuf[2] * 255 + RxBuf[3])+ 250 - 9900) / 400) * 240);
 +
 
 +
            Image image1 = new Bitmap("C:\\Users\\Timoransky\\Desktop\\needle_.png");
 +
            pictureBox2.Image = (Bitmap)image1.Clone();
 +
 
 +
            Image oldImage1 = pictureBox2.Image;
 +
 
 +
            //otacanie ukazovatela proporcionalne k vstupnym hodnotam
 +
 
 +
            pictureBox2.Image = Class1.RotateImage(image1,new PointF(pictureBox2.Location.X+pictureBox2.Image.Width/2, pictureBox2.Location.Y-8 + pictureBox2.Image.Height / 2),angle1);
 +
            if (oldImage1 != null)
 +
            {
 +
                oldImage1.Dispose();
 +
            }
 +
 
 +
            Image image2 = new Bitmap("C:\\Users\\Timoransky\\Desktop\\needle_.png");
 +
            pictureBox4.Image = (Bitmap)image1.Clone();
 +
 
 +
            Image oldImage2 = pictureBox4.Image;
 +
            pictureBox4.Image = Class1.RotateImage(image1, new PointF(pictureBox4.Location.X + pictureBox4.Image.Width / 2, pictureBox4.Location.Y-8 + pictureBox4.Image.Height / 2), angle2);
 +
            if (oldImage2 != null)
 +
            {
 +
                oldImage2.Dispose();
 +
            }
 +
 
 +
            Image image3 = new Bitmap("C:\\Users\\Timoransky\\Desktop\\needle_.png");
 +
            pictureBox5.Image = (Bitmap)image1.Clone();
 +
 
 +
            Image oldImage3 = pictureBox5.Image;
 +
            pictureBox5.Image = Class1.RotateImage(image1, new PointF(pictureBox5.Location.X + pictureBox5.Image.Width / 2, pictureBox5.Location.Y-8 + pictureBox5.Image.Height / 2), angle3);
 +
            if (oldImage3 != null)
 +
            {
 +
                oldImage3.Dispose();
 +
            }
 +
 
 +
            RxBuf.Clear();
 +
            serialPort1.DiscardInBuffer();
 +
            serialPort1.DiscardOutBuffer();
 +
 
 +
            pictureBox2.Invalidate();
 +
            pictureBox4.Invalidate();
 +
            pictureBox5.Invalidate();
 +
            Application.DoEvents();
 +
        }
 +
 
 +
        private void button1_Click(object sender, EventArgs e)
 +
        {
 +
 
 +
            //udalost kliknutia na tlacidlo "connect"
 +
 
 +
            if (serialPort1.IsOpen)
 +
            {
 +
                serialPort1.DataReceived -= serialPort1_DataReceived;
 +
                serialPort1.Close();
 +
            }
 +
            serialPort1.PortName = comboBox1.SelectedItem.ToString();
 +
 
 +
            int speed;
 +
            Int32.TryParse(textBox1.Text.ToString(), out speed);
 +
            serialPort1.BaudRate = speed;
 +
            serialPort1.DtrEnable = false;
 +
            serialPort1.DataReceived +=
 +
            new SerialDataReceivedEventHandler(serialPort1_DataReceived);
 +
 
 +
            serialPort1.ReadBufferSize = 6;
 +
            label7.Text = "";
 +
 
 +
 
 +
            try { serialPort1.Open(); }
 +
            catch (Exception ex)
 +
            {
 +
                label7.Text = ex.Message;
 +
            }
 +
        }
 +
 
 +
    }
 +
}
 +
</source>
 +
 
 +
Zdrojový kód: [[Médiá:main23.cs|Form1.cs]]
 +
 
 +
 
 +
Grafické rozhranie programu:
  
Nezabudnite napísať čosi ako užívateľský návod. Z neho by malo byť jasné čo program robí,
+
[[Súbor:Form.png|450px]]
ako sa prejavuje a aké má užívateľské rozhranie (čo treba stlačiť, čo sa kde zobrazuje).
 
Ak ste namerali nejaké signály, sem s nimi. Ak je výsledkom nejaký údaj na displeji,
 
odfotografujte ho.  
 
  
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.
+
=== Overenie ===
  
 +
Obsluha programu: Po spustení programu je potrebné si zvoliť komunikačný port (COM), zapísať rýchlosť a potvrdiť tlačidlom "connect". Volbu nevhodného portu program hlási. Volbou správných údajov aplikácia po prijatí prvých štyroch bajtov dát začne zobrazovať číselné hodnoty teploty, relatívneho a absolútneho tlaku.
  
 
[[Category:MEMS]] [[Category:I2C]]
 
[[Category:MEMS]] [[Category:I2C]]

Aktuálna revízia z 16:43, 31. máj 2016

Autori: Martin Valášek, Tomáš Timoranský
Študijný odbor: Aplikovaná mechatronika a elektromobilita 1. Ing. (2016)

Zadanie

Vytvoriť jednoduchú meteorologickú stanicu, ktorá bude merať atmosferický relatívny a absolutný tlak vzduchu a teplotu prostredia. Stanica bude pozostváť z digitálneho tlakového senzora BMP180, ktorý bude komunikovať prostredníctvom I2C rozhrania s embedded systémom RaspberryPI. Pomocou grafického použivateľského rozhrania bude používateľ informovaný o aktuálnej meteorogickej situácii.

Senzor bmp180.jpg


Literatúra: Datasheed BMP180


Analýza

BMP180

Senzor BMP180 vyrába firma Bosch, ide o nástupcu veľmi obľúbeného senzora BMP085. Senzor disponuje meraním atmosferického absolútného tlaku v rozsahu 300 až 1100 hPa. Pre kompenzáciu tepelných vplyvov na meranie atmosferického tlaku, má senzor integrovaný teplomer (merací rozsah -40 až +85°C), ktorý je taktiež možno vyčítať. Komunikácia je digitalná prostredníctvom I2C zbernice.

Jeho základné informácie:

  • Rozsah meracieho tlaku: 300 až 1100hPa (+9000m až -500m nad morom)
  • Napájacie napätie: 1.8 až 3.6 V (VDD), 1.62V až 3.6V (VDDIO)
  • Púzdro: LGA, Small footprint: 3.6mm x 3.8mm
  • Nízka spotreba: 5μA pri 1 vzorke / sekundu (standard mode)
  • Nízky šum:
    • 0.06hPa (0.5m) - ultra low power mode
    • 0.02 hPa (0.17m) - advanced resolution mode


  • Vstavané teplotné čidlo
  • I2C rozhranie
  • plne kalibrovaný
  • Pb-free, halogen-free and RoHS compliant

Typické využitie

  • rozšírenie GPS navigácie
  • vnútorná-vonkajšia navigácia
  • voľnočasové aktivy/ šport
  • vertikálny ukazovateľ rýchlosti


Popis komunikačnej zbernice

Tlakový senzor komunikuje prostredníctvom ľ2C zbernice, jeho adresa je:

  • 0xEF pre režím čitania
  • 0xEE pre režím zápisu

Add bmp180 pins.jpg


Voľba režimov prevodu

Senzor môže pracovať v niekoľkých meracích režimov. Voľbou jednotlivých režimov senzora sa volí presnosť dosiahnutého výslednu (šum signálu) a zároveň sa volí rýchlosť prevodu. Nasledujúci obrázok zobrazuje jednotlivé režímy.

Mode bmp180.jpg

Senzor disponuje vnútornou 176bit EEPROM pamäťou v ktorej je uložených 11 kalibračných koeficientov. Každý senzor má jedinečné koeficienty. Tieto koeficienty sú nahraná do senzora v procese výroby. Algoritmus pred prvým výpočtom tlaku a teploty vyčíta obsah tejto EEPROM pamäte, následne pomocou korečných výpočtov dopočíta korektné výsledky. Nasledujúci obrázok zobrazuje adresu jednotlivých adries kalibračných koeficientov.

Calib bmp180.jpg


Algoritmus merania

Pre výpočet je dostupný ANSI C kód od Bosch Sensortec ("BMP180_API"). Mikrokontrolér najskôr pošle start sekvenciu k inicializácii merania teploty a tlaku. Následne po uplynutí času prevodu, výsledné konštanty (UP alebo UT) sa môžu vyčítat prostredníctvom I2C rozhrania. Pre prepočet tlaku na hPa a teploty na °C, sa využijú kalibračné dáta z EEPROM pamäte. Vzorkovacia perióda senzora je do 128 vzoriek za sekundu (štandartný mód).

Algoritmus bmp180.jpg

Prepočet RAW dát na unifikované jednotky [hPa/ °C]

Nasledujúci obrázok zobrazuje prepočet RAW dát senzora a unifikované jednotky

Calculation bmp180.jpg


Priebehy I2C signálov

I2c 1.jpg

I2c 2.jpg

I2c 3.jpg


Zapojenie vývodov senzora

Senzor bmp180 pins.jpg

Popis riešenia

Senzor BMP180 je osadený na doske plošného spoja spolu so stabilizátorom napätia (7133). Tento stabilizátor stabilizuje vstupné napätie (5 V) na 3,3 V, ktoré napája celý tlakový senzor. Ďalej na doske sú obsiahnuté pull-up rezistory R1, R2 pre I2C rozhranie. Senzor sa pripája k RaspberryPi pomocou konektora J1, ktorý obsahuje napájanie senzora VCC a GND, zbernicovú komunikáciu pre I2C rozhranie - SDA, SDL, signál pre povolenie senzora EOC.

Schéma zapojenia snímača


Zapojenie bmp180.png


Algoritmus a program

Algoritmus pre komunikáciu so senzorom je naprogramovaný v jazyku Python. Najskôr je pripojená knižnica senzora "Adafruit_BMP.BMP085", ďalej systémové knižnice pre podporou sériového rozhrania (UART) - "serial" a knižnica pre systémový časovač "time". Nasleduje otvorenie komunikačného rozhrania "/dev/ttyAMA0" a nastavenie komunikačnej rýchlosti na 9600 Baud, ďalej vytvorenie triedy senzora (BMP180) pre nasledujúcu komunikaciu. Program obsahuje hlavnú cyklickú slučku, ktorá sa neustále vykonáva v 1 sekundovom intervale. V tejto slučke je načítanie teploty a tlaku senzora, ďalej jeho prepočet na celočiselnú sústavu INTEGER a jeho rozdelenie na 2-bajtové čislo. Nakoniec program posiela tieto hodnoty v tvare 5 bajtovej správy na sériový komunikačný port v tvare: <teplota_horný_bajt>, <teplota_dolný_bajt>, <tlak_horný_bajt>, <tlak_dolný_bajt>, <synchronizačný_bajt = vždy 0xff>.

#!/usr/bin/python

import Adafruit_BMP.BMP085 as BMP085
import time
import serial

port = serial.Serial("/dev/ttyAMA0", baudrate=9600)

sensor = BMP085.BMP085()

while 1:
        temp = sensor.read_temperature()*10
        pressure = sensor.read_pressure()/10.0

        print 'Temp = {0:0.2f} *C'.format(temp)
        print 'Pressure = {0:0.2f} Pa'.format(pressure)

        temp_h = int(temp/255)
        temp_l = int(temp%255)
        press_h = int(pressure/255)
        press_l = int(pressure%255)

        port.write("%s" % chr(temp_h) + chr(temp_l) + chr(press_h) + chr(press_l) + chr(255) )
        time.sleep(1)
port.close

Zdrojový kód: main.py

Zobrazovanie načítaných hodnôt v interaktívnej podobe sme realizovali vytvorením jednoduchej Windows Form aplikácie v jayzku C#. Komunikácia prebieha načítavaním dát zo sériového komunikačného portu. Nosná časť programu, kde sa nachádzajú obsluhy udalostí prijatia dát zo sériového komunikačného portu a obsluhy kliknutí myšou na tlačítka sa nachádza v triede Form1.cs.

namespace COM_Reader
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        // globalne premenne pre zasobnik

        int RxString;
        List<int> RxBuf = new List<int>();

        private void Form1_Load(object sender, EventArgs e)
        {

            // nastavenie transparentnosti obrazka ukazovatela

            pictureBox1.Controls.Add(pictureBox2);
            pictureBox2.Location = new Point(0, 5);
            pictureBox2.BackColor = Color.Transparent;

            pictureBox3.Controls.Add(pictureBox4);
            pictureBox4.Location = new Point(0, 5);
            pictureBox4.BackColor = Color.Transparent;

            pictureBox6.Controls.Add(pictureBox5);
            pictureBox5.Location = new Point(0, 5);
            pictureBox5.BackColor = Color.Transparent;

            //predvolene hodnoty

            textBox1.Text = "9600";
            comboBox1.SelectedItem = "COM3";

            
            if (serialPort1.IsOpen)
            {
                //vycistenie zasobnika serioveho portu(windows zasobnik)

                serialPort1.DiscardInBuffer();
                serialPort1.DiscardOutBuffer();

            }
        }
        private void serialPort1_DataReceived

        //udalost prijatia dat na seriovy port

        (object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                RxString = (serialPort1.ReadByte());
                if((uint)RxString != 255)
                {
                    RxBuf.Add(RxString);
                }
                else this.Invoke(new EventHandler(DisplayText));

        }

        private void DisplayText(object sender, EventArgs e)
        {

            //funkcia aktualizacie cislenych a analogovych vykreslovanych udajov

            if (RxBuf.Count != 4)
            {
                RxBuf.Clear();
                return;
            }

            string first = ((float)(RxBuf[0] * 255 + RxBuf[1])/10).ToString();
            string second = ((float)(RxBuf[2] * 255 + RxBuf[3])/10).ToString();
            string third = ((float)((RxBuf[2] * 255 + RxBuf[3])+250 )/ 10).ToString();

            label1.Text = first;
            label2.Text = second;
            label6.Text = third;

            int angle1 = (int)(((float)(RxBuf[0] * 255 + RxBuf[1]) / 500) * 240);
            int angle2 = (int)(((float)((RxBuf[2] * 255 + RxBuf[3])-9800) / 400) * 240);
            int angle3 = (int)(((float)((RxBuf[2] * 255 + RxBuf[3])+ 250 - 9900) / 400) * 240);

            Image image1 = new Bitmap("C:\\Users\\Timoransky\\Desktop\\needle_.png");
            pictureBox2.Image = (Bitmap)image1.Clone();

            Image oldImage1 = pictureBox2.Image;

            //otacanie ukazovatela proporcionalne k vstupnym hodnotam

            pictureBox2.Image = Class1.RotateImage(image1,new PointF(pictureBox2.Location.X+pictureBox2.Image.Width/2, pictureBox2.Location.Y-8 + pictureBox2.Image.Height / 2),angle1);
            if (oldImage1 != null)
            {
                oldImage1.Dispose();
            }

            Image image2 = new Bitmap("C:\\Users\\Timoransky\\Desktop\\needle_.png");
            pictureBox4.Image = (Bitmap)image1.Clone();

            Image oldImage2 = pictureBox4.Image;
            pictureBox4.Image = Class1.RotateImage(image1, new PointF(pictureBox4.Location.X + pictureBox4.Image.Width / 2, pictureBox4.Location.Y-8 + pictureBox4.Image.Height / 2), angle2);
            if (oldImage2 != null)
            {
                oldImage2.Dispose();
            }

            Image image3 = new Bitmap("C:\\Users\\Timoransky\\Desktop\\needle_.png");
            pictureBox5.Image = (Bitmap)image1.Clone();

            Image oldImage3 = pictureBox5.Image;
            pictureBox5.Image = Class1.RotateImage(image1, new PointF(pictureBox5.Location.X + pictureBox5.Image.Width / 2, pictureBox5.Location.Y-8 + pictureBox5.Image.Height / 2), angle3);
            if (oldImage3 != null)
            {
                oldImage3.Dispose();
            }

            RxBuf.Clear();
            serialPort1.DiscardInBuffer();
            serialPort1.DiscardOutBuffer();

            pictureBox2.Invalidate();
            pictureBox4.Invalidate();
            pictureBox5.Invalidate();
            Application.DoEvents();
        }

        private void button1_Click(object sender, EventArgs e)
        {

            //udalost kliknutia na tlacidlo "connect"

            if (serialPort1.IsOpen)
            {
                serialPort1.DataReceived -= serialPort1_DataReceived;
                serialPort1.Close();
            }
            serialPort1.PortName = comboBox1.SelectedItem.ToString();

            int speed;
            Int32.TryParse(textBox1.Text.ToString(), out speed);
            serialPort1.BaudRate = speed;
            serialPort1.DtrEnable = false;
            serialPort1.DataReceived +=
            new SerialDataReceivedEventHandler(serialPort1_DataReceived);

            serialPort1.ReadBufferSize = 6;
            label7.Text = "";


            try { serialPort1.Open(); }
            catch (Exception ex)
            {
                label7.Text = ex.Message;
            }
        }

    }
}

Zdrojový kód: Form1.cs


Grafické rozhranie programu:

Form.png

Overenie

Obsluha programu: Po spustení programu je potrebné si zvoliť komunikačný port (COM), zapísať rýchlosť a potvrdiť tlačidlom "connect". Volbu nevhodného portu program hlási. Volbou správných údajov aplikácia po prijatí prvých štyroch bajtov dát začne zobrazovať číselné hodnoty teploty, relatívneho a absolútneho tlaku.