Do you want to discover a seamless method for rapid prototyping with PSOC™ 6 microcontrollers and bring your ideas to life?
With the PSOC™ 6 Arduino integration, you can do just that! This powerful combination enables you to tap into the vast Arduino ecosystem and leverage the flexibility of PSOC™ 6 microcontrollers.
Experience the simplicity firsthand by interfacing an Infineon CO2 sensor with PSOC™ 6 AI Evaluation Kit and connecting it to Home Assistant with Arduino code. Say goodbye to complexity and hello to effortless prototyping!
OverviewMonitor indoor air quality with ease! This Arduino application, running on the CY8CKIT-062S2-AI, connects your CO2 sensor to Home Assistant via Wi-Fi and MQTT, utilizing Home Assistant's MQTT Discovery for seamless integration.
Prerequisite: Home Assistant & MQTT BrokerTo continue, you need to have the following ready: an MQTT broker, a Home Assistant instance with the MQTT integration, and a Wi-Fi network.
Here are some useful links to get everything working:
- Home Assistant installation: https://www.home-assistant.io/installation/
- MQTT broker & integration: https://www.home-assistant.io/integrations/mqtt/
That's it! If you have Home Assistant, a MQTT broker and the MQTT integration running, you're ready to continue.
What do you need?Hardware setupGrab an Infineon PAS CO2 sensor, connect it to the PSOC™ 6 AI Evaluation Kit, and run an Arduino code to read the sensor data. Then, stream it to Home Assistant and you're all set for data visualization! The diagram below shows how to connect the CO2 sensor to the Kit.
The sensor needs a 5V power supply to perform measurements and a 3.3V supply for logic & communication, which you can find here on the PSOC board:
Step 1: Install Arduino IDE
Ensure you have Arduino IDE 2.0 or higher installed. If not, download and install it from the official Arduino website.
Step 2: Add PSOC™ 6 Board to Arduino IDE
If you haven't already, follow the instructions in this Hackster article to install the PSOC™ 6 board in the Arduino IDE.
Step 3: Select CY8CKIT-062S2-AI Board
In the Arduino IDE, navigate to Tools > Board > Infineon PSOC6 Boards and select the CY8CKIT-062S2-AI board.
Step 4: Install PAS-CO2-Sensor Library
In the Arduino IDE, go to Sketch > Include Library > Library Manager. Search for pas-co2-sensor and install the library.
Step 5: Install Arduino_JSON Library
In the Arduino IDE, navigate to Sketch > Include Library > Library Manager. Search for Arduino_JSON and click the Install button to install the library. This library will simplify preparing the messages for Home Assistant.
Step 6: Install PubSubClient Library
In the Arduino IDE, navigate to Sketch > Include Library > Library Manager. Search for PubSubClient and click the Install button to install the library. This is the MQTT client and will allow to connect to a MQTT broker.
Constants
Now with all the hardware setup and software installed let's dig into the code. To start with using our sensor library we need to always include it along with the basic Arduino library at the top of our code :
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <pas-co2-ino.hpp>
#include <ArduinoJson.h>
Now we have to define the constant parameters for including the I2C communication frequency, measurement intervals, pressure reference, and message buffer size.
#define I2C_FREQ_HZ 400000
#define PERIODIC_MEAS_INTERVAL_IN_SECONDS 10
#define PRESSURE_REFERENCE 900
#define MSG_BUFFER_SIZE (256)
Then the constants for establishing a Wi-Fi connection and a MQTT broker should be defined.
const char* ssid = "your wifi name";
const char* password = "your wifi password";
const char* mqtt_server = "ip address of your mqtt broker";
const uint32_t mqtt_port = 1883;
const char* mqtt_user = "username for your mqtt broker";
const char* mqtt_password = "password for your mqtt broker";
Then we need to have the constants which are used to configure the MQTT sensor integration with Home Assistant, enabling automatic discovery and state updates.
const char* client_id = "co2-test-client";
const char* entity_id = "co2test";
const char* device_name = "CO2 Sensor Device"; // This is how the device will show in Home Assistant.
const char* entity_name = "CO2 Value"; // This is how the CO2 value will be named in Home Assistant.
const char* discoveryTopic = "homeassistant/sensor/co2-test-client/config";
const char* stateTopic = "homeassistant/sensor/co2-test-client/state";
Then a StaticJsonDocument
object named discoveryMessage
is defined with a 512-byte capacity to construct a JSON message for Home Assistant discovery.
StaticJsonDocument<512> discoveryMessage;
Now we define two objects sta
which is a WifiClient
object, which will be used to establish a Wi-Fi connection and then mqttc
which is PubSubClient
object that will be used for MQTT connection.
WiFiClient sta;
PubSubClient mqttc(sta);
Additionally we will have to instantiate an object of type PASCO2Ino
to define our desired sensing functionality, let's say we'll call it cotwo.
PASCO2Ino cotwo;
A character array msg
is declared with a size of MSG_BUFFER_SIZE
which will be used to store MQTT messages.
char msg[MSG_BUFFER_SIZE];
The last step to do before we can try everything out is to create an error type variable and a 16 bit integer to store our sensor readings. (The error type variable will be used as an error monitoring buffer, where we will be monitoring its value to make sure that everything is working properly):
int16_t co2ppm;
Error_t err;
Wi-Fi Connection
Now a function connect_wifi
is defined to establish a Wi-Fi connection. This function initially prints a message indicating the Wi-Fi network to connect to and initiates the Wi-Fi connection using begin()
. Then it waits for the connection to be established and once connected prints a success message and the local IP address obtained in the Wi-Fi network.
void connect_wifi() {
//connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
MQTT Connection
A function reconnect_mqtt()
is defined to establish or re-establish a MQTT connection. Here it enters a loop that continues until the MQTT connection is established. Then it attempts to connect to the MQTT broker using mqttc.connect()
. If the connection is successful it prints a success message or in case of failure it prints an error message with return code and waits for 3 seconds and retries.
void reconnect_mqtt() {
while (!mqttc.connected()) {
Serial.print("Attempting MQTT connection...");
if (mqttc.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(mqttc.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(3000);
}
}
}
Setup
Now we have the setup()
function. Here we initialize the Serial port with a baudrate of 115200
Serial.begin(115200);
and initialize the I2C interface for the CO2 sensor.
Wire.begin();
Wire.setClock(I2C_FREQ_HZ);
Next step is to actually initialize our sensor, we do this by using thebegin()
function on our created instance of the PASCO2Ino
object we created. Here the error type variable we created earlier proves itself handy. We will use it to check that the initialization was performed successfully:
err = cotwo.begin();
if (XENSIV_PASCO2_OK != err) {
Serial.print("initialization error : ");
Serial.println(err);
}
err = cotwo.setPressRef(PRESSURE_REFERENCE);
if (XENSIV_PASCO2_OK != err) {
Serial.print("Pressure reference error: ");
Serial.println(err);
}
err = cotwo.startMeasure(PERIODIC_MEAS_INTERVAL_IN_SECONDS);
if (XENSIV_PASCO2_OK != err) {
Serial.print("Start measure error: ");
Serial.println(err);
}
The Wi-Fi connection is established by calling theconnect_wifi()
function. Next, the MQTT client is configured with a server address, port, and buffer size, preparing it for communication. If the MQTT connection is lost, the reconnect_mqtt()
function is called to re-establish the link.
/* WiFi & MQTT Setup */
connect_wifi();
mqttc.setServer(mqtt_server, mqtt_port);
mqttc.setBufferSize(512);
reconnect_mqtt();
Now we have to prepare the Home Assistant MQTT Discovery message for the PAS CO2 sensor. See here for the docs behind this. Here we set properties such as name
, state_topic
, unit_of_measurement,
device_class,
and unique_id
for the sensor.
We also create a nested device
object with a name
property and an identifiers
array containing the our MQTT client_id
as identifier.
After this, the JSON object is serialized into a string, ready to be published to the MQTT broker.,
/* Home Assistant Auto Discovery */
discoveryMessage["name"] = entity_name;
discoveryMessage["state_topic"] = stateTopic;
discoveryMessage["unit_of_measurement"] = "ppm";
discoveryMessage["device_class"] = "carbon_dioxide";
discoveryMessage["unique_id"] = entity_id;
JsonObject device = discoveryMessage.createNestedObject("device");
device["name"] = device_name;
JsonArray identifiers = device.createNestedArray("identifiers");
identifiers.add(client_id);
String mqtt_discovery_payload;
serializeJson(discoveryMessage, mqtt_discovery_payload);
This code prints the MQTT discovery payload to the serial console for debugging purposes. It then publishes the payload to the specified discoveryTopic
using the MQTT client, with the false
parameter indicating that the message should not be retained on the broker.
Now, as an optional intermediate step, we print the message to be published.
After this, the message is published to the Home Assistant Discovery topic of the broker and the device will already show up in Home Assistant.
Serial.print("Publish:\t");
Serial.println(mqtt_discovery_payload.c_str());
mqttc.publish(discoveryTopic, mqtt_discovery_payload.c_str(), false);
Loop
The main loop does the following things:
- Maintains the MQTT connection by calling
reconnect_mqtt()
if disconnected. - Retrieves the CO2 sensor value using
cotwo.getCO2(co2ppm)
and if there is a error then tries to handle the error or publishes the CO2 value if successful. - Publish updated sensor values to the specified
state_topic.
- Calls
mqttc.loop()
to process incoming MQTT messages. - Waits for the specified interval (
PERIODIC_MEAS_INTERVAL_IN_SECONDS
) before taking the next measurement.
void loop() {
/* Keep connection to MQTT broker */
if (!mqttc.connected()) {
reconnect_mqtt();
}
/* Get CO2 Sensor value */
err = cotwo.getCO2(co2ppm);
if (XENSIV_PASCO2_OK != err) {
if (XENSIV_PASCO2_ERR_COMM == err) {
delay(600);
err = cotwo.getCO2(co2ppm);
if (XENSIV_PASCO2_OK != err) {
Serial.print("get co2 error: ");
Serial.println(err);
}
}
} else {
/* If successful, publish to MQTT broker */
Serial.print("Co2 PPM value: ");
Serial.println(co2ppm);
snprintf(msg, MSG_BUFFER_SIZE, "%d", co2ppm);
Serial.print("Publish message: ");
Serial.println(msg);
mqttc.publish(discoveryMessage["state_topic"], msg);
}
mqttc.loop();
delay(PERIODIC_MEAS_INTERVAL_IN_SECONDS * 1000);
}
Now, once you compile and upload the Arduino code to your PSOC6 device you will see the Sensor CO2 added in your Home Assistant MQTT Devices (Devices -> MQTT). Once uploaded, you should see the "CO2 Sensor Device" with "CO2 Value" entity added.
After a few seconds initialization time the sensor will publish the first measurement value, which will update every measurement interval. Your setup is complete, and you're ready to start monitoring and exploring the sensor's readings!
Dive deeper into our documentation for additional information.Stay ahead of the curve: explore our upcoming features and projects on Github.
Comments
Please log in or sign up to comment.