『瀚思彼岸』» 智能家居技术论坛

 找回密码
 立即注册
查看: 19693|回复: 22

[插件集成] esp8266NodeMCU刷EspEasy固件,攀藤PMS5003ST插件源码

[复制链接]

8

主题

115

帖子

758

积分

高级会员

Rank: 4

积分
758
金钱
643
HASS币
0
发表于 2018-1-17 21:58:04 | 显示全部楼层 |阅读模式
本帖最后由 阿东 于 2018-10-30 00:29 编辑

espeasy原固件只支持pmsx003,pm2.5激光传感器
看了smc326的 《新人第一原创,ESPEasy有PMS5003ST+MH-Z19B传感器可以用啦》帖子
买了攀藤PMS5003ST传感器,集成PM2.5、温湿度、甲醛传感器。

上面帖子的固件 能显示并用MQTT上传6个项目,用HTTP只能上传4个项目,温度,湿度刚好在第5第6


帖子里只有固件没有源码,只能硬着头皮自己改官方固件了
根据espeasy官网的编译指南,下载了固件源码包ATOM。
找到PMSx003.ino插件,修改后只保留了4个项目,pm2.5 温度、湿度、甲醛浓度。乐联网上传正常。
由于数据包长度不同,需要修改下字节数,和温湿度甲醛的计算方法,校验部分一样不用动。

========

简单的 data[14]/10 温湿度只有整数,0基础痛苦搜索了大半天,最后参考旁边DHT温湿度传感器的代码,原来小数点这么麻烦要用float。。。代码已更新,小数点终于正常了。
实测esp8266的nodemcu开发版刷了成功。

代码如下,或者下载附件,直接复制覆盖。(原文的很多PMSx003字眼没动,只改了关键数据部分)

//#######################################################################################################
//#################################### Plugin 053: Plantower PMSx003 ####################################
//#######################################################################################################
//
// [url=http://www.aqmd.gov/docs/default-source/aq-spec/resources-page/plantower-pms5003-manual_v2-3.pdf?sfvrsn=2]http://www.aqmd.gov/docs/default ... l_v2-3.pdf?sfvrsn=2[/url]
//
// The PMSx003 are particle sensors. Particles are measured by blowing air through the enclosure and,
// together with a laser, count the amount of particles. These sensors have an integrated microcontroller
// that counts particles and transmits measurement data over the serial connection.

#ifdef PLUGIN_BUILD_TESTING

#include <ESPeasySoftwareSerial.h>

#define PLUGIN_053
#define PLUGIN_ID_053 53
#define PLUGIN_NAME_053 "Dust - PMS5003ST"
#define PLUGIN_VALUENAME1_053 "pm2.5"
#define PLUGIN_VALUENAME2_053 "TEMP"
#define PLUGIN_VALUENAME3_053 "HUMI"
#define PLUGIN_VALUENAME4_053 "HCHO"
#define PMSx003_SIG1 0X42
#define PMSx003_SIG2 0X4d
#define PMSx003_SIZE 40

ESPeasySoftwareSerial *swSerial = NULL;
boolean Plugin_053_init = false;
boolean values_received = false;

// Read 2 bytes from serial and make an uint16 of it. Additionally calculate
// checksum for PMSx003. Assumption is that there is data available, otherwise
// this function is blocking.
void SerialRead16(uint16_t* value, uint16_t* checksum)
{
  uint8_t data_high, data_low;

  // If swSerial is initialized, we are using soft serial
  if (swSerial != NULL)
  {
    data_high = swSerial->read();
    data_low = swSerial->read();
  }
  else
  {
    data_high = Serial.read();
    data_low = Serial.read();
  }

  *value = data_low;
  *value |= (data_high << 8);

  if (checksum != NULL)
  {
    *checksum += data_high;
    *checksum += data_low;
  }

#if 0
  // Low-level logging to see data from sensor
  String log = F("PMSx003 : byte high=0x");
  log += String(data_high,HEX);
  log += F(" byte low=0x");
  log += String(data_low,HEX);
  log += F(" result=0x");
  log += String(*value,HEX);
  addLog(LOG_LEVEL_INFO, log);
#endif
}

boolean PacketAvailable(void)
{
  boolean success = false;

  if (swSerial != NULL) // Software serial
  {
    // When there is enough data in the buffer, search through the buffer to
    // find header (buffer may be out of sync)
    while (swSerial->available() >= PMSx003_SIZE)
    {
      if (swSerial->read() == PMSx003_SIG1 && swSerial->read() == PMSx003_SIG2)
      {
        success = true;
        break;
      }
    }
  }
  else // Hardware serial
  {
    // When there is enough data in the buffer, search through the buffer to
    // find header (buffer may be out of sync)
    while (Serial.available() >= PMSx003_SIZE)
    {
      if (Serial.read() == PMSx003_SIG1 && Serial.read() == PMSx003_SIG2)
      {
        success = true;
        break;
      }
    }
  }
  return success;
}

boolean Plugin_053(byte function, struct EventStruct *event, String& string)
{
  String log;
  boolean success = false;

  switch (function)
  {
    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_053;
        Device[deviceCount].Type = DEVICE_TYPE_TRIPLE;
        Device[deviceCount].VType = SENSOR_TYPE_TRIPLE;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = true;
        Device[deviceCount].FormulaOption = true;
        Device[deviceCount].ValueCount = 4;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = true;
        Device[deviceCount].GlobalSyncOption = true;
        success = true;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_053);
        success = true;
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_053));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_053));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_053));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_053));
        success = true;
        break;
      }

      case PLUGIN_GET_DEVICEGPIONAMES:
        {
          event->String1 = F("GPIO ← TX");
          event->String2 = F("GPIO → RX");
          event->String3 = F("GPIO → Reset");
          break;
        }

    case PLUGIN_INIT:
      {
        int rxPin = Settings.TaskDevicePin1[event->TaskIndex];
        int txPin = Settings.TaskDevicePin2[event->TaskIndex];
        int resetPin = Settings.TaskDevicePin3[event->TaskIndex];

        log = F("PMSx003 : config ");
        log += rxPin;
        log += txPin;
        log += resetPin;
        addLog(LOG_LEVEL_DEBUG, log);

        // Hardware serial is RX on 3 and TX on 1
        if (rxPin == 3 && txPin == 1)
        {
          log = F("PMSx003 : using hardware serial");
          addLog(LOG_LEVEL_INFO, log);
          Serial.begin(9600);
          Serial.flush();
        }
        else
        {
          log = F("PMSx003: using software serial");
          addLog(LOG_LEVEL_INFO, log);
          swSerial = new ESPeasySoftwareSerial(rxPin, txPin);
          swSerial->begin(9600);
          swSerial->flush();
        }

        if (resetPin >= 0) // Reset if pin is configured
        {
          // Toggle 'reset' to assure we start reading header
          log = F("PMSx003: resetting module");
          addLog(LOG_LEVEL_INFO, log);
          pinMode(resetPin, OUTPUT);
          digitalWrite(resetPin, LOW);
          delay(250);
          digitalWrite(resetPin, HIGH);
          pinMode(resetPin, INPUT_PULLUP);
        }

        Plugin_053_init = true;
        success = true;
        break;
      }
    // The update rate from the module is 200ms .. multiple seconds. Practise
    // shows that we need to read the buffer many times per seconds to stay in
    // sync.
    case PLUGIN_TEN_PER_SECOND:
      {
        if (Plugin_053_init)
        {
          uint16_t checksum = 0, checksum2 = 0;
          uint16_t framelength = 0;
          uint16_t data[17];
          // byte data_low, data_high;
          int i = 0;

          // Check if a packet is available in the UART FIFO.
          if (PacketAvailable())
          {
            log = F("PMSx003 : Packet available");
            addLog(LOG_LEVEL_DEBUG_MORE, log);
            checksum += PMSx003_SIG1 + PMSx003_SIG2;
            SerialRead16(&framelength, &checksum);
            if (framelength != (PMSx003_SIZE - 4))
            {
              log = F("PMSx003 : invalid framelength - ");
              log += framelength;
              addLog(LOG_LEVEL_ERROR, log);
              break;
            }

            for (i = 0; i < 17; i++)
              SerialRead16(&data[i], &checksum);

            log = F("PMSx003 : pm1.0=");
            log += data[0];
            log += F(", pm2.5=");
            log += data[1];
            log += F(", pm10=");
            log += data[2];
            log += F(", pm1.0a=");
            log += data[3];
            log += F(", pm2.5a=");
            log += data[4];
            log += F(", pm10a=");
            log += data[5];
            addLog(LOG_LEVEL_DEBUG, log);

            log = F("PMSx003 : count/0.1L : 0.3um=");
            log += data[6];
            log += F(", 0.5um=");
            log += data[7];
            log += F(", 1.0um=");
            log += data[8];
            log += F(", 2.5um=");
            log += data[9];
            log += F(", 5.0um=");
            log += data[10];
            log += F(", 10um=");
            log += data[11];
            log += F(", HCHO=");
            log += data[12];
            log += F(", TEMP=");
            log += float(data[13]/10.00);
            log += F(", HUMI=");
            log += float(data[14]/10.00);
            addLog(LOG_LEVEL_DEBUG_MORE, log);

            // Compare checksums
            SerialRead16(&checksum2, NULL);
            if (checksum == checksum2)
            {
              // Data is checked and good, fill in output
              UserVar[event->BaseVarIndex]     = data[4];
              UserVar[event->BaseVarIndex + 1] = float(data[13]/10.00);//data[13]/10;
              UserVar[event->BaseVarIndex + 2] = float(data[14]/10.00);//data[14]/10;
              UserVar[event->BaseVarIndex + 3] = float(data[12]/1000.000);//data[12]/1000;
              values_received = true;
              success = true;
            }
          }
        }
        break;
      }
    case PLUGIN_READ:
      {
        // When new data is available, return true
        success = values_received;
        values_received = false;
      }
  }
  return success;
}
#endif // PLUGIN_BUILD_TESTING


0AC4703C-6C02-4244-838D-C522B0C88AC9.png
F99CAD46-F5DD-4A7C-9611-8C3B753AD89F.png

_P053_PMSx003.ino

8.67 KB, 下载次数: 67

ESPEasy固件_mega-20180114_PMS5003ST_4096m.rar

426.93 KB, 下载次数: 140

评分

参与人数 3金钱 +37 收起 理由
smc326 + 7 赠人玫瑰,手留余香!
+ 20 膜拜大神!
windgo + 10 谢谢分享!

查看全部评分

回复

使用道具 举报

25

主题

416

帖子

3027

积分

元老级技术达人

积分
3027
金钱
2601
HASS币
40
发表于 2018-1-18 10:26:33 | 显示全部楼层
赞 多谢分享
回复

使用道具 举报

123

主题

4661

帖子

1万

积分

管理员

囧死

Rank: 9Rank: 9Rank: 9

积分
16410
金钱
11664
HASS币
45
发表于 2018-1-18 20:57:22 | 显示全部楼层
厉害了东哥,感谢分享!
回复

使用道具 举报

0

主题

217

帖子

613

积分

高级会员

Rank: 4

积分
613
金钱
395
HASS币
0
发表于 2018-1-21 14:31:32 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

2

主题

76

帖子

310

积分

中级会员

Rank: 3Rank: 3

积分
310
金钱
233
HASS币
0
发表于 2018-1-29 15:53:29 来自手机 | 显示全部楼层
这个插件,PMS5003.ico,用什么工具,怎么刷?
回复

使用道具 举报

8

主题

115

帖子

758

积分

高级会员

Rank: 4

积分
758
金钱
643
HASS币
0
 楼主| 发表于 2018-1-30 00:34:17 | 显示全部楼层
本帖最后由 阿东 于 2018-1-30 00:35 编辑
cced000 发表于 2018-1-29 15:53
这个插件,PMS5003.ico,用什么工具,怎么刷?

这个插件ino放入espeasy官网下载的源码文件夹里替换掉原插件,用ATOM软件打开载入espeasy项目编译成你需要的版本,我编译成4m测试版刷入成功运行。
1楼有教程链接,可以去看看
回复

使用道具 举报

2

主题

76

帖子

310

积分

中级会员

Rank: 3Rank: 3

积分
310
金钱
233
HASS币
0
发表于 2018-1-30 11:50:51 | 显示全部楼层
阿东 发表于 2018-1-30 00:34
这个插件ino放入espeasy官网下载的源码文件夹里替换掉原插件,用ATOM软件打开载入espeasy项目编译成你需要 ...

那你另外一个附件是不是可以直接用了,已经包含了你这个ico插件了。谢谢
回复

使用道具 举报

8

主题

115

帖子

758

积分

高级会员

Rank: 4

积分
758
金钱
643
HASS币
0
 楼主| 发表于 2018-1-31 13:23:15 | 显示全部楼层
cced000 发表于 2018-1-30 11:50
那你另外一个附件是不是可以直接用了,已经包含了你这个ico插件了。谢谢 ...

是的,第二个附件,已经修改过了,支持pms5003st
回复

使用道具 举报

2

主题

76

帖子

310

积分

中级会员

Rank: 3Rank: 3

积分
310
金钱
233
HASS币
0
发表于 2018-2-2 15:47:10 | 显示全部楼层
阿东 发表于 2018-1-31 13:23
是的,第二个附件,已经修改过了,支持pms5003st

再请教一下,espeasy是搞定了如何将数据传到HA,然后显示到手机上呢,用的是自带的mqtt,
-------
Description An Open Source MQTT broker
Version 1.0
-------
MQTT及EASPeasy要如何设置内,谢谢
回复

使用道具 举报

8

主题

115

帖子

758

积分

高级会员

Rank: 4

积分
758
金钱
643
HASS币
0
 楼主| 发表于 2018-2-2 18:52:59 | 显示全部楼层
cced000 发表于 2018-2-2 15:47
再请教一下,espeasy是搞定了如何将数据传到HA,然后显示到手机上呢,用的是自带的mqtt,
-------
Descri ...

这个得搜索下论坛里 mqtt ha,相关的教程,我只上传到乐联网没有上传到HA。
回复

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|Hassbian

GMT+8, 2024-11-24 12:46 , Processed in 0.453047 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表