hi55234 发表于 2013-11-28 22:03:57

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

本帖最后由 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/forum.php?mod=viewthread&tid=4848),顿时凌乱了:
http://image.geek-workshop.com/forum/201306/03/205645x2q7092dmw2q0qjd.png

即:
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


i7456 发表于 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;

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

lariver 发表于 2013-11-29 16:05:45

楼主,可以看这一篇非常详细的设置教程,Arduino+GP2Y1010空气质量监测方案,http://tuding.iego.cn:8001/archives/98

hi55234 发表于 2013-12-1 19:38:40

昨天淘宝买的,CP2102和pro mini到了,手工极差,却很有毅力的菜鸟开始干活

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





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

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

hi55234 发表于 2013-12-1 19:53:09

焊完了CP2102模块 开始焊pro mini,确实很小,对于俺这种苦手来说,真心伤不起····


背面一览


其实这货长这样子:


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

hi55234 发表于 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,怎么接,本菜鸟傻傻分不清楚,得,倒过来试试,再次下载:


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

hi55234 发表于 2013-12-1 20:31:34

附上链接图一张:


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

hi55234 发表于 2013-12-2 15:22:04

本帖最后由 hi55234 于 2013-12-20 13:47 编辑

hi55234 发表于 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);

}

hi55234 发表于 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("----");
}



}


hi55234 发表于 2013-12-2 17:21:51

本帖最后由 hi55234 于 2013-12-31 15:03 编辑



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


void setup() {               
Serial.begin (9600);
}

// the loop routine runs over and over again forever:
void loop() {
int a,b;
int *pointer_1, *pointer_2;
a=100;b=10;
pointer_1=&a;
pointer_2=&b;

delay (1000);
   Serial.print ("a=");
   Serial.println (a);
    Serial.print ("b=");
   Serial.println (b);
      Serial.print ("*pointer_1=");
   Serial.println (*pointer_1);
    Serial.print ("*pointer_2=");
   Serial.println (*pointer_2);
}

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

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

void setup() {               
Serial.begin (9600);
}

// the loop routine runs over and over again forever:
void loop() {
pa=xx;
pa2=&xx;

delay (1000);

Serial.println (*pa);
   Serial.println (*(pa+1));
   Serial.println (*(pa+2));
    Serial.println (*(pa+3));
    Serial.println (*(pa+4));


Serial.println (*pa2);
   Serial.println (*(pa2+1));
   Serial.println (*(pa2+2));
    Serial.println (*(pa2+3));
    Serial.println (*(pa2+4));
   
       Serial.println ("-----------------");
}

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

const char *pa = "arduino";

void setup() {               
Serial.begin (9600);
}


void loop() {

delay (1000);

Serial.println (*pa);
   Serial.println (*(pa+1));
   Serial.println (*(pa+2));
    Serial.println (*(pa+3));
    Serial.println (*(pa+4));
   Serial.println (*(pa+5));
   Serial.println (*(pa+6));

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

       Serial.print (*pa);
   Serial.print (*(pa+1));
   Serial.print (*(pa+2));
    Serial.print (*(pa+3));
    Serial.print (*(pa+4));
   Serial.print (*(pa+5));
   Serial.println (*(pa+6));
      Serial.println ("-----------------");
}

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

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

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

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


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

void setup() {               
Serial.begin (9600);
}

// the loop routine runs over and over again forever:
void loop() {
pa=xx;
pa2=yy;
pa3=zz;
pa4=nn;
int x=pa2-pa;
int y=pa3-pa;
int z=pa4-pa;
delay (1000);
Serial.println (x);
Serial.println (y);
Serial.println (z);
       Serial.println ("-----------------");
}

-----------------------------------------------
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,*(p+i)与*(a+i)等价

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



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

void setup() {               
Serial.begin (9600);
}

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


Serial.println (*xx);
Serial.println (*pa);
Serial.println (*(xx+1));
Serial.println (*(pa+1));
       Serial.println ("-----------------");
       delay (1000);
}

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

void setup() {               
Serial.begin (9600);
}


void loop() {
int a,i;
for(i=0;i<10;i++)
    a=i;
for(i=0;i<10;i++)
Serial.print (a);
Serial.print (",");

Serial.println ();
delay (1000);
Serial.println ("-----------------1");

int aa;
for(i=0;i<10;i++)
    *(aa+i)=i;
for(i=0;i<10;i++)
Serial.print (*(aa+i));
Serial.print (",");

Serial.println ();
delay (1000);
Serial.println ("-----------------2");

int aaa,*p;
p=aaa;
for(i=0;i<10;i++)
    *(p+i)=i;
for(i=0;i<10;i++)
Serial.print (*(p+i));
Serial.print (",");

Serial.println ();
delay (1000);
Serial.println ("-----------------3");

}

hi55234 发表于 2013-12-3 17:00:23

本帖最后由 hi55234 于 2013-12-16 16:38 编辑

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

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


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

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

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


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




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


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

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

}

void loop(){

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

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

}


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

if (millis() - time1 > 3000){
time1=millis();

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

/*邻采样平均averagedustVal的计算*/
mySensVals =dustVal;//把检测到的第一次电压塞给mySensVals
i=!i;//i值反转
averagedustVal=(mySensVals +mySensVals )*0.5;//计算平均电压



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

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


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

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

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


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

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




}



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



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

float test=dustValPM25;
    int test1=test*0.01;
    int test2=test*0.1;
    int test3=test;
       
   

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFE); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

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

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xF7); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

   
   }

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFE); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFD); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, 0xFB); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   }
   
   
   


   


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



}

hi55234 发表于 2013-12-15 21:54:46

本帖最后由 hi55234 于 2013-12-19 22:33 编辑

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


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

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

Pro mini~~~GP2Y1010AU0F:
5V-150欧-(V-LED)
5V-150欧—Vcc
5V-150欧-220uF-GND
GND-(LED-GND)
GND-(S-GND)
Pin2-LED
A0-Vo

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

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


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

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

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

*/



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

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

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


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

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

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


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

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

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



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

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

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

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


}

void loop(){

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

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

}


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

if (millis() - time1 > 3000){
time1=millis();

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

/*邻采样平均averagedustVal的计算*/
mySensVals =dustVal;//把检测到的第一次电压塞给mySensVals
i=!i;//i值反转
averagedustVal=(mySensVals +mySensVals )*0.5;//计算平均电压


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

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


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

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

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


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

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



//sensors.requestTemperatures();

Serial.print("dust number=");
Serial.print(dustnumber);//粉尘颗粒数
Serial.print("= averagedustVal=");
Serial.print(averagedustVal);//平均电压
Serial.print("= dustValPM25=");
Serial.print(dustValPM25);//PM2.5
Serial.print("=AQI=");
Serial.print(AQI);//AQI数
//Serial.print("=sensors.getTempCByIndex(0)=");
//Serial.print(sensors.getTempCByIndex(0));//温度
Serial.print("____________________=millis(0)=");
Serial.println(millis());//

xianshi=(xianshi+1)%4;

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

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

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

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

}



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





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

float test;

//对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
if(xianshi==0) test=dustValPM25;
else if(xianshi==1) test=AQI;
else if(xianshi==2) test=dustnumber*0.001;


    int test1=test*0.01;
    int test2=test*0.1;
    int test3=test;
       
   

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

   int test4=test*10-test3*10;//十分位上的数字,如1.23的2
   int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte   
    digitalWrite(latchPin, HIGH);
   
   }
    //test小数点左边有2位,4位数码管最高1位第一位test2
    //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
   else if(test1==0){
   
   int test4=test-test2*10;//个位上的数字,如12.34的2
   int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
   int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字
       
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   
   }

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   }
   
   
   


   


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


if(xianshi==3) {
      sensors.requestTemperatures();
    test=sensors.getTempCByIndex(0);
Serial.print("=sensors.getTempCByIndex(0)=");
Serial.println(sensors.getTempCByIndex(0));//温度
    for(int col=0;col<2499;col++){
   


    int test1=test*0.01;
    int test2=test*0.1;
    int test3=test;
       
   

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

   int test4=test*10-test3*10;//十分位上的数字,如1.23的2
   int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte   
    digitalWrite(latchPin, HIGH);
   
   }
    //test小数点左边有2位,4位数码管最高1位第一位test2
    //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
   else if(test1==0){
   
   int test4=test-test2*10;//个位上的数字,如12.34的2
   int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
   int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字
       
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   
   }

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   }
      
    }


}

}

hi55234 发表于 2013-12-19 22:18:16

本帖最后由 hi55234 于 2013-12-19 22:30 编辑

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

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

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

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


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

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


unsigned long time1=millis();
unsigned long time2=millis();
unsigned long time3=millis();

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



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


}


void loop(){




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

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

//打印是调试用的,实际程序不需要
Serial.print("xianshi2 = ");
Serial.println(xianshi2);



}


if(millis()-time3>500){
time3=millis();
int xianshi3=analogRead(1);
int col2=0;
if(isPressed){
for(int col=0;col<99;col++){
xianshi3=analogRead(1);
if(xianshi3<1000)col2++;
}
}

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


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






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

float test=xianshi;



    int test0=test*0.001;
    int test1=test*0.01;
    int test2=test*0.1;
    int test3=test;
       
   

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

   int test4=test*10-test3*10;//十分位上的数字,如1.23的2
   int test5=test*100-test3*100-test4*10;//百分位上的数字,如1.23的3
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte   
    digitalWrite(latchPin, HIGH);
   
   }
    //test小数点左边有2位,4位数码管最高1位第一位test2
    //(xx.xx的情况)数字口控制两片74HC595进而控制4位时钟数码管
   else if(test1==0){
   
   int test4=test-test2*10;//个位上的数字,如12.34的2
   int test5=test*10-test2*100-test4*10;//十分位上的数字,如12.34的3
   int test6=test*100-test2*1000-test4*100-test5*10;//百分位上的数字
       
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   
   }

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
   
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);
       
        digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   }
   


   


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







}

hi55234 发表于 2013-12-20 20:33:49

本帖最后由 hi55234 于 2013-12-20 20:39 编辑

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

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


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

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

Pro mini~~~GP2Y1010AU0F:
5V-150欧-(V-LED)
5V-150欧—Vcc
5V-150欧-220uF-GND
GND-(LED-GND)
GND-(S-GND)
Pin2-LED
A0-Vo

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

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


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

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

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

*/



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

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

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


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

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

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

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


//引入millis()来控制循环
unsigned long time1=millis();
unsigned long time2=millis();
unsigned long time3=millis();
unsigned long time4=millis();

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

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

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



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

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

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

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


}

void loop(){

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

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

}


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

if (millis() - time1 > 3000){
time1=millis();

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

/*邻采样平均averagedustVal的计算*/
mySensVals =dustVal;//把检测到的第一次电压塞给mySensVals
i=!i;//i值反转
averagedustVal=(mySensVals +mySensVals )*0.5;//计算平均电压


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

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


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

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

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


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

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



//sensors.requestTemperatures();

Serial.print("dust number=");
Serial.print(dustnumber);//粉尘颗粒数
Serial.print("= averagedustVal=");
Serial.print(averagedustVal);//平均电压
Serial.print("= dustValPM25=");
Serial.print(dustValPM25);//PM2.5
Serial.print("=AQI=");
Serial.print(AQI);//AQI数
//Serial.print("=sensors.getTempCByIndex(0)=");
//Serial.print(sensors.getTempCByIndex(0));//温度
Serial.print("____________________=millis(0)=");
Serial.print(millis());//
Serial.print("=xianshi = ");
Serial.println(xianshi);



}



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





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

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



}


if(millis()-time3>500){
time3=millis();
int xianshi2=analogRead(1);
int col2=0;
if(isPressed){
for(int col=0;col<99;col++){
xianshi2=analogRead(1);
if(xianshi2<1000)col2++;
}
}

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


}


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




//对显示的值究竟是PM2.5,AQI,粉尘颗粒数,温度进行切换
if(xianshi==0) test=dustValPM25;
else if(xianshi==1) test=AQI;
else if(xianshi==2) test=dustnumber*0.001;
elseif(xianshi==3) {

if(millis()-time4>3000){
time4=millis();
      sensors.requestTemperatures();
          Serial.print("=sensors.getTempCByIndex(0)=");
Serial.println(sensors.getTempCByIndex(0));//温度
test=sensors.getTempCByIndex(0);
          }

}



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


    int test0=test*0.001;
    int test1=test*0.01;
    int test2=test*0.1;
    int test3=test;




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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

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

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte   
    digitalWrite(latchPin, HIGH);

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

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);//加入小数点
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,0x80); //shift out lowbyte
    digitalWrite(latchPin, HIGH);


   }

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   }

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

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG4); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG3); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG2); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

      digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, MSBFIRST, DIG1); //shift out highbyte
    shiftOut(dataPin, clockPin, MSBFIRST,sequence); //shift out lowbyte
    digitalWrite(latchPin, HIGH);

   }






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










}
页: [1] 2
查看完整版本: 菜鸟求助,GP2Y1010AU0F与Arduino怎么连接?