这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【星空灯日志】我的第一个星空灯,女神收到都哭了!

共19条 1/2 1 2 跳转至

【星空灯日志】我的第一个星空灯,女神收到都哭了!

菜鸟
2021-05-17 20:44:20     打赏

白柴的推荐语:

星座图标,出乎意料的图案,意外的好看\(^o^)/


1.前期准备阶段

5.1号就开始准备材料了,用了eepw提供的墙纸。还有自己买的灯罩,32位单片机,杜邦线,蓝牙模块等等。所以,接下来就是等待材料到来时候了!刚开始有些意外,定制的亚克力板子由于没有和老板商量好,导致板子制作出来只有一小部分,所幸板子买的早。于是在5.8时候所有材料就送到我的手中。

1621301903426397.jpg

1621301925418194.jpg

所有材料到了就开始我的制作了!

2.制作我的星空灯

首先我使用的是STM32单片机,使用该单片机的原因是因为速度快,更重要的原因是除了这个其他的我不会。从网上仔细的学习了WS2812灯带的使用方法之后。发现他有以下的特性:

1)上电时,WS2812数据IO为低电平保持。

2)空闲时,IO为低电平。

3)数据发送完毕后,保持电平,超过规格书上定义的RESET时间(只有低电平时间超过280us,就可以认为是RESET.)

从而可见它比其他灯带操作还是更难的。接着对代码进行编写和优化。

灯带部分代码:

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop_DMA(&htim1,TIM_CHANNEL_1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if(Buffer>='A' && Buffer <='I')
    {
        Mode_Led = Buffer;
        printf("µÆ¹âģʽ£º%c",Mode_Led);
    }
    if(Buffer == 'J')
    {
        Mode_wait  +=10;
        if(Mode_wait==250)
            Mode_wait=240;
        printf("µÆ¹âËٶȣº%d",300-Mode_wait);
    }
    if(Buffer == 'K')
    {
        Mode_wait  -=10;
        if(Mode_wait==60)
            Mode_wait=70;
        printf("µÆ¹âËٶȣº%d",300-Mode_wait);
    }
    HAL_UART_Receive_IT(&huart2,&Buffer, 1);
}

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)
{

    switch(GPIO_Pin)
    {
        case GPIO_PIN_13:Mode_Led++;
        if(Mode_Led == 'J')
            Mode_Led ='A';break;
    }
}
void WS281x_SetPixelColor(uint16_t n, uint32_t GRBColor)
{
    uint8_t i;
    if (n < LED_NUMS)
    {
        for (i = 0; i < 24; ++i)
            RGB_buffur[24 * n + i] = ((GRBColor << i) & 0X800000) ? ONE_PULSE : ZERO_PULSE;
    }
}
uint32_t WS281x_Color(uint8_t red, uint8_t green, uint8_t blue)
{
    return green << 16 | red << 8 | blue;
}
uint32_t Wheel(uint8_t WheelPos)
{
    WheelPos = 255 - WheelPos;
    if (WheelPos < 85)
    {
        return WS281x_Color(255 - WheelPos * 3, 0, WheelPos * 3);
    }
    if (WheelPos < 170)
    {
        WheelPos -= 85;
        return WS281x_Color(0, WheelPos * 3, 255 - WheelPos * 3);
    }
    WheelPos -= 170;
    return WS281x_Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void Mode2_LED(uint8_t wait)
{
    uint32_t timestamp = HAL_GetTick();
    uint16_t i;
    static uint8_t j;
    static uint32_t next_time = 0;
    uint32_t flag = 0;
    if (next_time < wait)
    {
        if ((uint64_t)timestamp + wait - next_time > 0)
            flag = 1;
    }
    else if (timestamp > next_time)
    {
        flag = 1;
    }
    if (flag)
    {
        j++;
        next_time = timestamp + wait;
        for (i = 0; i < LED_NUMS; i++)
        {
            WS281x_SetPixelColor(i, Wheel((i + j) & 255));
        }
    }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void Mode1_LED(uint8_t wait)
{
    uint32_t timestamp = HAL_GetTick();
    uint16_t i;
    static uint8_t j;
    static uint32_t next_time = 0;

    static uint8_t loop = 0;
    if (loop == 0)
        next_time = timestamp;
    loop = 1; //Ê״ε÷Óóõʼ»¯

    if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
    {
        j++;
        next_time = timestamp + wait;
        for (i = 0; i < LED_NUMS; i++)
        {
            WS281x_SetPixelColor(i, Wheel(((i * 256 / (LED_NUMS)) + j) & 255));
        }
    }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void  Mode3_LED(void)//È«ºì
{
    uint16_t i;
    for (i = 0; i < LED_NUMS; i++)
    {
        WS281x_SetPixelColor(i,0x0ff000);
    }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void  Mode4_LED(void)//È«À¶
{
    uint16_t i;
    for (i = 0; i < LED_NUMS; i++)
    {
        WS281x_SetPixelColor(i,0x000ff0);
    }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void  Mode5_LED(void)//È«ÂÌ
{
    uint16_t i;
    for (i = 0; i < LED_NUMS; i++)
    {
        WS281x_SetPixelColor(i,0xf0000f);
    }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void  Mode6_LED(uint8_t wait)//È«ºìºôÎü
{
    static uint32_t led_init=0x000000;
    uint16_t i;static uint8_t temp =0;
    uint32_t timestamp = HAL_GetTick();
    static uint32_t next_time = 0;
    static uint8_t loop = 0;
    if (loop == 0)
        next_time = timestamp;
    loop = 1; //Ê״ε÷Óóõʼ»¯
    if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
    {
        next_time = timestamp + wait;
         if((led_init < 0x02F000) && (temp == 0))
        {
           led_init +=0x001000;
            if(led_init == 0x02F000)
                temp=1; 
        }else{
            led_init -=0x001000;
            if(led_init == 0x000000)
                temp=0;
        }
        for (i = 0; i < LED_NUMS; i++)
        {
            WS281x_SetPixelColor(i,led_init);
        }
   }
    
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
 
}
void  Mode7_LED(uint8_t wait)//È«À¶ºôÎü
{
    static uint32_t led_init=0x000000;
    uint16_t i;static uint8_t temp =0;
    uint32_t timestamp = HAL_GetTick();
    static uint32_t next_time = 0;
    static uint8_t loop = 0;
    if (loop == 0)
        next_time = timestamp;
    loop = 1; //Ê״ε÷Óóõʼ»¯

    if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
    {
        next_time = timestamp + wait;
    for (i = 0; i < LED_NUMS; i++)
    {
        WS281x_SetPixelColor(i,led_init);
    }
    if((led_init <0x0002f0) && (temp == 0))
    {
       led_init +=0x000010;
        if(led_init == 0x0002f0)
            temp=1; 
    }else{
        led_init -=0x000010;
        if(led_init == 0x000000)
            temp=0;
    }
   }
    
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);
}
void  Mode8_LED(uint8_t wait)//È«Â̺ôÎü
{
    static uint32_t led_init=0x000000;
    uint16_t i;static uint8_t temp =0;
    uint32_t timestamp = HAL_GetTick();
    static uint32_t next_time = 0;
    static uint8_t loop = 0;
    if (loop == 0)
        next_time = timestamp;
    loop = 1; //Ê״ε÷Óóõʼ»¯

    if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
    {
        next_time = timestamp + wait;
    for (i = 0; i < LED_NUMS; i++)
    {
        WS281x_SetPixelColor(i,led_init);
    }
    if((led_init <0xf00000) && (temp == 0))
    {
       led_init +=0x100000;
        if(led_init == 0xf00000)
            temp=1; 
    }else{
        led_init -=0x100000;
        if(led_init == 0x000000)
            temp=0;
    }
   }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);

}
void  Mode9_LED(uint8_t wait)//Ѭ»·
{
    static uint8_t temp =0,loop_A = 0;
    uint32_t timestamp = HAL_GetTick();
    static uint32_t next_time = 0;
    static uint8_t loop = 0;
    if (loop == 0)
        next_time = timestamp;
    loop = 1; //Ê״ε÷Óóõʼ»¯
    if ((timestamp > next_time)) // && (timestamp - next_time < wait*5))
    {
        next_time = timestamp + wait;
        if(loop_A == 0){
            WS281x_SetPixelColor(temp,0xf0000f);
            loop_A = 1;
        }
        else{
            WS281x_SetPixelColor(temp,0x000000);
            loop_A = 0;
            temp++;
            if(temp == LED_NUMS)
               temp=0;
        }
   }
    HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN);

    }

这时候基本功能已经完成大半了,和手机如何进行连接。有两种方案:1·使用ESp8266利用WIFI连接。优点是速度快。缺点是我不会。2·使用HC-06模块用蓝牙连接,优点是简单,缺点是速度太慢了。但是这里用这个完全就够了。

主机:用于向从机下发指令,能够搜索从机并主动建立连接的一方。

从机:用于接收主机下发的命令,不能主动建立连接,只能等别人连接自己。(HC-06只能工作在从机模式下。)

主从一体:能够在主机和从机模式间切换,即可做主机也可作从机。如:HC-05既可以设置为主机也可以设置为从机。

代码如下:

static void MX_USART2_UART_Init(void)
{

  /* USER CODE BEGIN USART2_Init 0 */

  /* USER CODE END USART2_Init 0 */

  /* USER CODE BEGIN USART2_Init 1 */

  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */

  /* USER CODE END USART2_Init 2 */

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

}

接下来就是重头戏,开始灯罩的设计。由于创造能力太差,我就雕刻的不咋好看,不过可以凑合着看:

1621302013367370.jpg

1621302030408021.jpg

3.完成

让我们一起看看效果原图吧!

1621302054269899.jpg

1621302069408735.jpg

1621302084851473.jpg

在宿舍,效果不是不很好。但是,谁收到都会感动哭了!




关键词: STM32     单片机     星空灯     电子DIY    

高工
2021-05-17 23:15:04     打赏
2楼

代码有点乱


高工
2021-05-17 23:15:25     打赏
3楼
已哭

工程师
2021-05-17 23:22:06     打赏
4楼

做的蛮好的


工程师
2021-05-17 23:33:53     打赏
5楼

厉害了


管理员
2021-05-19 17:15:16     打赏
6楼

感动不?
不敢动,不敢动


菜鸟
2021-05-20 10:13:34     打赏
7楼

现在STM32 功能强大, 哈哈


高工
2021-05-20 10:54:03     打赏
8楼

恭喜成功。


菜鸟
2021-05-28 09:31:01     打赏
9楼

代入感很强,我已经枯了


高工
2021-06-12 23:53:10     打赏
10楼

动手能力也太强了


共19条 1/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]