dht11 sensor timed out with cc2650 launchpad - embedded

I'm running launchxl-cc2650 on Contiki to read temperature and humidity value from dht11 sensor. Build with Contiki, and flash with ti programmer 2. But my board can't seem to read the value of the sensor (output reading timed out) i'm trying on 2 difference board and 2 sensors (same type) so i'm pretty sure the problem didn't come from hardware, and the led from sensor light up which mean it has power. This code has been run successfully by my senior last year. so it really confuse me of which could cause the problem, the plug the data to IOID_0 Pin. The code could be found at contiki-ng/dht11.c at develop branch in https://github.com/contiki-ng/contiki-ng with a little twist i made, code be written below.
#include "contiki.h"
#include <stdio.h>
#include "board.h"
#include "dht11-sensor.h"
/*---------------------------------------------------------------------------*/
PROCESS(dht11_process, "DHT 11 process");
AUTOSTART_PROCESSES(&dht11_process);
/*---------------------------------------------------------------------------*/
#define DHT11_GPIO_PORT (1)
#define DHT11_GPIO_PIN (12)
#define BOARD_IOID_DIO0 IOID_0
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(dht11_process, ev, data)
{
static struct etimer timer;
PROCESS_BEGIN();
dht11_sensor.configure(DHT11_CONFIGURE_GPIO_PIN, IOID_0);
dht11_sensor.configure(SENSORS_HW_INIT, 0);
/* Wait one second for the DHT11 sensor to be ready */
etimer_set(&timer, CLOCK_SECOND * 1);
/* Wait for the periodic timer to expire */
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
/* Setup a periodic timer that expires after 5 seconds. */
etimer_set(&timer, CLOCK_SECOND * 2);
while(1) {
/*
* Request a fresh read
*/
SENSORS_ACTIVATE(dht11_sensor);
switch(dht11_sensor.status(0)) {
case DHT11_STATUS_OKAY:
printf("Do Am : %d.%d %% \n",
dht11_sensor.value(DHT11_VALUE_HUMIDITY_INTEGER),
dht11_sensor.value(DHT11_VALUE_HUMIDITY_DECIMAL));
printf("Nhiet Do : %d.%d *C\n",
dht11_sensor.value(DHT11_VALUE_TEMPERATURE_INTEGER),
dht11_sensor.value(DHT11_VALUE_TEMPERATURE_DECIMAL));
break;
case DHT11_STATUS_CHECKSUM_FAILED:
printf("Check sum failed\n");
break;
case DHT11_STATUS_TIMEOUT:
printf("Reading timed out\n");
break;
default:
break;
}
/* Wait for the periodic timer to expire and then restart the timer. */
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&timer));
etimer_reset(&timer);
}
PROCESS_END();
`
The only different thing from my senior is that when i build using make command, it only result in .elf file, not the .hex and .bin file. Could this be the problem? i think it's unlikely cause Ti Programmer 2 support .elf file, and i have been flashing succesfully with .elf file with other examples. Plese lend me your though.

Related

PLL Init function in STM32F429 to configure max frequency (180Mhz)

I want to configure PLL in STM32F429 to its max frequency (180Mhz) without using STMCube-generated configurations. I am using my own register definitions like this
#define RCC_CFGR (*((volatile uint32 *)0x40023808))
and my own SET_BIT()/CLEAR_BIT() macros
My questions are:
1- Is this procedure correct?
2- How can I check if it is working?
3- May the MCU can not handle this speed (reading/writing in registers)?
#define PLL_M 16
#define PLL_N 360
#define PLL_P 2
#define PLL_Q 7
void PLL_init(void)
{
/* System Init */
/* HSI ON */
SET_BIT(RCC_CR, HSION);
/* Reset CFGR register */
RCC_CFGR = 0x00000000 ;
/* Reset PLLCFGR register */
RCC_PLLCFGR = 0x24003010;
/* Reset HSEON, CSSON and PLLON bits */
RCC_CR &= (uint32_t)0xFEF6FFFF;
/************* SetSysClock ************/
RCC_PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16)| (PLL_Q << 24);
/* PLL clock Source HSI or HSE */
CLEAR_BIT(RCC_PLLCFGR, PLLSRC);
/* APB1 PWR Enable*/
SET_BIT(RCC_APB1ENR, PWREN);
/* Select regulator voltage output Scale 1 mode, System frequency up to 180 MHz */
SET_BIT(PWR_CR, VOS0);
SET_BIT(PWR_CR, VOS1);
/* AHB div 1 */
CLEAR_BIT(RCC_CFGR,HPRE3);
CLEAR_BIT(RCC_CFGR,HPRE0);
/* APB2 Div = 2*/
CLEAR_BIT(RCC_CFGR,PPRE20);
CLEAR_BIT(RCC_CFGR,PPRE21);
SET_BIT(RCC_CFGR, PPRE23);
/* APB 1 Div = 8 */
CLEAR_BIT(RCC_CFGR, PPRE10);
SET_BIT(RCC_CFGR, PPRE11);
SET_BIT(RCC_CFGR, PPRE12);
/* SET PLL ON */
SET_BIT(RCC_CR, PLLON);
/* Check PLL is ready */
while(BIT_IS_CLEAR(RCC_CR,PLLRDY));
/* Enable the Over-drive to extend the clock frequency to 180 Mhz */
SET_BIT(PWR_CR, ODEN);
while(BIT_IS_CLEAR(PWR_CSR,ODRDY));
SET_BIT(PWR_CR, ODSWEN);
while(BIT_IS_CLEAR(PWR_CSR,ODSWRDY));
SET_BIT(FLASH_ACR, PRFTEN);
SET_BIT(FLASH_ACR, ICEN);
SET_BIT(FLASH_ACR, DCEN);
FLASH_ACR |= FLASH_ACR_LATENCY_5WS;
/* Select the main PLL as system clock source */
CLEAR_BIT(RCC_CFGR, SW0);
SET_BIT(RCC_CFGR, SW1);
/* Wait till the main PLL is used as system clock source */
while(!BIT_IS_CLEAR(RCC_CFGR,SWS0) && !BIT_IS_SET(RCC_CFGR,SWS1) ); /* Loop till is Set */
}
I did exactly this thing on my STM32F746 - set 216MHz with registers. It looks very similar to mine. Not observing any obvious things. You wait for all ready flags and all. Overdrive and overdrive switching are there, flash wait states are there.
How to check if it's working - timer is an easy idea. Timer that is clocked by a system clock with some prescaler and that outputs PWM to some pin. Given the configuration of the timer is set by you, you should know what output frequency to expect. You can set timer parameters in such a way that you expect timer-interrupt-toggle an LED every 1s.
The MCU should handle it OK if all prescalers for AHB/APB are within limits, as well as Flash latency is set correctly. Which seems to be the case.
If you want to compare the logic with what I do with STM32F746 (which looks almost identical in terms of how you do it), you can check it in this rcc.c file of mine. It definitely works, I tested it.

STM32 Nucleo EEPROM Emulator ee_init issue

I am working on trying to get the EEPROM Emulator from stm32 working. I have followed the example given for a stm32 l47x board however I am still running into issues. When I call EE_init I end up running into a stack overflow. I am not too familiar with this emulator and am using the default configurations from the example.
This is how I am initializing everything.
EE_Status ee_status = EE_OK;
/* Enable and set FLASH Interrupt priority */
/* FLASH interrupt is used for the purpose of pages clean up under interrupt */
HAL_NVIC_SetPriority(FLASH_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(FLASH_IRQn);
HAL_FLASH_Unlock();
if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) == RESET)
{
/* Blink LED_OK (Green) twice at startup */
LEDInterface_toggleColor(GREEN);
HAL_Delay(100);
LEDInterface_toggleColor(NONE);
HAL_Delay(100);
LEDInterface_toggleColor(GREEN);
HAL_Delay(100);
LEDInterface_toggleColor(NONE);
ee_status = EE_Init(EE_FORCED_ERASE);
if(ee_status != EE_OK)
{
while(1);
}
This is the eeprom_emul_conf.h settings which I also have not changed
/* Configuration of eeprom emulation in flash, can be custom */
#if defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx)
#define START_PAGE_ADDRESS 0x08100000U /*!< Start address of the 1st page in flash, for EEPROM emulation */
#else
#define START_PAGE_ADDRESS 0x08080000U /*!< Start address of the 1st page in flash, for EEPROM emulation */
#endif
#define CYCLES_NUMBER 1U /*!< Number of 10Kcycles requested, minimum 1 for 10Kcycles (default),
for instance 10 to reach 100Kcycles. This factor will increase
pages number */
#define GUARD_PAGES_NUMBER 2U /*!< Number of guard pages avoiding frequent transfers (must be multiple of 2): 0,2,4.. */
/* Configuration of crc calculation for eeprom emulation in flash */
#define CRC_POLYNOMIAL_LENGTH LL_CRC_POLYLENGTH_16B /* CRC polynomial lenght 16 bits */
#define CRC_POLYNOMIAL_VALUE 0x8005U /* Polynomial to use for CRC calculation *
/
I am running into the osal_hooks.c file where I am getting stuck in this while loop
#if defined(DOXYGEN)
void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
#else
OSAL_WEAK_FN(void, vApplicationStackOverflowHook)( TaskHandle_t xTask, char *pcTaskName )
#endif
{
volatile char * name = pcTaskName;
(void)name;
while (1)
{
;
}
}
Im sure I need to change where I allocate the memory but what is the best way to go about this. Thank you

USB CDC: STM32F103RBT6 Cant get USB Device to show up

I got an Olimexino-STM32 with an STM32F103RBT6. I used STM32 Workbench 2.6 on Windows 10 x64 and STMCubeXM 4.27.0.
I choosed in CubeMX
STM32F103RBT6
RCC HSE
USB
USB Device Communication Device Class
Debug Line: JTAG 4 pin
Fix clock speeds
Add LED1 on PA5 as GPIO Out
Add LED2 on PA1 as GPIO Out
Toolchain SW4STM
Stack size
In main.c in the while loop
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
HAL_Delay(500);
uint8_t HiMsg[] = "hello\r\n";
CDC_Transmit_FS(HiMsg, strlen(HiMsg));
}
/* USER CODE END 3 */
in usb_cdc_if.c
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
if (Buf[0]=='1')
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET);
}
else
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
}
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
Generate, compile and flash to Board. I can see the LED blinking in the main loop. The speed seems also correct but i just cant get a device registered on windows. I can flash the board with an example hex file from the distributor with the bootloader active. There i can get the COM port registered. So i can see the USB Port is ok but somehow the generated code doesnt register the COM port.
Any Ideas?
https://www.olimex.com/Products/Duino/STM32/OLIMEXINO-STM32/
Here is the test1.ioc file
#MicroXplorer Configuration settings - do not modify
File.Version=6
KeepUserPlacement=false
Mcu.Family=STM32F1
Mcu.IP0=NVIC
Mcu.IP1=RCC
Mcu.IP2=SYS
Mcu.IP3=USB
Mcu.IP4=USB_DEVICE
Mcu.IPNb=5
Mcu.Name=STM32F103R(8-B)Tx
Mcu.Package=LQFP64
Mcu.Pin0=PD0-OSC_IN
Mcu.Pin1=PD1-OSC_OUT
Mcu.Pin2=PA5
Mcu.Pin3=PA11
Mcu.Pin4=PA12
Mcu.Pin5=VP_SYS_VS_ND
Mcu.Pin6=VP_SYS_VS_Systick
Mcu.Pin7=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.PinsNb=8
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32F103RBTx
MxCube.Version=4.27.0
MxDb.Version=DB.4.0.270
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.USB_LP_CAN1_RX0_IRQn=true\:0\:0\:false\:false\:true\:false
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false
PA11.Mode=Device
PA11.Signal=USB_DM
PA12.Mode=Device
PA12.Signal=USB_DP
PA5.GPIOParameters=GPIO_Label
PA5.GPIO_Label=LED1
PA5.Locked=true
PA5.Signal=GPIO_Output
PCC.Checker=false
PCC.Line=STM32F103
PCC.MCU=STM32F103R(8-B)Tx
PCC.PartNumber=STM32F103RBTx
PCC.Seq0=0
PCC.Series=STM32F1
PCC.Temperature=25
PCC.Vdd=3.3
PD0-OSC_IN.Mode=HSE-External-Oscillator
PD0-OSC_IN.Signal=RCC_OSC_IN
PD1-OSC_OUT.Mode=HSE-External-Oscillator
PD1-OSC_OUT.Signal=RCC_OSC_OUT
PinOutPanel.RotationAngle=0
RCC.ADCFreqValue=36000000
RCC.AHBFreq_Value=72000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2
RCC.APB1Freq_Value=36000000
RCC.APB1TimFreq_Value=72000000
RCC.APB2Freq_Value=72000000
RCC.APB2TimFreq_Value=72000000
RCC.FCLKCortexFreq_Value=72000000
RCC.FamilyName=M
RCC.HCLKFreq_Value=72000000
RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value,USBPrescaler,VCOOutput2Freq_Value
RCC.MCOFreq_Value=72000000
RCC.PLLCLKFreq_Value=72000000
RCC.PLLMCOFreq_Value=36000000
RCC.PLLMUL=RCC_PLL_MUL9
RCC.SYSCLKFreq_VALUE=72000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.TimSysFreq_Value=72000000
RCC.USBFreq_Value=48000000
RCC.USBPrescaler=RCC_USBCLKSOURCE_PLL_DIV1_5
RCC.VCOOutput2Freq_Value=8000000
USB_DEVICE.CLASS_NAME_FS=CDC
USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS
USB_DEVICE.VirtualMode=Cdc
USB_DEVICE.VirtualModeFS=Cdc_FS
VP_SYS_VS_ND.Mode=No_Debug
VP_SYS_VS_ND.Signal=SYS_VS_ND
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Signal=USB_DEVICE_VS_USB_DEVICE_CDC_FS
board=custom
Problem solved: The Olimexino-STM32 has an output to connect and disconnect the USB. I had not configured that output pin.

USART giving unknown values on the atmega 328p

I have been unable to solve a simple USART transmit/receive program. The problem is that I used this in the past and worked effortlessly but now it returns in my Linux machine question marks and in windows some boxes and Chinese characters. I don´t understand what changed. I have tried a lot of different things like changing the code and the parts but nothing seems to solve it.
I´m using a AVR atmega 328p, and a pololu usb programmer. I flashed it from the atmel studio in windows and from avrdude in linux.
Here is the code:
#define F_CPU 1000000
#define BAUD 9600
#include <avr/io.h>
#include <util/delay.h>
#include <util/setbaud.h>
void init_USART(void);
void transmit_Byte(char data);
char receive_Byte(void);
int main(void)
{
char TEST;
init_USART(); /* Initialize USART */
while (1)
{
TEST = receive_Byte();
transmit_Byte(TEST);
}
}
void init_USART(void)
{
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2x
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
UCSR0B = (1 << TXEN0) | (1 << RXEN0); /* Enable USART
transmitt/receive */
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); /* 8 data bits, 1 stop
bit */
}
void transmit_Byte(char data)
{
loop_until_bit_is_set(UCSR0A, UDRE0); /* Wait for empty
transmit buffer */
UDR0 = data;
}
char receive_Byte(void)
{
loop_until_bit_is_set(UCSR0A, RXC0);
return(UDR0);
}
This is my first question so I apologize in advanced if I did something wrong.
Thanks a lot for your time!
edit: I have tried a ftdi232 and a mcp2221
edit 2: After addin UL still not as expected but got less unknown characters.
SOLVED: But I don't understand why. I changed the fuse CKDIV8 to 1 and it started working. The datasheet says it comes factory with 8 MHz clock and the CKDIV8=0 so it is set to 1 MHz. So why is it inversed? I also tried previously clock_prescale_set(clock_div_8); as the datasheet suggest for prescaling and it didn't work neither.
What is the difference between setting the CLDIV8 and the avr/power.h function?

How to receive packets on the MCU's serial port?

Consider this code running on my microcontroller unit(MCU):
while(1){
do_stuff;
if(packet_from_PC)
send_data_via_gpio(new_packet); //send via general purpose i/o pins
else
send_data_via_gpio(default_packet);
do_other_stuff;
}
The MCU is also interfaced to a PC via a UART.Whenever the PC sends data to the MCU, the new_packet is sent,
otherwise the default_packet is sent.Each packet can be 5 or more bytes with a pre defined packet structure.
My question is:
1.Should i receive the entire packet from PC using inside the UART interrut service routine (ISR)? In this case, i have to implement
a state machine inside the ISR to assemble the packet (which can be lengthy with if-else or switch-case blocks).
OR
2.Have the PC send some sort of a REQUEST command (one byte),detect it in my ISR set a flag, disable UART interrupt alone and form the packet in my while(1) loop by checking for the flag and polling the UART?In this case the UART interrupt would be re-enabled in the while(1) loop after the entire packet is formed.
Those are not the only two choices, and the second one seems suboptimal.
My first approach would be to a simple circular queue, and push bytes into it from the ISR and read bytes from in your main loop. That way you have a small and simple ISR and you and do the processing in your main loop without disabling interrupts.
The first choice is possible assuming you can code the ISR sensibly. You probably want to have timeouts when dealing with constructing packets; you need to be able to handle that correctly in your ISR. It depends on the line speed, the speed of your MCU and what else you need to do.
Update:
Doing it in the ISR is certainly reasonable. However, using a circular queue is pretty straightforward with a standard implementation in your bag of tricks. Here is a circular queue implementation; readers and writers can operate independently.
#ifndef ARRAY_ELEMENTS
#define ARRAY_ELEMENTS(x) (sizeof(x) / sizeof(x[0]))
#endif
#define QUEUE_DEFINE(name, queue_depth, type) \
struct queue_type__##name { \
volatile size_t m_in; \
volatile size_t m_out; \
type m_queue[queue_depth]; \
}
#define QUEUE_DECLARE(name) struct queue_type__##name name
#define QUEUE_SIZE(name) ARRAY_ELEMENTS((name).m_queue)
#define QUEUE_CALC_NEXT(name, i) \
(((name).i == (QUEUE_SIZE(name) - 1)) ? 0 : ((name).i + 1))
#define QUEUE_INIT(name) (name).m_in = (name).m_out = 0
#define QUEUE_EMPTY(name) ((name).m_in == (name).m_out)
#define QUEUE_FULL(name) (QUEUE_CALC_NEXT(name, m_in) == (name).m_out)
#define QUEUE_NEXT_OUT(name) ((name).m_queue + (name).m_out)
#define QUEUE_NEXT_IN(name) ((name).m_queue + (name).m_in)
#define QUEUE_PUSH(name) ((name).m_in = QUEUE_CALC_NEXT((name), m_in))
#define QUEUE_POP(name) ((name).m_out = QUEUE_CALC_NEXT((name), m_out))
Use it like this:
QUEUE_DEFINE(bytes_received, 64, unsigned char);
QUEUE_DECLARE(bytes_received);
void isr(void)
{
/* Move the received byte into 'c' */
/* This code enqueues the byte, or drops it if the queue is full */
if (!QUEUE_FULL(bytes_received)) {
*QUEUE_NEXT_IN(bytes_received) = c;
QUEUE_PUSH(bytes_received);
}
}
void main(void)
{
QUEUE_INIT(bytes_received);
for (;;) {
other_processing();
if (!QUEUE_EMPTY(bytes_received)) {
unsigned char c = *QUEUE_NEXT_OUT(bytes_received);
QUEUE_POP(bytes_received);
/* Use c as you see fit ... */
}
}
}