编写自己的Arduino库
参考及来源超给力啊:
https://www.cnblogs.com/lulipro/p/6090407.html
https://www.cnblogs.com/lulipro/p/6090407.html
lulipro - 代码钢琴家
学习知识的最大价值在于愉悦自己的大脑,其次才是让自己生存。
如何编写自己的Arduino库?
一开始写Arduino 的时候很不习惯,没有main函数,因为好多东西都被隐藏了。一直想搞清楚,以便编写自己的库文件。于是研究一下午,下面是一些总结。
Arduino工程的初步认识
一、目录规范
当创建一个空的工程,先按下ctrl+s保存一下。这个时候弹出对话框,命名工程。假如命名为LED,并保存在 我自己的Arduino工作目录下 H:\Arduino\workspace\。
于是IDE会自动帮我们在workspace下创建1个文件夹,并将sketch主文件放在里面,而且主文件和文件夹同名。
二、主文件代码框架规范
每一个Arduino程序(Sketch)都有1个主文件,后缀为 .ino ,它是程序的setup 函数和 loop函数所在的文件。
代码框架如下:
void setup() {
// put your setup code here, to run once:
//初始化操作代码放在setup函数中,他们将在程序启动的第一步得到执行 并只执行一次
} void loop() {
// put your main code here, to run repeatedly:
//将程序的主要逻辑代码,放在loop里。他们将会反复执行下去。
}
有C/C++开发经验的人看到这个程序框架会愣住:我的main函数去哪里呢?
Arduino 为了让更多的人能够使用Arduino平台开发出好玩的东西出来,绞尽脑汁降低门槛,它隐藏了程序的细节,使得开发者将注意力放在实现上。
在Arduino IDE的安装目录下可以找到main.cpp这个代码模板文件,main函数就位于此。文件位置:{Arduino安装目录}\hardware\arduino\avr\cores\arduino\main.cpp,内容如下:
/*
main.cpp - Main loop for Arduino sketches
Copyright (c) 2005-2013 Arduino Team. All right reserved. This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ #include <Arduino.h> // Declared weak in Arduino.h to allow user redefinitions.
int atexit(void (* /*func*/ )()) { return 0; } // Weak empty variant initialization function.
// May be redefined by variant files.
void initVariant() __attribute__((weak));
void initVariant() { } void setupUSB() __attribute__((weak));
void setupUSB() { } int main(void)
{
init(); //硬件初始化 initVariant(); //特有硬件初始化。因为不同的开发板有自己独特的初始化逻辑。 #if defined(USBCON)
USBDevice.attach();
#endif setup(); for (;;) {
loop();
if (serialEventRun) serialEventRun();
} return 0;
}
在项目中使用多文件
有时会程序越写越大,越大越乱。多文件管理可以解决这个麻烦。Arduino程序可以有多个源代码文件,但只有 1个 主文件,也就是存放 setup、loop函数的.ino文件。
为了使得代码更清晰,我们让主文件用来控制程序的主要逻辑部分,而把具体的细节封装成单个模块,存放在其他的文件中,这样方便管理。
那么怎么创建其他的文件呢???下面开始介绍。
使用无后缀的文件(其实是以.ino为后缀的,只是在IDE中不会显示后缀,而在电脑的资源管理器中会显示.ino , 以下都称为无后缀)
点击下图中标记的按钮,选择第一个选项 【新建标签】,输入文件名即可。
这样我们的工程就有了2个文件了。如下,一个主文件和一个名为LED的文件。这就是最简单的多文件方法。
我不推荐使用这种方法,这是为没有C/C++编程经验的小白准备的,他们不懂函数定义 后还要声明才能使用,不懂得头文件的包含。这些都被Arduino IDE帮他们做了。IDE的具体处理是
Also, this generation isn't perfect: it won't create prototypes for functions that have default argument values, or which are declared within a namespace or class.
使用传统的 C/C++分离式文件
这种方式下,对于一个代码模块,我们需要一对文件:源文件和头文件,即: .c 和.h 或者 .cpp 和 .h 。前者是C语言风格,后者是对会使用C++来说的。官方貌似推崇我们使用C++编写Arduino代码,无论是Arduino 的从标准库,还是教程中,都透露出一股强烈的OOP气息。所以我下面使用C++风格来举例子。
例如我们想要将LED的控制封装成一个模块。一开始我们需要创建2个文件 :LED.h 、 LED.cpp
然后是想清楚我们需要让提供LED控制的哪些操作。发挥你的想象力时候到了。规定操作后,我们先写出头文件,然后写出实现,最后在主文件中使用这个模块。在主文件中使用
#include"LED.h"预处理指令包含。
/*******************
LED.h *******************/ #ifndef _LED_H__
#define _LED_H__ //导入Arduino核心头文件
#include"Arduino.h" class LED
{
private:
byte pin; //控制led使用的引脚 public: LED(byte p , bool state=LOW ); //构造函数 ~LED(); //析构函数 byte getPin(); //获取控制的引脚 void on(); //打开LED void off(); //关闭LED bool getState(); //获取LED状态
void disattach(); //释放引脚与LED的绑定,使得引脚可以控制其他的东西 }; #endif
/*****************
LED.cpp ******************/ #include"LED.h"
#include"Arduino.h" LED::LED(byte p,bool state):pin(p)
{ pinMode(pin,OUTPUT);
digitalWrite(pin,state);
} LED::~LED()
{
disattach();
} void LED::on()
{
digitalWrite(pin,HIGH);
} void LED::off()
{
digitalWrite(pin,LOW);
} bool LED::getState()
{
return digitalRead(pin);
} void LED::disattach() //引脚回收,恢复到上电状态
{
digitalWrite(pin,LOW);
pinMode(pin,INPUT);
}
/********************** 实例化1个LED对象,用7号叫控制,让他闪烁10次,并在串口打印出它的状态。 10次完毕后释放回收引脚 **********************/
#include"LED.h" LED led(7);
byte count =0; void setup() { Serial.begin(9600); } void loop() { if(count<10) {
led.on();
delay(300);
Serial.print("LED state:");Serial.println(led.getState(),DEC); led.off();
delay(300);
Serial.print("LED state:");Serial.println(led.getState(),DEC); ++count;
if(count==10)
led.disattach();
} }
让它成为你自己的库!
如果上面的模块你觉得好用,符合自己的使用习惯,而且经常要用到,那么你可以将它变成你自己的库文件。这样以后就可以直接拿来用啦。
Arduino的扩展库都是放在 libraries目录下的。
所以我们需要在这个目录下创建一个文件夹,比如上面的例子是LED控制,于是我创建了 m_LED文件夹(前面加m是为了和官方库区分开,这只是我自己的习惯而已)。然后把写好的.cpp 和 .h文件拷贝到里面去,这样就OK了。
这样我们 的主文件就变成了下面这样,是不是很简洁干净呢。
#include<LED.h> //注意,由于LED控制模块已经是标准库了,所以使用尖括号<> 包含 LED led(7);
byte count =0; void setup() {
Serial.begin(9600);
} void loop() { if(count<10){
led.on();
delay(300);
Serial.println(led.getState(),DEC); led.off();
delay(300);
Serial.println(led.getState(),DEC); ++count;
if(count==10)
led.disattach();
}
}
细心的同学会发现 和 LED.cpp 、 LED.h 一起有个 keywords.txt文件,这个是什么用呢? 其实它没有太大的实用性,只是为了配置自定义库的语法高亮。让我们自己的库能在IDE下显示不同的颜色而已。如果不配置,Arduino IDE不能渲染出颜色的。
如果你觉得这个库非常不错,你还可以把它分享给别人使用。我们好像一直都在使用别人的东西,把自己的劳动成果分享出去,也为别人做出贡献,岂不更好?
编写自己的Arduino库的更多相关文章
- 如何编写自己的Arduino库?
一开始写Arduino 的时候很不习惯,没有main函数,因为好多东西都被隐藏了.一直想搞清楚,以便编写自己的库文件.于是研究一下午,下面是一些总结. Arduino工程的初步认识 一.目录规范 当你 ...
- 让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀
原文 让你编写的控件库在 XAML 中有一个统一的漂亮的命名空间(xmlns)和命名空间前缀 在 WPF XAML 中使用自己定义的控件时,想必大家都能在 XAML 中编写出这个控件的命名空间了.然而 ...
- Kelp.Net是一个用c#编写的深度学习库
Kelp.Net是一个用c#编写的深度学习库 基于C#的机器学习--c# .NET中直观的深度学习 在本章中,将会学到: l 如何使用Kelp.Net来执行自己的测试 l 如何编写测试 l ...
- 编写自己的代码库(css3常用动画的实现)
编写自己的代码库(css3常用动画的实现) 1.前言 在月初的时候,发了CSS3热身实战--过渡与动画(实现炫酷下拉,手风琴,无缝滚动).js的代码库也发过两次,两篇文章.之前也写了css3的热身实战 ...
- Arduino库和STM32的寄存器、标准库、HAL库、LL库开发比较之GPIO
标题: Arduino库和STM32的寄存器.标准库.HAL库.LL库开发比较之GPIO 作者: 梦幻之心星 sky-seeker@qq.com 标签: [#Arduino,#STM32,#库,#开发 ...
- 为Tcl编写C的扩展库
Tcl是一个比较简洁的脚本语言,官方地址 http://www.tcl.tk. tcl脚本加载C实现的动态库非常方便. 1. 为Tcl编写一个用C实现的扩展函数. #include <stdio ...
- Arduino库
单总线库: 下载地址 : 链接:https://pan.baidu.com/s/1YSuqrXWuBAxMEUWHy8rckw 提取码:svix 把整个文件夹复制到 Arduino安装目录的 ...
- 如何安装/导入Arduino库文件及库文件的不同位置与区别(以eFLL中嵌入式模糊逻辑库为例)
网上有数百个可在Aruduino中使用的库,这些代码集使得我们无需从0-1地搭建我们所需功能,这使得学习和使用Arduino变得更加方便简单.除此之外,平时直接从网上download下的代码也很有可能 ...
- php调用c语言编写的so动态库
from http://blog.csdn.net/wzhwho/article/details/6949297 PHP除了使用扩展库的方式调用c函数,还可以通过socket通信的方式.这里介绍前者. ...
随机推荐
- Laravel Reponse 响应客户端
Laravel Response 响应客户端 本篇文章逻辑较长,只说明和响应生命周期相关的必要代码. 本文主要内容顺序为: 1.执行上文管道中的then方法指定的闭包,路由的分发 2.在路由器中(Ro ...
- Apache Pulsar 社区周报:08-08 ~ 08-14
关于 Apache Pulsar Apache Pulsar 是 Apache 软件基金会顶级项目,是下一代云原生分布式消息流平台,集消息.存储.轻量化函数式计算为一体,采用计算与存储分离架构设计,支 ...
- 发生错误 1069 sqlserver
---------------------------SQL Server 服务管理器---------------------------发生错误 1069 - (由于登录失败而无法启动服务.),此 ...
- ios Standard Framework和Umbrella Framework
Standard Framework:标准库,通过引用对应的header文件而不是引用master header 文件来引用类(也可以通过引用Master Header file来引用需要使用的类), ...
- 使用Javax.mail 发送邮件
使用Javax.mail 发送邮件 详细说明都在代码中: 引入依赖 <!--sun定义的一套接收.发送电子邮件的API--> <dependency> < ...
- .net core中使用jwt进行认证
JSON Web Token(JWT)是一个开放标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间作为JSON对象安全地传输信息.由于此信息是经过数字签名的,因此可以被验证和信任 ...
- chrome设置跨域访问
1.新建目录 /usr/local/opt/myChromData 2.输入命令行 open -n /Applications/Google\ Chrome.app/ --args --disable ...
- PHP 安装 扩展时 抛出 /usr/local/Cellar/php@7.1/7.1.25/pecl 异常解决
liugx@MacBook-Pro ~/work/php/ext_source/php-xhprof-extension master make installmkdir: /usr/ ...
- java安全编码指南之:Number操作
目录 简介 Number的范围 区分位运算和算数运算 注意不要使用0作为除数 兼容C++的无符号整数类型 NAN和INFINITY 不要使用float或者double作为循环的计数器 BigDecim ...
- VMware虚拟中输入ifconfig提示not found解决办法
1. 查看虚拟机是否没有IP地址:命令行中输入ip addr,如图红框所示,若无是需要设置. 2. 进入sbin目录确认ifconfig是否安装:可以通过命令[ls | grep 'if']来看 3. ...