Arduino oled nitrox analyzer

This is update version of my DIY nitrox analyzer based on Arduino compatible board.

It’s using small oled display and powered by 9v battery. Display o2 percentage of gas, sensor mv output, two MOD(maximum operating depth) in meter. 1 push button for lock screen, calibration, po2 change.

Part list
  • Arduino nano compatible board (or any other Arduino board will do)
  • ADS1115 16 Bit DAC Module (the ADS1115 provides 16-bit precision at 860 samples/second over I2C!)
  • 0.96 inch OLED 128×64 I2c display module
  • Rocker or toggle switch for power on/off
  • 1 Push button
  • 1 9v battery connector (better using 3 AA or AAA)
  • 1 Piezo Buzzer (I took one from pc. Skip if you don’t need beeping analyzer :)
  • 1 Connector for o2 sensor (mine is molex)
  • 1 O2 sensor (I use old cell from my CCR but you can get sensor from Teledyne, Maxtec or other manufacturer.


  • VDD to 5v
  • GND to Ground
  • SCL to A5 (nano)
  • SDA to A4 (nano)

OLED 128×64 I2c display module

  • GND to Ground
  • VCC to 5v
  • SCL to A5 (nano)
  • SDA to A4 (nano)

Push button

  • 1 pin to Ground
  • 2 pin to D2 (nano)

9v battery

  • positive to VIN (nano) through rocker (toggle) switch
  • negative to Ground


  • positive to D9 (nano)
  • negative to Ground

Oxygen sensor

  • positive to A0 ADS1115
  • negative to A1 ADS1115
The source

Additional library


youtube video

  • 1 short button push to lock current display (1 push to unlock)
  • 2 sec hold to calibration
  • 3+ sec hold to MOD PO2 change (1.3 to 1.5 rotation)

I put everything include sensor in a small plastic box(65×95×55mm) with transparent cover. Here’s some image of ugly looking inside. I’m sure someone can 3d print smaller and prettier shell.

9v battery is very poor choice for Arduino project (I used because that’s what I have many). AA, AAA x 3 or small rechargeable batteries are better.

Warning! Be cautious when you use 9v battery. Arduino onboard DC regulator will be destroyed if you accidentally switch positive & negative.

Todo list

  • clean the code
  • replace board to custom pcb or pro mini
  • replace 9v batt to rechargeable small lipo battery
  • smaller case

Please don’t email me about basic arduino programming issue. You can search or post question here.

59 thoughts on “Arduino oled nitrox analyzer”

  1. Hi,

    Building a NX analysor based on your schema, so far so good.

    What did you use to put onto your revo cell? I will reuse my revo cells that are getting swapped.



  2. Hi there!

    It’s all good!! :)

    I see you changed the display code from the video you posted to the actual code here :D

    Can you confirm you only changed cosmetic display stuff and nothing important in the various calculations performed in the code?

    It’s pretty neat! I have quite a lot of fun putting it together, I imagine how you feel actually coding it all :D

    Next step is to solder it up and put it in the box…

    I have one more question: I also see you removed the max O2 display in the video. I understand we don’t need that info from a practical point of view. But nevertheless we still keep the clearing max result capability. Could you elaborate a bit why we actually need to clear the max O2 value and how it i used/purpose here?

    Thanks a million!!!


    1. Hi, I update the code on post too. You can download it.
      Max result is useful sometime if I forgot to lock the screen.
      Have fun with your project. :)

      1. Super cool :)

        One last question (sorry!) : the NRC O2 sensor I have specify a Recommended Load resistor of 10KOhms.

        To achieve this spec recommendation do I put a resistance in parallel between the O2 Cell wires?

        That’s what I believe but I am no pro at all..!

  3. Hey :)
    For my test-setup I’m using the sensor of an old OxyCheq Handheld and am experiencing quite some delay in the readings. Returning back to 20.9 from 19.0 takes about five minutes despite venting the sensor with fresh air.

    Things seem to improve when I put a 10 kOhm resistor in parallel to the sensor – at least regarding the speed – unfortunately at the cost of reading stability. So either I have a slow sensor or one with large drift in the readings.

    Any idea what the problem might be here?


      1. Yes, it’s quite old and most likely that’s the problem. Measuring the voltage directly it also behaves kind of sluggish. I will try to get a hold of a newer sensor and see what it’s like with that ☺️

  4. Thanks for posting this project. I built it and it is working perfectly. I made a few small modifications to the program: (1) increased the time to release the button on “CAL” from 1 to 2 seconds because otherwise I sometimes inadvertently changed the limit PPO2 value. (2) Max PPO2 always starts at 1.4 bar instead of retaining the last value of the previous use.

  5. Thanks for the project docs. I just finished it to replace a defunct old analog analyzer.
    I had fun modifying the code to move text around on the screen to work with my two color display and change the MOD measurements to feet from meters. This is way more feature rich than most commercial units at 4 times the price. Now to solder up a final version and print a box for it. Thank you!!!

    1. Find “Calculate MOD” function and change multiply value 10 to 33 (it’ll look like this).
      float cal_mod (float percentage, float ppo2 = 1.4) {
      return 33 * ( (ppo2/(percentage/100)) - 1 );

      And change “m” to “ft”.
      display.print(F("m ")); -> display.print(F("ft"));

      Hope this help.

    1. It seems it is written for a larger dislplay. For the .96 oled i used i had to change the position and text size. to make it fit.

  6. You need to adjust the display size in the library file Adafruit_SSD1306.h
    Look at line 60 an onwards for explanation: uncomment the display description for the one that you have and comment the other 2.
    I uncommented #define SSD1306_128_64 for my 0.96″ display.
    Then save the altered file and recompile the analyzer program.
    Good luck!

    1. For anyone coming to this project the way previously commented to set display size still works but has been depreciated. The correct way to do this now is to add the lines:

      #define SCREEN_WIDTH 128 // OLED display width, in pixels
      #define SCREEN_HEIGHT 64 // OLED display height, in pixels

      These should be placed into the o2_analyzer2.ino file and can then easily be edited to your display size but using the listed parts should work just fine. But if someone has decided to run a 128X128 display they can adjust for that. I am in the process of setting one up but still waiting on parts to come in. I will be making some changes to the original project on my fork that will include this and also plan to move a few things around as the display I have will have a yellow section at the top and blue towards the bottom. If at some point I end up with a larger or smaller display to work with I will try and set something up for them to work as well. I will also be likely implementing a separate hold and calibrate button for the project.

      1. Nightshade I tried your method but I got a bunch of errors so I went to Walts method. Using Walts method as a newbie I finally figured out to go to the directory where the library is stored (c:\windows\users\myname\documents\arduino\libraries\adafruit_ssd1306 and opened adafruit_ssd1306.h with notepad. Now depending on the library may depend on the position of the line that you need to edit (line 60 according to Walts directions in my file version has this text.. /// header client code will then need to be modified to use the scoped enum this is obviously not the right area so to make this instruction as foolproof as possible between versions then read the very beginning of the file beyond the licensing blurb and in mine the very first line I am interested in says // ONE of the following three lines must be #defined: and then below this I have three lines for a 128×64, a 128×32 and a 96×16 screen size. I removed the double // on

        define SSD1306_128_64

        so now the first set of lines looks like this:

        // ONE of the following three lines must be #defined:
        #define SSD1306_128_64 ///< DEPRECATED: old way to specify 128×64 screen
        //#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128×32 screen
        //#define SSD1306_96_16 ///< DEPRECATED: old way to specify 96×16 screen
        // This establishes the screen dimensions in old Adafruit_SSD1306 sketches

        Eunjae Im – super nice project. thanks so much.. and now on to seeing if I can make a helium analyzer :)

  7. First of all, this is great I love what you have done here!

    Just a question, could you host the project on GitHub (or an alternative?) that way it will be easier to track code changes for example. Also would allow other to contribute. (like add a toggle for meters/feet for example). Or the suggestion of defaulting to 1.4 instead of last po2 setting.

  8. Mine turned out great. I 3d printed a case that fits everything perfectly for a usb powered external sensor build.
    That case holds the Nano, .96oled, and the ads1115. Hot glued the buzzer into the round vent inside cover. Drilled a hole for the mono jack and button.
    Thanks again! Awesome work! Has me thinking about buying some solenoids and making a auto blender for nitrox.

    1. Hi Rob can i buy a housing from you?
      I am trying also to make a nitrox blender maybe you can help me out a litlle
      Thanx ron

    1. Nice box!

      Do you have any pictures of the finished product? I want to make the same analysor but have no 3D skills. Friend of mine can print it but would like to see where all components go and where do you place the O2 sensor.


  9. I am not that good white arduno,s or computers but I get a fail nl: adafruit_SSD1306:h:NO SUCH FILE DIRECTORY. what to do???

    1. witch Arduino version doe jou use? I use 1.8.7 and tryed 1.0.6 but 1.0.6 dos not work. fail: #define RA_SIZE 20
      RunningAverage RA(RA_SIZE);

  10. Great project/resource! I am diver and happen to be tinkering with the Arduino lately. Just one question – What did you use for the flow restrictor? What is the hole size? Thanks!

  11. Hello, I am interested in this project. may I ask if I replace the model of the oxygen sensor, do I need to change the Arduino code? Because I can’t find the output voltage curve of the R-17MED Oxygen Sensor, and the code seems to use the difference in oxygen between the air and the target gas to calculate the oxygen concentration, is that correct?

  12. No, you don’t need to change the code. Any type of galvanic oxygen cell outputs a voltage that is linear proportional to the oxygen percentage. So if your cell delivers 10 mV with 21% oxygen, it will supply 20 mV with 42% oxygen. The calibration process stores the voltage when the cell senses the oxygen in normal air and uses this value as the basis for the calculation of gases with another oxygen content.

  13. thank you for the foot conversion information. I added 1.4 after mod and put Fsw instead of ft and removed the last decimal place for clarity for my dive team. I have a second version for 1.6.

    1. you can help Steven? i making my analyzer…….how you put 1.4? and how i install the library RunningAverage? i not find option to download at github

  14. I’m a total newb at Arduino so this is probably really silly. In the diagram you have a breadboard (i think that’s the right term?) but then in the photos, you don’t? What happens to the wires that go to the same spot?

    1. Chris, the breadboard depending on type that you purchase is just what folks use to prepare and or test their projects. When they are ready to solder everything then they typically hard solder into place. For example on a breadboard you can see wire from the digital converter ADS1115 going from SCL to A5 (nano) and you have another wire going to the same A5 on the nano board from the OLED display module SCL spot. Same with SDL to A4 from ADS1115 to nano spot a4 and SDA from OLED to nano A4.

      SCL to A5 (nano)
      SDA to A4 (nano)

      OLED 128×64 I2c display module
      SCL to A5 (nano)
      SDA to A4 (nano)

      All this means is that you are connecting the wire from SCL from both the ADS1115 and the OLED to the same spot on the Nano (spot A5). On a breadboard there are typically circuit tracks that join the holes from each side so the two on the left all the wa down the board are connected by the circuit tracks and then the two sets of 5 in the center are each connected. I may not be explaining it very well but if you look at this article it will explain it for you and scroll down to the section of ‘Anatomy of a Breadboard’.

  15. Amazing little project, thanks! I have made my own, using a CITYcell AO2 sensor. Seems to work well enough and is quite fast. Can be picked up on AliExpress for about US$30.

  16. Went with a larger OLED for better readability, threaded the hole in the case to screw in the sensor to allow a diverter to be threaded on, and went with a waterproof bulkhead to allow charging of the Lithium battery. Next build has a small LiPo flat pack instead of the larger Lithium stick, even though it still has a lot of room in the case. I may custom print a case and bring down the form factor a bit more.

    1. Derek, what OLED did you use? Do you have a link for it? I would like to find a larger one but they seem to jump up in price from the 128×64 on the 0.96.

  17. I built this and it worked perfectly, then the battery went flat and after i replaced it, the display says the cell is only giving 0.06mV. I’ve checked the cell and it’s giving 8mV, which is getting right through to pins A0 & A1 of the ADS1115.
    Do you think I should replace the ADS1115 or have I somehow fried the Arduino board?

    1. As a follow up, I’ve found that it works perfectly when powered from the USB port, or when using an “older” 9v battery which is only giving 7.5v, but doesn’t work when using a brand new 9v battery at 9.5v. I don’t know why this is, but I’m going to switch to using a 3xAAA power pack

  18. I have everything installed but the% oxygen does not oscillate, after calibrating it gives me 0.06 mv and 20.9 oxy

Leave a Comment