+ All Categories
Home > Documents > ESD_Project-Report

ESD_Project-Report

Date post: 13-Apr-2017
Category:
Upload: ahmad-faizan
View: 31 times
Download: 0 times
Share this document with a friend
20
Page 0 | 19 Project Report Submitted By: Ahmad Faizan Humayun Akhtar Submitted To: Dr. Shahzad Ahmad Butt
Transcript
Page 1: ESD_Project-Report

P a g e 0 | 19

Project Report

Submitted By:

Ahmad Faizan

Humayun Akhtar

Submitted To:

Dr. Shahzad Ahmad Butt

Page 2: ESD_Project-Report

P a g e 1 | 19

1. INTRODUCTION:

This is simple water level controller but the new thing we’ll be using is modeling this

application in a real time embedded system using RTOS (Real Time Operating System).

What this Embedded system will do is plain simple. It will constantly monitor the level of

our water tank using an “Ultrasonic Sound Sensor” (SONAR) and check the level of

water using the reelection of sound it receives back generated from the speaker.

After that it will check if the water Tank is full or not according to the readings it received

from the sensor. If the level of water is not at the specified position. It will simply actuate

the water pump using “Arduino’s ATmega328P” until it is reached to the “full” level.

All of the status is being shown on “16x2 LCD display” which will display information

like current motor status, water tank level percentage. ]

Why SONAR sensor?

We have two methods for sensing water level

a) Contact methods are resistive method, capacitive and inductive methods

(magnetostriction).

b) Contactless methods are optical method, radar and ultrasonic method. Because we

didn’t want to affect the quality of water in tank we implement one of the

contactless methods i-e ultrasonic sensor

2. Equipment:

a. Arduino Mega w/(AT mega 2560)

b. SONAR sensor HC SR04

c. 16x2 characters Alphanumeric LCD

d. Ethernet cables for extension

e. Water Tank

f. Battery Pack 5v/Charger

Page 3: ESD_Project-Report

P a g e 2 | 19

Prototype Platform:

This is a simple project and any low priced

development will be fine but we have selected to use

Arduino Mega as it has easy to use interface, powerful

processor support (ATmega2560) also it has many

built-in libraries which make programming easy.

SONAR Sensor:

The basic principle of Ultrasonic sensor is

simple, we send a signal and we measure time

that send signal needs to come back.

Ultrasonic method is similar to radar. Instead of

radar wave we are sending ultrasonic wave.

This procedure is ideal for our needs because

ultrasonic sensors are easily accessible and low

priced.

We transmit short ultrasonic pulse and we measure travel time of that pulse from

transceiver to liquid and back to transceiver. Ultrasonic pulse will bounce from liquid level

since because change of density of ultrasonic pulse travel medium (ultrasonic pulse first

travel through air and bounce of liquid with higher density than air). Because water has

higher density, majority of pulse will bounce off.

Limitations:

a. Because of pulse length there is small window that we cannot receive pulse

with transceiver because transceiver is transmitting.

Page 4: ESD_Project-Report

P a g e 3 | 19

Solution: This problem is simple to solve: we placed our sensor higher from

maximum water level for few centimeters allowing receiver to start

receiving.

b. Because of the beam width we are limited with tank diameter. If tank

diameter is too small, signal could bounce of tank’s walls and could cause

false readings.

Solution:

By using a tank whose diameter is reasonably large we can avoid this

problem

3. RTOS (Real-Time Operating System):

There are many compatible RTOS’s for Atmel’s AVR microprocessors like FreeRTOS,

RTuinOS, ChibiOS/RT, etc. But I have chosen ChibiOS as it is free to use under GPL

license. ChibiOS/Nil is designed for embedded applications on 8, 16 and 32 bit

microcontrollers; size and execution efficiency are the main project goals. It’s very easy to

use and scalable as compared to FreeRTOS.

ChibiOS/Nil Features:

NIL has been created with the idea to bring RTOS functionalities to very small devices and

yet to be a full-fledged RTOS.

In Brief

Tiny RTOS, below 1kB of code space in its maximum configuration.

Small size of memory objects like Thread, Semaphores etc.

Focus on memory size, the target is to keep it below 1kB in its maximum

configuration. Common objects must take the minimal amount of RAM.

Scalable from 8 bits architectures upward.

Upward compatible with RT.

Reasonable API. Common features must be supported, it has to be an usable

RTOS not just minimal.

Fully Static Architecture.

Static tasks table, all tasks are declared statically.

Clean and elegant code base.

Page 5: ESD_Project-Report

P a g e 4 | 19

Predictable and Deterministic.

Fully compliant with HAL OSAL.

MISRA 2012 compliance.

Fully static architecture.

4. Detailed Algorithm Explained:

Basically we’ll model this real time problem into 4

tasks as following:

a) Task 1:

In Thread 1 we’re configuring Sonar sensor for

measuring distances and once the Distance is measure

then it will compare it will hardcoded values for

different levels of water if it detect tank is not full it will signal a Binary Semaphore using

Wait and Signal Synchronization. Otherwise it will only signal it for LCD display without

changing output of motor.

1. First we Configure Sonar sensor Trigger and Echo pins on our uC.

2. Next in a while loop configuration and measuring the distance method starts.

3. Trig pin is set to high for 10 microseconds.

4. Pulse in function is used.

5. Pulse in function give us the duration from when the function called and specific

value being set on the pin we pass through the function.

6. Distance is measure in centimeters according to the formula given in Datasheet

7. On the value of distance decision is made if the distance is equal to 7cm or less

then 7cm then the Water pump is turned on.

8. If the distance is has increased to a certain threshold then the Motor is turned on

to fill the Tank.

ChibiOs/Nil

Page 6: ESD_Project-Report

P a g e 5 | 19

Figure 1: Figure showing How Ultrasonic Waves propagate and reflect back after hitting

any object in its path

b) Task 2:

Basic Purpose of this Task is to show the Led Status and Turn on the Realy if the

Semaphore is available released in second task if the certain distance thresholds are met.

1. It first set out pin mods.

2. Then if the Semaphore is available it simply acquires it and turn on the Relay which

drives the motor and Status Led’s.

3. After that it release semaphore for Display to show the status of Water Tank in cm.

c) Task 3:

Basic Purpose of this task is to control the Display mechanism it will show distance in

cm.It will try the semaphore and check if it is available or not, if it’s available then it will

acquire it and show the level of water tank by displaying it on LCD display

Page 7: ESD_Project-Report

P a g e 6 | 19

START

READ VALUE

FROM SONAR

SENSOR

CONVERT THE

PULSE TO DISTANCE

& COMPARE IT TO

PREDEFINED

LEVELS

Is The Value

Greater Than

Threshold Level?

Actuate The

Motor And

Release

Semaphore

Acquire

Semaphore

And Update

The Display On

LCD

END

NO

Yes

Basic Flow Diagram Of RTOS Based Water Level Indicator

Figure 2: Block Diagram of Complete Project Algorithm Flow

Page 8: ESD_Project-Report

P a g e 7 | 19

4. Schematics

Page 9: ESD_Project-Report

P a g e 8 | 19

5. Hardware implementation:

6. Arduino Code: #include <avr_heap.h>

#include <nil.h>

#include <nilconf.h>

#include <nilcore.h>

#include <NilFIFO.h>

#include <NilRTOS.h>

#include <NilSerial.h>

#include <niltypes.h>

#include <LiquidCrystal.h>

Page 10: ESD_Project-Report

P a g e 9 | 19

/*

* Example to demonstrate thread definition, semaphores, and thread sleep.

*/

// Declare a semaphore with an inital counter value of zero.

SEMAPHORE_DECL(semOn, 0);

//SEMAPHORE_DECL(semOff, 0);

SEMAPHORE_DECL(semDisplay, 0);

//------------------------------------------------------------------------------

/*

HC-SR04 Ping distance sensor:

VCC to arduino 5v

GND to arduino GND

Echo to Arduino pin 9

Trig to Arduino pin 8*/

#define echopin 9 // echo pin

#define trigpin 8 // Trigger pin

LiquidCrystal lcd1(12,10, 5, 4, 3, 2);

Page 11: ESD_Project-Report

P a g e 10 | 19

long duration, distance;

//------------------------------------------------------------------------------

/*

* Thread 1, turn the LED off when signalled by thread 2.

*/

// Declare a stack with 128 bytes beyond context switch and interrupt needs.

NIL_WORKING_AREA(waThread1, 128);

int change=0;

int newd=0;

// Declare the thread function for thread 1.

NIL_THREAD(Thread1, arg) {

pinMode (trigpin, OUTPUT);

pinMode (echopin, INPUT );

while (TRUE) {

digitalWrite(trigpin,LOW);

delayMicroseconds(2);

digitalWrite(trigpin,HIGH);

delayMicroseconds(10);

duration=pulseIn (echopin,HIGH);

distance= duration/58.2;

Page 12: ESD_Project-Report

P a g e 11 | 19

distance+=1;

if (distance >= 12 )

{

if(newd-distance<=1)

{

nilSemSignal(&semOn);//signal semaphore to turn the relay on

}

}

else if (distance <=7)

{

digitalWrite (53,LOW);

digitalWrite (51,LOW);

if(newd-distance<=1)

{

nilSemSignal(&semDisplay);

}

}

nilThdSleepMilliseconds(50);

newd=distance;

}

}

//------------------------------------------------------------------------------

/*

* Thread 2, turn the LED on and signal thread 1 to turn the LED off.

*/

Page 13: ESD_Project-Report

P a g e 12 | 19

// Declare a stack with 128 bytes beyond context switch and interrupt needs.

NIL_WORKING_AREA(waThread2, 128);

// Declare the thread function for thread 2.

NIL_THREAD(Thread2, arg) {

pinMode (53, OUTPUT);//relay

pinMode (51,OUTPUT);//led status

while (TRUE) {

//nilThdSleepMilliseconds(50);

nilSemWait(&semOn);

digitalWrite (53,HIGH);

digitalWrite (51,HIGH);

nilSemReset(&semOn,0);

nilSemSignal(&semDisplay);

}

}

//------------------------------------------------------------------------------

//Thread 3,

// Declare a stack with 128 bytes beyond context switch and interrupt needs.

NIL_WORKING_AREA(waThread3, 128);

// Declare the thread function for thread 2.

long count=0;

NIL_THREAD(Thread3, arg) {

while (TRUE) {

Page 14: ESD_Project-Report

P a g e 13 | 19

//nilThdSleepMilliseconds(50);

// if(nilSemGetCounterI(&semDisplay)==1)

//{

//lcd1.clear();

nilSemWait(&semDisplay);

count=0;

lcd1.setCursor(0,0);

lcd1.print("---*********---");

lcd1.setCursor(0,1);

lcd1.print("Distance: ");

lcd1.print(distance);

//lcd1.setCursor(14,1);

lcd1.print(" cm");

/*if(millis()-count>1000)

{

lcd1.clear();

count=millis();

}

nilSemReset(&semDisplay,0);*/

nilThdSleepMilliseconds(200);

lcd1.clear();

//}

}

}

//------------------------------------------------------------------------------

/*

Page 15: ESD_Project-Report

P a g e 14 | 19

* Threads static table, one entry per thread. A thread's priority is

* determined by its position in the table with highest priority first.

*

* These threads start with a null argument. A thread's name may also

* be null to save RAM since the name is currently not used.

*/

NIL_THREADS_TABLE_BEGIN()

NIL_THREADS_TABLE_ENTRY("thread2", Thread2, NULL, waThread2, sizeof(waThread2))//Relay

on-off

NIL_THREADS_TABLE_ENTRY("thread1", Thread1, NULL, waThread1, sizeof(waThread1))//read

sonar

NIL_THREADS_TABLE_ENTRY("thread3", Thread3, NULL, waThread3, sizeof(waThread3))//lcd1

display

NIL_THREADS_TABLE_END()

//------------------------------------------------------------------------------

void setup() {

//-------

lcd1.begin(16,2);

lcd1.clear();

lcd1.setCursor(0,0);

lcd1.print("RTOS based Water Level Indicator...");

lcd1.setCursor(0,1);

lcd1.print(" Ahmad Faizan :)");

for (int positionCounter = 0; positionCounter <20; positionCounter++) {

// scroll one position left:

lcd1.scrollDisplayLeft();

// wait a bit:

delay(150);

Page 16: ESD_Project-Report

P a g e 15 | 19

}

// scroll 29 positions (string length + display length) to the right

// to move it offscreen right:

for (int positionCounter = 0; positionCounter < 22; positionCounter++) {

// scroll one position right:

lcd1.scrollDisplayRight();

// wait a bit:

delay(150);

}

lcd1.clear();

//---------------

// Start Nil RTOS.

nilSysBegin();

}

//------------------------------------------------------------------------------

// Loop is the idle thread. The idle thread must not invoke any

// kernel primitive able to change its state to not runnable.

void loop() {

// Not used.

}

7. PORTING NilRTOS on Arduino

Page 17: ESD_Project-Report

P a g e 16 | 19

Guide for porting NilRTOS: 1. Download NilRTOS (library version) from the following link:

https://github.com/greiman/NilRTOS-Arduino

2. After that extract the zip file named as NilRTOS-Arduino-master.zip and double click

on library.

3. Copy all the files in it.

4. Paste in the library path of your Arduino IDE in the following path:

C:\Program Files (x86)\Arduino\libraries

Page 18: ESD_Project-Report

P a g e 17 | 19

5. Now open up your Arduino IDE, select Sketch =>Include Library=>NilRTOS

Click on NilRTOS library.

6. Congratulation! You just ported NilRTOS on your Arduino IDE.

For API documentation, double click on NilRTOS.html found in NilRTOS-Arduino-

master.zip file.

Page 19: ESD_Project-Report

P a g e 18 | 19

Test Code:

/*

* Example to demonstrate thread definition, semaphores, and thread sleep.

*/

#include <NilRTOS.h>

// The LED is attached to pin 13 on Arduino.

const uint8_t LED_PIN = 13;

// Declare a semaphore with an inital counter value of zero.

SEMAPHORE_DECL(sem, 0);

//------------------------------------------------------------------------------

/*

* Thread 1, turn the LED off when signalled by thread 2.

*/

// Declare a stack with 128 bytes beyond context switch and interrupt needs.

NIL_WORKING_AREA(waThread1, 128);

// Declare the thread function for thread 1.

NIL_THREAD(Thread1, arg) {

while (TRUE) {

// Wait for signal from thread 2.

nilSemWait(&sem);

// Turn LED off.

digitalWrite(LED_PIN, LOW);

}

}

//------------------------------------------------------------------------------

/*

* Thread 2, turn the LED on and signal thread 1 to turn the LED off.

*/

// Declare a stack with 128 bytes beyond context switch and interrupt needs.

NIL_WORKING_AREA(waThread2, 128);

// Declare the thread function for thread 2.

NIL_THREAD(Thread2, arg) {

pinMode(LED_PIN, OUTPUT);

while (TRUE) {

Page 20: ESD_Project-Report

P a g e 19 | 19

// Turn LED on.

digitalWrite(LED_PIN, HIGH);

// Sleep for 200 milliseconds.

nilThdSleepMilliseconds(200);

// Signal thread 1 to turn LED off.

nilSemSignal(&sem);

// Sleep for 200 milliseconds.

nilThdSleepMilliseconds(200);

}

}

//------------------------------------------------------------------------------

/*

* Threads static table, one entry per thread. A thread's priority is

* determined by its position in the table with highest priority first.

*

* These threads start with a null argument. A thread's name may also

* be null to save RAM since the name is currently not used.

*/

NIL_THREADS_TABLE_BEGIN()

NIL_THREADS_TABLE_ENTRY("thread1", Thread1, NULL, waThread1,

sizeof(waThread1))

NIL_THREADS_TABLE_ENTRY("thread2", Thread2, NULL, waThread2,

sizeof(waThread2))

NIL_THREADS_TABLE_END()

//------------------------------------------------------------------------------

void setup() {

// Start Nil RTOS.

nilSysBegin();

}

//------------------------------------------------------------------------------

// Loop is the idle thread. The idle thread must not invoke any

// kernel primitive able to change its state to not runnable.

void loop() {

// Not used.

} 7. References:

http://www.chibios.org/dokuwiki/doku.php?id=chibios:product:nil:start

https://github.com/greiman/NilRTOS-Arduino

https://www.arduino.cc/en/Main/Software


Recommended