关闭视频

4G 开发 | 基于GOKIT+GC211的开发指南3,Arduino代码移植编写

发表于:2021年06月28日 11:13更新于:2024年05月03日 16:12

本案例主要讲述了使用GoKit和GC211(4G模块)来实现4G网络的开发。囊括模块接入、设备控制、数据采集、APP开发等方面内容。难度较低,适合新手入门。另外本次内容篇幅较长,将分成五部分来连载。主要是以图文形式呈现,如在实践过程中有疑问,可以加入机智云QQ群一起沟通探讨。

 

本文是连载第三篇!讲的是Arduino版块的移植,让GoKit实现和APP、云端的互联互通。当然,如果你对Arduino不感兴趣,可以不看这个。只看第二篇就够了。

 

连载教程内容:

♦ gokit2/3 实现 4G 网络模块 GC211 的接入

♦ STM32作为主控实现GOKIT全功能控制和采集

♦ Arduino作为主控实现GOKIT全功能控制和采集

♦ 新版本APP快速开发

♦ 网页控制GOKIT开发板

 

 

Arduino代码移植编写

 

通过这一步骤,我们要了解驱动下载地址、如何移植代码,如电机控制、颜色变化、函数初始化等,移植好代码后,为后续的APP应用开发奠定基础。

 

1.下载Arduino驱动文件,机智云下载中心下载。

图片

 

2.将下载的驱动文件解压,将芯片驱动文件复制到安装好的arduino软件的..\libraries目录下。

图片

 

3.将下载的代码进行解压,复制Gizwits到arduino 软件的.. \libraries目录下。

图片

 

4. 使用arduino软件打开下载自动生成代码下载的文件中 MCU_ArduinoUNOR3_source\examples\simpleTry\simpleTry.ino ,然后添加各驱动库的头文件,以及全局变量。

#include <DHT.h>

#include <ChainableLED.h>

#include <MsTimer2.h>

/*************************** HAL define ***************************/

#define Infrared_PIN 2 ///< 红外IO管脚

#define DHTPIN 3 ///< 温湿度IO管脚

#define MOTOR_PINA 4 ///< 电机IO管脚

#define MOTOR_PINB 5 ///< 电机IO管脚

#define KEY1 6 ///< 按键IO管脚

#define KEY2 7 ///< 按键IO管脚

//温湿度功能值定义

#define DHTTYPE DHT11

//电机功能值定义

#define MOTOR_MAX 100

#define MOTOR_MAX1 ‐100

#define MOTOR_MIN 0

#define MOTOR_16

//按键功能值定义

#define KEY1_SHORT_PRESS 1

#define KEY1_LONG_PRESS 2

#define KEY2_SHORT_PRESS 4

#define KEY2_LONG_PRESS 8

#define NO_KEY 0

#define KEY_LONG_TIMER 3

unsigned long Last_KeyTime = 0;

uint8_t NetConfigureFlag = 0;

uint8_t gaterSensorFlag = 0;

typedef enum

{

LED_Costom = 0x00,

LED_Yellow = 0x01,

LED_Purple = 0x02,

LED_Pink = 0x03,

} LED_ColorTypeDef;

DHT dht(DHTPIN, DHTTYPE);

ChainableLED leds(A5, A4, 1);

图片

 

5. 在simpleTry.ino文件中添加温湿度传感器数据获取的函数。

void DHT11_Read_Data(unsigned char * temperature, unsigned char * humidity)

{

 *temperature = (unsigned char)dht.readTemperature();

 *humidity = (unsigned char)dht.readHumidity();

 return;

}

图片

 

6. 在simpleTry.ino文件中添加控制电机的驱动函数

void Motor_status(long motor_speed)

{

 unsigned char Temp_motor_speed = 0;

 if (motor_speed == 0) //停止????

 {

   digitalWrite(MOTOR_PINA, LOW);

   digitalWrite(MOTOR_PINB, LOW);

 }

 if (motor_speed > 0) //正转

 {

   Temp_motor_speed = (motor_speed ‐ 0) * 51;

   if (Temp_motor_speed > 255) Temp_motor_speed = 255;

   digitalWrite(MOTOR_PINA, LOW);

   analogWrite( MOTOR_PINB, Temp_motor_speed);

 }

 if (motor_speed < 0) //反转

 {

   Temp_motor_speed = 255 ‐ (0 ‐ motor_speed) * 51; //Temp_motor_speed = (255 ‐ (5 + motor_speed))

   * 51;

   if (Temp_motor_speed > 255) Temp_motor_speed = 255;

   digitalWrite(MOTOR_PINA, HIGH);

   analogWrite( MOTOR_PINB, Temp_motor_speed );

 }

}

图片

 

7. 在simpleTry.ino文件中添加RGB LED控制函数

void LED_RGB_Control(byte red, byte green, byte blue)

{

 leds.setColorRGB(0, red, green, blue);

}

图片

 

8. 在simpleTry.ino文件中添加按键控制的驱动函数。

unsigned long gokit_time_s(void)

{

 return millis() / 1000;

}

char gokit_key1down(void)

{

 unsigned long keep_time = 0;

 if (digitalRead(KEY1) == LOW)

 {

   delay(100);

   if (digitalRead(KEY1) == LOW)

   {

     keep_time = gokit_time_s();

     while (digitalRead(KEY1) == LOW)

     {

       if ((gokit_time_s() ‐ keep_time) > KEY_LONG_TIMER)

       {

         Last_KeyTime = gokit_time_s();

         return KEY1_LONG_PRESS;

       }

     } //until open the key

     if ((gokit_time_s() ‐ Last_KeyTime) > KEY_LONG_TIMER)

     {

      return KEY1_SHORT_PRESS;

     }

     return 0;

   }

   return 0;

 }

 return 0;

}

 

char gokit_key2down(void)

{

 int unsigned long keep_time = 0;

 if (digitalRead(KEY2) == LOW)

 {

   delay(100);

   if (digitalRead(KEY2) == LOW)

   {

     keep_time = gokit_time_s();

     while (digitalRead(KEY2) == LOW) //until open the key

     {

       if ((gokit_time_s() ‐ keep_time) > KEY_LONG_TIMER)

       {

         Last_KeyTime = gokit_time_s();

         return KEY2_LONG_PRESS;

       }

     }

     if ((gokit_time_s() ‐ Last_KeyTime) > KEY_LONG_TIMER)

     {

       return KEY2_SHORT_PRESS;

     }

     return 0;

   }

   return 0;

 }

 return 0;

}

 

char gokit_keydown(void)

{

 char ret = 0;

 ret |= gokit_key2down();

 ret |= gokit_key1down();

 return ret;

}

 

void KEY_Handle(void)

{

 /* Press for over than 3 second is Long Press */

 switch (gokit_keydown())

 {

   case KEY1_SHORT_PRESS:

     Serial.println(F("KEY1_SHORT_PRESS , Production Test Mode "));

     myGizwits.setBindMode(WIFI_PRODUCTION_TEST);

   break;

   case KEY1_LONG_PRESS:

     Serial.println(F("KEY1_LONG_PRESS ,Wifi Reset"));

     myGizwits.setBindMode(WIFI_RESET_MODE);

   break;

   case KEY2_SHORT_PRESS:

     Serial.println(F("KEY2_SHORT_PRESS Soft AP mode"));

     myGizwits.setBindMode(WIFI_SOFTAP_MODE);

     ///< 进入Soft AP mode RGB LED亮红灯

     NetConfigureFlag = 1; ///< 等待连接路由的标志位

     LED_RGB_Control(100, 0, 0); ///< 红绿灯

     break;

   case KEY2_LONG_PRESS:

     Serial.println(F("KEY2_LONG_PRESS ,AirLink mode"));

     myGizwits.setBindMode(WIFI_AIRLINK_MODE);

     ///< 进入AirLink mode RGB LED亮绿灯

     NetConfigureFlag = 1; ///< 等待连接路由的标志位

     LED_RGB_Control(0, 100, 0); ///< 亮绿灯

     break;

   default:

     break;

 }

}

图片

 

9. 在simpleTry.ino文件中添加WiFi状态事件触发函数

void wifiStatusHandle()

{

 if(myGizwits.wifiHasBeenSet(WIFI_SOFTAP))

   Serial.println(F("WIFI_SOFTAP!"));

 if(myGizwits.wifiHasBeenSet(WIFI_AIRLINK))

   Serial.println(F("WIFI_AIRLINK!"));

 if(myGizwits.wifiHasBeenSet(WIFI_STATION))

   Serial.println(F("WIFI_STATION!"));

 if(myGizwits.wifiHasBeenSet(WIFI_CON_ROUTER))

 {

   Serial.println(F("WIFI_CON_ROUTER!"));

   if(1 == NetConfigureFlag)

   {

     LED_RGB_Control(0, 0, 0); ///< Airlink配置成功即模组连接到路由后关闭绿灯

     NetConfigureFlag = 0;

   }

 }

 if(myGizwits.wifiHasBeenSet(WIFI_DISCON_ROUTER))

   Serial.println(F("WIFI_DISCON_ROUTER!"));

 if(myGizwits.wifiHasBeenSet(WIFI_CON_M2M))

   Serial.println(F("WIFI_CON_M2M!"));

 if(myGizwits.wifiHasBeenSet(WIFI_DISCON_M2M))

   Serial.println(F("WIFI_DISCON_M2M!"));

}

图片

 

10. 在simpleTry.ino文件中添加只读型数据点相关的处理代码

void GizWits_GatherSensorData(void)

{

 uint8_t curTem, curHum;

 bool Infrared;

 //获取红外传感器IO的高低电平状态

 if (digitalRead(Infrared_PIN))

 {

   Infrared = 0;

 }

 else

 {

   Infrared = 1;

 }

 //获取温湿度传感器的数值

 DHT11_Read_Data(&curTem, &curHum);

 myGizwits.write(VALUE_INFRARED, Infrared); ///< 上报红外状态数据

 myGizwits.write(VALUE_TEMPERATURE, (long)curTem); ///< 上报温度数据

 myGizwits.write(VALUE_HUMIDITY, (unsigned long)curHum); ///< 上报湿度数据

}

 

void gokit_timer(void)

{

 static long gaterTime = 0;

 gaterTime++;

 if(gaterTime >= 1000)

 {

   gaterTime = 0;

   gaterSensorFlag = 1;

 }

}

图片

 

11. 在 simpleTry.ino 文件中的loop()函数中添加 间隔一秒的状态机调用,gokit_timer() 函数实现了周期性(这里间隔1秒)获取只读类型数据点的的数据,它是由初始化时的定时器实现的。每隔1秒设置一次gaterSensorFlag 标志位,然后触发 loop() 中的GizWits_GatherSensorData 标志进行数据采集。如果在 loop() 中直接调用例如温湿度这样的时序实现的驱动函数的话,由于loop执行过快会造成读传感器的异常,同时也避免了上报数据过频繁造成的问题 。

 if (gaterSensorFlag != 0)

 {

   GizWits_GatherSensorData();

   gaterSensorFlag = 0;

 }

图片

 

12. 在simpleTry.ino文件中的loop()函数中添加可写型传感器数据点相关的处理代码,通过myGizwits.hasBeenSet()这个方法判断这个数据点事件有是否发生,如果数据点事件发生了就通过myGizwits.read()这个方法把发生的事件所产生的数据读取出来,然后再做相应的判断。

图片

图片

 

13. 在simpleTry.ino文件中的loop()函数中添加WiFi状态事件触发函数 、按键控制的驱动函数的调用。

图片

 

14. 在simpleTry.ino文件的setup( )函数中添加各sensor的初始化

 Serial.begin(9600);

 myGizwits.begin();

 ///< 温度传感初始

 dht.begin();

 ///< RGB LED初始

 leds.init();

 digitalWrite(A0, HIGH);//使能RGB LED

 ///< 新添加代码: 按键初始

 pinMode(KEY1, INPUT_PULLUP); //KEY1 上拉输入

 pinMode(KEY2, INPUT_PULLUP); //KEY2 上拉输入

 ///< 电机初始化

 pinMode(MOTOR_PINA, OUTPUT);

 pinMode(MOTOR_PINB, OUTPUT);

 digitalWrite(MOTOR_PINB, LOW);

 digitalWrite(MOTOR_PINA, LOW);

 Motor_status(0);

 //定时中断初始

 MsTimer2::set(1, gokit_timer); // 1ms period

 MsTimer2::start();

图片

 

15. 编写完成之后将代码上传到开发板。特别提示,不要再网页上复制代码,否则大小或者写不对会导致编译无法通过,可参考源文件中的代码。

图片

然后按照第二篇文档STM32方式连接开发板即可,到此教程结束。