|Explaining Ohm's Law with a simple 'C' program (With GUI example)|
|Written by Bryce Ringwood|
Most kids with a technical bent wire up a simple circuit consisting of a battery, a bulb, and sometimes, a switch. Nowadays, we use an LED (Light Emitting Diode) plus a resistor instead of a torch bulb, but let's begin with a simple circuit consisting of a battery and a resistor. The notes below give a rough idea of how this works.
The voltage and current in the resistor obey Ohm's Law:
\textstyle V = IR
\textstyle P = IV
Where:V = Applied Voltage
I = Current (NOT "Amperage")
P = Power (NOT "Wattage")
R = Resistance
Programming Ohm's Law in 'C'
The "White Book" was one of the earliest books to promote the now infamous "Hello World" program as an simple programming example. Here, I'm going to use Ohm's Law. Its also simple, but it introduces one of the most harrowing properties of the language - namely pointers. I will try (and probably fail) to follow the style of the "White Book" The White Book- but remember that some of the modern C++ compilers will want things done slightly differently. I'm going to use "Turbo C" for DOS as the compiler. (See article on setting up an MSDOS computer).
If you have installed Turbo C in a directory such as "TC" you will have to set a path, so that the compiler can find everything. Type:
You can put this command in a batch file called turbc.bat, and invoke it by typing
from the command line. Alternatively, put the above command in your autoexec.bat file. You can use TC itself as the editor, or you can download an editor, such as "Terse" or the infamous "VI" pronounced vee eye. I'm pretty sure there's a'VI' editor for DOS. Just avoid 'edlin', which came with the DOSes up to about 3.3.
and enter the program. Compile it (Build all), save the program and exit.
Run the program by typing :
C:>ohm at the command line.
Now let's explain what's going on here.
In 'C' every program has a 'main' function that is invoked when the program begins. In 'C' this needs no arguments or return value. Later on we'll see that functions have values that you can pass to them, and every function has a return value - even if its the empty value "void". If you are using a C++ compiler, it may complain that it wants the function main to look like:
int main(int argc, char** argv) - we will see what this is all about a little later on.
At the beginning of the function, you will see the variables, namely i, r and v being declared as float. 'C' is a 'typed' language - you will learn the various types, but a float is a floating point number like 3.14159. The other declaration you will see early on is int - integer values like 1,2 3, 23766. Note that when they are declared - the floats have a little "f" after them.
Almost the first 'C' function you will encounter is printf(). Yes, printf is a function, and the stuff between the brackets are the arguments to the function. This is because printf is written in 'C' itself and not a strict part of the language like BASIC (and FORTRAN)s PRINT or Pascals "WriteLn".
The next function is scanf. You will see some mysterious "&" symbols in front of the i,v and r. Unlike other programming languages, 'C' passes its arguments to functions by value. These values cannot be changed when the function exits. (Unlike FORTRAN, for example, where you can sometimes do silly things like making 3.0 have the value of 0.0, or something else.) SO the way round the problem is to pass memory locations or pointers to functions. If you talk to yourself, you can subvocalise and say "&i" is the memory location where i is stored". Clearly, you can alter the contents of the memory location, but the value of the pointer (address of the mempry cell in RAM) to where "i" is stored remains the same. Nice cheat, hey? (In the C++ programming language "&" is called a reference, and has slightly different properties). Later on you can refer to the article on pointers.
Now follows a "Block if" statement. If the value v==0.0f equates to true, then the program continues, otherwise it proceeds to the next statement .. and so on. Actually, all this code is very buggy - do you see why ?
Finally, that statement right at the front: #include<stdio.h> means simply that the entire contents of the file stdio.h are prefixed to the code in the file ohm.c. This is required because 'C' wants all its functions defined before you use them, and this file contains definitions of printf and scanf, among many other things. 'C' has a macro language and #include is a macro.
This program can also be compiled using Visual Studio 2015 (See Below). You need to select a Win32 console application at Step 4. There is no 'C' compiler - so you need to modify the program slightly. The function main() has to be an integer type with a return value of zero. Because of all the nasty hackers, the scanf() function has been deprecated - you must now use scanf_s().
An Ohm Program with a Windows Dialog Box - GUI Example
The foregoing example uses a command-line interface, which is not very modern and may present too many difficulties for many users. Some months ago, Microsoft released Visual Studio 2015 Community Edition. This provides non-commercial developers with all the tools required to quickly and fairly easily develop applications with a modern(ish) look and feel.
Assuming you have a "Windows 10" computer:
When finished, we are ready to begin. "MFC" stands for "Microsoft Foundation Classes". Programs written using MFC do not need the .Net runtime, but they also don't run with "managed code" - so you can cause problems with memory allocation and so on. The alternative "Universal Windows Platform", I leave to you to investigate.
When "Windows" was first introduced, there were no "code generators" like VS, and programmers had to struggle with native code and "Win32" functions. With every new Windows version, Charles Petzold would bring out a new book telling us how to program the latest version using plain 'C'. There is nothing to stop you from doing this - it looks like VS still caters for Win32 programming.
Be that as it may, Microsoft introduced MFC with their first C++ compiler. Essentially, MFC provided a "wrapper" around the Win32 functions. For a while MFC seemed to languish, but Microsoft seem to have revived it.
I don't know much about the early "Visual Studio" versions - or maybe I have mercifully forgotten about them.(I vaguely remember struggling with an early system on Windows NT3). Visual Studio 6 was a great success, and programs could be developed that would run on Windows 95, XP, 7 .. and will even work on Win 10.
VS6 had to be paid for, so it is really nice that VS 2015 community edition is free.
You now have (or soon will have) four windows. The top left window has your dialog box, and a toolbox tab. The bottom left window has "Output".
The top right window is the solution explorer and displays your program code in a structured form. You will see header files (.h) and files containing code (.cpp). The bottom right pane contains the properties of the selected element on your dialog box.
Now add controls. First - Highlight the TODO wording and change it to "Enter Resistance". Copy it and paste it 4 times, and change the wording to "Enter Current", "Enter Voltage", "Enter Power" etc.
Now click the toolbox. Select "Edit control" and click the Dialog tab to see your dialog box again. Add the edit control. Copy and paste it three times.
Move the items around on the dialog box until you think it looks pretty.
Now you need to associate a variable with each edit box. Assuming you want to enter resistance in the top edit box, highlight it, then right click.
Select "Add Variable" - you will get the Add Member Variable Wizard.
Under "Category" select "Value". Under "Variable type", select "double" and give the variable a name "m_Res". Click "Finish".
The function "UpdateData(BOOL)" collects data from the edit windows when TRUE and sends data when FALSE.
The AfxMessageBox(LPCTSTR) function pops up a message box. Pressing the OK button causes the code to run. The _T macro converts yoursingle byte ASCII characters to Unicode (2 byte wide characters).
The Finished Ohm Program
Now run your program (Debug -> Start Without Debugging) and feel good.
Or not. The problem for some people may be that there has been a lot of clicking menus, filling in forms and absolutely no understanding of what is going on. If you are the sort of person that can't drive a car without understanding how the engine works, then the real truth of Windows programming is that it is complicated. MFC takes the basic windows functions and parameters, and converts them to members of windows classes.
Maybe the next step would be to get hold of one of Petzold's "Programming Windows" books and try to follow the explanations provided. You might even want to try a "Win32" application - native 'C'. In the mean time, you can hone your skills writing small programs that you may need.
Petzold's programming book is available free on the web. Look for the latest edition you can find.
Resistors in Series and Parallel
Sometimes, you don't have the correct value resistor in your junkbox, and have to combine values by putting others in series and/or parallel with a value near to the one you want. The notes below are just a simple explanation of how the formulae are derved.
Without getting too technical, Kirchoff's current law states that the sum of currents flowing into a node or point equals the sum flowing out.
Also the sum of voltages flowing in an electric circuit is also zero.
We used the Current law for resistors in parallel and we used the voltage law for the resistors in series. The classic puzzle is to calculate the equivalent resistance of a cube of 1 Ohm resistors, with connections made at opposite corners. Its quite easy if all the resistors have the same value - but more difficult if you let all the resistors have arbitrary values.
There is a computer program for solving this on the internet.
You might want to write a simple 'C' program for series and parallel resistors.
Resistor 'E' Series
Resistors can be bought in any value you want, but if you want a 201.305 Ohm resistor - it might be pretty pricey. (There used to be lady in Pretoria who would make up resistors specially for you to .001% tolerance. They were somewhat expensive - I think I still have one or two.)
Normally, I use 1% metal film resistors, because they are quite inexpensive. These are available in the E24 series, which has (expectedly) 24 values per decade. You may find a supplier who stocks E48 series. I think the idea was that there would be an overlap in tolerance between each resistor value.
Resistors in old radios often have a 20% tolerance (E6 series).
To read a resistor value with a 20% tolerance, often the first digit of the resistor was represented by the colour of the body. The next digit was the tip and the multiplier was a coloured dot on the body. (Remember body-tip-dot).
A 10% tolerance - 5% tolerance resistor has coloured bands. The first represents the first digit, the second represents the 2nd digit and the third represents the multiplier. So, a 47k resistor would be marked yellow(4) - Violet(7) - Orange (3 noughts). The final band would be the tolerance.
A 1% resistor would have 3 bands for the digits: yellow(4)-Violet(7)-black(0) and red (2 noughts). The tolerance band would be brown for 1%.
Surface mount resistors often have the value in digits in microscopic writing.
Before you charge off and learn the colour code for resistors (It follows the colours of the rainbow), I strongly suggest you use a multimeter to check the value before you go putting the thing in a circuit. To bring this point home, I have a bag of resistors marked 2.2K (Alias 2K2) Ohms, but in fact they are all 96K.
It is always a good idea to work out how much power will be used by the resistor itself. In most circuits, I use 1/8 watt resistors, but for valves, I use 1/2 watt, because the tiny resistors simply look silly, even though they would probably do the job. The Arduino uses surface mount components and the Pic Trix uses 1/4 Watt.
Very old radios seem to use a solid chunk of some resistive carbon-based material. In the 1940's and '50s, carbon composition resistors were used, consisting of a ceramic or phenolic tube with a wire at each end and some carbon powdery stuff in the middle. When you test these resistors nowadays, their value is often far away from that marked.
The cheapest resistors (excluding surface mount) are carbon film. These consist of a carbon spiral wound round a ceramic tube with wires secured to metal end-caps. Although they are fine for most circuits, they generate internal noise, which is not good for things like audio input circuits, RF stages and analog computers...
All these resistors have a fair amount of self-inductance.
Talking of which, wire-wound resistors are often used in power-supply circuits (especially valve) and may also be used for precision resistors. (less tha 1% tolerance) or where high stability is required.
Surface mount resistors seem to be made of a resistive carbon compound with metal caps bonded to each end. When the circuit board flexes (because you dropped it, maybe) one or other metal cap becomes unbonded and the thing works intermittently as you gently flex the circuit board. This is OK if its an electric shaver with two resistors on the board, but not very funny if its a complicated board with 2 or 3 hundred components sitting on it.