Skip to content

Programming the Electronics

Non-Solder breakout board

I wanted my node boards to be as minimal as possible, I wanted only an ATtiny 412, I uF capacitor, I2C pins and pins for the sensor. This meant that I needed to program the ATtiny412 before soldering it onto the board. Inpired by Quentin Bolsee´s Non-solder breakout board I made a simple board to program the ATtiny412.


Non-solder ATtiny412 breakout board

The board only has the ATtiny412 footprints, UPDI pins and a 1uF capacitor.

Non-solder ATtiny412 breakout board inkscape

Non-solder ATtiny412 breakout board Inkscape

Non-solder ATtiny412 breakout board

Non-solder ATtiny412 breakout board

Download non solder 412 breakout board trace .png file

I was able to program the ATtiny412s for the DHT22 node board and the MQ2 node board using the breakout board. I just had to hold the 412 in place while it was programmed through UPDI -> FTDI -> USB.


Programming the ATtiny412s

Programming with the Non-solder ATtiny412 breakout board

Programming the ATtiny 412s with the Non-solder ATtiny412 breakout board

After programming the ATtiny412s I soldered them onto the node boards.


Code

Using example codes from the internet I put together the code for all the components.

DHT22 node

The code for the DHT22 node is as simple and easy to understand as I could make it.

#define DHT_NODE_ADDRESS 1 // I2C address of the DHT22 slave module
#include <Wire.h> 
#include <DHTStable.h>

#define DHTPIN 4  // DHT connected to ATtiny412 pin 4 (PA3)
#define DHTTYPE DHT22   // DHT 22  (AM2302)

DHTStable DHT; // initialize the DHT library

// Initialize the humidity and temperature variables
int humidity = 0;
int temperature = 0;

void setup()
{
    Wire.begin(DHT_NODE_ADDRESS); // join i2c bus with defined address
    Wire.onRequest(requestEvent); // register event
}

void loop()
{
    DHT.read22(DHTPIN); // Read DHT22 data. 

    temperature  = DHT.getTemperature();
    humidity = DHT.getHumidity();

    delay(2000); /* Add 2 second delay in the loop */
}

void requestEvent() {
    Wire.write(temperature); // respond with message of 4 bytes
    Wire.write(humidity);    // respond with message of 4 bytes
}

MQ2 node

The code for the MQ2 node is very similar to the DhT22 node code.

Using the Wire library and DHTStable library I read the temperature and humidity and post the data to the master when requested.

#define MQ2_NODE_ADDRESS 2 // I2C address of the MQ2 node module
#include <Wire.h>>
const int MQ2_PIN = 4; // Analog pin connected to MQ2 sensor

int gasValue = 0;

void setup() {
    delay(20000); // allow the MQ2 to warm up
    Wire.begin(MQ2_NODE_ADDRESS); // Set the I2C slave address (0x43 for MQ2 gas sensor)
    Wire.onRequest(requestEvent); // Register the request event handler
}

void loop() {
    // Read gas sensor data
    gasValue = analogRead(MQ2_PIN);
    delay(2000);
}

void requestEvent() {
    Wire.write(gasValue);
}

Master node

The code for the Master node handles all requests to the sensor nodes as well as handling the reading for the DS18b20 waterproof temperature sensor. It also gathers all the data and displays the readings on the SSD1306 OLED display.

Using the Wire library I request data from the sensor nodes. The OneWire and DS18B20_INT libraries handle the waterproof sensor. Both Adafruit_ libraries are for the SSD1306 OLED display. This code snippet works and shows the basic readings and displaying of data. It is not the final version of the code. (for example no code to handle button inputs.)

#include <Wire.h> //For I2C 

#include <OneWire.h> //for DS18B20
#include <DS18B20_INT.h> //for DS18B20

#include <Adafruit_GFX.h> //for SSD1306 OLED
#include <Adafruit_SSD1306.h> //for SSD1306 OLED

#define DHT_NODE_ADDRESS 1 // I2C address of the DHT22 node module
#define MQ2_NODE_ADDRESS 2 // I2C address of the MQ2 node module

#define ONE_WIRE_BUS 21 // Pin for DS18B20 sensor

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

OneWire oneWire(ONE_WIRE_BUS); //for DS18B20
DS18B20_INT sensor(&oneWire); //for DS18B20

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

int temperature, humidity, gasValue, soilTemp;

void setup() {
    Wire.begin();        // join i2c bus (address optional for master)
    Serial.begin(115200);  // start serial for output

    sensor.begin(); //begin DS18B20 sensor

    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
    }
    delay(2000);
    display.clearDisplay();
}

void loop() {

    sensor.requestTemperatures(); // get temperature from DS18B20
    while (!sensor.isConversionComplete());  // (BLOCKING!!) wait until sensor is ready

    soilTemp = sensor.getTempC();

/*
    Serial.print("Temp: ");
    Serial.println(sensor.getTempC());
*/


    // Request data from the DHT22 sensor node
    Wire.requestFrom(DHT_NODE_ADDRESS, sizeof(int) * 2); // Request 2 integers
    if (Wire.available() >= sizeof(int) * 2) {

    temperature = Wire.read();
    humidity = Wire.read();

/*
    // Process and display the received data from DHT22
    Serial.print("DHT22 - Temperature: ");
    Serial.print(temperature);
    Serial.print(" °C, Humidity: ");
    Serial.print(humidity);
    Serial.println(" %");
*/
    }

    // Request data from the MQ2 gas sensor node
    Wire.requestFrom(MQ2_NODE_ADDRESS, sizeof(int)); // Request 1 integer

    if (Wire.available() >= sizeof(int)) {

    gasValue = Wire.read();

/*
    // Process and display the received data from MQ2 gas sensor
    Serial.print("MQ2 Gas Sensor - Gas Value: ");
    Serial.println(gasValue);
*/
    }

    display.clearDisplay();
    display.setTextSize(1);
    display.setTextColor(WHITE);
    display.setCursor(0, 0);
    // Display static text
    display.println("Air Temperature:");
    display.setCursor(100, 8);
    display.println(temperature);
    display.setCursor(0, 8);

    // Display static text
    display.println("Air Humidity");

    display.setCursor(100, 8);
    display.println(humidity);

    // Display static text
    display.setCursor(0, 16);
    display.println("Gas Value: ");
    display.setCursor(100, 16);

    // Display static text
    display.println(gasValue);
    display.setCursor(100, 32);

    // Display static text
    display.println(gasValue);
    display.display(); 


    delay(1000);
}

Using only the Wire library I read the gas level through analogRead and display the readings of all connected sensor to the OLED display.


Download DHT22 sensor node .ino code

Download MQ2 sensor node .ino code

Download Master node .ino code