// unit1.cpp v1.0
// Copyright (C)1999-2007 Virtual Integrated Design
// www.rs232pro.com
// This is the main form class.
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
#include <stdio.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
// Create new port.
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
Port=new RS232Port();
}
//---------------------------------------------------------------------------
// Close port and save settings.
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
Port->ClosePort();
delete Port;
Port=NULL;
SaveToIni("Dvm-001.ini");
}
//---------------------------------------------------------------------------
// Initialize forms and settings.
void __fastcall TForm1::FormShow(TObject *Sender)
{
// 1). Initialize Form2 from ini
// 2). Initialize display from ini
LoadFromIni("Dvm-001.ini");
MakeAdjustments();
}
//---------------------------------------------------------------------------
// Update display every 250ms.
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
if( Port->IsOpen() && Form2->AutoCheckBox->Checked )
{ DisplayAdcValue(); }
}
//---------------------------------------------------------------------------
// Clicking the "Advanced" menu item shows the form 2 menu that allows the user
// to set the samples, settle time, input selection, input compensation, auto-
// update and com port.
// When the user clicks "OK" we return to this method and we must adjust the
// settings appropriately.
void __fastcall TForm1::Advanced1Click(TObject *Sender)
{
int ReturnCode=Form2->ShowModal();
if(ReturnCode==mrOk)
{
MakeAdjustments();
}
}
//---------------------------------------------------------------------------
// We must "Make Adjustments" to our settings after the ini file is loaded
// and whenever we return from the advanced form.
void TForm1::MakeAdjustments(void)
{
AnsiString s="";
if(Form2->AutoCheckBox->Checked){ Timer1->Enabled = true; }
else{ Timer1->Enabled = false; }
DisplayRange();
if(Port->IsOpen())
{
SetAdcSamples((unsigned char)Form2->SamplesEdit->Text.ToInt());
SetAdcSettleTime((unsigned char)Form2->SettleEdit->Text.ToInt());
DisplayAdcValue();
}
}
//---------------------------------------------------------------------------
// Clicking the "Refresh" menu item displays 1 reading at a time.
void __fastcall TForm1::Refresh1Click(TObject *Sender)
{
AnsiString s="";
if(Port->IsOpen()){ DisplayAdcValue(); }
else
{
s = "Port must be open first.";
Application->MessageBox(s.c_str(),"Error",MB_OK | MB_ICONWARNING);
}
DisplayRange();
}
//---------------------------------------------------------------------------
// The open button shows "Open Port" when the port is closed and "Close Port"
// when its open. When the port can't be opened a warning message is shown.
void __fastcall TForm1::OpenButtonClick(TObject *Sender)
{
AnsiString s = Form2->PortCombo->Text;
AnsiString str = "";
if(OpenButton->Caption=="Open Port")
{
bool ok = Port->OpenPort(s);
if(!ok)
{
str = "Can't open port.";
Application->MessageBox(str.c_str(),"Error",MB_OK | MB_ICONWARNING);
}
if(Port->IsOpen()){ OpenButton->Caption="Close Port"; }
}
else
{
Port->ClosePort();
if(!Port->IsOpen()){ OpenButton->Caption="Open Port"; }
}
}
//---------------------------------------------------------------------------
// This method gets the reading from the micro, calculates the result based
// on what resistors are present for a given input and displays that value
// on the main readout label. value = R2/R1+R2.
bool TForm1::DisplayAdcValue(void)
{
unsigned short value = 1;
double divisor = 100000; // R2 = 100K
double result = 0;
char display[]={"0000000"};
double volts_per_count = 5;
volts_per_count /= 1024;
bool ok = GetAdcValue(value);
if( ok && (value<=1024) ){ result = (value * volts_per_count); }
if(ok && Form2->HvRadioButton->Checked) // R2/R1+R2
{
divisor /= 1100000;
result /= divisor;
result += Form2->HvEdit->Text.ToDouble();
sprintf(display,"%2.2f",result);
}
else if(ok && Form2->MvRadioButton->Checked) // R2/R1+R2
{
divisor /= 599000;
result /= divisor;
result += Form2->MvEdit->Text.ToDouble();
sprintf(display,"%2.2f",result);
}
else if(ok && Form2->LvRadioButton->Checked)
{
result += Form2->LvEdit->Text.ToDouble(); // Add comp if any
sprintf(display,"%1.3f",result);
}
if(ok)
{
strcat(display,"v");
MainReadOut->Caption = display;
}
return ok;
}
//---------------------------------------------------------------------------
// This method shows the input range selection on the smaller display label.
void TForm1::DisplayRange(void)
{
if(Form2->HvRadioButton->Checked){ SelectReadOut->Caption="H"; }
else if(Form2->MvRadioButton->Checked){ SelectReadOut->Caption="M"; }
else if(Form2->LvRadioButton->Checked){ SelectReadOut->Caption="L"; }
}
//---------------------------------------------------------------------------
// The micro returns a 2 byte representation of the 10-bit value that is seen
// by the micro's adc. The high byte is transmitted first. The amount of settle
// time after the command is received and the number of averaged samples taken
// for the adc reading are determined by the variables in the micro. These var-
// iables are defaulted to 16 samples and 50ms settle time and can be set by
// calling the SetAdcSamples and SetAdcSettleTime methods.
bool TForm1::GetAdcValue(unsigned short &us)
{
bool ok=false;
unsigned char uc[]={0,0};
unsigned char* ucp = (unsigned char*)&us;
Port->PutByte(0x01);
Port->PutByte(0x04);
if( Port->GetByte(uc[0]) && Port->GetByte(uc[1]) )
{
ok = true;
*(ucp+1) = uc[0];
*ucp = uc[1];
}
return ok;
}
//---------------------------------------------------------------------------
// Sets the number of samples variable in the micro. The variable is used
// by the micro to determine how many samples to take and average when a
// GetAdcValue is requested by the pc.
bool TForm1::SetAdcSamples(unsigned char uc) // loops per data request
{
bool ok=false;
unsigned char temp_uc = 0;
Port->PutByte(0x01);
Port->PutByte(0x02);
Port->PutByte(uc);
if( Port->GetByte(temp_uc) )
{
if( temp_uc == uc ){ ok = true; }
}
return ok;
}
//---------------------------------------------------------------------------
// Sets the settle time variable which determines how long the delay is from
// the time the request is received until the micro starts taking data.
// We have a delay after receiving the byte to let the supply settle. The act
// of receiving a byte pulls on the supply and may affect the accuracy of the
// reading because the micro gets its reference from the supply voltage.
bool TForm1::SetAdcSettleTime(unsigned char uc) // Milliseconds
{
bool ok=false;
unsigned char temp_uc = 0;
Port->PutByte(0x01);
Port->PutByte(0x03);
Port->PutByte(uc);
if( Port->GetByte(temp_uc) )
{
if( temp_uc == uc ){ ok = true; }
}
return ok;
}
//---------------------------------------------------------------------------
// Initializes new Form2 values.
bool TForm1::LoadFromIni(char* name)
{
bool ok=false;
if( FileExists(name) ) // Check for file exist
{
TStringList* inip=new TStringList;
inip->LoadFromFile(name);
if(inip->Count > 15)
{
ok = true;
Form2->PortCombo->ItemIndex = inip->Strings[1].ToInt();
if(inip->Strings[3] == "55V"){ Form2->HvRadioButton->Checked = true; }
else if(inip->Strings[3] == "29V"){ Form2->MvRadioButton->Checked = true; }
else if(inip->Strings[3] == "5V"){ Form2->LvRadioButton->Checked = true; }
else{ Form2->HvRadioButton->Checked = true; }
Form2->HvEdit->Text = inip->Strings[5];
Form2->MvEdit->Text = inip->Strings[7];
Form2->LvEdit->Text = inip->Strings[9];
if(inip->Strings[11] == "true"){ Form2->AutoCheckBox->Checked = true; }
else{ Form2->AutoCheckBox->Checked = false; }
Form2->SamplesEdit->Text = inip->Strings[13];
Form2->SettleEdit->Text = inip->Strings[15];
}
if(inip){ delete inip; }
}
return ok;
}
//---------------------------------------------------------------------------
// Saves Form2 parameters to ini file.
bool TForm1::SaveToIni(char* name)
{
// Load ini and save size parameters
bool ok=false;
if( FileExists(name) ) // Check for file exist
{
TStringList* inip=new TStringList;
inip->LoadFromFile(name);
inip->Strings[1] = Form2->PortCombo->ItemIndex;
if(Form2->LvRadioButton->Checked){ inip->Strings[3] = "5V"; }
if(Form2->MvRadioButton->Checked){ inip->Strings[3] = "29V"; }
if(Form2->HvRadioButton->Checked){ inip->Strings[3] = "55V"; }
inip->Strings[5] = Form2->HvEdit->Text;
inip->Strings[7] = Form2->MvEdit->Text;
inip->Strings[9] = Form2->LvEdit->Text;
if(Form2->AutoCheckBox->Checked){ inip->Strings[11] = "true"; }
else{ inip->Strings[11] = "false"; }
inip->Strings[13] = Form2->SamplesEdit->Text;
inip->Strings[15] = Form2->SettleEdit->Text;
inip->SaveToFile(name);
delete inip;
}
return ok;
}
//---------------------------------------------------------------------------