Tuesday, May 20, 2008

Character Arrays

Lesson 4.4

Characters and Character Arrays

Storing characters is slightly different from storing numbers. You may have notice through out this lesson; I have hardly shown any character arrays. But you have already used it in the first lesson of LCD output. Characters in C are individual letters, numbers and special symbols. These characters are stored using 1 byte or 8 bits using the ASCII character value. So when I store the letter ‘A’ in a variable, C stores the ASCII code value of ‘A’, which is integer 65. So, it would be perfectly valid for me to do this in C:-

result = ‘A’ + 32;

Result will now be 97 decimal, which is ‘a’ ASCII. In C individual characters are stored like this:-

char MenuOption[4] = {‘A’, ‘E’, ‘D’, ‘Q’};

Notice a single quotation mark ‘ is used.

When a collection of characters are stored in C, it is called a string and math operation like the example above cannot be preformed.

char callsign[6] = “9w2gu”;

This means, declare variable callsign of 6 elements long and initialize the variable with 9w2gu.

9w2gu is only 5 characters why did I specify 6 elements? The compiler need to know when the string terminates, it does this by adding a ‘\0’, a NUL character, at the end of the string. Also a string declaration begins and ends with double quotation mark “, and string do not require the { } for single dimensional array. So take care when declaring strings.

To declare and initialize string variables 1D character array.

char callsign[] = “9W2DTR”; // let compiler find the size

char handle[7] = ”Dexter”; // max char handle is 6 1 for ’\0’ NUL

To display the content of the string, just use the variable name.

lcd_out(1,1,callsign);

Using a for loop will display each character at a time. Ex.

.

lcd_out(1,1,callsign[pos]);

.

This is where the character array is different from numerical arrays.

if char is declared as below,

char callsign[6];

callsign = “9w2dtr”

Will only print 9w2dt or undesired results, remember you need to specify space for NUL character too.

Below a visual sample of 1D character array.



Now for some explanation on 2 and 3 dimensional character array.

They work similar to their numerical partners except the last element defines the width of the string field. Ex.

char dow[7][4] = {“Mon”, “Tue”, “Wed”, “Thu”, “Fri”, “Sat”, “Sun”);

This means, create an array of 7 rows, 4 characters each.

Below the visual display of the above declared 2D array.



To display Friday I would need to specify the row element only. Example:

lcd_out(1,1,dow[4]);

Will display Fri on the lcd.

Similarly, 3D character arrays work the same way.

3D character array are declared as shown below.

char students[3][2][7] =

{“9w2bpy”, “Yau”,

“9w2dtr”, “Dexter”,

“9m2cf”, “Chow”};

Which will look like this.

This means declare a character array called students 3 rows 2 columns which can hold 7 characters each. Always remember to allocate space for the NUL character. If I did this:-

char students[3][2][7] =

{“9w2bpy”, “Yau”,

“9w2dtr”, “Dexter”,

9m2cf”, “Uncle Chow”};

The complier will generate an error, because “Uncle Chow exceeds 7 characters.

Alternatively I could do this :-

char students[3][2][] =

{“9w2bpy”, “Yau”,

“9w2dtr”, “Dexter”,

“9m2cf”, “Uncle Chow”};

Let the compiler check for the max length of string.

lcd_out(1,1, students[1][0]); // will output 9w2dtr.

lcd_out(1,1,students[0][1]); // will output Yau.

So, important thing to remember is that character arrays is :-

Remember to allocate 1 extra character for NUL.

The last [] specifies number of characters.

All arrays, be it character or numerical, elements number (the numbers between []), can only be unsigned integer (no negative and no decimal point values).

Sunday, May 11, 2008

Answers 4

Lesson 4 Skill Check Answers


Q1

Q2a

Q2b

Q2c

3

4



These are sample code for common cathode. All code using to display or blink the dot, can be XOR with 0x80 will on or off the dot regardless of of common anode or cathode.

Saturday, May 10, 2008

Multidimensional Arrays

Lesson 4.2


2 Dimensional (2D).

By now, you should have an understanding how arrays work. The element number points to the data stored. I will briefly now explain 2D and 3D arrays. These are known as multidimensional array. You can have as many dimensional as you need, but make sure you have enough memory to store them.

Let’s say I want to collect temperature reading in degrees C, 3 times a day, at dawn, noon and dusk for 7 days. This is how I would declare my array:-

float TempC[7][3];

This will look like a small spreadsheet. 2D arrays are reference in row and column format. So TempC will have 7 rows and 3 columns as illustrated in the diagram below.






I could also do this:-


float TempC[3][7];


Which would look like:-

You can use any method as long as you take care in storing and accessing the data. It is the norm to use the first method.

No special attention is needed to initialize the array. I would do the following for easier reading.


int table[4][3] =
{1, 2, 3,
2, 4, 6,
3, 6, 9,
4, 8, 12};

It just makes it easier to understand the way the data in the array is stored. It would not be wrong to do this:-

int table[4][3] = {1, 2, 3, 2, 4, 6, 3, 6, 9, 4, 8, 12};

if I wanted to print the array on lcd:-

Lesson 4.3

3D

Now I want to record temperature 3 times a day morning, noon and dusk; for the whole year. I could declare the array as float TempC[365][3]. This way I would not know the month and date the temperature is recorded for. A better way to do this would be float TempC[12][31][3], which would look like:-

Looks confusing? Let me explain,

Each row from 0 to 11 is month which is [12];

Each alternate color column is day which is [31];

Each day column (0, 1 and 2) is time of day the temperature is recoded is [3].

To store / and retrieve data from 3D array:

You can have as many dimensions that you need, but must take care of how much memory you have available. Example if you have an array of char sample[100][100][100], that is 1,000,000 bytes. Programming on a PC is OK but not for PIC.

Therein is a brief explanation on 3D arrays. If you do not understand, do not hesitate to leave comments us. Hope you have all understood the use of arrays. Next, I will explain a different kind of array in the next topic.

Monday, May 5, 2008

ADC scaling explained...

There seems to be some confusion regarding ADC scaling requirement so here are some examples why and how you would do it...

Example No 1: Voltage to be measured is higher than 5V...
Do take note that PIC ADC has a maximum input of VDD (+5V) thus if you want to measure voltage higher than 5V, you need to do some scaling of the actual voltage before it gets into PIC. Easiest way is to use a voltage divider using resistors (for more demanding applications, an opamp-based circuit may be required).

Lets look at an example. Assuming you want to measure the automotive battery voltage. Typically, the battery voltage will be between 11V (standby) and 14V (charging). For safety reason, let's assume we design for 20V maximum input voltage (25% safety factor). To accomplish this, we'll use 4 resistors of 4.7k each... a potentiometer can also be used to set it correctly. Wire the resistors as shown below:
In the above circuit, when a 20V voltage is present at the input, input to the ADC will be 5V... a 10V input will result in 2.5V input at the ADC... thus, the input voltage has been scaled by factor of 1/4. The ratio is obtained from the voltage divider... check some references if you not sure why this is so... :-)
Voltage at PIC ADC Input = Actual Input x (R1 / (R1+R2+R3+R4))

Assuming you use VDD (5V) as the ADC+ reference, the ADC reading will be 1023 when the ADC input is 5V (actual input of 20V). So, to get the actual voltage reading, you need to calculate it as follows:

Actual Voltage = ADC Reading * Designed Maximum Voltage /1024. Putting the actual numbers in, Actual Voltage = 1023 * 20 /1024 = 19.98V. The small difference is because the 10-bit ADC maximum value is 1023 instead of 1024...

Under this scenario, the maximum resolution is 20V/1024 = 19.5mV.

I'll post another example for expanded ADC resolution later...