Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Analog CO2 Sensor for LoPy, can 5v pin power it?

    Scheduled Pinned Locked Moved LoPy
    co2lopyadc5vdcsensor
    15 Posts 4 Posters 5.2k Views 4 Watching
    Loading More Posts
    • 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.
    • ledbelly2142L Offline
      ledbelly2142
      last edited by

      Hello,
      I have a lopy with the pycom lopy expansion board that I am connecting an analog CO2 sensor to. This is a SEN0219 Gravity Analog Infrared CO2 sensor, more HERE

      The sensor specification:
      Gas Detection: Carbon Dioxide (CO2)
       Operating Voltage: 4.5 ~ 5.5V DC
       Average Current: <60mA @ 5V
       Peak Current: 150mA @ 5V
       Output Signal: Analog output (0.4 ~ 2V)
       Measuring Range: 0 ~ 5000ppm
       Accuracy: ± (50ppm + 3% reading)
       Preheating Time: 3min
       Response Time: 120s
       Operating Temperature: 0 ~ 50 Ԩ
       Operating Humidity: 0 ~ 95% RH (no condensation)
       Service Life: >5 years
       Size: 37mm * 69mm

      Vendor states this can be used in a 3.3V system as long as you power it with 5VDC. On the LoPy pin out diagram, the 3.3V pin states an absolute max of 1.2-A max load capability. Does this apply to the 5V pin as well? I assumed so, but I may not be getting enough amps.

      CO2 sensor connection: I have the sensor power plugged into the 5vdc pin, the gnd to the gnd and the signal (sensor output) to pin 16.

      When I run
      adc = machine.ADC() # create an ADC object
      apin = adc.channel(pin='P16') # create an analog pin on P16 & connect CO2 sensor
      value = apin()
      print("ADC count = %d" %(value))

      I get an ADC count = 1988

      Why is this so high?
      If I run the same code without anythign connected I get an ACD count of 4095...

      I need to set the attinuation level to 3.3v, but the syntax from the documentation does not work. I tried:

      apin = adc.channel(pin='P16', attn=ADC.ATTN_11DB)

      But get the error: Traceback (most recent call last) File "stdin", line 1, in <module> ValueError: invalid argument(s) value

      While this works:
      apin = adc.channel(pin='P16')

      How do I properly set the attinuation?

      Friends don't let friends run with scissors

      J robert-hhR 2 Replies Last reply Reply Quote 0
      • J Offline
        jmarcelino @ledbelly2142
        last edited by jmarcelino

        @ledbelly2142
        To use ADC.ATTN_11DB you must declare what ADC is with

        from machine import ADC

        I think in your code you must have used import machine instead. Alternatively you can also use machine.ADC.ATTN_11DB but it's longwinded and unusual.

        As for the values the data sheet you linked to suggests the maximum output signal is 2V so you can use ADC.ATTN_6DB (half) instead.
        This brings down the signal from 0-2V to the 0-1V the ADC expects, you definitely need the attenuation.

        Finally note the internal ADC currently suffers from calibration issues so don't expect much accuracy from the results.

        1 Reply Last reply Reply Quote 1
        • robert-hhR Offline
          robert-hh @ledbelly2142
          last edited by robert-hh

          @ledbelly2142 The 5V pin is connected to the USB 5V or Vin. So it should source enough power to run the sensor. In you example, to use the attenuator, the syntach is:

          adc = machine.ADC() # create an ADC object
          apin = adc.channel(pin='P16', attn=machine.ADC.ATTN_11DB) # create an analog pin on P16 & connect CO2 sensor
          value = apin()
          print("ADC count = %d" %(value))
          

          The value will never be 0, since the output of the sensor is in the range of 0.4..2 V. The esp32 is quite noisy, so you should average over a handful samples, like 10.

          1 Reply Last reply Reply Quote 0
          • ledbelly2142L Offline
            ledbelly2142
            last edited by

            @jmarcelino
            Thanks! yes, I only had 'import macine'
            Now I get a reading, but it does not look like the sensor is working correctly. I am using ATTN_11DB to make the math conversion easier value * (3300/1024.0)
            The raw ADC count is still high, at 883 and its not changing much.

            Perhaps I am missing something in the documentation, is the ADC count a division of something? e.g. 883 count = 0.83v?

            Thanks

            Friends don't let friends run with scissors

            robert-hhR 1 Reply Last reply Reply Quote 0
            • robert-hhR Offline
              robert-hh @ledbelly2142
              last edited by

              @ledbelly2142 The range of the ADC is 0..4096. With an attenuation of 11DB, the reading of 883 tells 883*3.3/4096V = 0.71V

              ledbelly2142L 1 Reply Last reply Reply Quote 1
              • ledbelly2142L Offline
                ledbelly2142 @robert-hh
                last edited by

                @robert-hh
                Thanks, I could not find where in the documentation the ADC range?

                The vendor of the CO2 sensor used the formula to get CO2 ppm:
                value*(3300/1024)

                I think there are 1024 is the steps on an arduino for the analog in.

                So I think the step function to interpret the ppm should be:
                value*(3300/4096) which would put us in the range of 711 ppm of CO2. Which sounds about right given that is on my desk right in front of me.

                Thanks!

                Friends don't let friends run with scissors

                J 1 Reply Last reply Reply Quote 0
                • ledbelly2142L Offline
                  ledbelly2142
                  last edited by

                  Here is what I used for this sensor:

                  import machine
                  from machine import ADC
                  
                  adc = machine.ADC()               # create an ADC object
                  apin = adc.channel(pin='P16', attn=ADC.ATTN_11DB)   # create an analog pin on P16 & connect CO2 sensor
                  
                  print("")
                  print("CO2 sensor Warming Up")
                  #time.sleep(180) # CO2 sensor needs 3 minutes to warm up
                  print("Reading CO2 Sensor...")
                  value = apin()
                  print("ADC count = %d" %(value))
                  
                  # LoPy  has 1.1 V input range for ADC
                  co2 = value * (3300/4096.0)
                  print("CO2 Level = %5.1f ppm" % (co2))
                  
                  

                  Friends don't let friends run with scissors

                  1 Reply Last reply Reply Quote 0
                  • J Offline
                    jmarcelino @ledbelly2142
                    last edited by jmarcelino

                    @ledbelly2142
                    The ADC is 12 bit so the range is 0..4095 as @robert-hh explained. The reference is 1.1 Volts.

                    At ATTN_11DB the full scale goes to 3.9V: 1.1 * math.pow(10.0, 11.0/20.0) so a more correct formula is value * (3900/4096)

                    Finally the sample code you linked doesn't just use the voltage reading (what you have now) as the concentration, it takes a few extra calculations.

                        int voltage_diference=voltage-400;
                        float concentration=voltage_diference*50.0/16.0;
                    

                    I haven't read the datasheet but I guess you'll need to do the same in your code.

                    ledbelly2142L 1 Reply Last reply Reply Quote 0
                    • ledbelly2142L Offline
                      ledbelly2142 @jmarcelino
                      last edited by

                      @jmarcelino
                      Thanks for your reply and help, I appreciate it. I understand the ADC bit range to 3900 instead of 3300--makes sense.

                      I am missing the voltage reading completely :( I was going on the ADC example code and explanations. It's gotta be in the documentation somewhere that I can't find. Even when I search the docs for 'voltage', only DAC shows up, not in ADC.

                      Why do we need the voltage difference -400 value?

                      How do I apply the concentration to get the value?
                      is that something like:

                      int voltage_diference=voltage-400
                      float concentration=voltage_diference*50.0/16.0
                      value = apin()
                      co2 = value * concentration(3900/4096.0)
                      

                      Or would it just be

                      co2 = value * concentration
                      

                      Thanks

                      Friends don't let friends run with scissors

                      J 1 Reply Last reply Reply Quote 0
                      • J Offline
                        jmarcelino @ledbelly2142
                        last edited by jmarcelino

                        @ledbelly2142
                        I can't find any proper datasheet for your sensor but this plot shows everything you need to know:

                        0_1501027117716_Screen Shot 2017-07-26 at 00.57.27.png

                        At 0 ppm the sensor outputs 0.4v so you you need to subtract 400 (in millivolts) from your voltage reading (the voltage_diference in that formula)

                        Then you know that 0.4 volts to 2.0 volts (a 1.6 volt range or 0 to 1600 in your voltage_diference from above) equates to a range of 0 to 5000 ppm.

                        ledbelly2142L 1 Reply Last reply Reply Quote 0
                        • ledbelly2142L Offline
                          ledbelly2142 @jmarcelino
                          last edited by

                          @jmarcelino
                          Thank you, makes sense now. Really appreciate it.
                          Cheers

                          Friends don't let friends run with scissors

                          1 Reply Last reply Reply Quote 0
                          • bmarkusB Offline
                            bmarkus
                            last edited by

                            Analog CO2 sensors does not really fit to todays IoT environment specially low power battery operated devices due to high power consumption and slow operation, long settle time. Take a look on Gas Sensing Solutions sensors. They are fast low power devices with digital interface. It is the data sheet of model I'm using with a LoRaWAN sensor (not PyCom), connected via serial line:

                            https://www.gassensing.co.uk/media/1050/cozir_ambient_datasheet_gss.pdf

                            ledbelly2142L 1 Reply Last reply Reply Quote 0
                            • ledbelly2142L Offline
                              ledbelly2142 @bmarkus
                              last edited by

                              @bmarkus
                              The COZIR sensors look nice. Are they in the sub $100 range? I also have CO2 sensors from co2meter.com, the K30. But they are a pain to work with and give very little support. At some point I wanted to create an I2C driver for micropython, but put it off because of the support. Another IoT option for low power gas sensors is Spec-Sensors We have used some of their stuff in the past, but they don't have CO2.

                              Thanks!

                              Friends don't let friends run with scissors

                              bmarkusB 1 Reply Last reply Reply Quote 0
                              • ledbelly2142L Offline
                                ledbelly2142
                                last edited by

                                Here's the updated code for this sensor with everyone's help. @jmarcelino @robert-hh
                                In testing it, the results seem reasonable. Not super accurate but enough within 100ppm. Digy-Key has them for $58

                                import machine
                                from machine import ADC
                                
                                adc = machine.ADC()               # create an ADC object
                                apin = adc.channel(pin='P16', attn=ADC.ATTN_11DB)   # create an analog pin on P16 & connect CO2 sensor
                                
                                print("")
                                print("CO2 sensor Warming Up")
                                #need initial delay (180) # CO2 sensor needs 3 minutes to warm up
                                print("Reading CO2 Sensor...")
                                value = apin()
                                print("ADC count = %d" %(value))
                                
                                # LoPy  has 1.1 V input range for ADC
                                co2 = (value-400) * (3900/4096.0)
                                print("CO2 Level = %5.1f ppm" % (co2))
                                

                                Friends don't let friends run with scissors

                                1 Reply Last reply Reply Quote 0
                                • bmarkusB Offline
                                  bmarkus @ledbelly2142
                                  last edited by bmarkus

                                  @ledbelly2142 said in Analog CO2 Sensor for LoPy, can 5v pin power it?:

                                  @bmarkus
                                  The COZIR sensors look nice. Are they in the sub $100 range?

                                  First hit of Google search gives $109 USD

                                  https://www.co2meter.com/products/cozir-0-2-co2-sensor

                                  As an indication you can visit the webshop of ChipCAD, a Hungarian distributor

                                  https://shop.chipcad.hu/Welcome/Default.aspx?scenarioID=360&pid=1878

                                  Prices are in HUF (Hungarian Forint), VAT not included. At the moment 1 USD = 262.6 HUF

                                  But it may vary by distributor, quantity, shipping conditions, custom, etc. and model. You can ask GSS to advice where to buy it, they are good.

                                  1 Reply Last reply Reply Quote 0

                                  Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                  Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                  With your input, this post could be even better 💗

                                  Register Login
                                  • 1 / 1
                                  • First post
                                    Last post

                                  Pycom on Twitter

                                  Pycom