Skip to content
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. General Discussion
  3. STM32?
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

STM32?

Scheduled Pinned Locked Moved General Discussion
82 Posts 19 Posters 34.4k Views 19 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • alowhumA Offline
    alowhumA Offline
    alowhum
    Plugin Developer
    wrote on last edited by
    #17

    The patch has just been added to the Mysensors Development branch, so it's easier to try out.

    I've created a guide on how to get started on the SMT32Duino forum.

    1 Reply Last reply
    1
    • alowhumA Offline
      alowhumA Offline
      alowhum
      Plugin Developer
      wrote on last edited by
      #18

      Heh, the STM32 doesn't have a digital pin 2 it seems. Where is the NRF supposed to connect to instead?

      mfalkviddM 1 Reply Last reply
      0
      • alowhumA alowhum

        Heh, the STM32 doesn't have a digital pin 2 it seems. Where is the NRF supposed to connect to instead?

        mfalkviddM Offline
        mfalkviddM Offline
        mfalkvidd
        Mod
        wrote on last edited by
        #19

        @alowhum looks like PA3: https://github.com/mysensors/MySensors/pull/795/commits/ac432acca3d7c58eb7c8f569dc562860605ea09f#diff-58c572256858a37808c4ebd0922b4060R50

        1 Reply Last reply
        0
        • alowhumA Offline
          alowhumA Offline
          alowhum
          Plugin Developer
          wrote on last edited by alowhum
          #20

          That's odd. I thought I had it just figured out. I'm about to test this at the top of a sketch:

          #define MY_RF24_CE_PIN PB0
          #define MY_RF24_CS_PIN PA4
          #define MY_RF24_MOSI_PIN PA7
          #define MY_RF24_MISO_PIN PA6
          #define MY_RF24_SCK_PIN PA5
          #define MY_RF24_IRQ_PIN PB10

          The fun thing is all the pins are almost in a row. Almost. And if the IRQ is A3, then one more pin would line up..

          According to this image the IRQ is pin PB10 though:
          http://wiki.stm32duino.com/images/a/ae/Bluepillpinout.gif

          mfalkviddM 1 Reply Last reply
          0
          • alowhumA alowhum

            That's odd. I thought I had it just figured out. I'm about to test this at the top of a sketch:

            #define MY_RF24_CE_PIN PB0
            #define MY_RF24_CS_PIN PA4
            #define MY_RF24_MOSI_PIN PA7
            #define MY_RF24_MISO_PIN PA6
            #define MY_RF24_SCK_PIN PA5
            #define MY_RF24_IRQ_PIN PB10

            The fun thing is all the pins are almost in a row. Almost. And if the IRQ is A3, then one more pin would line up..

            According to this image the IRQ is pin PB10 though:
            http://wiki.stm32duino.com/images/a/ae/Bluepillpinout.gif

            mfalkviddM Offline
            mfalkviddM Offline
            mfalkvidd
            Mod
            wrote on last edited by
            #21

            @alowhum sorry I misread your question. Don't know why, but I didn't see that you were talking about the NRF.

            IRQ is not used for the NRF on Arduino, so I supposed it is not used for STM32 either. There is nothing about IRQ in https://github.com/mysensors/MySensors/pull/795/commits/ac432acca3d7c58eb7c8f569dc562860605ea09f#diff-cf14b6301beb3a4dbaded9b95bb190feR487

            1 Reply Last reply
            0
            • alowhumA Offline
              alowhumA Offline
              alowhum
              Plugin Developer
              wrote on last edited by
              #22

              Really? On the Arduino nano I'm always connecting it to pin 2. It says to do so in the guide?

              Anyway, I haven't been able to get it to work. Perhaps some of the developers van shed some light on how it's supposed to work?

              tekkaT mfalkviddM 2 Replies Last reply
              0
              • tbowmoT Offline
                tbowmoT Offline
                tbowmo
                Admin
                wrote on last edited by
                #23

                @alowhum

                Its first in recent (develop branch?) that interrupt usage with nRF24L01 have been enabled, and only in certain scenarios.

                1 Reply Last reply
                0
                • alowhumA alowhum

                  Really? On the Arduino nano I'm always connecting it to pin 2. It says to do so in the guide?

                  Anyway, I haven't been able to get it to work. Perhaps some of the developers van shed some light on how it's supposed to work?

                  tekkaT Offline
                  tekkaT Offline
                  tekka
                  Admin
                  wrote on last edited by tekka
                  #24

                  @alowhum The MySensors RF24 driver is a polling driver (unless RX queuing is enabled), hence no IRQ required.

                  I've successfully tested the RF24 radio with this wiring on a BluePill board using MySensors 2.2.0-beta:

                  CLK -> PA5
                  MISO -> PA6
                  MOSI ->PA7
                  CSN -> PA4
                  CE -> PB0

                  do not forget to set:

                  #define MY_RF24_CE_PIN PB0
                  
                  gohanG 1 Reply Last reply
                  0
                  • alowhumA Offline
                    alowhumA Offline
                    alowhum
                    Plugin Developer
                    wrote on last edited by alowhum
                    #25

                    Hmm, that's pretty much what I had.

                    Could you perhaps share your example sketch?

                    // It's working now! Turns out I had to set the radio to low power..

                    tekkaT 1 Reply Last reply
                    0
                    • alowhumA alowhum

                      Really? On the Arduino nano I'm always connecting it to pin 2. It says to do so in the guide?

                      Anyway, I haven't been able to get it to work. Perhaps some of the developers van shed some light on how it's supposed to work?

                      mfalkviddM Offline
                      mfalkviddM Offline
                      mfalkvidd
                      Mod
                      wrote on last edited by
                      #26

                      @alowhum said in STM32?:

                      Really? On the Arduino nano I'm always connecting it to pin 2. It says to do so in the guide?

                      Well the guide also says "The IRQ is currently not used by the MySensors library so it can be left un-connected."

                      1 Reply Last reply
                      2
                      • alowhumA alowhum

                        Hmm, that's pretty much what I had.

                        Could you perhaps share your example sketch?

                        // It's working now! Turns out I had to set the radio to low power..

                        tekkaT Offline
                        tekkaT Offline
                        tekka
                        Admin
                        wrote on last edited by
                        #27

                        @alowhum Perfect!

                        1 Reply Last reply
                        1
                        • PhracturedBlueP Offline
                          PhracturedBlueP Offline
                          PhracturedBlue
                          wrote on last edited by
                          #28

                          FYI, I didn't check the work done by tekka, but I didn't file a pull request for my 'sleep' code. I have support for using low power mode (reduce current from ~40mA to 4mA during sleep) but I had issues with reliable wakeup, so I've just switched my code to all using delay loops.

                          Initially I was using these boards for my sensors, but there is very little benefit compared to a 3.,3V pro-mini for my usage cases, and the power is 10x more when running (and 100x more when idle without my sleep patches that don't work)

                          I don't have any sensors that need the extra horsepower of the STM32 personally. The one benefit I did realize is having a USB serial port which removes the need for USB->TTL.

                          F 1 Reply Last reply
                          0
                          • F Offline
                            F Offline
                            freynder
                            wrote on last edited by freynder
                            #29

                            Exactly what I was looking for, thank you!

                            I can't seem to get it to work though. I'll report my findings here in case it helps:

                            Platforms tested: platformio and arduino ide, I mainly use platformio
                            Hardware: blue pill with RFM69HW connected like this:
                            NSS <-> PA4
                            MOSI <-> PA7
                            MISO <-> PA6
                            SCK <-> PA5
                            DIO0 <-> PA3

                            Issues encountered:

                            1. undeclared values while compiling. I used the following workaround:
                            // Workaround for STM32 support
                            #define ADC_CR2_TSVREFE  (1 << 23) // from libopencm3
                            #define digitalPinToInterrupt(x) (x)
                            
                            1. examples/SecurityPersonalizer does not seem to work. I use it to write the AES encryption key to EEPROM. However, I do not see any output when running the sketch. As a workaround I created a minimal sketch to write the key to EEPROM which seemed to work.
                              Update: Looks like I was using an old sketch. Works correctly with updated sketch.

                            2. stm32 sensor is unable to connect to gateway:

                            22898 TSM:FAIL:RE-INIT
                            22898 TSM:INIT
                            22900 TSM:INIT:TSP OK
                            22901 TSM:FPAR
                            24120 TSF:MSG:SEND,255-255-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
                            26121 !TSM:FPAR:NO REPLY
                            
                            F 1 Reply Last reply
                            0
                            • F freynder

                              Exactly what I was looking for, thank you!

                              I can't seem to get it to work though. I'll report my findings here in case it helps:

                              Platforms tested: platformio and arduino ide, I mainly use platformio
                              Hardware: blue pill with RFM69HW connected like this:
                              NSS <-> PA4
                              MOSI <-> PA7
                              MISO <-> PA6
                              SCK <-> PA5
                              DIO0 <-> PA3

                              Issues encountered:

                              1. undeclared values while compiling. I used the following workaround:
                              // Workaround for STM32 support
                              #define ADC_CR2_TSVREFE  (1 << 23) // from libopencm3
                              #define digitalPinToInterrupt(x) (x)
                              
                              1. examples/SecurityPersonalizer does not seem to work. I use it to write the AES encryption key to EEPROM. However, I do not see any output when running the sketch. As a workaround I created a minimal sketch to write the key to EEPROM which seemed to work.
                                Update: Looks like I was using an old sketch. Works correctly with updated sketch.

                              2. stm32 sensor is unable to connect to gateway:

                              22898 TSM:FAIL:RE-INIT
                              22898 TSM:INIT
                              22900 TSM:INIT:TSP OK
                              22901 TSM:FPAR
                              24120 TSF:MSG:SEND,255-255-255-255,s=255,c=3,t=7,pt=0,l=0,sg=0,ft=0,st=OK:
                              26121 !TSM:FPAR:NO REPLY
                              
                              F Offline
                              F Offline
                              freynder
                              wrote on last edited by
                              #30

                              @freynder said in STM32?:

                              stm32 sensor is unable to connect to gateway:

                              After further testing, this seems to work now. I'm not exactly sure why unfortunately. I'm now using the new RFM69 library. I noticed that communication seems to fail after uploading the sketch over stlink, even when clicking the reset button. When disconnecting/reconnecting the usb power all works well. Maybe that was the issue previously as well.

                              F 1 Reply Last reply
                              0
                              • PhracturedBlueP PhracturedBlue

                                FYI, I didn't check the work done by tekka, but I didn't file a pull request for my 'sleep' code. I have support for using low power mode (reduce current from ~40mA to 4mA during sleep) but I had issues with reliable wakeup, so I've just switched my code to all using delay loops.

                                Initially I was using these boards for my sensors, but there is very little benefit compared to a 3.,3V pro-mini for my usage cases, and the power is 10x more when running (and 100x more when idle without my sleep patches that don't work)

                                I don't have any sensors that need the extra horsepower of the STM32 personally. The one benefit I did realize is having a USB serial port which removes the need for USB->TTL.

                                F Offline
                                F Offline
                                freynder
                                wrote on last edited by
                                #31

                                @PhracturedBlue What hardware were you using? Did it include a power led and voltage regulator? According to http://www.stm32duino.com/viewtopic.php?f=3&t=658&start=40 it should be possible to put the Blue Pill in stop mode using 13µA while sleeping when eliminating these.

                                I'm also interested in using the blue pill for the included RTC to periodically send data (RSSI, battery level, etc). I understand that with the current MySensors API this is not supported. E.g. combining a 24 hour sleep with a light switch: when the light switch is triggered, the 24 hour sleep is interrupted and starts again from scratch, so it is impossible to combine external interrupts with time interrupts, unless I am missing something. I am hoping RTC alarms could provide a solution here.

                                1 Reply Last reply
                                0
                                • tekkaT tekka

                                  @alowhum The MySensors RF24 driver is a polling driver (unless RX queuing is enabled), hence no IRQ required.

                                  I've successfully tested the RF24 radio with this wiring on a BluePill board using MySensors 2.2.0-beta:

                                  CLK -> PA5
                                  MISO -> PA6
                                  MOSI ->PA7
                                  CSN -> PA4
                                  CE -> PB0

                                  do not forget to set:

                                  #define MY_RF24_CE_PIN PB0
                                  
                                  gohanG Offline
                                  gohanG Offline
                                  gohan
                                  Mod
                                  wrote on last edited by gohan
                                  #32

                                  @tekka do you think stm32 is sufficiently stable running mysensors or should I stick to the "old" pro mini for battery powered sensors? (Also considering the ota updates support)

                                  F tekkaT 2 Replies Last reply
                                  0
                                  • gohanG gohan

                                    @tekka do you think stm32 is sufficiently stable running mysensors or should I stick to the "old" pro mini for battery powered sensors? (Also considering the ota updates support)

                                    F Offline
                                    F Offline
                                    freynder
                                    wrote on last edited by
                                    #33

                                    @gohan There is no support yet for sleep, so battery powered out of the box will not work. I've been testing custom sleep function (STOP mode, external interrupts) and so far was able to run a blue pill + RFM69 with MySensors between 0.01 and 0.20 mA (inconsistent results, not sure yet why). A sketch with just blue pill ran consistently at 0.01 mA. Unfortunately my multimeter does not allow more accurate measurements.

                                    1 Reply Last reply
                                    1
                                    • gohanG gohan

                                      @tekka do you think stm32 is sufficiently stable running mysensors or should I stick to the "old" pro mini for battery powered sensors? (Also considering the ota updates support)

                                      tekkaT Offline
                                      tekkaT Offline
                                      tekka
                                      Admin
                                      wrote on last edited by
                                      #34

                                      @gohan As @freynder pointed out, sleeping and low power modes are currently not implemented - if you do not need the higher speed & additional features that come along with the stm32 I'd stick (for the moment) to at328p for battery-powered sensors.

                                      1 Reply Last reply
                                      1
                                      • alowhumA Offline
                                        alowhumA Offline
                                        alowhum
                                        Plugin Developer
                                        wrote on last edited by
                                        #35

                                        I thought I'd just share a complete sketch. This is a sketch for a Co2 and dust sensor using the STM32 blue pill.

                                        /*
                                         * The MySensors Arduino library handles the wireless radio link and protocol
                                         * between your home built sensors/actuators and HA controller of choice.
                                         * The sensors forms a self healing radio network with optional repeaters. Each
                                         * repeater and gateway builds a routing tables in EEPROM which keeps track of the
                                         * network topology allowing messages to be routed to nodes.
                                         *
                                         * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                                         * Copyright (C) 2013-2015 Sensnology AB
                                         * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                                         *
                                         * Documentation: http://www.mysensors.org
                                         * Support Forum: http://forum.mysensors.org
                                         *
                                         * This program is free software; you can redistribute it and/or
                                         * modify it under the terms of the GNU General Public License
                                         * version 2 as published by the Free Software Foundation.
                                         *
                                         *******************************
                                         *
                                         *  DESCRIPTION
                                         *
                                         *  MH-Z19 CO2 sensor
                                         *  Uses infrared to measure Co2' absorbtion spectrum. Talks to the board over over serial 9600 on Serial1.
                                         *  
                                         *  PMS-7003
                                         *  This sensor uses a frickin' laser to measure lots of different fine dust levels, between 0.3 and 10 microns. 
                                         *  It can output the raw particle count for a certain particle size and up. Or it can give the official um/mg 
                                         *  measurement. Talks to the board over over serial 9600 on Serial2.
                                         *  
                                         *  
                                         *  NRF24 pins: b0 a7 a6 a5 a4 (and 3.3v power)
                                         *  MH-Z19 pins: a9 a1 (and 5v power)
                                         *  PMS7001 pins: a2 a3 (and 5v power)
                                         */
                                        
                                        
                                        
                                        /* 
                                        //------------------------------------------------------------------------------
                                        //  PM sensor PMS7003 (fine dust)
                                        
                                        
                                        
                                        
                                        Copyright 2017 Scapeler
                                        
                                        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.    
                                        
                                        */
                                        
                                        //------------------------------------------------------------------------------
                                        
                                        // if you uncomment this, you can get test and debug updates about the sensor' wireless connection by using the serial monitor tool.
                                        #define MY_DEBUG
                                        
                                        // Enable and select radio type attached
                                        #define MY_RADIO_NRF24                            // A 2.4Ghz transmitter and receiver, often used with MySensors.
                                        #define MY_RF24_PA_LEVEL RF24_PA_MIN              // This sets a low-power mode for the radio. Useful if you use the verison with the bigger antenna, but don't want to power that from a separate power source. It can also fix problems with fake Chinese versions of the radio.
                                        // #define MY_RADIO_RFM69                         // 433Mhz transmitter and reveiver.
                                        
                                        // This is needed if you use an STM32 board:
                                        #define MY_RF24_CE_PIN PB0
                                        
                                        // Choose if you want this sensor to also be a repeater.
                                        // #define MY_REPEATER_FEATURE                    // Just remove the two slashes at the beginning of this line to also enable this sensor to act as a repeater for other sensors. If this node is on battery power, you probably shouldn't enable this.
                                        
                                        // Are you using this sensor on battery power?
                                        // #define BATTERY_POWERED                        // Just remove the two slashes at the beginning of this line if your node is battery powered. It will then go into deep sleep as much as possible. While it's sleeping it can't work as a repeater!
                                        
                                        #include <SPI.h>
                                        #include <MySensors.h>
                                        
                                        // Co2 sensor
                                        #define CHILD_ID_CO2 0 // The Co2 sensor
                                        
                                        // Dust sensor
                                        #define CHILD_ID_DUST_PM03 1
                                        //#define CHILD_ID_DUST_PM05 2
                                        #define CHILD_ID_DUST_PM10 2 
                                        #define CHILD_ID_DUST_PM25 3
                                        #define CHILD_ID_DUST_PM50 4
                                        #define CHILD_ID_DUST_PM100 5
                                        
                                        // bool receivedConfig = false;                      // This is not used in the code, but perhaps MySensors requires this?
                                        // bool metric = true;                               // Variable that stores if the sensor will output the temperature in Fahrenheit of Celsius. The gateway sends this preference to the node.
                                        
                                        
                                        // Mysensors settings
                                        
                                        // Co2
                                        MyMessage msgCo2(CHILD_ID_CO2, V_LEVEL);
                                        MyMessage msgCo2b(CHILD_ID_CO2, V_UNIT_PREFIX);
                                        
                                        // Dust. If you want to get all the raw data, the commented lines are useful.
                                        MyMessage msgDust03(CHILD_ID_DUST_PM03, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                        MyMessage msgDust03b(CHILD_ID_DUST_PM03, V_UNIT_PREFIX);
                                        //MyMessage msgDust05(CHILD_ID_DUST_PM05, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                        //MyMessage msgDust05b(CHILD_ID_DUST_PM05, V_UNIT_PREFIX);
                                        MyMessage msgDust10(CHILD_ID_DUST_PM10, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                        MyMessage msgDust10b(CHILD_ID_DUST_PM10, V_UNIT_PREFIX);
                                        MyMessage msgDust25(CHILD_ID_DUST_PM25, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                        MyMessage msgDust25b(CHILD_ID_DUST_PM25, V_UNIT_PREFIX);
                                        MyMessage msgDust50(CHILD_ID_DUST_PM50, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                        MyMessage msgDust50b(CHILD_ID_DUST_PM50, V_UNIT_PREFIX);
                                        MyMessage msgDust100(CHILD_ID_DUST_PM100, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                        MyMessage msgDust100b(CHILD_ID_DUST_PM100, V_UNIT_PREFIX);
                                        
                                        
                                        
                                        // These defines and variables can be changed:
                                        
                                        // co2
                                        unsigned long co2MeasurementInterval = 30000;        // Time to wait between reads (in milliseconds).
                                        //float co2threshold = 0.1;   // How big a measurement difference has to be before an update is sent. Makes the sensor less precise, but also less jittery, and can save battery.
                                        
                                        // dust
                                        // Are you using this sensor on battery power?
                                        // #define BATTERY_POWERED                        // Just remove the two slashes at the beginning of this line if your node is battery powered. It will then go into deep sleep as much as possible. While it's sleeping it can't work as a repeater!
                                        
                                        int dustSlowDown = 20; // The dust sensor is internally checked approximately every 700 or 800 milliseconds. Once in how many loops should it send the data?
                                        
                                        unsigned long dustMeasurementInterval = 700;  // This is a fickle thing. Changing it can give more time-outs.
                                        
                                        // PROBABLE BEST NOT TO CHANGE THESE VARIABLES
                                        // PMS7003 sensor - input byte variables
                                        int inputHigh = 0;
                                        int inputLow = 0;
                                        // variable to caclulate checksum input variables
                                        uint16_t inputChecksum = 0;
                                        // sensor variables
                                        uint16_t concPM1_0_CF1;
                                        uint16_t concPM2_5_CF1;
                                        uint16_t concPM10_0_CF1;
                                        uint16_t concPM1_0_amb;
                                        uint16_t concPM2_5_amb;
                                        uint16_t concPM10_0_amb;
                                        uint16_t rawGt0_3um;
                                        uint16_t rawGt0_5um;
                                        uint16_t rawGt1_0um;
                                        uint16_t rawGt2_5um;
                                        uint16_t rawGt5_0um;
                                        uint16_t rawGt10_0um;
                                        uint8_t  version;
                                        uint8_t  errorCode;
                                        uint16_t checksum;
                                        int dustSlowDownCounter = 0;
                                        
                                        
                                        void presentation()
                                        {
                                          // Send the sketch version information to the gateway and Controller
                                          sendSketchInfo("AIQ Sensor CO2 MH-Z19 and Dust PMS-7003", "1.0");
                                        
                                          // Register all sensors to gateway (they will be created as child devices):
                                        
                                          // co2
                                          present(CHILD_ID_CO2, S_AIR_QUALITY);
                                          send(msgCo2b.set("ppm"));
                                        
                                          // dust
                                          //present(CHILD_ID_DUST_PM10, S_DUST);
                                          //send(msgPM10.set("ppm"));
                                          present(CHILD_ID_DUST_PM03, S_DUST);
                                          send(msgDust03b.set("um/m3"));    
                                          //present(CHILD_ID_DUST_PM05, S_DUST);
                                          //send(msgDust05b.set("pp/dl"));    
                                          present(CHILD_ID_DUST_PM10, S_DUST);
                                          send(msgDust10b.set("um/m3"));  
                                          present(CHILD_ID_DUST_PM25, S_DUST);
                                          send(msgDust25b.set("um/m3")); 
                                          present(CHILD_ID_DUST_PM100, S_DUST);
                                          send(msgDust100b.set("um/m3"));  
                                          present(CHILD_ID_DUST_PM50, S_DUST);
                                          send(msgDust50b.set("pp/dl"));   
                                        }
                                        
                                        
                                        void setup() {
                                             delay(1000);
                                           Serial.begin(115200);
                                             delay(1000);
                                           Serial1.begin(9600);       //C02 sensor read serial
                                               while (!Serial1) {
                                            }
                                        
                                            Serial2.begin(9600); // PMS7003 dust sensor read serial
                                              while (!Serial2) {
                                            }
                                                
                                           delay(2000);
                                           while (Serial1.read()!=-1) {};  //clear Co2 buffer.
                                           Serial.println("hello world, I am a sensor.");
                                        }
                                        
                                        
                                        void loop() {
                                        
                                           // You should not change these variables:
                                           static unsigned long previousCo2Millis = 0;       // Used to remember the time of the last temperature measurement.
                                           static unsigned long previousDustMillis = 0;       // Used to remember the time of the last temperature measurement.
                                        
                                           unsigned long currentMillis = millis(); // The time since the sensor started, counted in milliseconds. This script tries to avoid using the Sleep function, so that it could at the same time be a MySensors repeater.
                                        
                                          // Co2 loop
                                          if (currentMillis - previousCo2Millis >= co2MeasurementInterval) {
                                            Serial.println("");
                                            Serial.println("CO2 - Sending data request to sensor.");
                                            previousCo2Millis = currentMillis;
                                        
                                            long co2ppm = readCO2();
                                        
                                            Serial.println("Co2 - PPM = " + String(co2ppm));
                                            send(msgCo2.set((long)ceil(co2ppm))); 
                                            Serial.print("Co2 - zzzzZZZZzzzzZZZZzzzz\n");
                                          }
                                        
                                          // The dust sensor sends its data continuously, so let's get that data.
                                          int dustSensorOutput = pms7003ReadData();
                                        }
                                        
                                        
                                        // MAIN FUNCTION THAT GETS THE Co2 DATA
                                        int readCO2()
                                        {
                                          while (Serial1.read()!=-1) {};  //clear buffer  
                                        
                                          char response[9]; // for answer
                                          byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
                                          
                                          // command to ask for data
                                          Serial1.write(cmd, 9); //request PPM CO2 
                                        
                                          Serial1.readBytes(response, 9);
                                        
                                            Serial.print(response[0], HEX);   
                                            Serial.print(" - ");   
                                            Serial.print(response[1], HEX);   
                                            Serial.print(" - ");    
                                            Serial.print(response[2], HEX);   
                                            Serial.print(" - ");          
                                            Serial.print(response[3], HEX);   
                                            Serial.print(" - ");          
                                            Serial.print(response[4], HEX);   
                                            Serial.print(" - ");          
                                            Serial.print(response[5], HEX);   
                                            Serial.print(" - ");        
                                            Serial.print(response[6], HEX);   
                                            Serial.print(" - ");   
                                            Serial.print(response[7], HEX);   
                                            Serial.print(" - ");      
                                            Serial.print(response[8], HEX); 
                                            Serial.println(" - END");  
                                        
                                          if (response[0] != 0xFF)
                                          {
                                            Serial.println("Wrong starting byte from co2 sensor!");
                                            return -1;
                                          }
                                        
                                          if (response[1] != 0x86)
                                          {
                                            Serial.println("Wrong command from co2 sensor!");
                                            return -1;
                                          }
                                        
                                          int responseHigh = (int) response[2];
                                          int responseLow = (int) response[3];
                                          int ppm = (256 * responseHigh) + responseLow;
                                          
                                          return ppm;
                                        }
                                        
                                        
                                        // MAIN FUNCTION FOR THE DUST SENSOR, Thanks to Scapeler.nl
                                        int pms7003ReadData() {
                                            
                                          // while (Serial2.read()!=-1) {};  //clear buffer
                                        
                                          if (Serial2.available() < 32) {
                                            if (Serial2.available() == 0) {
                                              delay(150);
                                              return -1;
                                            };
                                            if (Serial2.available() > 16) {
                                              delay(10);
                                              return -1;
                                            };
                                            if (Serial2.available() > 0) {
                                              delay(30);
                                              return -1;
                                            };
                                            delay(100);
                                            return -1;
                                          }
                                          if (Serial2.read() != 0x42) return -1;
                                          if (Serial2.read() != 0x4D) return -1;
                                        
                                          inputChecksum = 0x42 + 0x4D;
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          if (inputHigh != 0x00) return -1; 
                                          if (inputLow != 0x1c) return -1;    
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          concPM1_0_CF1 = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          concPM2_5_CF1 = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          concPM10_0_CF1 = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          concPM1_0_amb = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          concPM2_5_amb = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          concPM10_0_amb = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          rawGt0_3um = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          rawGt0_5um = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          rawGt1_0um = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          rawGt2_5um = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          rawGt5_0um = inputLow+(inputHigh<<8);
                                        
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          inputChecksum += inputHigh + inputLow;
                                          rawGt10_0um = inputLow+(inputHigh<<8);
                                        
                                          inputLow = Serial2.read();
                                          inputChecksum += inputLow;
                                          version = inputLow;
                                        
                                          inputLow = Serial2.read();
                                          inputChecksum += inputLow;
                                          errorCode = inputLow;
                                        
                                          Serial.print("PMS7003;"); 
                                        
                                          // The measurement recalculated to micrograms per cubic meter, a common standard.
                                          Serial.print(concPM1_0_CF1);
                                          Serial.print(';'); 
                                          Serial.print(concPM2_5_CF1);
                                          Serial.print(';'); 
                                          Serial.print(concPM10_0_CF1);
                                          Serial.print(';'); 
                                        
                                          // The measurement recalculated to micrograms per cubic meter, a common standard. Not quite sure what the difference is..
                                          Serial.print(concPM1_0_amb);
                                          Serial.print(';'); 
                                          Serial.print(concPM2_5_amb);
                                          Serial.print(';');     
                                          Serial.print(concPM10_0_amb);
                                          Serial.print(';');     
                                        
                                          // this is the 'raw' data that the sensor gathers internally, before it calculates the above values.
                                          Serial.print(rawGt0_3um); // This indicates total number or particles in 0.1 liter of air that have a diameter above 0.3um. This will be the biggest number, as it measures the most particles. But it's very imprecise: 50% accuracy..
                                          Serial.print(';');
                                          Serial.print(rawGt0_5um); // This indicates the total number or particles in 0.1 liter of air that have a diameter above 0.5um (so it will be a smaller count than the line above)
                                          Serial.print(';'); 
                                          Serial.print(rawGt1_0um); // This indicates the total number or particles in 0.1 liter of air that have a diameter above 1 micron. And so on..
                                          Serial.print(';'); 
                                          Serial.print(rawGt2_5um);
                                          Serial.print(';'); 
                                          Serial.print(rawGt5_0um); // Acording to the datashet, at this point the accuracy has reached at 98%.
                                          Serial.print(';'); 
                                          Serial.print(rawGt10_0um);
                                          Serial.print(';'); 
                                          Serial.print(version);
                                          Serial.print(';'); 
                                          Serial.print(errorCode);
                                          Serial.println("---");
                                          
                                          inputHigh = Serial2.read();
                                          inputLow = Serial2.read();
                                          checksum = inputLow+(inputHigh<<8);
                                          if (checksum != inputChecksum) {
                                            Serial.print(';'); 
                                            Serial.print(checksum); 
                                            Serial.print(';'); 
                                            Serial.print(inputChecksum); 
                                          }
                                          //Serial.print('\n');
                                        
                                          // let's send a message with the results
                                          dustSlowDownCounter = dustSlowDownCounter + 1;
                                          if(dustSlowDownCounter > dustSlowDown){
                                            
                                            /*  MEASUREMENT  */
                                            if(rawGt1_0um > 0){
                                              Serial.println(" Dust1_0 = " + String(concPM1_0_CF1));
                                              send(msgDust10.set(concPM1_0_CF1,1));
                                            }         
                                            if(rawGt2_5um > 0){
                                              Serial.println(" Dust1_0 = " + String(concPM2_5_CF1));
                                              send(msgDust25.set(concPM2_5_CF1,1));
                                            }     
                                            if(rawGt10_0um > 0){
                                              Serial.println(" Dust1_0 = " + String(concPM10_0_CF1));
                                              send(msgDust100.set(concPM10_0_CF1,1));
                                            }     
                                        
                                            /*  RAW DATA  */            
                                            
                                            if(rawGt0_3um > 0){
                                              Serial.println(" Dust03 = " + String(rawGt0_3um));
                                              send(msgDust03.set(rawGt0_3um,1));
                                            }/*
                                            if(rawGt0_5um > 0){
                                              Serial.println(" Dust05 = " + String(rawGt0_5um));
                                              send(msgDust05.set(rawGt0_5um,1));
                                            }
                                            if(rawGt1_0um > 0){
                                              Serial.println(" Dust10 = " + String(rawGt1_0um));
                                              send(msgDust10.set(rawGt1_0um,1));
                                            }
                                            if(rawGt2_5um > 0){
                                              Serial.println(" Dust25 = " + String(rawGt2_5um));
                                              send(msgDust25.set(rawGt2_5um,1));
                                            }
                                            */
                                            if(rawGt5_0um > 0){
                                              Serial.println(" Dust50 = " + String(rawGt5_0um));
                                              send(msgDust50.set(rawGt5_0um,1));
                                            }      
                                            /*
                                            if(rawGt10_0um > 0){
                                              Serial.println(" Dust100 = " + String(rawGt10_0um));
                                              send(msgDust100.set(rawGt10_0um,1));
                                            }   
                                            */
                                        
                                            dustSlowDownCounter = 0;
                                          } // End of sensing message.
                                        
                                          delay(700);  // Data will come between 200 and 800 miliseconds. If you set this be be higher than 700 you will get checksum errors.
                                            
                                          return concPM2_5_CF1;
                                        }
                                        
                                        
                                        
                                        
                                        gohanG 1 Reply Last reply
                                        0
                                        • alowhumA alowhum

                                          I thought I'd just share a complete sketch. This is a sketch for a Co2 and dust sensor using the STM32 blue pill.

                                          /*
                                           * The MySensors Arduino library handles the wireless radio link and protocol
                                           * between your home built sensors/actuators and HA controller of choice.
                                           * The sensors forms a self healing radio network with optional repeaters. Each
                                           * repeater and gateway builds a routing tables in EEPROM which keeps track of the
                                           * network topology allowing messages to be routed to nodes.
                                           *
                                           * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                                           * Copyright (C) 2013-2015 Sensnology AB
                                           * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                                           *
                                           * Documentation: http://www.mysensors.org
                                           * Support Forum: http://forum.mysensors.org
                                           *
                                           * This program is free software; you can redistribute it and/or
                                           * modify it under the terms of the GNU General Public License
                                           * version 2 as published by the Free Software Foundation.
                                           *
                                           *******************************
                                           *
                                           *  DESCRIPTION
                                           *
                                           *  MH-Z19 CO2 sensor
                                           *  Uses infrared to measure Co2' absorbtion spectrum. Talks to the board over over serial 9600 on Serial1.
                                           *  
                                           *  PMS-7003
                                           *  This sensor uses a frickin' laser to measure lots of different fine dust levels, between 0.3 and 10 microns. 
                                           *  It can output the raw particle count for a certain particle size and up. Or it can give the official um/mg 
                                           *  measurement. Talks to the board over over serial 9600 on Serial2.
                                           *  
                                           *  
                                           *  NRF24 pins: b0 a7 a6 a5 a4 (and 3.3v power)
                                           *  MH-Z19 pins: a9 a1 (and 5v power)
                                           *  PMS7001 pins: a2 a3 (and 5v power)
                                           */
                                          
                                          
                                          
                                          /* 
                                          //------------------------------------------------------------------------------
                                          //  PM sensor PMS7003 (fine dust)
                                          
                                          
                                          
                                          
                                          Copyright 2017 Scapeler
                                          
                                          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.    
                                          
                                          */
                                          
                                          //------------------------------------------------------------------------------
                                          
                                          // if you uncomment this, you can get test and debug updates about the sensor' wireless connection by using the serial monitor tool.
                                          #define MY_DEBUG
                                          
                                          // Enable and select radio type attached
                                          #define MY_RADIO_NRF24                            // A 2.4Ghz transmitter and receiver, often used with MySensors.
                                          #define MY_RF24_PA_LEVEL RF24_PA_MIN              // This sets a low-power mode for the radio. Useful if you use the verison with the bigger antenna, but don't want to power that from a separate power source. It can also fix problems with fake Chinese versions of the radio.
                                          // #define MY_RADIO_RFM69                         // 433Mhz transmitter and reveiver.
                                          
                                          // This is needed if you use an STM32 board:
                                          #define MY_RF24_CE_PIN PB0
                                          
                                          // Choose if you want this sensor to also be a repeater.
                                          // #define MY_REPEATER_FEATURE                    // Just remove the two slashes at the beginning of this line to also enable this sensor to act as a repeater for other sensors. If this node is on battery power, you probably shouldn't enable this.
                                          
                                          // Are you using this sensor on battery power?
                                          // #define BATTERY_POWERED                        // Just remove the two slashes at the beginning of this line if your node is battery powered. It will then go into deep sleep as much as possible. While it's sleeping it can't work as a repeater!
                                          
                                          #include <SPI.h>
                                          #include <MySensors.h>
                                          
                                          // Co2 sensor
                                          #define CHILD_ID_CO2 0 // The Co2 sensor
                                          
                                          // Dust sensor
                                          #define CHILD_ID_DUST_PM03 1
                                          //#define CHILD_ID_DUST_PM05 2
                                          #define CHILD_ID_DUST_PM10 2 
                                          #define CHILD_ID_DUST_PM25 3
                                          #define CHILD_ID_DUST_PM50 4
                                          #define CHILD_ID_DUST_PM100 5
                                          
                                          // bool receivedConfig = false;                      // This is not used in the code, but perhaps MySensors requires this?
                                          // bool metric = true;                               // Variable that stores if the sensor will output the temperature in Fahrenheit of Celsius. The gateway sends this preference to the node.
                                          
                                          
                                          // Mysensors settings
                                          
                                          // Co2
                                          MyMessage msgCo2(CHILD_ID_CO2, V_LEVEL);
                                          MyMessage msgCo2b(CHILD_ID_CO2, V_UNIT_PREFIX);
                                          
                                          // Dust. If you want to get all the raw data, the commented lines are useful.
                                          MyMessage msgDust03(CHILD_ID_DUST_PM03, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                          MyMessage msgDust03b(CHILD_ID_DUST_PM03, V_UNIT_PREFIX);
                                          //MyMessage msgDust05(CHILD_ID_DUST_PM05, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                          //MyMessage msgDust05b(CHILD_ID_DUST_PM05, V_UNIT_PREFIX);
                                          MyMessage msgDust10(CHILD_ID_DUST_PM10, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                          MyMessage msgDust10b(CHILD_ID_DUST_PM10, V_UNIT_PREFIX);
                                          MyMessage msgDust25(CHILD_ID_DUST_PM25, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                          MyMessage msgDust25b(CHILD_ID_DUST_PM25, V_UNIT_PREFIX);
                                          MyMessage msgDust50(CHILD_ID_DUST_PM50, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                          MyMessage msgDust50b(CHILD_ID_DUST_PM50, V_UNIT_PREFIX);
                                          MyMessage msgDust100(CHILD_ID_DUST_PM100, V_LEVEL); // Sets up the message format that we'l be sending to the MySensors gateway later.
                                          MyMessage msgDust100b(CHILD_ID_DUST_PM100, V_UNIT_PREFIX);
                                          
                                          
                                          
                                          // These defines and variables can be changed:
                                          
                                          // co2
                                          unsigned long co2MeasurementInterval = 30000;        // Time to wait between reads (in milliseconds).
                                          //float co2threshold = 0.1;   // How big a measurement difference has to be before an update is sent. Makes the sensor less precise, but also less jittery, and can save battery.
                                          
                                          // dust
                                          // Are you using this sensor on battery power?
                                          // #define BATTERY_POWERED                        // Just remove the two slashes at the beginning of this line if your node is battery powered. It will then go into deep sleep as much as possible. While it's sleeping it can't work as a repeater!
                                          
                                          int dustSlowDown = 20; // The dust sensor is internally checked approximately every 700 or 800 milliseconds. Once in how many loops should it send the data?
                                          
                                          unsigned long dustMeasurementInterval = 700;  // This is a fickle thing. Changing it can give more time-outs.
                                          
                                          // PROBABLE BEST NOT TO CHANGE THESE VARIABLES
                                          // PMS7003 sensor - input byte variables
                                          int inputHigh = 0;
                                          int inputLow = 0;
                                          // variable to caclulate checksum input variables
                                          uint16_t inputChecksum = 0;
                                          // sensor variables
                                          uint16_t concPM1_0_CF1;
                                          uint16_t concPM2_5_CF1;
                                          uint16_t concPM10_0_CF1;
                                          uint16_t concPM1_0_amb;
                                          uint16_t concPM2_5_amb;
                                          uint16_t concPM10_0_amb;
                                          uint16_t rawGt0_3um;
                                          uint16_t rawGt0_5um;
                                          uint16_t rawGt1_0um;
                                          uint16_t rawGt2_5um;
                                          uint16_t rawGt5_0um;
                                          uint16_t rawGt10_0um;
                                          uint8_t  version;
                                          uint8_t  errorCode;
                                          uint16_t checksum;
                                          int dustSlowDownCounter = 0;
                                          
                                          
                                          void presentation()
                                          {
                                            // Send the sketch version information to the gateway and Controller
                                            sendSketchInfo("AIQ Sensor CO2 MH-Z19 and Dust PMS-7003", "1.0");
                                          
                                            // Register all sensors to gateway (they will be created as child devices):
                                          
                                            // co2
                                            present(CHILD_ID_CO2, S_AIR_QUALITY);
                                            send(msgCo2b.set("ppm"));
                                          
                                            // dust
                                            //present(CHILD_ID_DUST_PM10, S_DUST);
                                            //send(msgPM10.set("ppm"));
                                            present(CHILD_ID_DUST_PM03, S_DUST);
                                            send(msgDust03b.set("um/m3"));    
                                            //present(CHILD_ID_DUST_PM05, S_DUST);
                                            //send(msgDust05b.set("pp/dl"));    
                                            present(CHILD_ID_DUST_PM10, S_DUST);
                                            send(msgDust10b.set("um/m3"));  
                                            present(CHILD_ID_DUST_PM25, S_DUST);
                                            send(msgDust25b.set("um/m3")); 
                                            present(CHILD_ID_DUST_PM100, S_DUST);
                                            send(msgDust100b.set("um/m3"));  
                                            present(CHILD_ID_DUST_PM50, S_DUST);
                                            send(msgDust50b.set("pp/dl"));   
                                          }
                                          
                                          
                                          void setup() {
                                               delay(1000);
                                             Serial.begin(115200);
                                               delay(1000);
                                             Serial1.begin(9600);       //C02 sensor read serial
                                                 while (!Serial1) {
                                              }
                                          
                                              Serial2.begin(9600); // PMS7003 dust sensor read serial
                                                while (!Serial2) {
                                              }
                                                  
                                             delay(2000);
                                             while (Serial1.read()!=-1) {};  //clear Co2 buffer.
                                             Serial.println("hello world, I am a sensor.");
                                          }
                                          
                                          
                                          void loop() {
                                          
                                             // You should not change these variables:
                                             static unsigned long previousCo2Millis = 0;       // Used to remember the time of the last temperature measurement.
                                             static unsigned long previousDustMillis = 0;       // Used to remember the time of the last temperature measurement.
                                          
                                             unsigned long currentMillis = millis(); // The time since the sensor started, counted in milliseconds. This script tries to avoid using the Sleep function, so that it could at the same time be a MySensors repeater.
                                          
                                            // Co2 loop
                                            if (currentMillis - previousCo2Millis >= co2MeasurementInterval) {
                                              Serial.println("");
                                              Serial.println("CO2 - Sending data request to sensor.");
                                              previousCo2Millis = currentMillis;
                                          
                                              long co2ppm = readCO2();
                                          
                                              Serial.println("Co2 - PPM = " + String(co2ppm));
                                              send(msgCo2.set((long)ceil(co2ppm))); 
                                              Serial.print("Co2 - zzzzZZZZzzzzZZZZzzzz\n");
                                            }
                                          
                                            // The dust sensor sends its data continuously, so let's get that data.
                                            int dustSensorOutput = pms7003ReadData();
                                          }
                                          
                                          
                                          // MAIN FUNCTION THAT GETS THE Co2 DATA
                                          int readCO2()
                                          {
                                            while (Serial1.read()!=-1) {};  //clear buffer  
                                          
                                            char response[9]; // for answer
                                            byte cmd[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
                                            
                                            // command to ask for data
                                            Serial1.write(cmd, 9); //request PPM CO2 
                                          
                                            Serial1.readBytes(response, 9);
                                          
                                              Serial.print(response[0], HEX);   
                                              Serial.print(" - ");   
                                              Serial.print(response[1], HEX);   
                                              Serial.print(" - ");    
                                              Serial.print(response[2], HEX);   
                                              Serial.print(" - ");          
                                              Serial.print(response[3], HEX);   
                                              Serial.print(" - ");          
                                              Serial.print(response[4], HEX);   
                                              Serial.print(" - ");          
                                              Serial.print(response[5], HEX);   
                                              Serial.print(" - ");        
                                              Serial.print(response[6], HEX);   
                                              Serial.print(" - ");   
                                              Serial.print(response[7], HEX);   
                                              Serial.print(" - ");      
                                              Serial.print(response[8], HEX); 
                                              Serial.println(" - END");  
                                          
                                            if (response[0] != 0xFF)
                                            {
                                              Serial.println("Wrong starting byte from co2 sensor!");
                                              return -1;
                                            }
                                          
                                            if (response[1] != 0x86)
                                            {
                                              Serial.println("Wrong command from co2 sensor!");
                                              return -1;
                                            }
                                          
                                            int responseHigh = (int) response[2];
                                            int responseLow = (int) response[3];
                                            int ppm = (256 * responseHigh) + responseLow;
                                            
                                            return ppm;
                                          }
                                          
                                          
                                          // MAIN FUNCTION FOR THE DUST SENSOR, Thanks to Scapeler.nl
                                          int pms7003ReadData() {
                                              
                                            // while (Serial2.read()!=-1) {};  //clear buffer
                                          
                                            if (Serial2.available() < 32) {
                                              if (Serial2.available() == 0) {
                                                delay(150);
                                                return -1;
                                              };
                                              if (Serial2.available() > 16) {
                                                delay(10);
                                                return -1;
                                              };
                                              if (Serial2.available() > 0) {
                                                delay(30);
                                                return -1;
                                              };
                                              delay(100);
                                              return -1;
                                            }
                                            if (Serial2.read() != 0x42) return -1;
                                            if (Serial2.read() != 0x4D) return -1;
                                          
                                            inputChecksum = 0x42 + 0x4D;
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            if (inputHigh != 0x00) return -1; 
                                            if (inputLow != 0x1c) return -1;    
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            concPM1_0_CF1 = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            concPM2_5_CF1 = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            concPM10_0_CF1 = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            concPM1_0_amb = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            concPM2_5_amb = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            concPM10_0_amb = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            rawGt0_3um = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            rawGt0_5um = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            rawGt1_0um = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            rawGt2_5um = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            rawGt5_0um = inputLow+(inputHigh<<8);
                                          
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            inputChecksum += inputHigh + inputLow;
                                            rawGt10_0um = inputLow+(inputHigh<<8);
                                          
                                            inputLow = Serial2.read();
                                            inputChecksum += inputLow;
                                            version = inputLow;
                                          
                                            inputLow = Serial2.read();
                                            inputChecksum += inputLow;
                                            errorCode = inputLow;
                                          
                                            Serial.print("PMS7003;"); 
                                          
                                            // The measurement recalculated to micrograms per cubic meter, a common standard.
                                            Serial.print(concPM1_0_CF1);
                                            Serial.print(';'); 
                                            Serial.print(concPM2_5_CF1);
                                            Serial.print(';'); 
                                            Serial.print(concPM10_0_CF1);
                                            Serial.print(';'); 
                                          
                                            // The measurement recalculated to micrograms per cubic meter, a common standard. Not quite sure what the difference is..
                                            Serial.print(concPM1_0_amb);
                                            Serial.print(';'); 
                                            Serial.print(concPM2_5_amb);
                                            Serial.print(';');     
                                            Serial.print(concPM10_0_amb);
                                            Serial.print(';');     
                                          
                                            // this is the 'raw' data that the sensor gathers internally, before it calculates the above values.
                                            Serial.print(rawGt0_3um); // This indicates total number or particles in 0.1 liter of air that have a diameter above 0.3um. This will be the biggest number, as it measures the most particles. But it's very imprecise: 50% accuracy..
                                            Serial.print(';');
                                            Serial.print(rawGt0_5um); // This indicates the total number or particles in 0.1 liter of air that have a diameter above 0.5um (so it will be a smaller count than the line above)
                                            Serial.print(';'); 
                                            Serial.print(rawGt1_0um); // This indicates the total number or particles in 0.1 liter of air that have a diameter above 1 micron. And so on..
                                            Serial.print(';'); 
                                            Serial.print(rawGt2_5um);
                                            Serial.print(';'); 
                                            Serial.print(rawGt5_0um); // Acording to the datashet, at this point the accuracy has reached at 98%.
                                            Serial.print(';'); 
                                            Serial.print(rawGt10_0um);
                                            Serial.print(';'); 
                                            Serial.print(version);
                                            Serial.print(';'); 
                                            Serial.print(errorCode);
                                            Serial.println("---");
                                            
                                            inputHigh = Serial2.read();
                                            inputLow = Serial2.read();
                                            checksum = inputLow+(inputHigh<<8);
                                            if (checksum != inputChecksum) {
                                              Serial.print(';'); 
                                              Serial.print(checksum); 
                                              Serial.print(';'); 
                                              Serial.print(inputChecksum); 
                                            }
                                            //Serial.print('\n');
                                          
                                            // let's send a message with the results
                                            dustSlowDownCounter = dustSlowDownCounter + 1;
                                            if(dustSlowDownCounter > dustSlowDown){
                                              
                                              /*  MEASUREMENT  */
                                              if(rawGt1_0um > 0){
                                                Serial.println(" Dust1_0 = " + String(concPM1_0_CF1));
                                                send(msgDust10.set(concPM1_0_CF1,1));
                                              }         
                                              if(rawGt2_5um > 0){
                                                Serial.println(" Dust1_0 = " + String(concPM2_5_CF1));
                                                send(msgDust25.set(concPM2_5_CF1,1));
                                              }     
                                              if(rawGt10_0um > 0){
                                                Serial.println(" Dust1_0 = " + String(concPM10_0_CF1));
                                                send(msgDust100.set(concPM10_0_CF1,1));
                                              }     
                                          
                                              /*  RAW DATA  */            
                                              
                                              if(rawGt0_3um > 0){
                                                Serial.println(" Dust03 = " + String(rawGt0_3um));
                                                send(msgDust03.set(rawGt0_3um,1));
                                              }/*
                                              if(rawGt0_5um > 0){
                                                Serial.println(" Dust05 = " + String(rawGt0_5um));
                                                send(msgDust05.set(rawGt0_5um,1));
                                              }
                                              if(rawGt1_0um > 0){
                                                Serial.println(" Dust10 = " + String(rawGt1_0um));
                                                send(msgDust10.set(rawGt1_0um,1));
                                              }
                                              if(rawGt2_5um > 0){
                                                Serial.println(" Dust25 = " + String(rawGt2_5um));
                                                send(msgDust25.set(rawGt2_5um,1));
                                              }
                                              */
                                              if(rawGt5_0um > 0){
                                                Serial.println(" Dust50 = " + String(rawGt5_0um));
                                                send(msgDust50.set(rawGt5_0um,1));
                                              }      
                                              /*
                                              if(rawGt10_0um > 0){
                                                Serial.println(" Dust100 = " + String(rawGt10_0um));
                                                send(msgDust100.set(rawGt10_0um,1));
                                              }   
                                              */
                                          
                                              dustSlowDownCounter = 0;
                                            } // End of sensing message.
                                          
                                            delay(700);  // Data will come between 200 and 800 miliseconds. If you set this be be higher than 700 you will get checksum errors.
                                              
                                            return concPM2_5_CF1;
                                          }
                                          
                                          
                                          
                                          
                                          gohanG Offline
                                          gohanG Offline
                                          gohan
                                          Mod
                                          wrote on last edited by gohan
                                          #36

                                          @alowhum do you mind posting the links to the sensors you used? I was planning to make a similar one

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          9

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular