arre 0 Posted April 7, 2014 Share Posted April 7, 2014 Hi, Thought I'd share a small code snippit I built to interface succesfully with the DHT11 temp & humidity sensor (4 bucks on ebay): #include "inc/hw_types.h" #include "inc/hw_memmap.h" #include "driverlib/sysctl.h" #include "driverlib/pin_map.h" #include "driverlib/gpio.h" #include "driverlib/systick.h" #include "driverlib/timer.h" int temp; int humidity; inline long WaitUntilPinState(int clockMhz, long pinbase, long pin, long timerbase, long timer, int previousstate, int usec) { // Debounce really not needed unless you have huge noise, but just in case (the processor is fast enough) #define DEBOUNCEMATCHES 5 long timermax; long timerval; int matches = 0; TimerDisable(timerbase, timer); TimerConfigure(timerbase, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT); TimerLoadSet(timerbase, timer, usec*clockMhz); timermax = TimerValueGet(timerbase, timer); timerval = timermax; TimerEnable(timerbase, timer); while(matches < DEBOUNCEMATCHES){ /* Wait for DHT to pull down */ if( GPIOPinRead(pinbase, pin) > 0 != previousstate > 0) { matches++; } else { matches = 0; } timerval = TimerValueGet(timerbase, timer); if(!timerval) timerval = 1; /* make sure we never return 0 by mistake */ if (timerval==timermax){ return 0; } } return timerval; } int ReadDHT() { // bit buffers & timeout char bitcount; char byte; char bits[5] = {0,0,0,0,0}; unsigned int bitints[6]; long timerval; int clockMhz; #define MY_PIN_PERIPH SYSCTL_PERIPH_GPIOE #define MY_PIN_PORTBASE GPIO_PORTE_BASE #define MY_PINNR GPIO_PIN_1 #define MY_TIMER_PERIPH SYSCTL_PERIPH_TIMER0 #define MY_TIMERBASE TIMER0_BASE #define MY_TIMER TIMER_B clockMhz = SysCtlClockGet() / 1000000; /* Configure hardware counter to check how long we are looping */ SysCtlPeripheralEnable(MY_TIMER_PERIPH); TimerConfigure(MY_TIMERBASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT); // request reading SysCtlPeripheralEnable(MY_PIN_PERIPH); GPIOPinTypeGPIOOutput(MY_PIN_PORTBASE, MY_PINNR); GPIOPinWrite(MY_PIN_PORTBASE, MY_PINNR, 0x0); // #loops = loops_per_us*time_in_us = time in us * loops/us = time_in_us *(clockfreq/10000000) SysCtlDelay(30000*clockMhz); // -> 30 ms /////// SET PIN HIGH (putting it to input will do) GPIOPinTypeGPIOInput(MY_PIN_PORTBASE, MY_PINNR); SysCtlDelay(10*clockMhz); /* Wait for DHT pull down */ if(!WaitUntilPinState(clockMhz,MY_PIN_PORTBASE,MY_PINNR,MY_TIMERBASE,MY_TIMER,1,50)) return 0; /* Wait for dummy up */ if(!WaitUntilPinState(clockMhz,MY_PIN_PORTBASE,MY_PINNR,MY_TIMERBASE,MY_TIMER,0,90)) return 0; /* Wait for dummy down */ if(!WaitUntilPinState(clockMhz,MY_PIN_PORTBASE,MY_PINNR,MY_TIMERBASE,MY_TIMER,1,90)) return 0; // start receiving 40 bits char i; bitcount = 7; byte = 0; for (i=0; i < 40; i++) { /* Wait for pull up */ if(!WaitUntilPinState(clockMhz,MY_PIN_PORTBASE,MY_PINNR,MY_TIMERBASE,MY_TIMER,0,60)) return 0; /* Wait for pull down and count */ timerval = WaitUntilPinState(clockMhz,MY_PIN_PORTBASE,MY_PINNR,MY_TIMERBASE,MY_TIMER,1,90); if(!timerval) return 0; if (timerval < 40*clockMhz) bits[byte] |= (1 << bitcount); if (bitcount == 0) { bitcount = 7; byte++; }else{ bitcount--; } } // checksum /* Little Endian */ bitints[0] = ((unsigned int) bits[0] & (0x000000FF)); bitints[1] = ((unsigned int) bits[1] & (0x000000FF)); bitints[2] = ((unsigned int) bits[2] & (0x000000FF)); bitints[3] = ((unsigned int) bits[3] & (0x000000FF)); bitints[4] = ((unsigned int) bits[4] & (0x000000FF)); if(((bitints[0] + bitints[1] + bitints[2] + bitints[3]) & (0x000000FF)) == bitints[4]){ temp = bitints[2]; humidity = bitints[0]; return 1; }else{ return 0; } } int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ); //Configure the system clock to 40MHz if(ReadDHT() == 0) { //Failed result } else { // Stored in temp and humidity } } bluehash and dubnet 2 Quote Link to post Share on other sites
bluehash 1,581 Posted April 13, 2014 Share Posted April 13, 2014 @@arre Thanks for sharing! Quote Link to post Share on other sites
aureliokta 0 Posted August 19, 2014 Share Posted August 19, 2014 I´am using TM4C1294XL and I wasn't able to communicate, so I changed your code a little bit and is working, its not very polished but works.... So here is the code to EK launchpad. #include <stdint.h> #include <stdbool.h> #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "driverlib/gpio.h" #include "drivers/pinout.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/timer.h" #include "utils/uartstdio.h" int temp; int humidity; uint32_t g_ui32SysClock; #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif void ConfigureUART(void) { ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); ROM_GPIOPinConfigure(GPIO_PA0_U0RX); ROM_GPIOPinConfigure(GPIO_PA1_U0TX); ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig(0, 115200, g_ui32SysClock); } int ReadDHT() { // bit buffers & timeout char bitcount; char byte; char bits[5] = {0,0,0,0,0}; unsigned int bitints[6]; long timerval; int clockMhz; unsigned int loopCnt = 10000; #define MY_PIN_PERIPH SYSCTL_PERIPH_GPIOM #define MY_PIN_PORTBASE GPIO_PORTM_BASE #define MY_PINNR GPIO_PIN_6 #define MY_TIMER_PERIPH SYSCTL_PERIPH_TIMER0 #define MY_TIMERBASE TIMER0_BASE #define MY_TIMER TIMER_B SysCtlPeripheralEnable(MY_TIMER_PERIPH); TimerConfigure(MY_TIMERBASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT); SysCtlPeripheralEnable(MY_PIN_PERIPH); ROM_GPIOPinTypeGPIOOutput(MY_PIN_PORTBASE, MY_PINNR); GPIOPinWrite(MY_PIN_PORTBASE, MY_PINNR, 0x0); // #loops = loops_per_us*time_in_us = time in us * loops/us = time_in_us *(clockfreq/10000000) SysCtlDelay((g_ui32SysClock/3)/30 ); // -> 30 ms ROM_GPIOPinTypeGPIOInput(MY_PIN_PORTBASE, MY_PINNR); loopCnt = g_ui32SysClock/100; while(GPIOPinRead(MY_PIN_PORTBASE, MY_PINNR)) { loopCnt = loopCnt -1; if (loopCnt == 0) return 0; } loopCnt = g_ui32SysClock/100; while(!(GPIOPinRead(MY_PIN_PORTBASE, MY_PINNR))) //0 { loopCnt = loopCnt -1; if (loopCnt == 0) return 0; } loopCnt = g_ui32SysClock/100; while(GPIOPinRead(MY_PIN_PORTBASE, MY_PINNR)) { loopCnt = loopCnt -1; if (loopCnt == 0) return 0; } // start receiving 40 bits char i; bitcount = 7; byte = 0; int conta = 0; int timerval2=0; int largest = 0; int lowest = 99999; for (i=0; i < 40; i++) { loopCnt = g_ui32SysClock/100; while(!(GPIOPinRead(MY_PIN_PORTBASE, MY_PINNR))) { loopCnt = loopCnt -1; if (loopCnt == 0) return 0; } TimerDisable(MY_TIMERBASE, MY_TIMER); TimerConfigure(MY_TIMERBASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_ONE_SHOT); TimerLoadSet(MY_TIMERBASE, MY_TIMER, g_ui32SysClock/4000); TimerEnable(MY_TIMERBASE, MY_TIMER); timerval = TimerValueGet(MY_TIMERBASE, MY_TIMER); loopCnt = g_ui32SysClock/100; while(GPIOPinRead(MY_PIN_PORTBASE, MY_PINNR)) { loopCnt = loopCnt -1; if (loopCnt == 0) return 0; } timerval2 = TimerValueGet(MY_TIMERBASE, MY_TIMER); conta = timerval - timerval2; if (conta>largest) largest = conta; if (conta<lowest) lowest = conta; if ((conta) > (1000)) bits[byte] |= (1 << bitcount); if (bitcount == 0) { bitcount = 7; byte++; }else{ bitcount--; } } bitints[0] = ((unsigned int) bits[0] & (0x000000FF)); bitints[1] = ((unsigned int) bits[1] & (0x000000FF)); bitints[2] = ((unsigned int) bits[2] & (0x000000FF)); bitints[3] = ((unsigned int) bits[3] & (0x000000FF)); bitints[4] = ((unsigned int) bits[4] & (0x000000FF)); if(((bitints[0] + bitints[1] + bitints[2] + bitints[3]) & (0x000000FF)) == bitints[4]){ temp = bitints[2]; humidity = bitints[0]; return 1; }else{ return 0; } } int main(void) { g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 40000000); PinoutSet(false, false); ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1); ConfigureUART(); UARTprintf("Its runing at : %d\n",g_ui32SysClock); while(1) { // // Turn on D1. LED 1 // LEDWrite(CLP_D1, 1); SysCtlDelay(g_ui32SysClock / 3); //%1s Delay its required because if the sensor is ready to fast the comunication goes down. LEDWrite(CLP_D1, 0); SysCtlDelay(g_ui32SysClock / 3); if(ReadDHT() == 0) { UARTprintf("Erro!\n"); } else { UARTprintf("Temp %d !\n",temp); UARTprintf("Hum %d !\n",humidity); } } } L.R.A 1 Quote Link to post Share on other sites
aureliokta 0 Posted August 19, 2014 Share Posted August 19, 2014 The code uses Pin M6 and push the data over serial. The variables "largest" and "lowest" helps to tune the code, in accord with the operation frequency. L.R.A 1 Quote Link to post Share on other sites
L.R.A 78 Posted August 20, 2014 Share Posted August 20, 2014 Thank you @@aureliokta Quote Link to post Share on other sites
gadolly 0 Posted January 29, 2015 Share Posted January 29, 2015 arre, can you explain if(timerval<40*clockMhz) bit[byte]|=(1<<bitcount); I think it has to be if(timerval>40*clockMhz) as this will decide data"1" that takes long time. Also, how can you relate the 40*clockMhz to the 28usec time interval to decide data"0" or the 70usec time interval to decide data "1". clockMhz=40 in the code so this value will be 40*40=1600 that is too large for the time values in the data sheet of the sensor ! Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.