嵌入式C中的DHT11传感器和带AVR微控制器的ESP8266

如何解决嵌入式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会给出准确和正确的温度和湿度读数

我的假设

  1. 我已经在DHT11中使用TIMER0来记录 int dht11_receivedht(uint8_t arr) *中的数据,并在esp8266代码 int RFR_UART1(const char * rsp,无符号int超时),用于读取esp8266 AT指令对嵌入式C中的 milis函数的响应。因此,它们是否可以依赖于这两个。???

我知道问题似乎很冗长,但是其中大部分是代码。希望能得到良好的答复和建议

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-