菜鸟求助,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
(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;
人家有说明的,接线的说明和数据手册是对应得起来的。 楼主,可以看这一篇非常详细的设置教程,Arduino+GP2Y1010空气质量监测方案,http://tuding.iego.cn:8001/archives/98 昨天淘宝买的,CP2102和pro mini到了,手工极差,却很有毅力的菜鸟开始干活
前前后后的差不多用了6小时,就成了这副模样:
除开焊点与排针外,感觉工艺还可以~~~
短接RXD与TXD,运行USB-TTL测试工具,蒙苍天垂怜,一切正常 焊完了CP2102模块 开始焊pro mini,确实很小,对于俺这种苦手来说,真心伤不起····
背面一览
其实这货长这样子:
PS:为啥有的针没有焊好呢?因为焊好了,经过多次插拔与摔打,就成了这样子,好在不影响啥~~~
PS2:就是这个不影响,让俺从昨晚10点一直折腾到今天18:00······ 本帖最后由 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,怎么接,本菜鸟傻傻分不清楚,得,倒过来试试,再次下载:
泪奔啊,终于下载成功~~~ 附上链接图一张:
至于手动按REST:通过万用表的电压变化,个人的理解是,按下rest,pro mini的rest电压发生变化,以此通知cp2102已经做好准备,可以传输数据了,按得时机那网友的话来说就是出现:使用xx字节,xx字节可用的提示的时候········
本帖最后由 hi55234 于 2013-12-20 13:47 编辑
本帖最后由 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: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-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-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-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: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: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