OrangePi Zero2 全志H616开发学习文档、基础IO蜂鸣器、超声波测距、舵机PWM基础开发

news2025/1/23 6:00:07

一.平台介绍

OrangePi开发板不仅仅是一款消费品,同时也是给任何想用技术来进行创作创新的人设计的。它是一款简单、有趣、实用的工具,你可以用它去打造你身边的世界。

在这里插入图片描述

特性

  • CPU 全志H616四核64位1.5GHz高性能Cortex-A53处理器
  • GPU MaliG31MP2 SupportsOpenGLES1.0/2.0/3.2、OpenCL2.0
  • 运行内存 1GBDDR3(与GPU共享)
  • 存储 TF卡插槽_课程配套硬件16G,测试128G可支持、2MBSPIFlash
  • WIFI+蓝牙 AW859A芯片、支持IEEE802.11a/b/g/n/ac、BT5.0
  • 视频输出 MicroHDMI20a
  • 电源 USBTypeC接口输入
  • 外设 带有I2Cx1、SPIx1、UARTx1以及多个GPIO口
  • 电源指示灯和状态指示灯

二.基于官方外设开发

2.1 wiringPi外设SDK安装

git clone https://github.com/orangepi-xunlong/wiringOP //下载源码
cd wiringOP //进入文件夹
sudo ./build clean //清除编译信息
sudo ./build //编译

通过windows浏览器打开https://github.com/orangepi-xunlong/wiringOP
下载压缩包
把压缩包通过xterm传到开发板
解压 unzip xxx.zip
cd xxx
sudo ./build
gpio readall

验证指令:gpio readall,结果如下方所示:

在这里插入图片描述

2.2基本IO口应用——蜂鸣器开发

在这里插入图片描述

  • 代码:

    #include <stdio.h>
    #include <wiringPi.h>
    #include <unistd.h>
    #define BEEP 0 //设置针脚0为蜂鸣器的控制引脚
    int main (void)
    {
        wiringPiSetup () ;//初始化wiringPi库i
    
        pinMode (BEEP, OUTPUT) ;//设置IO口的输入输出,输出
    
        while(1){
            //sleep(1);
            usleep(100000);
            digitalWrite (BEEP, HIGH) ; //设置IO口输出低电平,蜂鸣器响
            //sleep(1);
            usleep(100000);
            digitalWrite (BEEP, LOW) ; //设置IO口输出低电平,蜂鸣器响
        }
    
        return 0;
    }
    
  • 简单编译shell脚本来gcc编译函数

    ./build beep.c
    gcc $1 -lwiringPi -lwiringPiDev -lpthread -lm -lcrypt -lrt
    shell脚本处理参数,可以通过$?来处理,这里的$1是要编译的文件
    

2.3超声波测距

  • 测距原理基本说明

    超声波测距模块是用来测量距离的一种产品,通过发送和收超声波,利用时间差和声音传播速度, 计算出模块到前方障碍物的距离。

    在这里插入图片描述

  • 超声波模块HC-SR04

    !在这里插入图片描述

  • 时序

    在这里插入图片描述

  • 时间函数

    gettimeofday 是一个在 Unix 及类 Unix 系统(如 Linux)中广泛使用的系统调用,它的目的是获取当前系统的日期和时间,精确到微秒级别。这个函数允许程序获取自1970年1月1日以来的秒数(即Unix时间戳)以及额外的微秒部分。这对于需要高精度时间测量的应用特别有用,例如在性能测试、计时、实时系统或是任何需要精确时间管理的场景。

    #include <sys/time.h>
    
    int gettimeofday(struct timeval *tv, struct timezone *tz);
    //结构体:
    struct timeval
    {
        long tv_sec;/*秒*/
        long tv_usec;/*微妙*/
    };
    struct timezone
    (在某些系统中可能已弃用或不推荐使用)结构包含了时区信息,但在大多数现代应用中,传递 NULL 给 tz 参数是常见的做法,因为时区处理现在更倾向于使用其他方法,如 localtime_r 或 gmtime_r 函数配合 struct tm
  • 测试代码:

    //计算程序在当前环境中数数10万次耗时多少
    #include <sys/time.h>
    #include <stdio.h>
    //int gettimeofday(struct timeval *tv,struct timezone *tz )
    void mydelay()
    {
        int i,j;
        for(i=0;i<100;i++){
        for(j=0;j<1000;j++);
        }
    }
    
    int main()
    {
        struct timeval startTime;
        struct timeval stopTime;
    
        gettimeofday(&startTime,NULL);
        mydelay();
        gettimeofday(&stopTime,NULL);
    
        long diffTime = 1000000*(stopTime.tv_sec - startTime.tv_sec) + (stopTime.tv_usec - startTime.tv_usec);
        printf("全志H6的Linux数100000耗时%ldus\n",diffTime);
    
        return 0;
    }
    
  • 超声波测距代码

    #include <stdio.h>
    #include <sys/time.h>
    #include <wiringPi.h>
    #include <stdlib.h>
    #include <unistd.h>
    #define Trig 0
    #define Echo 1
    double getDistance()
    {
        double dis;
        struct timeval start;
        struct timeval stop;
        pinMode(Trig, OUTPUT);
        pinMode(Echo, INPUT);
        digitalWrite(Trig ,LOW);
        usleep(5);
        digitalWrite(Trig ,HIGH);
        usleep(10);
        digitalWrite(Trig ,LOW);
        /*above init CSB*/
        while(!digitalRead(Echo));
        gettimeofday(&start,NULL);
        while(digitalRead(Echo));
        gettimeofday(&stop,NULL);
        long diffTime = 1000000*(stop.tv_sec-start.tv_sec)+(stop.tv_usec -
        start.tv_usec);
        printf("diffTime = %ld\n",diffTime);
        dis = (double)diffTime/1000000 * 34000 / 2;
        return dis;
    }
    
    int main()
    {
        double dis;
        if(wiringPiSetup() == -1){
        fprintf(stderr,"%s","initWringPi error");
        exit(-1);
        }
        while(1){
        dis = getDistance();
        printf("dis = %lf\n",dis);
        usleep(500000);
        }
        return 0;
    }
    

2.4SG90舵机开发

  • 舵机基本介绍

    如下图所示,最便宜的舵机sg90,常用三根或者四根接线,黄色为PWM信号控制用处:垃圾桶项目开盖用、智能小车的全比例转向、摄像头云台、机械臂等常见的有0-90°、0-180°、0-360°。

    在这里插入图片描述

  • 角度控制

    向黄色信号线“灌入”PWM信号。

    PWM波的频率不能太高,50hz,即周期=1/频率=1/50=0.02s,20ms左右数据:不同的PWM波形对应不同的旋转角度,以20ms为周期,50hz为频率的PWM波。

    0.5ms的高电平,19.5ms的低电平,角度为0°;1ms的高电平,19ms的低电平,角度为45°;1.5ms的高电平,18.5ms的低电平,角度为90°;以此类推。

  • 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;
    };
    
    //it_interval:计时器的初始值,一般基于这个初始值来加或者来减,看控制函数的参数配置
    //it_value:程序跑到这之后,多久启动定时器
    
    struct timeval
    {
        __time_t tv_sec; /* Seconds. */
        __suseconds_t tv_usec; /* Microseconds. */
    };
    
    int setitimer (__itimer_which_t __which,
                    const struct itimerval *__restrict __new,
                    struct itimerval *__restrict __old)
    //setitimer:通过传递定时器类型(which)、指向 itimerval 结构体的指针,以及一个之前 itimerval 的地址(可选,用于获取先前的定时器设置)来调用 setitimer。
    

    setitimer 支持三种类型的间隔定时器:

    • ITIMER_REAL:这是最常用的类型,它按照实际流逝的时间来计时,即使进程处于睡眠状态也会继续计时。当定时器到期时,会给进程发送 SIGALRM 信号。
    • ITIMER_VIRTUAL:这种定时器测量的是进程在用户模式下消耗的CPU时间。当进程因为系统调用等原因进入内核模式时,该定时器会暂停计时。到期时发送 SIGVTALRM 信号。
    • ITIMER_PROF:类似于 ITIMER_VIRTUAL,但是它不仅计算用户模式下的时间,也包括内核模式下消耗的时间(即总的CPU时间)。到期时发送 SIGPROF 信号。
  • 定时示例代码

    /*该代码实现的功能是: 1s后开启定时器,然后每隔1s向终端打印hello。*/
    #include <stdio.h>
    #include <sys/time.h>
    #include <stdlib.h>
    #include <signal.h>
    static int i;
    
    void signal_handler(int signum)
    {
        i++;
        if(i == 2000){
            printf("hello\n");
            i = 0;
        }
    }
    
    int main()
    {
        struct itimerval itv;
        //设定定时时间
        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);
        return 0;
    }
    

    这种方法需要注意的是,一个进程只能创建一个定时器。

  • SG90编程实现:键盘输入不同的值,让舵机转动,软件PWM实现

    #include <stdio.h>
    #include <sys/time.h>
    Orangepi Zero2 全志H616开发学习文档 猿学社
    #include <stdlib.h>
    #include <signal.h>
    #include <wiringPi.h>
    #define SG90Pin 5
    int jd;
    static int i = 0;
    void signal_handler(int signum)
    {
        if(i <= jd){
            digitalWrite(SG90Pin, HIGH);
        }else{
            digitalWrite(SG90Pin, LOW);
        }
        if(i == 40){
            i = 0;
        }
            i++;
        }
    int main()
    {
        struct itimerval itv;
        jd = 0;
        wiringPiSetup();
        pinMode(SG90Pin, 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("input jd: 1-0 2-45 3-90 4-135 \n");
            scanf("%d",&jd);
        }
        return 0;
    }
    

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

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

相关文章

LeetCode—用栈实现队列

1.题目 2.思路—双栈 思路与双队列实现栈类似&#xff1a; 将一个栈当作输入栈&#xff0c;用于压入push传入的数据&#xff1b;另一个栈当作输出栈&#xff0c;用于pop和peek操作。 每次 pop或 peek时&#xff0c;若输出栈outStack为空则将输入栈inStack的全部数据依次出栈并…

前端笔记-day06

文章目录 01-浮动-基本使用02-浮动-产品布局03-浮动-清除浮动带来的影响04-清除浮动-额外标签法05-清除浮动-单伪元素法06-清除浮动-双伪元素法单伪元素和双伪元素CSS 07-清除浮动-overflow08-flex布局-体验09-flex布局-组成10-flex布局-主轴对齐方式11-flex布局-侧轴对齐方式1…

如何用Rust获取CPU、内存、硬盘的信息?

目录 一、用Rust获取CPU、内存、硬盘的信息 二、知识点 systemstat 一、用Rust获取CPU、内存、硬盘的信息 首先&#xff0c;需要添加systemstat库到Cargo.toml文件&#xff1a; [dependencies] systemstat "0.2.3" 在Rust代码中使用它&#xff1a; extern crat…

400元已到账,成交从认真开始

昨天发了一个值班的需求&#xff0c;收到了很多好友的响应&#xff0c;这里非常感谢关注创业程序员卡酷的老朋友、新朋友。今天分享一下&#xff1a;拓展、合作、成交 现在不管是IT行业还是其他行业&#xff0c;大环境可谓一片惨淡&#xff0c;35乃至30找不到工作的失业人员一抓…

el-table 多级表头 列添加fixed=left 列错乱

如图错乱显示 添加 this.$refs.tableList.doLayout();

Linux 操作系统多路IO复用

1.多路IO复用 多路I/O复用是通过一种机制&#xff0c;可以监视多个描述符&#xff0c;一旦某个描述符就绪&#xff08;一般是读就绪或者写就绪&#xff09;&#xff0c;能够通知程序进行相应的读写操作。 这个机制能够通过select/poll/eroll等来使用。这些函数都可以同时监视多…

答辩PPT框架如何搭建?文心一言AI辅助构建

很多快要毕业的同学在做答辩PPT的时候总是感觉毫无思路&#xff0c;一窍不通。但这并不是你们的错&#xff0c;对于平时没接触过相关方面&#xff0c;第一次搞答辩PPT的人来说&#xff0c;这是很正常的一件事。一个好的答辩PPT可以根据以下分为以下几部分来写。 1.研究的背景和…

数据可视化(九):Pandas北京租房数据分析——房源特征绘图、箱线图、动态可视化等高级操作

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

数据可视化(十一):Pandas餐饮信息表分析——交叉表、离群点分析,多维分析等高级操作

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

简述RocketMQ系统架构及其相关概念

一、概述 RocketMQ是一款高性能、高吞吐量的分布式消息队列系统&#xff0c;它采用了分布式架构&#xff0c;支持多生产者和消费者并发读写&#xff0c;具有高可用性、高吞吐量、低延迟等特点。本文将对RocketMQ的系统架构进行详细解析。 二、架构设计 RocketMQ采用了分布式架…

AI如何改变PPT制作流程?推荐四款ai生成ppt工具

提起PPT&#xff0c;大家的第一反应就是痛苦。经常接触PPT的学生党和打工人&#xff0c;光看到这3个字母&#xff0c;就已经开始头痛了&#xff1a; 1、PPT内容框架与文案挑战重重&#xff0c;任务艰巨&#xff0c;耗费大量精力。 2、PPT的排版技能要求高&#xff0c;并非易事…

ATA-4315高压功率放大器在高频理疗仪驱动中的应用

现代社会&#xff0c;面对生活压力、工作压力&#xff0c;再加上不良的生活习惯&#xff0c;难免身体会出现这样或那样的问题&#xff0c;随着科技的发展&#xff0c;我们除了来到医院进行具体的治疗&#xff0c;一些可以用来辅助医生进行治疗的仪器设备也越来越多的应用到了临…

JavaScript 对象入门:基础用法全解析

目录 对象 语法 属性和访问 方法和调用 this关键字 null 遍历对象 内置对象 Math 属性 方法 Date 创建日期对象 获取和设置日期 ⭐对象 对象是 JavaScript 数据类型的一种&#xff0c;数据类型也包括数值类型、字符串类型、布尔类型、undefined。对象数据类型可…

Apache访问控制与虚拟主机

目录 一. Web服务简介 以下是一些 Web 服务的基本概念和特征 以下是一些主流的 Web 服务器 WEB 服务协议 二. Apache 服务的搭建与配置 2.1 Apache 介绍 2.2 Apache安装 2.3 Apache目录介绍 三. 访问控制 四. 修改默认网站发布目录 五. 虚拟主机 5.1 基于域名的虚拟…

Java入门——继承和多态(下)

抽象类 语法规则 在上一篇文章刚才的打印图形例子中, 我们发现, 父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由 Shape 的各种子类的 draw 方法来完成的. 像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法 包含抽象方法的类我们称为 抽象…

试试这四款高效AI论文写作工具和降重技术

在科研领域&#xff0c;AI写作工具如同新一代的科研利器&#xff0c;它们能够极大提高文献查阅、思路整理和表达优化的效率&#xff0c;本质上促进了科研工作的进步。AI写作工具不仅快速获取并整理海量信息&#xff0c;还帮助我们精确提炼中心思想&#xff0c;显著提升论文写作…

花趣短视频源码淘宝客系统全开源版带直播带货带自营商城流量主小游戏功能介绍

1、首页仿抖音短视频 &#xff0c;关注 &#xff0c;我的 本地 直播 可发布短视频 可录制上传 2、商城页面 广告位、淘口令识别、微信登录、淘宝登录、淘宝返佣、拼多多返佣、京东返佣、唯品会返佣、热销榜、聚划算、天猫超市、9.9包邮、品牌特卖、新人攻略 、小米有品、优惠加…

【JavaEE网络】HTTPS详解:从对称与非对称加密到证书认证

目录 HTTPSHTTPS 是什么“加密” 是什么HTTTPS 的工作过程引入对称加密引入非对称加密引入证书完整流程总结 HTTPS HTTPS 是什么 HTTPS 也是一个应用层协议. 是在 HTTP 协议的基础上引入了一个加密层. HTTP 协议内容都是按照文本的方式明文传输的. 这就导致在传输过程中出现…

openGemini v1.2.0版本正式发布,IoT 场景性能大幅提升!

在openGemini v1.2.0版本中&#xff0c;我们为您带来了一系列令人振奋的内核优化&#xff0c;将您的体验提升到新的高度&#xff0c;这包括 针对IoT场景的性能优化&#xff0c;查询效率有极大的提升。针对数据存储的优化&#xff0c;进一步节约磁盘空间&#xff0c;降低数据存…

MySQL基础指南:从入门到精通

MySQL基础指南&#xff1a;从入门到精通 MySQL是一个流行的开源关系型数据库管理系统&#xff0c;被广泛用于Web应用程序和服务器端开发。本文将从MySQL的基本概念开始&#xff0c;逐步介绍MySQL的安装、常用操作、数据类型、查询语句等内容&#xff0c;帮助你快速入门MySQL数…