HOME > RT-C Language
Controller > Sample "Analog Input Control""
Board Settings (※ Execute once when program
boots))
|
|
(1) Search Board
Get IO port to be used by PciFindDevice() of pcibus class.
|
|
(2) Initialize board
Output "Initialize process command" to IO port to initialize
board
|
|
(3) Set Sampling temrs
After outputing "setting command of sampling terms" to IO port,
output setting data ([input mode][channel mode][clock source to
be used][sampling mode]).
|
|
(4) Set Range Width
After outputting "Setting command of Output Range" to IO port,
output settings of Output Range per each channel.
|
|
(5) Set interrupt mask
After outputting "Setting command of Interrupt factor" to IO
port, output settings of factor for interrupt signal
occurrance.
※ All must be prohibited.
|
|
Data Sampling (※ Always executing in operation)
|
|
(6) Output data setting
After setting output channel to "Output channel setting
register" of IO port, set output data.
|
|
※ Repeat (6)
|
// *** Constant ***
/// <summary>
/// Output Range
/// </summary>
public enum RANGE : byte
{
U_1000 = 0x0, // Unipolar:0..10[V]
B_0500 = 0x1, // Bipolar:-5..5[V]
B_1000 = 0x2 // Bipolar:-10..10[V]
}
/// <summary>
/// Define global variables
/// </summary>
public unsafe class GlobalVar
{
public static Boolean inExe; // Request Execution
public static Boolean inBusy; // Flag for Running
public static Boolean inErr; // Fral for In Error
public static UInt32 inErrCode; // Error Code
public static UInt16 IOPort; // IO port of analaog board
public static Single fLo; // Voltage of minimum output
public static Single fHi; // Voltage of maximum output
public static UInt16 wData; // Output data instantaneous value
public static Single fData; // Output data [V]instantaneous value
}
/// <summary>
/// Define board setting value
/// </summary>
public unsafe class Board
{
// Target Board
public static UInt16 VenID = 0x1221; // CONTEC
public static UInt16 DevID = 0x8163; // DA12-16(PCI)
public static UInt16 DevIndex = 0; // Board ID:0
public static Byte bMaxCh = 16; // Board CH number
public static UInt16 Resolution = 0x0FFF; // Resolution
// Smapling terms Setting value
public static Byte bAOMode = 0; // Output Mode 0:Transparent Output 1:Synchronous Output
public static Byte bIntClk = 0; // Internal Sampling Blcok 0:Disabled 1:Enabled
public static Byte bExtClk = 0; // External Sampling Blcok 0:Disabled 1:Enabled
public static Byte bUseCh = 1; // CH numbers to be used
// Range Width Setting value
public static Byte bRange = (Byte)RANGE.B_1000; // Output Range
// Inerrupt Mask Setting value
public static Byte bFcr0 = 0xFF; // Interrupt mask0 ※Bit Unit (0:Occur 1:Prohibit)
public static Byte bFcr1 = 0xFF; // Interrupt mask1 ※Bit Unit (0:Occur 1:Prohibit)
}
/// <summary>
/// *****************************************************************************************************
/// Main Process Block
/// *****************************************************************************************************
/// </summary>
[FUNCTION_BLOCK]
public class _main
{
// *** Internal Variables ***
/// <summary>
/// Search Target board
/// </summary>
private Boolean FindBoard()
{
UInt32 BaseAddr = 0;
if (pcibus.PciFindDevice(Board.VenID, Board.DevID, Board.DevIndex, 0, 1, ref BaseAddr) == false)
{
GlobalVar.IOPort = 0;
return false;
}
GlobalVar.IOPort = (UInt16)(BaseAddr & 0x0000FFFC);
return true;
}
/// <summary>
/// Intialize board
/// </summary>
private void InitalizeBord()
{
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x0008), 0);
}
/// <summary>
/// Set Sampling terms
/// </summary>
private void SetSampling()
{
// +------------------------+------------------------+-----------+
// | D2 | D1 | D0 |
// +------------------------+------------------------+-----------+
// |External Sampling Blcok |Internal Sampling Blcok |Output Mode|
// +------------------------+------------------------+-----------+
Byte byDATA = (Byte)(
(Board.bExtClk << 0x02)
| (Board.bIntClk << 0x01)
| Board.bAOMode
);
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x0008), 0x01); // Issue set command for Sampling terms
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x000C), byDATA); // Write Sampling terms
}
/// <summary>
/// Set range width
/// </summary>
private void SetRange()
{
// ssue set command for range
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x0008), 0x02);
// Process for range setting
for (Byte i = 0; i < Board.bUseCh; i++)
{
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x000C), i); // Set CH to be set
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x000D), Board.bRange); // Set range width
}
// Set Voltage of minimum output / Voltage of maximum output
switch (Board.bRange)
{
case (Byte)RANGE.U_1000:
GlobalVar.fLo = 0.0f;
GlobalVar.fHi = 10.0f;
break;
case (Byte)RANGE.B_0500:
GlobalVar.fLo = -5.0f;
GlobalVar.fHi = 5.0f;
break;
case (Byte)RANGE.B_1000:
GlobalVar.fLo = -10.0f;
GlobalVar.fHi = 10.0f;
break;
}
}
/// <summary>
/// Set Interrupt mask
/// </summary>
private void SetIntrMask()
{
// Issue set command for Interrupt mask
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x0008), 0x07);
// Set Interrupt mask
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x000C), Board.bFcr0);
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x000D), Board.bFcr1);
}
/// <summary>
/// PLC Program - Process in download
/// </summary>
public unsafe _main()
{
// Analog board setting
if (!FindBoard()) // Search analog board
{
GlobalVar.inErr = true; // Error
GlobalVar.inErrCode = 1; // Board
return;
}
InitalizeBord(); // Initialize board
SetSampling(); // Set Sampling terms
SetRange(); // Set Range Width
SetIntrMask(); // Set Interrupt mask
// Initialize global variables
GlobalVar.inErr = false;
GlobalVar.inErrCode = 0;
}
/// <summary>
/// PLC Program - Process in reset
/// </summary>
~_main()
{
}
/// <summary>
/// PLC Program - Process in start
/// </summary>
public void __Init()
{
GlobalVar.inExe = false;
}
/// <summary>
/// PLC Program - Process in executes
/// </summary>
public unsafe void __Process()
{
if (GlobalVar.inErr)
{
GlobalVar.inExe = false; // Execute request OFF
return;
}
if (GlobalVar.inExe != true) // If Execute request is not issued
{
GlobalVar.inExe = true; // Execute request ON and start sampling
}
/* --- Write ToDo here --- */
}
}
/// <summary>
/// *****************************************************************************************************
/// Data Output Process Block
/// *****************************************************************************************************
/// </summary>
[FUNCTION_BLOCK]
public class _outputdata
{
// *** Internal Variables ***
private UInt32 Rate = 1000; // Sample Rate
private Single Lo = -10.0f; // Min(V)
private Single Hi = 10.0f; // Max(V)
private UInt32 uiStep;
// *** Internal Variables ***
/// <summary>
/// Output range check
/// </summary>
private Boolean CheckRange()
{
if ((Lo > GlobalVar.fHi) || (Lo < GlobalVar.fLo)) return false;
if ((Hi > GlobalVar.fHi) || (Hi < GlobalVar.fLo)) return false;
return true;
}
/// <summary>
/// Calculate output data
/// </summary>
private UInt16 CalcOutputData(Single volt)
{
// (Output Voltage[V] - Min Voltage[V]) * Resolution
// Output Voltage = ──────────────────────────
// Output Voltage[V] - Min Voltage[V]
return (UInt16)(((volt - GlobalVar.fLo) * Board.Resolution) / (GlobalVar.fHi - GlobalVar.fLo));
}
/// <summary>
/// Data Output
/// </summary>
private void OutData(Single volt)
{
Byte bChNo;
// Convert voltage value to output data
GlobalVar.wData = CalcOutputData(volt);
for (bChNo = 0; bChNo < Board.bUseCh; bChNo++)
{ // Output
pcibus.OutBYTE((ushort)(GlobalVar.IOPort + 0x0004), bChNo);
pcibus.OutHWORD((ushort)(GlobalVar.IOPort + 0x0000), GlobalVar.wData);
}
return;
}
/// <summary>
/// Create sine wave
/// </summary>
private Single SinData(UInt32 step)
{
Single gain = (Hi - Lo) / 2.0f; // Amplitude
Single ofst = gain + Lo; // DC offset
Single sin = (gain * (Single)Math.Sin((double)step * (Math.PI * 2.0) / (double)Rate)) + ofst;
return sin;
}
/// <summary>
/// PLC Program - Process in download
/// </summary>
public _outputdata()
{
}
/// <summary>
/// PLC Program - Process in reset
/// </summary>
~_outputdata()
{
}
/// <summary>
/// PLC Program - Process in start
/// </summary>
public unsafe void __Init()
{
GlobalVar.inBusy = false; // Execute Flag OFF
uiStep = 0; // Clear sine wave
}
/// <summary>
/// PLC Program - Process in execute
/// </summary>
public unsafe void __Process()
{
// Output process is not executed when IOPort cannot be got
if (GlobalVar.IOPort == 0)
{
GlobalVar.inBusy = false;
return;
}
// If Max voltage and Min voltage are outside the range, output 0V and end
if (!CheckRange())
{
GlobalVar.fData = 0;
OutData(GlobalVar.fData);
return;
}
// Refresh Execute Flag according to execution request
if (GlobalVar.inBusy != GlobalVar.inExe)
{
GlobalVar.inBusy = GlobalVar.inExe;
}
// If there is an execution request, start output process
if (GlobalVar.inExe)
{
// Create sine wave
uiStep = (uiStep + 1) % Rate;
GlobalVar.fData = SinData(uiStep);
// Write Data
OutData(GlobalVar.fData);
}
return;
}
}