//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "stdio.h"
#include "modrtu.h"
#include ".\lib\modbus.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
char caParity[]={'N','O','E'};
modbus_t *ctx;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        unsigned long ultimeout=0;
	char tmp[64];

	int		m_baud=Edit2->Text.ToInt();
	int		m_databit= Edit4->Text.ToInt();
	int		m_parity= Edit3->Text.ToInt();
	int		m_stopbit=Edit5->Text.ToInt();
	int		m_rtutime=Edit7->Text.ToInt();

        int comport=Edit1->Text.ToInt();

        if(comport<10)
        	sprintf(tmp,"COM%d:",comport );
        else
                sprintf(tmp,"\\\\.\\COM%d",comport );
                
	ctx = modbus_new_rtu(tmp, m_baud, caParity[m_parity], m_databit, m_stopbit); //Create a Modbus RTU context
        modbus_set_slave(ctx, 1); //Set slave ID
	ultimeout=m_rtutime*1000; //ms --> us


	if(ctx!=NULL){
                if (modbus_connect(ctx) == -1) { //Establish a connection
                        sprintf(tmp,"lasterror: %d",modbus_strerror(errno));
                        String s="Connection failed, " + AnsiString(tmp);

                        Application->MessageBox(s.c_str(), "OK", MB_OKCANCEL);
			modbus_free(ctx); //Free libmodbus context
		}
		else
		{
		//modbus_set_response_timeout(ctx,0,ultimeout); // set timeout for response
        		Application->MessageBox("RTU Create Success!", "OK", MB_OKCANCEL);
                }
	}   
}
//---------------------------------------------------------------------------

void __fastcall TForm1::FormCreate(TObject *Sender)
{
        Edit1->Text="1";

        Edit8->Text="0";  //read coils from
        Edit9->Text="5";  //read coils to
        
        Edit10->Text="0"; //read input bit from
        Edit11->Text="1"; //read input bit to


        Edit14->Text="0"; //read regs from
        Edit15->Text="4"; //read regs to

        Edit20->Text="0"; //read input reg from
        Edit21->Text="4"; //read input reg to

        Edit23->Text="6"; //write coil addr
        Edit24->Text="1"; //write coil value

        Edit26->Text="5"; //write Regs addr
        Edit27->Text="12345"; //write Regs value

        Edit2->Text="19200";
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
        if(ctx!=NULL)
        {
        	modbus_close(ctx);  //Close a connection
        	modbus_free(ctx);  //Free libmodbus context
        }
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)
{
	unsigned char *tab_bit;
	int 	m_rcoilfrom;
	int 	m_rcoilto;
	int rr;        

        m_rcoilfrom =Edit8->Text.ToInt();
        m_rcoilto = Edit9->Text.ToInt();
        
	int nbpoints=(m_rcoilto-m_rcoilfrom+1);

	tab_bit = (unsigned char *) malloc(nbpoints * sizeof(unsigned char));
	memset(tab_bit, 0, nbpoints * sizeof(unsigned char));

	printf("m_rcoilfrom=%d, nbpoints=%d\r\n",m_rcoilfrom,nbpoints);
	rr = modbus_read_bits(ctx, m_rcoilfrom, nbpoints, tab_bit); //The function uses the Modbus function code 0x01 (read coil status).
	if(rr>0)
	{
		String str;
		for(int i=0;i<nbpoints;i++)
		{
			str += tab_bit[i];
		}
	        Edit13->Text=str;
	}
        free(tab_bit);
}       //---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)
{
        unsigned char *tab_bit;
	int 	m_rInputbitfrom;
	int 	m_rInpubitto;
	int rr;

        m_rInputbitfrom =Edit10->Text.ToInt();
        m_rInpubitto = Edit11->Text.ToInt();
	int nbpoints=(m_rInpubitto-m_rInputbitfrom+1);
	tab_bit = (unsigned char *) malloc(nbpoints * sizeof(unsigned char));
	memset(tab_bit, 0, nbpoints * sizeof(unsigned char));

	rr = modbus_read_input_bits(ctx, m_rInputbitfrom, nbpoints, tab_bit); //The function uses the Modbus function code 0x02 (read input status).
	if(rr>0)
	{
		String str;
		for(int i=0;i<nbpoints;i++)
        		str += tab_bit[i];
                Edit12->Text=str;
        }
        free(tab_bit);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)
{
        unsigned short *tab_bit;
	int 	m_rregsfrom;
	int 	m_rregsto;
       	int rr;


        m_rregsfrom =Edit14->Text.ToInt();
        m_rregsto = Edit15->Text.ToInt();
	int nbpoints=(m_rregsto-m_rregsfrom+1);

	tab_bit = (unsigned short *) malloc(nbpoints * sizeof(unsigned short));
	memset(tab_bit, 0, nbpoints * sizeof(unsigned short));
	rr = modbus_read_registers(ctx, m_rregsfrom, nbpoints, tab_bit); //The function uses the Modbus function code 0x02 (read input status).
	if(rr>0)
	{
		String str;
		for(int i=0;i<nbpoints;i++)
        		str += tab_bit[i];
                Edit16->Text=str;
        }
        free(tab_bit);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button6Click(TObject *Sender)
{
        unsigned short *tab_bit;
	int 	m_rInputregfrom;
	int 	m_rInpuregto;
       	int rr;

        m_rInputregfrom =Edit20->Text.ToInt();
        m_rInpuregto = Edit21->Text.ToInt();
	int nbpoints=(m_rInpuregto-m_rInputregfrom+1);

	tab_bit = (unsigned short *) malloc(nbpoints * sizeof(unsigned short));
	memset(tab_bit, 0, nbpoints * sizeof(unsigned short));

	rr = modbus_read_input_registers(ctx, m_rInputregfrom, nbpoints, tab_bit); //The function uses the Modbus function code 0x04 (read input registers).
	if(rr>0)
	{
		String str;
		for(int i=0;i<nbpoints;i++)
        		str += tab_bit[i];
                Edit22->Text=str;
	}
        free(tab_bit);        
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)
{
	int 	m_wcoils;
	int 	m_wcoil;
       	int rr;

        m_wcoil =Edit23->Text.ToInt();
        m_wcoils = Edit24->Text.ToInt();

        rr= modbus_write_bit(ctx,m_wcoil,m_wcoils); //The function uses the Modbus function code 0x05 (force single coil).
	if(rr>0)
	{
		;
	}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button8Click(TObject *Sender)
{
	int 	m_wregv;
	int 	m_wreg;
       	int rr;

        m_wreg =  Edit26->Text.ToInt();
        m_wregv = Edit27->Text.ToInt();
        rr=modbus_write_register(ctx,m_wreg,m_wregv); //The function uses the Modbus function code 0x06 (preset single register).
	if(rr>0)
	{
		;
	}        
}
//---------------------------------------------------------------------------

