当前位置:   article > 正文

基于树莓派/香橙派的智能家居项目(1、1 引入与灯光控制)_香橙派能用树莓派系统吗

香橙派能用树莓派系统吗

写在最前智能家居项目已经搁置了有一段时间,现在已经有了初步的成果,代码基于wiringPi库来进行,原来一直希望可以通过树莓派来完成,但是后来设想希望后期能够在原先代码的基础上舍弃wiringPi库,自行编写驱动程序以及设备树文件来进行,现在树莓派的价格居高不下,手上仅有一块树莓派4b(是朋友借给我学习的),想到战线较长,故索性选择成本更加低的香橙派zero 2来继续完成这个项目。双方都是基于wiringpi库,因此换到新的平台无需做过多更改,只需重新选择合适的引脚以及串口节点即可。这将会是一系列博文,记录自己在制作过程中遇到的问题,日后也会对功能逐渐完善。

此次的项目,我暂时设定如下功能:

程序框架分析:

由上,我需要用到的模块是:四路/多路的继电器(用于灯光控制)、烟雾报警器(火灾报警)、温湿度传感器(检测环境温度)、甲醛传感器(检测房间内的甲醛含量)、摄像头(人脸识别、室内监控)、语音模块(室内语音控制)。以及需要用到socket编程使用网络来发送指令进行控制灯光等设备。主函数的实现无非是多线程进行,对于不同的模块的管理则需要用到链表,可以使用面向对象编程的思想,对于不同的模块去构造出相应的对象。通过链表对相同类型的模块设备进行管理,以访问该模块。

相应的结构体设计:

  1. struct controlDev
  2. {
  3. char devName[128];
  4. int status;
  5. int pinNum;
  6. int (*open)(int pinNum);
  7. int (*close)(int pinNum);
  8. int (*devInit)(int pinNum);
  9. int (*readStatus)(int pinNum, struct controlDev* str_Dev);
  10. int (*changeStatus)(int status, struct controlDev* str_Dev);
  11. //char *(*getPhoto)();
  12. //char* (*getBaseFaData)(char* dataPhotoPath);
  13. //int (*getOnce)();
  14. //size_t (*getDif)(void *ptr, size_t size, size_t nmemb,void *stream);
  15. struct controlDev* next;
  16. };

devName:设备名(用于模块的检索)

status:设备的状态

pinNum:引脚号

函数指针: open、close、devInit(用于设备的开启、关闭、初始化)

                    readStatus、changeStatus(设备状态的读取、改变设备的状态)

如上结构体用于管理模块设备

  1. struct InputCommander
  2. {
  3. char comName[128];
  4. char devName[128];
  5. char command[32];
  6. char port[12];
  7. int sfd;
  8. int fd;
  9. int (*init)(struct InputCommander* comstr, char *ipAdress, char* port);
  10. int (*getCommand)(struct InputCommander* comstr);
  11. char log[1024];
  12. struct InputCommander* next;
  13. };

此结构体用于管理输入指令的接收:语音模块、socket编程的代码管理。


这次我将对灯光控制部分进行分析,因为这部分相较之下比较简单,抛开驱动部分直接使用wiringpi库编程,无非就是相应的引脚控制,对于程序相对比较简单。

示例代码如下:

  1. int lightDevOpen(int pinNum)
  2. {
  3. digitalWrite(pinNum,LOW);
  4. }
  5. int lightDevClose(int pinNum)
  6. {
  7. digitalWrite(pinNum,HIGH);
  8. }
  9. int lightDevInit(int pinNum)
  10. {
  11. pinMode(pinNum,OUTPUT);
  12. digitalWrite(pinNum,HIGH);
  13. }
  14. int lightDevChangeSta(int status, struct controlDev* str_Dev)
  15. {
  16. str_Dev->status = status;
  17. return 0;
  18. }
  19. int lightDevReadSta(int pinNum, struct controlDev* str_Dev)
  20. {
  21. int pin_status;
  22. pin_status = digitalRead(pinNum);
  23. if(pin_status != str_Dev->status)
  24. str_Dev->status = pin_status;
  25. return pin_status;
  26. }
  27. struct controlDev light_dev= {
  28. .devName = "lightDevName",
  29. .pinNum = PIN_NUM,
  30. .status = HIGH,
  31. .open = lightDevOpen,
  32. .close = lightDevClose,
  33. .devInit = lightDevInit,
  34. .changeStatus = lightDevChangeSta,
  35. .readStatus = lightDevReadSta,
  36. };

随后将该模块添加进链表:

  1. struct controlDev* addLightDevInLink(struct controlDev* phead)
  2. {
  3. if(phead == NULL){
  4. phead = &light_dev;
  5. }else{
  6. light_dev.next = phead;
  7. phead = &light_dev;
  8. }
  9. return phead;
  10. }

这样就可以对灯光类型的模块进行添加,通过主函数中findDevName函数来找到相应的模块信息。通过结构体指针访问相应的模块成员。

  1. findDevName函数
  2. struct controlDev* findDevName(char *devName, struct controlDev* pheadDev)
  3. {
  4. struct controlDev* str = pheadDev;
  5. if(pheadDev == NULL){
  6. printf("NULL\n");
  7. }else{
  8. while(str != NULL){
  9. if(strcmp(str->devName,devName) == 0){
  10. return str;
  11. }
  12. str = str->next;
  13. }
  14. }
  15. return NULL;
  16. }

如上就是对灯光的控制,单个灯光会对应各自相应结构体,但是此类代码相对来说比较繁琐,不难看出如上对于灯光的代码大部分都是重复的,但以实现功能为前提,先将上述基本功能实现,随后可以慢慢精进。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/673891
推荐阅读
相关标签
  

闽ICP备14008679号