极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 57443|回复: 29

菜鸟求助,GP2Y1010AU0F与Arduino怎么连接?

[复制链接]
发表于 2013-11-28 22:03:57 | 显示全部楼层 |阅读模式
本帖最后由 hi55234 于 2013-12-20 13:51 编辑

1、GP2Y1010AU0F的针脚是怎么定义的?
看数据手册(https://www.sparkfun.com/datasheets/Sensors/gp2y1010au_e.pdf),内部示意图这样的:

按照本菜鸟的理解,对应的针脚就是1、3、2、6、5、4


按照外形尺寸的图:

按照本菜鸟的理解,对应的针脚就变成了是1、2、3、4、5、6

2、这个针脚是怎么和Arduino连接的?

按照本菜鸟的理解,这个是PNP三极管,目测V1(E极)>V3(B极)>V2(C极),同时V3决定了LED是否发光(是控制端)

网上关于各个针脚的连接方法是这么说的(http://www.guokr.com/article/434130/):
Sharp pin 1 (V-LED) => 5V (通过一个150欧的电阻连接)
Sharp pin 2 (LED-GND) => Arduino GND pin
Sharp pin 3 (LED) => Arduino pin 2
Sharp pin 4 (S-GND) => Arduino GND pin
Sharp pin 5 (Vo) => Arduino A0 pin
Sharp pin 6 (Vcc) => 5V

但看到大神的连接图时(http://www.geek-workshop.com/for ... thread&tid=4848),顿时凌乱了:


即:
1——V-LED——5V (通过一个150欧的电阻连接)
2——LED-GND——Arduino A0 pin
3——LED——Arduino GND pin
4——S-GND——Arduino pin 2
5——VO——Arduino GND pin

6——VCC——5V

怎么感觉和文字说明对不上号呢?请各位坛友不吝赐教

____________分割线_____20131214________________________
用GP2Y1010AU0F+Arduino pro min+ CP2102+74hc595 两片+四位时钟数码管+面包板(成本75元一个的样子) 做了2个pm2.5检测
目测稳定性还是有那么一点的(东西直接插面包板上,电容两端电压4.48v的4.75v,坑爹啊,统一电脑的相邻usb口取的电,只能说线没接好,面包板内阻也有差异,不过只要粉尘头上了电容滤波,实际看数据,模拟口处的电压的差异也就4个单位的样子,小于0.015V)
端口读取的图:


实际连接的样子:


----------------------分割线_____20131218--------------------------------
用SprintLayout画了个pcb


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2013-11-29 09:03:41 | 显示全部楼层
(1)        夏普GP2Y1010AU0F_粉尘传感器(按图示方式放置,从左到右分别为1~6脚)
Sharp pin 1 (V-LED) => 5V (串联150Ω电阻,pin 1和电阻之间连220μF电容接地);
Sharp pin 2 (LED-GND) => Arduino GND脚;
Sharp pin 3 (LED) => Arduino 数字口pin 2 ;
Sharp pin 4 (S-GND) => Arduino GND 脚;
Sharp pin 5 (Vo) => Arduino 模拟口A0pin;
Sharp pin 6 (Vcc) => 5V;

人家有说明的,接线的说明和数据手册是对应得起来的。
回复 支持 反对

使用道具 举报

发表于 2013-11-29 16:05:45 | 显示全部楼层
楼主,可以看这一篇非常详细的设置教程,Arduino+GP2Y1010空气质量监测方案,http://tuding.iego.cn:8001/archives/98
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-1 19:38:40 | 显示全部楼层
昨天淘宝买的,CP2102和pro mini到了,手工极差,却很有毅力的菜鸟开始干活

前前后后的差不多用了6小时,就成了这副模样:





除开焊点与排针外,感觉工艺还可以~~~

短接RXD与TXD,运行USB-TTL测试工具,蒙苍天垂怜,一切正常

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-1 19:53:09 | 显示全部楼层
焊完了CP2102模块 开始焊pro mini,确实很小,对于俺这种苦手来说,真心伤不起····


背面一览


其实这货长这样子:


PS:为啥有的针没有焊好呢?因为焊好了,经过多次插拔与摔打,就成了这样子,好在不影响啥~~~
PS2:就是这个不影响,让俺从昨晚10点一直折腾到今天18:00······

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-1 20:21:31 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-1 20:32 编辑

然后,既然都焊接好了,就该上机连接了吧~~

装好java JDK,下个绿色版的1.0.4,然后下程序,我下,我下,死活下不了,经典的avrdude: stk500_getsync(): not in sync: resp=0x00错误~~~

按道理来讲,俺是照着大神的教程来的,CTS接RST这种事还是知道的,可是,可是,还是下载不进去····一上午就这么纠结过去了

俺就是参照这个链接的(CP2102啥的,需要CTS接口啥的,都是拜这位大神指点):

原帖:http://www.geekfans.com/thread-63037-1-1.html


到了下午,淘宝上买的万用表到了,好了,看看是啥问题吧,

1、曾经一度怀疑CP2102被俺焊残废了,原因在于TX0-TXD这个在下载程序的时候没有电压变化~~~~不过USB-TTL测试工具运行的时候用电压表测试发现电压是会跳动的~~~所以CP2102是好的,可是,没道理啊,同样的解法,为啥俺就下载不了。

2、难道是pro mini被俺焊残废了?好在俺pro mini一次买了2片(当时是为了防止bootloader被俺搞残废了,网上大神说arduino是可以为arduino刷bootloader的),另外一片测试,依旧写不上去~~~

3、开始怀疑是arduino IDE的问题,1.0.5、1.0.4、1.0.1轮番试过,依旧无解

百般无奈之下考试测各个接口的电压,发现2个TX0的电压竟然不一致,一个2.5V、一个0.13V,怎么可能呢?一条导线联通的2点,竟然电压会不一致!!!拆开来看看,尼玛,TX0已经送了,当然,TX0只是众多松了的接口之一。速度飞线修正,烙铁也在今日早些时候归西,万幸人每受伤(平安是福啊)~~~

修正之后再次下载程序,是不是就OK了呢?果断不是啊,依旧是 resp=0x00错误~~~~

万般无奈之下,再次求助googol
发现一篇文章:

单片机串口通讯RXD与TXD如何对接详解(独家!)
http://blog.csdn.net/sdwuyulunbi/article/details/6632382

说的就是有时候是TX0接TXD,有时候是TX0接RXD,怎么接,本菜鸟傻傻分不清楚,得,倒过来试试,再次下载:


泪奔啊,终于下载成功~~~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-1 20:31:34 | 显示全部楼层
附上链接图一张:


至于手动按REST:通过万用表的电压变化,个人的理解是,按下rest,pro mini的rest电压发生变化,以此通知cp2102已经做好准备,可以传输数据了,按得时机那网友的话来说就是出现:使用xx字节,xx字节可用的提示的时候········

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-2 15:22:04 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-20 13:47 编辑

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-2 15:59:13 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-2 16:23 编辑

下面是关于自定义变量的问题:

int dustPin=1;//A0没焊好,就用了A1接口
int dustVal=0;

int ledPower=2;
int delayTime=280;
int delayTime2=40;
float offTime=9680;
void setup(){
Serial.begin(9600);
pinMode(ledPower,OUTPUT);
pinMode(4, OUTPUT);//这一行就本阶段来说目测是废的,因为数字口4,根本没接任何东西,即便注释掉也没问题
}

void loop(){
// l接下来6行,就是粉尘探测的程序
digitalWrite(ledPower,LOW); // power on the LED
delayMicroseconds(delayTime);
dustVal=analogRead(dustPin); // read the dust value via pin 5 on the sensor
delayMicroseconds(delayTime2);
digitalWrite(ledPower,HIGH); // turn the LED off
delayMicroseconds(offTime);

delay(3000);
Serial.println(dustVal);//所得到的dustVal是1024中德一个数字,一个单位代表5/1024伏特

float dustVal3=dustVal;
dustVal3=dustVal*5/1024;
Serial.println(dustVal3);//这个的结果就是0.00,自定义变量能定义却不能与其他自定义变量进行运算


float dustVal4=dustVal;
dustVal4=dustVal4*5/1024;
Serial.println(dustVal4);//这个却能得出正确的结果(作为人类的智商优越感瞬间爆棚,有木有!!)


float dustVal5=dustVal;
dustVal5=dustVal5*5/1024;
Serial.println(dustVal5);//这个的结果就是0,电压不足1V,取整导致为0



float dustVal6=dustVal3;
dustVal6=dustVal6*5/1024;
Serial.println(dustVal6);//自变量的传递,结果0.00,可见自变量不能传递,dustVal6=dustVal3无效,准备的说是dustVal3的值无效

float dustVal7=dustVal;
dustVal7=dustVal7*5/1024;
Serial.println(dustVal7);//第二次引用,得出正确的结果(dustVal7=dustVal有效),个人觉得更准确的说法是,如果自变量的值没有外部数据作为支撑,那么这个值只能本次自己用,且不能被传递
delay(3000);

}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-2 17:18:59 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-2 17:20 编辑

目前程序的样子:

int dustPin=1;
int dustVal=0;

int ledPower=2;
int delayTime=280;
int delayTime2=40;
float offTime=9680;
void setup(){
Serial.begin(9600);
pinMode(ledPower,OUTPUT);
//pinMode(4, OUTPUT);
}

void loop(){
// ledPower is any digital pin on the arduino connected to Pin 3 on the sensor
digitalWrite(ledPower,LOW); // power on the LED
delayMicroseconds(delayTime);
dustVal=analogRead(dustPin); // read the dust value via pin 5 on the sensor
delayMicroseconds(delayTime2);
digitalWrite(ledPower,HIGH); // turn the LED off
delayMicroseconds(offTime);

delay(3000);
Serial.println(dustVal);


float dustVal2=dustVal;
dustVal2=(dustVal2*5/1024-0.0356)*120000;
Serial.println(dustVal2);//实际的颗粒数

if(dustVal2<76)
{
Serial.println("EXCELLENT");
}
else if(dustVal2<151)
{
Serial.println("VERY GOOD");
}
else if(dustVal2<301)
{
Serial.println("GOOD");
}
else if(dustVal2<1051)
{
Serial.println("FAIR");
}
else if(dustVal2<3001)
{
Serial.println("POOR");
}
else
{
Serial.println("VERY POOR");
}


if(dustVal>118)
//此拟合公式有效y=0.172*x-0.0999
{
float dustVal3=dustVal;
dustVal3=((dustVal3*5/1024)*0.172-0.0999)*1000;
Serial.println("PM2.5:");
Serial.println(dustVal3);//实际的颗粒数
}
else
{
Serial.println("PM2.5:");
Serial.println("----");
}



}


回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-2 17:21:51 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-31 15:03 编辑



公司悲催的空气质量
~~~~~~~~~~~~~~~~~~
传说中的指针


  1. void setup() {               
  2. Serial.begin (9600);
  3. }

  4. // the loop routine runs over and over again forever:
  5. void loop() {
  6. int a,b;
  7.   int *pointer_1, *pointer_2;
  8.   a=100;b=10;
  9.   pointer_1=&a;
  10. pointer_2=&b;

  11.   delay (1000);
  12.    Serial.print ("a=");
  13.    Serial.println (a);
  14.     Serial.print ("b=");
  15.    Serial.println (b);
  16.       Serial.print ("*pointer_1=");
  17.    Serial.println (*pointer_1);
  18.     Serial.print ("*pointer_2=");
  19.    Serial.println (*pointer_2);
  20. }
复制代码


---------------------------------------------
C语言的printf目测在arduino中不能打印
---------------------------------------------
指针与数组

  1. int xx[5] = {1,2,3,4,5};
  2. int *pa;
  3. int *pa2;

  4. void setup() {               
  5. Serial.begin (9600);
  6. }

  7. // the loop routine runs over and over again forever:
  8. void loop() {
  9. pa=xx;
  10. pa2=&xx[0];

  11.   delay (1000);

  12. Serial.println (*pa);
  13.    Serial.println (*(pa+1));
  14.    Serial.println (*(pa+2));
  15.     Serial.println (*(pa+3));
  16.     Serial.println (*(pa+4));
  17.   
  18.   
  19.   Serial.println (*pa2);
  20.    Serial.println (*(pa2+1));
  21.    Serial.println (*(pa2+2));
  22.     Serial.println (*(pa2+3));
  23.     Serial.println (*(pa2+4));
  24.    
  25.        Serial.println ("-----------------");
  26. }
复制代码


-------------
char 与指针

  1. const char *pa = "arduino";

  2. void setup() {               
  3. Serial.begin (9600);
  4. }


  5. void loop() {

  6.   delay (1000);

  7. Serial.println (*pa);
  8.    Serial.println (*(pa+1));
  9.    Serial.println (*(pa+2));
  10.     Serial.println (*(pa+3));
  11.     Serial.println (*(pa+4));
  12.    Serial.println (*(pa+5));
  13.    Serial.println (*(pa+6));

  14.            Serial.println ("-----------------");

  15.        Serial.print (*pa);
  16.    Serial.print (*(pa+1));
  17.    Serial.print (*(pa+2));
  18.     Serial.print (*(pa+3));
  19.     Serial.print (*(pa+4));
  20.    Serial.print (*(pa+5));
  21.    Serial.println (*(pa+6));
  22.         Serial.println ("-----------------");
  23. }
复制代码


char *pc;
pc = "C Language"; 貌似arduino编译不过

char *pc="C Language";就没有问题

--------------------
指针变量的减法,(数组)元素个数差,仅有指定个数且填满了的数组才有意义

  1. int xx[5] = {1,2,3,4,5};
  2. int yy[10] = {1,2,3,4,5,6,7,8,9,0};
  3. int zz[] = {1,2,3,4,5,6,7,8,9};
  4. int nn[10] = {1,2,3,4,5};


  5. int *pa,*pa2,*pa3,*pa4;

  6. void setup() {               
  7. Serial.begin (9600);
  8. }

  9. // the loop routine runs over and over again forever:
  10. void loop() {
  11. pa=xx;
  12. pa2=yy;
  13. pa3=zz;
  14. pa4=nn;
  15. int x=pa2-pa;
  16. int y=pa3-pa;
  17. int z=pa4-pa;
  18.   delay (1000);
  19. Serial.println (x);
  20.   Serial.println (y);
  21.   Serial.println (z);
  22.        Serial.println ("-----------------");
  23. }
复制代码


-----------------------------------------------
  int a=10,b=20,s,t,*pa,*pb; /*说明pa,pb为整型指针变量*/
  pa=&a;                     /*给指针变量pa赋值,pa指向变量a*/
  pb=&b;                     /*给指针变量pb赋值,pb指向变量b*/
  s=*pa+*pb;                 /*求a+b之和,(*pa就是a,*pb就是b)*/
  t=*pa**pb;                 /*本行是求a*b之积*/

p的初值为&a[0],*(p+i)与*(a+i)等价

  1. int xx[5] = {1,2,3,4,5};



  2. int *pa,*pa2,*pa3,*pa4;

  3. void setup() {               
  4. Serial.begin (9600);
  5. }

  6. // the loop routine runs over and over again forever:
  7. void loop() {
  8. pa=xx;


  9. Serial.println (*xx);
  10.   Serial.println (*pa);
  11. Serial.println (*(xx+1));
  12.   Serial.println (*(pa+1));
  13.        Serial.println ("-----------------");
  14.        delay (1000);
  15. }
复制代码


------------------------------------------------
三种方式定义数组,另外不打括号的for循环就只管下面一排

  1. void setup() {               
  2. Serial.begin (9600);
  3. }


  4. void loop() {
  5.   int a[10],i;
  6.   for(i=0;i<10;i++)
  7.     a[i]=i;
  8.   for(i=0;i<10;i++)
  9.   Serial.print (a[i]);
  10.   Serial.print (",");

  11. Serial.println ();
  12. delay (1000);
  13. Serial.println ("-----------------1");

  14.   int aa[10];
  15.   for(i=0;i<10;i++)
  16.     *(aa+i)=i;
  17.   for(i=0;i<10;i++)
  18. Serial.print (*(aa+i));
  19. Serial.print (",");

  20. Serial.println ();
  21. delay (1000);
  22. Serial.println ("-----------------2");

  23.   int aaa[10],*p;
  24.   p=aaa;
  25.   for(i=0;i<10;i++)
  26.     *(p+i)=i;
  27.   for(i=0;i<10;i++)
  28. Serial.print (*(p+i));
  29. Serial.print (",");

  30. Serial.println ();
  31. delay (1000);
  32. Serial.println ("-----------------3");

  33. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-3 17:00:23 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-16 16:38 编辑
  1. /*粉尘头的代码*/
  2. int dustPin=0;//数字口p2控制模拟口A0读取粉尘电压
  3. int dustVal=0;
  4. int ledPower=2;
  5. int delayTime=280;
  6. int delayTime2=40;
  7. float offTime=9680;

  8. //定义一个只有2个元素的数组
  9. int mySensVals [2];
  10. //定义2个布尔变量,通过i的变化让粉尘电压值先进先出循环填入上数组,实现相邻采样平均
  11. boolean i=0,j=0;


  12. /*数码管与74hc595的代码*/
  13. //数码管显示为0-9共10个数字,以便四位数码管显示调用
  14. const byte DIGX_COUNT = 10;
  15. unsigned int sequence[DIGX_COUNT] = {0x77,0x14,0x5B,0x5E,0x3C,0x6E,0x6F,0x54,0x7F,0x7E};

  16. //接法:P5、P7、P9接第一片595(Q0-Q7对应数码管逆时针1、2、4、5、7、10、11、3(这个是点),第二片控制数码管共阴脚Q0-Q3接6、8、9、12),
  17. int latchPin = 8;  //Pin connected to ST_CP(pin 12) of 74HC595
  18. int clockPin = 7; //Pin connected to SH_CP(pin 11) of 74HC595
  19. int dataPin = 9;  //Pin connected to DS(pin 14) of 74HC595

  20. //引入millis()来控制循环
  21. unsigned long time1=millis();


  22. //pm2.5的数值、AQI指数、灰尘数,相邻采样平均电压
  23. float dustValPM25,AQI,dustnumber,averagedustVal;




  24. void setup(){
  25. Serial.begin(9600);


  26. pinMode(ledPower,OUTPUT);//开启粉尘的控制端口

  27. /*74HC595所涉及的3个端口*/
  28. pinMode(latchPin, OUTPUT);
  29. pinMode(clockPin, OUTPUT);
  30. pinMode(dataPin, OUTPUT);
  31.   
  32. }

  33. void loop(){

  34. //最初的3秒内获得mySensVals [0],第3秒的时候就可以计算averagedustVal
  35. if(!j){
  36.    /*粉尘头控制代码*/
  37. digitalWrite(ledPower,LOW); //开灯
  38. delayMicroseconds(delayTime);
  39. dustVal=analogRead(dustPin); //读电压
  40. delayMicroseconds(delayTime2);
  41. digitalWrite(ledPower,HIGH); //关灯
  42. delayMicroseconds(offTime);

  43. mySensVals [i]=dustVal;//把检测到的第一次电压塞给mySensVals [0]
  44. i=!i;//i值反转
  45. j=1;//不再执行这个程序

  46.   }
  47.   
  48.   
  49. /*粉尘头取得的粉尘对应电压dustVal,每3秒循环一次*/

  50. if (millis() - time1 > 3000){
  51. time1=millis();

  52. /*粉尘头控制代码*/
  53. digitalWrite(ledPower,LOW); //开灯
  54. delayMicroseconds(delayTime);
  55. dustVal=analogRead(dustPin); //读电压
  56. delayMicroseconds(delayTime2);
  57. digitalWrite(ledPower,HIGH); //关灯

  58. /*邻采样平均averagedustVal的计算*/
  59. mySensVals [i]=dustVal;//把检测到的第一次电压塞给mySensVals [1]
  60. i=!i;//i值反转
  61. averagedustVal=(mySensVals [0]+mySensVals [1])*0.5;//计算平均电压



  62. /*计算0.01 cubic feet的颗粒数:(v-0.0356)X120000
  63. 对于电压低于8个单位的用线性,搞定值以下颗粒数为负数的情况*/

  64. if(averagedustVal>8)dustnumber=(averagedustVal*5/1024-0.0356)*120000;
  65. else dustnumber=averagedustVal*52;


  66. /*计算pm2.5的数值 电压阀值以上用:(v*0.172-0.0999)*1000,阀值以下用线性,参考国外帖子,认为输出最低17,对应粉尘5000*/

  67. //0.9V【184.5】线性pm:电压单位*0.298373984进行计算,依据为手册上无灰尘也有0.9V的电压
  68. //0.78V【161】线性pm:电压单位*0.21931677行计算,颗粒数降低数/粉尘降低数值最大值
  69. //0.69V【142】线性pm:电压单位*0.136338028行计算,颗粒数/粉尘值增速加快速上升
  70. //((averagedustVal*5/1024)*0.172-0.0999)*1000公式实质是0.83984375*averagedustVal-99.9

  71. if(averagedustVal>184.5)dustValPM25=0.83984375*averagedustVal-99.9;
  72. else dustValPM25=averagedustVal*0.298373984;


  73. /*AQI的计算,美国标准*/

  74. if(dustValPM25<15.4) AQI=(50-0)/(15.4-0)*(dustValPM25-0)+0;
  75. else if(dustValPM25<40.4) AQI=(100-51)/(40.4-15.5)*(dustValPM25-15.5)+51;
  76. else if(dustValPM25<65.4) AQI=(150-101)/(65.4-40.5)*(dustValPM25-40.5)+101;
  77. else if(dustValPM25<150.4) AQI=(200-151)/(150.4-65.5)*(dustValPM25-65.5)+151;
  78. else if(dustValPM25<250.4) AQI=(300-201)/(250.4-150.5)*(dustValPM25-150.5)+201;
  79. else if(dustValPM25<350.4) AQI=(400-301)/(350.4-250.5)*(dustValPM25-250.5)+301;
  80. else AQI=(500-401)/(500.4-350.5)*(dustValPM25-350.5)+401;




  81. }



  82. //做一个保险,对应millis()溢出归零后,millis()<time1,则3秒检测一次循环终止的情况
  83. if (millis() < time1){
  84. time1=millis();
  85. i=0;//重置i的值
  86. j=0;//重置j的值
  87. }



  88.     /*计算任意数字(小于999)各上是什么数字*/
  89.   
  90.   float test=dustValPM25;
  91.     int test1=test*0.01;
  92.     int test2=test*0.1;
  93.     int test3=test;
  94.        
  95.    

  96.    
  97.    //test小数点左边有0位,4位数码管最高2位第一位不显,第二位为0
  98.   //(0.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  99.    if(test3==0){  
  100.    int test4=test*10;//十分位上的数字,如0.12的1
  101.    int test5=test*100-test4*10;//百分位上的数字,如0.12的2

  102.     digitalWrite(latchPin, LOW);
  103.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFE); //shift out highbyte
  104.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  105.     digitalWrite(latchPin, HIGH);

  106.     digitalWrite(latchPin, LOW);
  107.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
  108.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  109.     digitalWrite(latchPin, HIGH);
  110.    
  111.     digitalWrite(latchPin, LOW);
  112.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
  113.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  114.     digitalWrite(latchPin, HIGH);

  115.     digitalWrite(latchPin, LOW);//加入小数点
  116.     shiftOut(dataPin, clockPin, MSBFIRST, 0xF7); //shift out highbyte
  117.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  118.     digitalWrite(latchPin, HIGH);

  119.    }
  120.    //test小数点左边有1位,4位数码管最高1位第一位不显,第二位为test3
  121.    //(x.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  122.    else if(test2==0){  

  123.    int test4=test*10-test3*10;//十分位上的数字,如1.23的2
  124.    int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
  125.    
  126.     digitalWrite(latchPin, LOW);
  127.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFE); //shift out highbyte
  128.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  129.     digitalWrite(latchPin, HIGH);

  130.     digitalWrite(latchPin, LOW);
  131.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
  132.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  133.     digitalWrite(latchPin, HIGH);
  134.    
  135.     digitalWrite(latchPin, LOW);
  136.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
  137.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  138.     digitalWrite(latchPin, HIGH);


  139.     digitalWrite(latchPin, LOW);//加入小数点
  140.     shiftOut(dataPin, clockPin, MSBFIRST, 0xF7); //shift out highbyte
  141.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte     
  142.     digitalWrite(latchPin, HIGH);
  143.    
  144.    }
  145.     //test小数点左边有2位,4位数码管最高1位第一位test2
  146.     //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  147.    else if(test1==0){
  148.    
  149.    int test4=test-test2*10;//个位上的数字,如12.34的2
  150.    int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
  151.    int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字  
  152.        
  153.     digitalWrite(latchPin, LOW);
  154.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFE); //shift out highbyte
  155.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  156.     digitalWrite(latchPin, HIGH);

  157.     digitalWrite(latchPin, LOW);
  158.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
  159.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  160.     digitalWrite(latchPin, HIGH);
  161.    
  162.     digitalWrite(latchPin, LOW);
  163.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
  164.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  165.     digitalWrite(latchPin, HIGH);


  166.     digitalWrite(latchPin, LOW);
  167.     shiftOut(dataPin, clockPin, MSBFIRST, 0xF7); //shift out highbyte
  168.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test2]); //shift out lowbyte
  169.     digitalWrite(latchPin, HIGH);

  170.     digitalWrite(latchPin, LOW);//加入小数点
  171.     shiftOut(dataPin, clockPin, MSBFIRST, 0xF7); //shift out highbyte
  172.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  173.     digitalWrite(latchPin, HIGH);

  174.    
  175.    }

  176. //test小数点左边有3位,如123.45,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位不显,第二位为test1
  177. //(xxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxx)数字口控制两片74HC595进而控制4位时钟数码管
  178.    else {
  179.    int test4=test2-test1*10;//十位上的数字,如123.45的2
  180.    int test5=test-test1*100-test4*10;//个分位上的数字,如123.45的3

  181.     digitalWrite(latchPin, LOW);
  182.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFE); //shift out highbyte
  183.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  184.     digitalWrite(latchPin, HIGH);

  185.     digitalWrite(latchPin, LOW);
  186.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
  187.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  188.     digitalWrite(latchPin, HIGH);
  189.    
  190.     digitalWrite(latchPin, LOW);
  191.     shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
  192.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test1]); //shift out lowbyte
  193.     digitalWrite(latchPin, HIGH);

  194.    }
  195.    
  196.    
  197.    
  198.   

  199.    
  200.   
  201.   
  202.    /*计算任意数字(小于999)各上是什么数字--------------------end*/



  203. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-15 21:54:46 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-19 22:33 编辑

注意:因为我做了2个pm2.5的·检测,2个接74HC595的数字口有差异,所以接法与注释有差异,不过也就是595的差异,实际接法以程序为准


  1. /*
  2. 功能:四位12脚共阴数码管,实时循环显示所测定的PM2.5值\AQI\颗粒数\温度四个值,并驱动LED等在显示不同的值的时候显示不同的颜色

  3. 链接方式:
  4. CP2102~~~~Pro mini:
  5. GND-GND、5V-Vcc、TXD-RX1、RXD-TX0、CTS-GRN(rest)

  6. Pro mini~~~GP2Y1010AU0F:
  7. 5V-150欧-(V-LED)
  8. 5V-150欧—Vcc
  9. 5V-150欧-220uF-GND
  10. GND-(LED-GND)
  11. GND-(S-GND)
  12. Pin2-LED
  13. A0-Vo

  14. Pro mini~~~74HC595(片1):
  15. Pin8-ST_CP(pin 12)
  16. Pin7-SH_CP(pin 11)
  17. Pin9-DS(pin 14)
  18. GND-pin13【EN允许输出】
  19. GND-pin8【GND】
  20. Vcc-pin10【CR不清除】
  21. Vcc-pin16【Vcc】

  22. Pro mini~~~74HC595(片2):
  23. Pin8-ST_CP(pin 12)
  24. Pin7-SH_CP(pin 11)
  25. GND-pin13【EN允许输出】
  26. GND-pin8【GND】
  27. Vcc-pin10【CR不清除】
  28. Vcc-pin16【Vcc】


  29. 74HC595(片1)~~~74HC595(片2):
  30. Pin9【Q7s】-DS(pin 14)

  31. 74HC595(片1)~~~四位12脚共阴数码管
  32. Q0-Pin1(逆时针)
  33. Q1-Pin2(逆时针)
  34. Q2-Pin4(逆时针)
  35. Q3-Pin5(逆时针)
  36. Q4-Pin7(逆时针)
  37. Q5-Pin10(逆时针)
  38. Q6-Pin11(逆时针)
  39. Q7-Pin3(逆时针,这个控制小点)

  40. 74HC595(片2)~~~四位12脚共阴数码管
  41. Q0-Pin6(逆时针DIG4)
  42. Q1-Pin8(逆时针DIG3)
  43. Q2-Pin9(逆时针DIG2)
  44. Q3-Pin12(逆时针DIG1)
  45. Q4-LED蓝
  46. Q5-LED绿
  47. Q6-LED红

  48. */



  49. /*DS18B20的代码*/
  50. //调用外部的2个库文件
  51. #include <OneWire.h>
  52. #include <DallasTemperature.h>
  53. // DS18B20的数据接口pin3
  54. #define ONE_WIRE_BUS 3
  55. // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
  56. OneWire oneWire(ONE_WIRE_BUS);
  57. // Pass our oneWire reference to Dallas Temperature.
  58. DallasTemperature sensors(&oneWire);

  59. /*粉尘头的代码*/
  60. int dustPin=0;//数字口p2控制模拟口A0读取粉尘电压
  61. int dustVal=0;
  62. int ledPower=2;
  63. int delayTime=280;
  64. int delayTime2=40;
  65. float offTime=9680;

  66. //定义一个只有2个元素的数组
  67. int mySensVals [2];
  68. //定义2个布尔变量,通过i的变化让粉尘电压值先进先出循环填入上数组,实现相邻采样平均
  69. boolean i=0,j=0;


  70. /*数码管与74hc595的代码*/
  71. //数码管显示为0-9共10个数字,以便四位数码管显示调用
  72. const byte DIGX_COUNT = 10;
  73. unsigned int sequence[DIGX_COUNT] = {0x77,0x14,0x5B,0x5E,0x3C,0x6E,0x6F,0x54,0x7F,0x7E};

  74. //接法:P5、P7、P9接第一片595(Q0-Q7对应数码管逆时针1、2、4、5、7、10、11、3(这个是点),第二片控制数码管共阴脚Q0-Q3接6、8、9、12),
  75. int latchPin = 8;  //Pin connected to ST_CP(pin 12) of 74HC595
  76. int clockPin = 7; //Pin connected to SH_CP(pin 11) of 74HC595
  77. int dataPin = 9;  //Pin connected to DS(pin 14) of 74HC595

  78. //引入4个数组来控制第二片74hc595(即高位部分)
  79. //rgb led接第二片的Q4-Q6脚(对应蓝、绿、红),9蓝、A绿、B青、C红、D紫、E黄、F白
  80. unsigned int DIG4[6] = {0x9E,0xAE,0xBE,0xCE,0xCE,0xFE};//控制四位数码管的DIG4位
  81. unsigned int DIG3[6] = {0x9D,0xAD,0xBD,0xCD,0xCD,0xFD};
  82. unsigned int DIG2[6] = {0x9B,0xAB,0xBB,0xCB,0xCB,0xFB};
  83. unsigned int DIG1[6] = {0x97,0xA7,0xB7,0xC7,0xC7,0xF7};//控制四位数码管的DIG1位


  84. //引入millis()来控制循环
  85. unsigned long time1=millis();
  86. unsigned long time2=millis();

  87. //pm2.5的数值、AQI指数、灰尘数,相邻采样平均电压
  88. float dustValPM25,AQI,dustnumber,averagedustVal;

  89. //对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
  90. int xianshi=0;



  91. void setup(){
  92. Serial.begin(9600);

  93. sensors.begin(); //DS18B20所涉及的代码,开始检测?

  94. pinMode(ledPower,OUTPUT);//开启粉尘的控制端口

  95. /*74HC595所涉及的3个端口*/
  96. pinMode(latchPin, OUTPUT);
  97. pinMode(clockPin, OUTPUT);
  98. pinMode(dataPin, OUTPUT);
  99.   
  100.   
  101. }

  102. void loop(){

  103. //最初的3秒内获得mySensVals [0],第3秒的时候就可以计算averagedustVal
  104. if(!j){
  105.    /*粉尘头控制代码*/
  106. digitalWrite(ledPower,LOW); //开灯
  107. delayMicroseconds(delayTime);
  108. dustVal=analogRead(dustPin); //读电压
  109. delayMicroseconds(delayTime2);
  110. digitalWrite(ledPower,HIGH); //关灯
  111. delayMicroseconds(offTime);

  112. mySensVals [i]=dustVal;//把检测到的第一次电压塞给mySensVals [1]
  113. i=!i;//i值反转
  114. j=1;//不再执行这个程序

  115.   }
  116.   
  117.   
  118. /*粉尘头取得的粉尘对应电压dustVal,每3秒循环一次*/

  119. if (millis() - time1 > 3000){
  120. time1=millis();

  121. /*粉尘头控制代码*/
  122. digitalWrite(ledPower,LOW); //开灯
  123. delayMicroseconds(delayTime);
  124. dustVal=analogRead(dustPin); //读电压
  125. delayMicroseconds(delayTime2);
  126. digitalWrite(ledPower,HIGH); //关灯

  127. /*邻采样平均averagedustVal的计算*/
  128. mySensVals [i]=dustVal;//把检测到的第一次电压塞给mySensVals [1]
  129. i=!i;//i值反转
  130. averagedustVal=(mySensVals [0]+mySensVals [1])*0.5;//计算平均电压


  131. /*计算0.01 cubic feet的颗粒数:(v-0.0356)X120000
  132. 对于电压低于8个单位的用线性,搞定值以下颗粒数为负数的情况*/

  133. if(averagedustVal>8)dustnumber=(averagedustVal*5/1024-0.0356)*120000;
  134. else dustnumber=averagedustVal*52;


  135. /*计算pm2.5的数值 电压阀值以上用:(v*0.172-0.0999)*1000,阀值以下用线性,参考国外帖子,认为输出最低17,对应粉尘5000*/

  136. //0.9V【184.5】线性pm:电压单位*0.298373984进行计算,依据为手册上无灰尘也有0.9V的电压
  137. //0.78V【161】线性pm:电压单位*0.21931677行计算,颗粒数降低数/粉尘降低数值最大值
  138. //0.69V【142】线性pm:电压单位*0.136338028行计算,颗粒数/粉尘值增速加快速上升
  139. //((averagedustVal*5/1024)*0.172-0.0999)*1000公式实质是0.83984375*averagedustVal-99.9

  140. if(averagedustVal>184.5)dustValPM25=0.83984375*averagedustVal-99.9;
  141. else dustValPM25=averagedustVal*0.298373984;


  142. /*AQI的计算,美国标准*/

  143. if(dustValPM25<15.4) AQI=(50-0)/(15.4-0)*(dustValPM25-0)+0;
  144. else if(dustValPM25<40.4) AQI=(100-51)/(40.4-15.5)*(dustValPM25-15.5)+51;
  145. else if(dustValPM25<65.4) AQI=(150-101)/(65.4-40.5)*(dustValPM25-40.5)+101;
  146. else if(dustValPM25<150.4) AQI=(200-151)/(150.4-65.5)*(dustValPM25-65.5)+151;
  147. else if(dustValPM25<250.4) AQI=(300-201)/(250.4-150.5)*(dustValPM25-150.5)+201;
  148. else if(dustValPM25<350.4) AQI=(400-301)/(350.4-250.5)*(dustValPM25-250.5)+301;
  149. else AQI=(500-401)/(500.4-350.5)*(dustValPM25-350.5)+401;



  150. //sensors.requestTemperatures();

  151. Serial.print("dust number=");
  152. Serial.print(dustnumber);//粉尘颗粒数
  153. Serial.print("= averagedustVal=");
  154. Serial.print(averagedustVal);//平均电压
  155. Serial.print("= dustValPM25=");
  156. Serial.print(dustValPM25);//PM2.5
  157. Serial.print("=AQI=");
  158. Serial.print(AQI);//AQI数
  159. //Serial.print("=sensors.getTempCByIndex(0)=");
  160. //Serial.print(sensors.getTempCByIndex(0));//温度
  161. Serial.print("____________________=millis(0)=");
  162. Serial.println(millis());//

  163. xianshi=(xianshi+1)%4;

  164. /*打印这些造成的时间开销会导致LED数码管的闪烁(单线程,打印的时候LED的输出就终止了),所以如非迫不得已,最好不打印
  165. Serial.print("dust number=");
  166. Serial.print(dustnumber);//粉尘颗粒数
  167. Serial.print("= averagedustVal=");
  168. Serial.print(averagedustVal);//平均电压
  169. Serial.print("= dustValPM25=");
  170. Serial.print(dustValPM25);//PM2.5
  171. Serial.print("=AQI=");
  172. Serial.print(AQI);//AQI数
  173. Serial.print("=sensors.getTempCByIndex(0)=");
  174. Serial.print(sensors.getTempCByIndex(0));//温度
  175. Serial.print("=");

  176. if(AQI<50)  Serial.println("1-VERY GOOD");//优
  177. else if(AQI<100) Serial.println("2-good");//良
  178. else if(AQI<150) Serial.println("3-mild concentration");//轻度污染
  179. else if(AQI<200) Serial.println("4-mesosaprobic");//中度污染
  180. else if(AQI<300) Serial.println("5-serious pollution");//重度污染
  181. else Serial.println("6-severe contamination");//严重污染

  182. // 这个是DS18B20读取温度的指令(750ms的时间开销,坑爹不解释,LED抖动的罪魁祸首)
  183. sensors.requestTemperatures();

  184. Serial.print("____________________=millis(0)=");
  185. Serial.println(millis());//
  186. */

  187. }



  188. //做一个保险,对应millis()溢出归零后,millis()<time1,则3秒检测一次循环终止的情况
  189. if (millis() < time1){
  190. time1=millis();
  191. i=0;//重置i的值
  192. j=0;//重置j的值
  193. }





  194.     /*计算任意数字(小于999)各上是什么数字*/
  195.   
  196.   float test;
  197.   
  198.   //对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
  199.   if(xianshi==0) test=dustValPM25;
  200.   else if(xianshi==1) test=AQI;
  201.   else if(xianshi==2) test=dustnumber*0.001;

  202.   
  203.     int test1=test*0.01;
  204.     int test2=test*0.1;
  205.     int test3=test;
  206.        
  207.    

  208.    
  209.    //test小数点左边有0位,4位数码管最高2位第一位不显,第二位为0
  210.   //(0.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  211.    if(test3==0){  
  212.    int test4=test*10;//十分位上的数字,如0.12的1
  213.    int test5=test*100-test4*10;//百分位上的数字,如0.12的2

  214.     digitalWrite(latchPin, LOW);
  215.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  216.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  217.     digitalWrite(latchPin, HIGH);

  218.     digitalWrite(latchPin, LOW);
  219.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  220.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  221.     digitalWrite(latchPin, HIGH);
  222.    
  223.     digitalWrite(latchPin, LOW);
  224.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  225.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  226.     digitalWrite(latchPin, HIGH);

  227.     digitalWrite(latchPin, LOW);//加入小数点
  228.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  229.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  230.     digitalWrite(latchPin, HIGH);

  231.    }
  232.    //test小数点左边有1位,4位数码管最高1位第一位不显,第二位为test3
  233.    //(x.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  234.    else if(test2==0){  

  235.    int test4=test*10-test3*10;//十分位上的数字,如1.23的2
  236.    int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
  237.    
  238.     digitalWrite(latchPin, LOW);
  239.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  240.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  241.     digitalWrite(latchPin, HIGH);

  242.     digitalWrite(latchPin, LOW);
  243.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  244.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  245.     digitalWrite(latchPin, HIGH);
  246.    
  247.     digitalWrite(latchPin, LOW);
  248.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  249.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  250.     digitalWrite(latchPin, HIGH);


  251.     digitalWrite(latchPin, LOW);//加入小数点
  252.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  253.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte     
  254.     digitalWrite(latchPin, HIGH);
  255.    
  256.    }
  257.     //test小数点左边有2位,4位数码管最高1位第一位test2
  258.     //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  259.    else if(test1==0){
  260.    
  261.    int test4=test-test2*10;//个位上的数字,如12.34的2
  262.    int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
  263.    int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字  
  264.        
  265.     digitalWrite(latchPin, LOW);
  266.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  267.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  268.     digitalWrite(latchPin, HIGH);

  269.     digitalWrite(latchPin, LOW);
  270.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  271.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  272.     digitalWrite(latchPin, HIGH);
  273.    
  274.     digitalWrite(latchPin, LOW);
  275.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  276.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  277.     digitalWrite(latchPin, HIGH);


  278.     digitalWrite(latchPin, LOW);
  279.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  280.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test2]); //shift out lowbyte
  281.     digitalWrite(latchPin, HIGH);

  282.     digitalWrite(latchPin, LOW);//加入小数点
  283.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  284.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  285.     digitalWrite(latchPin, HIGH);

  286.    
  287.    }

  288. //test小数点左边有3位,如123.45,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位不显,第二位为test1
  289. //(xxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxx)数字口控制两片74HC595进而控制4位时钟数码管
  290.    else {
  291.    int test4=test2-test1*10;//十位上的数字,如123.45的2
  292.    int test5=test-test1*100-test4*10;//个分位上的数字,如123.45的3

  293.     digitalWrite(latchPin, LOW);
  294.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  295.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  296.     digitalWrite(latchPin, HIGH);

  297.     digitalWrite(latchPin, LOW);
  298.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  299.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  300.     digitalWrite(latchPin, HIGH);
  301.    
  302.     digitalWrite(latchPin, LOW);
  303.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  304.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test1]); //shift out lowbyte
  305.     digitalWrite(latchPin, HIGH);

  306.    }
  307.    
  308.    
  309.    
  310.   

  311.    
  312.   
  313.   
  314.    /*计算任意数字(小于999)各上是什么数字--------------------end*/


  315.   if(xianshi==3) {
  316.       sensors.requestTemperatures();
  317.     test=sensors.getTempCByIndex(0);
  318. Serial.print("=sensors.getTempCByIndex(0)=");
  319. Serial.println(sensors.getTempCByIndex(0));//温度
  320.     for(int col=0;col<2499;col++){
  321.      

  322.   
  323.     int test1=test*0.01;
  324.     int test2=test*0.1;
  325.     int test3=test;
  326.        
  327.    

  328.    
  329.    //test小数点左边有0位,4位数码管最高2位第一位不显,第二位为0
  330.   //(0.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  331.    if(test3==0){  
  332.    int test4=test*10;//十分位上的数字,如0.12的1
  333.    int test5=test*100-test4*10;//百分位上的数字,如0.12的2

  334.     digitalWrite(latchPin, LOW);
  335.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  336.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  337.     digitalWrite(latchPin, HIGH);

  338.     digitalWrite(latchPin, LOW);
  339.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  340.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  341.     digitalWrite(latchPin, HIGH);
  342.    
  343.     digitalWrite(latchPin, LOW);
  344.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  345.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  346.     digitalWrite(latchPin, HIGH);

  347.     digitalWrite(latchPin, LOW);//加入小数点
  348.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  349.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  350.     digitalWrite(latchPin, HIGH);

  351.    }
  352.    //test小数点左边有1位,4位数码管最高1位第一位不显,第二位为test3
  353.    //(x.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  354.    else if(test2==0){  

  355.    int test4=test*10-test3*10;//十分位上的数字,如1.23的2
  356.    int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
  357.    
  358.     digitalWrite(latchPin, LOW);
  359.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  360.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  361.     digitalWrite(latchPin, HIGH);

  362.     digitalWrite(latchPin, LOW);
  363.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  364.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  365.     digitalWrite(latchPin, HIGH);
  366.    
  367.     digitalWrite(latchPin, LOW);
  368.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  369.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  370.     digitalWrite(latchPin, HIGH);


  371.     digitalWrite(latchPin, LOW);//加入小数点
  372.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  373.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte     
  374.     digitalWrite(latchPin, HIGH);
  375.    
  376.    }
  377.     //test小数点左边有2位,4位数码管最高1位第一位test2
  378.     //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  379.    else if(test1==0){
  380.    
  381.    int test4=test-test2*10;//个位上的数字,如12.34的2
  382.    int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
  383.    int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字  
  384.        
  385.     digitalWrite(latchPin, LOW);
  386.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  387.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  388.     digitalWrite(latchPin, HIGH);

  389.     digitalWrite(latchPin, LOW);
  390.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  391.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  392.     digitalWrite(latchPin, HIGH);
  393.    
  394.     digitalWrite(latchPin, LOW);
  395.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  396.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  397.     digitalWrite(latchPin, HIGH);


  398.     digitalWrite(latchPin, LOW);
  399.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  400.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test2]); //shift out lowbyte
  401.     digitalWrite(latchPin, HIGH);

  402.     digitalWrite(latchPin, LOW);//加入小数点
  403.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  404.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  405.     digitalWrite(latchPin, HIGH);

  406.    
  407.    }

  408. //test小数点左边有3位,如123.45,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位不显,第二位为test1
  409. //(xxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxx)数字口控制两片74HC595进而控制4位时钟数码管
  410.    else {
  411.    int test4=test2-test1*10;//十位上的数字,如123.45的2
  412.    int test5=test-test1*100-test4*10;//个分位上的数字,如123.45的3

  413.     digitalWrite(latchPin, LOW);
  414.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  415.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  416.     digitalWrite(latchPin, HIGH);

  417.     digitalWrite(latchPin, LOW);
  418.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  419.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  420.     digitalWrite(latchPin, HIGH);
  421.    
  422.     digitalWrite(latchPin, LOW);
  423.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  424.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test1]); //shift out lowbyte
  425.     digitalWrite(latchPin, HIGH);

  426.    }
  427.       
  428.     }
  429.   

  430. }

  431. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-19 22:18:16 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-19 22:30 编辑

相当另类的按键切换功能,用模拟口A1来读电压实现,针对的是抖动问题(面包板模拟口插根铜丝,随意动一下,每循环99次中电压高于1000个单位的可以有60-70次,数字口因为抖动厉害,无法实现按键切换的问题,原型就是http://www.geek-workshop.com/for ... thread&tid=1092帖子,不过我没有实现,就是因为抖动太厉害了,我要切换的RGB LED是接在第二片74hc595上面的)

  1. /*数码管与74hc595的代码*/
  2. //数码管显示为0-9共10个数字,以便四位数码管显示调用
  3. const byte DIGX_COUNT = 10;
  4. unsigned int sequence[DIGX_COUNT] = {0x77,0x14,0x5B,0x5E,0x3C,0x6E,0x6F,0x54,0x7F,0x7E};

  5. //接法:P8、P7、P9接第一片595(Q0-Q7对应数码管逆时针1、2、4、5、7、10、11、3(这个是点),第二片控制数码管共阴脚Q0-Q3接6、8、9、12),
  6. int latchPin = 8;  //Pin connected to ST_CP(pin 12) of 74HC595
  7. int clockPin = 7; //Pin connected to SH_CP(pin 11) of 74HC595
  8. int dataPin = 9;  //Pin connected to DS(pin 14) of 74HC595

  9. //引入4个数组来控制第二片74hc595(即高位部分)
  10. //rgb led接第二片的Q4-Q6脚(对应蓝、绿、红),9蓝、A绿、B青、C红、D紫、E黄、F白
  11. //啰嗦一句,如果rgb led只在共脚上接一个电阻的话,7种颜色并不能全部实现,因为3种灯的电压要求不一样
  12. unsigned int DIG4[6] = {0x9E,0xAE,0xCE,0xBE,0xEE,0xFE};//控制四位数码管的DIG4位
  13. unsigned int DIG3[6] = {0x9D,0xAD,0xCD,0xBD,0xED,0xFD};
  14. unsigned int DIG2[6] = {0x9B,0xAB,0xCB,0xBB,0xEB,0xFB};
  15. unsigned int DIG1[6] = {0x97,0xA7,0xC7,0xB7,0xE7,0xF7};//控制四位数码管的DIG1位


  16. //对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
  17. int xianshi=0;
  18. int xianshi2=0;

  19. boolean isPressed = 0;  //针对按起不放开的情况


  20. unsigned long time1=millis();
  21. unsigned long time2=millis();
  22. unsigned long time3=millis();

  23. void setup(){
  24. Serial.begin(9600);



  25. /*74HC595所涉及的3个端口*/
  26. pinMode(latchPin, OUTPUT);
  27. pinMode(clockPin, OUTPUT);
  28. pinMode(dataPin, OUTPUT);
  29.   
  30.   
  31. }


  32. void loop(){




  33. if(millis()-time2>500){ //每500ms扫描一次
  34. time2=millis();
  35. int xianshi3=analogRead(1);
  36. int col2=0;
  37. if(xianshi3>1000&&!isPressed){  //高电压+不是按着不放的情况
  38. for(int col=0;col<99;col++){
  39.   xianshi3=analogRead(1);
  40. if(xianshi3>1000)col2++; //防抖动的关键,实际测试,接vcc是100%都是大于1000的
  41. }
  42. }

  43. if(col2>95){  //99次有95次都高,就算是按下了切换
  44. xianshi2++;
  45.   isPressed=1; //转换为按着不放的状态
  46. }
  47.   
  48.   //打印是调试用的,实际程序不需要
  49. Serial.print("xianshi2 = ");
  50. Serial.println(xianshi2);



  51. }


  52. if(millis()-time3>500){
  53. time3=millis();
  54. int xianshi3=analogRead(1);
  55. int col2=0;
  56. if(isPressed){
  57. for(int col=0;col<99;col++){
  58.   xianshi3=analogRead(1);
  59. if(xianshi3<1000)col2++;
  60. }
  61. }

  62. if(col2>40){  //与上同理,鉴于插铜线抖动严重,认为99次内小于1000个单位的有40次以上就算放开了
  63.   isPressed=0;
  64. }


  65. }
  66.        
  67. //pm2.5、aqi、颗粒数、温度一共四态,所以用4取模
  68. xianshi=xianshi2%4;






  69.     /*计算任意数字(小于9999)各上是什么数字*/
  70.   
  71.   float test=xianshi;
  72.   


  73.     int test0=test*0.001;
  74.     int test1=test*0.01;
  75.     int test2=test*0.1;
  76.     int test3=test;
  77.        
  78.    

  79.    
  80.    //test小数点左边有0位,4位数码管最高2位第一位不显,第二位为0
  81.   //(0.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  82.    if(test3==0){  
  83.    int test4=test*10;//十分位上的数字,如0.12的1
  84.    int test5=test*100-test4*10;//百分位上的数字,如0.12的2

  85.     digitalWrite(latchPin, LOW);
  86.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  87.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  88.     digitalWrite(latchPin, HIGH);

  89.     digitalWrite(latchPin, LOW);
  90.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  91.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  92.     digitalWrite(latchPin, HIGH);
  93.    
  94.     digitalWrite(latchPin, LOW);
  95.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  96.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  97.     digitalWrite(latchPin, HIGH);

  98.     digitalWrite(latchPin, LOW);//加入小数点
  99.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  100.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  101.     digitalWrite(latchPin, HIGH);

  102.    }
  103.    //test小数点左边有1位,4位数码管最高1位第一位不显,第二位为test3
  104.    //(x.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  105.    else if(test2==0){  

  106.    int test4=test*10-test3*10;//十分位上的数字,如1.23的2
  107.    int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
  108.    
  109.     digitalWrite(latchPin, LOW);
  110.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  111.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  112.     digitalWrite(latchPin, HIGH);

  113.     digitalWrite(latchPin, LOW);
  114.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  115.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  116.     digitalWrite(latchPin, HIGH);
  117.    
  118.     digitalWrite(latchPin, LOW);
  119.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  120.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  121.     digitalWrite(latchPin, HIGH);


  122.     digitalWrite(latchPin, LOW);//加入小数点
  123.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  124.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte     
  125.     digitalWrite(latchPin, HIGH);
  126.    
  127.    }
  128.     //test小数点左边有2位,4位数码管最高1位第一位test2
  129.     //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  130.    else if(test1==0){
  131.    
  132.    int test4=test-test2*10;//个位上的数字,如12.34的2
  133.    int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
  134.    int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字  
  135.        
  136.     digitalWrite(latchPin, LOW);
  137.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  138.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  139.     digitalWrite(latchPin, HIGH);

  140.     digitalWrite(latchPin, LOW);
  141.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  142.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  143.     digitalWrite(latchPin, HIGH);
  144.    
  145.     digitalWrite(latchPin, LOW);
  146.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  147.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  148.     digitalWrite(latchPin, HIGH);


  149.     digitalWrite(latchPin, LOW);
  150.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  151.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test2]); //shift out lowbyte
  152.     digitalWrite(latchPin, HIGH);

  153.     digitalWrite(latchPin, LOW);//加入小数点
  154.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  155.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  156.     digitalWrite(latchPin, HIGH);

  157.    
  158.    }

  159. //test小数点左边有3位,如123.45,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位不显,第二位为test1
  160. //(xxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxx)数字口控制两片74HC595进而控制4位时钟数码管
  161. else if(test0==0){
  162.    int test4=test2-test1*10;//十位上的数字,如123.45的2
  163.    int test5=test3-test2*10;//个位上的数字,如123.45的3

  164.     digitalWrite(latchPin, LOW);
  165.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  166.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  167.     digitalWrite(latchPin, HIGH);

  168.     digitalWrite(latchPin, LOW);
  169.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  170.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  171.     digitalWrite(latchPin, HIGH);
  172.    
  173.     digitalWrite(latchPin, LOW);
  174.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  175.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test1]); //shift out lowbyte
  176.     digitalWrite(latchPin, HIGH);

  177.    }
  178.    
  179.    //test小数点左边有3位,如1234,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位test0
  180. //(xxxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxxx)数字口控制两片74HC595进而控制4位时钟数码管
  181. else {
  182.    int test4=test2-test1*10;//十位上的数字,如1234的3
  183.    int test5=test-test2*10;//个位上的数字,如1234的4
  184.    int test6=test1-test0*10;//百位上的数字,如1234的2

  185.     digitalWrite(latchPin, LOW);
  186.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  187.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  188.     digitalWrite(latchPin, HIGH);

  189.     digitalWrite(latchPin, LOW);
  190.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  191.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  192.     digitalWrite(latchPin, HIGH);
  193.    
  194.     digitalWrite(latchPin, LOW);
  195.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  196.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  197.     digitalWrite(latchPin, HIGH);
  198.        
  199.         digitalWrite(latchPin, LOW);
  200.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  201.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test0]); //shift out lowbyte
  202.     digitalWrite(latchPin, HIGH);

  203.    }
  204.    
  205.   

  206.    
  207.   
  208.   
  209.    /*计算任意数字(小于9999)各上是什么数字--------------------end*/



  210.   

  211.   
  212.   
  213. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-12-20 20:33:49 | 显示全部楼层
本帖最后由 hi55234 于 2013-12-20 20:39 编辑

综合一下,代码如下,但还是有2个小问题
1、温度取得是12位分辨率,耗时750ms,导致采集温度时LED数码管必然有闪烁
2、对于没有后台记录习惯的用户,在显示温度时粉尘头依然在采集数据,这个是没啥意义的

打算的解决方法:
1、降低采集精度,如果用9位,据称50ms就能完成采集
2、在采集前先行判断是否有必要采集


  1. /*
  2. 功能:四位12脚共阴数码管,实时循环显示所测定的PM2.5值\AQI\颗粒数\温度四个值,并驱动LED等在显示不同的值的时候显示不同的颜色

  3. 链接方式:
  4. CP2102~~~~Pro mini:
  5. GND-GND、5V-Vcc、TXD-RX1、RXD-TX0、CTS-GRN(rest)

  6. Pro mini~~~GP2Y1010AU0F:
  7. 5V-150欧-(V-LED)
  8. 5V-150欧—Vcc
  9. 5V-150欧-220uF-GND
  10. GND-(LED-GND)
  11. GND-(S-GND)
  12. Pin2-LED
  13. A0-Vo

  14. Pro mini~~~74HC595(片1):
  15. Pin8-ST_CP(pin 12)
  16. Pin7-SH_CP(pin 11)
  17. Pin9-DS(pin 14)
  18. GND-pin13【EN允许输出】
  19. GND-pin8【GND】
  20. Vcc-pin10【CR不清除】
  21. Vcc-pin16【Vcc】

  22. Pro mini~~~74HC595(片2):
  23. Pin8-ST_CP(pin 12)
  24. Pin7-SH_CP(pin 11)
  25. GND-pin13【EN允许输出】
  26. GND-pin8【GND】
  27. Vcc-pin10【CR不清除】
  28. Vcc-pin16【Vcc】


  29. 74HC595(片1)~~~74HC595(片2):
  30. Pin9【Q7s】-DS(pin 14)

  31. 74HC595(片1)~~~四位12脚共阴数码管
  32. Q0-Pin1(逆时针)
  33. Q1-Pin2(逆时针)
  34. Q2-Pin4(逆时针)
  35. Q3-Pin5(逆时针)
  36. Q4-Pin7(逆时针)
  37. Q5-Pin10(逆时针)
  38. Q6-Pin11(逆时针)
  39. Q7-Pin3(逆时针,这个控制小点)

  40. 74HC595(片2)~~~四位12脚共阴数码管
  41. Q0-Pin6(逆时针DIG4)
  42. Q1-Pin8(逆时针DIG3)
  43. Q2-Pin9(逆时针DIG2)
  44. Q3-Pin12(逆时针DIG1)
  45. Q4-LED蓝
  46. Q5-LED绿
  47. Q6-LED红

  48. */



  49. /*DS18B20的代码*/
  50. //调用外部的2个库文件
  51. #include <OneWire.h>
  52. #include <DallasTemperature.h>
  53. // DS18B20的数据接口pin3
  54. #define ONE_WIRE_BUS 3
  55. // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
  56. OneWire oneWire(ONE_WIRE_BUS);
  57. // Pass our oneWire reference to Dallas Temperature.
  58. DallasTemperature sensors(&oneWire);

  59. /*粉尘头的代码*/
  60. int dustPin=0;//数字口p2控制模拟口A0读取粉尘电压
  61. int dustVal=0;
  62. int ledPower=2;
  63. int delayTime=280;
  64. int delayTime2=40;
  65. float offTime=9680;

  66. //定义一个只有2个元素的数组
  67. int mySensVals [2];
  68. //定义2个布尔变量,通过i的变化让粉尘电压值先进先出循环填入上数组,实现相邻采样平均
  69. boolean i=0,j=0;


  70. /*数码管与74hc595的代码*/
  71. //数码管显示为0-9共10个数字,以便四位数码管显示调用
  72. const byte DIGX_COUNT = 10;
  73. unsigned int sequence[DIGX_COUNT] = {0x77,0x14,0x5B,0x5E,0x3C,0x6E,0x6F,0x54,0x7F,0x7E};

  74. //接法:P5、P7、P9接第一片595(Q0-Q7对应数码管逆时针1、2、4、5、7、10、11、3(这个是点),第二片控制数码管共阴脚Q0-Q3接6、8、9、12),
  75. int latchPin = 8;  //Pin connected to ST_CP(pin 12) of 74HC595
  76. int clockPin = 7; //Pin connected to SH_CP(pin 11) of 74HC595
  77. int dataPin = 9;  //Pin connected to DS(pin 14) of 74HC595

  78. float test;//四位数码管拆分时用到的变量

  79. //引入4个数组来控制第二片74hc595(即高位部分)
  80. //rgb led接第二片的Q4-Q6脚(对应蓝、绿、红),9蓝、A绿、B青、C红、D紫、E黄、F白
  81. unsigned int DIG4[6] = {0x9E,0xAE,0xBE,0xCE,0xCE,0xFE};//控制四位数码管的DIG4位
  82. unsigned int DIG3[6] = {0x9D,0xAD,0xBD,0xCD,0xCD,0xFD};
  83. unsigned int DIG2[6] = {0x9B,0xAB,0xBB,0xCB,0xCB,0xFB};
  84. unsigned int DIG1[6] = {0x97,0xA7,0xB7,0xC7,0xC7,0xF7};//控制四位数码管的DIG1位


  85. //引入millis()来控制循环
  86. unsigned long time1=millis();
  87. unsigned long time2=millis();
  88. unsigned long time3=millis();
  89. unsigned long time4=millis();

  90. //pm2.5的数值、AQI指数、灰尘数,相邻采样平均电压
  91. float dustValPM25,AQI,dustnumber,averagedustVal;

  92. //对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
  93. int xianshi=0;

  94. boolean isPressed = 0;  //针对按起不放开的情况



  95. void setup(){
  96. Serial.begin(9600);

  97. sensors.begin(); //DS18B20所涉及的代码,开始检测?

  98. pinMode(ledPower,OUTPUT);//开启粉尘的控制端口

  99. /*74HC595所涉及的3个端口*/
  100. pinMode(latchPin, OUTPUT);
  101. pinMode(clockPin, OUTPUT);
  102. pinMode(dataPin, OUTPUT);


  103. }

  104. void loop(){

  105. //最初的3秒内获得mySensVals [0],第3秒的时候就可以计算averagedustVal
  106. if(!j){
  107.    /*粉尘头控制代码*/
  108. digitalWrite(ledPower,LOW); //开灯
  109. delayMicroseconds(delayTime);
  110. dustVal=analogRead(dustPin); //读电压
  111. delayMicroseconds(delayTime2);
  112. digitalWrite(ledPower,HIGH); //关灯
  113. delayMicroseconds(offTime);

  114. mySensVals [i]=dustVal;//把检测到的第一次电压塞给mySensVals [1]
  115. i=!i;//i值反转
  116. j=1;//不再执行这个程序

  117.   }


  118. /*粉尘头取得的粉尘对应电压dustVal,每3秒循环一次*/

  119. if (millis() - time1 > 3000){
  120. time1=millis();

  121. /*粉尘头控制代码*/
  122. digitalWrite(ledPower,LOW); //开灯
  123. delayMicroseconds(delayTime);
  124. dustVal=analogRead(dustPin); //读电压
  125. delayMicroseconds(delayTime2);
  126. digitalWrite(ledPower,HIGH); //关灯

  127. /*邻采样平均averagedustVal的计算*/
  128. mySensVals [i]=dustVal;//把检测到的第一次电压塞给mySensVals [1]
  129. i=!i;//i值反转
  130. averagedustVal=(mySensVals [0]+mySensVals [1])*0.5;//计算平均电压


  131. /*计算0.01 cubic feet的颗粒数:(v-0.0356)X120000
  132. 对于电压低于8个单位的用线性,搞定值以下颗粒数为负数的情况*/

  133. if(averagedustVal>8)dustnumber=(averagedustVal*5/1024-0.0356)*120000;
  134. else dustnumber=averagedustVal*52;


  135. /*计算pm2.5的数值 电压阀值以上用:(v*0.172-0.0999)*1000,阀值以下用线性,参考国外帖子,认为输出最低17,对应粉尘5000*/

  136. //0.9V【184.5】线性pm:电压单位*0.298373984进行计算,依据为手册上无灰尘也有0.9V的电压
  137. //0.78V【161】线性pm:电压单位*0.21931677行计算,颗粒数降低数/粉尘降低数值最大值
  138. //0.69V【142】线性pm:电压单位*0.136338028行计算,颗粒数/粉尘值增速加快速上升
  139. //((averagedustVal*5/1024)*0.172-0.0999)*1000公式实质是0.83984375*averagedustVal-99.9

  140. if(averagedustVal>184.5)dustValPM25=0.83984375*averagedustVal-99.9;
  141. else dustValPM25=averagedustVal*0.298373984;


  142. /*AQI的计算,美国标准*/

  143. if(dustValPM25<15.4) AQI=(50-0)/(15.4-0)*(dustValPM25-0)+0;
  144. else if(dustValPM25<40.4) AQI=(100-51)/(40.4-15.5)*(dustValPM25-15.5)+51;
  145. else if(dustValPM25<65.4) AQI=(150-101)/(65.4-40.5)*(dustValPM25-40.5)+101;
  146. else if(dustValPM25<150.4) AQI=(200-151)/(150.4-65.5)*(dustValPM25-65.5)+151;
  147. else if(dustValPM25<250.4) AQI=(300-201)/(250.4-150.5)*(dustValPM25-150.5)+201;
  148. else if(dustValPM25<350.4) AQI=(400-301)/(350.4-250.5)*(dustValPM25-250.5)+301;
  149. else AQI=(500-401)/(500.4-350.5)*(dustValPM25-350.5)+401;



  150. //sensors.requestTemperatures();

  151. Serial.print("dust number=");
  152. Serial.print(dustnumber);//粉尘颗粒数
  153. Serial.print("= averagedustVal=");
  154. Serial.print(averagedustVal);//平均电压
  155. Serial.print("= dustValPM25=");
  156. Serial.print(dustValPM25);//PM2.5
  157. Serial.print("=AQI=");
  158. Serial.print(AQI);//AQI数
  159. //Serial.print("=sensors.getTempCByIndex(0)=");
  160. //Serial.print(sensors.getTempCByIndex(0));//温度
  161. Serial.print("____________________=millis(0)=");
  162. Serial.print(millis());//
  163. Serial.print("=xianshi = ");
  164. Serial.println(xianshi);



  165. }



  166. //做一个保险,对应millis()溢出归零后,millis()<time1,则3秒检测一次循环终止的情况
  167. if (millis() < time1){
  168. time1=millis();
  169. i=0;//重置i的值
  170. j=0;//重置j的值
  171. }





  172. if(millis()-time2>500){ //每500ms扫描一次
  173. time2=millis();
  174. int xianshi2=analogRead(1);
  175. int col2=0;
  176. if(xianshi2>1000&&!isPressed){  //高电压+不是按着不放的情况
  177. for(int col=0;col<99;col++){
  178.   xianshi2=analogRead(1);
  179. if(xianshi2>1000)col2++; //防抖动的关键,实际测试,接vcc是100%都是大于1000的
  180. }
  181. }

  182. if(col2>95){  //99次有95次都高,就算是按下了切换
  183. xianshi++;
  184.   isPressed=1; //转换为按着不放的状态
  185. }



  186. }


  187. if(millis()-time3>500){
  188. time3=millis();
  189. int xianshi2=analogRead(1);
  190. int col2=0;
  191. if(isPressed){
  192. for(int col=0;col<99;col++){
  193.   xianshi2=analogRead(1);
  194. if(xianshi2<1000)col2++;
  195. }
  196. }

  197. if(col2>40){  //与上同理,鉴于插铜线抖动严重,认为99次内小于1000个单位的有40次以上就算放开了
  198.   isPressed=0;
  199. }


  200. }


  201.   //pm2.5、aqi、颗粒数、温度一共四态,所以用4取模
  202. xianshi=xianshi%4;


  203.   

  204.   //对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
  205.   if(xianshi==0) test=dustValPM25;
  206.   else if(xianshi==1) test=AQI;
  207.   else if(xianshi==2) test=dustnumber*0.001;
  208.   else  if(xianshi==3) {
  209.   
  210.   if(millis()-time4>3000){
  211. time4=millis();
  212.       sensors.requestTemperatures();
  213.           Serial.print("=sensors.getTempCByIndex(0)=");
  214. Serial.println(sensors.getTempCByIndex(0));//温度
  215. test=sensors.getTempCByIndex(0);
  216.           }

  217. }



  218.     /*计算任意数字(小于9999)各上是什么数字*/

  219.   
  220.     int test0=test*0.001;
  221.     int test1=test*0.01;
  222.     int test2=test*0.1;
  223.     int test3=test;




  224.    //test小数点左边有0位,4位数码管最高2位第一位不显,第二位为0
  225.   //(0.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  226.    if(test3==0){  
  227.    int test4=test*10;//十分位上的数字,如0.12的1
  228.    int test5=test*100-test4*10;//百分位上的数字,如0.12的2

  229.     digitalWrite(latchPin, LOW);
  230.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  231.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  232.     digitalWrite(latchPin, HIGH);

  233.     digitalWrite(latchPin, LOW);
  234.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  235.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  236.     digitalWrite(latchPin, HIGH);

  237.     digitalWrite(latchPin, LOW);
  238.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  239.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  240.     digitalWrite(latchPin, HIGH);

  241.     digitalWrite(latchPin, LOW);//加入小数点
  242.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  243.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  244.     digitalWrite(latchPin, HIGH);

  245.    }
  246.    //test小数点左边有1位,4位数码管最高1位第一位不显,第二位为test3
  247.    //(x.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  248.    else if(test2==0){  

  249.    int test4=test*10-test3*10;//十分位上的数字,如1.23的2
  250.    int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3

  251.     digitalWrite(latchPin, LOW);
  252.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  253.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  254.     digitalWrite(latchPin, HIGH);

  255.     digitalWrite(latchPin, LOW);
  256.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  257.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  258.     digitalWrite(latchPin, HIGH);

  259.     digitalWrite(latchPin, LOW);
  260.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  261.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test3]); //shift out lowbyte
  262.     digitalWrite(latchPin, HIGH);


  263.     digitalWrite(latchPin, LOW);//加入小数点
  264.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  265.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte     
  266.     digitalWrite(latchPin, HIGH);

  267.    }
  268.     //test小数点左边有2位,4位数码管最高1位第一位test2
  269.     //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
  270.    else if(test1==0){

  271.    int test4=test-test2*10;//个位上的数字,如12.34的2
  272.    int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
  273.    int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字  

  274.     digitalWrite(latchPin, LOW);
  275.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  276.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  277.     digitalWrite(latchPin, HIGH);

  278.     digitalWrite(latchPin, LOW);
  279.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  280.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  281.     digitalWrite(latchPin, HIGH);

  282.     digitalWrite(latchPin, LOW);
  283.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  284.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  285.     digitalWrite(latchPin, HIGH);


  286.     digitalWrite(latchPin, LOW);
  287.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  288.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test2]); //shift out lowbyte
  289.     digitalWrite(latchPin, HIGH);

  290.     digitalWrite(latchPin, LOW);//加入小数点
  291.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  292.     shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
  293.     digitalWrite(latchPin, HIGH);


  294.    }

  295. //test小数点左边有3位,如123.45,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位不显,第二位为test1
  296. //(xxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxx)数字口控制两片74HC595进而控制4位时钟数码管
  297. else if(test0==0){
  298.    int test4=test2-test1*10;//十位上的数字,如123.45的2
  299.    int test5=test3-test2*10;//个位上的数字,如123.45的3

  300.     digitalWrite(latchPin, LOW);
  301.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  302.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  303.     digitalWrite(latchPin, HIGH);

  304.     digitalWrite(latchPin, LOW);
  305.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  306.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  307.     digitalWrite(latchPin, HIGH);

  308.     digitalWrite(latchPin, LOW);
  309.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  310.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test1]); //shift out lowbyte
  311.     digitalWrite(latchPin, HIGH);

  312.    }

  313.    //test小数点左边有3位,如1234,因为只有4位时钟数码管,所以只显示前3位,最高1位第一位test0
  314. //(xxxx.x的情况,时钟数码管只有中间有小数点,所以变成了xxxx)数字口控制两片74HC595进而控制4位时钟数码管
  315. else {
  316.    int test4=test2-test1*10;//十位上的数字,如1234的3
  317.    int test5=test-test2*10;//个位上的数字,如1234的4
  318.    int test6=test1-test0*10;//百位上的数字,如1234的2

  319.     digitalWrite(latchPin, LOW);
  320.     shiftOut(dataPin, clockPin, MSBFIRST, DIG4[xianshi]); //shift out highbyte
  321.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test5]); //shift out lowbyte
  322.     digitalWrite(latchPin, HIGH);

  323.     digitalWrite(latchPin, LOW);
  324.     shiftOut(dataPin, clockPin, MSBFIRST, DIG3[xianshi]); //shift out highbyte
  325.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test4]); //shift out lowbyte
  326.     digitalWrite(latchPin, HIGH);

  327.     digitalWrite(latchPin, LOW);
  328.     shiftOut(dataPin, clockPin, MSBFIRST, DIG2[xianshi]); //shift out highbyte
  329.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test6]); //shift out lowbyte
  330.     digitalWrite(latchPin, HIGH);

  331.         digitalWrite(latchPin, LOW);
  332.     shiftOut(dataPin, clockPin, MSBFIRST, DIG1[xianshi]); //shift out highbyte
  333.     shiftOut(dataPin, clockPin, MSBFIRST,sequence[test0]); //shift out lowbyte
  334.     digitalWrite(latchPin, HIGH);

  335.    }






  336.    /*计算任意数字(小于9999)各上是什么数字--------------------end*/










  337. }
复制代码
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-24 21:24 , Processed in 0.058652 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表