A C-language tutorial for the 8-core Propeller microcontroller. It features the Propeller Activity Board [1]but other Propeller boards will work.
This tutorial will show you how to write simple programs in Propeller C, using the SimpleIDE software. You will compile your code and load it into the Propeller microcontroller, then see the results.
Along the way, you will write programs that use variables, do math, count loops, make decisions, and store information. You will also learn how to add Simple Libraries — useful pre-written code — to your project.
When you are done, you will be able write simple C programs that do all of the things mentioned above. And, you will be able to add Simple Libraries to your projects.
Next, you can dive into any of these three tutorials:
Just follow the links below to get started.
This C program will make the Propeller microcontroller send a "Hello!!!" message to the SimpleIDE Terminal on your computer.
When SimpleIDE opens the project, it will open Hello Message.c into its text editor pane.
A single "Hello!!!" message should appear in the Simple IDE Terminal.
The first thing this program does is delay for one second with pause(1000). This pause makes sure your computer and the SimpleIDE Terminal are ready to receive messages. Then, printf("Hello!!!") makes the Propeller chip send its message to your computer through its programming port. SimpleIDE Terminal displays the message on your computer screen.
Both pause(1000) and printf("Hello!!!") are followed by a semicolon ;. The semicolon is what tells the PropGCC compiler that it has reached the end of an instruction statement.
The pause and printf statements are inside curly braces {} below main(), and so we call them part of the main function’s code block. A C program always starts with the first statement in the main function, That is why pause(1000) was the first statement the program executed.
Pause and printf are also functions, but they are stored in other files called library files. Later on, you’ll get to search for libraries that contain usful functions to add to your own projects. For now, just keep in mind that your program needs #include "simpletools.h" because it has information about pause, printf, and many other useful functions.
The program has two statements: pause(1000); and printf("Hello!!!"); Let’s save this project under a new name, and add a third statement.
C is case-sensitive — You have to use the correct capitalization when programming in C. If you make an error, such as typing PrintF for example, SimpleIDE will let you know:
newline — \n is called the newline character, and it is an example of a control character used for positioning a cursor in a serial terminal.
Comments are notes about your code that help explain it to other people that have to work with it. Also, it is good to leave comments as notes to yourself about what you were doing in case you need a reminder days (or months or years) later.
If you want to comment all or part of a single line, use two forward slashes //. Everything to the right of // will be ignored by the C compiler. Block comments can span multiple lines. They start with /* and end with */, and everything in between will be ignored by the C compiler.
Variables are named sections of memory that make it possible for your program to “remember” values. Your program can also use them in math expressions to perform calculations.
This example program, Variables and Calculations.c, declares variables named a, b, and c. It stores 25 in a, 17 in b, and the result of a + b in the variable named c.
/* Variables and Calculations.c Add two integer values together and display the result. */ #include "simpletools.h" // Include simpletools header int main() // main function { pause(1000); // Wait 1 s for host computer int a = 25; // Initialize a variable to 25 int b = 17; // Initialize b variable to 17 int c = a + b; // Initialize c variable to a + b printf("c = %d ", c); // Display decimal value of c }
Variables and Calculations.c declares an integer value named a and assigns it the value 25 with int a = 25. Then, It declares a second variable named b and initializes it to 17 with int b = 17. The last integer variable it declares is named c, and stores the result of a + b in it.
Finally, it displays the value of c with printf("c = %d", c). This variation on printf displays a sequence of characters called a string, followed by a variable. The %d is called a format placeholder, and it tells printf how to display the value stored in that variable as a decimal number, 42 in this case.
The term + is a binary operator, meaning that it performs an operation on two inputs. Examples of binary operators include:
+ Add
– Subtract
* Multiply
/ Divide
% Modulus (remainder of a division calculation)
Here is a modified version of the main routine that displays "a = , b = "with their values, and then "a + b = " and the value of c on a new line. Then, it repeats for a – b.
Notice that the second time it calculates the value of c, we don’t need to declare it with int. It’s just c = a – b. Notice also that printf allows you to display more than one numeric value within your string. All it takes is two format placeholders in the string and two values, separated by commas, after the string.
PRO TIP: Displaying % with printf
To display the output of the Modulus operator, use ("a mod b = ...") or ("a %% b = ...) in the printf function. Since % has another purpose in printf strings, just saying ("a % b = ...) will give unexpected results.
So far, these lessons have processed integers values, which encompass negative and positive counting values. C language also handles floating point values, which allow you to process numbers with a decimal point and one or more digits to the right, much as a calculator does. Since the number of digits to the left or right of the decimal point is flexible, the decimal point's position can “float” from one position to another as needed.
Any time you need to work with floating point decimal values in your project, you set SimpleIDE to prepare for that.
This will make SimpleIDE add the math library to your project. simpletools.h already has a #include for the math library, so you will not need to add it to your program.
/* Floating Point Calculations.c Calculate and display circumference of a circle of radius = 1.0. */ #include "simpletools.h" // Include simpletools header int main() // Main function { pause(1000); // Wait 1 s for host computer float r = 1.0; // Set radius to 1.0 float c = 2.0 * PI * r; // Calculate circumference printf("circumference = %f \n", c); // Display circumference }
This program knows that PI ≈ 3.1415926... because it is defined in the simpletools library. Inside the main function, a floating point variable named r is initialized to 1.0 with float r = 1.0.
After that, the circumference is calculated with c = 2.0 * PI * r.
Then, printf("circumference = %f \n", c) displays the floating point value stored in c. Notice the new format placeholder: %f for a floating point value.
You can declare different variable types that can store different sizes and types of numbers.
signed char -127 to 127
char 0 to 255
int -2,147,483,647 to 2,147,483,647
unsigned int 0...4,294,967,295
long Same as int
unsigned long Same as unsigned int
float Approx: 3.4×10-38 to 3.4×1038 with 6 digits of precision
Let’s try calculating the area of a circle with a = π×r2, which is PI * r * r.
A variable array is a group of variables stored under the same name but with different index values. In the array declaration and initialization example below, you can think of the index value as the position of a specific variable in the list.
int p[] = {1, 2, 3, 5, 7, 11};
Each array element has a name (which is p in this example, the same as the array name) and an index (between brackets) that makes it possible to select an element.
This declaration sets aside six variables, each storing a prime number. This array has been initialized so that the p[0] array element stores 1. Likewise, the p[1] element stores 2. It continues for the rest of the array elements: p[2] stores 3, p[3] stores 5, p[4] stores 7, and p[5] stores 11.
/* Array Variables.c Declare and initialize an array and display a couple of its elements. */ #include "simpletools.h" // Include simple tools main() // Main function { int p[] = {1, 2, 3, 5, 7, 11}; // Initialize the array pause(1000); // Wait 1 s for host printf("p[0] = %d\n", p[0]); // Display what p[0] stores printf("p[3] = %d\n", p[3]); // display what p[3] stores }
int p[] = {1, 2, 3, 5, 7, 11} initializes an array named p with a list of numbers between braces { }. Keep in mind that p[0] stores 1, p[1] stores 2, p[2] stores 3, p[3] stores 5, and so on. So, printf("p[0] = %d\n", p[0]) displays the contents of p[0], which is 1. Likewise, printf("p[3] = %d\n", p[3]) displays the contents of p[3], which is 5.
Here is an example that shows how the value of an array element can be reassigned. Take a look at the second to last statement in the main function. It’s p[3] = 101. After that, printf("p[3] = %d\n", p[3]) will allow you to verify that the new value p[3] stores is 101.
A common program decision is what to do with an output, such as a light, speaker or motor, based on one or more inputs, such as measurements from sensors.
Next, we will look at some example programs that make decisions based on the values stored by certain variables. After you are through with this primer and into programs for simple circuits, you will see many examples of decisions based on sensor inputs.
This example program initializes and then displays the values of variables named a and b. After that, it checks if a is larger than b, and if so, it prints a message saying so.
/* Make a Decision.c If a condition is true, display a second message. */ #include "simpletools.h" // Include simpletools header main() // Main function { pause(1000); // Wait 1 s for computer connection int a = 25; // Initialize a variable to 25 int b = 17; // Initialize b variable to 17 printf("a = %d, b = %d\n", a, b); // Print all if(a > b) // If a > b condition is true { printf("a is larger \n"); // ...then print this message } }
After the pause, the program initializes a to 25 and b to 17 and displays both those values in the SimpleIDE Terminal. Then, it uses if(a > b) to decide whether to execute the contents of a code block, which contains the printf("a is larger \n") statement. If a is greater than b, it will print the second message. If it’s equal to or less than b, it will not print the message.
The > symbol is called a relational operator. Here is a list of relational operators and their meanings:
== Equal to != Not equal to > Greater than >= Greater than or equal to < Less than <= Less than or equal to
In C language, the expression a > b returns 0 if its false (a is not really greater than b) or 1 if it’s true (a is greater than b). So, in if(a > b){...}, the block of code inside the braces gets executed when a > b evaluates to 1, as in if(1) {...}. The code block does not get executed if a > b returns 0, as in if(0){...}.
Comparisons with negative numbers can be interesting.
Make a Decision [7] introduced the if statement, where a code block gets executed if its if statement is true. If a program has multiple if statements that are true, more than one code block might get executed. But sometimes, you might only want one code block to execute based on a list of conditions.
For example, let’s say we want one message when a is greater than b, a different message when a is less than b, and a third message if a is equal to b.
Another example you might see later is a robot with two contact sensors. It needs to back up and turn in different directions depending on whether both sensors are pressed, or just the left, or just the right.
/* Decision Chain.c Check a series of conditions, but only act on the first one that's true. */ #include "simpletools.h" // Include simpletools header main() // Main function { pause(1000); // Wait 1 s for computer connection int a = 25; // Initialize a variable to 25 int b = 17; // Initialize b variable to 17 printf("a = %d, b = %d\n", a, b); // Print all if(a > b) // If a > b condition is true { printf("a is larger \n"); // Then print this message } else if (a < b) // a > b not true? check a < b { printf("b is larger \n"); // If true, print this instead } else // Nothing else true? { printf("a equals b"); // Print this } }
The if...else if...else statement first checks if a is greater than b with if(a > b). If it is, then the printf("a is larger \n") gets executed. An important point here is that it skips checking any of the other conditions in the statement and moves on to whatever code might be below the else{...} block. Now, if a is not greater than b, it does not execute printf("a is larger \n") and instead moves on to check the next condition: if a is less than b with if(a < b){...}. If that’s true, it’ll print that message instead. If that’s not true either, the code will move on to the else condition, which is an optional catch-all if nothing else is true.
There are two else if conditions in the if...else if...else block below . The first one checks for a special condition, which is when b has reached or exceeded 1000. In this case, the program just displays a warning message. However in other applications such as a robot or factory equipment, if might have lots more code for remedying that special condition. Now, if b is greater than a, but it’s not equal to 1000, the code just displays the standard message.
Your programs will often need to decide what to do based on if one condition AND another condition are true. Another thing your code might need to check for is if one condition OR another condition is true. Decide on Multiple Conditions.c decides if one condition AND another condition are true using the && operator.
/* Decide on Multiple Conditions.c Make a decision based on two conditions. */ #include "simpletools.h" // Include simple tools main() // Main function { pause(1000); // Wait 1 s for computer connection int a = 100; // Initialize a variable to 25 int b = 17; // Initialize b variable to 17 printf("a = %d, b = %d\n", a, b); // Print all if((a > b) && (a == 100)) // If a > b AND A == 100 { printf("a is larger than b,\n"); // Then print this message printf("AND a is 100!\n"); // Then print this message } }
The statement if((a > b) && (a == 100){...} translates to “if a is greater than b AND a is equal to 100 then, do what’s in the braces.”
The && operator is called a logical operator. Your logical operator options are:
&& Checks for if one condition AND another condition || Checks if one condition OR another condition are true ! Inverts the result from true to false (1 to 0) or vice-versa
By now, you can probably tell that both conditions have to be true for the AND logical operator to evaluate to true (so that it will execute its code block). For one condition OR another to evaluate to true, either one or both conditions can be true.
Sometimes we need to be able to program our Propeller to repeat certain operations. This is useful for simple things, such as blinking a light, and more complex tasks, such as robotic sensor navigation.
Blocks of repeating code are called loops. The C while loop can be set up to repeat a code block while some condition is true. A while loop can also be set up to repeat endlessly, but there is a trick for escaping endless loops as well. Let's try all of these.
/* Repeat While.c Keep displaying n = n + 5 every half second while n < 200. */ #include <stdio.h> // Include standard I/O header #include "stamp.h" // Include stamp functions main() // Main function { int n = 0; // Declare n, initialize to zero while(n < 200) // Repeat while n less than 200 { pause(500); // 0.5 s between repetitions n = n + 5; // Add 5 to n each time through printf("n = %d\n", n); // Display name & value of n } printf("All done!"); // Display all done }
Inside main, a variable n is declared and initialized to zero. Then, while (n < 200) starts a loop that will keep repeating the code block below it as long as (n < 200) is true.
Each time through the loop, n = n +5 increases the value of n and then a printf displays the new value in the SimpleIDE terminal.
Eventually, n = 200 so (n < 200) is no longer true. At that point, the code execution skips to the first instruction below the while loop's code block. In this case, it's printf("All done!");.
Keep in mind that conditions like a < b and n < 200 evaluate to 1 if they are true or 0 if they are false. Like if statements, while statements execute their code block when the condition is 1, or really any value other than zero.
Think about the Did You Know section for a minute. Can you guess how to make a while loop repeat forever? If you change while(n < 200) to while(1), you’ll have an endless loop.
Even an endless loop doesn’t have to be endless thanks to the C language’s break keyword.
What do you think would happen if you move the break statement to just above printf inside the while loop's code block?
A for loop repeats a block of code, but it’s more configurable than a while loop. A for loop is also the preferred tool for counting tasks. while loops are better for repeating something “while” a condition is true. In contrast, for loops are better for repeating a block a certain number of times. This next program counts to ten with a for loop.
/* Count to Ten.c Count to ten in SimpleIDE Terminal. */ #include "simpletools.h" // Include simple tools main() // Main function { for(int n = 1; n <= 10; n++) // Count to ten { pause(500); // 0.5 s between reps printf("n = %d\n", n); // Display name & value of n } printf("All done!"); // Display all done }
The for statement has three parameters: for(start index; condition; increment).
In the Count to Ten program, the start index is int n = 1, a variable declaration that initializes the variable n to the value 1. The condition is n <= 10, which means that the loop will keep repeating while n is less than or equal to ten. The increment is n++, which is a shorthand form of n = n + 1. So with each repetition of the for loop’s code block, the value of n increases by 1.
Increment operators — The ++ operator is called an increment operator. Although increment and decrement operators are especially useful in for loops, they can be used as shortcuts in many parts of your programs.
++ add 1 to a variable –– subtract 1 from a variable
Assignment operators — There are also some useful shortcuts for assigning values to variables. For example, instead of n = n + 5, you can use n += 5. As you might expect there are, shortcuts for subtraction –=, multiplication *=, division /=, and modulus (remainder) %=. These are called the assignment forms of the operators.
Here is a for loop that will count to 200 in steps of 5, just like the while loop you experimented with earlier.
A great use of for loops is performing operations on elements in an array variable. The for loop can increment through the array's index values to access each element of the array in succesion. (See the Array Variables [8] lesson for a refresher.)
/* Index Array Variables.c Use a for loop to display all the elements in an array. */ #include "simpletools.h" // Include simple tools main() // Main function { int p[] = {1, 2, 3, 5, 7, 11}; // Initialize the array for(int i = 0; i < 6; i++) // Count i from 0 to 5 { pause(500); // 1/2 second pause printf("p[%d] = %d\n", i, p[i]); // Display array element & value } }
First, the main routine sets up an integer array named p with six elements.
Next comes a for loop with a start index of int i = 0, a condition of i < 6, and an increment of i++.
Now, take a close look at the printf statement in the for loop's code block. It prints two items each time through the loop: the value of the i variable displayed as a p index, and the value the element in the p array that has an index equal to i.
So, the first time through the for loop, printf("p[%d] = %d\n", i, p[i]) becomes printf("p[%d] = %d\n", 0, p[0]). That prints "p[0] = 1" in the SimpleIDE Terminal.
The second time through the loop, i++ increments the value of i, so the printf statement becomes printf("p[%d] = %d\n", 1, p[1]).
The for loop continues to count up through 5, displaying all the array's elements, ending with "p[5] = 11".
sizeof — C has a unary operator called sizeof that returns the number of bytes consumed by an object in memory, such as an array.
In the example program above, we knew our array had 5 elements, so we used i < 6 as the for loop's condition to access all of the elements in the p array. But what if we didn't know how many elements were in the p array? Here's a for loop that would work:
for(int i = 0; i < sizeof(p)/sizeof(int); i++)
Here, sizeof(p) gets the total number of bytes in the array. sizeof(int) gets the number of bytes used by one int element in the array. So, sizeof(p)/sizeof(int) equals the number of elements in the array.
Links:
[1] http://learn.parallax.com/node/653
[2] http://learn.parallax.com/propeller-c-set-simpleide
[3] http://learn.parallax.com/node/658
[4] http://learn.parallax.com/propeller-c-functions
[5] http://learn.parallax.com/propeller-c-simple-circuits
[6] http://learn.parallax.com/node/639
[7] http://learn.parallax.com/propeller-c-start-simple/make-decision
[8] http://learn.parallax.com/node/620