Senzor farieb TCS230
Zo stránky 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.
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.
Schéma zapojenia LCD displeja.
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.
Video:
Kľúčové slová 'Category', ktoré sú na konci stránky nemeňte.