查看: 4637|回复: 5

Arduino MQTT通信库

[复制链接]
  • TA的每日心情
    郁闷
    2018-12-6 22:21
  • 签到天数: 48 天

    [LV.5]常住居民I

    发表于 2017-8-14 18:07 | 显示全部楼层 |阅读模式
    github:
    https://github.com/knolleary/pubsubclient

    该库支持以下设备:
    Arduino Ethernet
    Arduino Ethernet Shield
    Arduino YUN
    Arduino WiFi Shield
    Sparkfun WiFly Shield – library
    TI CC3000 WiFi - library
    Intel Galileo/Edison
    ESP8266




    如果以上内容对你有帮助,你可以通过打赏支持作者
  • TA的每日心情
    奋斗
    2018-11-16 21:49
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2018-10-19 10:30 | 显示全部楼层
    谢谢楼主分享。
  • TA的每日心情
    郁闷
    2018-12-1 10:08
  • 签到天数: 1 天

    [LV.1]初来乍到

    发表于 2019-1-14 11:09 | 显示全部楼层


    您好,我按照例子,写的程序,发布消息没问题,mqtt服务器可以接受,但UNO却无法接受订阅消息,是哪里出了问题?

    kittenblock中小学创客名师推荐的图形化编程软件

    
    #include <OneWire.h>
    #include <U8glib.h>
    #include <MsTimer2.h>
    #include <WiFiEsp.h>
    #include <WiFiEspUdp.h>
    #include <WiFiEspClient.h>
    #include <PubSubClient.h>
    #include <SoftwareSerial.h>
    #define MqttServer_IP "10.1.3.172" // 连接服务器
    #define MqttServer_PORT 1883 // 连接服务器8234
    #define WIFI_AP "z"
    #define WIFI_PASSWORD "3333222222"
    #define ID "10002"
    int status = WL_IDLE_STATUS;     // the Wifi radio's status
    float celsius;
    bool flag_second;//每秒触发一次,用于每隔1秒,串口发送一次数据
    byte addr[8];
    byte pwmpin=5;//UNO中只能用 3,5,6,9,10,11
    String inString="";//输入指令字符 SET_PWM=52
    String PWM_valStr;
    byte PWM_val=255;//0-255,越大,速度越慢
    
    const byte interruptPin = 3;//脉冲输入IO ,UNO中断引脚只有 pin2 (int0) 和 pin3(int1)
    byte Val = 0; //设置变量 Val,计数 (服务器散热风扇,12V下最高风速时,162转/s)
    byte Val_n = 0; //每秒多少转
    unsigned int RPM = 0; //每分多少转
    OneWire  ds(13);  // on pin 10 (a 4.7K resistor is necessary)
    U8GLIB_KS0108_128 u8g(6, 7, 8, 9, 10,11, 12, A0,     A1, A2, A3, A4, A5 ); 
    //U8GLIB_KS0108_128 u8g(6(pin 7), 7(pin 8), 8(pin 9), 9(pin 10), 10(pin 11),11(pin 12), 12(pin 13), A0(pin 14)     A1(pin 6), A2(pin 15), A3(pin 16), A4(pin 4), A5(pin 5) ); 
    //          8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs1=14, cs2=15,di=17,rw=16
    //YXD-12864BG液晶屏1.Vss   2.+3.3V  3.背光调节  4.RS Comand/Data Input 5.R/W Read/Write Signal Input 6.E 7.D0 8.D1 9.D2 10.D3 11.D4 12.D5 13.D6 14.D7 15.CS1 16.CS2 17.RES 18.Vout 19.LED +5V 20.GND
    SoftwareSerial Serial_wifi(2, 4); // RX, TX 
    // 初始化以太网客户端对象 
    WiFiEspClient espClient;
    // 初始化MQTT库PubSubClient.h的对象
    PubSubClient client(espClient);
    void setup(void) {
      Serial.begin(9600);
     attachInterrupt(digitalPinToInterrupt(interruptPin), count, FALLING);//FALLING  RISING CHANGE
      InitWiFi();                                // 连接WiFi
      client.setServer( MqttServer_IP, MqttServer_PORT);      // 连接WiFi之后,连接MQTT服务器 
      client.setCallback(callback);
      client.subscribe("v1/devices/me/IntelligentFan_CMD");
      pinMode(pwmpin, OUTPUT);
       // 中断设置函数,每 1000ms 进入一次中断
       MsTimer2::set(1000, rpm_count);
       MsTimer2::start();  
    }
    
    void loop(void) {
      initDs18b20();//ds18b20中间取温度需要 750ms 用delay太浪费所以,程序分成两部分,运行其他
      
      status = WiFi.status(); 
      if ( status != WL_CONNECTED) {
        while ( status != WL_CONNECTED) {
          Serial.print("[loop()]Attempting connect to WPA SSID: ");
          Serial.println(WIFI_AP);
          // 连接WiFi热点
          status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
          delay(500);
        }
        Serial.println("[loop()]Connected to AP");    
      }
      if ( !client.connected() ) {
        reconnect();
      }
      client.loop();
      /*
      while(Serial.available()>0){
        char inChar= Serial.read();
        inString +=(char) inChar;
        delay(10);
      }
      if(inString!=""){
        Serial.print("Input String:");  
        Serial.println(inString);
        
        PWM_valStr=inString.substring(8);//SET_PWM=52
        PWM_val=PWM_valStr.toInt();   
        Serial.println(PWM_val);
        
    //    analogWrite(pwmpin, PWM_val);
      inString="";
      }
      */
      analogWrite(pwmpin, PWM_val);//设置pwm,
      //每秒发送一次数据
      if(flag_second==1){
        getandSendTemperatureAndRPMData();    
        //每秒标记
        flag_second=0;    
      }
    
     
      draw();  
      //delay(500);
      getDs18b20WenDu();
      
    
    }
    void initDs18b20(void) {
      byte i;
      if ( !ds.search(addr)) {
        //Serial.println("No more addresses.");
        ds.reset_search();
        delay(250);
        return;
      }
    
      //Serial.print("ROM =");
      //for ( i = 0; i < 8; i++) {
        //Serial.write(' ');
        //Serial.print(addr, HEX);
     // }
    
      if (OneWire::crc8(addr, 7) != addr[7]) {
        Serial.println("CRC is not valid!");
        return;
      }
      //Serial.println();
    
    
    
      ds.reset();
      ds.select(addr);
      ds.write(0x44, 1);        // start conversion, with parasite power on at the end
    
      //delay(1000);     // maybe 750ms is enough, maybe not
      // we might do a ds.depower() here, but the reset will take care of it.
    }
    
    void getDs18b20WenDu(void) {
      byte i;
      byte present = 0;
      byte data[12];
    
      present = ds.reset();
      ds.select(addr);
      ds.write(0xBE);         // Read Scratchpad
      for ( i = 0; i < 9; i++) {           // we need 9 bytes
        data = ds.read();
        //Serial.print(data, HEX);
        //Serial.print(" ");
      }
    
      int16_t raw = (data[1] << 8) | data[0];
    
        byte cfg = (data[4] & 0x60);
        // at lower res, the low bits are undefined, so let's zero them
        if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
        else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
        else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
        //// default is 12 bit resolution, 750 ms conversion time
    
      celsius = (float)raw / 16.0;
      //Serial.print("  T = ");//Temperature
      //Serial.println(celsius);
      //Serial.print(" Celsius, ");
    
    }
    /*
     * 
     * 把温度、转速发送到MQTT服务器上去
     * 
     */
    void getandSendTemperatureAndRPMData()
    {
      Serial.println("Collecting data.");
      //温度
      Serial.print("T=");//Temperature
      Serial.print(celsius,2);
      //转速
      Serial.print("; V=");
      Serial.print(Val_n);//Val是1秒钟转多少圈
      Serial.print("; RPM=");
      RPM=60*Val_n;
      Serial.print(RPM);//转换成rpm,Val是1秒钟转多少圈,rpm=60*val 
      Serial.println(";");
      String celsiusString = String(celsius);
      String Val_nString = String(Val_n);  
      String RPMString = String(RPM); 
      // 构建一个 JSON 格式的payload的字符串
      String payload = "{";
      payload += "\"temperature\":"; payload += celsiusString; payload += ",";
      payload += "\"Val\":"; payload += Val_nString;
      payload += ",\"RPM\":"; payload += RPMString;
      payload += "}";
      // Send payload
      char attributes[100];
      //payload.toCharArray( attributes, 100 );
      payload.toCharArray( attributes, 90 );
      // boolean publish(const char* topic, const char* payload);  
      client.publish( "v1/devices/me/IntelligentFan", attributes );
      Serial.print("[publish]-->>");
      Serial.println( attributes );
    }
    void InitWiFi()
    {
      // 初始化软串口,软串口连接ESP模块
      Serial_wifi.begin(9600);
      // 初始化ESP模块
      WiFi.init(&Serial_wifi);
      // 检测WiFi模块在不在,宏定义:WL_NO_SHIELD = 255,WL_IDLE_STATUS = 0,
      if (WiFi.status() == WL_NO_SHIELD) {
        Serial.println("WiFi not present");
        while (true);
      }
    
      Serial.println("[InitWiFi]Connect AP ...");
      // 尝试连接WiFi网络
      while ( status != WL_CONNECTED) {
        Serial.print("[InitWiFi]Attempt connect WPA SSID: ");
        Serial.println(WIFI_AP);
        // Connect to WPA/WPA2 network
        status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
        delay(500);
      }
      Serial.println("[InitWiFi]Connected AP");
    }
    /**
     * 
     * MQTT客户端断线重连函数
     * 
     */
    
    void reconnect() {
      // 一直循环直到连接上MQTT服务器
      while (!client.connected()) {
        Serial.print("[reconnect]Connect MQTT Server ...");
        // 尝试连接connect是个重载函数 (clientId, username, password)
      //boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
      //client.connect(ID, "v1/devices/me/telemetry_will",0, 0,"willdead");
        if ( client.connect(ID, "v1/devices/me/IntelligentFan_will",0, 0,"willdead") ) {//该设备的遗愿信息,如果mqtt服务器收不到信号,就会向订阅号发willdead信息
        //if ( client.connect(ID, NULL, NULL) ) {
        client.subscribe("v1/devices/me/IntelligentFan_CMD");
          Serial.println( "[DONE]" );
        } else {
          Serial.print( "[FAILED][mqtt connect error code=" );
          Serial.print( client.state() );
          Serial.println( " :retrying in 3 seconds]" );// Wait 5 seconds before retrying
          delay( 3000 );
        }
      }
    }
    void callback(char* topic, byte* payload, unsigned int length) {
      Serial.print("Message arrived [");
      Serial.print(topic);
      Serial.print("] ");
      for (int i=0;i<length;i++) {
        Serial.print((char)payload);
      }
      Serial.println();
    }
    void draw(void) {
      u8g.firstPage();
      do {
      //u8g.setColorIndex(1);
      u8g.setFont(u8g_font_unifont);
      //u8g.setFont(u8g_font_osb21);
      u8g.drawStr( 0, 40, "T:");
      u8g.setFont(u8g_font_unifont);
      u8g.setPrintPos(16, 40);
      u8g.print(celsius, 2);  
      //u8g.drawBitmapP ( 0 , 0 , 2 , 16 , bitmap_z); 
      //u8g.drawBitmapP ( 17 , 0 , 2 , 16 , bitmap_s );
      //u8g.drawBitmapP ( 33 , 0 , 2 , 16 , bitmap_j );
      u8g.drawStr( 0, 52, "V:");
      u8g.setFont(u8g_font_unifont);
      u8g.setPrintPos(16, 52);
      u8g.print(Val_n);
      u8g.drawStr( 0,64, "RPM:");
      u8g.setPrintPos(32, 64);
      u8g.print(RPM);  
      } while ( u8g.nextPage() );
    }
    void count() {
      Val += 1;
    }
    void rpm_count() {
      Val_n = Val;
      flag_second=1;
      Val = 0;//输出速度结果后清零,记录下一秒的触发次数
    }

    您需要登录后才可以回帖 登录 | 立即注册  

    本版积分规则

    热门推荐

    OLED 128*64自制可达10000000个选项的菜单(已更新)
    OLED 128*64自制可达10000
    OLED 128*64自制可达10000000个选项的菜单 温馨提示: 建议占个楼再食用本帖子
    这个怎么整?标点都是英文的
    这个怎么整?标点都是英文
    a=a+1改成a++也不行
    [WiFiduino-8266开发板测试]三、测试IO口
    [WiFiduino-8266开发板测
    首先测试IO口的关系,板载正面的D0~D15[D14,D15没有,相同的位置写的是D4,D5],反面
    求助,arduino nano发热严重
    求助,arduino nano发热严
    我有一块arduino nano板,装在一个扩展板上(如下图),用扩展板上的外接电源接口(资
    [限时福利]5分钟带你快速了解新一代开发板:M5STACK
    [限时福利]5分钟带你快速
    一、什么是M5Stack M5Stack是一种模块化、可堆叠扩展的开发板,每个模块
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   ( 蜀ICP备14017632号-3 )
    快速回复 返回顶部 返回列表