-
Notifications
You must be signed in to change notification settings - Fork 2
Dokumentace: Quido
- Základní příklad použití
- Výstupy - ovládání výstupů, apod.
- Vstupy - vstupy, čítače na vstupech
- Automatické události - zpracování automatických zpráv o změnách na vstupech
- Teploměr - měření teploty
- Odkaz na papouch.com: Přehled všech I/O modulů Quido
- Dokumentace společných funkcí protokolu Spinel - většinu těchto funkcí umí i I/O moduly Quido
-
Dokumentace funkce
SendAndReceive()
, kterou můžete snadno začít používat vlastní instrukce nebo ty, které nejsou v naší knihovně implementovány.
Nejjednodušší příklad C# WPF aplikace s tlačítky Sepnout a Rozepnout, která ovládají relé 3 na Quidu s Ethernetovým rozhraním.
(Komplexnější příklad aplikace v C# i VB.NET je k dispozici přímo v repozitáři v adresářích QuidoDemo_CS.NET a QuidoDemo_VB.NET.)
using Papouch.Communication;
using Papouch.Spinel.Spinel97;
using System;
using System.Windows;
namespace QuidoApp
{
public partial class MainWindow : Window
{
private ICommunicationInterface ci;
public Papouch.Spinel.Spinel97.Device.Quido.Quido MyDevice;
public MainWindow()
{
InitializeComponent();
// Příklad pro Quido RS (se sériovým portem):
//ci = new CiSerialPort();
//ci.ConfigString = "provider=SERIAL_PORT;PortName=COM4;BaudRate=9600;";
// Příklad pro Quido ETH na adrese 192.168.1.124 s datovým portem 10001:
// Upozornění: Quido musí být v režimu TCP server!
ci = new CiTcpClient();
ci.ConfigString = "provider=TCP_CLIENT;Host=192.168.1.124;Port=10001;";
if (!ci.Open(true))
{
MessageBox.Show("Spojení se nepodařilo otevřít!");
Application.Current.Shutdown();
}
// 0x31 je výchozí adresa z výroby
// 0xFE je univerzální adresa pokud je na lince jen jedno zařízení
MyDevice = new Papouch.Spinel.Spinel97.Device.Quido.Quido(ci, 0xFE);
if (MyDevice == null)
{
MessageBox.Show("Zařízení se nepovedlo inicializovat!");
Application.Current.Shutdown();
}
}
private void OutputOn_Click(object sender, RoutedEventArgs e)
{
if (!MyDevice.CmdSetOutput(3, true))
MessageBox.Show("Nedošlo k sepnutí výstupu 3");
}
private void OutputOff_Click(object sender, RoutedEventArgs e)
{
if (!MyDevice.CmdSetOutput(3, false))
MessageBox.Show("Nedošlo k rozepnutí výstupu 3");
}
}
}
...jednoduchý XAML s tlačítky:
<Window x:Class="QuidoApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:QuidoApp"
mc:Ignorable="d"
Title="QuidoApp" Height="120" Width="300" ResizeMode="NoResize">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="Sepnout" Margin="20" Click="OutputOn_Click" />
<Button Grid.Column="1" Content="Rozepnout" Margin="20" Click="OutputOff_Click"/>
</Grid>
</Window>
public bool CmdSetOutput(byte outid, bool value, byte timer = 0);
outid
je číslo výstupu (číslováno od 1).
value
je true/false pro sepnutí/rozepnutí výstupu.
timer
je volitelný parametr pro časově omezené nastavení. Lze zadat číslo 1 až 255, které představuje nastavení na 0,5 až 127,5 sec. Pokud je zadána 0, časování není použito.
if (MyDevice.CmdSetOutput(3, true, 10))
Console.WriteLine("Ok");
else
Console.WriteLine("Error");
Příkaz umožňuje trvalé nebo časově omezené nastavení jednoho nebo více výstupů najednou. Pořadí výstupů je libovolné, nesmí být adresován neexistující výstup.
public bool CmdSetOutputs(List<OutputState> outs, byte timer = 0)
outs
je list struktur se stavem jednotlivých výstupů.
OutputState
je struktura definovaná jako public OutputState(byte outid, bool outstate)
.
value
je true/false pro sepnutí/rozepnutí výstupu.
timer
je volitelný parametr pro časově omezené nastavení. Lze zadat číslo 1 až 255, které představuje nastavení na 0,5 až 127,5 sec. Pokud je zadána 0, časování není použito.
List<Quido.OutputState> outs = new List<Quido.OutputState>();
outs.Add(new Quido.OutputState(1, true));
outs.Add(new Quido.OutputState(3, false));
outs.Add(new Quido.OutputState(4, true));
if (MyDevice.CmdSetOutputs(outs, 4))
Console.WriteLine("Ok");
else
Console.WriteLine("Error");
public bool CmdGetOutputs(out bool[] outputs);
bool[]
je pole bitů se stavy jednotlivých výstupů. Počet bitů je zaokrouhlen na nejbližší vyšší násobek osmi. Takže například u Quida se čtyřmi výstupy se vrací osm hodnot.
if (MyDevice.CmdGetOutputs(out bool[] outputs))
{
string state;
for (int i = 0; i < outputs.Length; i++)
{
state = outputs[i] ? "ON" : "OFF";
Console.WriteLine($"Output {i+1} is {state}.");
}
}
Output 1 is OFF.
Output 2 is OFF.
Output 3 is ON.
Output 4 is OFF.
Output 5 is OFF.
Output 6 is OFF.
Output 7 is OFF.
Output 8 is OFF.
public bool CmdGetInputs(out bool[] inputs);
bool[]
je pole bitů se stavy jednotlivých vstupů. Počet bitů je zaokrouhlen na nejbližší vyšší násobek osmi. Takže například u Quida se čtyřmi vstupy se vrací osm hodnot.
if (MyDevice.CmdGetInputs(out bool[] inputs))
{
string state;
for (int i = 0; i < inputs.Length; i++)
{
state = inputs[i] ? "ON" : "OFF";
Console.WriteLine($"Input {i+1} is {state}.");
}
}
Input 1 is ON.
Input 2 is OFF.
Input 3 is OFF.
Input 4 is ON.
Input 5 is OFF.
Input 6 is OFF.
Input 7 is OFF.
Input 8 is OFF.
public bool CmdGetCounter(byte index, out int counter, bool erase = false);
index
je číslo vstupu (číslováno od 1).
counter
je stav počítadla.
erase
je volitelný parametr. True znamená, že po přečtení stavu má být počítadlo vynulováno.
if (MyDevice.CmdGetCounter(2, out int counter))
Console.WriteLine($"Counter value is {counter}.");
Counter value is 12348.
public bool CmdSetCounterSettings(byte index, bool rising, bool falling);
index
je číslo vstupu (číslováno od 1).
rising
znamená počítání náběžných hran na vstupu (změn z neaktivní na aktivní). Pokud je zde true, náběžné hrany se budou počítat.
falling
znamená počítání sestupných hran na vstupu (změn z aktivní na neaktivní). Pokud je zde true, sestupné hrany se budou počítat.
if (MyDevice.CmdSetCounterSettings(4, true, false))
Console.WriteLine("Ok");
public bool CmdGetCounterSettings(byte index, out bool rising, out bool falling);
index
je číslo vstupu (číslováno od 1).
rising
znamená počítání náběžných hran na vstupu (změn z neaktivní na aktivní). Pokud je zde true, náběžné hrany se počítají.
falling
znamená počítání sestupných hran na vstupu (změn z aktivní na neaktivní). Pokud je zde true, sestupné hrany se počítají.
string state;
if (MyDevice.CmdGetCounterSettings(4, out bool rising, out bool falling))
{
state = rising ? "ON" : "OFF";
Console.WriteLine($"Rising counter is {state}.");
state = falling ? "ON" : "OFF";
Console.WriteLine($"Falling counter is {state}.");
}
Rising counter is ON.
Falling counter is OFF.
Po inicializaci objektu MyDevice je aktivní synchroní režim. V synchroním režimu jsou data odesílána i přijímána v kontextu volání dané funkce - nejsou thread-safe!
Asynchronní režim je možné aktivovat voláním funkce MyDevice.StartListen()
, deaktivace asynchronního režimu se provádí funkcí MyDevice.StopListen()
. V asynchronním režimu je aktivován BackgroundWorker
, který vyřizuje požadavky na odesílání paketů a také přijímá, parseuje a páruje přijaté pakety. Synchronizace mezi voláním příkazu a odpovědí je prováděna pomocí eventů. Funkce jsou v asynchronním režimu thread-safe.
Událost je vyvolána při jakékoli změně na vstupu. Výstupem je informace o předchozím a aktuálním stavu vstupu.
public event EventQuidoInputChange OnInputChange;
Nejdříve nastaví, aby události OnInputChange
zpracovávala funkce OnInputChange
a poté aktivuje asynchronní režim quida. Jakmile se změní stav vstupu, dojde k zavolání funkce OnInputChange
.
MyDevice.OnInputChange += new Papouch.Spinel.Spinel97.Device.Quido.Quido.EventQuidoInputChange(OnInputChange);
MyDevice.StartListen();
/// <summary>
/// Funkce je volána při detekci změny na vstupu (pro každý vstup samostatně).
/// Při první změně na některém vstupu je funkce zavolána pro všechny vstupy, protože není znám předchozí stav. Z tohoto důvodu je prvním volání io_old_stat a io_new_stat shodná u vstupů, na kterých nenastala změna.
/// Při první změně se funkce zavolá pro počet vstupů zaokrouhlený nahoru na násobky osmi. Z tohoto důvodu přijde například u Quida se čtyřmi vstupy při první změně info o změně i ze vstupů IN5 až IN8.
/// </summary>
/// <param name="quido">Objekt Quida, u kterého jsou sledovány změny na vstupech.</param>
/// <param name="io_index">Číslo vstupu. IN1 = 0</param>
/// <param name="io_old_stat">Předchozí stav vstupu.</param>
/// <param name="io_new_stat">Nový stav vstupu.</param>
private void OnInputChange(Papouch.Spinel.Spinel97.Device.Quido.Quido quido, int io_index, bool io_old_stat, bool io_new_stat)
{
string state = io_new_stat ? "ON" : "OFF";
Console.WriteLine($"InputChange: IN{io_index+1} is {state}");
}
První informace o změně obsahuje stav všech vstupů. Zde je příklad z Quida ETH 4/4, které má čtyři vstupy - všimněte si, že počet vstupů je zaokrouhlen nahoru na nejbližší násobek osmi:
InputChange: IN1 is OFF
InputChange: IN2 is OFF
InputChange: IN3 is OFF
InputChange: IN4 is ON
InputChange: IN5 is OFF
InputChange: IN6 is OFF
InputChange: IN7 is OFF
InputChange: IN8 is OFF
Další informace o změnách již přicházejí jednotlivě pro konkrétní vstupy:
InputChange: IN4 is OFF
InputChange: IN2 is ON
InputChange: IN2 is OFF
Událost je vyvolána při jakékoli změně na vstupu. Výstupem je informace o aktuálním stavu všech vstupů.
public event EventQuidoInputsChange OnInputsChange;
Nejdříve nastaví, aby události OnInputsChange
zpracovávala funkce OnInputsChange
a poté aktivuje asynchronní režim quida. Jakmile se změní stav některého vstupu, dojde k zavolání funkce OnInputsChange
.
MyDevice.OnInputsChange += new Papouch.Spinel.Spinel97.Device.Quido.Quido.EventQuidoInputsChange(OnInputsChange);
MyDevice.StartListen();
/// <summary>
/// Funkce je volána při detekci změny na vstupu (jednou pro každou změnu).
/// </summary>
/// <param name="quido">Objekt Quida, u kterého jsou sledovány změny na vstupech.</param>
/// <param name="inputs">Pole bitů s aktuálním stavem všech vstupů. Počet bitů je zaokrouhlený nahoru na násobky osmi. Z tohoto důvodu i u Quida jen se dvěma vstupy má pole 8 položek (položky neexistujících vstupů jsou neplatné a vždy 0).</param>
private void OnInputsChange(Papouch.Spinel.Spinel97.Device.Quido.Quido quido, Boolean[] inputs)
{
string state;
for (int index = 0; index < inputs.Length; index++)
{
state = inputs[index] ? "ON" : "OFF";
Console.WriteLine($"InputsChange: IN{index+1} is {state}");
}
}
Příklad z Quida ETH 4/4 - všimněte si, že počet vstupů je zaokrouhlen nahoru na nejbližší násobek osmi:
InputsChange: IN1 is OFF
InputsChange: IN2 is ON
InputsChange: IN3 is OFF
InputsChange: IN4 is OFF
InputsChange: IN5 is OFF
InputsChange: IN6 is OFF
InputsChange: IN7 is OFF
InputsChange: IN8 is OFF
Událost je vhodná k obecnému příjmu ayutomatických zpráv, což je využitelné i v jiných zařízeních, které komunikují Spinelem a vysílají automatické zprávy.
public event EventSpinelPacketReceive OnPacketReceive;
Nejdříve nastaví, aby události OnPacketReceive
zpracovávala funkce OnPacketReceive
a poté aktivuje asynchronní režim quida. Jakmile přijde jakákoli automatická zpráva, dojde k zavolání funkce OnPacketReceive
.
MyDevice.OnPacketReceive += new Papouch.Spinel.Spinel97.Device.Device.EventSpinelPacketReceive(OnPacketReceive);
MyDevice.StartListen();
private void OnPacketReceive(PacketSpinel97 packet)
{
Console.WriteLine("Receive Packet > " + BitConverter.ToString(packet.GetBin()));
}
Receive Packet > 2A-61-00-06-31-00-0D-08-28-0D
public Boolean CmdGetIOCounts(out int inputsCount, out int outputsCount, out int thermsCount);
Zjistí počet vstupů, výstupů a vstupů pro teploměr
if (quido.CmdGetIOCounts(out int inputsCount, out int outputsCount, out int thermsCount))
{
Console.WriteLine($"Quido has {inputsCount} inputs, {outputsCount} outputs and {thermsCount} thermometer");
}
Quido has 8 inputs, 8 outputs and 1 thermometer
Quido umí měřit teplotu pomocí externího senzoru. (Senzor není standardní součástí každého Quida.)
public Boolean CmdGetTemperature(out float temp, byte index = 0x01);
temp
je teplota v nastavené teplotní jednotce (z výroby má Quido nastaveno °C).
index
je číslo teploměru, číslováno od 1. Ve standardních variantách Quida je zde vždy 1.
if (MyDevice.CmdGetTemperature(out float temp))
Console.WriteLine($"Current temperature is {temp} °C");
else
MessageBox.Show("Temperature is not available.");
Current temperature is 37,3 °C