Embedded elevator multimedia design

Keywords: data structure linked list

Embedded elevator multimedia design code implementation, which has some comments

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <strings.h>
#include <malloc.h>
#include <stdbool.h>
#include <pthread.h>

#include <linux/input.h>

//Define nodes in the linked list
typedef struct node
{
int member;// Members in node
struct node *pNext;// Pointer to the next node
}Node, *pNode;

int *init_mmap(void)
{
int file_fd = open("/dev/fb0", O_RDWR);// Turn on the LCD display
if(file_fd == -1)
{
printf("open /dev/fb0 fail!\n");
return NULL;
}

int *init_mmap_fd = malloc(sizeof(int *));//Define mapping pointers and establish mapping relationships.
init_mmap_fd = mmap(NULL, 800*480*4, PROT_READ|PROT_WRITE,  MAP_SHARED, file_fd, 0);
if(init_mmap_fd == MAP_FAILED)
{
	printf("mmap lcd fail!\n");
	return NULL;
}

return init_mmap_fd;

}

/*
Function: break the mapping relationship and release resources.
Formal parameters:
int *end_mmap: mapping pointer.
Return value: success 0
Failed - 1
/
int close_mmap(int end_mmap)
{
int ret = munmap(end_mmap, 8004804);// Break the mapping relationship and release resources.
if(ret == -1)
{
return -1;
}

return 0;

}

extern pNode pHead;// Call the structure pointer defined in the main function.

/*
Function: create linked list and process floor information.
Formal parameters:
int info: store the floor number of the pressed floor.
Return value:
Success: returns a structure pointer.
Failed: NULL returned
*/
pNode CreateList(int info)
{
pNode pHead = (pNode)malloc(sizeof(Node));// Allocate a header node that does not store valid data
pNode pTail = pHead;// The last node of the linked list
pTail->pNext = NULL;// The pointer to the last node is set to null

pNode pNew = (pNode)malloc(sizeof(Node));//Allocate space for new nodes
pNew->member = info;//Assign the data entered by the user to the members of the node
pTail->pNext = pNew;//Point the pointer of the last node to the next new node
pNew->pNext = NULL;//Set the pointer in the new node to null
pTail = pNew;//Assign the new node to the last node

return pHead;//Return header node

}

/*
Function: linked list node insertion function.
Formal parameters:
pNode pHead: header node.
int front: insert before the node number.
int data: data to insert.
Return value:
Success: true.
Failed: false.
*/
bool Insert_Node(pNode pHead, int front, int data)
{
int i = 0;
pNode Node = pHead;
pNode pSwap;// For exchange

if ( ( front<1 ) && ( Node!=NULL ) )//Judge whether the data entered by the user is greater than or equal to 1 and whether the Node is empty
{
    return false;
}

while ( i<( front-1 ) )//Loop the pointer to the node before which node to insert.
{
    Node = Node->pNext;
    ++i;
}

pNode pNew = (pNode)malloc(sizeof(Node));

pNew->member = data;//Assign the input data to the node to be inserted
pSwap = Node->pNext;//Give the address of the next node to pSwap for exchange
Node->pNext = pNew;//Give the address of the node to be inserted to the pointer field of the previous node
pNew->pNext = pSwap;//Give the address of the next node of the inserted node to the pointer field of the inserted node

return true;

}

/*
Function: query whether the current floor exists in the linked list, c 1 (found) 0 (not found)
Formal parameters:
pNode pHead: header node.
int number: the data to find.
Return value:
Success: returns 1 or 0.
Failed: - 1.
*/
int Search(pNode pHead, int number)
{
int b = 1;
int c = 0;

pNode p;
p = pHead->pNext;
while( ( p!=NULL ) && ( ( p->member )!=number ))//Find the corresponding floor 
{
	p = p->pNext;
	b++;
}  

if( p && ( p->member )==number )  
{
	c = b;
}

return c;

}

/*
Function: process trigger floor and delete trigger floor information.
Formal parameters:
pNode pHead: header node.
int number: data to delete.
Return value:
Success: returns 1 or 0.
Failed: - 1.
*/
int Del_Node(pNode pHead, int delete)
{
int j = 0;
int data = 0;

pNode pSwap;
pNode Node = pHead;

if ( ( delete<1 ) && (Node->pNext == NULL) )//Judge whether there is deleted data
{
    printf("delete node fail!\n");
    return 0;
}

while( j<( delete-1 ) )
{
    Node = Node->pNext;
    ++j;
}

pSwap = Node->pNext;
data = pSwap->member;
Node->pNext = pSwap->pNext;

free(pSwap);

return data;

}

/*
Function: calculate the length of the linked list, that is, calculate the total number of floors pressed
Formal parameters:
pNode pHead: header node.
Return value:
Success: 0.
Failed: - 1.
*/
int Length(pNode pHead)
{
int j = 0;
pNode p = pHead;

while( ( p->pNext )!=NULL )
{
	p = p->pNext;
	j++;
}

return j;

}

int show_location_bmp(char *pathname,int lcd_x_coordinates, int lcd_y_coordinates, int wide, int height,int *show_bmp_lcd_mmap)
{
int i;
int ret;
int x, y;

char bmp_buf[wide*height*3];
int  new_buf[wide*height];
bzero(bmp_buf, sizeof(bmp_buf));
bzero(new_buf, sizeof(new_buf));

int bmp_fd = open(pathname, O_RDONLY);//1. Open BMP format picture
if(bmp_fd == -1)
{
	printf("show_location_bmp(), open bmp failed\n");
	return -1;
}

ret = lseek(bmp_fd,54,SEEK_SET);//2. Skip the first 54 positions of bmp pictures
if(ret == -1)
{
	printf("show_location_bmp(), lseek bmp failed\n");		
	return -1;
}

int *new_p = show_bmp_lcd_mmap + 800*lcd_y_coordinates + lcd_x_coordinates;//3. Redefine the mapping location.

ret = read(bmp_fd, bmp_buf, wide*height*3);//4. Fetch and read picture pixels
if(ret == -1)
{
	printf("show_location_bmp(), read bmp failed\n");	
	return -1;
}

close(bmp_fd);//5. Close picture

for(i=0; i<wide*height; i++)//6. 24bits to 32bits control variable
{
		new_buf[i] = bmp_buf[i*3]<<0  |  bmp_buf[(i*3)+1]<<8 | bmp_buf[(i*3)+2]<<16;		
}

for(y=0;y<height;y++)//7. Solve the problem of picture upside down
{
	for(x=0;x<wide;x++)
	{
		*(new_p+(800*((height-1)-y))+x) = new_buf[wide*y+x];
	}
}

return 0;		

}

static int ts_fd;// Open the socket of the touch screen device

/*
Function: open the touch screen.
Formal parameter: none.
Return value: success 0
Failed - 1
*/
int open_ts()
{
ts_fd=open("/dev/input/event0",O_RDWR);
if(ts_fd==-1)
{
perror("failed to open touch screen \ n");
return -1;
}
}

//Get coordinates
int read_ts(int *ts_x,int *ts_y)
{
//Define event structure
struct input_event ts_event;

//Define count
int count=0;

while(1)
{
	//2. Read touch coordinates
	read(ts_fd,&ts_event,sizeof(ts_event));
	
	//3, 	 Processing coordinates and judging information
	if(ts_event.type==EV_ABS)//Judge whether the current is touch
	{
		if(ts_event.code==ABS_X)//Judge whether the current touch coordinate is the x-axis
		{
			*ts_x=ts_event.value;//Output x-axis coordinates
			count++;
			
		}
		if(ts_event.code==ABS_Y)//Judge whether the current touch coordinate is the x-axis
		{
			*ts_y=ts_event.value;//Output x-axis coordinates
			count++;
		}
		
		if(count==2)
			break;
	}
	
}

}

//Turn off touch
int ts_close()
{
close(ts_fd);
}

void click_event(int);
void floor_sound(int);
void each_floor(int);
void recover();

//Variable definition
int *main_mmap;// Mapping pointer
int ts_x, ts_y;//x. Y-axis coordinates

int i = 1;// Define current floor
int click;// Define click floor
int state;// Rising and falling state control variable 1 (elevator rising) - 1 (elevator falling) 0 (no key pressed)
int flag = 0;
pNode pHead = NULL;

void *elevator_control(void *arg)
{
int increase_num = 0;
int searchnum = 0;

while(1)
{ 

	ts_x = 0;
	ts_y = 0;
	read_ts(&ts_x, &ts_y);
	printf("\n\n======thread_start:(x,y):(%d,%d)======\n\n", ts_x, ts_y);

	
	if(ts_x<800)
		continue;
		
	
	if(ts_x>800 && ts_x<900 && ts_y>500 && ts_y<600)
		click = 1;
	if(ts_x>900 && ts_x<1000 && ts_y>500 && ts_y<600)                    
		click = 2;                 
	if(ts_x>800 && ts_x<900 && ts_y>400 && ts_y<500)
		click = 3;
	if(ts_x>900 && ts_x<1000 && ts_y>400 && ts_y<500)
		click = 4;
	if(ts_x>800 && ts_x<900 && ts_y>300 && ts_y<400)
		click = 5;
	if(ts_x>900 && ts_x<1000 && ts_y>300 && ts_y<400)
		click = 6;
	if(ts_x>800 && ts_x<900 && ts_y>150 && ts_y<250)
		click = 7;
	if(ts_x>900 && ts_x<1000 && ts_y>150 && ts_y<250)
		click = 8;
	if(ts_x>800 && ts_x<900 && ts_y>0 && ts_y<100)
		click = 9;
	if(ts_x>900 && ts_x<1000 && ts_y>0 && ts_y<100)
		click = 10;
	
	if(click != i) 
		click_event(click);		
	
	if(pHead == NULL) 
	{
		if(click > i)//Elevator rise
		{   system("madplay s.mp3 -a +30 &");
			flag  = 1;    
			state = 1;
			
			show_location_bmp("up.bmp", 480, 110, 120, 120, main_mmap);
			
			pHead = CreateList(click);
		} 
		else//Elevator descent
		{   system("madplay x.mp3 -a +30 &");
			flag = 1;
			state = -1;
		 
			show_location_bmp("down.bmp", 480, 240, 120, 120, main_mmap);
			
			pHead = CreateList(click);
			 
		}   
	} 		
	else{
			if(state==1 && click>i)
			{
				searchnum = Search(pHead, click);
				if(searchnum == 0)
				{
					increase_num = Length(pHead);
					increase_num = increase_num + 1;
					Insert_Node(pHead, increase_num, click);
				}
			}
			else if(state==-1 && click<i) 
				 {
						searchnum = Search(pHead, click);
						if(searchnum == 0)
						{
							increase_num = Length(pHead);
							increase_num = increase_num + 1;
							Insert_Node(pHead, increase_num, click);
						}
				 }
		}
}
	
//Thread exit
pthread_exit(NULL);

}

void *ad(void *arg)
{
while(1)
{

	show_location_bmp("ad1.bmp", 0, 0, 200, 480, main_mmap);
	sleep(1);
	
	show_location_bmp("ad2.bmp", 0, 0, 200, 480, main_mmap);
	sleep(1);
	show_location_bmp("ad3.bmp", 0, 0, 200, 480, main_mmap);
	sleep(1);	
}

pthread_exit(NULL);//Thread exit

}

int main(int argc, char const *argv[])
{
open_ts();// Open touch screen
main_mmap = init_mmap();// Establish mapping relationship

show_location_bmp("main.bmp", 0, 0, 800, 480, main_mmap);


while(1)//Click to enter the elevator display system
{
	ts_x = 0;
	ts_y = 0;
	read_ts(&ts_x, &ts_y);
	if(ts_x>0 && ts_x<1000 && ts_y>0 && ts_y<600)
	{
		show_location_bmp("elevatorinterface.bmp", 200, 0, 600, 480, main_mmap);
		show_location_bmp("1.bmp", 210, 140, 200, 200, main_mmap);
		ts_x = 0;
		ts_y = 0;
		break;
	}			
}

pthread_t ele_con, advertisement;//Create two threads for elevator control and advertisement playback 
pthread_create(&ele_con, NULL,&elevator_control, NULL);//Elevator control
pthread_create(&advertisement, NULL, &ad, NULL);//Advertisement broadcast

int b = 0;
int del_num = 0;
int searchnum = 0;

while(1) 
{		
	while(1) 
	{    
		if(flag == 1) 
		{
			if(state == 1)
			{
				each_floor(i);
				
				searchnum = Search(pHead, i);
				printf("\n=============debug 1:  searchnum=%d, i=%d!\n\n", searchnum, i);
				if(searchnum != 0)
				{
					del_num = Del_Node(pHead, searchnum);
					printf("=============debug 2: delete number: %d\n", del_num);
					
					floor_sound(i);
					
					sleep(5);
				}
				else
					sleep(1);
				
				b = Length(pHead); 
				printf("=============debug 2!  Total number of floors=%d\n", b);
				
				if(b == 0)
				{
					flag = 0;
					
					pHead = NULL;
					
					state = 0;
					
					recover();. 
					each_floor(i);
					each_floor(i);

					
					show_location_bmp("restore_up.bmp", 480, 110, 120, 120, main_mmap);
					
					break;
				}	
				i++; 	
			} 
			else    if(state==-1)
					{
						each_floor(i);
						
						searchnum = Search(pHead, i);
						if(searchnum != 0)
						{
							del_num = Del_Node(pHead, searchnum);
							printf("=============debug 2: delete number: %d\n", del_num);
							
							floor_sound(i); 
							
							sleep(5);		 
						}
						else
							sleep(1);
						
						b = Length(pHead);	
						if (b == 0) 
						{
							flag = 0;
							   
							pHead = NULL;
							
							state = 0;
							
							recover();
							each_floor(i);
							
							show_location_bmp("restore_down.bmp", 480, 240, 120, 120, main_mmap);
							
							break;
						} 
						i--; 	
					} 
		}
	   
	}
} 	

close_ts();//Turn off touch screen
close_mmap(main_mmap);	//Break the mapping relationship and release resources.

pthread_join(ele_con,NULL);//Reclaim elevator control thread
pthread_join(advertisement,NULL);//Recycle ad display thread

return 0;

}

void floor_sound(int select)
{
switch(select)
{
case 1:
show_location_bmp("01.bmp", 600, 384, 100, 96, main_mmap);

	    	break;
	case 2:
			show_location_bmp("02.bmp", 700, 384, 100, 96, main_mmap);
		 
			break;
	case 3:
			show_location_bmp("03.bmp", 600, 288, 100, 96, main_mmap);
			
			break;
	case 4:	
			show_location_bmp("04.bmp", 700, 288, 100, 96, main_mmap);
		
			break;
	case 5:
			show_location_bmp("05.bmp", 600, 192, 100, 96, main_mmap);	
			
			break;
	case 6:	
			show_location_bmp("06.bmp", 700, 192, 100, 96, main_mmap);
			
			break;
	case 7:
			show_location_bmp("07.bmp", 600, 96, 100, 96, main_mmap);
			
			break;
	case 8:
			show_location_bmp("08.bmp", 700, 96, 100, 96, main_mmap);
			
			break;
	case 9:
			show_location_bmp("09.bmp", 600, 0, 100, 96, main_mmap);
			
			break;
	case 10:
			show_location_bmp("010.bmp", 700, 0, 100, 96, main_mmap);
			
			break;
}

}

void click_event(int click)
{
if( click1 )
show_location_bmp("001.bmp", 600, 384, 100, 96, main_mmap);
if( click2 )
show_location_bmp("002.bmp", 700, 384, 100, 96, main_mmap);
if( click3 )
show_location_bmp("003.bmp", 600, 288, 100, 96, main_mmap);
if( click4 )
show_location_bmp("004.bmp", 700, 288, 100, 96, main_mmap);
if( click5 )
show_location_bmp("005.bmp", 600, 192, 100, 96, main_mmap);
if( click6 )
show_location_bmp("006.bmp", 700, 192, 100, 96, main_mmap);
if( click7 )
show_location_bmp("007.bmp", 600, 96, 100, 96, main_mmap);
if( click8 )
show_location_bmp("008.bmp", 700, 96, 100, 96, main_mmap);
if( click9 )
show_location_bmp("009.bmp", 600, 0, 100, 96, main_mmap);
if( click10 )
show_location_bmp("0010.bmp", 700, 0, 100, 96, main_mmap);
}

void each_floor(int select)
{
switch(select)
{
case 1:
show_location_bmp("1.bmp", 210, 140, 200, 200, main_mmap);
break;
case 2:
show_location_bmp("2.bmp", 210, 140, 200, 200, main_mmap);
break;
case 3:
show_location_bmp("3.bmp", 210, 140, 200, 200, main_mmap);
break;
case 4:
show_location_bmp("4.bmp", 210, 140, 200, 200, main_mmap);
break;
case 5:
show_location_bmp("5.bmp", 210, 140, 200, 200, main_mmap);
break;
case 6:
show_location_bmp("6.bmp", 210, 140, 200, 200, main_mmap);
break;
case 7:
show_location_bmp("7.bmp", 210, 140, 200, 200, main_mmap);
break;
case 8:
show_location_bmp("8.bmp", 210, 140, 200, 200, main_mmap);
break;
case 9:
show_location_bmp("9.bmp", 210, 140, 200, 200, main_mmap);
break;
case 10:
show_location_bmp("10.bmp", 210, 140, 200, 200, main_mmap);
break;
}
}

void recover(void)
{
show_location_bmp("elevatorinterface.bmp", 200, 0, 600, 480, main_mmap);

}

Posted by hitman6003 on Wed, 27 Oct 2021 23:21:53 -0700