14. 扩展板

14.1 IO扩展板

简介

IO Expansion Shield for Edge101WE 是一款用于 Edge101WE 工业物联网主板的输入输出接口扩展板。在板上集成了12路光耦隔离输入、8路继电器、4路ADC、2路PWM。可完成传感器输入采集、计数、模拟量传感器采集、脉冲串输出、PWM输出功能。

产品的特点

  • 8路光电隔离输入,可用于读取开关量输出的传感器。具有计数器功能,最大计数频率 100KHz,最大计数值 32bit,具备掉电保持。

  • 可选的数字量滤波,用于滤除开关信号的抖动。输入必须在时延期限内保持在新状态,才能被认为有效。

  • 4路高速光电隔离输入,最高200KHz频率输入,可用于读取正交编码器等高速输入的数字脉冲型号。

  • 2路光电隔离电流采集ADC输入通道,输入电流范围0~20mA,16位采样分辨率,用于电流模拟量输出传感器信号采集。

  • 1路光电隔离电压采集ADC输入通道,输入电压范围0~10V,16位采样分辨率,用于电压模拟量输出传感器信号采集。可通过内部2倍放大器采集0~5V信号,提高分辨率。

  • 模拟量3通道分时采样,最高采样率500Hz,每通道具备2KByte FIFO缓存。可至少缓存6秒钟模拟量采集数据。

  • 8路继电器隔离输出,常开触点,最大控制电流5A。

  • 2路光电隔离晶体管NPN开漏输出,最大控制电流 0.5A,最大电压50V。可设置为高速脉冲串(PTO)输出或者脉宽调制波形(PWM)输出。频率可调范围1Hz~100KHz,可用于步进电机驱动器、伺服驱动器、固态继电器、气阀等高速设备控制。

参数

尺寸重量功耗

  • 尺寸 长 x 宽 x 高(mm) : x x

  • 重量: g

  • 功耗: W

数字输入

  • 数字输入电流消耗(24 V DC) 所用的每点输入 4 mA

  • 脉冲捕捉输入 :8个

    具备中断功能

    具备32bit计数器

    可写计数器

  • 高速计数器: 4 个 单相:4 个 200 KHz 正交相位:4 个 100 KHz

    具备32bit计数器

    可写计数器

  • 隔离(输入电源与逻辑侧): ?? V AC

  • 滤波延迟时间每个通道可单独选择:1 ~ 500,000 μs

数字输出

  • 继电器输出点数: 8 路

    类型: 继电器,干触点

    电压范围: 5 ~ 30 V DC 或 5 ~ 250 V AC

    每点的额定电流(最大): 5A

    开关延迟: 10ms

    机械寿命(无负载): 1,000,000 个断开/闭合周期

    额定负载下的触点寿命: 100,000 个断开/闭合周期

    隔离(输入电源与逻辑侧): ?? V AC

  • 高速晶体管输出通道: 2 路

    类型: 固态-MOSFET(源型)

    电压范围: 5~50V

    每点的额定电流(最大:) 0.5A

    最大频率:2个100 KHz

    断开到接通最长: ?? μs 接通到断开最长: ?? μs

    隔离(输入电源与逻辑侧): ?? V AC

模拟输入

  • 输入路数:3路

  • 输入范围: 0~10 V,0 ~ 20 mA

  • 满量程范围:65535

  • 分辨率:16bit

  • 最大耐压/耐流: ±35 V/±40 mA

  • 采样率:50Hz、60Hz、250Hz、500 Hz可选。

  • 内部放大器增益调节: 1倍或2倍可选。

  • 噪声抑制: 50Hz、60Hz、250Hz、500 Hz可选。

  • 输入阻抗: ≥4 MΩ(电压)/100 Ω(电流)

  • 隔离: 1500V AC ??

  • 精度(25˚C / 0 ~ 55 ˚C :电压模式:满量程的±?? %/±?? %,电流模式:满量程的±?? %/±?? %

  • 非线性度:0.003% ??

  • 模数转换时间: 625 μs(400 Hz 抑制) ??

  • 共模抑制: 40 dB,DC 到 60 Hz ??

  • 工作信号范围: 信号加共模电压必须小于 +12 V 且大于 -12 V ??

  • 具备自校准、零标度校准、满标度校准功能。

API参考 (根据实际库做修改)

DFRobot_IOExpension() - 构造函数

IO扩展板的地址设置。扩展板具备两个备选地址 0x50,0x52,通过IO扩展板的跳帽设置。

语法

DFRobot_IOExpension(uint8_t addr=DFRobot_IOExpension_ADDR_H,TwoWire *pWire=&Wire);

参数

传入值 说明 值范围
addr IO扩展板的地址设置。扩展板具备两个备选地址 0x51,0x50(默认0x51) 0x51,0x50
pWire IIC bus

返回

begin() - 初始化函数

初始化I2C总线,读取扩展板ID,判断通信是否成功

语法

int begin(void);

返回

返回值 说明 值范围
ERR_OK 获取到的PID正确,通信成功 0
ERR_DATA_BUS IIC通讯失败 -1
ERR_IC_VERSION 获取到的PID错误 -2

reset() - 复位函数,初始化扩展板

语法

void reset(void);

返回

enableInterrupt() - 使能扩展板的中断通知功能

当中断事件被触发,扩展板中断引脚输出低电平

语法

void enableInterrupt(uint8_t type,void (*intr_handler)());

参数

传入值 说明 值范围
type 中断类型 五种类型的中断通知功能,SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能

返回

getInterruptType() - 获取扩展板的中断状态

语法

uint8_t getInterruptType();

参数

返回值

返回值 说明
返回何种中断被触发 SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能

当收到IO扩展板中断引脚下降沿时通过此函数判断中断的类型,基于中断类型做处理。

getSwitchINT() - 判断扩展板的某路输入触发了SWITCH_INT中断

语法

uint16_t getSwitchINT();

参数

返回值

返回值 说明 范围
12路开关中断状态 bit0-bit11分别对应第11路的开关状态 1代表触发,0代表非触发 0,1

setINPUTFilter() - 设置12路脉冲捕捉输入滤波延迟时间

语法

void setINPUTFilter(uint16_t inputNumber,uint16_t filtertime);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12
filtertime 过滤时间(单位为ms.步长10ms) 0-500

返回

readSwitchStauts() - 读取扩展板上的12路输入的状态

语法

uint16_t readSwitchStauts();

参数

返回

返回值为12路开关的状态 bit0-bit11分别对应第1-12路的开关状态 1代表触发,0代表非触发

getCounterINT() - 判断扩展板的某路输入触发了COUNTER_INT中断

语法

uint16_t getCounterINT()();

参数

返回值

返回值 说明 范围
12路计数器中断状态 bit0-bit11分别对应第11路的计数器中断状态 1代表触发,0代表非触发 0,1

setCountingFilter() - 设置12路脉冲捕捉输入滤波延迟时间

每个通道可单独选择:1 ~ 500,000 μs,当输入信号持续时间超过延迟时间,才作为有效信号。

语法

void setCountingFilter(uint16_t counter,uint32_t filtertime);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12
filtertime 过滤时间 0~ 500,000 μs

返回

setCountingIntervaltime() - 设置12路脉冲捕捉输入信号时间间隔

每个通道可单独选择:1 ~ 500,000 μs,当输入信号持续时间超过时间间隔,才作为有效信号。

语法

void setCountingIntervaltime(uint16_t counter,uint32_t intervalTime);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12
intervalTime 过滤时间 0~ 500,000 μs

返回

setCountingInitValue() - 设置扩展板上的12路计数器的初始值

设置扩展板上的12路计数器的计数值,可用作初始化计数器的计数值或者对计数器清零。

语法

void setCountingInitValue(uint16_t counter,uint32_t value);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12
value 计数值 0~ 4,294,967,294

返回

setCountingPresetValue() - 设置扩展板上的12路计数器的预设数

设置扩展板上的12路计数器的预设数

语法

void setCountingPresetValue(uint16_t counter,uint32_t persetValue);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12
value 计数值 0~ 4,294,967,294

返回

setCounterMode() - 设置计数器工作模式

语法

void setCounterMode(uint16_t counter,eCounterMode_t mode);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12
mode 计数模式 向上计数 eCTU、向下计数 eCTD

返回

startCounter() - 开启计数器

语法

void startCounter(uint16_t counter);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12

返回

stopCounter() - 关闭计数器

语法

void stopCounter(uint16_t counter);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12

返回

readCounterValue() - 读取12路脉冲捕捉输入的计数器值

读取指定计数器32bit数字输入的计数值。

语法

uint32_t readCounterValue(uint16_t counter);

参数

传入值 说明 值范围
counter 计数器编号 SWITCH_COUNTER_1~SWITCH_COUNTER_12

返回

返回值 说明 值范围
uint32_t 该编号计数器的计数值 0~ 4,294,967,294

enQuadraturePhaseCounter() - 使能正交相位计数器

语法

void enQuadraturePhaseCounter(uint8_t counter);

参数

传入值 说明 值范围
counter 计数器 1,2

返回

disQuadraturePhaseCounter() - 失能正交相位计数器

语法

void disQuadraturePhaseCounter(uint8_t counter);

参数

传入值 说明 值范围
counter 计数器 1,2

返回

readQuadraturePhaseCounterValue() - 读取正交相位计数器的计数值

语法

int32_t readQuadraturePhaseCounterValue(uint8_t counter);

参数

传入值 说明 值范围
counter 计数器 1,2

返回

返回值 说明 范围
计数值 该通道的计数值 -536870912~ 536870911

setQuadraturePhaseCounterValue() - 设置正交相位计数器的计数值

语法

void setSinglePhaseCounterValue(uint8_t counter,int32_t value);

参数

传入值 说明 值范围
counter 计数器 1~4
value 计数值 -536870912~ 536870911

返回

setRelayStatus() - 设置扩展板上的8路继电器的状态

语法

void setRelayStatus(uint8_t channel,uint8_t mode);

参数

传入值 说明 值范围
channel 继电器选择 1~8
mode 1:开启该编号继电器;0:关闭该编号继电器值 0,1

返回

readRelayStatus() - 读取扩展板上的8路继电器的状态

语法

uint8_t readRelayStatus();

返回

返回值 说明 值范围
uint8_t 返回值为8路开关的状态:bit0-bit7分别对应第1-8路的输出状态
1代表开启,0代表关闭
0~255

setPeriodUs() - 设置扩展板脉冲周期——单位:微秒

语法

void setPeriodUs(uint8_t channel,uint16_t period);

参数

传入值 说明 值范围
channel 输出通道选择 1,2
period 周期 0-65535

返回


setPeriodMs() - 设置扩展板脉冲周期——单位:毫秒

语法

 void setPeriodMs(uint8_t channel,uint16_t period);

参数

传入值 说明 值范围
channel 输出通道选择 1,2
period 周期值 0~ 65,535

返回

setPWMPulseWidth() - 设置扩展脉冲输出的PWM模式的脉冲宽度

语法

void setPWMPulseWidth(uint8_t channel,uint32_t pulseValue);

参数

传入值 说明 值范围
uint8_t channel 输出通道选择 1,2
uint32_t pulseValue PWM 模式下的脉冲宽度值 0~ 65535

返回

setPWMDutyRatio() - 设置扩展脉冲输出的PWM模式的占空比

语法

void setPWMDutyRatio(uint8_t channel,float duty);

参数

传入值 说明 值范围
channel 输出通道选择 1,2
duty 占空比 0.00—100.00%

返回

setPTOPulseNumber() - 设置扩展脉冲PTO模式的脉冲数量

语法

void setPTOPulseNumber(uint8_t channel,uint16_t number);

参数

传入值 说明 值范围
channel 输出通道选择 1,2
number PTO模式下的脉冲数量 0-65535

返回

PWMStart() - 开启PWM输出

语法

void PWMStart(uint8_t channel);

参数

传入值 说明 值范围
channel 输出通道选择 1,2

返回

PTOStart() - 开启PTO输出

语法

void PTOStart(uint8_t channel);

参数

传入值 说明 值范围
channel 输出通道选择 1,2

返回

stopHighSpeedTransistor() -关闭脉冲输出

语法

void stopHighSpeedTransistor(uint8_t channel);

参数

传入值 说明 值范围
channel 输出通道选择 1,2

返回

ADCCollectConfig() - 配置扩展板的3个通道模拟输入

AD7705最详细讲解 https://blog.csdn.net/cugautozp/article/details/108032819

http://www.ad.siemens.com.cn/productportal/Prods/s7-200-portal/MicroPower2013/s7-200/function/pto-pwm/pto-pwm.htm

设置采样率和内部放大器增益。

采样率:50Hz、60Hz、250Hz、500 Hz可选。

内部放大器增益调节: 1倍或2倍可选。

语法

void ADCCollectConfig(uint8_t sampleRate,uint8_t gain,uint8_t calibrateMode);

参数

传入值 说明 值范围
sampleRate 采样率 IOEXPENSION_ADC_SAMPLING_50HZ、IOEXPENSION_ADC_SAMPLING_60HZ、IOEXPENSION_ADC_SAMPLING_250HZ、IOEXPENSION_ADC_SAMPLING_500HZ
gain 增益 一倍:GAIN_1、两倍 :GAIN_2
calibrateMode 校准模式 不校准:NOT_CALIBRATION;自校准:SELF_CALIBRATION、零标度校准:ZERO_CALIBRATION、满标度校准:FULL_CALIBRATION

返回

返回值 说明
-1 代表参数设置错误
0 代表设置成功

setADCFIFOMode() - 设置ADC采集FIFO模式

语法

void setADCFIFOMode(bool mode);

参数

传入值 说明 值范围
mode 工作模式 true 开启FIFO模式,false关闭FIFO模式

返回

startADCCollect() - 开启ADC采集

语法

void startADCCollect();

参数

返回

stopADCCollect() - 停止ADC采集

语法

void stopADCCollect();

参数

返回

readADCvalue() -读取3通道ADC采集值

通道 1-3 其中通道1、2是采集的电流值(0-25mA),通道3采集的是电压值(0-10V)

语法

float readADCvalue(uint8_t channel);

参数

传入值 说明 值范围
channel 通道1、2是采集的电流值(0-25mA),通道3采集的是电压值(0-10V) 1~3

返回

返回值 说明 值范围
该通道采集的值 float

readFIFOCount() -读取ADC FIFO中的数据个数

通道 1-3 其中通道1、2是采集的电流值(0-25mA),通道3采集的是电压值(0-10V)

语法

uint8_t readFIFOCount(uint8_t channel);

参数

传入值 说明 值范围
channel 通道1、2是采集的电流值(0-25mA),通道3采集的是电压值(0-10V) 1~3

返回

返回值 值范围
该通道采集的个数 float

例程一 :2路的正交相位计数器

/*!
 * @file 2-wayOrthogonalPhaseCounter.ino
 * @brief 扩展板提供了2路的正交相位计数器,本实例介绍了使用正交相位计数器的方法
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU SEN0452
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-06-15
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
void setup() {
  Serial.begin(9600);
  while(IOExpension.begin()!=0);

  /**
   * @brief  设置正交相位计数器的初始计数值
   * @param  counter 计数器 范围 1-2  
   * @param  计数值
   */
  IOExpension.setQuadraturePhaseCounterValue(/*counter= */1,/*value= */0);
  IOExpension.setQuadraturePhaseCounterValue(/*counter= */2,/*value= */0);

  /**
   * @brief  使能正交相位计数器
   * @param  counter 计数器 范围 1-2
   * @n 注意:当选择正交相位计数器计数器1时,不能再单独使能单相计数器 1和单相计数器2;当选择正交相位计数器计数器2时,不能再单独使能单相计数器3和单相计数器4。
   * @n      当关闭正交相位计数器后,可以使能对应的单相计数器;关闭正交相位计数器的方法是:disQuadraturePhaseCounter( counter=1/2);
   */
  IOExpension.enQuadraturePhaseCounter(/*counter=*/1);
  IOExpension.enQuadraturePhaseCounter(/*counter=*/2);
}
void loop(){
  /**
   * @brief  读取正交相位计数器的计数值
   * @param  counter 计数器 范围 1-2
   * @return 计数值
   */
  Serial.print("counter1:");
  Serial.println(IOExpension.readQuadraturePhaseCounterValue(/*counter=*/1));
  delay(1000);
  Serial.print("counter2:");
  Serial.println(IOExpension.readQuadraturePhaseCounterValue(/*counter=*/2));
  delay(1000);
}

例程二:12路的输入做输入脉冲计数器—向下计数

/*!
 * @file IN1_12CTD.ino
 * @brief 扩展板提供了12路的输入可用做输入脉冲计数器,本实例介绍了使用输入脉冲计数器向下计数的方法
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x52);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
bool interruptFlag = false;
void interEvent()
{
  interruptFlag = true;
}
void setup() {
  Serial.begin(115200);
  while(IOExpension.begin()!=0);

  /**
   * @brief 使能扩展板的中断通知功能
   * @param type 五种类型的中断通知功能,SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能
   * @param intr_handler 中断处理函数
   */
  IOExpension.enableInterrupt(/*type= */COUNTER_INT,/*intr_handler=*/interEvent);

  /**
   * @brief 设置计数器输入信号滤波值
   * @param counter 计数器 范围(SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param filtertime 滤波值
   */
  IOExpension.setCountingFilter(/*counter= */SWITCH_COUNTER_1,/*filtertime= */100);

  /**
   * @brief 设置输入信号时间间隔 
   * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param intervalTime 时间间隔 (1us-500000us)
   */
  IOExpension.setCountingIntervaltime(/*counter= */SWITCH_COUNTER_1,/*filtertime= */100);

  /**
   * @brief 设置计数器预设数
   * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param persetValue 预设数
   */
  IOExpension. setCountingPresetValue(SWITCH_COUNTER_1,100);

  /**
   * @brief 设置计数器工作模式
   * @param counter 计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param mode 计数模式,向上计数 eCTU、向下计数 eCTD
   */
  IOExpension.setCounterMode(/*channel= */SWITCH_COUNTER_1,eCTD);

  /**
   * @brief 开启计数器
   * @param counter 计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   */
  IOExpension.startCounter(/*channel= */SWITCH_COUNTER_1);
 

}
void loop(){
  if(interruptFlag){
    interruptFlag = false;
    if(IOExpension.getInterruptType() & COUNTER_INT){
      if(IOExpension.getCounterINT() & SWITCH_COUNTER_1){
        Serial.print("counter 1:");
        /**
         * @brief 读取计数值
         * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
         * @return 返回该计数器的计数值
         */
        Serial.println(IOExpension.readCounterValue(/*counter=*/SWITCH_COUNTER_1));
      }
    }
  }
}

例程三:12路的输入做输入脉冲计数器—向上计数

/*!
 * @file 8-wayCounter.ino
 * @brief 扩展板提供了8路的输入可用做输入脉冲计数器,本实例介绍了使用输入脉冲计数器向上计数的方法
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
bool interruptFlag = false;
void interEvent()
{
  interruptFlag = true;
}
void setup() {
  Serial.begin(115200);
  while(IOExpension.begin()!=0);

  /**
   * @brief 使能扩展板的中断通知功能
   * @param type 五种类型的中断通知功能,SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能
   * @param intr_handler 中断处理函数
   */
  IOExpension.enableInterrupt(/*type= */SWITCH_INT,/*intr_handler=*/interEvent);

  /**
   * @brief 设置计数器输入信号滤波值
   * @param counter 计数器 范围(SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param filtertime 滤波值
   */
  IOExpension.setCountingFilter(/*counter= */SWITCH_COUNTER_1,/*filtertime= */100);

  /**
   * @brief 设置输入信号时间间隔 
   * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param intervalTime 时间间隔 (1us-500000us)
   */
  IOExpension.setCountingIntervaltime(/*counter= */SWITCH_COUNTER_1,/*filtertime= */100);

  /**
   * @brief 设置计数初始值
   * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param value  计数初始值
   */
  IOExpension.setCountingInitValue(SWITCH_COUNTER_1,0);

  /**
   * @brief 设置计数器预设数
   * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param persetValue 预设数
   */
  IOExpension. setCountingPresetValue(SWITCH_COUNTER_1,100);

  /**
   * @brief 设置计数器工作模式
   * @param counter 计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param mode 计数模式,向上计数 eCTU、向下计数 eCTD
   */
  IOExpension.setCounterMode(/*channel= */SWITCH_COUNTER_1,eCTU);

  /**
   * @brief 开启计数器
   * @param counter 计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   */
  IOExpension.startCounter(/*channel= */SWITCH_COUNTER_1);
}
void loop(){
  if(interruptFlag){
    interruptFlag = false;
    if(IOExpension.getInterruptType() & COUNTER_INT){
      if(IOExpension.getCounterINT() & SWITCH_COUNTER_1){
        Serial.print("counter 1:");
        /**
         * @brief 读取计数值
         * @param counter  计数器编号 IN1-IN12 范围 (SWITCH_COUNTER_1~SWITCH_COUNTER_12)
         * @return 返回该计数器的计数值
         */
        Serial.println(IOExpension.readCounterValue(/*counter=*/SWITCH_COUNTER_1));
      }
    }
  }
}

例程四:3路的ADC采集

/*!
 * @file ADCCOllect.ino
 * @brief 扩展板提供了3路的ADC采集通道,本实例介绍了使用ADC采集通道的方法
 * @n   通道1-2采集电流数据 范围是:0-25mA; 通道3是采集电压数据范围是0-10V
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
bool interruptFlag = false;
void interEvent()
{
  interruptFlag = true;
}
void setup() {
  Serial.begin(115200);

  while(IOExpension.begin()!=0);
  /**
   * @brief 使能扩展板的中断通知功能
   * @param type 五种类型的中断通知功能,SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能
   * @param intr_handler 中断处理函数
   */
  IOExpension.enableInterrupt(/*type= */ADC_CALIBRATION_INT,/*intr_handler=*/interEvent);

  /**
   * @brief 配置扩展板的3通道模拟输入
   * @param sampleRate 采样率 IOEXPENSION_ADC_SAMPLING_50HZ、IOEXPENSION_ADC_SAMPLING_60HZ、IOEXPENSION_ADC_SAMPLING_250HZ、IOEXPENSION_ADC_SAMPLING_500HZ
   * @param gain 增益 一倍:GAIN_1;两倍 :GAIN_2
   * @param calibrateMode 校准模式 : 不校准:NOT_CALIBRATION;自校准:SELF_CALIBRATION、零标度校准:ZERO_CALIBRATION、满标度校准:FULL_CALIBRATION
   */
  IOExpension.ADCCollectConfig(/*sampleRate=*/IOEXPENSION_ADC_SAMPLING_500HZ,/*gain=*/GAIN_1,/*calibrateMode=*/SELF_CALIBRATION);
  while(1){
    if(interruptFlag){
      interruptFlag = false;
      uint8_t status = IOExpension.getInterruptType();
      Serial.println(status);
      if(status & ADC_CALIBRATION_INT ){
        Serial.println("Set to complete");
        break;
      }
      
    }
    yield();
  }
  /**
   * @brief 开启ADC采集
   */
  IOExpension.startADCCollect();
}
void loop(){
  /**
   * @brief 设置3通道ADC采集值
   * @param channel 通道 1-3 其中通道1、2是采集的电流值(0-25mA),通道3采集的是电压值(0-10V)
   * @return 该通道采集的值
   */
  Serial.print("Channel 1 : ");
  Serial.printf("%.2f mA\n",IOExpension.readADCValue(/*channel=*/1));
  delay(1000);
  Serial.print("Channel 2 : ");
  Serial.printf("%.2f mA\n",IOExpension.readADCValue(/*channel=*/2));
  delay(1000);
  Serial.print("Channel 3 : ");
  Serial.printf("%.2f V\n",IOExpension.readADCValue(/*channel=*/3));
  delay(1000);
}

例程五:8路的输出用来控制8路继电器

/*!
 * @file controlRelay.ino
 * @brief 扩展板提供了8路的输出用来控制8路继电器,本实例介绍了控制8路继电器的的方法,8路继电器相互独立
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU SEN0452
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-06-15
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H;拉低IIC从机地址为DFRobot_IOExpension_ADDR_L
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
void setup() {
  Serial.begin(9600);
  IOExpension.begin();

  /**
   * @brief 设置扩展板上的8路继电器的状态
   * @param channel 继电器选择 1-8
   * @param mode 1:开启该编号继电器;0:关闭该编号继电器
   */
  IOExpension.setRelayStatus(/*channel= */1,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */2,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */3,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */4,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */5,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */6,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */7,/*mode=*/1);
  IOExpension.setRelayStatus(/*channel= */8,/*mode=*/1);
  delay(1000);

  /**
   * @brief 读取扩展板上的8路继电器的状态
   * @return 返回值为8路继电器的状态  bit0-bit7分别对应第1-8路的输入状态 1代表开启,0代表关闭
   */
  uint8_t status = IOExpension.readRelayStatus();
  if(status & RELAY_1){
    Serial.println("Relay No. 1 starts working");
  }
  if(status & RELAY_2){
    Serial.println("Relay No. 2 starts working");
  }
  if(status & RELAY_3){
    Serial.println("Relay No. 3 starts working");
  }
  if(status & RELAY_4){
    Serial.println("Relay No. 4 starts working");
  }
  if(status & RELAY_5){
    Serial.println("Relay No. 5 starts working");
  }
  if(status & RELAY_6){
    Serial.println("Relay No. 6 starts working");
  }
  if(status & RELAY_7){
    Serial.println("Relay No. 7 starts working");
  }
  if(status & RELAY_8){
    Serial.println("Relay No. 8 starts working");
  }
}
void loop(){

}

例程六:PTO模式—2路的脉冲输出

/*!
 * @file pulsePTO.ino
 * @brief 扩展板提供了2路的脉冲输出,这里采用PTO模式,本实例介绍了PTO,其中两路输出相互独立
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
void setup() {
  Serial.begin(115200);
  while(IOExpension.begin()!=0);

  /**
   * @brief 设置脉冲周期
   * @param channel 输出通道选择 1-2
   * @param period 周期,单位us
   */
  IOExpension.setPeriodMs(/*channel= */1,/*period=*/2000);

  /**
   * @brief 设置PTO模式脉冲个数
   * @param channel 输出通道选择 1-2
   * @param number PTO模式下的脉冲数量
   */
  IOExpension.setPTOPulseNumber(/*Channel=*/1,/*number=*/100);

  /**
   * @brief 使能扩展板高速晶体管的输出模式
   * @param channel 输出通道选择 1-2
   * @param mode PWM/PTO 模式 可选择参数:IOEXPENSION_PWM、IOEXPENSION_PTO、IOEXPENSION_OFF
   */
  IOExpension.PTOStart(/*Channel=*/1);

}
void loop(){

}

例程七:脉冲输出PTO模式下输出完成中断通知

/*!
 * @file PTOInterrupt.ino
 * @brief 扩展板提供了2路的脉冲输出,这里采用PTO模式,并在输出完成后以中断的方式通知MESH主控板,本实例介绍了PTO输出完成中断通知功能,其中两路输出相互独立
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
bool interruptFlag = false;
void interEvent()
{
  interruptFlag = true;
}
void setup() {
  Serial.begin(115200);
  while(IOExpension.begin()!=0);

  /**
   * @brief 使能扩展板的中断通知功能
   * @param type 五种类型的中断通知功能,SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能
   * @param intr_handler 中断处理函数
   */
  IOExpension.enableInterrupt(/*type= */PTO1_INT,/*intr_handler=*/interEvent);

  /**
   * @brief 设置扩展板的定时器的周期数和预分频值
   * @param channel 输出通道选择 1-2 (两通道采用来了两个定时器所以他们相互独立)
   * @param period 周期值
   * @param prescaler 预分频值
   */
  IOExpension.setPeriodMs(/*channel= */1,/*period=*/2000);
  //IOExpension.setPeriodUs(/*channel= */1,/*period=*/2000);

  /**
   * @brief 设置扩展板的定时器的周期数和预分频值
   * @param channel 输出通道选择 1-2 (两通道采用来了两个定时器所以他们相互独立)
   * @param number PTO模式下的脉冲数量
   */
  IOExpension.setPTOPulseNumber(/*Channel=*/1,/*number=*/10);

  /**
   * @brief 使能扩展板高速晶体管的输出模式
   * @param channel 输出通道选择 1-2
   * @param mode PWM/PTO 模式 可选择参数:IOEXPENSION_PWM、IOEXPENSION_PTO、IOEXPENSION_OFF
   */
  IOExpension.PTOStart(/*Channel=*/1);
}
void loop(){
  uint8_t status = 0;
  if(interruptFlag){
    interruptFlag = false;
    /**
     * @brief 获取扩展板的中断状态
     * @return 返回值 返回何种中断被触发
     */
    status = IOExpension.getInterruptType();
    if(status & PTO1_INT ){
        Serial.println("PTO1 Output complete");
        IOExpension.stopHighSpeedTransistor(/*Channel=*/1);
    }
  }
}

例程八:PWM模式—2路的脉冲输出

/*!
 * @file pulsePWM.ino
 * @brief 扩展板提供了2路的脉冲输出,这里采用PWM模式,本实例介绍了PWM,其中两路输出相互独立
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
void setup() {
  Serial.begin(115200);

  while(IOExpension.begin()!=0);
  /**
   * @brief 设置脉冲周期
   * @param channel 输出通道选择 1-2
   * @param period 周期,单位us
   */
  IOExpension.setPeriodMs(/*channel= */1,/*period=*/2000);
  //IOExpension.setPeriodUs(/*channel= */1,/*period=*/20000);

  /**
   * @brief 设置扩展脉冲输出的PWM模式的脉冲宽度
   * @param channel 输出通道选择 1-2 (两通道采用来了两个定时器所以他们相互独立)
   * @param pulseValue 脉冲宽度 
   */
  IOExpension.setPWMPulseWidth(/*Channel=*/1,/*pulseValue=*/1000);
  /**
   * @brief 设置扩展脉冲输出的PWM模式的占空比
   * @param channel 输出通道选择 1-2 (两通道采用来了两个定时器所以他们相互独立)
   * @param duty PWM 占空比 范围(0% - 100%)
   */
  IOExpension.setPWMDutyRatio(/*Channel=*/1,/*duty=*/50.0);
  /**
   * @brief 使能扩展板高速晶体管的输出模式
   * @param channel 输出通道选择 1-2
   */
  IOExpension.PWMStart(/*Channel=*/1);

}
void loop(){
}

例程九:中断模式下的开关检测

/*!
 * @file switchInterrupt.ino
 * @brief 扩展板提供了8路输入,这里可用作开关检测。当开关被按下,会触发主控的外部中断,在中断触发后去检测是哪一路的开关被按下
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @SKU DFR0887
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-09-04
 */
#include "DFRobot_IOExpension.h"
/*
  扩展板的IIC从机地址与扩展板上的IIC地址选择IO口有关,IO口默认拉高。
  IIC地址选择IO口拉高 扩展板IIC从机地址为 DFRobot_IOExpension_ADDR_H(0x51);拉低IIC从机地址为DFRobot_IOExpension_ADDR_L(0x50)
*/
DFRobot_IOExpension IOExpension(DFRobot_IOExpension_ADDR_H);
bool interruptFlag = false;
void interEvent()
{
  interruptFlag = true;
}
void setup() {
  Serial.begin(115200);
  while(IOExpension.begin()!=0);
  /**
   * @brief 设置输入信号滤波值
   * @param inputNumber 计数器 范围(SWITCH_COUNTER_1~SWITCH_COUNTER_12)
   * @param filtertime 滤波值
   */
  IOExpension.setINPUTFilter(/*inputNumber*/SWITCH_COUNTER_1,/*filtertime*/500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_2,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_3,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_4,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_5,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_6,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_7,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_8,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_9,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_10,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_11,500);
  IOExpension.setINPUTFilter(SWITCH_COUNTER_12,500);
  /**
   * @brief 使能扩展板的中断通知功能
   * @param type 五种类型的中断通知功能,SWITCH_INT开关状态中断通知功能、PTO1_INT通道1脉冲输出结束中断通知、PTO2_INT通道2脉冲输出结束中断通知功能、COUNTER_INT 计数器中断、ADC_CALIBRATION_INT ADC校准完成通知功能
   * @param intr_handler 中断处理函数
   */
  IOExpension.enableInterrupt(/*type= */SWITCH_INT,/*intr_handler=*/interEvent);
}

void loop(){
  uint8_t status = 0;
  if(interruptFlag){
    interruptFlag = false;
    if(IOExpension.getInterruptType() & SWITCH_INT){
      /**
       * @brief 判断扩展板的12路开关谁触发了SWITCH_INT中断
       * @return 8路开关中断状态
       */
      uint16_t status = IOExpension.getSwitchINT();
      if(status & SWITCH_COUNTER_1){
        Serial.println("Switch No. 1 is pressed");
      }else{
        Serial.println("Switch No. 1 is released");
      }
      if(status & SWITCH_COUNTER_2){
        Serial.println("Switch No. 2 is pressed");
      }else{
        Serial.println("Switch No. 2 is released");
      }
      if(status & SWITCH_COUNTER_3){
        Serial.println("Switch No. 3 is pressed");
      }else{
        Serial.println("Switch No. 3 is released");
      }
      if(status & SWITCH_COUNTER_4){
        Serial.println("Switch No. 4 is pressed");
      }else{
        Serial.println("Switch No. 4 is released");
      }
      if(status & SWITCH_COUNTER_5){
        Serial.println("Switch No. 5 is pressed");
      }else{
        Serial.println("Switch No. 5 is released");
      }
      if(status & SWITCH_COUNTER_6){
        Serial.println("Switch No. 6 is pressed");
      }else{
        Serial.println("Switch No. 6 is released");
      }
      if(status & SWITCH_COUNTER_7){
        Serial.println("Switch No. 7 is pressed");
      }else{
        Serial.println("Switch No. 7 is released");
      }
      if(status & SWITCH_COUNTER_8){
        Serial.println("Switch No. 8 is pressed");
      }else{
        Serial.println("Switch No. 8 is released");
      }
      if(status & SWITCH_COUNTER_9){
        Serial.println("Switch No. 9 is pressed");
      }else{
        Serial.println("Switch No. 9 is released");
      }
      if(status & SWITCH_COUNTER_10){
        Serial.println("Switch No. 10 is pressed");
      }else{
        Serial.println("Switch No. 10 is released");
      }
      if(status & SWITCH_COUNTER_11){
        Serial.println("Switch No. 11 is pressed");
      }else{
        Serial.println("Switch No. 11 is released");
      }
      if(status & SWITCH_COUNTER_12){
        Serial.println("Switch No. 12 is pressed");
      }else{
        Serial.println("Switch No. 12 is released");
      }
    }
  }
}

14.2 4G扩展板

14.2.1 API介绍

begin() - 确定模块与主板间通信的uart

语法

  void          begin(HardwareSerial &s_);

参数

传入值 说明 值范围
s_ 串口 指定为Serial1

checkSignalQuality() - 查询信号质量

语法

int      checkSignalQuality(void);

返回值

返回值 说明 值范围
信号质量 0:小于等于-115dBm; 1: -111dBm; 2~30: -109~-53dBm: 31: 大于等于-51dBm; 99: 未知或不可测 int

attachService() - 使模块附着服务

语法

bool     attachService(void);

返回值

返回值 说明 值范围
模块服务状态 true 附着成功,有服务,false附着失败,无服务 true/false

setBaudRate() - 设置主板与4G模块串口通信的波特率

语法

bool     setBaudRate(long rate);

参数

传入值 说明 值范围
rate 串口波特率 1200、2400、4800、9600、19200、38400、57600、115200、230400、460800、921600、

返回值

返回值 说明 值范围
设置状态 true 设置成功,false设置失败 true/false

checkSIMStatus() - 查询SIMS状态

语法

bool     checkSIMStatus(void);

返回值

返回值 说明 值范围
SIMS状态 true 表示PIN码锁并未开启,false表示PIN码锁开启 true/false

openNetwork() - 建立网络连接

语法

bool     openNetwork(Protocol ptl, const char *host, int port);

参数

传入值 说明 值范围
ptl 网络连接模式 TCP\UDP
host 远端服务器 IP 地址 或域名皆可
port 远端服务端口 int

返回值

返回值 说明 值范围
网络连接状态 true 表示连接成功,false表示连接失败 true/false

send() - 发送网络数据

语法

bool     send(void *buffer,size_t len);

参数

传入值 说明 值范围
buffer 数据
len 数据长度

返回值

返回值 说明 值范围
发送结果 true 表示发送成功,false表示发送失败 true/false

recv() - 发送网络数据

语法

int      recv(char* buf, int maxlen, int timeout);

参数

传入值 说明 值范围
buf 接收数据的buffer
maxlen 最大数据长度
timeout 超时时间

返回值

返回值 说明 值范围
接收的数据长度 int

closeNetwork() - 断开网络连接

语法

bool     closeNetwork(void);

返回值

返回值 说明 值范围
网络状态 true 表示断开成功,false表示断开失败 bool

httpInit() - http初始化

语法

bool     httpInit();

返回值

返回值 说明 值范围
http初始化状态 true 表示初始化成功,false表示初始化失败 bool

httpConnect() - 建立http连接

语法

  bool     httpConnect(const char *Host);

参数

传入值 说明 值范围
Host HTTP 或 HTTPS URL

返回值

返回值 说明 值范围
http连接状态 true 表示连接成功,false表示连接失败 bool

httpPost() - 上传http信息

语法

bool     httpPost(const char *Host , String data);

参数

传入值 说明 值范围
Host HTTP 或 HTTPS URL
data 数据

返回值

返回值 说明 值范围
上传数据结果 表示post成功,false表示post失败 bool

httpGet() - 获取http信息

语法

char *   httpGet(const char *Host);

参数

传入值 说明 值范围
Host HTTP 或 HTTPS URL

返回值

返回值 说明 值范围
获得的数据 http information

httpDisconnect() - 断开http连接

语法

void     httpDisconnect(void);

mqttDisonnect() - 断开mqtt连接

语法

bool     mqttDisonnect();

返回值

返回值 说明 值范围
mqtt连接状态 true 表示断开成功,false表示断开失败 bool

mqttIPStart() - 建立mqtt的IP连接

语法

bool     mqttIPStart(const char *host, int port);

参数

传入值 说明 值范围
Host 服务器的ip或者域名
port 端口号

返回值

返回值 说明 值范围
mqtt IP 连接状态 表示连接成功,false表示连接失败 bool

mqttIPClose() - 断开mqtt的IP连接

语法

bool     mqttIPStart(const char *host, int port);

返回值

返回值 说明 值范围
mqtt IP 连接状态 true 表示断开成功,false表示断开失败 bool

mqttConnect() - 建立mqtt连接

语法

bool     mqttConnect(uint16_t keepalive);

参数

传入值 说明 值范围
keepalive 保活时间
时间单位:秒 设备端在保活时间内至少需要发送一次报文,包括PING请求。如果服务器端在保活时间内未接收到任何报文,会断开连接,设备端需要发起重连。建议取值在 300s 以上。
<65535

返回值

返回值 说明 值范围
mqtt 连接状态 true 表示连接成功,false表示连接失败 bool

mqttUNSUB() - 取消订阅主题

语法

bool     mqttUNSUB(char* iot_topic);

参数

传入值 说明 值范围
iot_topic 订阅的主题 char*

返回值

返回值 说明 值范围
取消订阅主题的结果 true 表示取消成功,false表示取消失败 bool

mqttSUB() - 订阅主题

语法

bool     mqttSUB(char* iot_topic,int qos);

参数

传入值 说明 值范围
iot_topic 订阅的主题 char*
qos 应用程序消息的服务质量
0:at most once delivery for application message
1:at least once delivery for application message
2:exactly once delivery for application message
0-2

返回值

返回值 说明 值范围
订阅主题的结果 true 表示订阅成功,false表示订阅失败 bool

mqttPUB() - 发布消息

语法

bool     mqttPUB(char* iot_topic,int qos,int retain,String str);

参数

传入值 说明 值范围
iot_topic 订阅的主题 char*
qos 应用程序消息的服务质量
0:at most once delivery for application message
1:at least once delivery for application message
2:exactly once delivery for application message
0-2
retain retain flag
0: the server will restore the application meassge and its QoS
1: the server must not restore the application meassge and must not remove or replace any existing retained message
0-1
str 发布的消息

返回值

返回值 说明 值范围
发布消息的结果 true 表示发布成功,false表示发布失败 bool

mqttConfig() - mqtt通信配置

语法

bool     mqttConfig(char* iot_client, char* iot_username, char* iot_key);

参数

传入值 说明 值范围
iot_client client identity (最大 256 个字节) char*
iot_username username to login server (最大 256 个字节) char*
iot_key password to login server (最大 256 个字节) char*

返回值

返回值 说明 值范围
发布消息的结果 true 表示配置成功,false表示配置失败 bool

mqttRecv() - mqtt接收订阅主题的消息

语法

bool     mqttRecv(char* iot_topic, char* buf,int maxlen);

参数

传入值 说明 值范围
iot_topic 主题 char*
buf 接收数据的buffer char*
maxlen 接收最大长度 int

返回值

返回值 说明 值范围
接收消息的结果 true 表示接收成功,false表示接收失败 bool

reset() - 模块重启

语法

bool     reset();

返回值

返回值 说明 值范围
重启命令发送的结果 true 表示重启命令发送成功,false表示重启命令发送失败 bool

factoryDataReset() - 模块回复出厂设置并重启

语法

bool     factoryDataReset();

返回值

返回值 说明 值范围
命令发送的结果 true 表示命令发送成功,false表示命令发送失败 bool

getSIMtype() - 获取 SIM 卡类型

语法

int      getSIMtype();

返回值

返回值 说明 值范围
SIM卡类型 0:SIM; 1: USIM。 0-1

setNTP() - 同步网络时间

语法

int      setNTP();

返回值

返回值 说明 值范围
同步结果 1: 网络时间同步成功; 61: 网络错误; 62: DNS 解析错误; 63: 连接错误; 64: 服务响应错误; 65: 服务响应超时; 0-1

getCLK() - 获取时钟

语法

char *   getCLK();

返回值

返回值 说明 值范围
模块系统时间 char *

getLocalIP() - 获取本地ip地址

语法

char *   getLocalIP();

返回值

返回值 说明 值范围
IP地址 char *

queryModuleModel() - 查询模块型号

语法

char *   queryModuleModel();

返回值

返回值 说明 值范围
模块型号 char *

queryModuleVersion() - 查询模块版本信息

语法

char *   queryModuleVersion();

返回值

返回值 说明 值范围
模块版本信息 char *

queryIMEI() - 查询 IMEI 号

语法

char *   queryIMEI();

返回值

返回值 说明 值范围
IMEI 号 char *

querySIMCardICCID() - 查询 SIM 卡 ICCID 号码

语法

char *   querySIMCardICCID();

返回值

返回值 说明 值范围
ICCID 号码 char *

queryFirmWare() - 查询模块 FIRMWARE 版本

语法

char *   queryFirmWare();

返回值

返回值 说明 值范围
FIRMWARE 版本 char *

readLBSInformationAndTime() - 读取基站定位(LBS)信息和时间

语法

char *   readLBSInformationAndTime();

返回值

返回值 说明 值范围
基站定位(LBS)信息和时间 char *

14.2.2 示例程序

例程1:AT指令透传

/*!
 * @file ATTest.ino
 * @brief This example use the serial port to send AT command to control the AIR720UH
 *        With initialization completed, we can enter AT command to AIR720UH directly
 *        Common AT commands : 
 *        AT+CPIN? : Check SIM card
 *        AT+CSQ   : Check signal quality
 *        AT+CGATT?: Check net attached state
 *        AT+CSTT  : Start net connect task
 *        AT+CIFSR : Get local IP
 *        Get the AT command table in Resource folder :Luat 4G模块AT命令手册V4.3.3.pdf
 *        Note  : The AT command must end with CRLF
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
void setup() {
    Serial.begin(115200);
    while(!Serial);
    Serial1.begin(115200);//The 4G module is connected to the Serial1 of the development board
    Serial.println("For example, if you type AT\\r\\n, OK\\r\\n will be responsed!");
    Serial.println("Enter your AT command :");
}

void loop() {
    while(Serial1.available()){
        Serial.write(Serial1.read());
    }
    while(Serial.available()){
        Serial1.write(Serial.read());
    }
}

例程2: 查询模块基础信息

/*!
 * @file basic.ino
 * @brief : This example is used to get basic information about the module and SIM card
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
#include <DFRobot_AIR720UH.h>
DFRobot_AIR720UH      AIR720UH;

void setup(){
    int signalStrength,dataNum;
    Serial.begin(115200);
    Serial1.begin(115200);
    while(!Serial);
    AIR720UH.begin(Serial1);

    char *buff=NULL;
    Serial.print("Module Model:");
    buff=AIR720UH.queryModuleModel();
    if(buff!=NULL){
      Serial.println(buff);
    }else{
      Serial.println("query module model error!");
      while(1);
    }

    Serial.print("Module Version:");
    buff=AIR720UH.queryModuleVersion();
    if(buff!=NULL){
      Serial.println(buff);
    }else{
      Serial.println("query module version error!");
      while(1);
    }

    Serial.print("IMEI:");
    buff=AIR720UH.queryIMEI();
    if(buff!=NULL){
      Serial.println(buff);
    }else{
      Serial.println("query IMEI error!");
      while(1);
    }

    Serial.print("Firmware:");
    buff=AIR720UH.queryFirmWare();
    if(buff!=NULL){
      Serial.println(buff);
    }else{
      Serial.println("query module firmware error!");
      while(1);
    }

    Serial.println("Check SIM card......");
    if(AIR720UH.checkSIMStatus()){                               //Check SIM card
        Serial.println("SIM card READY");
    }else{
        Serial.println("SIM card ERROR, Check if you have insert SIM card and restart AIR720UH");
        while(1);
    }

    Serial.print("SIM type:");
    int data=AIR720UH.getSIMtype();
    if(data==1){
      Serial.println("USIM");
    }else if(data ==0){
      Serial.println("SIM");
    }else{
      Serial.println("get error");
      while(1);
    }

    Serial.print("ICCID:");
    buff=AIR720UH.querySIMCardICCID();
    if(buff!=NULL){
      Serial.println(buff);
    }else{
      Serial.println("query SIM card ICCID error!");
      while(1);
    }

    Serial.println("Get signal quality......");
    delay(500);
    signalStrength=AIR720UH.checkSignalQuality();                //Check signal quality
    Serial.print("signalStrength =");
    Serial.println(signalStrength);
    delay(500);

}

void loop(){
}

例程3: http通信

/*!
 * @file httpTest.ino
 * @brief : This example verify HTTP connection over a HTTP request
 *          With initialization completed, we connect to server POST data and GET data
 *          Thus we finished the HTTP POST and GET verification
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
#include <DFRobot_AIR720UH.h>

#define POSTURL   "https://fanyi.youdao.com/"
#define GETURL    "https://fanyi.youdao.com/"

DFRobot_AIR720UH    AIR720UH;

void setup(){
    int signalStrength,dataNum;
    Serial.begin(115200);
    while(!Serial);
    Serial1.begin(115200);
    AIR720UH.begin(Serial1);

    Serial.println("Check SIM card......");
    if(AIR720UH.checkSIMStatus()){                            //Check SIM card
        Serial.println("SIM card READY");
    }else{
        Serial.println("SIM card ERROR, Check if you have insert SIM card and restart AIR720UH");
        while(1);
    }

    Serial.println("Get signal quality......");
    signalStrength=AIR720UH.checkSignalQuality();             //Check signal quality
    Serial.print("signalStrength =");
    Serial.println(signalStrength);
    delay(500);
    
    Serial.println("Init http......");
    while(1){
        if(AIR720UH.httpInit()){                          //Init http service
            Serial.println("HTTP init !");
            break;
        }else{
            Serial.println("Fail to init http");
        }
    }

    Serial.print("POST to ");
    Serial.println(POSTURL);
    String httpbuff = "English";
    while(1){
        if((httpbuff=AIR720UH.httpPost(POSTURL,httpbuff))!=NULL){              //HTTP POST
            Serial.println("Post successed");
            break;
        }else{
            Serial.println("Fail to post");
        }
    }

    Serial.print("GET from ");
    Serial.println(GETURL);
    Serial.println(AIR720UH.httpGet(GETURL));                  //HTTP GET

    Serial.println("Disconnect");
    AIR720UH.httpDisconnect();                                //Disconnect
    Serial.println("Close net work");
    AIR720UH.closeNetwork();                                  //Close net work
}

void loop() {
}

例程4:TCP通信

/*!
 * @file tcpTest.ino
 * @brief : This example validates the TCP connection. The module will connect to the TCP server (IP:120.76.100.197 PORT:10002) for data interaction
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
#include <Wire.h>
#include <DFRobot_AIR720UH.h>

#define serverIP    "120.76.100.197"
#define serverPort   10002
DFRobot_AIR720UH      AIR720UH;
char                 sendData[100];
char                 buff[100];

void setup(){
    int signalStrength,dataNum;
    Serial.begin(115200);
    Serial1.begin(115200);
    while(!Serial);
    AIR720UH.begin(Serial1);

    Serial.println("Check SIM card......");
    if(AIR720UH.checkSIMStatus()){                               //Check SIM card
        Serial.println("SIM card READY");
    }else{
        Serial.println("SIM card ERROR, Check if you have insert SIM card and restart AIR720UH");
        while(1);
    }
    
    Serial.println("Get signal quality......");
    delay(500);
    signalStrength=AIR720UH.checkSignalQuality();                //Check signal quality
    Serial.print("signalStrength =");
    Serial.println(signalStrength);
    delay(500);

    Serial.println("Attaching service......");
    while(1){
        if(AIR720UH.attachService()){                            //Open the connection
            Serial.println("Attach service");
            Serial.print("Local IP:");
            Serial.println(AIR720UH.getLocalIP());
            break;
        }else{
            Serial.println("Fail to Attach service");
            delay(1000);
        }
    }

}

void loop(){
    delay(2000);
    Serial.println("Connecting......");
    if(AIR720UH.openNetwork(TCP,serverIP,serverPort)){           //Start up TCP connection
        Serial.println("Connect OK");
    }else{
        Serial.println("Fail to connect");
        return;
    }
    while(1){
      Serial.println("Input data :");
      readSerial(sendData);
      Serial.println("Send data :");
      Serial.println(sendData);
      if(AIR720UH.send(sendData,strlen(sendData))){                                 //Send data to server
          Serial.println("Send data, recive :");
          AIR720UH.recv(buff,100,5);
          Serial.println(buff);
          memset(buff,0,100);
      }else{
          Serial.println("Failed to send");
          break;
      }
      delay(500);
    }

    Serial.println("Close connection......");
    if(AIR720UH.closeNetwork()){                                 //End the connection
        Serial.println("Closed !");
    }else{
        Serial.println("Fail to close connection");
    }
}

int readSerial(char result[]){
    int i = 0;
    while(1){
        while(Serial.available() > 0){
            char inChar = Serial.read();
            if(inChar == '\n'){
                result[i] = '\0';
                Serial.flush();
                return 0;
            }
            if(inChar != '\r'){
                result[i] = inChar;
                i++;
            }
        }
    }
}

例程5:mqtt通信

/*!
 * @file mqttTest.ino
 * @brief : This example verify MQTT send verification
 *          With initialization completed, we connect to iot.dfrobot.com.cn
 *          Then send data to a topic
 *          Thus we finished the MQTT send verification
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
#include <DFRobot_AIR720UH.h>

//Login website (http://iot.dfrobot.com.cn) to register an account ,fill the following information based on your account
#define serverIP        "iot.dfrobot.com.cn"
#define IOT_CLIENT      "CLIENT_NAME"
#define IOT_USERNAME    "YOUR_USERNAME"
#define IOT_KEY         "YOUR_KEY"
#define IOT_TOPIC       "YOUR_TOPIC"

DFRobot_AIR720UH         AIR720UH;
String readSerial(){
    int i = 0;
    String result;
    while(1){
        while(Serial.available() > 0){
            char inChar = Serial.read();
            if(inChar == '\n'){
                result += inChar;
                while(Serial.read() >= 0);
                return result;
            }
            if(i == 50){
                Serial.println("The data is too long");
                result += '\0';
                while(Serial.read() >= 0);
                return result;
            }
            result += inChar;
            i++;
        }
    }
}
void setup(){
    int signalStrength;
    Serial.begin(115200);
    while(!Serial);
    Serial1.begin(115200);
    AIR720UH.begin(Serial1);
    Serial.println("Check SIM card......");
    if(AIR720UH.checkSIMStatus()){                                //Check SIM card
        Serial.println("SIM card READY");
    }else{
        Serial.println("SIM card ERROR, Check if you have insert SIM card and restart AIR720UH");
        while(1);
    }

    Serial.println("Get signal quality......");
    delay(500);
    signalStrength=AIR720UH.checkSignalQuality();                 //Check signal quality
    Serial.print("signalStrength =");
    Serial.println(signalStrength);
    delay(500);

    Serial.println("Attaching service......");
    while(1){
        if(AIR720UH.attachService()){                            //Open the connection
            Serial.println("Attach service");
            Serial.print("Local IP:");
            Serial.println(AIR720UH.getLocalIP());
            break;
        }else{
            Serial.println("Fail to Attach service");
            delay(1000);
        }
    }
}

void loop(){
    if(AIR720UH.mqttConfig(IOT_CLIENT,IOT_USERNAME,IOT_KEY)){
        Serial.println("mqttConfig !");
    }else{
        Serial.println("Failed to mqttConfig");
        return;
    }
    delay(200);
    if(AIR720UH.mqttIPStart(serverIP,1883)){                  //Config server
        Serial.println("mqttIPStart !");
    }else{
        Serial.println("Failed to mqttIPStart");
        AIR720UH.mqttIPClose();
        return;
    }
    Serial.print("Connect to :");
    Serial.println(serverIP);
    Serial.print("Connect to : ");
    Serial.println(IOT_USERNAME);
    if(AIR720UH.mqttConnect(60)){                  //Connect to server
        Serial.println("Connected !");
    }else{
        Serial.println("Failed to connect");
        AIR720UH.mqttDisonnect();
        return;
    }
    if(AIR720UH.mqttSUB(IOT_TOPIC,0)){                 //Subscribe to the topic
        Serial.println("mqttSUB OK");
    }else{
        Serial.println("Failed to mqttSUB");
        AIR720UH.mqttDisonnect();
        return;
    }
    Serial.println("Input data end with CRLF : ");
    String sendData;
    sendData= readSerial();
    Serial.print("Send data : ");
    Serial.print(sendData);
    Serial.println(" ......");
    if(AIR720UH.mqttPUB(IOT_TOPIC,0,0,sendData)){                 //Send data to topic
       Serial.println("Send OK");
    }else{
       Serial.println("Failed to send");
       AIR720UH.mqttDisonnect();
       return;
    }
    delay(1000);
    char buf[128];
    if(AIR720UH.mqttRecv(IOT_TOPIC,buf,128)){
       Serial.println("Received a message about the subscription topic:");
       Serial.print(buf);
       memset(buf,0,sizeof(buf));
    }
    delay(200);
    if(AIR720UH.mqttDisonnect()){                                  //Close connection
        Serial.println("Close connection !");
    }else{
        Serial.println("Fail to close connection !");
        return;
    }
    delay(2000);
}

例程6:获取基站位置和时间信息

/*!
 * @file readLBSInformationAndTime.ino
 * @brief : Read base station location (LBS) information and time
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
#include <DFRobot_AIR720UH.h>
DFRobot_AIR720UH      AIR720UH;
void setup(){
    int signalStrength,dataNum;
    Serial.begin(115200);
    Serial1.begin(115200);
    while(!Serial);
    AIR720UH.begin(Serial1);
    Serial.println("Check SIM card......");
    if(AIR720UH.checkSIMStatus()){                               //Check SIM card
        Serial.println("SIM card READY");
    }else{
        Serial.println("SIM card ERROR, Check if you have insert SIM card and restart AIR720UH");
        while(1);
    }
    Serial.println("Get signal quality......");
    delay(500);
    signalStrength=AIR720UH.checkSignalQuality();                //Check signal quality
    Serial.print("signalStrength =");
    Serial.println(signalStrength);
    delay(500);
    Serial.println("Base station location (LBS) information and time:");
}

void loop(){
    char *buff=AIR720UH.readLBSInformationAndTime();
    if(buff!=NULL){
        Serial.println(buff);
    }
    delay(1000);
}

例程7:获取网络时间

/*!
 * @file setNTP.ino
 * @brief : Synchronizing network Time
 * @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
 * @licence The MIT License (MIT)
 * @author [yangfeng]<feng.yang@dfrobot.com>
 * @version V1.0
 * @date 2021-08-18
 */
#include <DFRobot_AIR720UH.h>
DFRobot_AIR720UH      AIR720UH;
void setup(){
    int signalStrength,dataNum;
    Serial.begin(115200);
    Serial1.begin(115200);
    while(!Serial);
    AIR720UH.begin(Serial1);
    Serial.println("Check SIM card......");
    if(AIR720UH.checkSIMStatus()){                               //Check SIM card
        Serial.println("SIM card READY");
    }else{
        Serial.println("SIM card ERROR, Check if you have insert SIM card and restart AIR720UH");
        while(1);
    }
    Serial.println("Get signal quality......");
    delay(500);
    signalStrength=AIR720UH.checkSignalQuality();                //Check signal quality
    Serial.print("signalStrength =");
    Serial.println(signalStrength);
    delay(500);
    Serial.println("set NTP ...");
    while(1){
      int data=AIR720UH.setNTP();
      if(data==1){
        Serial.println("The network time is synchronized successfully!");
        break;
      }else if(data ==61){
        Serial.println("Network error");
        break;
      }else if(data ==62){
        Serial.println("DNS resolution error");
        break;
      }else if(data ==63){
        Serial.println("Connection error");
        break;
      }else if(data ==64){
        Serial.println("Service response error");
        break;
      }else if(data ==65){
        Serial.println("Service response time out");
        break;
      }else{
        Serial.println("set error");
      }
    }
}

void loop(){
  char *buff = AIR720UH.getCLK();
  if(buff!=NULL){
    Serial.println(buff);
  }
}