Again, we will have to change folders. We will create a new file for this tutorial, but let's create it in the same directory we've been working with, so type
 
Again, we will have to change folders. We will create a new file for this tutorial, but let's create it in the same directory we've been working with, so type
   −
<code><nowiki> cd contiki-2.7/examples/rime </nowiki></code>
+
::<code><nowiki> cd contiki-2.7/examples/rime </nowiki></code>
    
into the terminal. For this tutorial, we will be modifying the example-broadcast.c file we have previously used, so type  
 
into the terminal. For this tutorial, we will be modifying the example-broadcast.c file we have previously used, so type  
   −
<code><nowiki> cp example-broadcast.c example-timer.c </nowiki></code>
+
::<code><nowiki> cp example-broadcast.c example-timer.c </nowiki></code>
    
into your terminal. You should now see a new file, "example-timer.c" in your directory. Open it up with an editor of your choice (we will use gedit for this tutorial):
 
into your terminal. You should now see a new file, "example-timer.c" in your directory. Open it up with an editor of your choice (we will use gedit for this tutorial):
   −
<code><nowiki> edit example-timer.c </nowiki></code>
+
::<code><nowiki> edit example-timer.c </nowiki></code>
    
=== Step 2 ===
 
=== Step 2 ===
 
There is currently a working example of an etimer in this code, so before we proceed, let's understand this. At the beginning of the process, it is declared with
 
There is currently a working example of an etimer in this code, so before we proceed, let's understand this. At the beginning of the process, it is declared with
   −
<code><nowiki> static struct etimer et; </nowiki></code>
+
::<code><nowiki> static struct etimer et; </nowiki></code>
    
This creates an etimer instance. Within the while loop, it is set with the function
 
This creates an etimer instance. Within the while loop, it is set with the function
   −
<code><nowiki> etimer_set(&et, CLOCK_SECOND*4 + random_rand() % (CLOCK_SECOND * 4)); </nowiki></code>
+
::<code><nowiki> etimer_set(&et, CLOCK_SECOND*4 + random_rand() % (CLOCK_SECOND * 4)); </nowiki></code>
    
This function takes the arguments:  
 
This function takes the arguments:  
   −
<code><nowiki> etimer_set(struct etimer *et, clock_time_t interval); </nowiki></code>
+
::<code><nowiki> etimer_set(struct etimer *et, clock_time_t interval); </nowiki></code>
    
and sets the etimer et to expire after interval.
 
and sets the etimer et to expire after interval.
 
After that, we see the line:  
 
After that, we see the line:  
   −
<code><nowiki> PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); </nowiki></code>
+
::<code><nowiki> PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); </nowiki></code>
    
which tells the example_broadcast_process to pause until it receives an event, so the program is essentially giving up system control. When an etimer expires, it posts a PROCESS_EVENT_TIMER event to the example_broadcast_process. So this tells the process to continue and begin running again, as the etimer has expired, and an event has been posted. Now that we understand what the etimer is doing here, let's incorporate some other timers.
 
which tells the example_broadcast_process to pause until it receives an event, so the program is essentially giving up system control. When an etimer expires, it posts a PROCESS_EVENT_TIMER event to the example_broadcast_process. So this tells the process to continue and begin running again, as the etimer has expired, and an event has been posted. Now that we understand what the etimer is doing here, let's incorporate some other timers.
 
To start simply, we are going to use a timer to just print out a message once it expires. Just below
 
To start simply, we are going to use a timer to just print out a message once it expires. Just below
   −
<code><nowiki> static struct etimer et; </nowiki></code>
+
::<code><nowiki> static struct etimer et; </nowiki></code>
    
declare a timer with the line:  
 
declare a timer with the line:  
   −
<code><nowiki> static struct timer t; </nowiki></code>
+
::<code><nowiki> static struct timer t; </nowiki></code>
    
Before the while loop, set the timer with the line:  
 
Before the while loop, set the timer with the line:  
   −
<code><nowiki> timer_set(&t, CLOCK_SECOND * 10); </nowiki></code>
+
::<code><nowiki> timer_set(&t, CLOCK_SECOND * 10); </nowiki></code>
    
This sets the timer to expire after 10 seconds.
 
This sets the timer to expire after 10 seconds.
 
Below the line
 
Below the line
   −
<code><nowiki> printf("broadcast message sent\n"); </nowiki></code>
+
::<code><nowiki> printf("broadcast message sent\n"); </nowiki></code>
    
add in the code:
 
add in the code:
   −
<code><nowiki> if(timer_expired(&t)){
+
::<code><nowiki> if(timer_expired(&t)){
 
                                 printf("Timer expired\n");
 
                                 printf("Timer expired\n");
 
                             }</nowiki></code>
 
                             }</nowiki></code>
 
Now, save and run your code on your Tmote Sky by typing into your terminal:
 
Now, save and run your code on your Tmote Sky by typing into your terminal:
   −
<code><nowiki> make TARGET=sky example-timer.upload </nowiki></code>
+
::<code><nowiki> make TARGET=sky example-timer.upload </nowiki></code>
    
If you don't have a Sky, run this code on Mspsim with the line
 
If you don't have a Sky, run this code on Mspsim with the line
   −
<code><nowiki> make TARGET=sky example-timer.mspsim </nowiki></code>
+
::<code><nowiki> make TARGET=sky example-timer.mspsim </nowiki></code>
    
Among the "broadcast message sent" messages, you should see a "Timer expired" notice. This only occurs one time, however. This is because we never reset the timer. So, return to your example-timer.c file. Underneath your printf("Timer expired\n") line, add the code
 
Among the "broadcast message sent" messages, you should see a "Timer expired" notice. This only occurs one time, however. This is because we never reset the timer. So, return to your example-timer.c file. Underneath your printf("Timer expired\n") line, add the code
   −
<code><nowiki> timer_reset(&t); </nowiki></code>
+
::<code><nowiki> timer_reset(&t); </nowiki></code>
    
This will reset the timer to expire again in 10 * CLOCK_SECONDS. Run your code again. You should now see "Timer expired" every few broadcast messages. Now, say we only wanted to send broadcast messages for 30 seconds. Let's use our timer to exit our process after it expires. Change your original timer_set function to:
 
This will reset the timer to expire again in 10 * CLOCK_SECONDS. Run your code again. You should now see "Timer expired" every few broadcast messages. Now, say we only wanted to send broadcast messages for 30 seconds. Let's use our timer to exit our process after it expires. Change your original timer_set function to:
   −
<code><nowiki> timer_set(&t, CLOCK_SECOND * 30); </nowiki></code>
+
::<code><nowiki> timer_set(&t, CLOCK_SECOND * 30); </nowiki></code>
    
Now, just delete the line
 
Now, just delete the line
   −
<code><nowiki> timer_reset(&t); </nowiki></code>
+
::<code><nowiki> timer_reset(&t); </nowiki></code>
    
and replace it with
 
and replace it with
   −
<code><nowiki> PROCESS_EXIT(); </nowiki></code>
+
::<code><nowiki> PROCESS_EXIT(); </nowiki></code>
    
Run your code again, and it should stop after the timer expires. You have now learned some basic functionality of the timer.
 
Run your code again, and it should stop after the timer expires. You have now learned some basic functionality of the timer.
 
Begin by deleting the  
 
Begin by deleting the  
   −
<code><nowiki> PROCESS_EXIT(); </nowiki></code>  
+
::<code><nowiki> PROCESS_EXIT(); </nowiki></code>  
    
line that you previously wrote. We are going to implement a ctimer and no longer want to exit the process. At the beginning of the process, where you declared the other timers, include the code  
 
line that you previously wrote. We are going to implement a ctimer and no longer want to exit the process. At the beginning of the process, where you declared the other timers, include the code  
   −
<code><nowiki> static struct ctimer ct </nowiki></code>
+
::<code><nowiki> static struct ctimer ct </nowiki></code>
    
This declares a ctimer, which has the property of calling a function when it expires. In order to do this, we will need to declare a function for it to call! So, just before the start of the process, underneath the line
 
This declares a ctimer, which has the property of calling a function when it expires. In order to do this, we will need to declare a function for it to call! So, just before the start of the process, underneath the line
   −
<code><nowiki> static struct broadcast_conn broadcast; </nowiki></code>
+
::<code><nowiki> static struct broadcast_conn broadcast; </nowiki></code>
    
Declare the following function:
 
Declare the following function:
   Exception encountered, of type "Error"