香橙派使用外设驱动库wiringOP 配合定时器来驱动舵机
舵机认识和硬件接线
关于舵机也是使用过很多次了,详见:
使用PWM波控制开发SG90-CSDN博客
同时再次回顾香橙派的物理引脚对应:
所以舵机的VCC接 2,GND接 6,PWM接 7(此处写的是物理引脚编号)
Linux定时器
驱动舵机必不可少的就是生成PWM波,上节超声波测距的时间计算学习了Linux自带的时间函数,本节生成PWM就正式学习香橙派的定时器,用定时器来生成PWM波!
由于香橙派跑的系统就是Linux,所以其实就是使用Linux来实现定时器,根据舵机的原理,一般使用50Hz频率(周期为20ms)的PWM波来控制,而角度的大小就取决于高电平的占比,20ms中有0.5ms,1.0ms,1.5ms,2.0ms,2.5ms的高电平就分别对应舵机转0度,45度,90度,135度,180度。所以本质上,只要能实现出一个定时0.5ms(500us)的定时器,并让他定时1次,2次,3次,4次,5次就可以实现所有的角度。
Linux定时器的实现,是通过 itimerval 结构体以及函数 setitimer 产生的信号,系统随之使用signal信号处理函数 来处理产生的定时信号,从而实现定时器。
itimerval结构体
struct itimerval
{
/* Value to put into `it_value' when the timer expires. */struct timeval it_interval;
/* Time to the next timer expiration. */struct timeval it_value;
};struct timeval
{__time_t tv_sec; /* Seconds. */__suseconds_t tv_usec; /* Microseconds. */
};
可见,itimerval结构体中有两个成员,这两个成员都属于timeval结构体,timeval结构体上节课接触过,有两个分别代表秒和微秒的成员。
- it_interval:计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置
- it_value:程序跑到这之后,多久启动定时器
setitimer函数
setitimer()将value指向的结构体设为计时器的当前值,如果ovalue不是NULL,将返回计时器原有值
#include <sys/time.h>int setitimer (__itimer_which_t __which, const struct itimerval *__restrict __new, struct itimerval *__restrict __old)
- which:控制的方法,有以下三种类型
- ITIMER_REAL //数值为0,计时器的值实时递减,发送的信号是SIGALRM
- ITIMER_VIRTUAL //数值为1,进程执行时递减计时器的值,发送的信号是SIGVTALRM
- ITIMER_PROF //数值为2,进程和系统执行时都递减计时器的值,发送的信号是SIGPROF
- new:指向 itimerval 结构体的指针
- old: 一般不用,设置为NULL
- 返回值:成功返回0,失败返回-1
signal函数
之前在系统编程部分学过,详见:
信号-CSDN博客
#include <signal.h>typedef void (*sighandler_t)(int); //一个指向“传入参数是int 返回值是void的函数”,名为“sighandler_t”的指针sighandler_t signal(int signum, sighandler_t handler);
- signum:信号编号
- handler:函数指针,指向信号处理函数;也可以使用宏,比如使用“SIG_IGN”,则忽略信号
这种方法需要注意的是,一个进程只能创建一个定时器!
代码验证
timer_test.c:
/*该代码实现的功能是: 1s后开启定时器,然后每隔1s向终端打印hello。*/#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>static int i;void signal_handler(int signum)
{i++;if(i == 2000){ //计时2000*500 = 1000000us = 1sprintf("hello\n");i = 0;}
}int main()
{struct itimerval itv;//设定定时时间为500usitv.it_interval.tv_sec = 0;itv.it_interval.tv_usec = 500;//设定开始生效,启动定时器的时间为1秒后itv.it_value.tv_sec = 1;itv.it_value.tv_usec = 0;//设定定时方式if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){perror("timer");exit(-1);}//信号处理signal(SIGALRM,signal_handler);while(1); //防止程序退出return 0;
}
代码编写
SG90_test.c:
#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <stdlib.h>
#include <wiringPi.h>#define PWM 2int angle;
static int i;void signal_handler(int signum)
{if(i <= angle){digitalWrite(PWM, HIGH);}else{digitalWrite(PWM, LOW);}if(i == 40){ //40*500 = 20000us = 20msi = 0;}i++;}int main()
{struct itimerval itv;wiringPiSetup () ;pinMode (PWM, OUTPUT);//设定定时时间itv.it_interval.tv_sec = 0;itv.it_interval.tv_usec = 500;//设定开始生效,启动定时器的时间itv.it_value.tv_sec = 1;itv.it_value.tv_usec = 0;//设定定时方式if( -1 == setitimer(ITIMER_REAL, &itv, NULL)){perror("error");exit(-1);}//信号处理signal(SIGALRM,signal_handler);while(1){printf("enter the angle: 1 -> 0; 2 -> 45; 3 -> 90; 4 -> 135; 5 -> 180\n");scanf("%d",&angle);i = 0;}return 0;
实现效果:
在Linux界面输入角度值,舵机就会相应的转动多少度:
(缠黑纱绑带的一段视为方向指示端)
相关文章:

香橙派使用外设驱动库wiringOP 配合定时器来驱动舵机
舵机认识和硬件接线 关于舵机也是使用过很多次了,详见: 使用PWM波控制开发SG90-CSDN博客 同时再次回顾香橙派的物理引脚对应: 所以舵机的VCC接 2,GND接 6,PWM接 7(此处写的是物理引脚编号) Li…...

C++学习笔记--函数重载(2)
文章目录 1.3、Function Templates Handling1.3.1、Template Argument Deduction1.3.2、Template Argument Substitution 1.4、Overload Resolution1.4.1、Candidate functions1.4.2、Viable functions1.4.3、Tiebreakers 1.5、走一遍完整的流程1.6、Name Mangling1.7、总结 1.…...
代码随想录算法训练营Day56 || ● 583. 两个字符串的删除操作 ● 72. 编辑距离
今天接触到了真正的距离,但可以通过增删改操作来逼近。 问题1:583. 两个字符串的删除操作 - 力扣(LeetCode) 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字…...

chrome_elf.dll丢失怎么办?修复chrome_elf.dll文件的方法
Chrome是目前最受欢迎的网络浏览器之一,然而有时用户可能会遇到Chrome_elf.dll丢失的问题。该DLL文件是Chrome浏览器的一个重要组成部分,负责启动和管理程序的各种功能。当Chrome_elf.dll丢失时,用户可能无法正常启动Chrome或执行某些功能。本…...
代码随想录32|738.单调递增的数字,968.监控二叉树,56. 合并区间
738.单调递增的数字 链接地址 class Solution { public:int monotoneIncreasingDigits(int n) {string str to_string(n);int flag str.size();for (int i str.size() - 1; i > 0; i--) {if (str[i] < str[i - 1]) {str[i - 1] - 1;flag i;}}for (int j flag; j <…...

BIO NIO AIO演变
Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能、高可靠的网络服务器和客户端程序。Netty简化了网络程序的开发,是很多框架和公司都在使用的技术。 Netty并非横空出世,它是在BIO,NIO,AIO演变中的产物…...

JVM GC垃圾回收
一、GC垃圾回收算法 标记-清除算法 算法分为“标记”和“清除”阶段:标记存活的对象, 统一回收所有未被标记的对象(一般选择这种);也可以反过来,标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象 。它…...

【数据结构】队列知识点总结--定义;基本操作;队列的顺序实现;链式存储;双端队列;循环队列
欢迎各位看官^_^ 目录 1.队列的定义 2.队列的基本操作 2.1初始化队列 2.2判断队列是否为空 2.3判断队列是否已满 2.4入队 2.5出队 2.6完整代码 3.队列的顺序实现 4.队列的链式存储 5.双端队列 6.循环队列 1.队列的定义 队列(Queue)是一种先…...

嵌入式学习之链表
对于链表,要重点掌握链表和数组区别和实现,链表静态添加和动态遍历,链表中pointpoint-next,链表节点个数的查找,以及链表从指定节点后方插入新节点的知识。...

静态代理和动态代理笔记
总体分为: 1.静态代理: 代理类和被代理类需要实现同一个接口.在代理类中初始化被代理类对象.在代理类的方法中调 用被代理类的方法.可以选择性的在该方法执行前后增加功能或者控制访问 2.动态代理: 在程序执行过程中,实用JDK的反射机制,创建代理对象,并动态的指定要…...
[SM6225][Android13]user版本默认允许root和remount
开发平台基本信息 芯片: 高通SM6225版本: Android 13kernel: msm-5.15 问题描述 刚刚从Framework踏入性能的小殿堂,User版本默认是不会开启root权限的,而且一般调试需要设置一下CPU GPU DDR performance模式或者修改一些schedule util等调核调频节点去…...
pyinstaller打包exe,使用wexpect的问题
参考github首先打包wexpect 1.进入wexpect目录执行 pyinstaller __main__.py -n wexpect 会生成dist文件夹 2.python代码A.py中使用wexpect,注意wexpect.spawn前后必须按照下面添加代码 import sys,os,wexpect #spawn前 real_executable sys.executable try:if sy…...

OpenCV(三十三):计算轮廓面积与轮廓长度
1.介绍轮廓面积与轮廓长度 轮廓面积(Contour Area)是指轮廓所包围的区域的总面积。通常情况下,轮廓面积的单位是像素的平方。 轮廓长度(Contour Length)又称周长(Perimeter),表示轮廓…...

9.11作业
实现一个对数组求和的函数,数组通过实参传递给函数 sum0 arr(11 22 33 44 55) Sum() {for i in ${arr[*]}do$((sumi))donereturn $sum } Sum ${arr[*]} var$? echo $var写一个函数,输出当前用户的uid和gid,并使用变量接收结果 Sum() {aid -…...
AI伦理与未来社会:探讨人工智能的道德挑战与机会
引言 引出AI伦理和社会影响的主题,强调AI的快速发展和广泛应用。 概述博客的主要内容:探讨AI的伦理挑战以及它对社会的影响。 第一部分:AI的伦理挑战 算法偏见: 解释什么是算法偏见,以及它为何在AI中成为一个重要问题。…...

Android窗口层级(Window Type)分析
前言 Android的窗口Window分为三种类型: 应用Window,比如Activity、Dialog;子Window,比如PopupWindow;系统Window,比如Toast、系统状态栏、导航栏等等。 应用Window的Z-Ordered最低,就是在系…...

微信小程序基础加强总结
本篇文章给大家带来了关于微信小程序的相关问题,其中主要介绍了一些基础内容,包括了自定义组件、样式隔离、数据、方法和属性等等内容,下面一起来看一下,希望对大家有帮助。 1、自定义组件 1.1、创建组件 在项目的根目录中&…...

【JAVA - List】差集removeAll() 四种方法实现与优化
一、场景: 二、结论: 1. 四种方法耗时 三、代码: 一、场景: 求差集 List1 - Lsit2 二、结论: 1. 四种方法耗时 初始条件方法名方法思路耗时 List1.size319418 List2.size284900 List..removeAll(Lsit2)1036987ms…...

sql注入基本概念
死在山野的风里,活在自由的梦里 sql注入基本概念 MYSQL基本语法union合并查询2个特性:order by 排序三个重要的信息 Sql Server MYSQL 基本语法 登录 mysql -h ip -u user -p pass基本操作 show databases; 查看数据库crea…...
AIGC系列:1.chatgpt可以用来做哪些事情?
上图的意思:神器轩辕剑 那么,在现在AI盛行的信息时代, 你是否知道如何获得和利用ChatGPT这一把轩辕剑来提升你的攻击力和生存能力呢? 故事 程序员小张: 刚毕业,参加工作1年左右,日常工作是C…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
AI编程--插件对比分析:CodeRider、GitHub Copilot及其他
AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

FFmpeg avformat_open_input函数分析
函数内部的总体流程如下: avformat_open_input 精简后的代码如下: int avformat_open_input(AVFormatContext **ps, const char *filename,ff_const59 AVInputFormat *fmt, AVDictionary **options) {AVFormatContext *s *ps;int i, ret 0;AVDictio…...
深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙
WebGL:在浏览器中解锁3D世界的魔法钥匙 引言:网页的边界正在消失 在数字化浪潮的推动下,网页早已不再是静态信息的展示窗口。如今,我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室,甚至沉浸式的V…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架
1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...