Problem mit TCS230 und Servo Ansteuerung

Hallo

Ich möchte mit einem Farnsensor TCS230/3200 einen Servo ansteuern, welcher mir die gelesene Farbe auf einer Scheibe anzeigen kann. Leider funktioniert der Servo nur im oberen Void Setup Teil. Dort kann ich die Startposition des Servos bestimmen, was problemlos geht. Im Loop Teil reagiert dann der Servo nicht mehr auf die Programmbefehle.

Ich habe hier im Forum einige Hinweise über solche Probleme gelesen. Leider hat mir das nicht weiter geholfen. Da angeblich libraries von der Servo und dem TCS 230 einen Timer1 Konflikt haben, habe ich versucht den Timer2 für den TCS zu initialisieren. Hat auch nicht funktioniert. :frowning:

Was funktioniert ist nur die Anzeige der LED, welche mir die Farbe rot oder grün bestätigt.

Den Code abgeschaut habe ich hier:

Kann mir jemand mit seinem Wissen weiter helfen? Danke!

Hier der Code:

// Libraries einbinden
#include <Servo.h>
#include <FreqCount.h>
#include <MD_TCS230.h>
#include <Wire.h>

#define S2_OUT 12
#define S3_OUT 13
#define OE_OUT 8 // LOW = ENABLED
// Out auf Pin 5 und VCC auf 5V

// Servo-Positionen in Grad für Farben,
const int redPos = 160;
const int orangePos = 130;
const int yellowPos = 100;
const int greenPos = 70;
const int bluePos = 30;
const int nonePos = 0; // Kein Objekt erkannt

// Servo-Objekt initialisieren
Servo myservo;

// Color Sensor-Objekt initialisieren
MD_TCS230 CS(S2_OUT, S3_OUT, OE_OUT);

/////////////////////////////////////////////////////////////////////////////////////

// setup() wird einmal beim Start des Arduino ausgeführt
void setup() {

Serial.begin(57600);
CS.begin();

//Der Servo hängt am PWM-Pin 3
myservo.attach(9);

//Servo in Grundstellung fahren
myservo.write(0);
delay(1000);

//LED
pinMode(2, OUTPUT);
digitalWrite(2, LOW);
pinMode(6, OUTPUT);
digitalWrite(6, LOW);
}
//////////////////////////////////////////////////////////////////////////////////////
void TCS ()
{
timer2_init();
}

void timer2_init(void)
{
TCCR2A = 0x00;
TCCR2B = 0x07; //the clock frequency source 1024 points
TCNT2 = 100; //10 ms overflow again
TIMSK2 = 0x01; //allow interrupt
}

///////////////////////////////////////////////////////////////////////////////////////

void readsensor()
{
static bool waiting;

if (!waiting)
{
CS.read();
waiting = true;
}
else
{
if (CS.available())
{
colorData rgb;

CS.getRGB(&rgb);
Serial.print(“RGB [”);
Serial.print(rgb.value[TCS230_RGB_R]);
Serial.print(",");
Serial.print(rgb.value[TCS230_RGB_G]);
Serial.print(",");
Serial.print(rgb.value[TCS230_RGB_B]);
Serial.println("]");

waiting = false;
}
}
}

///////////////////////////////////////////////////////////////////////////////////

void loop() {
// put your main code here, to run repeatedly:

readsensor ();

colorData rgb;
CS.getRGB(&rgb);

int r = rgb.value[TCS230_RGB_R];
int g = rgb.value[TCS230_RGB_G];
int b = rgb.value[TCS230_RGB_B];

// Versuch der Farbfeststellung anhand der r,g,b-Werte.
if ((r > 78) && (g < 50) && (b < 68)) {
Serial.print("\tROT");
myservo.write(redPos);
digitalWrite(2, HIGH);
}
else if ((r < 77) && (g > 54) && (b < 82)) {
Serial.print("\tGRUEN");
myservo.write(greenPos);
digitalWrite(6, HIGH);
}
else if ((r < 84) && (g < 63) && (b > 90)) {
Serial.print("\tBLAU");
myservo.write(bluePos);

}
// Zeilenwechsel ausgeben
Serial.println("");

// Wartezeit anpassen für serielles Debugging (Geschwindigkeit beim Lesen der Farbe)
delay(200);

//LED Zurücksetzen
digitalWrite(2, LOW);
digitalWrite(6, LOW);
}

Farbsensor_mit_Servo_Original.ino (2.78 KB)

Friba: Ich möchte mit einem Farnsensor TCS230/3200 einen Servo ansteuern, welcher mir die gelesene Farbe auf einer Scheibe anzeigen kann.

Farnsensor, ja? Und Farn ist grün, oder was?

Wenn irgendwas nicht funktioniert, warum hast Du keine Debug-Ausgaben auf Serial im Programm, z.B. warum gibst Du die Farben nicht auf Serial aus:

int r = rgb.value[TCS230_RGB_R]; int g = rgb.value[TCS230_RGB_G]; int b = rgb.value[TCS230_RGB_B];

Und überhaupt, wie schnell ändert sich die Farbe? Stellt Dir da hunderte male pro Sekunde jemand einen Farn hin und nimmt ihn wieder weg?

Ich sehe nirgendwo einen Taktgeber, der z.B. einmal pro Sekunde eine Farbmessung macht, wenn der Sensor schnell genug ist, könntest Du mit Deinem Code hunderte male pro Sekunde die Farbe messen und genau so oft die Servo Position setzen.

Vorschlag: Debugge die Fehlfunktionen, z.B. indem Du Dir die Messwerte auf Serial anzeigen läßt und reduziere die Messrate auf eine vernünftige Taktung, z.B. eine Messung pro Sekunde und bei schnellem Farbwechsel vielleicht 10 Messungen pro Sekunde!

Soll die "Farnerkennung" vielleicht für einen Pflanzroboter sein? Der NDR hat zur Zeit noch diese Reportage über die größte Gärtnerei Europas in der Mediathek, ab ca. 03:40min wird dort für ca. 2 Minuten der neueste Pflanzroboter der Firma vorgestellt, der schafft angeblich 15000 Töpfe pro Stunde: http://www.ndr.de/fernsehen/epg/import/Wie-geht-Europas-groesste-Gaertnerei,sendung494828.html

Hallo

Danke für Deinen Vorschlag.

Mit delay(xxx) am Ende des Codes kann ich die Geschwindigkeit der Farbmessung einstellen. Jetzt macht es pro Sekunde eine Messung, welche auf dem Seriellen Monitor ausgegeben wird. Neben den RGB Daten schreibt es auch welche Farbe gemessen wurde. Es leuchtet auch die entsprechende LED in rot oder grün auf. Also Farbe erkennen und ausgeben funktioniert. Nur der Servo macht nachdem er auf die 0 Positon gefahren ist nichts mehr.

Wenn ich den Programmteil des TCS’s deaktiviere reagiert der Servo auch im Loop auf Programmbefehle.

Ich habe ein Stück Farn über den Sensor gelegt. Ist tatsächlich als grün im Serial Monitor ausgegeben worden :wink:

Das ist mein erster Versuch mit Arduino was zu machen.

Hast Du mir noch einen weiteren Vorschlag?
Wie kann ich einen Servo ohne <Servo.h> ansteuern?

Friba: Mit delay(xxx) am Ende des Codes kann ich die Geschwindigkeit der Farbmessung einstellen. Jetzt macht es pro Sekunde eine Messung

Das mit einer Messung pro Sekunde kann ich auch nach nochmaliger Durchsicht des Codes nicht sehen. Was ich erst jetzt gesehen habe, ist das delay() in der loop Funktion:

delay(200);

Die 200 ms delay in der loop bremsen Deine loop-Funktion durch Blockierung des Sketches auf maximal 5 pro Sekunde aus.

Nicht schön, sondern unschön, aber solange Du sonst nichts anderes gleichzeitig machen brauchst, kann man natürlich auch den Sketch mit delay blockieren und ausbremsen, bis die Messrate da ist wo Du sie haben möchtest.

Ja das ist nicht schön mit dem delay (200) in der loop-Funktion. Das habe ich aus dem Beispiel Code übernommen. Aber darum kümmere ich mich nachdem sich der Servo endlich mal wie gewünscht bewegt.