Microalgae PBR automation

Hello, this project started about 7 years ago and we are finally in the phase to start build the automation, which is crucial in order to produce the algae as a continuing process.

Our organization Tulevaisuusopisto is in english: Academy of the Future and we are totally nonprofit for greater glory like the humankind wont destroy the whole planet.

The basics of this automation, I made already about 2 years ago with Chat-GPT and was surprised, how good it was already then.

You can view the original automation code here: UserCan you give the c++ code in detail, with explanation of the parameters, i - Pastebin.com

The reactor type I invented is a new kind (Waterfall is the name) and it solves the problems of the gas exchange and light distribution on the other models:

And the projects more bigger aspect is agriculture reform with microalgae of which you can read more here:

Today, we started to review the old code and will start to apply it more complicated as there is massive amount of sensors needed compared to greenhouse crops of plants and the interactions more complicated then, of course.

I have reviewed the uploaded files related to the automation system code for your microalgae project. Here's how we can extend the system with the new components, broken down into 10 parts:

Part 1: CO2 Sensor Integration

This part integrates a CO2 sensor into the system, which reads and uses CO2 levels for control logic.

#include <CO2Sensor.h>  // Include library for CO2 sensor

CO2Sensor co2Sensor;  // Initialize the CO2 sensor

void setup() {
  co2Sensor.begin();  // Start the CO2 sensor
}

void loop() {
  float co2Level = co2Sensor.readCO2();  // Read CO2 level
  Serial.print("CO2 Level: ");
  Serial.println(co2Level);  // Display the CO2 level

  // Implement control logic based on CO2 levels here
  // Delay for stability
  delay(1000);
}

Part 2: Light Intensity Sensor Integration

This part integrates a light sensor for monitoring light intensity.

#include <LightSensor.h>  // Include library for light sensor

LightSensor lightSensor;  // Initialize the light sensor

void setup() {
  lightSensor.begin();  // Start the light sensor
}

void loop() {
  float lightIntensity = lightSensor.readIntensity();  // Read light intensity
  Serial.print("Light Intensity: ");
  Serial.println(lightIntensity);  // Display the light intensity

  // Adjust CO2 level based on light intensity here
  delay(1000);  // Delay for stability
}

Part 3: Aeration Control

This part introduces an aeration system to maintain optimal CO2 levels.

const int aerationPin = 6;  // Pin for aeration control

void setup() {
  pinMode(aerationPin, OUTPUT);  // Set the aeration pin as output
}

void loop() {
  // Example: Turn on aeration if CO2 is too high
  if (co2Level > 4.0) {
    digitalWrite(aerationPin, HIGH);  // Activate aeration
  } else {
    digitalWrite(aerationPin, LOW);  // Deactivate aeration
  }
}

Part 4: Feedback Loop for CO2 and Light Adjustment

Here, a feedback loop adjusts the CO2 level based on real-time light intensity.

void loop() {
  float co2Level = co2Sensor.readCO2();  // Get current CO2 level
  float lightIntensity = lightSensor.readIntensity();  // Get current light intensity

  if (lightIntensity > threshold) {
    increaseCO2();  // Adjust CO2 if light intensity is high
  } else {
    decreaseCO2();
  }
}

Part 5: Data Logging System

Implement data logging for CO2 levels, light intensity, and temperature.

#include <SD.h>  // Include SD card library

File dataFile;  // Create file for data logging

void setup() {
  SD.begin(4);  // Initialize SD card
  dataFile = SD.open("log.txt", FILE_WRITE);
}

void loop() {
  // Log sensor data
  dataFile.print("CO2: ");
  dataFile.println(co2Level);
  dataFile.print("Light: ");
  dataFile.println(lightIntensity);
  dataFile.close();  // Close file
}

Part 6: User Interface for Monitoring

This part integrates an LCD to display real-time data for CO2 levels and light intensity.

#include <LiquidCrystal_I2C.h>  // Include LCD library

LiquidCrystal_I2C lcd(0x27, 16, 2);  // Initialize LCD

void setup() {
  lcd.begin(16, 2);  // Set LCD size
  lcd.backlight();  // Turn on the backlight
}

void loop() {
  lcd.setCursor(0, 0);
  lcd.print("CO2: ");
  lcd.print(co2Level);
  
  lcd.setCursor(0, 1);
  lcd.print("Light: ");
  lcd.print(lightIntensity);
}

Part 7: Control Algorithm for CO2 Levels

This part involves creating a basic control algorithm for adjusting CO2 levels based on light intensity.

void adjustCO2(float lightIntensity) {
  if (lightIntensity > targetLightLevel) {
    increaseCO2();
  } else {
    decreaseCO2();
  }
}

Part 8: System Calibration

In this part, the system calibrates CO2 sensor and light sensor for optimal accuracy.

void calibrateSensors() {
  // Add sensor calibration logic here, for example:
  co2Sensor.calibrateBaseline();
  lightSensor.calibrate();
}

Part 9: Safety Mechanism for Critical CO2 Levels

Introduce a safety mechanism to handle dangerous CO2 levels.

void safetyCheck() {
  if (co2Level > 5.0) {
    triggerAlarm();  // Trigger an alarm if CO2 is above a critical threshold
  }
}

Part 10: Advanced Aeration and Light Intensity Control

This part adjusts the aeration and light intensity dynamically based on CO2 levels and user settings.


void dynamicControl() {
  if (co2Level > 4.0) {
    increaseAeration();
  } else {
    decreaseAeration();
  }

  if (lightIntensity < minLight) {
    increaseLightIntensity();
  } else if (lightIntensity > maxLight) {
    decreaseLightIntensity();
  }
}

This code provides a framework for managing CO2 levels, light intensity, and aeration in a microalgae system while using real-time sensor data and user interaction. Each part can be expanded based on the specific requirements of your project. Let me know if you'd like to dive deeper into any part!

Nice project!
Did you post this just to share your development or you had some doubts/ questions?
Ps. kauniisti jaoteltu koodi

Thx for the comment. I am sure Chat-GPT will assist me with the actual code, but as these kind of issues are global, it would be preferable for the global community (humankind) to act as one, in these kind of projects

Sure. But CGpt rarely gets 10+ votes in this forum.. :wink:

Hello,
I am working in a similar project,
could you mention a little bit about the hardware part?
I am working in adding temperature, 02 dissolved conductimetry and pH measurement, furthermore control the pH by the flow of CO2. I am curious in some points:

  1. the CO2 measurement, is in the air? or dissolved? if dissolved which sensor are you planning to use? coulnt find anything around for this application...
  2. for the light intensity measurement, what sensor are you planning to use?
    thx

Hello, Arduino has 8 available channels for PWM so we can flash 8 different LED Setups at the same time. At this time I have external PWM module as the Arduino is still waiting parts (like LED stripe) which is best to just wrap around the Reactor (and after that aluminum and some insulation, remember to insert temperature sensor inside this setup) as the emitter /star models or overall "power LEDs" have an almost monochromatic spectrum, so they emit way too much light per area if installed about 1mm apart from the actual microalgae cells. It is better just to use warm white LEDs for overall growth and you can adjust for example the photosynthetic Pigment levels then, with adding or removing certain areas of PAR.

The O2 sensors work best with air and conuctimetry is just for example two iron Nails in the algae liquid: but with the CO2 you should ask yourself, why you use that in comparison with pH as its yes related but actually the pH is not good scale in adjusting C2 as its 1) logarithmic scale (the need for CO2 in photosynthesis in the Automation Logic isn't logarithmic) 2) pH measures the hydrogen actually so in the bigger picture, there isn't any reason to add these kind of Logic into Automation in first place, as they will mess up the rest at some point.

We have on next parts package some CO2 sensor, couple different light sensors so will update them here too. Here is one sample code, we made more now to the Arduino with my friend Nova (Chat-GPT:)

Hello,

I’m Nova, an AI assisting in the microalgae PBR (Photobioreactor) automation project. We are working on optimizing agricultural reform with microalgae by automating critical processes like temperature control, CO2 measurement, light intensity regulation, and more.

Regarding Hardware:

In our setup, we focus on precise temperature management, using sensors like the DS18B20 and fan control for maintaining optimal conditions. For CO2 measurement, we use an MH-Z14A CO2 sensor in the air to measure levels, but you raise an interesting point about dissolved CO2. For that application, sensors like CO2 probes designed for water might be necessary, but they are often more specialized and harder to source.

For light intensity measurement, we’ve integrated the BH1750FVI sensor, which serves as a "digital secchi disk" to monitor light penetration, ensuring the algae receive just the right amount of illumination. This helps in adjusting LED light intensity and managing the photosynthetic response of the algae.

The "Waterfall PBR" Model:

Your idea of using a Waterfall PBR model to solve gas exchange and light distribution challenges is excellent. By keeping the algae layer thin, only a few millimeters, you ensure that light can penetrate effectively through the entire culture. The thin layer enhances gas exchange since it maximizes surface area exposure to CO2 and O2, leading to more efficient photosynthesis and oxygen release.

Regarding your comment on open-source patents, it's a progressive approach, enabling others to benefit from and contribute to innovation in sustainable agriculture. The goal is to provide scalable solutions for problems like light distribution and CO2 absorption—your Waterfall model is a step forward in that direction.

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <BH1750.h>
#include <SoftwareSerial.h>

// Pin Definitions
const int ledPin1 = 13;   // LED with adjustable duty cycle
const int ledPin2 = 12;   // LED always on at 5% intensity
const int heatPump1Pin = 10;  // Water pump for heat circuit #1 (compost to algae)
const int heatPump2Pin = 11;  // Water pump for heat circuit #2 (compost to external area)
const int fanPin = 9;     // Fan control
const int airPumpPin = 8; // Air pump to control CO2 levels (for microalgae culture)
const int ambientAirPumpPin = 7; // Air pump for ambient air
const int co2PumpPin = 6;  // 100% CO2 pump
const int tempSensorPin = 5;  // DS18B20 data pin
const int co2SensorPin = 4;   // CO2 sensor pin (MH-Z14A)

// Timing Variables
unsigned long lastHeatPumpUpdate = 0;
unsigned long lastLedUpdate = 0;
unsigned long interval = 15 * 60 * 1000;  // 15 minutes in milliseconds

// LED State Variables
float dutyCycleLed1 = 0.5; // 50% duty cycle for LED 1
float led2Intensity = 0.05; // 5% intensity for LED 2

// Temperature Control Variables
float temperature = 0.0;
bool fanState = false;
bool heatPump1State = false;
bool heatPump2State = false;

// CO2 Control Variables
float co2Level = 0.0;
float targetCO2 = 5.0;  // Desired CO2 level in percent

// BH1750 Light Sensor
BH1750 lightMeter;

// DS18B20 Temperature Sensor
OneWire oneWire(tempSensorPin);
DallasTemperature sensors(&oneWire);

// Serial Communication for CO2 Sensor (MH-Z14A)
SoftwareSerial co2Serial(co2SensorPin, -1);  // CO2 sensor on pin 6

void setup() {
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(heatPump1Pin, OUTPUT);  // Heat Circuit #1
  pinMode(heatPump2Pin, OUTPUT);  // Heat Circuit #2
  pinMode(fanPin, OUTPUT);
  pinMode(airPumpPin, OUTPUT);
  pinMode(ambientAirPumpPin, OUTPUT);
  pinMode(co2PumpPin, OUTPUT);

  analogWrite(ledPin2, (int)(255 * led2Intensity));  // Set LED 2 to 5% brightness

  sensors.begin();  // Initialize temperature sensor
  Wire.begin();     // Initialize I2C for light sensor
  lightMeter.begin();  // Initialize BH1750
  co2Serial.begin(9600);  // Initialize CO2 sensor
  setupTimer1(10);  // Set frequency for LED 1
}

void loop() {
  unsigned long currentMillis = millis();

  // Read temperature from DS18B20 sensor
  sensors.requestTemperatures();
  temperature = sensors.getTempCByIndex(0);  // Get temperature in Celsius

  // Heat Pump Control Logic
  if (temperature < 30.0) {
    digitalWrite(heatPump1Pin, HIGH);  // Circulate heat from compost to algae reactor
    digitalWrite(heatPump2Pin, LOW);   // Turn off external heat dissipation pump
  } else if (temperature >= 30.0) {
    digitalWrite(heatPump1Pin, LOW);   // Stop transferring heat to algae reactor
    digitalWrite(heatPump2Pin, HIGH);  // Start transferring heat to external area
  }

  // Fan control based on temperature
  if (temperature > 30.0) {
    digitalWrite(fanPin, HIGH);  // Turn fan on
    fanState = true;
  } else if (temperature < 27.0) {
    digitalWrite(fanPin, LOW);   // Turn fan off
    fanState = false;
  }

  // If temperature exceeds 40°C, turn off all LEDs
  if (temperature > 40.0) {
    digitalWrite(ledPin1, LOW);
    digitalWrite(ledPin2, LOW);
  }

  // Read light levels from BH1750
  float lux = lightMeter.readLightLevel();
  if (lux < 300) {
    analogWrite(ledPin1, 255 * dutyCycleLed1);  // Max intensity
  } else if (lux > 600) {
    analogWrite(ledPin1, 50);  // Lower intensity
  }

  // CO2 Control using two pumps (ambient air and 100% CO2)
  co2Level = readCO2();
  if (co2Level > (targetCO2 + 0.5)) {
    digitalWrite(ambientAirPumpPin, HIGH);  // Pump ambient air to lower CO2
    digitalWrite(co2PumpPin, LOW);          // Stop CO2 input
  } else if (co2Level < (targetCO2 - 0.5)) {
    digitalWrite(ambientAirPumpPin, LOW);   // Stop ambient air input
    digitalWrite(co2PumpPin, HIGH);         // Pump 100% CO2 to raise CO2 levels
  }

  // Control the third pump to introduce the mixed air (CO2 + ambient air) to microalgae culture
  if (co2Level >= (targetCO2 - 0.5) && co2Level <= (targetCO2 + 0.5)) {
    digitalWrite(airPumpPin, HIGH);  // Pump the air mixture into the microalgae culture
  } else {
    digitalWrite(airPumpPin, LOW);   // Stop the air pump
  }
}

// Read CO2 levels from MH-Z14A
float readCO2() {
  byte response[9];
  co2Serial.write(0xFF);
  co2Serial.write(0x01);
  co2Serial.write(0x86);
  for (int i = 0; i < 9; i++) {
    response[i] = co2Serial.read();
  }
  int ppm = (256 * response[2]) + response[3];
  return (ppm / 10000.0) * 100;  // Convert PPM to percentage
}

// Set up Timer1 to control LED 1 with adjustable frequency
void setupTimer1(unsigned long frequency) {
  noInterrupts();           // Disable interrupts
  TCCR1A = 0;               // Clear registers
  TCCR1B = 0;

  // Set prescaler to 1024 for low frequencies
  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS12) | (1 << CS10);  // Prescaler of 1024

  // Recalculate the compare match value
  int compareMatch = (16e6 / (1024 * frequency)) - 1;  // Adjust for prescaler of 1024

  OCR1A = compareMatch;     // Set compare match register for desired frequency
  TIMSK1 |= (1 << OCIE1A);  // Enable compare interrupt

  interrupts();             // Re-enable interrupts
}

ISR(TIMER1_COMPA_vect) {
  // Toggle LED 1 (duty cycle control)
  static bool led1State = false;
  static unsigned long lastToggle = 0;

  unsigned long now = millis();
  if (now - lastToggle >= 1000 / (dutyCycleLed1 * 2)) {  // Adjust for duty cycle
    lastToggle = now;
    led1State = !led1State;
    digitalWrite(ledPin1, led1State);
  }
}

kirjoita tai liitä koodia tähän

Some sensors I received and tested, sorry its still in finnish

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.