【香橙派系列教程】(十七) 视觉垃圾桶-功能完善优化

【十七】视觉垃圾桶-功能完善优化

一、增加垃圾桶开关盖

1.引脚

实现功能:使用语音模块和摄像头在香橙派上做垃圾智能分类识别, 同时根据识别结果开关不同的垃圾桶的盖子。

主要用到的PWM引脚:5和7。

image-20240724220636887

2.PWM 频率的公式

这个 PWM 频率的公式可以更详细地表示为:

P W M f r e q = 1 × 1 0 6 ( p u l s e − w i d t h ) × r a n g e PWMfreq = \frac{1 \times 10^6}{(pulse-width) \times range} PWMfreq=(pulsewidth)×range1×106
其中:

  1. P W M f r e q PWMfreq PWMfreq :是 PWM 的频率(赫兹)。

  2. 1 × 1 0 6 {1 \times 10^6} 1×106 :是为了将频率从赫兹(Hz)转换为微秒(μs)。

  3. $pulse-width $ 是每个 PWM 脉冲的宽度(微秒)。

  4. × r a n g e \times range ×range 是 PWM 的范围,即 PWM 值的最大范围。

这个公式的基本思想是,PWM 的频率与脉冲宽度和范围有关。脉冲宽度表示每个 PWM 脉冲的持续时间,而范围表示 PWM 值的最大范围。通过调整这两个参数,可以控制 PWM 的频率。

在之前《官方外设开发》一节中我们也讲到了舵机的开发,我们用到的是定时器模拟pwm,一个进程只能创建一个定时器,也就意味着只能驱动一个舵机,所以如果我们想要驱动多个的话,就需要下面的方法了。

range设置为200时,PWM的频率将是50Hz。这里的range值表示PWM周期被分成200个步进,每个步进的时间为:0.5微秒。
每个步进时间 = 周期时间 步数 = 100 μ s 200 = 0.5 μ s \text{每个步进时间} = \frac{\text{周期时间}}{\text{步数}} = \frac{100\mu s}{200} = 0.5\mu s 每个步进时间=步数周期时间=200100μs=0.5μs

3.PWM_API

softPwmCreatesoftPwmWrite 函数用于在不支持硬件PWM或者需要额外PWM通道的微控制器或类似设备上实现软件PWM控制。虽然这些函数不是标准C库的一部分,但是它们的API可能有如下特点:

softPwmCreate
  • 函数原型

    void softPwmCreate(uint8_t pin, uint16_t value, uint16_t range);
    
  • 参数

    • pin:指定用于PWM输出的数字引脚编号。
    • value:初始PWM值,可以是0(表示PWM输出为0%占空比)或其他值,取决于range参数。
    • range:定义PWM周期的分辨率。在这个范围内,PWM值将被分割,从而控制占空比。
  • 功能:初始化指定引脚的软件PWM功能,并设置其初始值和PWM周期的分辨率。

softPwmWrite
  • 函数原型

    void softPwmWrite(uint8_t pin, uint16_t value);
    
  • 参数

    • pin:指定要修改PWM值的数字引脚编号。
    • value:新的PWM值,这个值将影响引脚的占空比,其具体范围由softPwmCreate函数中的range参数决定。
  • 功能:设置指定引脚的PWM占空比。这个函数通常在PWM创建后被调用来改变输出信号的占空比。

附加说明
  • 周期和频率:PWM的周期是高电平和低电平时间的总和,频率是周期的倒数。在softPwmCreate中设置的range参数会影响周期的计算。
  • 精度range参数的值越大,PWM的控制精度越高,但同时可能需要更复杂的算法来计算定时器中断。
  • 线程安全:在多线程环境中使用这些API时,需要注意线程安全问题,以避免竞态条件。
  • 平台依赖性:这些API可能是针对特定硬件平台或软件库设计的,因此它们的实现和行为可能会因平台而异。

请注意,由于softPwmCreatesoftPwmWrite不是标准API,具体的函数原型、参数和行为可能会根据实际使用的库或框架有所不同。

softPwmStop

softPwmStop 函数用于停止软件PWM信号的API函数。

函数原型示例

void softPwmStop(uint8_t pin);
  • pin:指定要停止PWM输出的数字引脚编号。

注意事项

  • 在使用 softPwmStop 之前,确保已经通过 softPwmCreate 成功创建了PWM信号。
  • 如果 softPwmStop 用于释放资源,确保在重新使用PWM功能之前重新初始化。
  • 在多线程环境中,如果 softPwmStop 影响共享资源,需要考虑线程同步和互斥。

image-20240326165346171

4.代码

pwm.c

pwm.c(增加用于实现开关盖(驱动舵机)的源码文件)

#include <wiringPi.h>
#include <softPwm.h>
//根据公式:PWMfreq = 1 x 10^6 / (100 x range) ,要得到PWM频率为50Hz,则range为200,即周期分为200步,控制精度相比硬件PWM较低。
void pwm_write(int pwm_pin)
{
   
   
    pinMode(pwm_pin, OUTPUT);
    softPwmCreate(pwm_pin,0,200);// 起始值为0,周期范围设置为200步。, 周期20ms
    softPwmWrite(pwm_pin,10);//1ms 45度,这将产生一个占空比为5%的PWM信号(因为10是200步中的一小部分)。
    delay(1000);
    softPwmStop(pwm_pin);
}
void pwm_stop(int pwm_pin)
{
   
   
    pinMode(pwm_pin, OUTPUT);
    softPwmCreate(pwm_pin,0,200);// range设置周期分为200步, 周期20ms
    softPwmWrite(pwm_pin,5);//0.5ms 0度
    delay(1000);
    softPwmStop(pwm_pin);
}

pwm.h

pwm.h

#ifndef __PWM__H
#define __PWM__H
#define PWM_GARBAGE 7
#define PWM_RECOVERABLE_GARBAGE 5
void pwm_write(int pwm_pin);
void pwm_stop(int pwm_pin);
#endif

main.c

main.c里增加调用舵机的控制代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <wiringPi.h>
#include "uartTool.h"
#include "garbage.h"
#include "pwm.h"
static int detect_process(const char *process_name)
{
   
   
    int n = -1;
    FILE *strm;
    char buf[128]={
   
   0};
    sprintf(buf,"ps -ax | grep %s|grep -v grep", process_name);
    if((strm = popen(buf, "r")) != NULL)
    {
   
   
        if(fgets(buf, sizeof(buf), strm) != NULL)
        {
   
   
            printf("buf=%s\n",buf);
            n = atoi(buf);
            printf("n=%d\n",n);
        }
    }
    else
    {
   
   
        return -1;
    }
    pclose(strm);
    return n;
}
int main(int argc, char *argv[])
{
   
   
    int serial_fd = -1;
    int len = 0;
    int ret = -1;
    char *category = NULL;
    unsigned char buffer[6] = {
   
   0xAA, 0x55, 0x00, 0x00, 0X55, 0xAA};
    wiringPiSetup();
    garbage_init();
    ret = detect_process("mjpg_streamer");
    if ( -1 == ret)
    {
   
   
        printf("detect process failed\n");
        goto END;
    }
    serial_fd = myserialOpen(SERIAL_DEV, BAUD);
    if (-1 == serial_fd)
    {
   
   
        printf("open serial failed\n");
        goto END;
    }
    while(1)
    {
   
   
        len = serialGetstring(serial_fd, buffer);
        if<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

橘猫.exe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值