My_Arduino(1)基础入门篇
这里主要是依托Simon Monk著的《Aruduino编程从零开始》,更多的是对其中出现过的内置函数语法的简单说明,同时在数据结构存储篇稍微详细的进行了总结,本博文内容不包含该书的第九章与第十章的内容,仅对其他章节进行学习说明(因为第十一章内容涉及C++同时书中也是简写,这里只是简单的写出了书中写的例子,一个简单的库,没有过多的写)。
这里给出该书的PDF版的下载地址:(等审核通过了再补上吧。。。)
以下为该书中出现的内置函数:
Serial.begin(9600);
初始化串口通信,并将波特率设置为9600
Serial.available();
函数返回缓冲区等待读取的数据的字节数,若无,返回0.
Serial.read();
读取一个Byte的数据;
digitalRead(pin)
读取数字引脚的HIGH或LOW
返回值:HIGH 或 LOW
analogWrite(pin,x)
x的参数范围为0-255,0为关闭,255为全功率。
analogRead(pin)
介绍:从指定的模拟引脚读取值。
Arduino主板有6个通道(Mini和Nano有8个,Mega有16个),10位AD(模数)转换器。
这意味着输入电压0-5伏对应0-1023的整数值。这就是说读取精度为:5伏/1024个单位,约等于每个单位0.049伏(4.9毫伏)。
输入范围和进度可以通过analogReference()进行修改。
pin:读取的模拟输入引脚号(大多数主板是0-5,Mini和Nano是0-7,Mega是0-15)
返回值:整数型 int(0到1023)
注:如果模拟输入引脚没有连接到任何地方,analogRead()的返回值也会因为某些因素而波动(如其他模拟输入,你的手与主板靠的太近)
random(max)
random(min, max)
min - 随机数的最小值,随机数将包含此值。 (此参数可选)
max - 随机数的最大值,随机数不包含此值。( 数据类型为long )
注:配合以randomSeed()设定的种子输出指定范围的整数伪随机数
bitRead(要被操作的数,要被操作数的第几位)
返回值:被操作数的第几位。
bitWrite(操作的数,第几位,位的值)
返回值:把操作数的第几位改为位的值后的数。
tone(针脚,声音的频率,声音的长度(可选))
若不写第三个参数,则声音会一直响下去。
介绍:让针脚发出声音
notone(针脚)
让针脚停止发出声音
shiftOut(位需要发送到的针脚,被用作时钟的针脚号(每发送一位后触发一次),MSBFRIST(LSBFRIST),发送数据的字节数)
第三个参数用来决定位是从最小的开始发送还是从最大的。
attachInterrupt(interrupt,function,mode)中断函数
第一个参数指定你想要使用哪个中断(0意味着使用D2,1意味着使用D3)
第二个参数是中断是被调用的函数名。
第三个参数是常量CHANGE、RISING、FALLING、LOW中的一个
注:interrupts()函数与noInterrupts()函数分别负责打开与关闭总中断,这两个函数均为无返回值函数,无参数。
注:LOW(低电平触发)、CHANGE(变化时触发)、
RISING(低电平变为高电平触发)、FALLING(高电平变为低电平触发)
数据存储
把数据存储在闪存中 :
PROGMEM()(需要#include <avr/pgmspace.h>)(本方法只适用于AVR为核心的arduino 现在并不懂这句话的意思。。。)难
注:需要确保使用特殊的PROGMEM可以支持的数据类型(并不包括char的字符串))
引用:使用PROGMEM在flash中存储数据:https://www.arduino.cn/thread-7781-1-1.html
把数据存储在EEPROM中:
(#include <EEPROM.h>)
写入方法:EEPROM.write(address, value)
第一个参数为EEPROM中的内存地址:数值在0-1023
第二个参数是需要在这个地址写入的数据,只能有一个字节。
写入整数
因为EEPROM每次只能读写一个字节,所以存储2个字节的整数将有些难度:
补充:
lowByte(x)
介绍:提取一个变量(例如一个字)的低位(最右边)字节。
返回:x是任何类型的值,返回byte
highByte(x)
介绍:提取一个字节的高位(最左边的),或一个更长的字节的第二低位。
返回:x是任何类型的值,返回byte
eg:
int x = 1234;
EEPROM.write(0,highByte(x));
EEPROM.write(1,lowByte(x));
则:
若想把该整数从EEPROM中读取出来,需要这样:
byte high = EEPROM.read(0);
byte low = EEPROM.read(1);
int x = (high << 8 ) + low;
补充:
x << num 或者 x>> num
其中<<左运算符,表示使左运算元中的某些位移动右运算元中的指定位数。
其中>>右运算符,表示使左运算元中的某些位移动右运算元中的指定位数。
写入浮点数
在EEPROM中存储浮点数(union)使用C语言中的共用体
共用体:就是一个多个变量的结构同时使用一块内存区域,区域的取值大小为该结构中长度最大的变量的值
eg:
//定义一个共用体convert
union data
{
float f;
int i;
}convert;
然后可以用下面的方法再union中放置一个浮点数:
float f = 1.23;
convert.f = f;
然后就可以像下面一样把一个整数拆成2字节,并存储到EEPROM
EEPROM.write(0,highByte(convert.i));
EEPROM.write(1,highByte(convert.i));
当想要重新读取浮点数的时候,需要先把2字节组装成一个单独的整数,然后将整数放入union作为浮点数读取出来:
byte high = EEPROM.read(0);
byte low = EEPROM.read(1);
convert.i = (high << 8 ) + low;
float f = convert.f;
(也可以通过union来吧float分为四个字节,byte a[4],读者可以自行尝试。)
在EEPROM中存储字符串
读写字符串相对简单,只需要每次写入一个字符。。
写:
char *a = "Hello World!";
int i=0;
while(a[i]!='\0'){
EEPROM.write(i,a[i]);
i++;
}
读:
char a[20];
int i = 0;
char ch;
ch = EEPROM.read(i);
while(ch != '\0' && i < 20){
a[i] = ch;
ch = EEPROM.read(i):
i++;
}
清除EEPROM的内容
即便你上传新的sketch也不会清空EEPROM,仍会在EEPROM中遗留数据,这里给出可以将EEPROM的数据清空为0的代码:
书中的sketch 8-03:
#include <avr/eeprom.h>
void setup()
{
Serial.begin(9600);
int i1 = 123;
eeprom_write_block(&i1, 0, 2);
int i2 = 0;
eeprom_read_block(&i2, 0, 2);
Serial.println(i2);
}
void loop()
{
}
注:
1.EEPROM的同一位置只能被读写10W次,之后将变得不可靠。
2.EEPROM很慢,3ms才能写入1字节。
压缩:
当存储空间不太够用的时候,就需要用最有效的办法来表示数据。
eg:
你想要把 float类型的20.25存储到EEPROM中,若此时只使用1字节,将会节省空间。这个时候你可以采用的方法是,在存储之前改变数据
因为一个字节可以存储一个0-255之间的整数,故有两种办法:
- int x = (int)20.25;//进行强制类型转换,这种办法只能保留住整数部分,造成精度缺失。
- int x = 20.25 * 4;//这时将存储进EEPROM的数是原来数字的四倍,当我们读取的时候需要除以4倍,这种方法不失精度,但是注意数据范围。
当想要读取数据的时候:
float y = (float)(x) / 4;
其他压缩数据的方法:
若要记录变化很慢的度数,例如温度,可以先全分辨率的存储第一个温度值,然后每次只记录w温度相对于前一个值的变化值,变化值一般比较小,占据更少的字节数。
C++编写类
一个类包含俩文件:拓展名为.h的头文件,和实现文件功能的.cpp文件
保存位置:Windows下 我的文档\arduino\libraies(libraies文件夹是放置所有库的地方)下新建文件夹
写一个简单的灯闪烁的类:
1.位置
2.文件夹内部
.h文件的代码
//灯闪库
//注意,书中给的是#include “WProgram.h” ,需要换为#include "Arduino.h"
#include "Arduino.h"
class Flasher
{//类分为了共有和私有
public://共有部分看起来像函数开头,被称为方法,只能被作为类的一部分使用,不能单独使用。
Flasher(int pin,int duration);
void flash(int times);
private://私有部分包含俩个变量的定义,每当你创建一个Flasher类的对象的时候,必须包含这俩个变量。
//使得在新的对象中可以记住针脚和日期。
//变量称为成员变量,都以下划线开头(另外一种命名方法是以小写m开头)
int _pin;
int _d;
};
方法被称为构建函数,可以通过他来创建一个新的Flasher对象在Sketch中使用:
Flasher slowFlasher(13,500);//将创建一个新的被称为slowFlasher的Flasher,可以以500ms为周期在D13针脚上闪烁。
头文件只定义了类看起来什么样,仍需要一个实现文件去做真正的工作
.cpp文件的代码
//注意,书中给的是#include “WProgram.h” ,需要换为#include "Arduino.h"
#include "Arduino.h"
#include "Flasher.h"
Flasher::Flasher(int pin, int duration)
{
pinMode(pin,OUTPUT);
_pin = pin;
_d = duration / 2;
}
void Flasher::flash(int times)//Flasher::作前缀。表明方法都属于Flasher类
{
for (int i = 0;i<times;i++)
{
digitalWrite(_pin,HIGH);
delay(_d);
digitalWrite(_pin,LOW);
delay(_d);
}
}
完成k库后,仍需要在Flasher”文件夹内创建一个名为“keyword.txt”的文件,文件只有俩行:
Flasher KEYWORD1
flash KEYWORD2
(俩列中空格数量不重要,但每个关键字必须另起一行)
最后添加范例即可(这里不再说明添加方法)。
写在最后的小零碎
小知识:
有些针脚上写的有:PWM 表示脉冲宽度调制,旨在控制输出的功率,通过快速地开关输出实现
小技巧:
1.数字输入的常见用途是检测某个开关是否被关闭。
2.digitalWrite(inputPin,HIGH); 开打input阵脚内部的上拉电阻
3.消除抖动的方法:在检测到第一次按钮按下之后加上一个延迟
4.D2和D3针脚可以附加中断。若这俩个针脚作为输入使用,通过某种特殊的方式收到信号的时候,arduino处理器会停止正在做的任何事情并执行中断的函数
注意:
LED_BUILTIN的常量值为 D13
1,模式名必须大写。
2.数字输入只给一个0或1表开关,模拟输入可以给你0-1023之间的值,值的大小取决于模拟输入针脚上的电压。
3.如果想学在电脑上写接口与arduino对话,可以学processing