现在电用电器是必不可少的,因此,电就变成了必需品,但是在用电的过程中带来方便的同时也隐藏着巨大的危险。现在在网上看到很多排插都具备了保护功能,比如,漏电保护,定时开关等。所以打算用dragonboard 410c也做一个智能开关,首先要做的是硬件选择。

      主控制器就是dragonboard 410c,这里就不过多的介绍了。接下来就是如何安全的控制排差供电的通断了,最简单的就是继电器了,它的好处就是可以用很小的电压、电流通路来控制很高的电压、电流通路。继电器有很多种,最常见的是电磁继电器和固态继电器。

      电磁继电器是利用电磁铁来控制电路通断的开关,不同型号的电磁继电器功能也不同,可以是直流控直流,直流空交流,交流控直流,交流控交流。但是因为有机械触点,所以易损坏,但是价格便宜。

昂达h410sd4 BIOS_手机端

昂达h410sd4 BIOS_底层驱动_02

昂达h410sd4 BIOS_工作原理_03

                                                                           图1 继电器                                                                                                                                              图2 继电器工作原理图


      固态继电器是由微电子电路,分立电子器件,电力电子功率器件组成的无触电开关。微小控制信号就可以直接驱动大电流负载。价格比较贵,一般用在工业,医疗,消防等。

昂达h410sd4 BIOS_昂达h410sd4 BIOS_04

昂达h410sd4 BIOS_工作原理_05

                              图3 固态继电器                                                                                                                                   图4 固态继电器工作原理图



     因为固态继电器价格稍高一些,固态继电器的价格相对来说比较低,并且固态继电器已经可以满足对220v的控制了,所以选用的固态继电器。

     最后就是一个排插了,用的普通排插。

昂达h410sd4 BIOS_底层驱动_06

图5 排插


     其主要工作原理和功能:

     将dragonboard 410c连接网络,手机端也连接到网络。当我们不在家时可以查看排查的工作状态,如果家里没人也在工作,并且没有像冰箱这种不可以断电的电器连接在上面,我们就可以通过手机端将其断电,以确保用电安全和节约。

    

     软件上主要实现有两部分,一部分是底层的继电器驱动,另一部分是上层的apk。底层驱动比较简单,如下:

 

到这里底层驱动就完成了,接下来就是上层apk的实现了,也比较简单,这里就不介绍了。

struct relay_data{ 
     int pin;      
     int d; 
     struct mutex data_lock; 
 }; 
  
 static int parse_dt(struct platform_device* pdev,struct relay_data* data){ 
     int rc; 
     struct device_node* node = pdev->dev.of_node; 
     data->pin = of_get_named_gpio(node,"thunder,gpio",0); 
     if(gpio_is_valid(data->pin)){ 
         rc = gpio_request(data->pin,"relay_pin"); 
         if(rc < 0){ 
             pr_err("Unable to request pin gpio\n"); 
         } 
         gpio_direction_output(data->pin, 1); 
         data->d = '1'; 
     } 
     return 0; 
 } 
  
 static ssize_t relay_store_value(struct device *dev,                                                                                                                                                   
                 struct device_attribute *attr, 
                 const char *buf, size_t size){ 
     struct relay_data* data = dev_get_drvdata(dev); 
     if(buf[0] == '1'){ 
         gpio_set_value(data->pin, 1); 
     }else{ 
         gpio_set_value(data->pin, 0); 
     } 
     data->d = buf[0]; 
     dump_stack(); 
     return size; 
 } 
  
 static ssize_t relay_show_value(struct device *dev, 
                                   struct device_attribute* attr,char* buf){ 
     struct relay_data* data = dev_get_drvdata(dev); 
     ssize_t da; 
     mutex_lock(&data->data_lock); 
     da = sprintf(buf, "%c", data->d); 
     mutex_unlock(&data->data_lock); 
     printk("show buf=%c\n", *buf); 
     dump_stack(); 
     return da; 
 } 
  
 static DEVICE_ATTR(value,0666,relay_show_value,relay_store_value); 
  
 static int relay_probe(struct platform_device *pdev){ 
     struct relay_data* data; 
     int result; 
     data = kmalloc(sizeof(struct relay_data),GFP_KERNEL); 
     if(!data){ 
         pr_err("%s kmalloc error\n",__FUNCTION__); 
         return -ENOMEM;   
     } 
     dev_set_drvdata(&pdev->dev,data); 
     result = parse_dt(pdev,data); 
     if(result<0){ 
         pr_err("%s error when parse dt\n",__FUNCTION__); 
         result = -EINVAL; 
         goto err_parse_dt; 
     } 
  
     mutex_init(&data->data_lock); 
      
     result=sysfs_create_file(&pdev->dev.kobj,&dev_attr_value.attr); 
     printk("relay probe success\n"); 
     return 0; 
 err_parse_dt: 
     kfree(data); 
     printk("relay probe failed\n"); 
     return result; 
 } 
 static int relay_remove(struct platform_device *pdev){ 
     return 0; 
 } 
  
  static struct of_device_id relay_match_table[] = { 
     { .compatible = "thunder,relay",}, 
     { }, 
 }; 
  
  static struct platform_driver relay_driver = { 
     .probe = relay_probe, 
     .remove = relay_remove, 
     .driver = { 
         .owner = THIS_MODULE, 
         .name = "relay", 
         .of_match_table = relay_match_table, 
     }, 
 }; 
  
  module_platform_driver(relay_driver); 
 MODULE_AUTHOR("RELAY"); 
 MODULE_LICENSE("GPL v2");