Sie sind auf Seite 1von 15

Christopher Hayes

RC-Circuit Calculator
Introduction
A simple RC electric circuit consists of an EMF source (battery), a Resistor,
and a Capacitor. When the resistor and capacitor are connected in series with
the EMF source, the capacitor is being charged. When the EMF source is
bypassed, the capacitor discharges. Both of these actions produce a current.
There is a mathematical relationship between EMF, resistance, capacitance,
time, and current, and that is what this application calculates and displays.

Index
Quantity
Voltage
Current
Resistance
Capacitan
ce
Charge
Time

Formulas
Symbol
V or E
I
R
C
Q
t

Unit

Abbreviati

Volt
Ampere
Ohm
Farad

on
V
A

Coulomb
Seconds

t
)
RC

1e
q=Qf

(Charging)

I0 =

Qf =VC

C
s

q=Q0 e

t
)
RC

(Discharging)

V
R

i=I 0 e

t
)
RC

Methods
1. Assigned member variables for time, capacitance, current, resistance,
charge, and voltage.
2. Calculated the initial current (I0) and max charge Q0 outside of loop.
3. Set time to 0.
4. Created a multiplier variable based on the users time input to scale the
x cooredinates of the graph to the window. The size of the graph is 500
so multiplier = 500/time.
5. Created a multiplier variable based on the largest quantity to be
graphed (initial current or max charge) and used an if-else statement
to choose between the two. Since the Y graph is + - 100, multiplier 2 is
100 / (I0 or Q0).
6. Created a for-loop with a counter from 1-1000 with a sleep of 10 ms, so
the animation will last 10 seconds.
7. Used time to calculate current and charge and then display the results
in a text box.
8. Used CClient DC to alternate between drawing the current graph and
charge graph for each cycle in the loop.

Results
Charging

Discharging

Discussion and Conclusion

The program works as intended and all results are accurate. The current
through the circuit and the charge on the capacitor displays correctly over a
specified time period. The final results are displayed in the text boxes on the
right.

Appendix A

Instructions:
1.
2.
3.
4.
5.
6.
7.

Enter the EMF in Volts. (V)


Enter the Resistance in ohms. ()
Enter the Capacitance in micro Farads (uF).
Enter the time in seconds. (s)
Press the charge button.
Press the discharge Button
Observe Results in Amazement.

Appendix B
C++ Code:

Dlg.h file
// ChargingandDischargingCapacitorDlg.h : header file
//
#pragma once
// CChargingandDischargingCapacitorDlg dialog
class CChargingandDischargingCapacitorDlg : public CDialogEx
{
// Construction
public:
CChargingandDischargingCapacitorDlg(CWnd* pParent = NULL);
constructor

// standard

// Dialog Data
enum { IDD = IDD_CHARGINGANDDISCHARGINGCAPACITOR_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
// Implementation
protected:
HICON m_hIcon;

public:

// Generated message map functions


virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
double m_V;
double m_R;
double m_C;
afx_msg void OnBnClickedBtnCharge();
double m_i;
double m_q;
double m_t;
afx_msg void OnBnClickedBtnDischarge();

// DDX/DDV support

CString m_current;
CString m_charge;
CString m_time;
afx_msg void OnBnClickedBtnReset();
double m_boundx;
double m_boundypos;
double m_boundyneg;
afx_msg void OnEnChangeEdtTime();
};

Dld.cpp file

// ChargingandDischargingCapacitorDlg.cpp : implementation file


//
#include
#include
#include
#include
#include

"stdafx.h"
"ChargingandDischargingCapacitor.h"
"ChargingandDischargingCapacitorDlg.h"
"afxdialogex.h"
"math.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);

// DDX/DDV support

}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CChargingandDischargingCapacitorDlg dialog

CChargingandDischargingCapacitorDlg::CChargingandDischargingCapacitorDlg(CWnd* pParent
/*=NULL*/)
: CDialogEx(CChargingandDischargingCapacitorDlg::IDD, pParent)
, m_V(0)
, m_R(0)
, m_C(0)
, m_i(0)
, m_q(0)
, m_t(0)
, m_current(_T(""))
, m_charge(_T(""))
, m_time(_T(""))
, m_boundx(0)
, m_boundypos(0)
, m_boundyneg(0)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CChargingandDischargingCapacitorDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDT_EMF, m_V);
DDX_Text(pDX, IDC_EDT_RESISTANCE, m_R);
DDX_Text(pDX, IDC_EDT_CAPACITANCE, m_C);
DDX_Text(pDX, IDC_STA_CURRENT, m_current);
DDX_Text(pDX, IDC_STA_CHARGE, m_charge);
DDX_Text(pDX, IDC_EDT_TIME, m_time);
DDX_Text(pDX, IDC_STA_BOUNDX, m_boundx);
DDX_Text(pDX, IDC_STA_BOUNDYPOS, m_boundypos);
DDX_Text(pDX, IDC_STA_BOUNDYNEG, m_boundyneg);
}
BEGIN_MESSAGE_MAP(CChargingandDischargingCapacitorDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_CHARGE,
&CChargingandDischargingCapacitorDlg::OnBnClickedBtnCharge)
ON_BN_CLICKED(IDC_BTN_DISCHARGE,
&CChargingandDischargingCapacitorDlg::OnBnClickedBtnDischarge)
ON_BN_CLICKED(IDC_BTN_RESET,
&CChargingandDischargingCapacitorDlg::OnBnClickedBtnReset)
ON_EN_CHANGE(IDC_EDT_TIME,
&CChargingandDischargingCapacitorDlg::OnEnChangeEdtTime)
END_MESSAGE_MAP()

// CChargingandDischargingCapacitorDlg message handlers


BOOL CChargingandDischargingCapacitorDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE);
// Set big icon
SetIcon(m_hIcon, FALSE);
// Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CChargingandDischargingCapacitorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CChargingandDischargingCapacitorDlg::OnPaint()
{
if (IsIconic())

CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND,
reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{

CDialogEx::OnPaint();

}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CChargingandDischargingCapacitorDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CChargingandDischargingCapacitorDlg::OnBnClickedBtnCharge()
{
// TODO: Add your control notification handler code here
UpdateData(true);
m_t = _tstof(m_time);
double mult = 500/m_t;
double mult2;
double I0 = m_V/m_R;
double j = m_t/100;
double Q0 = m_V * m_C;
double cur,curp,t,tp,q,qp;
curp = 200;
tp = 50;
qp = 200;
m_t = 0;
if(I0 > Q0)
{
mult2 = 100/I0;
m_boundypos = I0;
m_boundyneg = -I0;
}
else
{
mult2 = 100/Q0;
m_boundypos = Q0;

m_boundyneg = -Q0;

CClientDC dc(this);
CPen greenPen(0,1,RGB(0,255,0));
CPen bluePen(0,1,RGB(0,0,255));
CPen yellowPen(0,1,RGB(255,255,0));
CPen redPen(0,1,RGB(255,0,0));
CPen* pPen;
dc.Rectangle(49,99,551,301);
dc.MoveTo(50,200);
dc.LineTo(550,200);

//Diagram
//
//
dc.MoveTo(625,100);
dc.LineTo(575,100);
dc.LineTo(575,195);
//EMF source
dc.MoveTo(560,195);
dc.LineTo(590,195);
dc.MoveTo(570,205);
dc.LineTo(580,205);
dc.MoveTo(575,205);
dc.LineTo(575,300);
dc.LineTo(725,300);
dc.LineTo(725,100);
dc.LineTo(675,100);
//Resistor
dc.MoveTo(650,300);
dc.LineTo(650,273);
dc.LineTo(655,270);
dc.LineTo(645,265);
dc.LineTo(655,260);
dc.LineTo(645,255);
dc.LineTo(655,250);
dc.LineTo(645,245);
dc.LineTo(650,242);
dc.LineTo(650,180);
//Capacitor
dc.MoveTo(640,180);
dc.LineTo(660,180);
dc.MoveTo(640,170);
dc.LineTo(660,170);
dc.MoveTo(650,170);
dc.LineTo(650,140);
//Switch

pPen = dc.SelectObject(&redPen);
dc.LineTo(625,100);
dc.MoveTo(650,140);
pPen = dc.SelectObject(&yellowPen);
dc.LineTo(675,100);
for(int i = 1; i <= 100; i++)
{

m_t += j;
m_time.Format(_T("%1.3e"),m_t);
m_i = I0 * exp(-m_t/(m_R * m_C));
m_current.Format(_T("%1.3e"),m_i);
m_q = m_C * m_V * (1 - exp(-m_t / (m_R * m_C)));
m_charge.Format(_T("%1.3e"),m_q);
t = 50 + mult * m_t;
cur = 200 - mult2 * m_i;
q = 200 - mult2 * m_q;
dc.MoveTo(tp,qp);
pPen = dc.SelectObject(&bluePen);
dc.LineTo(t, q);
qp = q;

dc.MoveTo(tp,curp);
pPen = dc.SelectObject(&greenPen);
dc.LineTo(t,cur);
curp = cur;
tp = t;
Sleep(100);
UpdateData(false);

}
void CChargingandDischargingCapacitorDlg::OnBnClickedBtnDischarge()
{
// TODO: Add your control notification handler code here
UpdateData(true);
m_t = _tstof(m_time);
double mult = 500/m_t;
double mult2;
double q2 = m_q;
m_q = 0;
double j = m_t/100;
double Q0 = m_V * m_C;
double I0 = Q0/(m_R * m_C);
double cur,curp,t,tp,q,qp;
curp = 200;
tp = 50;
qp = 200;
m_t = 0;
if(fabs(I0) > Q0)
{

}
else
{

mult2 = 100/I0;
m_boundypos = I0;
m_boundyneg = -I0;

mult2 = 100/Q0;
m_boundypos = Q0;
m_boundyneg = -Q0;

CClientDC dc(this);
dc.Rectangle(49,99,551,301);
dc.MoveTo(50,200);
dc.LineTo(550,200);
CPen greenPen(0,1,RGB(0,255,0));
CPen bluePen(0,1,RGB(0,0,255));
CPen yellowPen(0,1,RGB(255,255,0));
CPen redPen(0,1,RGB(255,0,0));
CPen* pPen;
//Diagram
//
//
dc.MoveTo(625,100);
dc.LineTo(575,100);
dc.LineTo(575,195);
//EMF source
dc.MoveTo(560,195);
dc.LineTo(590,195);
dc.MoveTo(570,205);
dc.LineTo(580,205);
dc.MoveTo(575,205);
dc.LineTo(575,300);
dc.LineTo(725,300);
dc.LineTo(725,100);
dc.LineTo(675,100);
//Resistor
dc.MoveTo(650,300);
dc.LineTo(650,273);
dc.LineTo(655,270);
dc.LineTo(645,265);
dc.LineTo(655,260);
dc.LineTo(645,255);
dc.LineTo(655,250);
dc.LineTo(645,245);
dc.LineTo(650,242);
dc.LineTo(650,180);
//Capacitor
dc.MoveTo(640,180);
dc.LineTo(660,180);
dc.MoveTo(640,170);
dc.LineTo(660,170);

dc.MoveTo(650,170);
dc.LineTo(650,140);
//Switch
pPen = dc.SelectObject(&redPen);
dc.LineTo(625,100);
dc.MoveTo(650,140);
pPen = dc.SelectObject(&yellowPen);
dc.LineTo(675,100);
for(int i = 1; i <= 100; i++)
{

m_t += j;
m_time.Format(_T("%1.3e"),m_t);
m_i = -m_q/(m_R * m_C);
m_current.Format(_T("%1.3e"),m_i);
m_q = q2 * exp(-m_t/(m_R * m_C));
m_charge.Format(_T("%1.3e"),m_q);
t = 50 + mult * m_t;
cur = 200 - mult2 * m_i;
q = 200 - mult2 * m_q;
dc.MoveTo(tp,qp);
pPen = dc.SelectObject(&bluePen);
dc.LineTo(t, q);
qp = q;
dc.MoveTo(tp,curp);
pPen = dc.SelectObject(&greenPen);
dc.LineTo(t,cur);
curp = cur;
tp = t;
Sleep(100);
UpdateData(false);
}
}
void CChargingandDischargingCapacitorDlg::OnBnClickedBtnReset()
{
// TODO: Add your control notification handler code here
UpdateData(true);
m_V = 0;
m_R = 0;
m_C = 0;
m_time = _T("0");
m_current = _T("0");
m_charge = _T("0");
m_boundx = 1;
m_boundypos = 1;
m_boundyneg = -1;

CClientDC dc(this);
dc.Rectangle(49,99,551,301);
dc.MoveTo(50,200);
dc.LineTo(550,200);
UpdateData(false);
}
void CChargingandDischargingCapacitorDlg::OnEnChangeEdtTime()
{
// TODO: If this is a RICHEDIT control, the control will not
// send this notification unless you override the CDialogEx::OnInitDialog()
// function and call CRichEditCtrl().SetEventMask()
// with the ENM_CHANGE flag ORed into the mask.

// TODO: Add your control notification handler code here


UpdateData(true);
m_boundx = _tstof(m_time);
UpdateData(false);

Das könnte Ihnen auch gefallen