1.3.1 Images and Plots Live Update


Sending Data to a Matrix and See Image Live Update

C#

The following code assume a form with the following objects:

  • a button named "Init" to connect to Origin
  • a combo list named "combDelayTime" with values of 300,500,700,1000
  • a button named "StartStop"
  • a label text named "msgOutBox"
  • a Timer object named "timer1"
  1. You first click the Init button and the StartStop button will enabled and Origin will run and show the single matrix in View Image mode.
  2. You can then click Start to see the image update with the delay time specified.
using System.Windows.Forms;
using Origin;//to allow using MatrixObject etc with Origin.

namespace Realtime_Send_Matrix_View_Image
{
    public partial class Form1 : Form
    {
        const int NUM_ROWS = 480;
        const int NUM_COLS = 640;

        object Default = System.Type.Missing;
        private Origin.ApplicationSI m_app;
        private MatrixPage      m_mpg;
        private MatrixSheet     m_msht;
        private MatrixObject    m_mObj;
        private bool            m_bStarted = false;
        private int             m_nSendCount = 0;

        public Form1()
        {
            InitializeComponent();
            timer1.Interval = Convert.ToInt32(comboDelayTime.Text);
            timer1.Enabled = false;
            StartStop.Enabled = false;// enable after init
        }

        private void Init_Click(object sender, EventArgs e)
        {
            m_app = new Origin.ApplicationSI();
            m_app.NewProject();

            m_app.Visible = MAINWND_VISIBLE.MAINWND_SHOW;

            m_mpg = m_app.MatrixPages.Add(Default, Default);
            m_msht = m_mpg.Layers[0] as MatrixSheet;
            m_msht.Cols = NUM_COLS;
            m_msht.Rows = NUM_ROWS;

            m_mObj = m_msht.MatrixObjects.Add();
            m_mObj.DataFormat = COLDATAFORMAT.DF_USHORT; // unsign short
            //set to view matrix as image, this has to be done by LabTalk for now, until we add the
            //proper COM method in next SR
            m_msht.Execute("matrix -ii");

            StartStop.Enabled = true;
            Init.Enabled = false;//once init, we will not need to execute this again

        }

        private void StartStop_Click(object sender, EventArgs e)
        {
            if (!m_bStarted)
            {
                StartStop.Text = "Stop";
                this.timer1.Enabled = true;
                m_bStarted = true;
            }
            else
            {
                StartStop.Text = "Start";
                this.timer1.Enabled = false;
                m_bStarted = false;
            }
        }
        private void comboDelayTime_SelectedIndexChanged(object sender, EventArgs e)
        {
            timer1.Interval = Convert.ToInt32(comboDelayTime.Text);

        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (m_mObj != null)
            {
                //send over full range values 
                int nMax = (NUM_ROWS - 1) + (NUM_COLS - 1);

                ushort[,] usData = new ushort[NUM_ROWS, NUM_COLS];
                int nn = m_nSendCount++;
                for (int nr = 0; nr < NUM_ROWS; nr++)
                {
                    for (int nc = 0; nc < NUM_COLS; nc++)
                    {
                        int kk = nc + nr;
                        int even = nn % 2; // every other time will flip the matrix
                        if(even == 1)
                            kk = nMax - kk;

                        usData[nr, nc] = (ushort)kk;
                    }
                }
                m_mObj.SetData(usData, 0, 0);
                //for now, need to use LabTalk to specify the Z range of the image to be drawn, Z1 and Z2 are LabTalk variables for the given
                //matrix object to control the Z range to showing the image. Execute for matrixObject is not supported so use matrix sheet
                //is good enough to affect the active MatrixObject
                m_msht.Execute("Z1=0;Z2=" + nMax.ToString());
                msgOutBox.Text = nn.ToString() + ". sending...";
            }
            else
                msgOutBox.Text = "m_mObj is null";
        }
    }
}

VC++

The following code assumes an existing dialog containing three buttons : IDC_BUTTON_Connect, IDC_BUTTON_Disconnect, IDC_BUTTON_SendData; a checkbox IDC_CHECK_AutoUpdate and a combobox of IDC_COMBO_AutoUpdate. Code assumes that you have added Origin COM to your project correctly.


  1. When run the code, first you can click Connect button to launch an Origin instance, click SendData button to send data manually.
  2. When Origin is connected, check auto updating checkbox will enable auto updating data to Origin. Image on Matrixsheet will flip at an interval of some value specified by the combobox.

Main code in Dialog class are as follows:

void CSentDataToMatrixDlg::OnBnClickedCheckAutoupdate()
{
	UpdateData();
	KillTimer(1);//Stop in case already started
	if( this->m_checkAutoUpdate.GetCheck() )
	{
		CString strText;
		GetDlgItem(IDC_COMBO_AutoUpdate)->GetWindowText(strText);

        wchar_t* p = strText.GetBuffer(strText.GetLength());
		UINT nElapse;
		swscanf_s(p, L"%d", &nElapse);

		SetTimer(1, nElapse, NULL);
	}
	else
		KillTimer(1);
}

void CSentDataToMatrixDlg::OnBnClickedButtonConnect()
{
	connect();

}

// connect to Origin
bool CSentDataToMatrixDlg::connect(void)
{
	CoInitialize(NULL);
	disconnect(); //disconnect in case connected

	this->m_pIOApp.CreateInstance(__uuidof(Application));
	m_pIOApp->PutVisible(Origin::MAINWND_SHOW_BRING_TO_FRONT);

	const int nMatrixPageType = 5;
	const int nVisible = 2;
	m_pIOApp->CreatePage( nMatrixPageType, "Data", "", nVisible);

	m_pMatrixPage = m_pIOApp->GetActivePage();
	m_pMatrixSheet = m_pMatrixPage->GetLayers()->Add();

	m_pMatrixSheet->Activate();

	if( m_pMatrixSheet )
	{
		m_pMatrixSheet->PutCols(NUM_COLS);
		m_pMatrixSheet->PutRows(NUM_ROWS);
		m_pMatrixObject = m_pMatrixSheet->GetMatrixObjects()->Add();
		m_pMatrixObject->Activate();
		m_pMatrixObject->DataFormat = Origin::COLDATAFORMAT::DF_USHORT;
        //set to view matrix as image, this has to be done by LabTalk for now, until we add the
        //proper COM method in next SR
		m_pMatrixSheet->Execute("matrix -ii");
	}

	if( m_pIOApp != NULL )
	{
		GetDlgItem(IDC_BUTTON_SendData)->EnableWindow(true);
		GetDlgItem(IDC_BUTTON_Disconnect)->EnableWindow(true);
		GetDlgItem(IDC_BUTTON_Connect)->EnableWindow(false);
		m_bConnected = true;
	}
	
	return true;
}

// disconnect
void CSentDataToMatrixDlg::disconnect(void)
{
	if( m_bConnected )
	{
		KillTimer(1); //Stop auto sending
		this->m_checkAutoUpdate.SetCheck(0);
		GetDlgItem(IDC_BUTTON_SendData)->EnableWindow(false);
		GetDlgItem(IDC_BUTTON_Disconnect)->EnableWindow(false);
		GetDlgItem(IDC_BUTTON_Connect)->EnableWindow(true);
		m_bConnected = false;
		m_pIOApp->Exit();
		m_pIOApp = NULL;
	}
}

void CSentDataToMatrixDlg::OnBnClickedButtonDisconnect()
{
	disconnect();
}

// send data to Origin
bool CSentDataToMatrixDlg::sendData(void)
{
	if( m_pMatrixObject )
	{
		USHORT MAX = NUM_ROWS + NUM_COLS;

		COleSafeArray csarr;
		DWORD bounds[] = {NUM_ROWS, NUM_COLS};
		csarr.Create(VT_UI2, 2, bounds);//create a safe array of two dimesion of unsigned int type
		long index[2];

		for( int ii = 0; ii < NUM_ROWS; ii++ )
		{
			for( int jj = 0; jj < NUM_COLS; jj++ )
			{
				USHORT usData = ii + jj;
				if( m_bFlip ) // every other time will flip the matrix
					usData = MAX - usData;
				index[0] = ii;
				index[1] = jj;
				csarr.PutElement(index, &usData);
			}
		}
		m_bFlip = !m_bFlip;

		m_pMatrixObject->SetData(csarr, 0, 0);
        //for now, need to use LabTalk to specify the Z range of the image to be drawn, Z1 and Z2 are LabTalk variables for the given
        //matrix object to control the Z range to showing the image. Execute for matrixObject is not supported so use matrix sheet
        //is good enough to affect the active MatrixObject
		CString strCmd("Z1=0;Z2=" + MAX);
		_bstr_t _bstrCmd(strCmd);
		m_pMatrixSheet->Execute(_bstrCmd);
	}

	return true;
}

void CSentDataToMatrixDlg::OnBnClickedButtonSenddata()
{
	if( m_bConnected )
		sendData();
}

void CSentDataToMatrixDlg::OnTimer(UINT_PTR nIDEvent)
{
	if ( m_bConnected )
		sendData();
	CDialog::OnTimer(nIDEvent);
}

void CSentDataToMatrixDlg::OnCbnSelchangeComboAutoupdate()
{
	OnBnClickedCheckAutoupdate(); //Just want to update timer interval
}

VB

The following code assume existing a form with following controls:

  • a button named ButtonConnect to connect Origin
  • a button named ButtonDisconnect to disconnect Origin
  • a button named ButotnSendData to send data manually
  • a checkbox named CheckBoxAutoUpdate to allow auto updating.
  • a combobox named ComboBoxAutoUpdate to set intervlas for auto updating
  1. When run the code, first you can click Connect button to launch an Origin instance, click SendData button to send data manually.
  2. When Origin is connected, check auto updating checkbox will enable auto updating data to Origin. Image on Matrixsheet will flip at an interval of some value specified by the combobox.

Code assumes you've added Oringin COM objects to your project correctly:

Public Class Form1
    Dim OriginApp As IOApplication

    Dim msht As MatrixSheet
    Dim mobj As MatrixObject
    Dim NUM_COLS As Integer
    Dim NUM_ROWS As Integer
    Dim STATUS As Integer
    Const MATRIXPAGETYPE = 5
    Const SHOW_WND = 2


    Private Sub ButtonConnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonConnect.Click
        OriginApp = GetObject("", "Origin.Application")
        OriginApp.Visible = MAINWND_VISIBLE.MAINWND_SHOW_BRING_TO_FRONT

        OriginApp.CreatePage(MATRIXPAGETYPE, "", "", SHOW_WND)
        msht = OriginApp.FindMatrixSheet("")
        msht.Cols = NUM_COLS
        msht.Rows = NUM_ROWS

        msht.MatrixObjects.Add()
        mobj = msht.MatrixObjects.Item(0)
        mobj.DataFormat = COLDATAFORMAT.DF_USHORT
        msht.Execute("matrix -ii") 'Currently have to use labtalk command to force Matrix as Image view
        ButtonConnect.Enabled = False
        ButtonDisconnect.Enabled = True
        ButtonSendData.Enabled = True
        CheckBoxAutoUpdate.Enabled = True
    End Sub

    Private Sub ButtonDisconnect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonDisconnect.Click
        ButtonConnect.Enabled = True
        ButtonDisconnect.Enabled = False
        ButtonSendData.Enabled = False
        CheckBoxAutoUpdate.Enabled = False
        CheckBoxAutoUpdate.Checked = False
        mytimer.Enabled = False

        OriginApp.Exit()
        OriginApp = Nothing
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBoxAutoUpdate.SelectedIndex = 0
        NUM_COLS = 500
        NUM_ROWS = 500
    End Sub

    Private Sub mytimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mytimer.Tick
        If (CheckBoxAutoUpdate.Checked) Then
            sendData()
        End If
    End Sub

    Private Sub sendData()
        Dim ii As Integer
        Dim jj As Integer
        Dim MAX As UShort
        MAX = NUM_COLS + NUM_ROWS
        Dim data(0 To NUM_ROWS - 1, 0 To NUM_COLS - 1) As UShort

        For ii = 0 To NUM_ROWS - 1
            For jj = 0 To NUM_COLS - 1
                data(ii, jj) = Convert.ToUInt16(ii + jj)
                If STATUS = 0 Then
                    data(ii, jj) = MAX - Convert.ToUInt16(data(ii, jj))
                End If
            Next
        Next

        If STATUS = 0 Then
            STATUS = 1
        Else
            STATUS = 0
        End If
        mobj.SetData(data, 0, 0)
        'for now, need to use LabTalk to specify the Z range of the image to be drawn, Z1 and Z2 are LabTalk variables for the given
        'matrix object to control the Z range to showing the image. Execute for matrixObject is not supported so use matrix sheet
        'is good enough to affect the active MatrixObject
        msht.Execute("Z1=0;Z2=" + MAX.ToString)
    End Sub

    Private Sub ButtonSendData_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonSendData.Click
        sendData()
    End Sub

    Private Sub CheckBoxAutoUpdate_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CheckBoxAutoUpdate.CheckedChanged
        If (CheckBoxAutoUpdate.Checked) Then
            mytimer.Enabled = True
        Else
            mytimer.Enabled = False
        End If
    End Sub

    Private Sub ComboBoxAutoUpdate_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ComboBoxAutoUpdate.SelectedIndexChanged
        mytimer.Interval = Convert.ToInt32(ComboBoxAutoUpdate.SelectedItem.ToString)
    End Sub
End Class