Rapport - Digitala projekt 5p




Khalil Khalil:              
e02kk@student.lth.se <mailto:e02kk@student.lth.se>

Anastasios Daniilidis: 
d04ad@student.lth.se <mailto:d04ad@student.lth.se>

Grupp 18

Date: 27/02/2007


Department of Information Technology
Lund Institute of Technology
Lund University





Abstract

The aim of this project is to develop a control system for an elevator. The application should satisfy the requirements, which is to move the elevator up or down depending on if somebody called the elevator or if a person in the elevator presses any button. The display shows the actual floor and the buttons inside and outside the elevator are active when pressed.





1. Inledning4
1.1 Bakgrund4
1.2 Mål4
1.3 Rapportens disposition4
2. Hårdvara5
2.1 kretsen5
2.1.1 Processorn5
3 Mjukvara5
4 Konstruktion och genomförande5
5 Utvärderande diskussion6
6 Referenser6
1. Inledning
1.1 Bakgrund
Syftet med kursen Digitala Projekt är att ge eleverna en uppfattning och bild om hur utvecklingsarbete inom arbetslivet fungerar. Gruppen fick välja en konstruktionsuppgift som sedan skulle konstrueras, byggas och testas. Resultatet blev en fungerande hiss som uppfyllde nämnda kraven.



1.2 Mål
Ambitionen är att Hissen skulle kunna styras med kretskortet som byggdes samt av programvaran. De digitala signalerna från knapparna förs in i kretsen och därmed läses av programvaran och beroende på händelsen motsvarande uppgifter äger rum.
Kraven:
·Hissen ska kunna röra sig beroende på knapptryckning
·Displayen skall vissa var hissen befinner sig
·Lysdioderna skall lysa om någon knapp trycks ner
·Nöd knapparna skall stoppa hissen



1.3 Rapportens disposition
Först beskriver vi hårdvaran vi har använt och sedan mjukvaran. Efter det beskriver vi det praktiska genomförandet för att sedan avsluta med resultat och slutsats.

2. Hårdvara

Det kopplades på en kopplingsbräda en processor, en buffer och 10st 74HC373 som tar in signalerna från hissens krets till processorn för styrning. Kopplingen bifogas som bilaga.

2.1 kretsen
·AVR Mega 16
·10 st. 74HC373
·1 st. 74HC245
·6 kondensatorer

2.1.1 Processorn
Det användes en AVR ATmega16 som processor för  projektet. Det är en 8-bitars mikrokontroller med RISC-arkitektur och en klocka på upp till 8 MHz. Den har 1 kb internt SRAM samt 16 kb Self-Programmable Flash. AVR ATmega16 är inte enbart en processor utan en mikrokontroller dvs. en komplett dator som fungerar självständigt utan behov av påbyggnader. Processorn har 40 pinnar varav 32 kan användas för in- och utmatning av data. Den har även inbyggd timer och 10-bitars AD-omvandlare. Till Hissen användes en 16-bitars timer. Timern ställdes in så att den fungerade på 0,001ms vilket sätter igång interrupt funktioner.
.

2.1.2 74HC373
Octal 3-State NonInverting D-Latch. Användes för in- och utmatning av signaller.

2.1.3 74HC245 Buffret. Användes för att styra riktningen på bussen.


3 Mjukvara
Programmet som styr hissen använde en interruptvektor som kontrollerade om någon tryckte på någon knapp, varje 0,001 sekund. Programmet modifierades för att exekvera motsvarande funktioner varje 0,1 sekund. Programmet medföljer som bilaga.

4 Konstruktion och genomförande

Konstruktionen består av en krets som kopplas till hissen för att ta emot signaler samt utföra operationer till densamma.
För att börja projektet, var det bra att utföra en beskrivning på blockschemat samt en kravspecifikation  för att veta vilka funktioner som ska utföras.
Blockschemat ritades med PowerLogic (se fig.) Syftet med schemat var att göra kopplingen av kretskortet enklare då man kopplar sladdar med komponenterna.

Komponenthållare blev det först som monterades på kretsen och sen kopplades sladdarna enligt blockschemat. Sedan kopplades hissens krets till våran.
Processorn monterades samt en 74HC373 in/ut enhet för att testa kopplingen och vi skrev ett litet test program på AVR studio som är interface till processorn.
Hissen reagerade på commandon som betyder att kopplingen var rätt kopplad.
Nästa steg var att montera resten av komponenterna och några kondensatorer för att ta bort störningar. En kondensator skulle ligga mellan två av ut/in- enheter och jord .
Grunden i den färdiga konstruktionen utgörs av en AVR ATmega16-processor. Till denna finns kopplad i första hand alla in/ut- enheter.

Alla enheterna i konstruktionen är avsedda för en matningsspänning på 5.0 V.
I fortsättningen skrevs mjukvaran som skulle läggas i processorn. Mjukvaran är skrivet i C. Det användes Atmel’s AVR Studio 4 som med hjälp av JTAG laddar programmet till processorn. 




5 Utvärderande diskussion

Medan mjukvaran skrevs på datorn, upptäcktes att sättet man kopplar in- och utsignaler spelar stor roll  för programmets skrivande. Det underlättar om man kopplar vissa enheter separata, t.ex. om givarna från höger hissen kopplas på en chip och givarna från den vänstra på en annan. Dock betyder detta flera integrerande enheter men med tanke på antal signaler och sättet de kan programmeras så är det värt att genomföra kopplingen på detta sätt. Projektet kan anses som en svår programmeringsuppgift  eftersom det finns moment där man måste tillbringa tid att komma på lösningar, algoritmer, för att båda hissarna skall fungera samtidigt.     


6 Referenser

Informationsbank
<http://www.it.lth.se/digp/information.asp>, 2006-05-15 BILAGA A

Programmet i C

/*
* Software to elevator project. Definitions to comments: TK(tryckknappar), HH(hisshall), H(hiss), GIV(givare)
* LEDS(no comment), EL(elevator), MOT(motorerna), BUF(buffert)
*
* @author Anastasios Daniilidis
* @date 10/02/2007
*/

#include <avr/io.h>
#include <avr/sfr_defs.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

short int pres_but1, pres_but2, dest1, dest2;
short int destgiv1, destgiv2, destgiv3, destgiv4, tofloor1, tofloor2, stop1, stop2;
short int giv1, giv2;
short int dir1, dir2, dir3, dir4, temp1, temp2;
char lu[10], ld[10], ru[10], rd[10];
char *p1u, *p1d, *p2u, *p2d;
int count = 100;
int done1 = 0;
int done2 = 0;
int comp1, comp2, comp3, comp4;
int on_zero_floor;
int res_stop1, res_stop2;
int tmp_disp;


void zero_all()
{
destgiv2 = destgiv3 = destgiv4 = tofloor1 = tofloor2 = comp1 = comp2 = comp3 = comp4 =0 ;
destgiv1 = dir1 = dir2 = dir3 = dir4 = temp2 = 0;
}

/*
* Set Port A to be output
*/
void set_PORTA_out()
{
DDRA = 0xFF;
}

/*
* Set Port A to be input
*/
void set_PORTA_in()
{
DDRA = 0x00;
}

/*
* Set Port B to be output
*/
void set_PORTB_out()
{
DDRB = 0xFF;
}

/*
* Set Port D to be output
*/
void set_PORTD_out()
{
DDRD = 0xFF;
}

void set_PORTD_in()
{
DDRD = 0x00;
}

/*
* Initiate sequences
*/
void init_seq()
{
// Left elev down sequence
ld[0] = 0b00001010;
ld[1] = 0b00001001;
ld[2] = 0b00000101;
ld[3] = 0b00000110;
ld[4] = 0b00001010;
ld[5] = 0b00001111;

// Left elevator rotation up
lu[0] = 0b00001010;
lu[1] = 0b00000110;
lu[2] = 0b00000101;
lu[3] = 0b00001001;
lu[4] = 0b00001010;
lu[5] = 0b00001111;

// Right elevator rotation down
rd[0] = 0b10100000;
rd[1] = 0b10010000;
rd[2] = 0b01010000;
rd[3] = 0b01100000;
rd[4] = 0b10100000;
rd[5] = 0b1111;

// Right elev up
ru[0] = 0b10100000;
ru[1] = 0b01100000;
ru[2] = 0b01010000;
ru[3] = 0b10010000;
ru[4] = 0b10100000;
ru[9] = 0b1111;

p1u = &lu[0];// Pointers till början av vetorerna
p1d = &ld[0];
p2u = &ru[0];
p2d = &rd[0];
}

/*
* Initiate elevator. Show floor at display. Port B and D will always be outputs.
*/
void init_elev()
{
short int tmp1, tmp2;
set_PORTB_out();
PORTB = 0b01100000;// Aktivera sista chipet
set_PORTD_out();// Set buffert att peka in, avbrott TK från HH
PORTD = 0x03;
set_PORTA_in();// Läs värde från GIV1-8
tmp1 = PINA;
PORTB = 0b10100000;// Läs värde från GIV9-10
tmp2 = PINA;
PORTB = 0b11100000;// Avaktivera chiperna
PORTD = 0x07;
set_PORTA_out();

if(tmp2==0x80 || tmp2==0x40)
{
PORTB = 0b11101000;
if(tmp2 == 0x80 && tmp1 == 0x01)
PORTA = 0x29;
else if(tmp2 == 0x80 && tmp1 == 0x02)
PORTA = 0x2A;
else if(tmp2 == 0x80 && tmp1 == 0x04)
PORTA = 0x2B;
else if(tmp2 == 0x80 && tmp1 == 0x08)
PORTA = 0x2C;
else if(tmp2 == 0x80 && tmp1 == 0x10)
PORTA = 0x2D;
if(tmp2 == 0x40 && tmp1 == 0x01)
PORTA = 0x21;
else if(tmp2 == 0x40 && tmp1 == 0x02)
PORTA = 0x22;
else if(tmp2 == 0x40 && tmp1 == 0x04)
PORTA = 0x23;
else if(tmp2 == 0x40 && tmp1 == 0x08)
PORTA = 0x24;
else if(tmp2 == 0x40 && tmp1 == 0x10)
PORTA = 0x25;
}

if(tmp1 == 0b00100000 && tmp_disp != 0)
{
switch(tmp_disp) {
case 0x01: temp1 = tmp_disp; break;
case 0x02: temp1 = tmp_disp; break;
case 0x04: temp1 = 0x04; break;
case 0x08: temp1 = 0x08; break;
case 0x10: temp1 = 0x10; break;
}

}
if(tmp1 != 0b00100000)
{
switch(tmp1) {
case 0b00000001: PORTB = 0b11101000; PORTA = 0b00000001; temp1 = 0x01; break;
case 0b00000010: PORTB = 0b11101000; PORTA = 0b00000010; temp1 = 0x02; break;
case 0b00000100: PORTB = 0b11101000; PORTA = 0b00000011; temp1 = 0x04; break;
case 0b00001000: PORTB = 0b11101000; PORTA = 0b00000100; temp1 = 0x08; break;
case 0b00010000: PORTB = 0b11101000; PORTA = 0b00000101; temp1 = 0x10; break;
case 0b00100001: PORTB = 0b11101000; PORTA = 0b00001001; temp1 = 0x01; temp2 = 0x01; break;// Våning 1-1
case 0b01000001: PORTB = 0b11101000; PORTA = 0b00010001; temp1 = 0x01; temp2 = 0x02; break;
case 0b10000001: PORTB = 0b11101000; PORTA = 0b00011001; temp1 = 0x01; temp2 = 0x04; break;
case 0b00100010: PORTB = 0b11101000; PORTA = 0b00001010; temp1 = 0x02; temp2 = 0x01; break;// 1-2
case 0b01000010: PORTB = 0b11101000; PORTA = 0b00010010; temp1 = 0x02; temp2 = 0x02; break;
case 0b10000010: PORTB = 0b11101000; PORTA = 0b00011010; temp1 = 0x02; temp2 = 0x04; break;
case 0b00100100: PORTB = 0b11101000; PORTA = 0b00001011; temp1 = 0x04; temp2 = 0x01; break;// 1-3
case 0b01000100: PORTB = 0b11101000; PORTA = 0b00010011; temp1 = 0x04; temp2 = 0x02; break;
case 0b10000100: PORTB = 0b11101000; PORTA = 0b00011011; temp1 = 0x04; temp2 = 0x04;break;
case 0b00101000: PORTB = 0b11101000; PORTA = 0b00001100; temp1 = 0x08; temp2 = 0x01;break;// 1-4
case 0b01001000: PORTB = 0b11101000; PORTA = 0b00010100; temp1 = 0x08; temp2 = 0x02;break;
case 0b10001000: PORTB = 0b11101000; PORTA = 0b00011100; temp1 = 0x08; temp2 = 0x04;break;
case 0b00110000: PORTB = 0b11101000; PORTA = 0b00001101; temp1 = 0x10; temp2 = 0x01;break;// 1-5
case 0b01010000: PORTB = 0b11101000; PORTA = 0b00010101; temp1 = 0x10; temp2 = 0x02;break;
case 0b10010000: PORTB = 0b11101000; PORTA = 0b00011101; temp1 = 0x10; temp2 = 0x04;break;
}
}
PORTB = 0b11100000;
}

/*
* Check and join propriate GIV to floor. Join alarm and stop 2.
*/
void check_where_pres()
{
if(dir3 == 0)
{
switch(pres_but1) {
case 0x01: destgiv1 = 0x01; break;
case 0x02: destgiv1 = 0x02; break;
case 0x04: destgiv1 = 0x02; break;
case 0x08: destgiv1 = 0x04; break;
case 0x10: destgiv1 = 0x04; break;
case 0x20: destgiv1 = 0x08; break;
case 0x40: destgiv1 = 0x08; break;
case 0x80: destgiv1 = 0x10; break;
}
}
switch(pres_but2) {
case 0x01: destgiv2 = 0x01; break;
case 0x02: destgiv2 = 0x02; break;
case 0x04: destgiv2 = 0x02; break;
case 0x08: destgiv2 = 0x04; break;
case 0x10: destgiv2 = 0x04; break;
case 0x20: destgiv2 = 0x08; break;
case 0x40: destgiv2 = 0x08; break;
case 0x80: destgiv2 = 0x10; break;
}
switch(dest2) {
case 0x10: stop2 = 1; break;
case 0x04: stop1 = 1; break;
case 0x08: stop1 = 0; break;
case 0x20: stop2 = 0; break;
}
}

/*
* Combine destination
*/
void check_where_to()
{
switch(tofloor1) {
case 0x01: destgiv3 = 0x01; break;
case 0x02: destgiv3 = 0x02; break;
case 0x04: destgiv3 = 0x04; break;
case 0x08: destgiv3 = 0x08; break;
case 0x10: destgiv3 = 0x10; break;
}
}

/*
* Set correct value to giv1, giv2
*/
void correct_giv()
{
switch(giv1) {
case 0b00000000: giv1 = 0x00;break;
case 0b00000001: giv1 = 0x01;break;
case 0b00000010: giv1 = 0x02;break;
case 0b00000100: giv1 = 0x04;break;
case 0b00001000: giv1 = 0x08;break;
case 0b00010000: giv1 = 0x10;break;
case 0b00100000: giv1 = 0x00; giv2 = 0x01;break;// Våning 0-1
case 0b00100001: giv1 = 0x01; giv2 = 0x01;break;// Våning 1-1
case 0b01000001: giv1 = 0x01; giv2 = 0x02;break;
case 0b10000001: giv1 = 0x01; giv2 = 0x04;break;
case 0b00100010: giv1 = 0x02; giv2 = 0x01;break;// 2-1
case 0b01000010: giv1 = 0x02; giv2 = 0x02;break;
case 0b10000010: giv1 = 0x02; giv2 = 0x04;break;
case 0b00100100: giv1 = 0x04; giv2 = 0x01;break;// 3-1
case 0b01000100: giv1 = 0x04; giv2 = 0x02;break;
case 0b10000100: giv1 = 0x04; giv2 = 0x04;break;
case 0b00101000: giv1 = 0x08; giv2 = 0x01;break;// 4-1
case 0b01001000: giv1 = 0x08; giv2 = 0x02;break;
case 0b10001000: giv1 = 0x08; giv2 = 0x04;break;
case 0b00110000: giv1 = 0x10; giv2 = 0x01;break;// 5-1
case 0b01010000: giv1 = 0x10; giv2 = 0x02;break;
case 0b10010000: giv1 = 0x10; giv2 = 0x04;break;
}
}
/*
* Compare to find direction with help of variables temp1, temp2;
*/
void find_dir_oncall()
{
if((dir3 == 0 && dir4 == 0) && dir1 == 0)
{
if(destgiv1 > temp1)
dir1 = 1;// Rör uppåt om destination är större
else if(destgiv1 < temp1 && destgiv1 !=0)
dir1 = -1;
if(destgiv2 > temp2)
dir2 = 1;// Samma för H nr 2.
else if(destgiv2 < temp2 && destgiv2 !=0 && giv2 != 0)
dir2 = -1;
}
}

/*
* Find the direction if person in EL pressed to go to some floor
*/
void find_dir_onpres()
{
if((dir1 == 0 && dir2 == 0) && dir3 == 0)
{
correct_giv();
if(tofloor1 != 0 && dir3 == 0) // allagi kl. 10.48
{
if(tofloor1 > temp1)
dir3 = 1;
else if (tofloor1 < temp1)
dir3 = -1;
}
if(tofloor2 != 0 && dir4 == 0)
{
if(tofloor2 > giv2)
dir4 = 1;
else if (tofloor2 < giv2)
dir4 = -1;
}
}
}

/*
* Stop if on same floor and disable LED
*/
void stop_on_samef()
{
// Släk LED när i samma våning och stanna H
if(dir1 == 1 && giv1==destgiv1)
{
comp1 = destgiv1;
tmp_disp = destgiv1;

}
else if(dir1==1 && comp1!=0)
{
if(giv1 == 0)
{
PORTD = 0x07;
PORTB = 0b11100001;
set_PORTA_out();
PORTA = 0x00;
zero_all();
PORTD = 0x03;
set_PORTA_in();
PORTB = 0b11100000;
}
}
else if (dir1 == -1 && giv1 == destgiv1)
{
PORTD = 0x07;
PORTB = 0b11100001;
set_PORTA_out();
PORTA = 0x00;
zero_all();
PORTB = 0b11100000;
}
}

/*
* Stop on destination and turn off LED
*/
void stop_on_dest()
{
correct_giv();
if(dir3 == 1 && giv1==destgiv3)
comp3 = destgiv3;
if(dir3==1 && comp3!=0)
{
if(giv1 == 0)
{
if(destgiv3 == 0x01)
{
int var1;
PORTD = 0x03;
set_PORTA_in();
PORTB = 0b11101000;
var1 = PINA;
var1 = var1 | 0x01;
PORTD = 0x07;
set_PORTA_out();
PORTA = var1;
zero_all();
}
else if(destgiv3 == 0x02)
{
int var2;
PORTD = 0x03;
set_PORTA_in();
PORTB = 0b11101000;
var2 = PINA;
var2 = var2 | 0x02;
PORTD = 0x07;
set_PORTA_out();
PORTA = var2;
zero_all();
}
switch(destgiv3) {
case 0x04: PORTD = 0x07; set_PORTA_out(); PORTB = 0b11110000; PORTA = 0x00; zero_all(); break;
case 0x08: PORTD = 0x07; set_PORTA_out(); PORTB = 0b11110000; PORTA = 0x00; zero_all(); break;
case 0x10: PORTD = 0x07; set_PORTA_out(); PORTB = 0b11110000; PORTA = 0x00; zero_all(); break;
}
PORTB = 0b11100000;
}
}
else if (dir3 == -1 && giv1 == destgiv3)
{
PORTD = 0x07;
PORTB = 0b11110000;
set_PORTA_out();
PORTA = 0x00;
zero_all();
PORTB = 0b11100000;
}
PORTB = 0b11100000;
}

/*
* Wait and move EL. Light Led from pressed button.
*/
void move_on_kt()
{
if(dir3 == 0 && dir4 == 0 )
{
check_where_pres();
find_dir_oncall();
correct_giv();
stop_on_samef();
}
}

/*
* Light LEDS if någon pressed
*/
void leds_on()
{
// Någon anropat H. Tänd motsvarande Led.
if(pres_but1 != 0) // Om anrop till H
{
PORTD = 0x07;// BUF pekar ut
PORTB = 0b11100001;
set_PORTA_out();
PORTA = pres_but1;
}
if(pres_but2 != 0)
{
PORTD = 0x07;
PORTB = 0b11100010;
set_PORTA_out();
PORTA = pres_but2;
}
PORTB = 0b11100000;
}

/*
* Set timer1 to 0,1s
*/
void init_timer()
{
TCCR1B = 0b00000101; //Set timer till clk/1024
TIMSK = 0b00000100;  // Start timer
}

/*
* Check which floor button was pressed in the EL
*/
void which_floor()
{
PORTD = 0x7;
set_PORTA_out();
dest2 = dest2 & 0b00000011;
switch(dest2) {
case 0b00000001: PORTB = 0b11110000; PORTA = 0b01000000; tofloor2 = 0x80; break;
case 0b00000010: PORTB = 0b11110000; PORTA = 0b10000000; tofloor2 = 0x10; break;
}
switch(dest1) {
case 0b00000001: PORTB = 0b11101000; PORTA = 0b01000000; tofloor1 = 0x01; break; // 1
case 0b00000010: PORTB = 0b11101000; PORTA = 0b10000000; tofloor1 = 0x02; break; // 2
case 0b00000100: PORTB = 0b11110000; PORTA = 0b00000001; tofloor1 = 0x04; break; // 3
case 0b00001000: PORTB = 0b11110000; PORTA = 0b00000010; tofloor1 = 0x08; break;
case 0b00010000: PORTB = 0b11110000; PORTA = 0b00000100; tofloor1 = 0x10; break;
case 0b00100000: PORTB = 0b11110000; PORTA = 0b00100000; tofloor2 = 0x01; break; // 1H
case 0b01000000: PORTB = 0b11110000; PORTA = 0b01000000; tofloor2 = 0x02; break; // 2H
case 0b10000000: PORTB = 0b11110000; PORTA = 0b10000000; tofloor2 = 0x04; break; //
case 0b00100001: PORTB = 0b11110000; PORTA = 0b00100001; tofloor1 = 0x01; tofloor2 = 0x01; break;
case 0b01000001: PORTB = 0b11110000; PORTA = 0b01000001; tofloor1 = 0x01; tofloor2 = 0x02; break;
case 0b10000001: PORTB = 0b11110000; PORTA = 0b10000001; tofloor1 = 0x01; tofloor2 = 0x04; break;
case 0b00100010: PORTB = 0b11110000; PORTA = 0b00100010; tofloor1 = 0x02; tofloor2 = 0x01; break;
case 0b01000010: PORTB = 0b11110000; PORTA = 0b01000010; tofloor1 = 0x02; tofloor2 = 0x02; break;
case 0b10000010: PORTB = 0b11110000; PORTA = 0b10000010; tofloor1 = 0x02; tofloor2 = 0x04; break;
case 0b00100100: PORTB = 0b11110000; PORTA = 0b00100100; tofloor1 = 0x04; tofloor2 = 0x01; break;
case 0b01000100: PORTB = 0b11110000; PORTA = 0b01000100; tofloor1 = 0x04; tofloor2 = 0x02; break;
case 0b10000100: PORTB = 0b11110000; PORTA = 0b10000100; tofloor1 = 0x04; tofloor2 = 0x04; break;
case 0b00101000: PORTB = 0b11110000; PORTA = 0b00101000; tofloor1 = 0x08; tofloor2 = 0x01; break;
case 0b01001000: PORTB = 0b11110000; PORTA = 0b01001000; tofloor1 = 0x08; tofloor2 = 0x02; break;
case 0b10001000: PORTB = 0b11110000; PORTA = 0b10001000; tofloor1 = 0x08; tofloor2 = 0x04; break;
case 0b00110000: PORTB = 0b11110000; PORTA = 0b00110000; tofloor1 = 0x10; tofloor2 = 0x01; break;
case 0b01010000: PORTB = 0b11110000; PORTA = 0b01010000; tofloor1 = 0x10; tofloor2 = 0x02; break;
case 0b10010000: PORTB = 0b11110000; PORTA = 0b10010000; tofloor1 = 0x10; tofloor2 = 0x04; break;
}
PORTB = 0b11100000;
}

/*
* Move EL if person in the elevator pressed a button
*/
void move_to_fl()
{
which_floor();
if(dir1 == 0 && (tofloor1 != 0 || tofloor2 != 0))
{
find_dir_onpres();
check_where_to();
stop_on_dest();
}
}

/*
* Write the tasks in Interrupt vector for Timer1
*/
ISR(TIMER1_OVF_vect)//Interrupt vector
{
TCNT1 = 65528; //Lägg värde för 0.001s
if(count == 0)// Exekvera varje 0.1s
{
PORTB = 0b11100000;
set_PORTA_in();//Port A pekar in.
// Check if EL is called
PORTD = 0x01;//Aktivera TK i vänster H, buffert pekar in
pres_but1 = PINA;
PORTD = 0x02;//Aktivera TK i höger H, buffert pekar in
pres_but2 = PINA;
// Check which is the destination floor
PORTD = 0x03;//Buffert pekar in.Avaktivera TK vänster och höger
PORTB = 0b11000000;//Aktivera 8st TK in i hissen
dest1 = PINA;
PORTB = 0b10100000;//Aktvera övriga 2
dest2 = PINA;
// Check sensors
PORTD = 0x03;
PORTB = 0b10100000;//Aktivera chipet med de 2st GIV
giv2 = PINA;
PORTB = 0b01100000;//Aktivera chipet med de övriga 8
giv1 = PINA;//Läs värdena
}
// Kolla dir1,2 och om de är sklida från 0, rör H
if(dir1 != 0 || dir3 != 0)
{
if((dir1 == 1 || dir3 == 1) && stop1 != 1)
{
int older1, half1;
if(*p1u == 0b1111)
p1u = &lu[0];
PORTD = 0x03;
set_PORTA_in(); 
PORTB = 0b11100100;
older1 = PINA;
half1 = older1 & 0xf0;
PORTD = 0x07;
set_PORTA_out();
PORTA = *p1u | half1;
p1u+=1;
}
else if((dir1 == -1 || dir3 == -1)  && stop1 != 1)
{
int half2, older2;
if(*p1d == 0b1111)
p1d = &ld[0];
PORTD = 0x03;
set_PORTA_in(); 
PORTB = 0b11100100;
older2 = PINA;
half2 = older2 & 0xf0;
PORTD = 0x07;
set_PORTA_out();
PORTA = *p1d | half2;
p1d+=1;
}
}
if(dir2 != 0 || dir4 != 0)
{
if((dir2 == 1 || dir4 == 1) && stop2 != 1)
{
int half3, older3;
if(*p2u == 0b1111)
p2u = &ru[0];
PORTD = 0x03;
set_PORTA_in();
PORTB = 0b11100100;
older3 = PINA;
half3 = older3 & 0x0f;
PORTD = 0x07;
set_PORTA_out();
PORTA = *p2u | half3;
p2u+=1;
}
else if((dir2 == -1 || dir4 == -1) && stop2 != 1)
{
int half4, older4;
if(*p2d == 0b1111)
p2d = &rd[0];
PORTD = 0x03;
set_PORTA_in();
PORTB = 0b11100100;
older4 = PINA;
half4 = older4 & 0x0f;
PORTD = 0x07;
set_PORTA_out();
PORTA = *p2d | half4;
p2d+=1;
}
}
PORTD = 0x07;
set_PORTA_out();
PORTB = 0b11100000;
if(count == 0)
count = 100;
count--;
}

/*
* Main method
*/
int main(void)
{
init_seq();
TCNT1 = 65528;// Ställd varje 0.001s.
init_timer();
sei();
while(1)
{
init_elev();
leds_on();
move_on_kt();
move_to_fl();
}
return 0;//Unreachable.
}