TCS230 Farbsensor - Servo ansteuern

Hallo Leute,
also ersteinmal zu mir ich bin noch Neuling auf dem Gebiet und habe mich nun an eine M&M Sortiermaschine gewagt.
Dazu möchte ich den Farbsensor TCS230 sowie einen Servo verwenden, der je nach Farbe auf eine bestimmte Postion gehen soll.
Den Code zur Farberkennung habe ich schon soweit, dass alle Farben richtig erkannt werden und diese im SerialMonitor ausgegeben werden.
Nun habe ich angefangen den Standard Code, den ich für den Farbsensor bekam so zu modifizieren, dass sich der Servo auf eine Position bewegt.
Zunächst soll er auf Position 0 gehen, das klappt auch schon. Doch anders als bei den einfachen Werten im SerialMonitor macht der Servo gar nichts, wenn ich in den void loop () befehl schreibe, er soll auf 90° gehen.
Ich komme echt nicht weiter hat jemand vielleicht eine Idee wo ich stattdessen im Code den Servo ansprechen soll?

#include <TimerOne.h>
#include <Servo.h>


#define S0     6
#define S1     5
#define S2     4
#define S3     3
#define OUT    2

Servo servo;
int pos = 0;
int   g_count = 0;    // count the frequecy
int   g_array[3];     // store the RGB value
int   g_flag = 0;     // filter of RGB queue
float g_SF[3];        // save the RGB Scale factor
 

 
 
 
// Init TSC230 and setting Frequency.
void TSC_Init()
{
  
  pinMode(S0, OUTPUT);
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(OUT, INPUT);
 

 
 
  digitalWrite(S0, LOW);  // OUTPUT FREQUENCY SCALING 2%
  digitalWrite(S1, HIGH); 
}
 
// Select the filter color 
void TSC_FilterColor(int Level01, int Level02)
{
  if(Level01 != 0)
    Level01 = HIGH;
 
  if(Level02 != 0)
    Level02 = HIGH;
 
  digitalWrite(S2, Level01); 
  digitalWrite(S3, Level02); 
}
 
void TSC_Count()
{
  g_count ++ ;
}
 
void TSC_Callback()
{
  
  switch(g_flag)
  {
    case 0: 
         Serial.println("->WB Start");
         TSC_WB(LOW, LOW);              //Filter without Red
         break;
    case 1:
         Serial.print("->Frequency R=");
         Serial.println(g_count);
         g_array[0] = g_count;
         TSC_WB(HIGH, HIGH);            //Filter without Green
         break;
    case 2:
         Serial.print("->Frequency G=");
         Serial.println(g_count);
         g_array[1] = g_count;
         TSC_WB(LOW, HIGH);             //Filter without Blue
         break;
 
    case 3:
         Serial.print("->Frequency B=");
         Serial.println(g_count);
         Serial.println("->WB End");
         g_array[2] = g_count;
         TSC_WB(HIGH, LOW);             //Clear(no filter)   
         break;
   default:
         g_count = 0;
         break;
  }

  
}
 
void TSC_WB(int Level0, int Level1)      //White Balance
{
  g_count = 0;
  g_flag ++;
  TSC_FilterColor(Level0, Level1);
  Timer1.setPeriod(1000000);             // set 1s period
}
 
void setup()
{
  servo.attach (9);
  servo.write (pos);
  delay (1000);

  TSC_Init();
  Serial.begin(9600);
  Timer1.initialize();             // defaulte is 1s
  Timer1.attachInterrupt(TSC_Callback);  
  attachInterrupt(0, TSC_Count, RISING);  
 
  delay(4000);
 
  for(int i=0; i<3; i++)
    Serial.println(g_array[i]);
 
  g_SF[0] = 255.0/ g_array[0];     //R Scale factor
  g_SF[1] = 255.0/ g_array[1] ;    //G Scale factor
  g_SF[2] = 255.0/ g_array[2] ;    //B Scale factor
 
  Serial.println(g_SF[0]);
  Serial.println(g_SF[1]);
  Serial.println(g_SF[2]);

 
}

void loop()
{
   g_flag = 0;
   for(int i=0; i<3; i++)   
   if (g_array[0] < 1000)
   {
     servo.write(pos);
     delay (4000);
   }
   else {
     delay (4000);
   }
}

Ich hoffe ihr könnt mir weiterhelfen.
Schöne Grüße, Flo

flolol175:
wenn ich in den void loop () befehl schreibe, er soll auf 90° gehen.

Das machst Du doch nirgends!

Du initialisierst im Programm pos auf 0 und zur Ansteuerung gibt es nur:
servo.write(pos);

Die Variable pos bekommt nirgendwo einen anderen Wert zugewiesen, wieso sollte der Servo dann eine andere Position als 0 anfahren?

Hi Jurs, Danke für die schnelle antwort. Ich hatte es bis jetzt immer so getestet, dass ich nachdem void setup ausgeführt wurde den servo ein stückchen verdreht habe um dann zu schauen ob er wie im void loop befehl gesagt wieder auf pos 0 geht, das tat er aber nicht. Selbst wenn man einen anderen Wert an dieser Stelle einsetzt nimmt der Servo diesen scheinbar nicht an. --> Problem besteht weiterhin

Achja, das merkwürdige ist, dass wenn ich statt einem servo einfach eine LED ansteuere funktioniert alles bestens. Also, dass diese leuchtet wenn ein bestimmter Farbwert erreicht ist. Kann es sein, dass ich die Befehle für den Servo an die falschen Stellen schreibe?

Gruß, Flo

void loop()
{
   g_flag = 0;
   for(int i=0; i<3; i++)   
   if (g_array[0] < 1000)
   {
     servo.write(pos);
     delay (4000);
   }
   else {
     delay (4000);
   }
}

Hier steckt der Teufel im Detail. wofür wird die for-Schleife benötigt? Diese führt keine Aktion aus. Lediglich i++. Was ist, wenn du statt dessen schreibst

void loop()
{
     servo.write(pos);
}
[code]

[/code]

flolol175:
→ Problem besteht weiterhin

OK, dann dazu:
#include <TimerOne.h>
#include <Servo.h>

Welches Arduino-Board verwendest Du?

Dass die Servo-Library bei den meisten Arduino-Boards standardmäßig Timer1 verwendet hast Du berücksichtigt?

Weil wenn Du Timer1 sowohl mit der Servo-Library als auch mit der TimerOne-Library gleichzeitig doppelt für zwei verschiedene Dinge verwenden möchtest, dann beißt sich der Timer1 natürlich ganz gewaltig in die eigenen Eier.

Hey Danke für die Antworten. Also @sschultewolter du hast recht, die aktion ist überflüssig. Stammt aus der ursprünglichen Funktion habe ich vergessen zu löschen. Deine Idee hatte ich auch allerdings mit dem gleichen Ergebnis wie oben --> der Servo bewegt sich kein Stück.

@ jurs das ist ein interessanter Gedanke. Also erstmal ich benutze das Arduino UNO und musste für den Farbsensor erstmal ein neues Verzeichnis für diesen in die Libary laden. Der Sensor verwendet ebenfalls Timer1. Wie gesagt ich bin noch Neuling aber wenn ich dich richtig verstehe kann es logischerweise so nicht funktionieren ( "Timer1 natürlich ganz gewaltig in die eigenen Eier" - ich lach mich kaputt, super formuliert :D :D )

Ähm gibt es da denn ne möglichkeit das zu ändern? Kann ich in den Libary Verzeichnissen einfach Timer1 ändern?

Danke für die Hilfe :) Viele Grüße,Flo

Wenn du einfach jede Sekunde was ausführen willst brauchst du keinen extra Timer: http://arduino.cc/en/Tutorial/BlinkWithoutDelay

Außerdem solltest du Variablen die in Interrupts verwendet werden als "volatile" deklarieren.

flolol175: Ähm gibt es da denn ne möglichkeit das zu ändern? Kann ich in den Libary Verzeichnissen einfach Timer1 ändern?

Um eine Funktion einmal pro Sekunde laufen zu lassen braucht es keinen Timer, sondern eine kleine selbstgeschriebene Funktion.

Und um einen Servo anzusteuern braucht es keine Servo-Library und damit auch keinen Timer.

Außerdem kannst Du in der Servo-Library (ich glaube in der Header-Datei) eine bedingte Compilierung ändern, so dass ein anderer Timer als Timer1 für die Servosteuerung verwendet werden kann. Wenn es denn unbedingt kompliziert, mit Servo-Library und Timer-Verwendung sein muß.

Du kannst Dir alles aussuchen, was Du machst. Aber Du darfst knappe und nur ein einziges mal vorhandene Hardware nicht versuchen doppelt für verschiedene Dinge zu benutzen, so wie Du es mit Timer1 bisher versuchst.

Hallo Leute, Vielen Lieben Dank für die Tolle Hilfe! Wär ich niemals drauf gekommen, dass sich TimerOne und die Servo Libary in die Quere kommen. Habe jetz den Code so umgeschrieben, dass die Servo Libary nicht benötigt wird. Funktionier alles super!

DANKE!

Schönes Wochenende noch. Gruß, Flo