Ergebnis 1 bis 6 von 6

Thema: Lichtsensoren Auswerten

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    26.05.2012
    Beiträge
    15

    Frage Lichtsensoren Auswerten

    Hallo zusammen ,
    nachdem ich meinen RP6 mit einem Roboterarm ausgerüstet habe möchte ich nun eine automatische Beleuchtung anbringen
    starke LEDs hab ich schon , Ich möchte das Programm so schreiben , dass wenn die Lichtsensoren des RP6 eine Lichtstärke messen die eine Bestimmte Helligkeit unterschreitet der RP6 eine seiner LEDs anschaltet und somit auch den dazugehörigen I/O Port an den ich einen Transistor hänge der dann meine LEDs eischaltet

    in etwa so

    if(festgelegter Minimallichtwer)
    {
    setLEDs(0b010000);
    }

    schonmal Danke...

  2. #2
    Hallo,

    die Werte der Lichtsensoren des RP6 fragst Du mit adcLSL und adcLSR ab.
    Jedoch würde ich Dir nicht empfehlen, die Beleuchtung mit nur einem Schwellwert zu steuern:
    Nehmen wir mal an, dass der gemessene Lichtwert ständig um den Schwellwert pendelt. Das würde bedeuten, dass Deine Beleuchtung ständig ein- und ausgeschaltet wird - das sieht ziemlich unprofessionell aus
    Stattdessen solltest Du eine Hysterese (zwei Schwellwerte) einführen. Das bedeutet, dass Du die Lichter einschaltest, wenn ein Schwellwert SCHWELLWERT_AUS unterschritten wird und sie erst wieder einschaltest, wenn Schwellwert
    SCHWELLWERT_EIN überschritten wird, wobei natürlich SCHWELLWERT_EIN>SCHWELLWERT_AUS gilt. SCHWELLWERT_AUS und SCHWELLWERT_EIN musst Du experimentell bestimmen - einfach so, wie es Dir gefällt

    In Pseudocode sieht das so aus:

    Code:
    #define SCHWELLWERT_AUS ...
    #define SCHWELLWERT_EIN ...
    
    ...
    ...
    ...
    
    if(adcLSL<= SCHWELLWERT_AUS){ //Schwellwert für "Licht aus" wurde unterschritten
    setLEDs(...);//Mach die Lichter aus
    }else if(adcLSL >= SCHWELLWERT_EIN){ //Schwellwert für "Licht ein" wurde überschritten
    setLEDs(...);//Schalte sie hier wieder ein
    }
    Grüße,

    Max

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    26.05.2012
    Beiträge
    15
    Danke ,
    ich hab mal etwas einfacher angefangen, aber iregend etwas fonktioniert da nicht richtet

    Mein Programm:


    #include "RP6RobotBaseLib.h"

    int main(void)
    {
    initRobotBase();
    powerON();

    while(true)
    {
    task_RP6System();

    if(adcLSL<= 200)
    {
    setLEDs(0b010000);
    }
    }
    return 0;
    }


    Gruß,
    petzi--

  4. #4
    Hallo,

    also, wenn ich das richtig verstehe hast Du den Transistor, der Deine Beleuchtung ansteuert, direkt an den LED Pin 5 angeschlossen?
    Leuchtet denn die LED 5 am RP6, wenn Du das Programm ausführst und den linken Lichtsensor bedeckst? Lass Dir auch mal die Sensorwerte per RP6Loader ausgeben (WriteInteger und WriteString_P verwenden).
    Vielleicht ist hier auch einfach etwas falsch verschaltet, bitte prüfe das nochmal! Probiere es auch mal mit abgeklemmtem Transistor.
    Und: was genau funktioniert nicht?

    Max

  5. #5
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    50
    Beiträge
    5.492
    Blog-Einträge
    8
    Hallo

    Mal aus der Hüfte geschossen: adcLSL wird durch das Tasksystem mit dem Helligkeitswert geladen:

    Code:
    /**
     * This functions checks all ADC channels sequentially in the Background!
     * It can save a lot of time, if the ADC channels are checked like this, because
     * each A/D conversion takes some time. With this function you don't need to
     * wait until the A/D conversion is finished and you can do other things in the 
     * meanwhile.
     * If you use this function (this is also the case if you use task_RP6System 
     * because it calls this function), you can NOT use readADC anymore!
     *
     * Instead you can use the seven global variables you see above to
     * get the ADC values!
     */
    void task_ADC(void)
    {
    	static uint8_t current_adc_channel = 0;
    	if(!(ADCSRA & (1<<ADSC))) {
    	//	ADCSRA |= (1<<ADIF);
    		switch(current_adc_channel) {
    			case 0: adcBat = ADC; startADC(ADC_MCURRENT_L); break;
    			case 1: adcMotorCurrentLeft = ADC; startADC(ADC_MCURRENT_R); break;
    			case 2: adcMotorCurrentRight = ADC; startADC(ADC_LS_L); break;
    			case 3: adcLSL = ADC; startADC(ADC_LS_R); break;
    			case 4: adcLSR = ADC; startADC(ADC_ADC0); break;
    			case 5: adc0 = ADC; startADC(ADC_ADC1); break;
    			case 6: adc1 = ADC; startADC(ADC_BAT); break;
    		}
    		if(current_adc_channel == 6)
    			current_adc_channel = 0;
    		else
    			current_adc_channel++;
    	}
    }
    Wenn du das Tasksystem vorerst nicht verwenden möchtest, dann kannst du die Werte auch mit readADC() ermitteln:

    Code:
    /*****************************************************************************/
    // ADC:
    
    /**
     * Read ADC channel (10 bit -> result is an integer from 0 to 1023).
     * The channels (ADC_BAT etc.) are defined in the RP6RobotBase.h file!
     *
     * This is a blocking function, which means it waits until the conversion
     * is complete. There is a more complicated alternative that frequently 
     * checks all channels (s. below).
     *
     * This function returns 0 if the ADC is buisy! This has been done to
     * prevents problems when the automatical function is used.
     * You should usually NOT use this function if you use the automatic one!
     *
     * Example:
     *
     *			uint16_t uBat = readADC(ADC_BAT);
     *			if(uBat < 600)
     *				writeString("WARNING: BAT IS LOW!\n");
     *
     */
    uint16_t readADC(uint8_t channel)
    {
    	if((ADCSRA & (1<<ADSC))) return 0; // check if ADC is buisy...
    	ADMUX = (1<<REFS0) | (0<<REFS1) | (channel<<MUX0);
    	ADCSRA = (0<<ADIE) | (1<<ADSC) | (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADIF);
    	while ((ADCSRA & (1<<ADSC))); 
    	ADCSRA |= (1<<ADIF);
    	return ADC;
    }
    (Beide Funktionen sind aus RP6RobotBaseLib.c)

    Die Kanäle werden in RP6RobotBase.h definiert:
    Code:
    #define ADC_BAT 			7
    #define ADC_MCURRENT_L 		6
    #define ADC_MCURRENT_R 		5
    #define ADC_LS_L 			3
    #define ADC_LS_R 			2
    #define ADC_ADC1 			1
    #define ADC_ADC0 			0

    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    26.05.2012
    Beiträge
    15
    Danke für die vielen Antworten ,
    Ich hab das Problem jetzt so gelöst:


    #include "RP6RobotBaseLib.h"

    int main(void)
    {
    initRobotBase();
    powerON();

    while(true)
    {
    task_RP6System();

    if(adcLSL>=520)
    {
    setLEDs(0b000000);
    }

    else
    {
    setLEDs(0b000100);
    }
    }

    return 0;
    }

    Gruß,
    petzi--

Ähnliche Themen

  1. noch 2 Lichtsensoren
    Von TrainMen im Forum Robby RP6
    Antworten: 8
    Letzter Beitrag: 16.08.2009, 08:25
  2. ACS mit Lichtsensoren
    Von RobotMichi im Forum Robby RP6
    Antworten: 4
    Letzter Beitrag: 19.07.2009, 17:15
  3. lichtsensoren an einem asuro
    Von smile5000 im Forum Sensoren / Sensorik
    Antworten: 1
    Letzter Beitrag: 08.12.2008, 16:45
  4. Lichtsensoren optimieren
    Von PhoenixPFA im Forum Sensoren / Sensorik
    Antworten: 1
    Letzter Beitrag: 24.05.2007, 20:26
  5. Lichtsensoren aber welche?
    Von garbage im Forum Sensoren / Sensorik
    Antworten: 6
    Letzter Beitrag: 16.01.2006, 16:47

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •