基于OrangePi Zero 2实现垃圾分类智能垃圾桶项目(6)语音模块与阿里云结合

一、语音模块与Orangepi接线以及环境准备

 

1、在orange pi 3.0.6上确认已经配置开启了uart5:(overlays=uart5)

跳转到如何开启uart5步骤

https://mp.csdn.net/mp_blog/creation/editor/134051044

2. 同时将USB摄像头接到香橙派上

3. 确认已经运行了mjpg-streamer服务

服务开机自启动脚本编写详见

https://mp.csdn.net/mp_blog/creation/editor/134071144

二、代码实现(在VScode上远程桌面进行代码编写)

garbage.c

#include "Python.h"//包含Python.h头文件,以便使用Python API
#include "garbage.h"

void garbage_init(void){
	Py_Initialize();//初始化Python解释器
	PyObject *sys=PyImport_ImportModule("sys");
	PyObject *path=PyObject_GetAttrString(sys,"path");//获取sys.path对象
	PyList_Append(path,PyUnicode_FromString("."));//将当前路径添加到sys.path中,以便加载当前Pythn模块(Python文件)

}

void garbage_final(void){
	Py_Finalize();//关闭Python解释器
}

char *garbage_category(char *category){

	PyObject *pModule=PyImport_ImportModule("garbage");//导入Python模块,并检查是否有误
	if(!pModule){
		PyErr_Print();
		printf("Error:failed to load garbage.py\n");
		goto FAILED_MODULE;
	}

	PyObject *pFun=PyObject_GetAttrString(pModule,"alibaba_garbage");//获取Python函数对象,并检查是否可调用
	if(!pFun){
		PyErr_Print();
		printf("Error:failed to load alibaba_garbage\n");
		goto FAILED_FUN;
	}

	PyObject *pValue=PyObject_CallObject(pFun,NULL);//调用Python函数,并获取返回值
	if(!pValue){
		PyErr_Print();
		printf("Error:failed to load pFun\n");
		goto FAILED_VALUE;
	}

	char *result=NULL;//用指针来接收返回值
	if(!PyArg_Parse(pValue,"s",&result)){
		PyErr_Print();
		printf("Error:parse failed\n");
		goto FAILED_VALUE;
	}
	
	printf("result=%s\n",result);
	category=(char *)malloc(sizeof(char)*(strlen(result)+1));
	memset(category,0,(strlen(result)+1));
	strncpy(category,result,(strlen(result)+1));

FAILED_RESULT:
	Py_DECREF(pValue);
FAILED_VALUE:
	Py_DECREF(pFun);
FAILED_FUN:
	Py_DECREF(pModule);
FAILED_MODULE:

	return category;
}

garbage.h

#ifndef __GARBAGE__H
#define __GARBAGE__H
void garbage_init(void);
void garbage_final(void);
char *garbage_category(char *category);

//拍照并保存在指定目录
#define WGET_CMD "wget http://127.0.0.1:8080/?action=snapshot -o /tmp/garbage/jpg"
//清除上一次的照片,给下一次拍照留存储空间
#define GARBAGE_FILE "/tmp/garbage.jpg"

#endif

uartTool.c

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "wiringSerial.h"

int myserialOpen (const char *device, const int baud)//打开串口
{
     struct termios options ;
     speed_t myBaud ;
     int   status, fd ;

     switch (baud){
         case    9600:   myBaud =    B9600 ; break ;//常用波特率设置
         case  115200:   myBaud =  B115200 ; break ;
     }
     if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
     return -1 ;

     fcntl (fd, F_SETFL, O_RDWR) ;

 // Get and modify current options:

     tcgetattr (fd, &options) ;

     cfmakeraw   (&options) ;
     cfsetispeed (&options, myBaud) ;
     cfsetospeed (&options, myBaud) ;

     options.c_cflag |= (CLOCAL | CREAD) ;
     options.c_cflag &= ~PARENB ;
     options.c_cflag &= ~CSTOPB ;
     options.c_cflag &= ~CSIZE ;
     options.c_cflag |= CS8 ;
     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
     options.c_oflag &= ~OPOST ;

     options.c_cc [VMIN]  =   0 ;
     options.c_cc [VTIME] = 100 ;    // Ten seconds (100 deciseconds)

     tcsetattr (fd, TCSANOW, &options) ;

     ioctl (fd, TIOCMGET, &status);

     status |= TIOCM_DTR ;
     status |= TIOCM_RTS ;
    ioctl (fd, TIOCMSET, &status);

     usleep (10000) ;    // 10mS

     return fd ;
 }

 void serialSendstring (const int fd, const unsigned char *s,int len)//发送
 {
     int ret;
     ret = write (fd, s, len);
     if (ret < 0)
         printf("Serial Puts Error\n");

 }

 int serialGetstring (const int fd,unsigned char *buffer)//接收
 {
     int n_read;
     n_read=read(fd,buffer,32);
     return n_read;
 }
 

uartTool.h

#ifndef __UARTTOOL__H
#define __UARTTOOL__H

int myserialOpen (const char *device, const int baud);
void serialSendstring (const int fd, const unsigned char *s,int len);
int serialGetstring (const int fd, unsigned char *buffer);

#define SERIAL_DEV "/dev/ttyS5"
#define BAUD 115200


#endif

main.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

#include "uartTool.h"
#include "garbage.h"

static int detect_process(const char *process_name){//判断是否已经自启动了mjp_streamer
    int n=-1;
    FILE *strm;
    char buf[128]={0};
    sprintf(buf,"ps -ax | grep %s|greparabage -v grep",process_name);
    if((strm=popen(buf,"r"))!=NULL){
        if(fgets(buf,sizeof(buf),strm)!=NULL){
            n=atoi(buf);
        }
    }
    else{
        return -1;
    }
    pclose(strm);
    return n;
}

int main(int argc,char *argv[]){
    //初始化阿里云接口
    garbage_init();//打开Python解释器
    int ret=-1;
    ret=detect_process("mjpg_streamer");
    if(-1==ret){
        goto END;
    }
    
    //orangepi串口初始化
    int serial_fd =-1;
    serial_fd=myserialOpen(SERIAL_DEV,BAUD);
    if(serial_fd==-1){//判断是否打开成功
        goto END;
    }

    //orangepi读取语音模块数据
    unsigned char buffer[6]={0xAA,0X55,0X00,0X00,0X55,0XAA};//串口发送数据起始位是AA 55,停止位是55 AA
    while(1){
        int len=0;//用于存放串口接收数据函数的返回值
        //int serialGetstring (const int fd, unsigned char *buffer);
        len=serialGetstring(serial_fd,buffer);
        if(len>0 && buffer[2]==0x46){//判断是否接收到开始识别指令
            buffer[2]=0x00;//接收到开始识别指令后清零
            system(WGET_CMD);//在终端输出拍照指令使摄像头拍照
            if(access(GARBAGE_FILE,F_OK)==0){//判断照片是否存在
            char *category=NULL;//用于存储返回值(垃圾类型)
            //char *garbage_category(char *category);阿里云接口函数
            category=garbage_category(category);
                if(strstr(category,"干垃圾")){
                    buffer[2]=0x41;
                }else if(strstr(category,"湿垃圾")){
                    buffer[2]=0x42;
                }else if(strstr(category,"可回收垃圾")){
                    buffer[2]=0x43;
                }else if(strstr(category,"有害垃圾")){
                    buffer[2]=0x44;
                }else{
                    buffer[2]=0x45;
                }
            }else{
                buffer[2]=0x45;
            }
            //void serialSendstring (const int fd, const unsigned char *s,int len)
            serialSendstring(serial_fd,buffer,6);//将内容回传给语音模块,用于播报垃圾类型
            buffer[2]=0x00;
            remove(GARBAGE_FILE);//清除本次照片,为下一次拍照留空间
        }
    }
close(serial_fd);

END:
    garbage_final();//关闭(释放)Python解释器
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的示例代码,用于在STM32和Orange Pi Zero 2之间通过串口通信传输数据: ```c #include "stm32f4xx.h" #include "stm32f4xx_usart.h" #define USARTx USART1 #define USARTx_CLK RCC_APB2Periph_USART1 #define USARTx_TX_PIN GPIO_Pin_9 #define USARTx_TX_GPIO_PORT GPIOA #define USARTx_TX_GPIO_CLK RCC_AHB1Periph_GPIOA #define USARTx_TX_SOURCE GPIO_PinSource9 #define USARTx_TX_AF GPIO_AF_USART1 #define USARTx_RX_PIN GPIO_Pin_10 #define USARTx_RX_GPIO_PORT GPIOA #define USARTx_RX_GPIO_CLK RCC_AHB1Periph_GPIOA #define USARTx_RX_SOURCE GPIO_PinSource10 #define USARTx_RX_AF GPIO_AF_USART1 #define USARTx_IRQn USART1_IRQn #define BUFFER_SIZE 256 uint8_t buffer[BUFFER_SIZE]; uint8_t index = 0; void USART_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(USARTx_TX_GPIO_CLK | USARTx_RX_GPIO_CLK, ENABLE); RCC_APB2PeriphClockCmd(USARTx_CLK, ENABLE); GPIO_PinAFConfig(USARTx_TX_GPIO_PORT, USARTx_TX_SOURCE, USARTx_TX_AF); GPIO_PinAFConfig(USARTx_RX_GPIO_PORT, USARTx_RX_SOURCE, USARTx_RX_AF); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Pin = USARTx_TX_PIN; GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USARTx_RX_PIN; GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USARTx, &USART_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = USARTx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); USART_Cmd(USARTx, ENABLE); } void USARTx_IRQHandler(void) { if (USART_GetITStatus(USARTx, USART_IT_RXNE) != RESET) { buffer[index++] = USART_ReceiveData(USARTx); if (index >= BUFFER_SIZE) { index = 0; } } } int main(void) { USART_Configuration(); while (1) { // 发送数据 USART_SendData(USARTx, 'H'); USART_SendData(USARTx, 'e'); USART_SendData(USARTx, 'l'); USART_SendData(USARTx, 'l'); USART_SendData(USARTx, 'o'); USART_SendData(USARTx, '\r'); USART_SendData(USARTx, '\n'); // 接收数据 if (index > 0) { USART_SendData(USARTx, buffer[index - 1]); index--; } } } ``` 请注意,此示例代码仅用于演示如何在STM32和Orange Pi Zero 2之间通过串口通信传输数据。实际应用中,您需要根据自己的需求进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值