پروژه های AVR, پروژه‌ها

پروژه راه اندازی سنسور تشخیص رنگ TCS34725 با استفاده از مجموعه آموزشی AVR WIZARD به زبان C

فهرست مطالب

هدف از این آموزش راه‌اندازی واحد I2C با سنسور تشخیص رنگ TCS34725 ، به زبان برنامه نویسی C  توسط مجموعه آموزشی AVR WIZARD میباشد.

 

قطعات مورد نیاز:

سنسور تشخیص رنگ

 سنسور TCS34725 یک سنسور رنگ دیجیتالی است که با استفاده از پردازنده‌ای مانند Arduino می‌توان مقادیر RGB رنگ یک شی یا نور را بدست آورد.


TCS34725 با استفاده از روش دیجیتال اندازه‌گیری رنگ ، مقادیر RGB و  Clear )کل اندازه‌گیری فیلتر نشده) را انجام می‌دهد. ارتباط با سنسور توسط I2C انجام می‌شود.این سنسور فیلتر مادون قرمز را شامل می‌شود ، که دقت آن را در محیط های نویزی بهبود می‌بخشد. زمان و gain  اندازه‌گیری قابل تنظیم است.

TCS34725 دارای حساسیت گسترده و دامنه پویای گسترده ای از 3،800،000: 1 است که حتی در یک لیوان تاریک قادر به کار است.هنگامی که سطح نور خارج از محدوده آستانه باشد ، TCS34725 باعث ایجاد وقفه‌ای می‌شود که تا زمان تنظیم مجدد توسط کنترلر فعال شود.بر خلاف سنسورهای رنگی دیگر مانند TCS3200 ، که تنها قادر به تشخیص رنگ‌های اصلی هستند ، TCS34725 قادر است اندازه‌گیری نسبتاً دقیقی از RGB رنگ اندازه‌گیری شده را ارائه دهد.

البته، مانند هر سنسور، TCS34725 بی نقص نبوده و دارای انحراف استاندارد است، بنابراین شما یک اندازه‌‍گیری کاملاً دقیق دریافت نخواهید کرد. به طور کلی لازم است که این سنسور را کالیبره کنید.

شکل 1. سنسور TCS34725

TCS34725 دارای حساسیت بالا ، دامنه پویای گسترده‌ای است ، و شامل یک فیلتر مسدود کننده IR است که آن را به یک راه حل سنجش رنگ ایده‌آل برای استفاده در شرایط روشنایی متنوع تبدیل می‌کند. این سنسور همچنین شامل چهار LED فوق العاده روشن است که به سنسور اجازه می‌دهد بدون منابع نوری خارجی کار کند.

 
شکل 2. عملکرد TCS34725

نحوه عملکرد TCS34725

 TCS34725 یک سنسور نوری است که شامل یک آرایه نوری 3 بعدی 3X4 ، به همراه 4 مبدل آنالوگ دیجیتال 16 بیتی ADC است که فوتو‌دیود را اندازه‌گیری می‌کند.

 
شکل 3. بلوک داخلی TCS34725

ماتریس 3X4 متشکل از فوتو‌دیود‌های فیلتر شده برای قرمز ، سبز ، آبی و فاقد فیلتر (واضح) است، که همه سنسورها برای مادون قرمز فیلتر می‌شوند.

شکل 5. نمودار TCS34725

مبدل‌های ADC اندازه‌گیری فوتو‌دیود را که به نمونه‌های داخلی TCS347 منتقل می‌شود را، که شامل یک بافر دوتایی برای اطمینان از ‌یکپارچگی داده‌ها هستند ، ادغام می‌کنند.

 
شکل 6. TCS34725

پین‌های ماژول TCS34725

 اتصال ماژول‌های TCS34725 ساده است، زیرا ارتباطات از طریق I2C انجام می‌شود. ولتاژ تأمین TCS34725 برابر با 3.3 ولت است ، اما به طور معمول ماژول‌ها یک خروجی Vin را در اختیار شما قرار می‌دهد که به 5 ولت متصل شود.


پین LED روشنایی چراغ خنثی LED را که در ماژول یکپارچه است کنترل می‌کند. اتصال این پین می‌تواند به شرح زیر باشد:

  1. بدون اتصال به آن ادامه دهید تا به طور مداوم ادامه یابد.
  2. برای خاموش کردن مداوم به GND وصل شوید.

 
شکل 7. پین های TCS34725

برنامه‌نویسی

هدر فایل TCS34725

				
					#ifndef TCS_h
#define TCS_h
#include "Twi.h"
#define TCS34725_ADDRESS     0x29
#define SLAVE_ADDRESS_WRITE    0|(TCS34725_ADDRESS<< 1)
#define SLAVE_ADDRESS_READ     1|(TCS34725_ADDRESS<< 1)                
#define TCS34725_COMMAND_BIT (0x80) /**< Command bit **/
#define TCS34725_ENABLE (0x00)      /**< Interrupt Enable register */
#define TCS34725_ENABLE_AIEN (0x10) /**< RGBC Interrupt Enable */
#define TCS34725_ENABLE_WEN                                                    \
  (0x08) /**< Wait Enable - Writing 1 activates the wait timer */
#define TCS34725_ENABLE_AEN                                                    \
  (0x02) /**< RGBC Enable - Writing 1 actives the ADC, 0 disables it */
#define TCS34725_ENABLE_PON                                                    \
  (0x01) /**< Power on - Writing 1 activates the internal oscillator, 0        \
            disables it */
#define TCS34725_ATIME (0x01) /**< Integration time */
#define TCS34725_WTIME                                                         \
  (0x03) /**< Wait time (if TCS34725_ENABLE_WEN is asserted) */
#define TCS34725_WTIME_2_4MS (0xFF) /**< WLONG0 = 2.4ms   WLONG1 = 0.029s */
#define TCS34725_WTIME_204MS (0xAB) /**< WLONG0 = 204ms   WLONG1 = 2.45s  */
#define TCS34725_WTIME_614MS (0x00) /**< WLONG0 = 614ms   WLONG1 = 7.4s   */
#define TCS34725_AILTL                                                         \
  (0x04) /**< Clear channel lower interrupt threshold (lower byte) */
#define TCS34725_AILTH                                                         \
  (0x05) /**< Clear channel lower interrupt threshold (higher byte) */
#define TCS34725_AIHTL                                                         \
  (0x06) /**< Clear channel upper interrupt threshold (lower byte) */
#define TCS34725_AIHTH                                                         \
  (0x07) /**< Clear channel upper interrupt threshold (higher byte) */
#define TCS34725_PERS                                                          \
  (0x0C) /**< Persistence register - basic SW filtering mechanism for          \
            interrupts */
#define TCS34725_PERS_NONE                                                     \
  (0b0000) /**< Every RGBC cycle generates an interrupt */
#define TCS34725_PERS_1_CYCLE                                                  \
  (0b0001) /**< 1 clean channel value outside threshold range generates an     \
              interrupt */
#define TCS34725_PERS_2_CYCLE                                                  \
  (0b0010) /**< 2 clean channel values outside threshold range generates an    \
              interrupt */
#define TCS34725_PERS_3_CYCLE                                                  \
  (0b0011) /**< 3 clean channel values outside threshold range generates an    \
              interrupt */
#define TCS34725_PERS_5_CYCLE                                                  \
  (0b0100) /**< 5 clean channel values outside threshold range generates an    \
              interrupt */
#define TCS34725_PERS_10_CYCLE                                                 \
  (0b0101) /**< 10 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_15_CYCLE                                                 \
  (0b0110) /**< 15 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_20_CYCLE                                                 \
  (0b0111) /**< 20 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_25_CYCLE                                                 \
  (0b1000) /**< 25 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_30_CYCLE                                                 \
  (0b1001) /**< 30 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_35_CYCLE                                                 \
  (0b1010) /**< 35 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_40_CYCLE                                                 \
  (0b1011) /**< 40 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_45_CYCLE                                                 \
  (0b1100) /**< 45 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_50_CYCLE                                                 \
  (0b1101) /**< 50 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_55_CYCLE                                                 \
  (0b1110) /**< 55 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_PERS_60_CYCLE                                                 \
  (0b1111) /**< 60 clean channel values outside threshold range generates an   \
              interrupt*/
#define TCS34725_CONFIG (0x0D) /**< Configuration **/
#define TCS34725_CONFIG_WLONG                                                  \
  (0x02) /**< Choose between short and long (12x) wait times via               \
            TCS34725_WTIME */
#define TCS34725_CONTROL (0x0F) /**< Set the gain level for the sensor */
#define TCS34725_ID                                                            \
  (0x12) /**< 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 */
#define TCS34725_STATUS (0x13)      /**< Device status **/
#define TCS34725_STATUS_AINT (0x10) /**< RGBC Clean channel interrupt */
#define TCS34725_STATUS_AVALID                                                 \
  (0x01) /**< Indicates that the RGBC channels have completed an integration cycle */
#define TCS34725_CDATAL (0x14) /**< Clear channel data low byte */
#define TCS34725_CDATAH (0x15) /**< Clear channel data high byte */
#define TCS34725_RDATAL (0x16) /**< Red channel data low byte */
#define TCS34725_RDATAH (0x17) /**< Red channel data high byte */
#define TCS34725_GDATAL (0x18) /**< Green channel data low byte */
#define TCS34725_GDATAH (0x19) /**< Green channel data high byte */
#define TCS34725_BDATAL (0x1A) /**< Blue channel data low byte */
#define TCS34725_BDATAH (0x1B) /**< Blue channel data high byte */
#define uint32_t  unsigned long int
#define uint16_t  unsigned int
typedef enum {
  TCS34725_INTEGRATIONTIME_2_4MS =
      0xFF, /**<  2.4ms - 1 cycle    - Max Count: 1024  */
  TCS34725_INTEGRATIONTIME_24MS =
      0xF6, /**<  24ms  - 10 cycles  - Max Count: 10240 */
  TCS34725_INTEGRATIONTIME_50MS =
      0xEB, /**<  50ms  - 20 cycles  - Max Count: 20480 */
  TCS34725_INTEGRATIONTIME_101MS =
      0xD5, /**<  101ms - 42 cycles  - Max Count: 43008 */
  TCS34725_INTEGRATIONTIME_154MS =
      0xC0, /**<  154ms - 64 cycles  - Max Count: 65535 */
  TCS34725_INTEGRATIONTIME_700MS =
      0x00 /**<  700ms - 256 cycles - Max Count: 65535 */
} tcs34725IntegrationTime_t;

tcs34725IntegrationTime_t _TCS34725_IntegrationTime = TCS34725_INTEGRATIONTIME_700MS;

typedef enum {
  TCS34725_GAIN_1X = 0x00,  /**<  No gain  */
  TCS34725_GAIN_4X = 0x01,  /**<  4x gain  */
  TCS34725_GAIN_16X = 0x02, /**<  16x gain */
  TCS34725_GAIN_60X = 0x03  /**<  60x gain */
} tcs34725Gain_t;

void Tcs34725_WriteData(uint8_t RegisterName,uint8_t value)
{
  Twi_Start();   
  Twi_Send(SLAVE_ADDRESS_WRITE);   
  Twi_Send(RegisterName|TCS34725_COMMAND_BIT);    
  Twi_Send(value);
}

uint8_t Tcs34725_ReadData(uint8_t RegisterName)
{
  Twi_Start();   
  Twi_Send(SLAVE_ADDRESS_WRITE);   
  Twi_Send(RegisterName|TCS34725_COMMAND_BIT);    
  Twi_Start();
  Twi_Send(SLAVE_ADDRESS_READ);  
  return Twi_Read(NACK); 
}


void TCS34725_SetIntegrationTime(tcs34725IntegrationTime_t it)
{
   _TCS34725_IntegrationTime=it;     
   Tcs34725_WriteData(TCS34725_ATIME,it);
}
void TCS34725_SetGain(tcs34725Gain_t gain)
{
    Tcs34725_WriteData(TCS34725_CONTROL,gain);
}

void TCS34725_Enable()
 {   
  Tcs34725_WriteData(TCS34725_ENABLE,TCS34725_ENABLE_PON);
  delay_ms(3);   
  Tcs34725_WriteData(TCS34725_ENABLE,TCS34725_ENABLE_PON | TCS34725_ENABLE_AEN);
  /* Set a delay for the integration time.
    This is only necessary in the case where enabling and then
    immediately trying to read values back. This is because setting
    AEN triggers an automatic integration, so if a read RGBC is
    performed too quickly, the data is not yet valid and all 0's are
    returned */
  switch (_TCS34725_IntegrationTime) {
  case TCS34725_INTEGRATIONTIME_2_4MS:
     delay_ms(3);
    break;
  case TCS34725_INTEGRATIONTIME_24MS:
     delay_ms(24);
    break;
  case TCS34725_INTEGRATIONTIME_50MS:
     delay_ms(50);
    break;
  case TCS34725_INTEGRATIONTIME_101MS:
     delay_ms(101);
    break;
  case TCS34725_INTEGRATIONTIME_154MS:
     delay_ms(154);
    break;
  case TCS34725_INTEGRATIONTIME_700MS:
     delay_ms(700);
    break;
  }
}

void Tcs34725_Init(tcs34725IntegrationTime_t time,tcs34725Gain_t gain)
{
  TCS34725_SetIntegrationTime(time) ;
  TCS34725_SetGain(gain) ;
  TCS34725_Enable()    ;
}

uint16_t TCS34725_GetRawRed(void)
{
  uint16_t x;
  uint16_t t;
  t=Tcs34725_ReadData(TCS34725_RDATAL);  
  delay_ms(3); 
  x=Tcs34725_ReadData(TCS34725_RDATAH);
  x <<= 8;
  x |= t;    
  return x;
}
uint16_t TCS34725_GetRawBlue(void)
{
  uint16_t x;
  uint16_t t;
  t=Tcs34725_ReadData(TCS34725_BDATAL);  
  delay_ms(3); 
  x=Tcs34725_ReadData(TCS34725_BDATAH);
  x <<= 8;
  x |= t;    
  return x;
}
uint16_t TCS34725_GetRawGreen(void)
{
  uint16_t x;
  uint16_t t;
  t=Tcs34725_ReadData(TCS34725_GDATAL);  
  delay_ms(3); 
  x=Tcs34725_ReadData(TCS34725_GDATAH);
  x <<= 8;
  x |= t;    
  return x;
}
uint16_t TCS34725_GetRawClear(void)
{
  uint16_t x;
  uint16_t t;
  t=Tcs34725_ReadData(TCS34725_CDATAL);  
  delay_ms(3); 
  x=Tcs34725_ReadData(TCS34725_CDATAH);
  x <<= 8;
  x |= t;    
  return x;
}

void TCS34725_GetRawRGBC(uint16_t *red, uint16_t *green, uint16_t *blue, uint16_t *clear)
{  
        *red=TCS34725_GetRawRed();
        delay_ms(5);   
        *green=TCS34725_GetRawGreen();
;       delay_ms(5);
        *blue=TCS34725_GetRawBlue();
        delay_ms(5);
        *clear=TCS34725_GetRawClear();
        delay_ms(5);
}


#endif

				
			

هدر فایل TWI

				
					
#ifndef TwoWire_h
#define TwoWire_h
#include <mega16a.h>
#define uint8_t     unsigned char
#define ACK     0
#define NACK     1
void Twi_Start(void);
void Twi_Send(uint8_t data)  ;
uint8_t Twi_ReadStatus(void)   ;
void Twi_Stop()  ;
void Twi_Init(void)  ;
uint8_t Twi_Read(uint8_t ack_n)  ;
void Twi_AsSlave(uint8_t slave_a)    ;
void Twi_listen(void)  ;

 void Twi_Start(void)
{
    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
    while ((TWCR & (1<<TWINT))==0);    
    
}

void Twi_Send(uint8_t data)
{
    TWDR=data;
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    while ((TWCR & (1<<TWINT))==0); 
}

uint8_t Twi_ReadStatus(void)
{
    uint8_t i=0;
    i=TWSR & 0XF8;
    return i;
}

void Twi_Stop()
{
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}

void Twi_Init(void)
{
    TWSR=0;
    TWBR=0x48;
    TWCR=0x44;
}
uint8_t Twi_Read(uint8_t ack_n)
{
    if(ack_n==0)
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
    else
    TWCR=(1<<TWINT)|(1<<TWEN);
    while ((TWCR & (1<<TWINT))==0);
    return TWDR;
}

void Twi_AsSlave(uint8_t slave_a)
{
    TWAR=slave_a;
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
}

void Twi_listen(void)
{
  while ((TWCR & (1<<TWINT))==0);
}  

#endif

				
			

در ادامه برنامه به زبان C در تابع MAIN را مشاهده می کنید:

				
					#include <mega16a.h>
#include <alcd.h>
#include <delay.h>
#include <stdlib.h>
#include "TCS34725.h"
#include "Twi.h"

// Declare your global variables here

// Standard Input/Output functions
#include <stdio.h>

void main(void)
{
  uint8_t data_rx    ;    
  uint16_t red, green, blue, clear, colorTemp, lux;                         
  char redbuffer[6],bluebuffer[6],clearbuffer[6],greenbuffer[6];
// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRA=(0<<DDA7) | (0<<DDA6) | (0<<DDA5) | (0<<DDA4) | (0<<DDA3) | (0<<DDA2) | (0<<DDA1) | (0<<DDA0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTA=(0<<PORTA7) | (0<<PORTA6) | (0<<PORTA5) | (0<<PORTA4) | (0<<PORTA3) | (0<<PORTA2) | (0<<PORTA1) | (0<<PORTA0);

// Port B initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (0<<DDB5) | (0<<DDB4) | (0<<DDB3) | (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);

// Port C initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRC=(0<<DDC7) | (0<<DDC6) | (0<<DDC5) | (0<<DDC4) | (0<<DDC3) | (0<<DDC2) | (0<<DDC1) | (0<<DDC0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTC=(0<<PORTC7) | (0<<PORTC6) | (0<<PORTC5) | (0<<PORTC4) | (0<<PORTC3) | (0<<PORTC2) | (0<<PORTC1) | (0<<PORTC0);

// Port D initialization
// Function: Bit7=In Bit6=In Bit5=In Bit4=In Bit3=In Bit2=In Bit1=In Bit0=In 
DDRD=(0<<DDD7) | (0<<DDD6) | (0<<DDD5) | (0<<DDD4) | (0<<DDD3) | (0<<DDD2) | (0<<DDD1) | (0<<DDD0);
// State: Bit7=T Bit6=T Bit5=T Bit4=T Bit3=T Bit2=T Bit1=T Bit0=T 
PORTD=(0<<PORTD7) | (0<<PORTD6) | (0<<PORTD5) | (0<<PORTD4) | (0<<PORTD3) | (0<<PORTD2) | (0<<PORTD1) | (0<<PORTD0);

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x67;

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTB Bit 0
// RD - PORTB Bit 1
// EN - PORTB Bit 2
// D4 - PORTA Bit 4
// D5 - PORTA Bit 5
// D6 - PORTA Bit 6
// D7 - PORTA Bit 7
// Characters/line: 16
lcd_init(16);
lcd_putsf( "   HI Wellcom   " ) ;
lcd_gotoxy( 0 , 1 );
lcd_putsf( "TO REDRONIC.COM" ) ;
delay_ms(2000);
lcd_clear();
Twi_Init() ;
Tcs34725_Init(TCS34725_INTEGRATIONTIME_700MS,TCS34725_GAIN_1X);
while (1)
      {   
        lcd_clear();
        TCS34725_GetRawRGBC(&red, &green, &blue, &clear);       
        itoa (red,redbuffer);  
        itoa (blue,bluebuffer);
        itoa (clear,clearbuffer);
        itoa (green,greenbuffer);
        lcd_gotoxy(0,0);
        lcd_putsf("G:");
        lcd_gotoxy(3,0); 
        lcd_puts(greenbuffer); 
        lcd_gotoxy(9,0);
        lcd_putsf("R:");   
        lcd_gotoxy(11,0);  
        lcd_puts(redbuffer);
        lcd_gotoxy(0,1);
        lcd_putsf("B:");
        lcd_gotoxy(3,1); 
        lcd_puts(bluebuffer); 
        lcd_gotoxy(9,1);  
        lcd_putsf("C");       
        lcd_gotoxy(11,1); 
        lcd_puts(clearbuffer); 
        delay_ms(2000);        
      }
}

				
			

خروجی برنامه

نظرتان را درباره این مقاله بگویید 8 نظر

پروژه راه اندازی سنسور تشخیص رنگ TCS34725 با استفاده از مجموعه آموزشی AVR WIZARD به زبان C

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *