阳光下使用颜色传感器

其实是在几周前我就在试验如何在阳光下让颜色传感器工作,一开始想的是通过程序的办法控制~但是在实验中却发现所测得的频率根本就不变,这就导致转换出的三原色的值也不变~~所以在试了无数种程序的方法后,终于发现只从程序入手是行不通的,只有改装~~

于是,我就给传感器假装了一个纸筒~~如图~~像这样弄基本能测出近20cm外的led颜色(当然,纸筒就占了近15cm了~~)~~

9CFAEE0D27859B370F0D574527ABA14F_B500_900_500_380

9CFAEE0D27859B370F0D574527ABA14F_B500_900_500_3809CFAEE0D27859B370F0D574527ABA14F_B500_900_500_380     然后把我的程序代码也贴出来吧~~基于官方的原始代码,改了红光的检测语句,并且删掉了一些没用的代码~~

 

#include  //引用TimerOne.h 库文件
#define S0 6 //定义S0 为引脚6
#define S1 5 //定义S1 为引脚5
#define S2 4 //定义S2 为引脚4
#define S3 3 //定义S3 为引脚3
#define OUT 2 //定义OUT 为引脚2
  
int g_count = 0; // 定义整型变量g_count 并赋初值为0,用于存储计数频率
int g_array[3]; // 定义整型数组变量g_array[3],用于存储RGB 的值
int g_flag = 0; // 定义整形变量g_flag 并赋初值为0,用于过滤器排列
float g_SF[3]; // 定义浮点型数组变量g_SF[3],用于存储RGB 比例因子
int value[3]; // 定义定义整型数组变量value[3],用于判断颜色
// 初始化tsc230 和设置频率
void TSC_Init()
{
  pinMode(S0, OUTPUT); //定义S0 为输出状态
  pinMode(S1, OUTPUT); //定义S1 为输出状态
  pinMode(S2, OUTPUT); //定义S2 为输出状态
  pinMode(S3, OUTPUT); //定义S3 为输出状态
  pinMode(OUT, INPUT); //定义OUT 为输入状态
  digitalWrite(S0, LOW); //定义S0 为低电平
  digitalWrite(S1, HIGH); //定义S1 为高电平
  //输出频率缩放2%
}
// 选择过滤器的颜色
void TSC_FilterColor(int Level01, int Level02)
{
  if(Level01 != 0) //如果Level01 不等于0
      Level01 = HIGH; //则Level01 为高电平
  if(Level02 != 0) //如果Level02 不等于0
      Level02 = HIGH; //则Level02 为高电平
  digitalWrite(S2, Level01); //将Level01 值送给S2
  digitalWrite(S3, Level02); //将Level02 值送给S3
  //选择过滤器颜色
}
void TSC_Count()
{
  g_count ++ ; //自动计算频率
}
void TSC_Callback()
{
  switch(g_flag)
  {
  case 0:
    Serial.println("->WB Start"); //串口打印字符串"->WB Start"
    TSC_WB(LOW, LOW); //没有过滤红色
    break;
  case 1:
    Serial.print("->Frequency R="); //串口打印字符串"->Frequency R="
    Serial.println(g_count); //串口打印g_count 变量值
    g_array[0] = g_count;
    TSC_WB(HIGH, HIGH); //没有过滤绿色
    break;
  case 2:
    Serial.print("->Frequency G="); //串口打印字符串"->Frequency G="
    Serial.println(g_count); //串口打印g_count 变量值
    g_array[1] = g_count;
    TSC_WB(LOW, HIGH); //没有过滤蓝色
    break;
  case 3:
    Serial.print("->Frequency B="); //串口打印字符串"->Frequency B="
    Serial.println(g_count); //串口打印g_count 变量值
    Serial.println("->WB End"); //串口打印字符串"->WB End"
    g_array[2] = g_count;
    TSC_WB(HIGH, LOW); //清除(无过滤)
    break;
  default:
    g_count = 0;
    break;
  }
}
void TSC_WB(int Level0, int Level1) //白平衡
{
  g_count = 0;
  g_flag ++;
  TSC_FilterColor(Level0, Level1);
  Timer1.setPeriod(1000000); //设置一秒周期
}
void setup()
{
  TSC_Init(); //初始化tcs230
  Serial.begin(9600); //打开串口并设置通信波特率为9600
  Timer1.initialize(); //初始化默认是一秒
  Timer1.attachInterrupt(TSC_Callback); //外部中断为一秒
  attachInterrupt(0, TSC_Count, RISING); //外部中断口初始0
  delay(4000); //延迟4 秒
  for(int i=0; i<3; i++)
    Serial.println(g_array[i]); //串口打印g_array[i]变量值
  g_SF[0] = 255.0/ g_array[0]; //红色的比例因子
  g_SF[1] = 255.0/ g_array[1] ; //绿色的比例因子
  g_SF[2] = 255.0/ g_array[2] ; //蓝色的比例因子
  Serial.println(g_SF[0]); //串口打印g_SF[0]变量值
  Serial.println(g_SF[1]); //串口打印g_SF[1]变量值
  Serial.println(g_SF[2]); //串口打印g_SF[2]变量值
}
void loop()
{
  digitalWrite(13,HIGH); 
  
  g_flag = 0;
  for(int i=0; i<3; i++) { Serial.println(int(g_array[i] * g_SF[i])); //串口打印g_array[i] * g_SF[i]变量值 value[i]=int(g_array[i] * g_SF[i]); //将g_array[i] * g_SF[i]值赋值给value[i] } if ((value[0] -value[1]>10) && (value[0] -value[2]>10)) //如果变量value[i]数值满足为红色值范围则执行下面语句
  { 
    Serial.println("->Red"); //串口打印字符串"->Red"
  }
  else if (((value[0]>235) && (value[0]<275)) && ((value[1]>198) && (value[1]<238)) && ((value[2]>96) && (value[2]<136))) //如果变量value[i]数值满足为黄色值范围则执行下面语句 { Serial.println("->Yellow"); //串口打印字符串"->Yellow"
  }
  else if (((value[0]>74) && (value[0]<114)) && ((value[1]>119) && (value[1]<159)) && ((value[2]>76) && (value[2]<116))) //如果变量value[i]数值满足为绿色值范围则执行下面语句 { Serial.println("->Green"); //串口打印字符串"->Green"
  }
  else if(((value[0]>46) && (value[0]<86)) && ((value[1]>71) && (value[1]<111)) && ((value[2]>117) && (value[2]<157))) //如果变量value[i]数值满足为蓝色值范围则执行下面语句 { Serial.println("->Blue"); //串口打印字符串"->Blue"
  }
  else if (((value[0]>230) && (value[0]<280)) && ((value[1]>230) && (value[1]<280)) && ((value[2]>230) && (value[2]<280))) //如果变量value[i]数值满足为白色值范围则执行下面语句 { Serial.println("->White"); //串口打印字符串"->White"
  }
  else if (value[0]>0 && value[1]>0 && value[2]>0)
    //如果变量value[i]数值不满足上述颜色值范围则执行下面语句
  { 
    Serial.println("->Other Color"); //串口打印字符串"->Other Color"
  }
  delay(4000); //延迟4 秒
}

 

 

当然啦,等实际运用在小车上时不可能这么慢的检测速度~根本就不需要对外打印嘛~改成一问一答就行了,到地方再检测~~嗯·~~

 

然后关于改进的猜想是,用油漆把传感器上4个led和纸筒内部涂黑(我用记号笔涂led试过,基本盖不住~)~~然后可以用手电筒上的喇叭形的那个小东西装在纸筒里传感器的芯片上,这样在纸筒基本隔绝了外界光之后起一个集光增加灵敏度的作用~~当然啦,这些现在都只是猜想啦,还需要试验来验证的~~

阳光下使用颜色传感器》上有1条评论

  1. Pingback引用通告: BZ编程小组 作品 | BZ编程小组

发表评论

电子邮件地址不会被公开。 必填项已用*标注