如何解决嵌入式C中的DHT11传感器和带AVR微控制器的ESP8266
我正在使用嵌入式C中的ATmega 2560开发用于DHT11传感器和ESP8266(AT命令)的固件。 以下是这两种设备的Embedded C的完整代码。
用于ESP8266的嵌入式C(nodemcu连接到Atmega2560的UART1)
// USART Receiver buffer
#define RX_BUFFER_SIZE_UART1 255
uint8_t Rx_Buffer_UART1[RX_BUFFER_SIZE_UART1]; // character array (buffer)
uint8_t RX_Wr_Index_UART1 =0; //index of next char to be put into the buffer // head
uint8_t RX_Rd_Index_UART1=0; //index of next char to be fetched from the buffer //tail
uint8_t RX_Counter_UART1=0; //a total count of characters in the buffer
uint8_t RX_No_of_byte_UART1=0;
bool RX_Buffer_Overflow_UART1; // This flag is set on USART Receiver // buffer overflow
char rx_byte;
ISR(USART1_RX_vect)
{
rx_byte = UDR1;
Rx_Buffer_UART1[RX_Wr_Index_UART1]= rx_byte; /* put received char in buffer */
if(++RX_Wr_Index_UART1 > RX_BUFFER_SIZE_UART1)
RX_Wr_Index_UART1 = 0;
if(++RX_Counter_UART1 > RX_BUFFER_SIZE_UART1) /* keep a character count */
{
/* overflow check.. */
RX_Counter_UART1 = RX_BUFFER_SIZE_UART1; /* if too many chars came */
RX_Buffer_Overflow_UART1 = 1; /* in before they could be used */
} /* that could cause an error!! */
RX_No_of_byte_UART1=RX_Counter_UART1 ;
//UART_TxChar0(rx_byte);
}
/* reading from interrupt buffer*/
char getchar_UART1() // <---> Serial.read()
{
char c;
c = Rx_Buffer_UART1[RX_Rd_Index_UART1]; /* get one from the buffer..*/
if(++RX_Rd_Index_UART1 > RX_BUFFER_SIZE_UART1) /* wrap the pointer */
RX_Rd_Index_UART1 = 0;
if(RX_Counter_UART1)
RX_Counter_UART1--; /* keep a count (buffer size) */
return c ;//return char *
//printString0("n \n ");
}
char RX_DATA_UART1[RX_BUFFER_SIZE_UART1];
void getstring_UART1()
{
printString0(" Number of characters received : ");
decimel0(RX_No_of_byte_UART1);
printString0("\n");
uint8_t x=0;
memset(RX_DATA_UART1,'\0',RX_BUFFER_SIZE_UART1);
while (RX_Counter_UART1)
{
RX_DATA_UART1[x]= getchar_UART1();
x++;
}
printString0(RX_DATA_UART1);
//_delay_ms(1000);
}
char* search_buffer(const char* search)
{
char* p;
int bufferlen = strlen((const char * )RX_DATA_UART1);
if(bufferlen < RX_BUFFER_SIZE_UART1)
p= strstr ((const char *)RX_DATA_UART1,search);
//printString0(p);
return (p);
}
int RFR_UART1(const char * rsp,unsigned int timeout)
{
unsigned long timeIn = millis(); // Timestamp coming into function
uint8_t received = 0;
memset(RX_DATA_UART1,RX_BUFFER_SIZE_UART1);
//printString0(" Number of characters received : ");
//decimel0(RX_No_of_byte_UART1);
//printString0("\n");
while (millis() - timeIn < timeout) // While we haven't timed out
{
if(RX_Counter_UART1)
{
RX_DATA_UART1[received]= getchar_UART1();
//decimel0(received);
//printString0(" ");
//UART_TxChar0(RX_DATA_UART1[received]);
//printString0("\n");
received++;
if(search_buffer(rsp)) return 1;
}
}
//printString0(RX_DATA_UART1);
if (received > 0) // If we received any characters
return 0; // Return unkown response error code
else // If we haven't received any characters
return 2; // Return the timeout error code
}
void send_command(const char * command)
{
printString1(command);
}
void esp8266_rst()
{
send_command("AT+RST\r\n");
int rsp = RFR_UART1("OK",4000);
if(rsp==1) printString0(RX_DATA_UART1);
}
int CWMODE=0;
void esp8266_getmode()
{
send_command("AT+CWMODE?\r\n");
int rsp = RFR_UART1("OK",1000);
if(rsp==1)
{
//printString0("command is successfully send\n");
char * p = strchr(RX_DATA_UART1,':');
if(p!=NULL)
{
char mode = *(p+1);
CWMODE= mode-48;
if(CWMODE==1) printString0("Station mode selected\n");
if(CWMODE==2) printString0("SoftAP mode selected\n");
if(CWMODE==3) printString0("SoftAP+Station mode selected\n");
}
}
else
{
//printString0("Error in receiving command (check the command) or timeout has happened\n");
//esp8266_rst();
printString0(RX_DATA_UART1);
}
}
void esp8266_connectiontype()
{
send_command("AT+CIPMUX?\r\n");
int rsp = RFR_UART1("OK",1000);
if(rsp==1)
{
// printString0("command is successfully send\n");
char * p = strchr(RX_DATA_UART1,':');
if(p!=NULL)
{
char mode = *(p+1);
int num = mode-48;
if(num==0) printString0("Single connection - configured as client\n");
if(num==1) printString0("multiple connection - configured as server\n");
}
}
else
{
// printString0("Error in receiving response (check the command) or timeout has happened\n");
printString0(RX_DATA_UART1);
}
}
void esp8266_setAP(const char * ssid,const char * pass)
{
char setAP[40];
char bua[35],buc[35];
sprintf(setAP,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pass);
send_command(setAP);
int rsp = RFR_UART1("OK",16000);
if(rsp==1)
{
printString0("WiFi is connected to :");
printString0(ssid);
printString0("\n");
}
else
{
printString0("Error in connecting to :");
printString0(ssid);
printString0("\n");
char * p = strstr(RX_DATA_UART1,"+CWJAP:");
if(p!=NULL)
{
p+= strlen("+CWJAP:");
char error_code = *p;
int num = error_code-48;
if(num==1) printString0("Connection timeout \n");
if(num==2) printString0("Wrong password \n");
if(num==3) printString0("cannot find the target AP\n");
if(num==4) printString0("connection failed \n");
}
}
}
void esp8266_getAP()
{
char ssid[20];
send_command("AT+CWJAP?\r\n");
int rsp = RFR_UART1("OK",1000);
if(rsp==1)
{
if (strstr(RX_DATA_UART1,"No AP") != NULL) printString0("No AP is connected\n");
char * p = strstr(RX_DATA_UART1,"+CWJAP:");
if(p!=NULL)
{
p += strlen("+CWJAP") +2;
char * q=strchr(p,'"');
strncpy(ssid,p,q-p);
printString0("Connected to Wifi:");
printString0(ssid);
printString0("\n");
}
}else
{
//printString0("Error in receiving response (check the command ) or timeout has happened\n");
printString0(RX_DATA_UART1);
}
}
void esp8266_disconnect()
{
send_command("AT+CWQAP\r\n");
//printString0("Sending \n");
int rsp = RFR_UART1("WIFI DISCONNECT",1000);
if(rsp==1) printString0("WIFI is disconnected \n");
if(rsp==0) printString0("WIFI is already disconnected \n");
}
void esp8266_IPadress()
{
send_command("AT+CIFSR\r\n");
int rsp = RFR_UART1("OK",1000);
char staip[20],stamac[20],apip[20],apmac[20];
memset(staip,sizeof(staip));
memset(stamac,sizeof(stamac));
memset(apip,sizeof(apip));
memset(apmac,sizeof(apmac));
while(rsp==1)
{
printString0("IP address is \n");
if(CWMODE==1) //if station mode is selected
{
//Station IP
char * p = strstr(RX_DATA_UART1,"+CIFSR:STAIP");
p += strlen("+CWJAP:STAIP")+2;
char * q=strchr(p,'"');
strncpy(staip,q-p);
printString0("IP address of Station is :");
printString0(staip);
// Station MAC
char * r = strstr(RX_DATA_UART1,"+CIFSR:STAMAC");
r += strlen("+CIFSR:STAMAC")+2;
char * s =strchr(r,'"');
strncpy(stamac,r,s-r);
printString0("\n Mac address of Station is :");
printString0(stamac);
break;
}
if(CWMODE==2)
{
// Soft AP IP
char * p = strstr(RX_DATA_UART1,"+CIFSR:APIP");
p += strlen("+CIFSR:APIP")+2;
char * q=strchr(p,'"');
strncpy(apip,q-p);
printString0("IP address of SoftAP is :");
printString0(apip);
// Soft AP MAC
char * r = strstr(RX_DATA_UART1,"+CIFSR:APMAC");
r += strlen("+CIFSR:APMAC")+2;
char * s =strchr(r,'"');
strncpy(apmac,s-r);
printString0("\n Mac address of SoftAP is :");
printString0(apmac);
break;
}
if(CWMODE==3) // Soft AP+Station
{
//Station IP
char * p = strstr(RX_DATA_UART1,q-p);
printString0("IP address of Station is :");
printString0(staip);
printString0("\n");
// Station MAC
char * r = strstr(RX_DATA_UART1,s-r);
printString0("Mac address of Station is :");
printString0(stamac);
printString0("\n");
// Soft AP IP
char * a = strstr(RX_DATA_UART1,"+CIFSR:APIP");
a += strlen("+CIFSR:APIP")+2;
char * b=strchr(a,a,b-a);
printString0("IP address of SoftAP is :");
printString0(apip);
printString0("\n");
// Soft AP MAC
char * c = strstr(RX_DATA_UART1,"+CIFSR:APMAC");
c += strlen("+CIFSR:APMAC")+2;
char * d =strchr(c,c,d-c);
printString0("Mac address of SoftAP is :");
printString0(apmac);
printString0("\n");
break;
}
}
}
void esp8266_listAP()
{
send_command("AT+CWLAP\r\n");
int rsp = RFR_UART1("OK",7000);
//printString0(RX_DATA_UART1);
//printString0("\n");
if(rsp==0)
{
printString0("WiFi networks near are: \n");
printString0(RX_DATA_UART1);
printString0("\n");
}else
printString0(RX_DATA_UART1);
}
void esp8266_initialise()
{
esp8266_getmode();
esp8266_connectiontype();
esp8266_getAP();
esp8266_setAP("JioFiber 2.4ghz","Mansi5481");
//esp8266_disconnect();
esp8266_listAP();
esp8266_IPadress();
//esp8266_rst();
}
DHT11的嵌入式C代码(传感器连接到PORTH-PH4:数字引脚7)
#define SET_BIT(byte,bit) (byte |= (1 << bit))
#define CLEAR_BIT(byte,bit) (byte &= ~(1 << bit))
#define IS_SET(byte,bit) ((byte) & (1<<bit))
// Function for sending Start signal
void dht11_init()
{
SET_BIT(DDRH,PH4);
CLEAR_BIT(PORTH,PH4); //----> Start Signal of 20ms
_delay_ms(20);
SET_BIT(PORTH,PH4);
_delay_us(40); // --> sensor getting ready: High for 40us
CLEAR_BIT(DDRH,PH4); // --> pin set as input to get sensor response
}
//Sensor response
int dht11_find_response()
{
//While sensor pull the pin low for 80us
if(!(IS_SET(PINH,PH4))) //first response signal is low
_delay_us(82); //While sensor pull the pin low for 80us(max-140)
else
return 1;
if(IS_SET(PINH,PH4)) //Second response signal is high
_delay_us(85); //While sensor pull the pin HIGH for 80us(max-140)
else
return 2;
}
// Getting Sensor data.. Using TIMER0-Normal mode for this purpose instaed of delay
// DHT11 data is stored in array of int type of size 5 : data[5]( In Binary form). Data[0]= Humidity //integral,Data[1] = humidity decimel,Data[2]= Temperature integral,Data[3] = Temperature decimel. //Data[4]= checksum
int dht11_receivedht(uint8_t* arr)
{
uint8_t data [5];
uint8_t check;
TCCR0B|= (1<<CS01); //clk/8: Time Period= 5*10^-7 and Timer clock frequency= 2000000MHZ
for (int z = 0; z < 5; ++z)
{
for(int j = 7; j >= 0; --j)
{
/* First there is always a 50µs low period */
TCNT0=0;
while(!IS_SET(PINH,PH4))
{
if(TCNT0 >= 120)
//to see if low signal is detected or not uncomment the nbelow 4 lines and remove semicolan from if
{
decimel0(TCNT0);
return 12;
//break;
}
}
TCNT0 = 0;
/* Then the data signal is sent. 26 to 28µs (ideally)
indicate a low bit,and around 70µs a high bit */
while(IS_SET(PINH,PH4))
{
if (TCNT0 >= 160 ) // data signal is high for max 71us (as for 0 it is 26-28us and for 1 it is 70us)
{//decimel0(TCNT0);
return 1; }
}
/* Store the value now so that the whole checking doesn't
move the TCNT0 forward by too much to make the data look
bad */
//cnt = TCNT0;
if ((TCNT0 >= 40) & (TCNT0 <= 70)) //20us to 35 us
{ CLEAR_BIT(data[z],j); //decimel0(TCNT0);printString0("\n");
}
else if ((TCNT0 >= 120) & (TCNT0 <= 160)) // 60us to 80us
{ SET_BIT(data[z],j); //printString0("\n");decimel0(TCNT0); printString0("\n");
}
else
{printString0("error 2\n"); decimel0(TCNT0); return 2;}
}
TCNT0=0;
}
check = (data[0] + data[1] + data[2] + data[3]) & 0xFF;
if (check != data[4]) return 3;
//bit0(data[2]);
for(int w = 0; w < 4; ++w)
{ arr[w] = data[w]; }
return 4;
}
现在主要在这里我已经提交了esp8266_initialise(),并且在循环中我仅调用了DHT11传感器功能,在这种情况下,我得到了准确的温度读数(通过读取r 2)。When esp8266_initialise is not called
int main(void)
{
init_millis(16000000UL); //frequency the atmega328p is running at
UART_Init0(); // Serial Monitor Baudrate of 9600
UART_Init1(); ///for esp baudrate is selected 115200
printString0("******************ESP8266 AT Commands firmware (using embedded C)*****************");
printString0("\n");
**//esp8266_initialise();**
sei();
uint8_t r[5]; // array to store DHT11 sensor readings
while(1)
{
**dht11_init();
dht11_find_response();
dht11_receivedht(r);**
decimel0(r[2]); (
printString0("\n");
}
}
现在,当我主要调用esp8266_initialise()并在循环中调用DHT11传感器功能时,在这种情况下,即使我读取r [5]的不同索引,DHT11传感器也给出相同的值,我得到的值相同值和预期的不同读数。 (通过阅读r 2,r [0]等)。when both esp8266_initialise() and dht11 sensor functions are called
int main(void)
{
init_millis(16000000UL); //frequency the atmega328p is running at
UART_Init0(); // Serial Monitor Baudrate of 9600
UART_Init1(); ///for esp baudrate is selected 115200
printString0("******************ESP8266 AT Commands firmware (using embedded C)*****************");
printString0("\n");
**esp8266_initialise();**
sei();
uint8_t r[5]; // array to store DHT11 sensor readings
while(1)
{
**dht11_init();
dht11_find_response();
dht11_receivedht(r);**
decimel0(r[2]); (
printString0("\n");
}
}
当我使用esp8266_initialize()调用传感器时,为什么DHT11传感器会给出不同且不需要的读数?我无法确定esp8266代码会影响DHT11的哪一部分,因为当我不致电esp8266_initialise时,我的DHT11会给出准确和正确的温度和湿度读数
我的假设
- 我已经在DHT11中使用TIMER0来记录 int dht11_receivedht(uint8_t arr) *中的数据,并在esp8266代码 int RFR_UART1(const char * rsp,无符号int超时),用于读取esp8266 AT指令对嵌入式C中的 milis函数的响应。因此,它们是否可以依赖于这两个。???
我知道问题似乎很冗长,但是其中大部分是代码。希望能得到良好的答复和建议
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。