본문 바로가기

VERILOG

[프로젝트]BASYS3를 이용한 VERILOG 스마트팜 만들기(1)

BASYS3를 이용한 VERILOG 스마트팜 만들기(1)

프로젝트 제작 기간 도구 프로젝트 목표
5.17 ~ 5.24 BOARD BASYS 3 / Xilinx Vivado Smart Farm 구현
(온습도센서, 초음파센서, 조도센서, 서보모터, 모터, 모터드라이버 )

 

목차

  • SmartFarm에 필요한 초음파 센서와 온습도 센서와 조도센서를 이용해 기본모드를 제작하였다.
  • 온습도 센서를 기본모드로 설정하여 FND에 출력할 수 있게 설계 하였습니다.
  • 온습도센서의 값을 이용하여 습도의 차이에 따라 환풍기를 설계할 수 있도록 PWM을 통해모터를 습도에 따라 다르게 구현하였습니다.
  • 온도에 따라 높은온도의 경우 서보모터를 이용해 창문 개폐를 설계하였고, 낮은 온도의 경우 LED를 켜 히터역할을 설계하였습니다.
  • 버튼을 누르면 모드가 바뀌며 조도센서와 초음파센서를 FND로 결과값을 확인 할 수 있게 설계하였습니다.

보드 연결

사용하는 보드인 BASYS3에 센서들의 값을 받아올 수 있게 연결해준다. 

 

 

 

 

 

배선 연결

위의 보드 설명에 맞게 부품을 연결한다.

 

 

 

스마트팜 상태도

SMART FARM의 TOP  MODULE

SmartFarn 의 TOP모듈을 구현하였다.

module smartfarm_top(
    input clk, //클락
    input [4:0] btn, // 총 사용하는 버튼
    inout dht11_data,
    input vauxp6,
    input vauxn6,
    input echo,
    output [1:0] pwm_mode,
    output trig,
    output  pwm_fan,
    output  pwm_window,
    output [3:0] com_an, 
    output reg led,
    output [7:0] seg_7 // 7-segment와 연결
    );
    
    wire dht_btn, light_btn, ultra_btn;
    wire [7:0] humidity, temperature;
    wire [3:0] light_com, ultra_com, dht_com;
    wire [7:0] light_seg, ultra_seg, dht_seg;
    
    reg [1:0] mode;
    
    assign reset_n = ~btn[2]; // btn2번을 누르게 되면 반전되면서 모드가 바뀌게 된다.
    
    clock_usec uCLK(.clk(clk), .reset_n(reset_n), .clk_usec(clk_usec));
    clock_msec mCLK(.clk(clk), .clk_usec(clk_usec), .reset_n(reset_n), .clk_msec(clk_msec));
    
    // debouncing 
    D_flip_flop_posedge_trig dff_dht(.D(btn[0]), .E(clk_msec), .Q(dht_btn)); 
    D_flip_flop_posedge_trig dff_ultra(.D(btn[1]), .E(clk_msec), .Q(ultra_btn)); 
    D_flip_flop_posedge_trig dff_light (.D(btn[3]), .E(clk_msec), .Q(light_btn)); 

    //btn의 입력에따른 모드 2bit 설정
    always @(posedge dht_btn or posedge ultra_btn or posedge light_btn or negedge reset_n)
    begin
        if(!reset_n) begin
            mode  = 2'b00;
        end
        else begin
            if (dht_btn) mode = 2'b00;
            else if(ultra_btn) mode = 2'b01;
            else if (light_btn) mode = 2'b10;   
        end
    end
    
    //온습도 센서, 초음파 센서, 조도 센서  인스턴스 
    
    DHT11_top dht11( .clk(clk),  .btn(btn[2]),  .dht11_data(dht11_data), .humidity(humidity), .temperature(temperature), .com_an(dht_com),  .seg_7(dht_seg) );
    ultrasonic_top ultra_top(.clk(clk), .trig(trig), .echo(echo), .btn(btn[2]), .com_an(ultra_com), .seg_7(ultra_seg) );
    ch6_ADC_top at( .vauxp6(vauxp6), .vauxn6(vauxn6), . clk(clk), .com_an(light_com), .seg_7(light_seg));
    
    
    // 4 bit 의  mux 를 사용해야하는데, 한 번에 먹스를 사용하게 되면 13 bit가 되므로 한비트씩 끊어서 하기 
     mux_4_1 m0 (.D({0, light_com[0], ultra_com[0], dht_com[0]}), .S(mode), . F(com_an[0]));
     mux_4_1 m1 (.D({0, light_com[1], ultra_com[1], dht_com[1]}), .S(mode), . F(com_an[1]));
     mux_4_1 m2 (.D({0, light_com[2], ultra_com[2], dht_com[2]}), .S(mode), . F(com_an[2]));
     mux_4_1 m3 (.D({0, light_com[3], ultra_com[3], dht_com[3]}), .S(mode), . F(com_an[3]));
     
     mux_4_1 s0 (.D({0, light_seg[0], ultra_seg[0], dht_seg[0]}), .S(mode), . F(seg_7[0]));
     mux_4_1 s1 (.D({0, light_seg[1], ultra_seg[1], dht_seg[1]}), .S(mode), . F(seg_7[1]));
     mux_4_1 s2 (.D({0, light_seg[2], ultra_seg[2], dht_seg[2]}), .S(mode), . F(seg_7[2]));
     mux_4_1 s3 (.D({0, light_seg[3], ultra_seg[3], dht_seg[3]}), .S(mode), . F(seg_7[3]));
     mux_4_1 s4 (.D({0, light_seg[4], ultra_seg[4], dht_seg[4]}), .S(mode), . F(seg_7[4]));
     mux_4_1 s5 (.D({0, light_seg[5], ultra_seg[5], dht_seg[5]}), .S(mode), . F(seg_7[5]));
     mux_4_1 s6 (.D({0, light_seg[6], ultra_seg[6], dht_seg[6]}), .S(mode), . F(seg_7[6]));
     mux_4_1 s7 (.D({0, light_seg[7], ultra_seg[7], dht_seg[7]}), .S(mode), . F(seg_7[7]));
     
     //---------------------------------FAN---------------------------------// 
     // 습도가 60 이상이면 duty rate 40으로, 습도 70이상이면 duty rate 60, 습도 80이상이면 duty rate 90
     reg [15:0] duty_temp_window, duty_temp_fan;

     wire clk_160ns, clk_2560ns, clk_40us;
    
    clock_divider cd_16(  .clk(clk), .sel(3), .clk_out(clk_160ns));                              // 160ns 
    clock_divider cd_256(  .clk(clk_160ns), .sel(3), .clk_out(clk_2560ns));          // 160ns * 16 = 2560분주 
    clock_divider cd_4096(  .clk(clk_2560ns), .sel(3), .clk_out(clk_40us));  
     
     pwm_top LUT(.clk(clk), .reset_btn(btn[2]), .duty_cycle(duty_temp_fan), .pwm(pwm_fan),  .pwm_mode(pwm_mode));
     
     always @(negedge reset_n  or negedge clk_40us)
     begin
        if(!reset_n) begin
            duty_temp_fan = 0;
        end
        else begin
            if(humidity > 60) begin //duty 40%
                duty_temp_fan = 16'd8000;
            end
            else if(humidity > 70) begin //duty 60%
                duty_temp_fan = 16'd12000;
            end
            else if(humidity > 80) begin //duty 90%
                duty_temp_fan = 16'd16000;
            end
            else begin
                duty_temp_fan = 0;
            end
        end
     end
//--------------------------------WINDOW--------------------------------//
//온도가 26 미만인 경우 역방향 회전, 27 초과인 경우는 정방향 회전 
    pwm_top LUT2(.clk(clk), .reset_btn(btn[2]), .duty_cycle(duty_temp_window), .pwm(pwm_window),  .pwm_mode(pwm_mode));
    
    always @(negedge reset_n  or negedge clk_40us)
     begin
        if(!reset_n) begin
            duty_temp_window = 16'd1900;
        end
        else begin
            if(temperature > 27 ) begin //duty 40%
                duty_temp_window = 16'd1100;
            end
            if (temperature < 26 )begin
                duty_temp_window = 16'd1900;
            end
        end
     end
//---------------------------------LIGHT---------------------------------//
// 온도가 25보다 작은 경우엔 led on, 그 외 led off
    always @(negedge clk_40us ) begin
        if(temperature < 25) led = 1'b1;
        else led =1'b0;        
    end

 
endmodule

 

 


버튼구상


RTL회로