Stm32f401re-Nucleo - DHT11 & LCD

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
Cooper
Posts: 3
Joined: Fri Oct 30, 2015 10:28 am

Stm32f401re-Nucleo - DHT11 & LCD

Post by Cooper »

Hello everyone
I am struggling with a microcontroller STM32F401re-Nucleo, I connected to the board temperature sensor DHT11 to calculate the temperature and humidity of a room, everything in amble of svilippo chibios.
So far, so good.
I find it difficult when I go to connect HD44780 LCD for viewing on the display.

This is the code:

Code: Select all

/*
    PLAY Embedded demos - Copyright (C) 2014-2015 Rocco Marco Guglielmi

    This file is part of PLAY Embedded demos.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"
#include "lcd.h"
#include "chprintf.h"





/*===========================================================================*/
/* LCD configuration                                                         */
/*===========================================================================*/
static const PWMConfig pwmcfg = {
  100000,                                   /* 100kHz PWM clock frequency.  */
  100,                                      /* PWM period is 1000 cycles.    */
  NULL,
  {
   {PWM_OUTPUT_ACTIVE_HIGH, NULL},
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL},
   {PWM_OUTPUT_DISABLED, NULL}
  },
  0,
  0
};

static const LCDConfig lcdcfg = {

  {
   {GPIOA, GPIOA_PIN4},                      /* RS Port and pin */
   {GPIOA, GPIOA_PIN1},                       /* RW Port and pin */
   {GPIOA, GPIOA_PIN0},                      /* E Port and pin */
   {
    {GPIOC, GPIOC_PIN0},
    {GPIOC, GPIOC_PIN1},
    {GPIOC, GPIOC_PIN2},
    {GPIOC, GPIOC_PIN3},
    {GPIOC, GPIOC_PIN4},
    {GPIOC, GPIOC_PIN5},
    {GPIOC, GPIOC_PIN6},
    {GPIOC, GPIOC_PIN7} /* Data Ports and pins */
   },
   {GPIOA, GPIOA_PIN8},                      /* A Port and pin */
  },
  HD44780_EMS_Inc,
  HD44780_DC_DisplayOn | HD44780_DC_CursorOff | HD44780_DC_BlinkingOff,
  HD44780_Set_Font5x10Dots | HD44780_Set_2Lines | HD44780_Set_DataLenght8bit,
  &PWMD1,                                    /* PWM Driver for back-light */
  &pwmcfg,                                   /* PWM driver configuration for back-light */
  0,                                         /* PWM channel */
  100,                                       /* Back-light */
};


/*
 * Enable if your terminal supports ANSI ESCAPE CODE
 */
#define ANSI_ESCAPE_CODE_ALLOWED                  TRUE

//static BaseSequentialStream * chp = (BaseSequentialStream*) &SD2;
/*===========================================================================*/
/* DHT11 related defines                                                     */
/*===========================================================================*/
/*
 * Width are in useconds
*/
#define    MCU_REQUEST_WIDTH                     18000
#define    DHT_ERROR_WIDTH                         200
#define    DHT_START_BIT_WIDTH                      80
#define    DHT_LOW_BIT_WIDTH                        28
#define    DHT_HIGH_BIT_WIDTH                       70
/*===========================================================================*/
/* ICU related code                                                          */
/*===========================================================================*/

#define    ICU_TIM_FREQ                        1000000

static uint8_t TEMP, HR, CHECK_SUM, tmp, bit_counter = 0;;
static icucnt_t widths [40];
char* int2Char(int num, char* str, int base);
char* reverse(char* str, int  dim_string);


char* reverse(char* str, int  dim_string){
  int pos_begin=0;
  int pos_end=dim_string-1;
  char temp;
  while(pos_begin!=pos_end && pos_begin<pos_end){
    temp=str[pos_begin];
    str[pos_begin]=str[pos_end];
    str[pos_end]=temp;
     pos_begin=pos_begin+1;
     pos_end=pos_end-1;
  }

  return str;
}
/*
 * Convert int to char
 * */
char* int2Char(int num, char* str, int base){
  int i = 0;
      bool isNegative = false;

      /* Handle 0 explicitely, otherwise empty string is printed for 0 */
      if (num == 0)
      {
          str[i++] = '0';
          str[i] = '\0';
          return str;
      }

      // In standard itoa(), negative numbers are handled only with
      // base 10. Otherwise numbers are considered unsigned.
      if (num < 0 && base == 10)
      {
          isNegative = true;
          num = -num;
      }

      // Process individual digits
      while (num != 0)
      {
          int rem = num % base;
          str[i++] = (rem > 9)? (rem-10) + 'a' : rem + '0';
          num = num/base;
      }

      // If number is negative, append '-'
      if (isNegative)
          str[i++] = '-';

      str[i] = '\0'; // Append string terminator

      // Reverse the string
      reverse(str, i);

      return str;

}


static void icuwidthcb(ICUDriver *icup) {

  icucnt_t width = icuGetWidthX(icup);

  if(width >= DHT_START_BIT_WIDTH){
    /* starting bit resetting the bit counter */
    bit_counter = 0;
  }
  else{
    /* Recording current width. Just for fun  */
    widths[bit_counter] = width;

    if(width > DHT_LOW_BIT_WIDTH){
      tmp |= (1 << (7 - (bit_counter % 8)));
    }
    else{
      tmp &= ~(1 << (7 - (bit_counter % 8)));
    }

    /* When bit_counter is 7, tmp contains the bit from 0 to 7 corresponding to
       The Humidity Rate integer part (Decimal part is 0 on DHT 11) */
    if(bit_counter == 7)
      HR = tmp;
    /* When bit_counter is 23, tmp contains the bit from 16 to 23 corresponding to
       The Temperature integer part (Decimal part is 0 on DHT 11) */
    if(bit_counter == 23)
      TEMP = tmp;
    /* When bit_counter is 39, tmp contains the bit from 32 to 39 corresponding to
       The Check sum value */
    if(bit_counter == 39)
      CHECK_SUM = tmp;
    bit_counter++;
  }
}


static ICUConfig icucfg = {
  ICU_INPUT_ACTIVE_HIGH,
  ICU_TIM_FREQ,                                /* 1MHz ICU clock frequency.   */
  icuwidthcb,
  NULL,
  NULL,
  ICU_CHANNEL_1,
  0
};

/*===========================================================================*/
/* Generic function                                                          */
/*===========================================================================*/

/*
 * Red LED blinker thread, times are in milliseconds.
 */
static THD_WORKING_AREA(waThread1, 128);
static THD_FUNCTION(Thread1, arg) {

  (void)arg;
  chRegSetThreadName("blinker");
  while (true) {
    if(TEMP >= 28){
      palSetPad(GPIOA, GPIOA_LED_GREEN);
      chThdSleepMilliseconds(500);
    }else{
      palClearPad(GPIOA, GPIOA_LED_GREEN);
      chThdSleepMilliseconds(500);
    }
  }
}
/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();
  lcdInit();
  /*
   * Activates the serial driver 2 using the driver default configuration.
   */
  sdStart(&SD2, NULL);

  /*
   * Creates the blinker thread.
   */
  chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);

  chThdSleepMilliseconds(1000);


  palSetPadMode(GPIOA, GPIOA_PIN8, PAL_MODE_ALTERNATE(1));
    palSetPadMode(GPIOA, GPIOA_PIN0, PAL_MODE_OUTPUT_PUSHPULL |
                  PAL_STM32_OSPEED_HIGHEST);
    palSetPadMode(GPIOA, GPIOA_PIN1, PAL_MODE_OUTPUT_PUSHPULL |
                  PAL_STM32_OSPEED_HIGHEST);
    palSetPadMode(GPIOA, GPIOA_PIN4, PAL_MODE_OUTPUT_PUSHPULL |
                  PAL_STM32_OSPEED_HIGHEST);
    chThdSleepMilliseconds(100);
    lcdStart(&LCDD1, &lcdcfg);

    char valore_temperatura[3];
    char valore_umidita[3];

    int2Char(TEMP,valore_temperatura,10);
    char temperatura[]="Temperatura :";
    strcat(temperatura, valore_temperatura);

    int2Char(HR, valore_umidita,10);
    char umidita[]="   Umidita :";
    strcat(umidita, valore_umidita);



    //lcdWriteString(&LCDD1, "  Umidita         ",38);
    chThdSleepMilliseconds(2000);

  /*
   * Normal main() thread activity, in this demo it does nothing except
   * sleeping in a loop and check the button state.
   */
  while (true) {


    lcdStart(&LCDD1, &lcdcfg);
    lcdWriteString(&LCDD1, temperatura, 0);
    lcdWriteString(&LCDD1, umidita, 38);


    /*
            * Making a request
            */
           palSetPadMode(GPIOA, GPIOA_PIN8, PAL_MODE_OUTPUT_PUSHPULL);
           palWritePad(GPIOA, GPIOA_PIN8, PAL_LOW);
           chThdSleepMicroseconds(MCU_REQUEST_WIDTH);
           palWritePad(GPIOA, GPIOA_PIN8, PAL_HIGH);

           /*
            * Initializes the ICU driver 1.
            * GPIOA8 is the ICU input.
            */
           palSetPadMode(GPIOA, GPIOA_PIN8, PAL_MODE_ALTERNATE(1));
           icuStart(&ICUD1, &icucfg);
           icuStartCapture(&ICUD1);
           icuEnableNotifications(&ICUD1);
           chThdSleepMilliseconds(700);
      /* #if ANSI_ESCAPE_CODE_ALLOWED
           chprintf(chp, "\033[2J\033[1;1H");
       #endif
           icuStopCapture(&ICUD1);
           icuStop(&ICUD1);

           chprintf(chp, "Temperature: %d C, Humidity Rate: %d %% \n\r", TEMP, HR);
           if(CHECK_SUM == (TEMP | HR)){
             chprintf(chp, "Checksum OK!\n\r");
           }
           else{
             chprintf(chp, "Checksum FAILED!\n\r");
           }*/

           int2Char(TEMP,valore_temperatura,10);
                  strcpy(temperatura,"Temperatura :");
                  strcat(temperatura, valore_temperatura);
                  chThdSleepMilliseconds(2000);

           int2Char(HR,valore_umidita,10);
                  strcpy(umidita,"  Umidita :");
                  strcat(umidita, valore_umidita);
                  chThdSleepMilliseconds(2000);



  }
}


Image

I hope that someone might give me some suggestions useful.

Thank you in advance.
Attachments
chibios gives me the following error:
chibios gives me the following error:
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Stm32f401re-Nucleo - DHT11 & LCD

Post by Giovanni »

Giovanni,

It looks you enabled the same peripheral for more than one driver in mcuconf.h, this is why there are conflicting IRQ vectors. For example you can use TIM2 for PWM or ICU, not both.

Giovanni
Cooper
Posts: 3
Joined: Fri Oct 30, 2015 10:28 am

Re: Stm32f401re-Nucleo - DHT11 & LCD

Post by Cooper »

Hello Giovanni

I enabled TIM3 the errors are gone,
but when I go to debug, on the display the temperatue and humidity remain equal to zero.
Cooper
Posts: 3
Joined: Fri Oct 30, 2015 10:28 am

Re: Stm32f401re-Nucleo - DHT11 & LCD

Post by Cooper »

Is there anyone who can help me?
User avatar
Giovanni
Site Admin
Posts: 14893
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 997 times

Re: Stm32f401re-Nucleo - DHT11 & LCD

Post by Giovanni »

Probably who wrote that demo.

Giovanni
Post Reply