Introduction: IOT123 - I2C MQ2 BRICK

About: The tension between novelty and familiarity...

The IOT123 BRICKS are DIY modular units that can be mashed up with other IOT123 BRICKS, to add functionality to a node or wearable. They are based on the inch square, double-sided protoboards with interconnected through holes.

A number of these BRICKS are expected to be on multiple nodes (Master MCUs - ESP8266 or ATTINY84) on a site. The MCU needs no prior knowledge of the sensors purpose or software needs. It scans for I2C nodes then requests a property dump (sensor data) from each slave. These BRICKs supply 5.0V, 3.3V and another AUX line which is customisable.

This I2C MQ2 BRICK dumps 3 properties:

LPG (Parts Per Million), CO (PPM), SMOKE (PPM).

This Sensor provided an interesting scenario: It needs at least 2 minutes (up to 5 minutes) to warm up, then it needs to calibrate for 20 seconds before use. As the host MCU is only inteseted in getting name/value pairs (and a continue message), we have introduced a "PREPARE" property. As its continue message is "1" (more to come), the Host MCU will keep polling the BRICK until it is ready. Also it is recommended to "Burn-in" the MQ2 before use i.e. leave connected to your 5V circuit for 24 hours.

The Keyes type sensor bricks will be abstracted first as they come with vitamins (extra components needed) included and are relatively cheep (I bought 37 for 10AUD). Other boards/circuits will be introduced to the I2C BRICKS.

The through-holes adjacent to the ATTINY85 have been left unused, to enable a pogo pin programmer while the DIP8 is soldered to the PCB.

A further abstraction, packaging the BRICKS in small cylinders that plug into a D1M WIFI BLOCK hub, pumping the values to a MQTT server, is being developed.

Step 1: Material and Tools

    There is a full Bill of Material and Sourcing list.

    1. MQ2 sensor brick (1)
    2. ATTINY85 20PU (1)
    3. 1" Double sided protoboard (1)
    4. Male Header 90º (3P, 3P)
    5. Male Header (2P, 2P)
    6. Jumper Shunt (1)
    7. Hookup wire (~7)
    8. Solder and Iron (1)

    Step 2: Prepare the ATTINY85

    AttinyCore from the Boards Manager is needed. Burn bootloader "EEPROM Retained", "8mHZ Internal" (all config shown above).

    Use the included source; compile and program to the ATtiny85.

    The GIST is here:

    You may find more details in these instructables:

    Best to test via breadboard before continuing.

    If you have existing ASSIMILATE SENSORS, make sure the slave address is different on a SENSOR/MCU Host combination i.e. all the Temperature sensors can have the same address as long as you only have one Temperature sensor on a MCU/node.

    Step 3: Assemble the Circuit

    1. On the front, insert the components ATTINY85 (1), 3P 90deg male headers (2)(3), 2P male headers (4)(5), and solder off on the back.
    2. On the rear, trace a orange wire from ORANGE1 to ORANGE2 and solder.
    3. On the rear, trace a blue wire from BLUE1 to BLUE2 and solder.
    4. On the rear, trace a green wire from GREEN1 to GREEN2 and solder.
    5. On the rear, trace a bare wire from SILVER1 to SILVER2 and solder.
    6. On the rear, trace a bare wire from SILVER3 to SILVER4 and solder.
    7. On the rear, trace a black wire from BLACK1 to BLACK2 and solder.
    8. On the rear, trace a black wire from BLACK3 to BLACK4 and solder.
    9. On the rear, trace a red wire from RED1 to RED2 and solder.
    10. On the rear, trace a red wire from RED3 to RED4 and solder.
    11. On the rear, trace a yellow wire from YELLOW1 to YELLOW2 and solder.

    The sensor can now be connected directly via its pins to the PCB or via wires, to the points shown in the pin contract.

    Step 4: Testing

    A number of these BRICKS are expected to be on multiple nodes (MCUs - ESP8266 or ATTINY84) in an environment. This is a unit test: checks the UNO requests/responses until all the data has been dumped, then neglects the I2C slave.

    1. Upload the UNO code to your UNO test harness. Ensure ADDRESS_SLAVE matches the BRICK's I2C address.
    2. Connect the 5.0V on UNO to a VCC on BRICK.
    3. Ensure jumper for that pin is on.
    4. Connect the GND on UNO to GND on BRICK.
    5. Connect the A5 on UNO to SCL on BRICK.
    6. Connect the A4 on UNO to SDA on BRICK.
    7. Connect a 4K7 pull-up resistor from SDA to VCC.
    8. Connect a 4K7 pull-up resistor from SCL to VCC.
    9. Connect your UNO to your Dev PC with USB.
    10. Open the Arduino Console.Choose 9600 baud (restart the UNO and reopen the console if you have to).
    11. The Property Names and values should be printed to the console once then the word sleep is repeated.

    If you see "setup" then 3 lines of garbage repeated you may have your SDA and SCL lines back to front.

    I2C Master logging from I2C slave with plotter/metadata support.

    bool _outputPlotterOnly = false;
    bool _confirmedMetadata = false;
    int _packetSegment = 0;
    bool _i2cNodeProcessed = false;
    char _property[2][24] = {"name", "value"};
    voidsetup() {
    Wire.begin(); // join i2c bus (address optional for master)
    Serial.begin(9600); // start serial for output
    if (!_outputPlotterOnly){
    voidloop() {
    if (_i2cNodeProcessed){
    if (!_confirmedMetadata){// let the slave know to start sending sensor data
    _confirmedMetadata = true;
    _i2cNodeProcessed = false;
    if (!_outputPlotterOnly){
    Wire.requestFrom(ADDRESS_SLAVE, 16);
    char packet[16];
    intindex = 0;
    bool isContinueSegment = false;// continueSegment (the 3rd) 1=more, 0=last
    while (Wire.available()) { // slave may send less than requested
    char c =;
    packet[index] = int(c) > -1 ? c : '';// replace invalid chars with spaces
    if (_packetSegment == 3){
    _packetSegment = 0;
    isContinueSegment = true;
    if (int(c) == 48 || int(c) == 86){// 0 on last property
    _i2cNodeProcessed = true;
    // send values to MQTT
    if (!isContinueSegment){
    if (!_outputPlotterOnly){
    strcpy(_property[_packetSegment - 1], packet);// set local var with name/value
    if (_outputPlotterOnly && _confirmedMetadata){
    if (_i2cNodeProcessed){

    Step 5: Next Steps

    The basic layout of the circuit and the I2C layer of the software is relate-able to many different sensors. The main thing to get right to start with, is the packet contract between master and slave.

    I have slated/started a (3D printed) packaged network of sensors that use this framework and will link to it as parts are published.

    This BLOCK is used by the MQ2 ASSIMILATE SENSOR.

    Be the First to Share


      • Remote Control Contest

        Remote Control Contest
      • First Time Author Contest

        First Time Author Contest
      • Stone Concrete Cement Contest

        Stone Concrete Cement Contest