ESP8266连接阿里云,安卓控制LED灯亮灭

代码的主体是照着B站的视频搞得,这篇文章主要说一下学到的一些点

【物联网项目实战入门(esp8266+阿里云+APP)【重制】】 https://www.bilibili.com/video/BV1vM4y1s7rN/?share_source=copy_web&vd_source=5d4e5f4221bfa55d1399968d0b180d8f


实时同步LED状态

这部分主要是要明白传输的数据格式,读取指定的数据并添加对应的判断和功能

arduino部分

void loop() {
  // 轮询MQTT客户端
  mqttClient.poll();

  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // 保存上次发送消息的时间
    previousMillis = currentMillis;

    String payload;

    int value = digitalRead(4);

    DynamicJsonDocument json_msg(512);
    DynamicJsonDocument json_data(512);

    json_data["temp"] = value;

    json_msg["params"] = json_data;
    json_msg["version"] = "1.0.0";
    serializeJson(json_msg,payload);
    
    Serial.print("Sending message to topic: ");
    Serial.println(outTopic);
    Serial.println(payload);
    //Serial.println(value);

    // 发送消息,可以使用Print接口设置消息内容
    // 在这种情况下,我们提前知道大小,因此可以流式传输消息负载

    bool retained = false;
    int qos = 1;
    bool dup = false;

    mqttClient.beginMessage(outTopic, payload.length(), retained, qos, dup);
    mqttClient.print(payload);
    mqttClient.endMessage();

    Serial.println();

    count++;
  }
}

值得注意的点是digitalRead()函数的运用,最开始的时候我是直接将json_data["temp"] = digitalRead();导致读出来的数据一直是null。后来还是用的(不会这个软件debug,所以用的Serial.println(value);来输出读出来的值)

Android部分

/ 初始化 Handler 对象,用于处理消息回传
        handler = new Handler() {
            @SuppressLint("SetTextI18n")
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                switch (msg.what) {
                    case 1: // 开机校验更新回传
                        // 可在此处添加处理开机校验更新回传的逻辑
                        break;
                    case 2: // 反馈回传
                        // 可在此处添加处理反馈回传的逻辑
                        break;
                    case 3: // MQTT 收到消息回传

                        // 获取消息内容并进行解析
                        String message = msg.obj.toString();
                        Log.d("nicecode", "handleMessage: " + message);
                        try {

                            // 解析收到的 JSON 消息
                            JSONObject jsonObjectALL = new JSONObject(message);
                            JSONObject items = jsonObjectALL.getJSONObject("items");//问题items
                            JSONObject obj_temp = items.getJSONObject("temp");
                            //取值
                            ledState = obj_temp.getInt("value");
                            Log.d("nicecode", "temp: "+ ledState);

                            if (ledState == 0) {
                                // LED 关,更改 ImageView 的背景为相应的图像
                                imageView.setBackgroundColor(Color.WHITE);
                                if(Judgment == 1) {
                                    Toast.makeText(MainActivity.this, "开启成功", Toast.LENGTH_SHORT).show();
                                    Judgment = 0;
                                }
                            } else if (ledState == 1) {
                                // LED 关,更改 ImageView 的背景为相应的图像
                                imageView.setBackgroundColor(Color.BLACK);
                                if(Judgment == 1) {
                                    Toast.makeText(MainActivity.this, "关闭成功", Toast.LENGTH_SHORT).show();
                                    Judgment = 0;
                                }
                            } else {
                                Toast.makeText(MainActivity.this, "失败,请重试", Toast.LENGTH_SHORT).show();
                            }
                            System.out.println(ledState);
                        } catch (JSONException e) {
                            e.printStackTrace();
                            // 异常处理
                            break;
                        }
                        break;
                    case 30: // 连接失败
                        // 显示连接失败的提示
                        Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_SHORT).show();
                        break;
                    case 31: // 连接成功
                        // 显示连接成功的提示
                        Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
                        try {
                            // 订阅主题
                            client.subscribe(sub_topic, 1);
                        } catch (MqttException e) {
                            e.printStackTrace();
                        }
                        break;
                    default:
                        break;
                }
            }
        };
    }

通过解析读取JSON数据中led的标识符temp的值来同步LED和当前页面显示状况

开灯状态

关灯状态


判断是否发生状态的改变

主要是要分清楚功能的先后顺序(我就是栽坑里了)其实就是需求分析的时候出现了问题,画个流程图就没这问题应该(狗头)

这个部分主要先实现LED的状态实时同步,然后再判断是否发生状态的改变

之前一直在考虑怎么实现怎么将“改变状态”这个判断

尝试过监听器里面加限制条件,通过延长进程的执行时间来改变数据收到之后是发生改变的,后来发现要执行两次才能达到效果,之后又加了其他的限制条件(一直是在外面添加,没想过加载里面),也在Handler对象和监听器两个部分来回测试过好几次,都没有达到效果(就这样一直陷入死循环)

public void onClick(View v) {
                // 点击“关”按钮时,发布关的消息
                publish_message("{\"params\":{\"temp\":1},\"version\":\"1.0.0\"}");
                Judgment = 1;
//                try {
//                    sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                if (ledState == 1) {
//                    imageView.setBackgroundColor(Color.BLACK);
//                    Toast.makeText(MainActivity.this, "关闭", Toast.LENGTH_SHORT).show();
//                }else{
//                    Toast.makeText(MainActivity.this, "失败,请重试", Toast.LENGTH_SHORT).show();
//                }
            }

后来的改进是发现实时同步状态是要最先实现的功能,在功能里面通过标识符来判断是否发生状态改变(点击事件),在Handler 对象中实现

if (ledState == 0) {
                                // LED 关,更改 ImageView 的背景为相应的图像
                                imageView.setBackgroundColor(Color.WHITE);
                                if(Judgment == 1) {//是否点击按钮
                                    Toast.makeText(MainActivity.this, "开启成功", Toast.LENGTH_SHORT).show();
                                    Judgment = 0;//标识符返回初始状态
                                }
                            } else if (ledState == 1) {
                                // LED 关,更改 ImageView 的背景为相应的图像
                                imageView.setBackgroundColor(Color.BLACK);
                                if(Judgment == 1) {
                                    Toast.makeText(MainActivity.this, "关闭成功", Toast.LENGTH_SHORT).show();
                                    Judgment = 0;
                                }
                            } else {
                                Toast.makeText(MainActivity.this, "失败,请重试", Toast.LENGTH_SHORT).show();
                            }
  • 12
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值