Probleme mit Servo und MH-Z19

Hallo, ich habe ein Code geschrieben, um einen Servomotor mit dem Eingang eines MH-Z19 CO2 Sensors zu steuern. Jedoch will der Motor sich immer auf 0 grad bewegen, obwohl er bereits auf 0 Grad ist, Hat jemand eine Idee wie ich dies andres verhindere als im Code versucht?

hier der Code

#include <MHZ19.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#include <Arduino.h>

#define RX_PIN 10
#define TX_PIN 11
#define BAUDRATE 9600 // Native to the sensor (do not change)

#include <SoftwareSerial.h> // Remove if using HardwareSerial or non-uno compatible device
SoftwareSerial mySerial(RX_PIN, TX_PIN); // (Uno example) create device to MH-Z19 serial

Servo myServo;
SoftwareSerial co2Serial(10, 11); // RX, TX
MHZ19 myMHZ19;
int servoPosition = 0;

void setup()
{
Serial.begin(9600);
mySerial.begin(BAUDRATE); // Uno example: Begin Stream with MHZ19 baudrate
myMHZ19.begin(mySerial); // *Important, Pass your Stream reference
myServo.attach(8); // Anschließen des Servomotors an Pin 9

}

void loop() {
int CO2 = myMHZ19.getCO2();
Serial.print("CO2: ");
Serial.println(CO2);

Serial.print("Servo Position: ");
Serial.println(servoPosition);

if (CO2 > 1000 && myServo.read() != 180) {
myServo.write(180); // Schreibe den Servomotor auf die Position fĂŒr CO2-Werte ĂŒber 1000 ppm
servoPosition = 180;
delay(1000); // Kurze Verzögerung, um den Servomotor stabilisieren zu lassen
} else if (myServo.read() != 0 && CO2 <= 1000 ) {
myServo.write(0);
servoPosition = 0;
delay(1000); // Kurze Verzögerung, um den Servomotor stabilisieren zu lassen
}

delay(2000); // Messung alle 2 Sekunden wiederholen
}

Hier ist ein Beispiel, wie du einen Servo ansteuern kannst. Weil kein CO Messer vorhanden ist, wird der Wert als Zufallszahl generiert. Es werden vier LuftqualitÀts- Wertebereiche unterschieden (gut, mittel, schlecht und sehr schlecht).

Der Servo wird je nach Wert in 45° Schritten (0°- 45°- 90° -135°) gestellt.

#include <Servo.h>
#include <Streaming.h>
Print &cout {Serial};

enum class Direction : int8_t { up = 1, down = -1 };
enum AirQuality : uint8_t { good, medium, poor, veryPoor };

constexpr uint8_t SERVO_PIN {6};
constexpr int servoPos[] {0, 45, 90, 135};

Servo servo;

int setServo(Servo &sv, uint16_t position, Direction dir) {
  sv.write(position);
  position += static_cast<int>(dir);
  delay(5);
  return position;
}

void showCO(uint16_t coV, Servo &sv) {
  int pos = sv.read();
  int targetPos;

  switch (coV) {
    case 0 ... 799: targetPos = servoPos[AirQuality::good]; break;
    case 800 ... 999: targetPos = servoPos[AirQuality::medium]; break;
    case 1000 ... 1399: targetPos = servoPos[AirQuality::poor]; break;
    default: targetPos = servoPos[AirQuality::veryPoor]; break;
  }
  do { pos = setServo(sv, pos, (pos > targetPos) ? Direction::down : Direction::up); } while (pos != targetPos);

  cout << "CO: " <<_WIDTH(coV,4) << " Pos: " << _WIDTH(pos,3) << endl;
}

void setup() {
  Serial.begin(115200);
  servo.attach(SERVO_PIN);
  servo.write(servoPos[AirQuality::good]);
}

void loop() {
  static uint8_t lastCoValue {0};
  delay(2000);
  uint16_t coValue = random(0, 2000);
  if (coValue != lastCoValue) {
    lastCoValue = coValue;
    showCO(coValue, servo);
  }
}

Wie das ablÀuft kannst Du Dir in folgender Simulation anschauen:

Vielleicht hilft es Dir ja weiter.

1 Like

Das Beispiel schein ihm nicht gefallen zu haben. Jetzt versucht er es nebenan.

Gruß Tommy

Edit: Du hast es schon selbst gesehen.

Moin, danke fĂŒr die Antwort. Es tut mir leid das ich noch nicht drauf reagiert hatte, ich hatte noch nicht wieder die Gelegenheit in ruhe weiter zu arbeiten. Leider muss ich gestehen, dass ich recht neu in dem Bereich bin und weiß nicht wie ich den CO2 Sensor dort mit einbringen kann, so dass der Motor sich auf Grund der CO2 Werte im raum bewegt.
Falls es hilft, ich möchte ein Vogel der bei guter Luft im Zimmer steht und bei schlechter Luft im Zimmer soll dieser runter hĂ€ngen. Dementsprechend 0 Grad und 180 Grad fĂŒr den Motor.
Danke im voraus

Danke fĂŒr die schnelle Antwort und dein VerstĂ€ndnis. Ich weis jedoch leider nicht ganz wie ich in denn Code schreibe das er die CO2 Werte vom Sensor nehmen soll und nicht zufĂ€llig generiert

EDIT:
Ich habe mal mein GlĂŒck probiert:
WÀre es so möglich?

#include <Servo.h>
#include <MHZ19.h>
#include <SoftwareSerial.h> 
#include <Streaming.h>
Print &cout {Serial};

enum class Direction : int8_t { up = 1, down = -1 };
enum AirQuality : uint8_t { good, bad };

constexpr uint8_t SERVO_PIN {6};
constexpr int servoPos[5] {0, 180};

Servo servo;
MHZ19 mhz19;

int setServo(Servo &sv, uint16_t position, Direction dir, uint16_t stepDelay_ms = 5) {
  sv.write(position);
  position += static_cast<int8_t>(dir);
  delay(stepDelay_ms);
  return position;
}

void showCO(uint16_t co2V, Servo &sv) {
  int pos = sv.read();
  int targetPos;

  switch (co2V) {
    case 0 ... 999: targetPos = servoPos[AirQuality::good]; break;
    default: targetPos = servoPos[AirQuality::bad]; break;
  }
  do { pos = setServo(sv, pos, (pos > targetPos) ? Direction::down : Direction::up); } while (pos != targetPos);
  cout << _FMT("CO2: % -> Pos: %", _WIDTH(co2V, 4), _WIDTH(pos, 3)) << "°\n";
}

void setup() {
  Serial.begin(115200);
  cout << "Start" << __FILE__ << endl;
  servo.attach(SERVO_PIN);
  servo.write(servoPos[AirQuality::good]);

  SoftwareSerial mhzSerial(10, 11); 
  mhz19.begin(mhzSerial);
}

void loop() {
  static uint8_t lastCo2Value {0};
  delay(2000);

  int co2Value = mhz19.getCO2();
  
  if (co2Value != lastCo2Value) {
    lastCo2Value = co2Value;
    showCO(co2Value, servo);
  }
}

Du hast den Code doch schon in Deinem Programm. Das jetzt zusammen zu bringen bekommst Du ja wohl selber hin.

Das ist leider Mein erstes Projekt. War dein Code eine ErgÀnzung oder allein stehend?
Tut mir leid, das ich etwas schwer von Begriff bin, was dass angeht.

Wie du siehst arbeitet der Code von mit alleine stehend. Er muss lediglich um den Code fĂŒr den CO2 Messer ergĂ€nzt werden. Also hole alle diese Teile in den Beispielcode.

Ein bisschen musst Du schon selber machen
..

Okay, danke fĂŒr deine Hilfe und nochmals Entschuldigung!

Das SoftwareSerial Objekt muss genau so wie das Servo und mhz19 Objekt global definiert werden. Außerdem fehlt mySerial.begin(BAUDRATE); in setup().

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