嵌入式之路,贵在日常点滴
---阿杰在线送代码
目录
系列文章之红外寻迹篇(库函数版本)
在介绍循迹模块时,先介绍一个知识点:
黑色的东西吸收比较强,反射能力弱
TCRT5000就是一个红外发射和接收器,不断发射和接收红外线。
产品用途:
1、电度表脉冲数据采样
2、传真机碎纸机纸张检测
3、障碍检测
4、黑白线检测
深色(黑色)的是发射端,白色(透明)的是接收端。中间蓝色的是可以调节灵敏度的旋钮。
TCRT5000光电传感器模块是基于TCRT5000红外光电传感器设计的一款红外反射式光电开关。传感器采用高发射功率红外光电二极管和高灵敏度光电晶体管组成,输出信号经施密特电路整形,稳定可靠。
总共有4个管脚,分别是VCC、GND、A0、D0。
A0是模拟信号输出,D0是TTL电平输出(即数字信号)。使用TCRT5000主要就是用来循迹,只需要连接VCC、GND、D0就可以了。
(1)工作电压 3.3V-5V,推荐工作电压为5V
(2)模块上的电位器是用来调节灵敏度的
(3)检测反射距离:1mm~25mm 适用
(4)输出形式 :数字开关量输出(0 和 1)
(5)设有固定螺栓孔,方便安装
(6)小板 PCB 尺寸:3.2cm x 1.4cm
(7)使用宽电压 LM393 比较器
循迹模块我用的是红外传感器。黑线的检测原理是红外发射管发射光线到路面,红外光遇到白底则被反射,接收管接收到反射光,经施密特触发器整形后输出低电平,指示灯点亮;当红外光遇到黑线时则被吸收,接收管没有接收到反射光,经施密特触发器整形后输出高电平,输出指示灯熄灭。简单的说就是当红外寻迹模板遇见黑线时会产生一个高电平,遇见白线时会返回一个低电平。所以根据原理设计思路为当左侧红外传感器遇见黑线时左拐,右边红外传感器遇见黑线时右拐。这样就可以完成小车寻迹。
当然除了遇到黑线熄灭,当距离太远红外线反射后检测不到,此时指示灯也会熄灭。
那么如果要循迹,模块离地面要近,在没有遇到黑线时确保指示灯长亮,一旦指示灯熄灭就说明遇到黑线了。

(1)因为硬件条件有限,反应速度不是很快会有一定的误差,所以小车的速度要尽量慢下来,从而弥补硬件的不足让小车有足够的反应时间。
(2)在设置两个红外传感器的IO口模式时要设置为浮空输入,这样才能通过程序读取IO口的状态来判断。
(3)在测试小车时尽量在光线较暗的条件下来测试小车,避免光线过亮影响测试。
(4)红外寻迹模块的OUT不能接在有上拉电阻的IO口。
在这里,我利用的主控是STM32F103C8T6最小板,主芯片通过读取四路红外循迹模块判断小车偏离中心黑线的情况,主芯片根据小车偏离情况对电机的差速进行控制调整,通过左右电机的不同转速,实现寻黑线的功能。
通过GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数获得对应端口的电平。
我的原理图 红外对管依次连接 PB5 、PB4 、PB3 、PA15
注意:这里需要使用的PB3、PB4、PA15是单片机的'特殊引脚
打开数据手册:STM32F103x8B_DS_CH_V10,在引脚定义章节,说明了复位后的主功能和默认复用功能以及重定义功能。
在参考手册:STM32中文参考手册_V10, 在8.3.5 JTAG/SWD复用功能重映射中,说明了引脚使用情况。

怎么办呢?
需要关闭JTAG-DP 启用SW-DP ,我们重映射配置应写为
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
话不多说上代码
#include "xunji.h"
void xunji_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;//定义一个结构体变量
//使能GPIOA和GPIOB 使能PC端口时钟 rcc.h-693
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);
//重映射配置关闭JTAG-DP 启用SW-DP从而可以使用PA15 PB3 PB4
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//PA15 设置成下拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHz
GPIO_Init(GPIOA,&GPIO_InitStructure);//根据设定参数初始化GPIOE.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 设置成下拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB 5 4 3
}
#ifndef _XUNJI_H
#define _XUNJI_H
#include "stm32f10x.h"
#include "sys.h"
#define HW_1 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5)//读取 PB5 电平
#define HW_2 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_4)//读取 PB4 电平
#define HW_3 GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_3)//读取 PB3 电平
#define HW_4 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//读取 PA15 电平
void xunji_init(void);
#endif
main.c
//转弯时速度不适宜太快,这里我设置的占空比是1/4。小伙伴只需调试每个动作执行时间的长短
来使你的车在寻迹时丝滑起来
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 0 && HW_4 == 0)
{
qian(500);
delay_ms(50);
}
if(HW_1 == 0 && HW_2 == 1 && HW_3 == 0 && HW_4 == 0)
{
zuo(500);
delay_ms(150);
}
if(HW_1 == 1 && HW_2 == 0 && HW_3 == 0 && HW_4 == 0)
{
zuo(500);
delay_ms(250);
}
if(HW_1 == 1 && HW_2 == 1 && HW_3 == 0 && HW_4 == 0)
{
zuo(500);
delay_ms(300);
}
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 1 && HW_4 == 0)
{
you(500);
delay_ms(150);
}
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 0 && HW_4 == 1)
{
you(500);
delay_ms(250);
}
if(HW_1 == 0 && HW_2 == 0 && HW_3 == 1 && HW_4 == 1)
{
you(500);
delay_ms(300);
}
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:
前面一篇关于智能合约翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用程序语言去编写智能合约了。而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂智能合约代码,或找出其中的漏洞,那么,学习Solidity这门高级的智能合约语言是有必要的,当然,这都得在公链``````以太坊上,毕竟国内的联盟链有些是不兼容Solidity。Solidity是一种面向对象的高级语言,用于实现智能合约。智能合约是管理以太坊状态下的账户行为的程序。Solidity是运行在以太坊(Ethereum)虚拟机(EVM)上,其语法受到了c++、python、javascript影响。Solidity是静态类型
文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3
LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L