I am developing firmware for the DHT11 sensor and ESP8266 (AT commands) with ATmega 2560 in embedded C.
Below is the full code in Embedded C for both the devices.
For ESP8266 In Embedded C (nodemcu connected to UART1 of Atmega2560)
// 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, '\0',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, '\0',sizeof(staip)); memset(stamac, '\0',sizeof(stamac)); memset(apip, '\0',sizeof(apip)); memset(apmac, '\0',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,p,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,p,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,r,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,"+CIFSR:STAIP"); p += strlen("+CWJAP:STAIP")+2; char * q=strchr(p,'"'); strncpy(staip,p,q-p); printString0("IP address of Station is :"); printString0(staip); printString0("\n"); // 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("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,'"'); strncpy(apip,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,'"'); strncpy(apmac,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(); }
Embedded C code of DHT11(Sensor connected at PORTH-PH4: digital pin 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; }
Now here in main i have Commited the esp8266_initialise() and in loop i have only called DHT11 sensor funtions, In this case i get my exact temperature reading ( by reading r[2]).[When esp8266_initialise is not called ][1]
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"); } }
Now when in main i have called the the esp8266_initialise() and in loop i have also called DHT11 sensor funtions, In this case DHT11 sensor is giving same values even if i read different index of r[5], i get same values and different readings then expected. ( by reading r[2], r[0]etc).[when both esp8266_initialise() and dht11 sensor functions are called][2]
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"); } }
**Why DHT11 sensor is giving different and unwanted readings when i call the sensor with esp8266_initialize()? I am not able to figure out what part of DHT11 is getting affected by esp8266 code.As when i don't call esp8266_initialise then my DHT11 is giving exact and proper readings of temperature and humidity**
My Assumptions:
1) I have used TIMER0 in DHT11 for recording the data in **int dht11_receivedht(uint8_t* arr)** and used TIMER1 in esp8266 code **int RFR_UART1(const char * rsp, unsigned int timeout)** for reading the response of esp8266 AT commands for the **milis function** in embedded C. So can their be any dependence of these Two.???
[1]: https://i.stack.imgur.com/5aHfU.png
[2]: https://i.stack.imgur.com/BwBlg.png
I Know question seems to be quite lengthy, But Most part of it is code.Hoping to get good response and suggestions