Operácie

Senzor farieb TCS230

Z SensorWiki

Záverečný projekt predmetu MIPS / LS2023 - Tomáš Bečvarov


Zadanie

Senzor farieb - naprogramujte senzor na rozpoznávanie jednotlivých farieb, zobrazenie na LCD displej.

Chceme dosiahnúť toho, aby sme vedeli rozoznávať rôzne farby za pomocy senzora TCS230.

Vývojová doska ACROB.

Literatúra:


Analýza a opis riešenia

Senzor pracuje na takom princípe, že keď ho zapojíme do vývojovej dosky, tak bude naspäť posielať obdĺžnikový signál, ktorého frekvencia je priamo úmerná intenzite svetla. Senzor má 64 fotodiód, z čoho 16 má červený filter, 16 má zelený filter, 16 ma modrý filter a 16 má čistích, teda bez filtru. Tieto filtre dokážeme nastavovať pomocou pinov S2 a S3 (S2 -> log.0 a S3 -> log.0 = červený filter, atď). Takže nám stačí nastaviť filter na určitú frabu a potom stačí zmerať frekvenciu zo senzora. Na meranie frekvencii sme použili počítadlo 1 (TIMER1), čo je 16 bitové počítadlo, ktorým sme merali čas od dobežnej hrany po nábežnú a keď sme tým podelili polovicu frekvencie kryštálu (polovicu preto, lebo sme merali iba pól periódu, pretože ten signál ma 50% duty), tak dostaneme výslednú frekvenciu pri danom filtri. Potom to už len zobrazíme na LCD displaj.

TCS230 senzor farieb.

Schéma zapojenia LCD displeja.

Schéma zapojenia LCD displeja.

Schéma zapojenia senzora TCS230.

Schéma zapojenia senzora TCS230.

Algoritmus a program

Algoritmus programu je....


#include <avr/io.h>

#include <avr/io.h>
#include <stdio.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include "lcd_ch.h"

#define LCD_CLR 0      // DB0: Vy?istenie displaja
#define LCD_CTRL_PORT DDRD
#define LCD_DATA_PORT DDRB

#define LCD_RS_pin 2	// Zadefinovanie pinov LCD displaja
#define LCD_RW_pin 3
#define LCD_EN_pin 4

#define LCD_D4_pin 1
#define LCD_D5_pin 2
#define LCD_D6_pin 3
#define LCD_D7_pin 4

#define S0_PIN  PD5		// Zadefinovanie pinov sníma?a
#define S1_PIN  PD6
#define S2_PIN  PD7
#define S3_PIN  PB0
#define OUT_PIN  PB5

void setup() 
{
    //LCD:
	DDRD |= (1<<LCD_EN_pin);	// Pin D4 (Enable)  PORTD  výstup  
	DDRD |= (1<<LCD_RW_pin);	// Pin D3 (RW)      PORTD  výstup  
	DDRD |= (1<<LCD_RS_pin);	// Pin D2 (RS)      PORTD  výstup  
	
	LCD_DATA_PORT |= (1<<LCD_D4_pin)|(1<<LCD_D5_pin)|(1<<LCD_D6_pin)|(1<<LCD_D7_pin);	// Piny 1,2,3,4, PORTB ako výstupy (Dáta pre display)
	
	//Snimac:
	DDRD |= (1 << S0_PIN) | (1 << S1_PIN) | (1 << S2_PIN);   // Nastavenie pinov S0, S1 a S2 ako výstupy
	DDRB |= (1 << S3_PIN);		// Nastavenie S3 ako výstup
    DDRB &= ~(1 << OUT_PIN);	// Nastavenie pinu OUT ako vstup

    // Nastavenie frekven?nej škály na 2%
    PORTD &= ~(1 << S0_PIN);   // S0: 0
    PORTD |= (1 << S1_PIN);    // S1: 1
}

uint16_t TCSMeasure()
{
   if(!(PINB & (1 << OUT_PIN)))		// 
   {
      while(!(PINB & (1 << OUT_PIN)));   //?akanie na nábežnú hranu  
   }

   while(PINB & (1 << OUT_PIN));   //?akanie na dobežnú hranu

   TCNT1=0x0000;	//Resetovanie po?ítadla

   TCCR1B=(1<<CS10);	//Nastavenie predeli?ky = F_CPU/1 (za?iatok po?ítania)

   while(!(PINB & (1 << OUT_PIN)));   //?akanie na nábežnú hranu

   TCCR1B=0x00;		//Zastavenie po?ítadla

   return ((float)8000000UL/TCNT1);

}

long map(long x, long in_min, long in_max, long out_min, long out_max)		//Funkcia map na kalibráciu sníma?a
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;		//(premenná, najmenšia daná hodnota, najvä?šia daná hodnota, najmenšia požadovaná hodnota, najvä?šia požadovaná hodnota)
}


int main(void) 
{  
	setup();	// iniciácia nastavenia vstupov
	
	lcd_init();  // iniciácia LCD

	void lcd_puts(const char *s)	// funkcia na použivanie puts
	{
		register unsigned char c;
		while((c = *s++))
			lcd_data(c);
	}	

	char vysledokR[  ]={  };	// nastavenie premenných na zapisovanie hodnôt
	char vysledokG[  ]={  };
	char vysledokB[  ]={  };
		
    while(1)
	{
		lcd_command(1 <<  LCD_CLR);		// vy?istenie displaja
		lcd_command(0b00001100);	//odstranenie kurzora
		lcd_command(0x80);		// nastavenie na prvý riadok
		lcd_puts("Namerana farba:");	//Napiseme do prveho riadku
		
		PORTD &= ~(1 << S2_PIN);	//Nastavenie ?erveného filtra
		PORTB &= ~(1 << S3_PIN);

		unsigned int hodnotaR = TCSMeasure();	//Uloženie nameranej hodnoty pre ?ervený filter
		hodnotaR = map(hodnotaR,433,2195,0,255);	//upravenie na požadované hodnoty
		
		lcd_command(0xC0);		// nastavenie na druhý riadok
		lcd_puts("R=");
        sprintf(vysledokR,"%d",hodnotaR);	// prepísanie ?ísla ako charakter
		lcd_puts(vysledokR);		//Vypisanie na LCD displaj
		_delay_ms(10);
		
		PORTD |= (1 << S2_PIN);		//Nastavenie zeleného filtra
		PORTB |= (1 << S3_PIN);
		
		unsigned int hodnotaG = TCSMeasure();	//Uloženie nameranej hodnoty pre zelený filter
		hodnotaG = map(hodnotaG,384,1300,0,255);	//Upravenie na požadované hodnoty
		
		lcd_command(0xC0+5);	// nastavenie na 6tu pozíciu na druhom riadku
		lcd_puts("G=");
		sprintf(vysledokG,"%d",hodnotaG);	// prepísanie ?ísla ako charakter
		lcd_puts(vysledokG);		//Vypisanie na LCD displaji
		_delay_ms(10);
		
		PORTD &= ~(1 << S2_PIN);	//Nastavenie modrého filtra
		PORTB |= (1 << S3_PIN);
		
		unsigned int hodnotaB = TCSMeasure();	//Uloženie nameranej hodnoty pre modrý filter
		hodnotaB = map(hodnotaB,487,2100,0,255);	//Upravenie na požadované hodtoty
		
		lcd_command(0xC0+10);	// Nastavenie na 11tu poziciu na druhom riadku
		lcd_puts("B=");
		sprintf(vysledokB,"%d",hodnotaB);	// prepísanie ?ísla ako charakter
		lcd_puts(vysledokB);	//Vypisanie na LCD dispaji
		_delay_ms(200);

	}     
   
}
#include <avr/io.h>

void adc_init(void);                                   // A/D converter initialization

unsigned int adc_read(char a_pin);

Pridajte sem aj zbalený kompletný projekt, napríklad takto (použite jednoznačné pomenovanie, nemôžeme mať na serveri 10x zdrojaky.zip:

Zdrojový kód: zdrojaky.zip


Overenie

Na používanie našej aplikácie stačia dve tlačítka a postup používania je opísaný v sekcii popis riešenia. Na konci uvádzame fotku záverečnej obrazovky pred resetom. Vypísaný je tu priemerný čas a najlepší čas.

Aplikácia.

Video:

Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.