Orangepi Zero2使用外设驱动库wiringOP配合定时器驱动SG90舵机

news2024/11/26 9:58:23

目录

一、舵机的基本认知和硬件接线

1.1 舵机的基本认知:

1.2 硬件接线:

1.3 怎么控制舵机旋转不同的角度:

二、Linux定时器

2.1 定时器setitimer()函数原型和头文件:

2.2 信号处理函数signal()原型和头文件:

2.3 定时器setitimer()函数应用实例:

2.4 使用wiringOP库配合定时器驱动舵机旋转0-180°:


一、舵机的基本认知和硬件接线

1.1 舵机的基本认知:

如下图所示:是一个SG90舵机,常用三根或者四根接线,红色为电源VCC棕色为电源GND黄色为PWM信号

控制用处:垃圾桶项目开盖用、智能小车的全比例转向、摄像头云台、机械臂等常见的有0-90°、0-180°、0-360°

1.2 硬件接线:

1.3 怎么控制舵机旋转不同的角度:

  • 向黄色信号线“灌入”PWM信号PWM波的频率不能太高,50hz,即周期=1/频率=1/50=0.02s20ms左右数据:不同的PWM波形对应不同的旋转角度,以20ms为周期,50hz为频率的PWM波

定时器需要定时20ms,关心的单位0.5ms, 20ms = 0.5ms * 40

二、Linux定时器

2.1 定时器setitimer()函数原型和头文件:

/*	setitimer 是一个UNIX系统上的系统调用函数,用于设置和管理定时器。它通常用于定期触发信号或执行某些操作	*/
#include <sys/time.h>

int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);

int 		函数返回值,成功执行时返回0,失败返回-1
    
int whic	指定要设置的定时器类型,可以是 ITIMER_REAL、ITIMER_VIRTUAL 或 ITIMER_PROF 中的一个
1. ITIMER_REAL 		//数值为0,计时器的值实时递减,发送的信号是SIGALRM。
2. ITIMER_VIRTUAL 	//数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM。
3. ITIMER_PROF 		//数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF。
    
struct itimerval *new_value		一个struct itimerval结构,用于指定新的定时器值。struct itimerval 结构定义如下:
    
struct itimerval {
        struct timeval it_interval;  // 定时器重复的间隔时间
        struct timeval it_value;     // 定时器的初始值
};

it_interval		计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置
it_value		程序跑到这之后,多久启动定时器
    
struct timeval {  
        __time_t      tv_sec;   /* 秒 */  
        __suseconds_t tv_usec;  /* 微秒 */  
};

struct itimerval *old_value		一个struct itimerval 结构,用于存储旧的定时器值(可选参数)
    
/*
函数说明:
实现定时器,通过itimerval结构体以及函数setitimer产生的信号,系统随之使用signal信号处理函数来处理产生的定时信号。从而实现定时器。
*/

2.2 信号处理函数signal()原型和头文件:

/*
	Linux下 man 2 signal查看手册
*/
#include <signal.h>
 
typedef void (*sighandler_t)(int);
 
sighandler_t signal(int signum, sighandler_t handler);
 
sighandler_t			函数返回值,返回信号处理程序的前一个值,或者在错误时SIG ERR。如果发生错误,则设置errno来指示原因。
 
int signum				指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号
 
sighandler_t handler	描述了与信号关联的动作,它可以取以下三种值:  
    
1. 一个无返回值的函数地址
此函数必须在signal()被调用前声明,handler中为这个函数的名字。当接收到一个类型为signum的信号时,就执行handler 所指定的函数。这个函数应有如下形式的定义:
void handler(int signum);
 
2. SIG_IGN
这个符号表示忽略该信号,执行了相应的signal()调用后,进程会忽略类型为sig的信号。
    
3. SIG_DFL
这个符号表示恢复系统对信号的默认处理。

2.3 定时器setitimer()函数应用实例:

实现的功能是:1秒后打开定时器,然后每隔一秒打印一次Hello

#include <stdio.h>          // 包含标准输入输出库,用于输入输出操作
#include <sys/time.h>       // 包含时间处理库,用于获取系统时间
#include <stdlib.h>         // 包含标准库,用于内存分配和程序终止等操作
#include <signal.h>         // 包含信号处理库,用于处理系统信号

static int i = 0;                                                                               //全局变量i 

void signal_handler(int signum)                                                             //信号处理函数
{
    i++;
    if(i == 2000){                                                                             //每2000次触发一次
        printf("Hello\n");
        i = 0;
    }
}

int main()
{
    struct itimerval itv;                                               		//定义一个itimerval结构体变量

    //设定定时时间
    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = 500;                                                     //每隔0.5毫秒触发一次 
    //设定启动定时器时间
    itv.it_value.tv_sec = 1;                                                             //启动定时器1秒后触发    
    itv.it_value.tv_usec = 0;               
    //设定定时方式
    //int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
    if(setitimer(ITIMER_REAL, &itv, NULL) == -1){                                        //设置定时器  
        perror("setitimer");
        exit(-1);
    }
    //信号处理
    signal( SIGALRM, signal_handler);                                                     //设置信号处理函数

    while(1);
    
    return 0;
}

2.4 使用wiringOP库配合定时器驱动舵机旋转0-180°:

#include <stdio.h>          // 包含标准输入输出库,用于输入输出操作
#include <sys/time.h>       // 包含时间处理库,用于获取系统时间
#include <stdlib.h>         // 包含标准库,用于内存分配和程序终止等操作
#include <signal.h>         // 包含信号处理库,用于处理系统信号
#include <wiringPi.h>       // 包含WiringPi库,用于控制GPIO

#define SG90Pin 5           // 定义SG90的引脚号

static int i = 0;                                                        	//全局变量i 
int jd;                                                                   	//全局变量jd 

void signal_handler(int signum)                                            	//信号处理函数
{
    if(i <= jd){
        digitalWrite(SG90Pin, HIGH);                        				//设置SG90引脚为高电平
    }else{
        digitalWrite(SG90Pin, LOW);                          				//设置SG90引脚为低电平
    }
    if(i == 40){                                                    //每40次信号处理函数被调用一次,输出一次当前时间
        i = 0;                                              				//i归零
    }
    i++;
}

int main()
{
    struct itimerval itv;                                                  	//定义一个itimerval结构体变量
    jd = 0;                                                                 //初始化jd为0    
    wiringPiSetup();                                                     	//初始化WiringPi库
    pinMode(SG90Pin, OUTPUT);                                             	//设置SG90引脚为输出模式

    //设定定时时间
    itv.it_interval.tv_sec = 0;
    itv.it_interval.tv_usec = 500;                                         	//每隔0.5毫秒触发一次 
    //设定启动定时器时间
    itv.it_value.tv_sec = 1;                                          		//启动定时器1秒后触发    
    itv.it_value.tv_usec = 0;               
    //设定定时方式
    //int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
    if(setitimer(ITIMER_REAL, &itv, NULL) == -1){                      		//设置定时器  
        perror("setitimer");
        exit(-1);
    }
    //信号处理
    signal( SIGALRM, signal_handler);                                      	//设置信号处理函数

    while(1){
        printf("请输入你想要的角度: 1-0 2-45 3-90 4-135 5-180\n");
        scanf("%d",&jd);                                                 	 //输入角度   
    }
    
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1878921.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

thymeleaf+mybatis(本文章用于期末考前10分钟速看)

期末速看 pom&#xff08;了解&#xff09;application.propertiessql代码Controller控制层视图service&#xff1a; 服务层mapper&#xff08;dao&#xff09;&#xff1a;持久层entity层(model层&#xff0c;domain层、 bean)&#xff1a;对应数据库表&#xff0c;实体类 效果…

【C语言】指针剖析(2)

©作者:末央&#xff06; ©系列:C语言初阶(适合小白入门) ©说明:以凡人之笔墨&#xff0c;书写未来之大梦 目录 一、数组名1.概念2.sizeof和&里面的数组名sizeof& 二、使用指针访问数组三、一维数组传参本质四、指针数组1.概念实例&#xff08;模拟二维数…

【GitOps】使用Google工具JIB实现本地无需安装容器推送镜像,加速SpringCloud项目开发

文章目录 一、效果展示二、简介三、安装Jib插件1、区分环境2、安装插件一、效果展示 本地是window系统,无docker环境,没有任何runtime,使用jib工具打包镜像并推送完成,用时20秒 二、简介 Jib 是 Google 开发的一款开源工具,旨在帮助 Java 开发者更高效地将 Java 应用程…

25届近5年北京交通大学自动化考研院校分析

北京交通大学 目录 一、学校学院专业简介 二、考试科目指定教材 三、近5年考研分数情况 四、近5年招生录取情况 五、最新一年分数段图表 六、初试大纲复试大纲 七、学费&奖学金&就业方向 一、学校学院专业简介 二、考试科目指定教材 1、考试科目介绍 2、指定教…

vue使用scrollreveal和animejs实现页面滑动到指定位置后再开始执行动画效果

效果图 效果链接&#xff1a;http://website.livequeen.top 介绍 一、Scrollreveal ScrollReveal 是一个 JavaScript 库&#xff0c;用于在元素进入/离开视口时轻松实现动画效果。 ScrollReveal 官网链接&#xff1a;ScrollReveal 二、animejs animejs是一个好用的动画库…

LabVIEW电压电流实时监测系统

开发了一种基于LabVIEW和研华&#xff08;Advantech&#xff09;数据采集卡的电压电流实时监测系统&#xff0c;通过高效的数据采集和处理&#xff0c;为工业和科研用户提供高精度、实时的电压电流监测解决方案。系统采用研华USB-4711A数据采集卡&#xff0c;结合LabVIEW编程环…

【自然资源】国家历史文化名城你知道多少?

【自然资源】国家历史文化名城你知道多少&#xff1f; 中国五千年的历史孕育出了一些因深厚的文化底蕴和发生过重大历史事件而青史留名的城市。根据《中华人民共和国文物保护法》&#xff0c;“历史文化名城”是指保存文物特别丰富&#xff0c;具有重大历史文化价值和革命意义…

数据恢复篇: 如何在数据丢失后恢复照片

数据丢失的情况并不少见。如果您曾经遇到过图像丢失的情况&#xff0c;您可能想过照片恢复工具是如何工作的&#xff1f;可能会丢失多少数据图像&#xff1f;即使是断电也可能导致照片和媒体文件丢失。 话虽如此&#xff0c;如果你认为删除的照片无法恢复&#xff0c;那你就错…

sheng的学习笔记-hadoop,MapReduce,yarn,hdfs框架原理

目录 搭建hadoop 下载hadoop JAVA 下载bin windows 改环境变量 将winutils.exe和hadoop.dll放到C:\Windows\System32下&#xff0c;然后重启 修改配置 vim core-site.xml vim hdfs-site.xml hadoop-env.sh mapred-site.xml yarn-site.xml 格式化命令 启动集群 …

大数据可视化实验(七):Python数据可视化

目录 一、实验目的... 1 二、实验环境... 1 三、实验内容... 1 1&#xff09;绘制带颜色的柱状图。.. 1 2&#xff09;绘制堆叠柱状图。.. 3 3&#xff09;绘制数学函数曲线图。.. 4 4&#xff09;使用seaborn绘制组合图形。... 5 5&#xff09;使用Boken绘制多个三角形…

区块链技术与数字货币

1.起源 ➢中本聪(Satoshi Nakamoto), 2008 ➢比特币:一种点对点的电子现金系统 2.分布式账本技术原理 1.两个核心技术&#xff1a; ➢以链式区块组织账本数据实现账本数据的不可篡改 ➢分布式的可信记账机制 2.共识机制&#xff1a;由谁记账 ➢目的&#xff1a; ⚫ 解…

数据可视化期末总结

期末考试重点&#xff08;世界上最没意义的事情&#xff09; 选择 p8 数据可视化的标准&#xff1a; 实用、完整、真实、艺术、交互&#xff08;性&#xff09; p21 色彩三属性 色相、饱和度、亮度 p23 视觉通道的类型&#xff1a; 记得色调是定性 p39 散点图&#xff08;二维…

检查显卡驱动和cuda版本的对应关系并下载

1. CUDA 12.5 Release Notes — Release Notes 12.5 documentation Official Drivers | NVIDIA&#xff08;驱动下载&#xff09;搜索结果 | GeForce RTX 3090 | Linux 64-bit | NVIDIA nvidia-smi &#xff08;查看cuda&#xff09; pipx run nvitop nvcc -V https://deve…

飞书API 2-3:如何使用 API 创建数据表,解放人工?

一、引入 作为飞书多维表的深度使用者&#xff0c;经常需要将一些数据库的数据同步到多维表上&#xff0c;在数据写入之前&#xff0c;一般需要新建数据表和字段。当通过网页端界面新建字段时&#xff0c;如果字段少&#xff0c;还能接受手动一个个创建&#xff0c;不过一旦字…

win11 内存占用过大优化尝试

关闭开机加速 wins打开搜索 控制面板&#xff0c;打开控制面板 找到硬件和声音-电源选项-选择电源按钮的功能-去掉勾选启用快速启动 关闭windows 更新 winr 输入services.msc打开服务-搜索windows 更新-双击打开设置-选择禁用 貌似没什么用。

【C++ | 委托构造函数】委托构造函数 详解 及 例子源码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

TypeScript学习笔记(全)

文章目录 TypeScript入门2.编译并运行TS代码2.1.简化运行ts步骤 3.TS中的常用类型3.1.TS中的类型注解3.2.TS中的原始类型3.3.TS中的数组类型3.4.TS中的联合类型3.5.类型别名3.6.函数类型3.6.1.单独执行参数、返回值类型3.6.2.同时指定参数&#xff0c;返回值类型3.6.3.函数的vo…

【C++开发必备工具】Dependency Walker与Dependencies

Dependency Walker 与 Dependencies 1. Dependency Walker1.1 功能特点1.2 使用方法1.3 注意事项 2. Dependencies2.1 功能特点2.2 使用方法2.3 注意事项 3. 总结 1. Dependency Walker Dependency Walker 是一个免费软件工具&#xff0c;用于查看 Windows 应用程序的模块&…

el-tree结构清空选中节点

<el-tree:data"data"show-checkboxdefault-expand-allnode-key"id"ref"tree"highlight-current:props"defaultProps"> </el-tree>this.$refs.tree.setCheckedKeys(this.$refs.tree.getCheckedNodes(),false);

【单片机毕业设计选题24037】-基于STM32的电力系统电力参数无线监控系统

系统功能: 系统上电后&#xff0c;OLED显示“欢迎使用电力监控系统请稍后”&#xff0c;两秒后显示“Waiting..”等待ESP8266初始化完成&#xff0c; ESP8266初始化成功后进入正常页面显示&#xff0c; 第一行显示电压值&#xff08;单位V&#xff09; 第二行显示电流值&am…