【发布时间】:2019-07-10 20:34:08
【问题描述】:
您好,我想知道为什么这段代码不起作用,因为编码器正在 100% 工作,而且我确信应该执行读取部分的代码块也能正常工作,请检查代码如果可以的话,我猜一定是某种非常愚蠢的错误.. 或者 arduino uno 是否有可能无法读取这么多引脚?这是代码
问题是由 getTemperature 函数引起的
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>
#define LDR A0
#define Fan 3
#define ONE_WIRE_BUS 2
#define BACKLIGHT 5
#define outputA 6
#define outputB 7
LiquidCrystal lcd(13, 12, 11, 10, 9, 8);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
float temperature = 0;
int start = 0 , start1 = 0;
unsigned long timer = 0;
unsigned long tx;
int counter = 0;
int aState, aLastState;
void setup(void)
{
Serial.begin(9600);
sensors.begin();
lcd.begin(16, 2);
pinMode(Fan , OUTPUT);
pinMode(A1,INPUT);
pinMode(BACKLIGHT,OUTPUT);
pinMode(4,INPUT_PULLUP);
setEncoder();
}
boolean isMin=true;
int temp1=4,temp2=15;
long pressed=millis();
void loop(void)
{
encoderRead();
getTemperature();
if(digitalRead(4)==LOW&&millis()-pressed>=1000){
isMin = !isMin;
pressed=millis();
tx=millis();
}
if(isMin){
//temp2 = map(counter , 0 , 100 , 1 , 60); //For setting 15 min time from range of 1-60 minutes
//tx=millis();
}else{
//temp1 = map(counter , 0 , 100 , 1 , 24); //For setting 5 hour time from range of 1-24 hour
//tx=millis();
}
String s = "HODINY: "+String(temp1)+"\nMINUTY: "+String(temp2);
Serial.println(s);
Serial.println(counter);
String t1 , t2;
if (temp1 < 10)
t1 = " " + String(temp1);
else
t1 = String(temp1);
if (temp2 < 10)
t2 = " " + String(temp2);
else
t2 = String(temp2);
if (millis() - tx < 600000) { //LCD displays stops every 10 minutes (600000milli seconds)
lcd.setCursor(0, 0);
lcd.print("Temp: " + String(temperature));
lcd.setCursor(0, 1);
lcd.print("T1: " + String(t1) + " H T2: " + String(t2) + " M");
digitalWrite(BACKLIGHT,HIGH);
}
else
digitalWrite(BACKLIGHT,LOW); //No data on display
//1. LDR - detects LIGHTS ON (daytime)
if (analogRead(LDR) >= 700 && start == 0) { //If it is day time
start = 1; //Set start (day) as 1
start1 = 0; //Set start1 (night) as 0
timer = millis(); //Reset timer
digitalWrite(Fan , HIGH); //Arduino has FANS OFF
//Serial.println("ZACAL SOM CAST JEDNA");
}
//1. LDR - detects LIGHTS OFF (night time)
else if (analogRead(LDR) <700 && start1 == 0) { //If it is night time
start = 0; //Set start (day) as 0
start1 = 1; //Set start1 (night) as 1
timer = millis(); //Reset timer
digitalWrite(Fan , LOW); //Turn ON Fan When nite time is detected Arduino has FANS ON
//Serial.println("ZACAL SOM CAST DVA");
}
//DAYTIME PROGRAM
if (start == 1) {
digitalWrite(Fan , HIGH); //2. Arduino has FANS OFF and waits for temp to reach >90 deg (temperature rises during daytime)
getTemperature(); //3. Once >90 deg, Arduino runs "Timer A" for 15 minutes (set by pot #A)
//Serial.println(temperature);
if (temperature >= 90) //If temperature is greater then 90
{
start = 2; //Go to step 2
timer = millis(); //Reset timer
}
}
else if (start == 2) { //Step2- If it is day time and temperature is greater 90 and timer is then 1-60 minutes set by pot
if((millis() - timer)/1000 <= temp2 * 60) { //Wait for timer 'A' to expire, Arduino has fans off
//Serial.println((millis() - timer)/1000);
digitalWrite(Fan , HIGH);
//Serial.println("CAKAM TIME A");
}else{
getTemperature();
digitalWrite(Fan,LOW);
start = 3; //Go to step 3
timer = millis(); //Reset timer
}
}
else if (start == 3 && (millis() - timer)/1000 <= temp1 * 3600) { //Step3-If it is day time and timer is less then 1-24 hour set by pot
getTemperature(); //5. Also immediately after 15 minute “Timer A” expires, Arduino runs “Timer B” that runs for 4 hours (set by pot#B).
if(temperature>=77){ //When temperature is more than 77deg turn on the FAN
getTemperature();
digitalWrite(Fan,LOW);
//Serial.println("ZNIZUJEM TIMER B");
}
else if (temperature < 77){ //If regular daytime temperature is less then 76 turn OFF FAN
digitalWrite(Fan , HIGH); //Turn OFF Fan
//Serial.println("STOJIM");
getTemperature();
}
//Serial.println("CAKAM TIMER B");
}
else if(start ==3) { //If it is day time and timer is greater then 1-24 hour set by pot
start = 1; //6. Once 4 hour “Timer B” expires and temperatures have been regulated at >78 <77 during this time, FAN OFF. LOOP TO #2 above (daytime program).
//Serial.println("ZNOVA ZACINAM DEN");
}
//NIGHT TIME PROGRAM
if (start1 == 1 && (millis() - timer)/1000 < temp1 * 3600) { //Step1-If it is night time and timer is less then 1-24 hour set by pot
getTemperature(); //3. Also, as soon as nite time is detected by LDR “Timer B” (set by pot #B) is to run for 4 hours.
if (temperature >= 70) { //If temperature is greater then 70 turn ON FAN
//Serial.println("ZNIZUJEM NOC");
digitalWrite(Fan , LOW); //Turn ON Fan
}
else if (temperature <= 69){ //If temperature is less= then 69 turn OFF FAN
//Serial.println("ZVYSUJEM NOC");
digitalWrite(Fan , HIGH); //Turn OFF Fan
}
}
else if (start1 == 1 && (millis() - timer)/1000 >= temp1 * 3600) { //If it is night and timer is greater then 1-24 hour set by pot
getTemperature();
if (temperature >= 66) { //Timer 'B' expired, FANs on until temp is lower than 66deg.
//Serial.println("KONIEC BCKA IDEM CAKAT NA MENEJ AKO 66");
digitalWrite(Fan , LOW);
getTemperature();
}
//Once temperature is lower than 66deg = Arduino runs “Timer A” for 15 minutes (set by pot #A)
else if(temperature < 66){
digitalWrite(Fan , HIGH); //Turn OFF Fan
start1 = 3; //Go to step 2
//Serial.println("MENEJ AKO 66");
timer = millis(); //Reset timer
}
}
else if (start1 == 3 && (millis() - timer)/1000 > temp2 * 60) { //If it is night time and timer is greater then 1-60 minutes set by pot
//7. After “Timer A” expires, LOOP TO #2 (night time program)
start1 = 1; //Go to step 1 night time
timer = millis(); //Reset timer
//Serial.println("ZACINAM ZNOVA NOCICKU");
}
}
void getTemperature(){
sensors.requestTemperatures();
temperature = sensors.getTempFByIndex(0);
}
void encoderRead(){
aState = digitalRead(outputA);
if(aState != aLastState){
if(digitalRead(outputB)!=aState){
if(counter<=100){
counter++;
}
}else{
if(counter>=0){
counter--;
}
}
}
aLastState = aState;
}
void setEncoder(){
pinMode(outputA,INPUT);
pinMode(outputB,INPUT);
aLastState = digitalRead(outputA);
}
这是我测试过的代码,readigs 很好
#define outputA 6
#define outputB 7
int counter = 0;
int aState,aLastState;
void setup(void)
{
Serial.begin(9600);
pinMode(4,INPUT_PULLUP);
setEncoder();
}
void loop() {
encoderRead();
Serial.println(counter);
}
void encoderRead(){
aState = digitalRead(outputA);
if(aState != aLastState){
if(digitalRead(outputB)!=aState){
if(counter<=100){
counter++;
}
}else{
if(counter>=0){
counter--;
}
}
}
aLastState = aState;
}
void setEncoder(){
pinMode(outputA,INPUT);
pinMode(outputB,INPUT);
aLastState = digitalRead(outputA);
}
【问题讨论】:
-
缩减你的野心。备份您的代码并尝试使用越来越少的代码来重现错误,直到您减少返回有效代码的方式。错误很可能出现在最后被删除的代码中,而且需要解决的代码要少得多。使用minimal reproducible example 作为灵感。一般来说,从工作代码开始,缓慢而仔细地添加,测试每一个变化你很少会发现自己处于一个有一百行代码却不知道错误在哪里的位置,因为通常错误会出现或暴露于刚刚添加的代码..
-
现在我知道错误是由 getTemperature 函数引起的
-
如果代码很大并且做了很多事情,那么在调用编码器函数之间可能需要很长时间,并且您可能会丢失脉冲。在这种情况下,最好使用中断来读取编码器。这是脉冲足够短以至于中断是合理的地方之一。
-
我刚刚想通了,最后做了for循环,我总是调用encoderRead函数100次:D猜我得看看中断,谢谢你的提示