Intelligent garbage bin based on raspberry pie

This project is based on the smart trash bin of raspberry pie. The whole project uses the ultrasonic module, DS18B20 temperature sensor, L9110S bridge two-way DC motor drive board, SG90 steering gear, oled display screen. This project also joins the network programming, which can control the trash bin to walk remotely. Next, through each module to explain the principle.

Ultrasound module + SG90 steering gear

Ultrasound module and SG90 steering gear module are used to realize the function that when we touch the mouth of the garbage can, we use ultrasound to detect. When the detection distance is less than the set distance, we use the steering gear to open the lid.

Ultrasound Principle: There used to be an ultrasonic module implemented by C51 single-chip computer. The same is true for the use of ultrasound on raspberry pie. The speed of transmission of ultrasound in the air is known. The time when the acoustic wave meets obstacles after launching is measured, and the transmission is calculated according to the time difference between launching and receiving. The actual distance from the point to the obstacle. The raspberry pie sends a 10us pulse to the Tri foot, receives the pulse signal sent by the raspberry pie, starts sending ultrasound, and sets Echo to a high level. Then prepare to receive the returned ultrasound. When receiving the returned ultrasound, set Echo to a low level. The duration of Echo's high level is the interval between the launch and return of the ultrasound.
Rudder Principle: When the high level (i.e. PWM wave) is continuously simulated by GPIO within 20 ms, the steering gear can turn linearly from 0 to 180 degrees in the time of 0.5 ms to 2.5 Ms. SG90 has three wires. The red wires are connected to 5V power supply and the brown wires are GND. The yellow line is the data control line, which connects to the GPIO. Here we are the 1 port in the wiring PI mode.

void *chaoshenbo(void *arg){
	init_chaoshengbo();
	float dis;
	int degree;
	int i;

	degree=(200+5)/180.0*20.0;
	while(1){
		dis=distance();
		if(dis>0&&dis<10){ //When the distance is less than 10, the steering gear turns and the cover is opened.
			softPwmCreate(pin,15,RANGE);
			delay(1000);
			softPwmWrite(pin,5);
			delay(2000);
			softPwmWrite(pin,degree);
			delay(1000);
			softPwmWrite(pin,15);
	
		}
    }

}

OLED Screen

The oled code on this side: https://download.csdn.net/download/qq_30801535/10189091
On the basis of this code, the oled code is partitioned and a write code is added.

void o_write(char *str,int i){ //Parametric i is the number of rows
    sprintf(yi[i],"%s",str);
}

void *led(void *arg){
   o_init();	
   char *str="wendu: ";
   float temp;
   char *buf=(char *)malloc(128); 
   pthread_create(&t3,NULL,chaoshenbo,NULL); //Threads with the function of ultrasonic module
   log_creat("test.txt");
   log_time();
   qingping(); //Clean screen

    while (1) {
	    shijian();//Display time
		temp= get_temp(); //Acquisition of temperature
		sprintf(buf,"Temp:%0.3f",temp);//Convert to self-paid Abu
	    o_write(buf,2);//Write in
        ascii();//ascii transformation display
        delay(1000);
    }
    log_destroy();

}

DS18B20 temperature sensor

The GPIO port of raspberry pie is used to obtain the temperature detected by the sensor. First, we need to configure the raspberry pie.

sudo raspi-config //  Enter interfacing options to allow single bus interfaces
enable 1-wire interface

sudo modprobe w1-gpio(Loading equipment)
sudo modprobe w1-therm(Loading equipment)
cd /sys/bus/w1/devices/
ls
cd 28-00000xxxxxx //28-00000xxxxxx x as temperature sensor version
cat w1_slave//View the detected temperature

How to get the temperature through the code? Here we use the open function to get the temperature by reading the file and display it on our display screen.

//Part of the code
#define BUFSIZE 128
float get_temp(){
    float temp;
    int fd;
    int ret;
    int i;
    int j;
    char buf[BUFSIZE];
    char tempbuf[5];
    fd=open("/sys/bus/w1/devices/28-03159779c101/w1_slave",O_RDONLY);

    if(-1==fd){
        log_write("open device file failed,fd=%d\n",fd); //Write to log file
        exit(-1);
    }

    while(1){
        ret=read(fd,buf,BUFSIZE);
        if(0==ret){
            log_write("read success,ret=%d\n");
            break;
        }
        if(-1==ret){
            log_write("read failed,ret=%d\n",ret);            
        }
    }
    for(i=0;i<sizeof(buf);i++){ //The t=xxxxxx in the second line of cat w1_slave is the current temperature, which is converted to centigrade divided by 1000, that is, the current temperature.
        if(buf[i]=='t'){ //When the character t is read, the subsequent string is put into buf
            for(j=0;j<sizeof(tempbuf);j++){
                tempbuf[j]=buf[i+j+2];
            }
        }
    }
    temp=(float)atoi(tempbuf)/1000;//Converting the read string to temperature
    close(fd);
    return temp;

}

L9110SQ Bridge Two-way DC Motor Drive Board

Principle: DC motor can be easily realized by using Raspberry Pi. We use L9110SQ motor driver to control the DC motor, which allows the motor to move forward or backward. The pins of IN1, IN2, IN3 and IN4 are set at high and low levels to realize the forward and reverse rotation of the motor.

//Code for Car Walking
void *run(void *arg) {  
    char flag;
    int c_fd=*(int *)arg;
    int ret;
    init();//Port initialization
    log_creat("service.txt");
    pthread_create(&t2,NULL,led,NULL);//Add threads to display screen
    while(1){
    ret = my_recv(c_fd, (char *)&flag, sizeof(char));
    if (-1 == ret) {
        log_write("server recevice failed,ret=%d\n", ret);

    } else {
        log_write("recevice %d \n", ret);
    }
    switch (flag) {
        case 'w':
		   			 stop();
				    delay(50);
				    forword();
		            break;
        case 's':
				    stop();
				    delay(50);
				    back();
		            break;
        case 'd':
				    stop();
				    delay(100);
				    right();
          			break;
        case 'a':
				    stop();
				    delay(100);
				    left();
			        break;
        case ' ':
				    stop();
			        break;
			        default:
			        break;
    }
  }
    log_destroy();
}

Network programming

The most important thing of this project is network programming. We need to write a server and client, raspberry pie as the server, virtual machine as the client (at this time, the virtual machine and raspberry pie can communicate under the same LAN). We can control the trash can through the input of the virtual machine. At the same time, each function module will be realized through multi-threading.
The principle of multi-threading: refers to the technology of concurrent execution of multiple threads from software or hardware. With hardware support, computers with multithreading capability can execute more than one thread at the same time, thus improving the overall processing performance.
The receiving and sending of the server and client I wrote here is to send and receive in one byte, which has some limitations. It can only be used in this project. Later, it will be improved. When sending w, the car will go forward, s-backward, a-left, d-right.

//Server builds part of the code
int main() {
    int s_fd;
    int c_fd;
    int ret;
    log_creat("service.txt");
    log_time();

    struct sockaddr_in s_addr;
    struct sockaddr_in c_addr;

    memset(&s_addr, 0, sizeof(struct sockaddr_in));
    memset(&c_addr, 0, sizeof(struct sockaddr_in));

    s_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == s_fd) {
        log_write("create socket failed,ret=%d\n", s_fd);
    }
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(PORT);//Port is port number 8080
    s_addr.sin_addr.s_addr = htonl(INADDR_ANY); //Any ip can access this server

    ret = bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
    if (-1 == ret) {
        log_write("bind failed,ret=%d\n", ret);
    }

    ret = listen(s_fd, 10);
    if (-1 == ret) {
        log_write("listen failed,ret=%d\n", ret);
    }
   int on=1;
   setsockopt(ret,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    while (1) {
        int c_len = sizeof(struct sockaddr_in);
        c_fd = accept(s_fd, (struct sockaddr *)&c_addr, (socklen_t *)&c_len);
        if (-1 == c_fd) {
            log_write("accept failed,ret=%d\n", c_fd);
        }
        printf("get the car ip:%s\n", inet_ntoa(c_addr.sin_addr));
		wiringPiSetup();
        pthread_create(&t1,NULL,run,(void *)&c_fd);//Join in the car's traveling threads   	
    }
    log_destroy();
    return 0;
}
//Client Build Part Code
int main() {
    int c_fd;
    char flag;
    int ret;
    struct sockaddr_in c_addr;
    
    
    memset(&c_addr, 0, sizeof(struct sockaddr_in));
    log_creat("client.txt");
    log_time();
    c_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == c_fd) {
        log_write("client connect failed,ret=%d\n", ret);
    }
    c_addr.sin_family = AF_INET;
    c_addr.sin_port = htons(PORT);
    inet_aton(SEVERADDR, &c_addr.sin_addr);

    ret = connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr));
    if (-1 == ret) {
        log_write("client connect failed,ret=%d\n", ret);
    }
    log_destroy();

    while (1) {
        log_creat("client.txt");
        flag=handle();
        ret = send(c_fd, (char *)&flag, sizeof(char),0);
        if (-1 == ret) {
            log_write("client send failed,ret=%d\n");
        }else{
            log_write("send %d\n",ret);
        }

        log_destroy();
    }
}

In doing this project, although it is a small project, but it allows me to better grasp some of the basic development of embedded. This time the smart trash bin is a basic software and hardware integration project, through this project also more mastery of network programming, although some places will forget, later need to be consolidated from time to time.

Tags: network Programming sudo socket

Posted on Tue, 03 Sep 2019 06:35:56 -0700 by PHPcoder25