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);
}
}
I hope that someone might give me some suggestions useful.
Thank you in advance.