From 6f607f04f508e79851c1708e05bb82ff9bc1aa6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Criver=E2=80=9D?= <“1345048433@qq.com”> Date: Wed, 5 Jul 2023 09:45:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=91=E5=B9=B3=E5=8F=B0=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=EF=BC=8C=E6=B8=A9=E6=B9=BF=E5=BA=A6=E7=9B=91=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cloud_SHT30/BUILD.gn | 32 +++ cloud_SHT30/include/E53_IA1.h | 84 +++++++ cloud_SHT30/include/wifi_connect.h | 21 ++ cloud_SHT30/iot_cloud_oc_sample.c | 387 +++++++++++++++++++++++++++++ cloud_SHT30/src/E53_IA1.c | 304 ++++++++++++++++++++++ cloud_SHT30/src/wifi_connect.c | 233 +++++++++++++++++ 6 files changed, 1061 insertions(+) create mode 100644 cloud_SHT30/BUILD.gn create mode 100644 cloud_SHT30/include/E53_IA1.h create mode 100644 cloud_SHT30/include/wifi_connect.h create mode 100644 cloud_SHT30/iot_cloud_oc_sample.c create mode 100644 cloud_SHT30/src/E53_IA1.c create mode 100644 cloud_SHT30/src/wifi_connect.c diff --git a/cloud_SHT30/BUILD.gn b/cloud_SHT30/BUILD.gn new file mode 100644 index 0000000..41427e0 --- /dev/null +++ b/cloud_SHT30/BUILD.gn @@ -0,0 +1,32 @@ +config_file = [ "../../third_party/libs/libiot_link.a" ] +copy("config") { + sources = config_file + outputs = [ "//out/qihang/qihang/libs/{{source_file_part}}" ] +} + + +static_library("Iot_cloud_oc_sample") { + sources = [ + "//device/board/isoftstone/qihang/app/cloud_SHT30/src/E53_IA1.c", + "//device/board/isoftstone/qihang/app/cloud_SHT30/src/wifi_connect.c", + "//device/board/isoftstone/qihang/app/cloud_SHT30/iot_cloud_oc_sample.c", + + ] + + + include_dirs = [ + "//base/iot_hardware/peripheral/interfaces/kits", + "../../iot_hardware_hals/include", + "//device/board/isoftstone/qihang/app/cloud_SHT30/include", + #MQTT includes + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//third_party/cJSON", + "//device/board/isoftstone/qihang/third_party/iot_link/oc_mqtt/oc_mqtt_al", + "//device/board/isoftstone/qihang/third_party/iot_link/oc_mqtt/oc_mqtt_profile_v5", + "//device/board/isoftstone/qihang/third_party/iot_link/inc", + + #"include", + ] + #MQTT links + deps = [ ":config" ] +} diff --git a/cloud_SHT30/include/E53_IA1.h b/cloud_SHT30/include/E53_IA1.h new file mode 100644 index 0000000..9275c33 --- /dev/null +++ b/cloud_SHT30/include/E53_IA1.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __E53_IA1_H__ +#define __E53_IA1_H__ + +/* 寄存器宏定义 --------------------------------------------------------------------*/ +#define BH1750_ADDR 0x23 +#define BH1750_SEND_DATA_LEN 2 +#define BH1750_RECV_DATA_LEN 2 +#define BH1750_READ_DELAY_US 180000 +#define BH1750_COEFFICIENT_LUX 1.2 + +#define SHT30_ADDR 0x44 +#define SHT30_SEND_DATA_LEN 2 +#define SHT30_TEMP_DATA_LEN 2 +#define SHT30_HUM_DATA_LEN 2 +#define SHT30_CONSTANT_1 175 +#define SHT30_CONSTANT_2 45 +#define SHT30_CONSTANT_3 100 + +#define DATA_WIDTH_8_BIT 8 // 8 bit + +#define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6 +#define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6 +#define WIFI_IOT_IO_FUNC_GPIO_8_GPIO 0 +#define WIFI_IOT_IO_FUNC_GPIO_14_GPIO 4 +#define WIFI_IOT_I2C_IDX_1 1 +#define WIFI_IOT_I2C_BAUDRATE 400000 + +#define E53_IA1_LIGHT_GPIO 5 +#define E53_IA1_MOTOR_GPIO 2 +#define E53_IA1_I2C1_SDA_GPIO 0 +#define E53_IA1_I2C1_SCL_GPIO 1 + +typedef enum { + OFF = 0, + ON +} E53IA1Status; + +/* E53_IA1传感器数据类型定义 ------------------------------------------------------------*/ +typedef struct { + float Lux; // 光照强度 + float Humidity; // 湿度 + float Temperature; // 温度 +} E53IA1Data; + +enum CheckDataPart { + DATA_LSB = 0, + DATA_MSB = 1, + DATA_CHECK = 2, + CHECK_DATA_BUTT, +}; + +enum Sht3xDataBufferPart { + TEMP_LSB = 0, + TEMP_MSB = 1, + TEMP_HSB = 2, + HUM_LSB = 3, + HUM_MSB = 4, + HUM_HSB = 5, + SHT3X_DATA_BUTT, +}; + +int E53IA1Init(void); +int E53IA1ReadData(E53IA1Data *ReadData); +void LightStatusSet(E53IA1Status status); +void MotorStatusSet(E53IA1Status status); + + +#endif /* __E53_IA1_H__ */ + diff --git a/cloud_SHT30/include/wifi_connect.h b/cloud_SHT30/include/wifi_connect.h new file mode 100644 index 0000000..618645b --- /dev/null +++ b/cloud_SHT30/include/wifi_connect.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __WIFI_CONNECT_H__ +#define __WIFI_CONNECT_H__ + +int WifiConnect(const char *ssid, const char *psk); + +#endif /* __WIFI_CONNECT_H__ */ diff --git a/cloud_SHT30/iot_cloud_oc_sample.c b/cloud_SHT30/iot_cloud_oc_sample.c new file mode 100644 index 0000000..b9317af --- /dev/null +++ b/cloud_SHT30/iot_cloud_oc_sample.c @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "cmsis_os2.h" +#include "ohos_init.h" + +#include +#include +#include +#include +#include "E53_IA1.h" +#include "wifi_connect.h" + +#define CONFIG_WIFI_SSID "Alice" // 修改为自己的WiFi 热点账号 +#define CONFIG_WIFI_PWD "31415926" // 修改为自己的WiFi 热点密码 +#define CONFIG_APP_SERVERIP "fc3556d708.st1.iotda-device.cn-south-1.myhuaweicloud.com" +#define CONFIG_APP_SERVERPORT "1883" +#define CONFIG_APP_DEVICEID "64a390420d8c4759720806d9_1688441918253" // 替换为注册设备后生成的deviceid +#define CONFIG_APP_DEVICEPWD "12345678" // 替换为注册设备后生成的密钥 +#define CONFIG_APP_LIFETIME 60 // seconds +#define CONFIG_QUEUE_TIMEOUT (5 * 1000) +#define MSGQUEUE_COUNT 16 +#define MSGQUEUE_SIZE 10 +#define CLOUD_TASK_STACK_SIZE (1024 * 10) +#define CLOUD_TASK_PRIO 24 +#define SENSOR_TASK_STACK_SIZE (1024 * 4) +#define SENSOR_TASK_PRIO 25 +#define TASK_DELAY 3 + +osMessageQueueId_t mid_MsgQueue; // message queue id +typedef enum { + en_msg_cmd = 0, + en_msg_report, + en_msg_conn, + en_msg_disconn, +} en_msg_type_t; + +typedef struct { + char *request_id; + char *payload; +} cmd_t; + +typedef struct { + int lum; + int temp; + int hum; +} report_t; + +typedef struct { + en_msg_type_t msg_type; + union { + cmd_t cmd; + report_t report; + } msg; +} app_msg_t; + +typedef struct { + osMessageQueueId_t app_msg; + int connected; + int led; + int motor; +} app_cb_t; +static app_cb_t g_app_cb; + +static void deal_report_msg(report_t *report) +{ + oc_mqtt_profile_service_t service; + oc_mqtt_profile_kv_t temperature; + oc_mqtt_profile_kv_t humidity; + oc_mqtt_profile_kv_t luminance; + oc_mqtt_profile_kv_t led; + oc_mqtt_profile_kv_t motor; + + if (g_app_cb.connected != 1) { + return; + } + + service.event_time = NULL; + service.service_id = "15322"; + service.service_property = &temperature; + service.nxt = NULL; + + temperature.key = "temperature"; + temperature.value = &report->temp; + temperature.type = EN_OC_MQTT_PROFILE_VALUE_INT; + temperature.nxt = &humidity; + + humidity.key = "humidity"; + humidity.value = &report->hum; + humidity.type = EN_OC_MQTT_PROFILE_VALUE_INT; + humidity.nxt = &luminance; + + luminance.key = "Luminance"; + luminance.value = &report->lum; + luminance.type = EN_OC_MQTT_PROFILE_VALUE_INT; + luminance.nxt = &led; + + led.key = "LightStatus"; + led.value = g_app_cb.led ? "ON" : "OFF"; + led.type = EN_OC_MQTT_PROFILE_VALUE_STRING; + led.nxt = &motor; + + motor.key = "fengshan"; + motor.value = g_app_cb.motor ? "ON" : "OFF"; + motor.type = EN_OC_MQTT_PROFILE_VALUE_STRING; + motor.nxt = NULL; + + oc_mqtt_profile_propertyreport(NULL, &service); + return; +} + +// use this function to push all the message to the buffer +static int msg_rcv_callback(oc_mqtt_profile_msgrcv_t *msg) +{ + int ret = 0; + char *buf; + int buf_len; + app_msg_t *app_msg; + + if ((msg == NULL) || (msg->request_id == NULL) || (msg->type != EN_OC_MQTT_PROFILE_MSG_TYPE_DOWN_COMMANDS)) { + return ret; + } + + buf_len = sizeof(app_msg_t) + strlen(msg->request_id) + 1 + msg->msg_len + 1; + buf = malloc(buf_len); + if (buf == NULL) { + return ret; + } + app_msg = (app_msg_t *)buf; + buf += sizeof(app_msg_t); + + app_msg->msg_type = en_msg_cmd; + app_msg->msg.cmd.request_id = buf; + buf_len = strlen(msg->request_id); + buf += buf_len + 1; + memcpy_s(app_msg->msg.cmd.request_id, buf_len, msg->request_id, buf_len); + app_msg->msg.cmd.request_id[buf_len] = '\0'; + + buf_len = msg->msg_len; + app_msg->msg.cmd.payload = buf; + memcpy_s(app_msg->msg.cmd.payload, buf_len, msg->msg, buf_len); + app_msg->msg.cmd.payload[buf_len] = '\0'; + + ret = osMessageQueuePut(g_app_cb.app_msg, &app_msg, 0U, CONFIG_QUEUE_TIMEOUT); + if (ret != 0) { + free(app_msg); + } + + return ret; +} + +static void oc_cmdresp(cmd_t *cmd, int cmdret) +{ + oc_mqtt_profile_cmdresp_t cmdresp; + ///< do the response + cmdresp.paras = NULL; + cmdresp.request_id = cmd->request_id; + cmdresp.ret_code = cmdret; + cmdresp.ret_name = NULL; + (void)oc_mqtt_profile_cmdresp(NULL, &cmdresp); +} + +///< COMMAND DEAL +#include +static void deal_light_cmd(cmd_t *cmd, cJSON *obj_root) +{ + cJSON *obj_paras; + cJSON *obj_para; + int cmdret; + + obj_paras = cJSON_GetObjectItem(obj_root, "paras"); + if (obj_paras == NULL) { + cJSON_Delete(obj_root); + } + obj_para = cJSON_GetObjectItem(obj_paras, "Light"); + if (obj_paras == NULL) { + cJSON_Delete(obj_root); + } + ///< operate the LED here + if (strcmp(cJSON_GetStringValue(obj_para), "ON") == 0) { + g_app_cb.led = 1; + LightStatusSet(ON); + printf("Light On!\r\n"); + } else { + g_app_cb.led = 0; + LightStatusSet(OFF); + printf("Light Off!\r\n"); + } + cmdret = 0; + oc_cmdresp(cmd, cmdret); + + cJSON_Delete(obj_root); + return; +} + +static void deal_motor_cmd(cmd_t *cmd, cJSON *obj_root) +{ + cJSON *obj_paras; + cJSON *obj_para; + int cmdret; + + obj_paras = cJSON_GetObjectItem(obj_root, "Paras"); + if (obj_paras == NULL) { + cJSON_Delete(obj_root); + } + obj_para = cJSON_GetObjectItem(obj_paras, "Motor"); + if (obj_para == NULL) { + cJSON_Delete(obj_root); + } + ///< operate the Motor here + if (strcmp(cJSON_GetStringValue(obj_para), "ON") == 0) { + g_app_cb.motor = 1; + MotorStatusSet(ON); + printf("Motor On!\r\n"); + } else { + g_app_cb.motor = 0; + MotorStatusSet(OFF); + printf("Motor Off!\r\n"); + } + cmdret = 0; + oc_cmdresp(cmd, cmdret); + + cJSON_Delete(obj_root); + return; +} + +static void deal_cmd_msg(cmd_t *cmd) +{ + cJSON *obj_root; + cJSON *obj_cmdname; + + int cmdret = 1; + obj_root = cJSON_Parse(cmd->payload); + if (obj_root == NULL) { + oc_cmdresp(cmd, cmdret); + } + obj_cmdname = cJSON_GetObjectItem(obj_root, "command_name"); + if (obj_cmdname == NULL) { + cJSON_Delete(obj_root); + } + if (strcmp(cJSON_GetStringValue(obj_cmdname), "Agriculture_Control_light") == 0) { + deal_light_cmd(cmd, obj_root); + } else if (strcmp(cJSON_GetStringValue(obj_cmdname), "Agriculture_Control_Motor") == 0) { + deal_motor_cmd(cmd, obj_root); + } + + return; +} + +static int CloudMainTaskEntry(void) +{ + app_msg_t *app_msg; + uint32_t ret; + + WifiConnect(CONFIG_WIFI_SSID, CONFIG_WIFI_PWD); + dtls_al_init(); + mqtt_al_init(); + oc_mqtt_init(); + + g_app_cb.app_msg = osMessageQueueNew(MSGQUEUE_COUNT, MSGQUEUE_SIZE, NULL); + if (g_app_cb.app_msg == NULL) { + printf("Create receive msg queue failed"); + } + oc_mqtt_profile_connect_t connect_para; + (void)memset_s(&connect_para, sizeof(connect_para), 0, sizeof(connect_para)); + + connect_para.boostrap = 0; + connect_para.device_id = CONFIG_APP_DEVICEID; + connect_para.device_passwd = CONFIG_APP_DEVICEPWD; + connect_para.server_addr = CONFIG_APP_SERVERIP; + connect_para.server_port = CONFIG_APP_SERVERPORT; + connect_para.life_time = CONFIG_APP_LIFETIME; + connect_para.rcvfunc = msg_rcv_callback; + connect_para.security.type = EN_DTLS_AL_SECURITY_TYPE_NONE; + ret = oc_mqtt_profile_connect(&connect_para); + if ((ret == (int)en_oc_mqtt_err_ok)) { + g_app_cb.connected = 1; + printf("oc_mqtt_profile_connect succed!\r\n"); + } else { + printf("oc_mqtt_profile_connect faild!\r\n"); + } + + while (1) { + app_msg = NULL; + (void)osMessageQueueGet(g_app_cb.app_msg, (void **)&app_msg, NULL, 0xFFFFFFFF); + if (app_msg != NULL) { + switch (app_msg->msg_type) { + case en_msg_cmd: + deal_cmd_msg(&app_msg->msg.cmd); + break; + case en_msg_report: + deal_report_msg(&app_msg->msg.report); + break; + default: + break; + } + free(app_msg); + } + } + return 0; +} + +static int SensorTaskEntry(void) +{ + app_msg_t *app_msg; + int ret; + E53IA1Data data; + + ret = E53IA1Init(); + if (ret != 0) { + printf("E53_IA1 Init failed!\r\n"); + return; + } + while (1) { + ret = E53IA1ReadData(&data); + if (ret != 0) { + printf("E53_IA1 Read Data failed!\r\n"); + return; + } + app_msg = malloc(sizeof(app_msg_t)); + printf("SENSOR:lum:%.2f temp:%.2f hum:%.2f\r\n", data.Lux, data.Temperature, data.Humidity); + if(data.Humidity>=60) + { + g_app_cb.motor = 1; + MotorStatusSet(ON); + printf("风扇开\r\n"); + + }else{ + g_app_cb.motor = 0; + MotorStatusSet(OFF); + printf("风扇关\r\n"); + } + if (app_msg != NULL) { + app_msg->msg_type = en_msg_report; + app_msg->msg.report.hum = (int)data.Humidity; + app_msg->msg.report.lum = (int)data.Lux; + app_msg->msg.report.temp = (int)data.Temperature; + + if (osMessageQueuePut(g_app_cb.app_msg, &app_msg, 0U, CONFIG_QUEUE_TIMEOUT != 0)) { + free(app_msg); + } + } + sleep(TASK_DELAY); + } + return 0; +} + +static void IotMainTaskEntry(void) +{ + osThreadAttr_t attr; + + attr.name = "CloudMainTaskEntry"; + attr.attr_bits = 0U; + attr.cb_mem = NULL; + attr.cb_size = 0U; + attr.stack_mem = NULL; + attr.stack_size = CLOUD_TASK_STACK_SIZE; + attr.priority = CLOUD_TASK_PRIO; + + if (osThreadNew((osThreadFunc_t)CloudMainTaskEntry, NULL, &attr) == NULL) { + printf("Failed to create CloudMainTaskEntry!\n"); + } + attr.stack_size = SENSOR_TASK_STACK_SIZE; + attr.priority = SENSOR_TASK_PRIO; + attr.name = "SensorTaskEntry"; + if (osThreadNew((osThreadFunc_t)SensorTaskEntry, NULL, &attr) == NULL) { + printf("Failed to create SensorTaskEntry!\n"); + } +} + +APP_FEATURE_INIT(IotMainTaskEntry); \ No newline at end of file diff --git a/cloud_SHT30/src/E53_IA1.c b/cloud_SHT30/src/E53_IA1.c new file mode 100644 index 0000000..1b7ae35 --- /dev/null +++ b/cloud_SHT30/src/E53_IA1.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "cmsis_os2.h" +#include "iot_errno.h" +#include "iot_gpio.h" +#include "iot_gpio_ex.h" +#include "iot_i2c.h" +#include "iot_i2c_ex.h" +#include "E53_IA1.h" + +/*************************************************************** + * 函数名称: E53IA1IoInit + * 说 明: E53_IA1 GPIO初始化 + * 参 数: 无 + * 返 回 值: 无 + ***************************************************************/ +static void E53IA1IoInit(void) +{ + IoTGpioInit(E53_IA1_MOTOR_GPIO); + IoTGpioSetFunc(E53_IA1_MOTOR_GPIO,IOT_GPIO_FUNC_GPIO_2_GPIO); + IoTGpioSetDir(E53_IA1_MOTOR_GPIO, IOT_GPIO_DIR_OUT); // 设置GPIO_2为输出模式 + + IoTGpioInit(E53_IA1_LIGHT_GPIO); + IoTGpioSetFunc(E53_IA1_LIGHT_GPIO, IOT_GPIO_FUNC_GPIO_5_GPIO); + IoTGpioSetDir(E53_IA1_LIGHT_GPIO, IOT_GPIO_DIR_OUT); // 设置GPIO_5为输出模式 + + IoTGpioInit(E53_IA1_I2C1_SDA_GPIO); + IoTGpioSetFunc(E53_IA1_I2C1_SDA_GPIO, IOT_GPIO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA + IoTGpioInit(E53_IA1_I2C1_SCL_GPIO); + IoTGpioSetFunc(E53_IA1_I2C1_SCL_GPIO, IOT_GPIO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL + IoTI2cInit(WIFI_IOT_I2C_IDX_1, WIFI_IOT_I2C_BAUDRATE); +} + +/*************************************************************** + * 函数名称: Init_BH1750 + * 说 明: 写命令初始化BH1750 + * 参 数: 无 + * 返 回 值: 0 成功; -1 失败 + ***************************************************************/ +static int InitBH1750(void) +{ + int ret; + uint8_t send_data[1] = { 0x01 }; + ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (BH1750_ADDR << 1) | 0x00, send_data, 1); + if (ret != 0) { + printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret); + return -1; + } + return 0; +} + +/*************************************************************** + * 函数名称: StartBH1750 + * 说 明: 启动BH1750 + * 参 数: 无 + * 返 回 值: 0 成功; -1 失败 + ***************************************************************/ +static int StartBH1750(void) +{ + int ret; + uint8_t send_data[1] = { 0x10 }; + ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (BH1750_ADDR << 1) | 0x00, send_data, 1); + if (ret != 0) { + printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret); + return -1; + } + return 0; +} + +/*************************************************************** + * 函数名称: SHT30Reset + * 说 明: SHT30复位 + * 参 数: 无 + * 返 回 值: 0 成功; -1 失败 + ***************************************************************/ +static int SHT30Reset(void) +{ + int ret; + uint8_t send_data[BH1750_SEND_DATA_LEN] = { 0x30, 0xA2 }; + ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (SHT30_ADDR << 1) | 0x00, send_data, sizeof(send_data)); + if (ret != 0) { + printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret); + return -1; + } + return 0; +} + +/*************************************************************** + * 函数名称: InitSHT30 + * 说 明: 初始化SHT30,设置测量周期 + * 参 数: 无 + * 返 回 值: 无 + ***************************************************************/ +static int InitSHT30(void) +{ + int ret; + uint8_t send_data[BH1750_SEND_DATA_LEN] = { 0x22, 0x36 }; + ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (SHT30_ADDR << 1) | 0x00, send_data, sizeof(send_data)); + if (ret != 0) { + printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret); + return -1; + } + return 0; +} + +/*************************************************************** +* 函数名称: SHT3xCheckCrc +* 说 明: 检查数据正确性 +* 参 数: data:读取到的数据 + nbrOfBytes:需要校验的数量 + checksum:读取到的校对比验值 +* 返 回 值: 校验结果,0-成功 1-失败 +***************************************************************/ +static uint8_t SHT3xCheckCrc(uint8_t data[], uint8_t nbrOfBytes, uint8_t checksum) +{ + uint8_t crc = 0xFF; + uint8_t bit = 0; + uint8_t byteCtr; + const int16_t POLYNOMIAL = 0x131; + // calculates 8-Bit checksum with given polynomial + for (byteCtr = 0; byteCtr < nbrOfBytes; ++byteCtr) { + crc ^= (data[byteCtr]); + for (bit = DATA_WIDTH_8_BIT; bit > 0; --bit) { + if (crc & 0x80) + crc = (crc << 1) ^ POLYNOMIAL; + else + crc = (crc << 1); + } + } + + if (crc != checksum) + return 1; + else + return 0; +} + +/*************************************************************** + * 函数名称: SHT3xCalcTemperatureC + * 说 明: 温度计算 + * 参 数: u16sT:读取到的温度原始数据 + * 返 回 值: 计算后的温度数据 + ***************************************************************/ +static float SHT3xCalcTemperatureC(uint16_t u16sT) +{ + float temperatureC = 0; // variable for result + u16sT &= ~0x0003; // clear bits [1..0] (status bits) + // -- calculate temperature [℃] -- + temperatureC = (SHT30_CONSTANT_1 * (float)u16sT / 0xffff - SHT30_CONSTANT_2); // T = -45 + 175 * rawValue / (2^16-1) + return temperatureC; +} + +/*************************************************************** + * 函数名称: SHT3xCalcRH + * 说 明: 湿度计算 + * 参 数: u16sRH:读取到的湿度原始数据 + * 返 回 值: 计算后的湿度数据 + ***************************************************************/ +static float SHT3xCalcRH(uint16_t u16sRH) +{ + float humidityRH = 0; // variable for result + u16sRH &= ~0x0003; // clear bits [1..0] (status bits) + // -- calculate relative humidity [%RH] -- + humidityRH = (SHT30_CONSTANT_3 * (float)u16sRH / 0xffff); // RH = rawValue / (2^16-1) * 10 + return humidityRH; +} + +/*************************************************************** + * 函数名称: E53IA1Init + * 说 明: 初始化E53_IA1 + * 参 数: 无 + * 返 回 值: 0 成功; -1 失败 + ***************************************************************/ +int E53IA1Init(void) +{ + int ret; + E53IA1IoInit(); + ret = InitBH1750(); + if (ret != 0) { + printf("Init BH1750 failed!\r\n"); + return -1; + } + ret = InitSHT30(); + if (ret != 0) { + printf("Init SHT30 failed!\r\n"); + return -1; + } +} + +/*************************************************************** + * 函数名称: E53IA1ReadData + * 说 明: 测量光照强度、温度、湿度 + * 参 数: ReadData,光照强度、温度、湿度数据 + * 返 回 值: 0 成功; -1 失败 + ***************************************************************/ +int E53IA1ReadData(E53IA1Data *ReadData) +{ + int ret; + ret = StartBH1750(); // 启动传感器采集数据 + if (ret != 0) { + printf("Start BH1750 failed!\r\n"); + return -1; + } + usleep(BH1750_READ_DELAY_US); + uint8_t recv_data[BH1750_RECV_DATA_LEN] = { 0 }; + ret = IoTI2cRead(WIFI_IOT_I2C_IDX_1, (BH1750_ADDR << 1) | 0x01, recv_data, sizeof(recv_data)); // 读取传感器数据 + if (ret != 0) { + return -1; + } + ReadData->Lux = (float)(((recv_data[0] << DATA_WIDTH_8_BIT) + recv_data[1]) / BH1750_COEFFICIENT_LUX); + + uint8_t data[CHECK_DATA_BUTT]; // data array for checksum verification + uint16_t dat, tmp; + uint8_t SHT3X_Data_Buffer[SHT3X_DATA_BUTT]; // byte 0,1 is temperature byte 4,5 is humidity + + IotI2cData sht30_i2c_data = { 0 }; + uint8_t send_data[SHT30_SEND_DATA_LEN] = { 0xE0, 0x00 }; + sht30_i2c_data.sendBuf = send_data; + sht30_i2c_data.sendLen = sizeof(send_data); + sht30_i2c_data.receiveBuf = SHT3X_Data_Buffer; + sht30_i2c_data.receiveLen = sizeof(SHT3X_Data_Buffer); + ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (SHT30_ADDR << 1) | 0x00, &sht30_i2c_data); // Read bh1750 sensor data + if (ret != 0) { + return -1; + } + /* check tem */ + data[DATA_LSB] = SHT3X_Data_Buffer[TEMP_LSB]; + data[DATA_MSB] = SHT3X_Data_Buffer[TEMP_MSB]; + data[DATA_CHECK] = SHT3X_Data_Buffer[TEMP_HSB]; + + tmp = SHT3xCheckCrc(data, SHT30_TEMP_DATA_LEN, data[DATA_CHECK]); + /* value is ture */ + if (!tmp) { + dat = ((uint16_t)data[0] << DATA_WIDTH_8_BIT) | data[1]; + ReadData->Temperature = SHT3xCalcTemperatureC(dat); + } + + /* check humidity */ + data[DATA_LSB] = SHT3X_Data_Buffer[HUM_LSB]; + data[DATA_MSB] = SHT3X_Data_Buffer[HUM_MSB]; + data[DATA_CHECK] = SHT3X_Data_Buffer[HUM_HSB]; + /* value is ture */ + tmp = SHT3xCheckCrc(data, SHT30_HUM_DATA_LEN, data[DATA_CHECK]); + if (!tmp) { + dat = ((uint16_t)data[0] << DATA_WIDTH_8_BIT) | data[1]; + ReadData->Humidity = SHT3xCalcRH(dat); + } + return 0; +} + +/*************************************************************** + * 函数名称: LightStatusSet + * 说 明: 灯状态设置 + * 参 数: status,ENUM枚举的数据 + * OFF,关 + * ON,开 + * 返 回 值: 无 + ***************************************************************/ +void LightStatusSet(E53IA1Status status) +{ + if (status == ON) { + IoTGpioSetOutputVal(E53_IA1_LIGHT_GPIO, 1); // 设置GPIO_14输出高电平点亮灯 + } + + if (status == OFF) { + IoTGpioSetOutputVal(E53_IA1_LIGHT_GPIO, 0); // 设置GPIO_14输出低电平关闭灯 + } +} + +/*************************************************************** + * 函数名称: MotorStatusSet + * 说 明: 电机状态设置 + * 参 数: status,ENUM枚举的数据 + * OFF,关 + * ON,开 + * 返 回 值: 无 + ***************************************************************/ +void MotorStatusSet(E53IA1Status status) +{ + if (status == ON) { + IoTGpioSetOutputVal(E53_IA1_MOTOR_GPIO, 1); // 设置GPIO_8输出高电平打开电机 + } + + if (status == OFF) { + IoTGpioSetOutputVal(E53_IA1_MOTOR_GPIO, 0); // 设置GPIO_8输出低电平关闭电机 + } +} diff --git a/cloud_SHT30/src/wifi_connect.c b/cloud_SHT30/src/wifi_connect.c new file mode 100644 index 0000000..76ad7a6 --- /dev/null +++ b/cloud_SHT30/src/wifi_connect.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "lwip/api_shell.h" +#include "lwip/ip4_addr.h" +#include "lwip/netif.h" +#include "lwip/netifapi.h" + +#include "cmsis_os2.h" +#include "ohos_init.h" +#include "wifi_device.h" +#include "wifi_error_code.h" + +#define DEF_TIMEOUT 15 +#define ONE_SECOND 1 +#define DHCP_DELAY 100 + +static int WiFiInit(void); +static void WaitSacnResult(void); +static int WaitConnectResult(void); +static void OnWifiScanStateChangedHandler(int state, int size); +static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info); +static void OnHotspotStaJoinHandler(StationInfo *info); +static void OnHotspotStateChangedHandler(int state); +static void OnHotspotStaLeaveHandler(StationInfo *info); + +static int g_staScanSuccess = 0; +static int g_ConnectSuccess = 0; +static int g_ssid_count = 0; +static struct netif *g_lwip_netif = NULL; +static WifiEvent g_wifiEventHandler = { 0 }; +WifiErrorCode error; + +#define SELECT_WLAN_PORT "wlan0" + + +int WifiConnectAp(const char *ssid, const char *psk, WifiScanInfo *info, int i) +{ + if (strcmp(ssid, info[i].ssid) == 0) { + int result; + printf("Select:%3d wireless, Waiting...\r\n", i + 1); + + // 拷贝要连接的热点信息 + WifiDeviceConfig select_ap_config = { 0 }; + strcpy_s(select_ap_config.ssid, sizeof(select_ap_config.ssid), info[i].ssid); + strcpy_s(select_ap_config.preSharedKey, sizeof(select_ap_config.preSharedKey), psk); + select_ap_config.securityType = WIFI_SEC_TYPE_PSK; + + if (AddDeviceConfig(&select_ap_config, &result) == WIFI_SUCCESS) { + if (ConnectTo(result) == WIFI_SUCCESS && WaitConnectResult() == 1) { + g_lwip_netif = netifapi_netif_find(SELECT_WLAN_PORT); + return 0; + } + } + } + return -1; +} + +int WifiConnect(const char *ssid, const char *psk) +{ + unsigned int size = WIFI_SCAN_HOTSPOT_LIMIT; + + // 初始化WIFI + if (WiFiInit() != WIFI_SUCCESS) { + printf("WiFiInit failed, error = %d\r\n", error); + return -1; + } + // 分配空间,保存WiFi信息 + WifiScanInfo *info = malloc(sizeof(WifiScanInfo) * WIFI_SCAN_HOTSPOT_LIMIT); + if (info == NULL) { + return -1; + } + // 轮询查找WiFi列表 + do { + Scan(); + WaitSacnResult(); + error = GetScanInfoList(info, &size); + } while (g_staScanSuccess != 1); + // 打印WiFi列表 + printf("********************\r\n"); + for (uint8_t i = 0; i < g_ssid_count; i++) { + printf("no:%03d, ssid:%-30s, rssi:%5d\r\n", i + 1, info[i].ssid, info[i].rssi); + } + printf("********************\r\n"); + // 连接指定的WiFi热点 + for (uint8_t i = 0; i < g_ssid_count; i++) { + if (WifiConnectAp(ssid, psk, info, i) == WIFI_SUCCESS) { + printf("WiFi connect succeed!\r\n"); + break; + } + + if (i == g_ssid_count - 1) { + printf("ERROR: No wifi as expected\r\n"); + while (1) + osDelay(DHCP_DELAY); + } + } + + // 启动DHCP + if (g_lwip_netif) { + dhcp_start(g_lwip_netif); + printf("begain to dhcp\r\n"); + } + // 等待DHCP + for (;;) { + if (dhcp_is_bound(g_lwip_netif) == ERR_OK) { + printf("<-- DHCP state:OK -->\r\n"); + // 打印获取到的IP信息 + netifapi_netif_common(g_lwip_netif, dhcp_clients_info_show, NULL); + break; + } + osDelay(DHCP_DELAY); + } + return 0; +} + +int WiFiInit(void) +{ + g_wifiEventHandler.OnWifiScanStateChanged = OnWifiScanStateChangedHandler; + g_wifiEventHandler.OnWifiConnectionChanged = OnWifiConnectionChangedHandler; + g_wifiEventHandler.OnHotspotStaJoin = OnHotspotStaJoinHandler; + g_wifiEventHandler.OnHotspotStaLeave = OnHotspotStaLeaveHandler; + g_wifiEventHandler.OnHotspotStateChanged = OnHotspotStateChangedHandler; + error = RegisterWifiEvent(&g_wifiEventHandler); + if (error != WIFI_SUCCESS) { + printf("register wifi event fail!\r\n"); + return -1; + } + // 使能WIFI + if (EnableWifi() != WIFI_SUCCESS) { + printf("EnableWifi failed, error = %d\r\n", error); + return -1; + } + // 判断WIFI是否激活 + if (IsWifiActive() == 0) { + printf("Wifi station is not actived.\r\n"); + return -1; + } + return 0; +} + +static void OnWifiScanStateChangedHandler(int state, int size) +{ + if (size > 0) { + g_ssid_count = size; + g_staScanSuccess = 1; + } + printf("callback function for wifi scan:%d, %d\r\n", state, size); + return; +} + +static void OnWifiConnectionChangedHandler(int state, WifiLinkedInfo *info) +{ + if (info == NULL) { + printf("WifiConnectionChanged:info is null, stat is %d.\n", state); + } else { + if (state == WIFI_STATE_AVALIABLE) { + g_ConnectSuccess = 1; + } else { + g_ConnectSuccess = 0; + } + } +} + +static void OnHotspotStaJoinHandler(StationInfo *info) +{ + (void)info; + printf("STA join AP\n"); + return; +} + +static void OnHotspotStaLeaveHandler(StationInfo *info) +{ + (void)info; + printf("HotspotStaLeave:info is null.\n"); + return; +} + +static void OnHotspotStateChangedHandler(int state) +{ + printf("HotspotStateChanged:state is %d.\n", state); + return; +} + +static void WaitSacnResult(void) +{ + int scanTimeout = DEF_TIMEOUT; + while (scanTimeout > 0) { + sleep(ONE_SECOND); + scanTimeout--; + if (g_staScanSuccess == 1) { + printf("WaitSacnResult:wait success[%d]s\n", (DEF_TIMEOUT - scanTimeout)); + break; + } + } + if (scanTimeout <= 0) { + printf("WaitSacnResult:timeout!\n"); + } +} + +static int WaitConnectResult(void) +{ + int ConnectTimeout = DEF_TIMEOUT; + while (ConnectTimeout > 0) { + sleep(ONE_SECOND); + ConnectTimeout--; + if (g_ConnectSuccess == 1) { + printf("WaitConnectResult:wait success[%d]s\n", (DEF_TIMEOUT - ConnectTimeout)); + break; + } + } + if (ConnectTimeout <= 0) { + printf("WaitConnectResult:timeout!\n"); + return 0; + } + return 1; +} -- Gitee