Tutorial 5 : Digital Input Output driver - sudeshmoreyos/Morey_os-demo-1.0 GitHub Wiki

Home <<Prev 5 Next>>

In Morey_os Digital.h is the first driver that we are going to learn about. In order to use this driver we need to include header file :

#include "Digital.h"

Please note D is capital, while all other letters are in small letters.

Digital driver supports following functions :

1. Digital.pinmode(pin,direction);

2. Digital.write(pin,value);

3. Digital.read(pin);

1. Digital.pinmode(pin,direction);

This function is used to set the direction of a digital pin of a controller or a Board. It has two inputs i.e. pin number and pin direction. pin direction can be : OUTPUT and INPUT. Some boards or platforms may support more possibilities like AVR controllers supports INPUT_PULLUP. Please note OUTPUT, INPUT and INPUT_PULLUP are all in capital letters. By giving direction as OUTPUT, chosen pin act as output and similarly for INPUT. INPUT direction takes floating input as Tri-state while INPUT_PULLUP take floating input as HIGH. This function has no output.

Digital driver functions accept pin number by three methods/ways :

a) Universal Morey_os pin numbers which are portable across all controllers or platforms or boards, only limited by selected controller's capability. Universal Morey_os pin numbers are denoted as : P0 , P1 , P2 , P3, etc. For Arduino Uno P0 is same as pin0, P1 is same as pin1, etc.

b) Architecture specific pin numbers which are portable across all controllers supported by a selected controller architecture or controller family. Like for AVR_MEGA series, pins are named as A0-A7, B0-B7, C0-C7 and so on. For Arduino Uno D0 is same as pin0, D1 is same as pin1, up to D7 is same as pin7. Then B0 is same as pin8, up to B5 is same as Pin13. And finally C0 is same as pinA0 or pin14, up to C5 is same as pinA5 or pin19.

c) Lastly Board specific pin numbers like pin0, pin1, pin2, etc

Please note a Board supports all three methods of pin numbering while controller supports only a) and b) pin numbering methods.

2. Digital.write(pin,value);

This function is used to set value of an output pin. Before using this function, selected pin must be set as OUTPUT using Digital.pinmode function. It takes two inputs : pin number and its value. pin numbering we have already discussed before. A digital output pin can be given three possible values a) LOW or 0 b) HIGH or 1 c) TOGGLE or 2. LOW sets output low, HIGH sets output high, while TOGGLE toggles the output. Please note LOW , HIGH and TOGGLE are all in capital letters. This function has no output. This function should not be used for pins which are set as INPUT or INPUT_PULLUP by Digital.pinmode function.

3. Digital.read(pin);

This function is used to read the input status of an input pin. Before using this function, selected pin must be set as INPUT or INPUT_PULLUP using Digital.pinmode function. It takes one input as pin number and gives 1 or 0 as output. This function can also be used for pins which are set in OUTPUT direction. This function reads the current output state of the selected pin.

4. Example Code

Let us now check an example code named digital-input-output.c that can be found in example folder (examples/board-examples/arduino-uno/digital-input-output). It implements both digital input and output. The code is as follows :


#include "morey_os.h"

#include "Digital.h"

void setup(void)

{

Digital.pinmode(pin13,OUTPUT);

Digital.pinmode(pin12,OUTPUT);

Digital.pinmode(pin2,INPUT);

}

TASK_CREATE(led_blink,"led blink");

TASK_CREATE(input_test,"input test");

TASK_AUTOSTART(&led_blink, &input_test);

TASK_RUN(led_blink)

{

// Process starts here

BEGIN();

while(1)

{

Digital.write(pin13,HIGH);

    DELAY_SEC(0.5);

Digital.write(pin13,LOW);

    DELAY_SEC(0.5);           

}

// process ends here

END();

}

TASK_RUN(input_test)

{

// Process starts here

BEGIN();

while(1)

{

if(Digital.read(pin2)==1)

	Digital.write(pin12,HIGH);

else

	Digital.write(pin12,LOW);

DELAY_SEC(0.1);            

}

// process ends here

END();

}


Code Explanation :

  1. morey_os.h header file is compulsory to include in all codes. Since we are using digital driver functionality, we have added Digital.h header too.

#include "morey_os.h"

#include "Digital.h"

  1. In setup function we have declared pin13 and pin12 of Arduino Uno as output while pin2 is set as input.

void setup(void)

{

Digital.pinmode(pin13,OUTPUT);

Digital.pinmode(pin12,OUTPUT);

Digital.pinmode(pin2,INPUT);

}


  1. We have created two tasks named led_blink and input_test. Please note TASK_CREATE Macro has two inputs. First input is name of the task to be created, other input is string name of the task which is used during code debugging process. We will discuss more about code debugging in subsequent tutorials.

TASK_CREATE(led_blink,"led blink");

TASK_CREATE(input_test,"input test");

  1. Next we autostart both the tasks at startup or powerup of the board. We can optionally start these tasks manually inside some other tasks. Starting or ending tasks inside a task will be discuss in subsequent tutorials. For now we will autostart all tasks at controller/board boot time.

TASK_AUTOSTART(&led_blink, &input_test);

  1. Next we declare TASK_RUN for both the tasks. led_blink task blinks LED connected at pin13 after every 0.5 seconds. To give delay in morey_os we can use DELAY_SEC() or DELAY_SEC_PRECISE() macros. Detailed discussion of these two macros is to be done in subsequent tutorials. Also it is very important to note that to blink LED continuously we have used while(1) in our code which is an infinite loop. Morey_os is based on cooperative threads, thats why this infinite loop must have at least one DELAY_SEC() or DELAY_SEC_PRECISE() macro. To give delay between LED blinks we have used DELAY_SEC(0.5); hence this condition is satisfied.

TASK_RUN(led_blink)

{

BEGIN();

while(1)

{

Digital.write(pin13,HIGH);

DELAY_SEC(0.5);

Digital.write(pin13,LOW);

DELAY_SEC(0.5);           

}

END();

}


  1. input_check task continuously reads input from pin2 and accordingly gives high low output to pin12. Again here we are using an infinite loop using while(1). In a typical code we will not use any delay in this infinite loop. But since it is a requirement for morey_os to add at least one DELAY_SEC() or DELAY_SEC_PRECISE() macro inside an infinite loop, we have added DELAY_SEC(0.1); Ideally this delay should be as low as possible for fast response. DELAY_SEC() or DELAY_SEC_PRECISE() macros supports minimum of 1 milli-second or 0.001 second delay. However, it is recommended not to give delay less than 50 milli-second or 0.05 Seconds.

TASK_RUN(input_test)

{

BEGIN();

while(1)

{

if(Digital.read(pin2)==1)

	Digital.write(pin12,HIGH);

else

	Digital.write(pin12,LOW);


DELAY_SEC(0.1);            

}

END();

}


  1. What happens if we forget to use at least one DELAY_SEC() or DELAY_SEC_PRECISE() macro inside an infinite loop? Detailed discussions of cooperative thread implementation is done is subsequent tutorials. Let me share basic information here. In Morey_os, tasks must return their control to Morey_os kernel. Being cooperative thread implementation, OS cannot take back control on its own. Control to OS is returned back to OS by DELAY_SEC() or DELAY_SEC_PRECISE() macros. If we forgot to add it, respective task will stuck in infinite loop without returning control to OS. In that case after 2 seconds, watchdog timer is triggered and OS will restart itself. So in any code implementation, if you notice that code is automatically restarting again and again, then you might have missed adding DELAY_SEC() macros inside an infinite loop.

  2. Content of Makefile is as follows :


PROJECT = digital-input-output

MOREY_OS_PATH = ../../../..

BOARD = ARDUINO_UNO

include $(MOREY_OS_PATH)/Makefile.include


PROJECT Macro will hold name of the project file name. MOREY_OS_PATH holds the location of Morey_os root directory. BOARD Macro should hold ARDUINO_UNO since we are programming for Arduino_uno board. And last line should remain the same as mentioned above.

  1. This code is simple and requires no special configurations. Hence config.h file content will remain same as below :

#ifndef CONFIG_H

#define CONFIG_H

#define COMPILER AVR_GCC

#endif


Next we will learn about SevenSegment library in Tutorial-6.

Home <<Prev 5 Next>>