Page 1 of 1
[SOLVED] Can I generate a PWM signal through the break-out or expansion circuit of Crazyflie?
Posted: Mon Jun 12, 2017 2:32 pm
by thanhvu94
I want to add an IR LED to the expansion or breakout circuit board and then make it flicker at 17 kHz frequency. I'm wondering is it possible to generate the PWM signal via the stm32 to the expansion/breakout board or not? If yes, can you give me some materials on how I can program?
Thank you so much.
Re: Can I generate a PWM signal through the break-out or expansion circuit of Crazyflie?
Posted: Tue Jun 13, 2017 9:21 am
by tobias
Yes it is possible to to generate a PWM signal on the deck expansion port but you will have to program the low level driver for it. You can use any of the unused pins with unused timers. I suggest IO_1 (PB8) where you can use TIM10. I tried to do this a long time ago but never finished it. I have attached my try code below as a reference. I can't remember I ever got it to work but It will give you something at least
Code: Select all
#include <stdint.h>
/* FreeRtos includes */
#include "FreeRTOS.h"
#include "task.h"
#include "stm32fxxx.h"
#include "ir_tx.h"
#include "debug.h"
#include "nvicconf.h"
#include "ir_code.h"
#define IR_TX_CARRIER_FREQ 56000
#define IR_TX_CARRIER_PWM_PERIOD (SystemCoreClock / IR_TX_CARRIER_FREQ)
#define IR_TX_DELAY_PRESCALER (84 - 1)
#define IR_TX_CARRIER_TIMER TIM10
#define IR_TX_CARRIER_TIMER_RCC RCC_APB2Periph_TIM10
#define IR_TX_CARRIER_TIMER_CH_Init TIM_OC1Init
#define IR_TX_CARRIER_TIMER_CH_PreloadConfig TIM_OC1PreloadConfig
#define IR_TX_CARRIER_TIMER_CH_SetCompare TIM_SetCompare1
#define IR_TX_CARRIER_RCC RCC_AHB1Periph_GPIOB
#define IR_TX_CARRIER_PORT GPIOB
#define IR_TX_CARRIER_PIN GPIO_Pin_8
#define IR_TX_DELAY_TIMER TIM6
#define IR_TX_DELAY_TIMER_IRQ TIM6_DAC_IRQn
#define IR_TX_DELAY_TIMER_RCC RCC_APB1Periph_TIM6
#define IR_TX_DELAY_TIMER_IRQ_HANDLER TIM6_DAC_IRQHandler
volatile uint16_t g_tx_bufferIndex;
volatile uint16_t g_tx_repeatCount;
volatile IrCode* g_tx_code;
static void irTxOn();
static void irTxOff();
void irTxTask(void *arg)
{
ir_code_setup();
while (true)
{
vTaskDelay(M2T(1000));
ir_tx_send(&codes[0]);
}
}
void irTxInit(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(IR_TX_CARRIER_RCC, ENABLE);
RCC_APB2PeriphClockCmd(IR_TX_CARRIER_TIMER_RCC, ENABLE);
// Configure the GPIO for the timer output
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = IR_TX_CARRIER_PIN;
GPIO_Init(IR_TX_CARRIER_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_TIM10);
// Time base configuration
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = IR_TX_CARRIER_PWM_PERIOD;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(IR_TX_CARRIER_TIMER, &TIM_TimeBaseStructure);
// PWM channel configuration
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
// Configure Output Compare for PWM
IR_TX_CARRIER_TIMER_CH_Init(IR_TX_CARRIER_TIMER, &TIM_OCInitStructure);
IR_TX_CARRIER_TIMER_CH_PreloadConfig(IR_TX_CARRIER_TIMER, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(IR_TX_CARRIER_TIMER, ENABLE);
IR_TX_CARRIER_TIMER_CH_SetCompare(IR_TX_CARRIER_TIMER, IR_TX_CARRIER_PWM_PERIOD / 10);
TIM_Cmd(IR_TX_CARRIER_TIMER, ENABLE);
// Delay timer
RCC_APB1PeriphClockCmd(IR_TX_DELAY_TIMER_RCC, ENABLE);
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xffff;
TIM_TimeBaseStructure.TIM_Prescaler = IR_TX_DELAY_PRESCALER;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(IR_TX_DELAY_TIMER, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = NVIC_IR_TX_DELAY_TIMER_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(IR_TX_DELAY_TIMER, TIM_IT_Update, ENABLE);
irTxOff();
xTaskCreate(irTxTask, (const signed char * const)"IR-TX", 50, NULL, 0, NULL);
}
void ir_tx_send(IrCode* code)
{
g_tx_bufferIndex = 0;
g_tx_repeatCount = code->repeatCount;
g_tx_code = code;
TIM_SetCounter(IR_TX_DELAY_TIMER, 1);
TIM_SetAutoreload(IR_TX_DELAY_TIMER, g_tx_code->code[g_tx_bufferIndex++]);
irTxOn();
TIM_Cmd(IR_TX_DELAY_TIMER, ENABLE);
}
void __attribute__((used)) IR_TX_DELAY_TIMER_IRQ_HANDLER()
{
if (TIM_GetITStatus(IR_TX_DELAY_TIMER, TIM_IT_Update) != RESET)
{
if((g_tx_bufferIndex % 2) == 0)
{
irTxOn();
}
else
{
irTxOff();
}
if(g_tx_bufferIndex < g_tx_code->codeLength - 1)
{
TIM_SetCounter(IR_TX_DELAY_TIMER, 1);
TIM_SetAutoreload(IR_TX_DELAY_TIMER, g_tx_code->code[g_tx_bufferIndex++]);
}
else
{
g_tx_repeatCount--;
irTxOff();
if(g_tx_repeatCount == 0)
{
TIM_Cmd(IR_TX_DELAY_TIMER, DISABLE);
} else
{
g_tx_bufferIndex = 0;
TIM_SetCounter(IR_TX_DELAY_TIMER, 1);
TIM_SetAutoreload(IR_TX_DELAY_TIMER, g_tx_code->gap);
}
}
TIM_ClearITPendingBit(IR_TX_DELAY_TIMER, TIM_IT_Update);
}
}
static void irTxOn()
{
TIM_CCxCmd(IR_TX_CARRIER_TIMER, TIM_Channel_1, ENABLE);
}
static void irTxOff()
{
TIM_CCxCmd(IR_TX_CARRIER_TIMER, TIM_Channel_1, DISABLE);
}
Re: Can I generate a PWM signal through the break-out or expansion circuit of Crazyflie?
Posted: Tue Jun 13, 2017 9:36 am
by thanhvu94
Thank you. I will try to figure it out. Which IDE did you use to program? And is there any tutorial on bitcraze wiki on how to upload the code into the stm board?
Re: Can I generate a PWM signal through the break-out or expansion circuit of Crazyflie?
Posted: Tue Jun 13, 2017 10:19 am
by arnaud
Hi,
You can follow this getting started documentation that explains how to modify, compile and upload new firmware to the Crazyflie:
https://www.bitcraze.io/getting-started ... velopment/
Re: Can I generate a PWM signal through the break-out or expansion circuit of Crazyflie?
Posted: Tue Jun 13, 2017 12:35 pm
by thanhvu94
Thank you. I forgot but I should write the code directly in the main.c file, right?
Re: Can I generate a PWM signal through the break-out or expansion circuit of Crazyflie?
Posted: Wed Jun 14, 2017 8:03 am
by arnaud
No, you should not touch main.c in the Crazyflie firmware. We are answering in your other thread:
viewtopic.php?f=6&t=2470.