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

一.平台介绍

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;
    }
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【树】简要理解树的概念

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 目录 1、树的概念2、树的相关概念3、结语 1、树的概念 树是一种非线性的数据结构&#xff0c;它…

[FSCTF 2023]ez_php1

一共有三小关 第一关&#xff1a;md5加密 第二关&#xff1a;反序列化 重点 单个字符串序列化 unserialize($str) "$KEY" <?php $KEY"YES I love";echo serialize($KEY); s:10:"YES I love"; 第三关&#xff1a; 反序列化 把a的地址赋给…

【SpringBoot】 什么是springboot(二)?springboot操作mybatisPlus、swagger、thymeleaf模板

文章目录 SpringBoot第三章1、整合mybatsPlus1-234-67-10问题 2、整合pageHelper分页3、MP代码生成器1、编写yml文件2、导入依赖3、创建mp代码生成器4、生成代码5、编写配置类扫描mapper类6、编写控制器类 4、swagger1、什么是swagger2、作用3、发展历程4、一个简单的swagger项…

Hexo博客重新部署与Git配置

由于电脑重装了一次&#xff0c;发现之前Hexo与NexT主题版本过于落后&#xff0c;重新部署了下。 1 Node.js与git安装 这一块安装就不赘述了。去两个官网找安装文件安装即可。 node.js git 打开git以后配置的几个关键命令行。 git config --global user.name "你的gi…

ArcGIS水文水环境数据编辑、管理、处理与分析;ArcGIS水文分析及流域特征提取;湖泊水库水环境监测及评价;河道水污染预测与水环境容量计算等案例实践

目录 专题一 ArcGIS&#xff1a;数据管理 专题二 ArcGIS&#xff1a;数据转换 专题三 ArcGIS&#xff1a;地图制作 专题四 水文水环境数据编辑与管理 专题五 水文水环境数据处理与分析 专题六 ArcGIS水文分析及流域特征提取 专题七 湖泊水库水环境监测及评价 专题八 河…

java学习之zip炸弹攻击

一、概述 Zip炸弹是一种特殊类型的Zip文件&#xff0c;它包含了大量的无用数据。Zip文件格式允许使用压缩算法来减小文件的大小&#xff0c;但是如果Zip文件中的某些内容被重复压缩&#xff0c;就会导致文件大小急剧增加。Zip炸弹利用这个特性&#xff0c;将一些无用的数据多次…

配置接口的主从IP地址

组网需求 如图1所示&#xff0c;Router上只有一个空闲接口GE1/0/0&#xff0c;但该局域网中的计算机分别属于2个不同的网段10.16.1.0/24和10.16.2.0/24&#xff0c;要求通过Router可以实现一个接口接入两个不同的网段。 图1 配置IP地址示例 配置思路 配置主从IP地址的思路…

【C++】STL-list的使用

目录 1、list的使用 1.1 list的构造 1.2 list的遍历 1.3 list capacity 1.4 list element access 1.5 容量相关 list是一个带头双向循环链表 1、list的使用 1.1 list的构造 1.2 list的遍历 list只有两种遍历方式&#xff0c;因为没有operator[] 因为list的双向链表&am…

Docker复习

文章目录 基础Docker基础命令镜像操作命令容器操作命令 案例:安装MySql案例:查看DockerHub&#xff0c;拉取Nginx镜像&#xff0c;并运行容器 基础 Docker基础命令 启动Docker systemctl start docker镜像操作命令 从远程仓具下载镜像到本地 docker pull 镜像名称 无版本号…

高并发系统设计-系统的“三高“目标

目录 一、高并发 1.高并发相关指标 2.如何提高并发能力 二、高并发的目标 1.高性能 2.高可用 3.高扩展 一、高并发 高并发&#xff08;High Concurrency&#xff09;是互联网分布式系统架构设计中必须考虑的因素之一&#xff0c;它通常是指&#xff0c;通过设计保证系统能…

parallelsdesktop19密钥激活 PD19虚拟机完整图文安装教程

Parallels Desktop 19 &#xff08;简称 PD 19)是最新发布的 macOS 平台的 windows 虚拟机&#xff0c;本文是使用 Parallels Desktop 19 虚拟机安装 Windows 的详细图文破解安装教程。 一下载安装 Parallels Desktop 软件下载完成后打开&#xff0c;双击打开 安装.dmg Para…

1070: 邻接矩阵存储简单路径

解法&#xff1a; #include<iostream> #include<vector> using namespace std; int arr[100][100]; int n; int sta, des; vector<int> path; vector<vector<int>> res; void dfs(vector<int> &a,int i) {a[i] 1;path.push_back(i);…

【漏洞复现】osCommerce install.php存在远程代码执行漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

第5章 处理GET请求参数

1 什么是GET请求参数 表单GET请求参数是指在HTML表单中通过GET方法提交表单数据时所附带的参数信息。在HTML表单中&#xff0c;可以通过表单元素的name属性来指定表单字段的名称&#xff0c;通过表单元素的value属性来指定表单字段的值。当用户提交表单时&#xff0c;浏览器会将…

C# WinForm —— 16 MonthCalendar 介绍

1. 简介 可以选择单个日期&#xff0c;也可以选择一段日期&#xff0c;在选择时间范围上 比较适用&#xff0c;但不能跨月份选择日期范围 在直观上&#xff0c;可以快速查看、选择日期/日期范围 2. 常用属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到,一般…

邮箱API发送邮件调试的方法?有哪些限制?

邮箱API发送邮件调试的好处&#xff1f;如何正确调试邮箱API&#xff1f; 使用邮箱API发送邮件是一个常见的需求。然而&#xff0c;当遇到发送失败、内容错误或格式问题时&#xff0c;如何进行有效的调试就显得尤为重要。本文将为您介绍一些邮箱API发送邮件调试的方法&#xf…

Leetcode-有效的括号

20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/valid-parentheses/ 题目 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&…

MySql软件安装

1.打开mysql官网网址 MySQL :: Download MySQL Community Server 2.本次针对版本8的图形化界面安装&#xff0c;下载成功后接下来对MySQL进行安装 3.图形化下载后有一个MSI文件 4.我们安装典型即可&#xff0c;选择第一个 5.选择数据库信息存放的路径&#xff0c;我默认放在C盘…

Redis继续(黑马)

Redis持久化 RDB与AOF RDB记录是二进制数据&#xff0c;Redis停机时会触发保存&#xff0c;名称&#xff1a; dump.rdb 缺点&#xff1a;间歇式复制可能存在宕机数据更新丢失 AOF 记录的写操作命令&#xff0c;每秒记录一下&#xff0c;也存在数据更新丢失的可能&#xff0c;相…

【数轮】数论、质数、最大公约数、菲蜀定理

数学 唯一分解定理 n>2都可以表示为质因数的乘方。 令 n a1b1a2b2 … \dots … a1,b1 … \dots …都是质因数&#xff0c;b1,b2 … \dots …是对应质因数的数量。 调和级数 11/2 1/3 1/4 ⋯ \cdots ⋯ 1/ n 约等于 logn。 证明过程&#xff1a; 1/3 1/4 < (1/2) …