Diseño basado en trabajos stm32: luz ambiental multifuncional, control inalámbrico de aplicación móvil ws2812, programa de actualización inalámbrica MCU

Del 27 de octubre de 2021 al 1 de enero de 2022, podemos realizar el diseño de una microcomputadora de un solo chip. Si está interesado, puede agregar Q2809786963.

Work Bilibili Video: https://www.bilibili.com/video/BV1Yb4y1a7AQ#reply5536921990
Enlace de datos:
Bluetooth Lantern v1.01 Enlace de datos:
CSDN:
https://download.csdn.net/download/mbs520/ 25149435
Disco de red Baidu :
https://pan.baidu.com/s/14Vout7Q2P6JBDZCCd8Gm6w
Código de extracción: b7it

Enlace de datos de linterna Bluetooth v1.03:
https://download.csdn.net/download/mbs520/25150035
Quítatelo y recuerda darle me gusta~
Si tiene alguna pregunta, puede publicarla en el área de comentarios o mensaje privado.
inserte la descripción de la imagen aquí

1. Antecedentes laborales

En la era inteligente de 2021, todos los jóvenes amigos sufren de pereza, y yo también.
Una noche de insomnio, encendí la gloria del rey. Estoy acostumbrado a jugar con la luz de mi teléfono móvil, lo que puede reducir el daño a mis ojos. Finalmente, gané varios juegos. El tiempo llegó a las 2:30 en por la mañana. Empecé a sentirme somnoliento. Cuando colgué el teléfono y estaba a punto de cerrar los ojos y quedarme dormido, descubrí que las luces eran extraordinariamente deslumbrantes y me molesté. Realmente no quería presionar el interruptor que solo se puede alcanzar después de levantarse de la cama y caminar unos pasos, pero el diseño de la habitación es así, no se puede cambiar. Indefenso, todavía luché por levantarme de la cama y presioné el interruptor, y luego me quedé dormido con tranquilidad.
Como estudiante de electrónica, no me comprometo. Debo diseñar una luz que se pueda apagar sin levantarme de la cama.

2. Proceso de diseño e implementación de funciones

(1) Diseño funcional
1. Los botones se pueden usar para controlar el encendido y apagado de las luces, el brillo y el cambio de color
2. Los botones se pueden usar para controlar más de 6 estilos de visualización de luces
4. Diseña una carcasa para que sea más hermosa
5. Diseñe una aplicación de teléfono móvil, realice todas las funciones de los botones y ajuste cualquier color de la luz
6. Diseñe una aplicación móvil para actualizar la función del programa MCU, que puede guardar el programa MCU en una determinada versión de la aplicación móvil, y haga clic la actualización en la aplicación móvil para completar la actualización del programa MCU.
(2) Proceso de implementación
1. Diseñe un botón para conectarse con la MCU, escriba un botón multifunción (un solo clic, doble clic, pulsación prolongada) para controlar el encendido y apagado de la luz, el brillo y el cambio de colores y más de 6 estilos de visualización

2. Use CAD para dibujar una carcasa que tenga el tamaño correcto para la PCB y entréguela a Taobao para que la personalice.

3. Escriba una aplicación de Android con QT, use el módulo Bluetooth para comunicarse con el microcontrolador y complete las funciones de control y actualización

3. Realizar funciones básicas

(1), el primero es seleccionar materiales

1. Selección de LED:
dado que WS2812 quiere hacer luces de cualquier color, no hay duda de que las luces RGB a todo color de 24 bits WS2812 más comunes pueden emitir 2^24 = 16777215 colores.
inserte la descripción de la imagen aquí

2. Selección de microcomputadora de un solo chip: STM32G0
es, por supuesto, considerado para su propio bolsillo cuando las MCU son tan raras y costosas. El reloj de conducción de WS2812 necesita alrededor de 800 KHZ, y el requisito de velocidad es muy alto. Primero, elija stm32. Después de mirar al precio, elige amable stm32g030c8t6, ​​6 yuanes y envío gratis
inserte la descripción de la imagen aquí
3. Selección del módulo de comunicación: el módulo Bluetooth JDY-31
necesita un teléfono móvil para controlar las luces, primero piense en usar un módulo Bluetooth, teniendo en cuenta el precio, elija el más barato Módulo Bluetooth JDY-31 en toda la red, en comparación con HC-05, es más pequeño, pero la velocidad de conexión no es muy rápida
inserte la descripción de la imagen aquí

Con estos 3 materiales principales, podemos comenzar a diseñar el diagrama esquemático

(2) diseño esquemático

1. La microcomputadora de un solo chip necesita una fuente de alimentación de 3,3 V. Primero, diseñe una parte de la fuente de alimentación, primero use usb para suministrar 5 V a ws2812 y luego use un chip reductor para reducir a 3,3 V para suministrar MCU.
inserte la descripción de la imagen aquí

2. Diseñe un sistema de microcomputadora mínimo de un solo chip y reserve una interfaz de descarga, lo cual es conveniente para usar ST-LINK para descargar programas.3.Luego
inserte la descripción de la imagen aquí
conecte un Bluetooth y un botón como control, y reserve un LED como luz indicadora 4.
inserte la descripción de la imagen aquí
Diseño del circuito de luces RGB, aquí dos grupos de LED están controlados por dos puertos IO para evitar la distorsión de la señal causada por demasiados LED.
inserte la descripción de la imagen aquí
Este diagrama esquemático está diseñado.

(2), la primera versión del diseño de PCB

1. De acuerdo con el diagrama esquemático, importe el paquete correspondiente en la PCB, luego realice el diseño y el cableado, y diseñe un
dibujo de PCB 2D que se pueda imprimir para el servicio al cliente de Taobao:
inserte la descripción de la imagen aquí

3D:
inserte la descripción de la imagen aquí
Entonces entrégaselo a Taobao, aquí recomiendo Jiali Chuang, que es barato y de alta calidad.
Aquí está la primera PCB impresa:
inserte la descripción de la imagen aquí

(3), placa PCB de soldadura

1. Después de imprimir la PCB, por supuesto, necesita soldar los componentes a la placa PCB. Al soldar la primera placa, no necesita soldarlas todas a la vez. Primero, suelde la parte de potencia para ver si El chip de alimentación puede funcionar normalmente.Por ejemplo, I El paquete de la toma USB hembra de la placa dibujada no corresponde al diagrama esquemático, lo que resulta en la inversión directa de los polos positivo y negativo, lo que puede dañar fácilmente los componentes. Después de probar que el voltaje es normal, soldar otros componentes.

inserte la descripción de la imagen aquí

(4) Escritura de programas MCU

El programa MCU contiene mucho conocimiento
1. Sistema multitarea ligero
2. Protocolo de control personalizado de datos Bluetooth,MCU de actualización inalámbrica Bluetooth
3. Múltiples botones de modo de control + Bluetooth
4. Botones multifunción, un solo clic, doble clic, pulsación larga
5. Control de la serie ws2812
6. Algoritmo de luz de respiración
7. Algoritmo de gradiente de color
...

/****************************************
* 函数名称: DIS_TASK()
* 输入参数: 无
* 输出参数: 无
* 功    能: 显示任务
*
*****************************************/

void DIS_TASK(void)
{
    
    
	static u8 r=0,g=0,b=0,a=0,dir=0;
	static int i,cnt=0;
	static int color_rgb;
    SCHTaskBegin(); //开始固定格式一定要的
    while (1)
    {
    
    
		if(SysState.Dis_flag == 1)//可以更新显示
		{
    
    
					/***********************静态*******************************/
					if(SysState.Dismode == DisMode_Static)//静态
					{
    
    
						SysState.Dis_flag = 0;
						RGB_Refresh(SysState.StaticRgb,LED_NUM);//显示
						RGB2_Refresh(SysState.StaticRgb,LED_NUM);//显示
					}
					
					/***********************呼吸*******************************/
					else if(SysState.Dismode == DisMode_Breathe)//呼吸
					{
    
    
						SysState.Dedlay_Time=20;
						if(dir==0)
						{
    
    
							a += (1+a*10/0xff);
							if(a > 0xf0)dir = 1;
						}else if(dir)
						{
    
    
							a -= (1+a*10/0xff);
							if(a <= 4)dir = 0;
						}
						
						r = ((SysState.StaticRgb>>16)%0x100)*a/0xff;
						g = ((SysState.StaticRgb>>8)%0x100)*a/0xff;
						b = ((SysState.StaticRgb>>0)%0x100)*a/0xff;
						color_rgb = (r<<16) + (g<<8) + b;
						printf("%d %d %d %d\r\n",r,g,b,a);
						RGB_Refresh(color_rgb,LED_NUM);//显示
						RGB2_Refresh(color_rgb,LED_NUM);//显示
						SCHCurTaskDly(SysState.Dedlay_Time);
					}
					
					/***********************闪烁*******************************/
					else if(SysState.Dismode ==DisMode_Twinkle)//闪烁
					{
    
    
						SysState.Dedlay_Time=200;//*SysState.Dedlay_Ratio/0x0f;;
						RGB_Refresh(SysState.StaticRgb,LED_NUM);
						RGB2_Refresh(SysState.StaticRgb,LED_NUM);
						SCHCurTaskDly(SysState.Dedlay_Time);
						RGB_Refresh(0,LED_NUM);
						RGB2_Refresh(0,LED_NUM);
						SCHCurTaskDly(SysState.Dedlay_Time);
					}
					
					/***********************渐变*******************************/
					else if(SysState.Dismode ==DisMode_GraChange)//渐变
					{
    
    
						extern u8 GraChange_flag;
						SysState.Dedlay_Time=100;//*SysState.Dedlay_Ratio/0x0f;
						RgbAlg(&SysState.StaticRgb,&GraChange_flag);//渐变算法
						RGB_Refresh(SysState.StaticRgb,LED_NUM);//显示
						RGB2_Refresh(SysState.StaticRgb,LED_NUM);//显示
						SCHCurTaskDly(SysState.Dedlay_Time);
					}
					
					/***********************蹦迪*******************************/
					else if(SysState.Dismode == DisMode_DiscoDance)//蹦迪
					{
    
    
						SysState.Dedlay_Time=20;//*SysState.Dedlay_Ratio/0x0f;
						RGB_Refresh(Static_DisColor[cnt],LED_NUM);
						RGB2_Refresh(Static_DisColor[cnt],LED_NUM);
						SCHCurTaskDly(SysState.Dedlay_Time);
						RGB_Refresh(0,LED_NUM);
						RGB2_Refresh(0,LED_NUM);
						SCHCurTaskDly(SysState.Dedlay_Time*50);
					}
					
					/***********************流水*******************************/
					else if(SysState.Dismode == DisMode_RunWater)//流水
					{
    
    
						static int i=0,flag=0;
						SysState.Dedlay_Time=100;
						i++;
						if(i == LED_NUM)
						{
    
    
							i=0;flag=!flag;
						}
						if(flag){
    
    		//设置颜色		
							RGB_Refresh(SysState.StaticRgb,i+1);
							RGB2_Refresh(SysState.StaticRgb,i+1);
							SysState.Dedlay_Time=50;//*SysState.Dedlay_Ratio/0x0f;
							SCHCurTaskDly(SysState.Dedlay_Time);
						}
						else{
    
    		//灭
							RGB_Refresh(0,i+1);
							RGB2_Refresh(0,i+1);
							SysState.Dedlay_Time=50;//*SysState.Dedlay_Ratio/0x0f;
							SCHCurTaskDly(SysState.Dedlay_Time);
						}
						
					}
					
					/***********************用户*******************************/
					else if(SysState.Dismode ==DisMode_User1)  //用户
					{
    
    
						SysState.Dedlay_Time=1000;
						RGB_Refresh(SysState.StaticRgb,1);
						RGB2_Refresh(0,1);
						SCHCurTaskDly(SysState.Dedlay_Time);
						RGB2_Refresh(SysState.StaticRgb,1);
						RGB_Refresh(0,1);
						SCHCurTaskDly(SysState.Dedlay_Time);
					}
		}
		SCHCurTaskDly(10);
    }
    SCHTaskEnd();  //结束固定格式一定要的
}

(5) Verificación del programa de descarga

Pruebe si ws2812 funciona normalmente después de descargar el programa

4. Diseño de carcasa

(1) diseño de dibujo CAD

Siente que sería feo sin un caparazón, agrega un caparazón y haz que el mundo sea hermoso
inserte la descripción de la imagen aquíinserte la descripción de la imagen aquí

El agujero en el medio es del tamaño incorrecto: 5 por 7 en lugar de 7 por 7

inserte la descripción de la imagen aquí

(2) tablero acrílico esmerilado

Taobao busca la personalización de la placa acrílica esmerilada, envía el dibujo CAD al maestro y se puede hacer para ti.Esta
es una placa acrílica terminada, que se adapta de acuerdo con el tamaño de la placa PCB.
inserte la descripción de la imagen aquí

5. Rediseñar la PCB

Rediseñe y diseñe la tercera versión de la placa terminada: PCBV1.3
inserte la descripción de la imagen aquí
Esta es la apariencia soldada después de la prueba:
inserte la descripción de la imagen aquí

6. Diseño de la aplicación Android QT

(1) Diseño de interfaz

inserte la descripción de la imagen aquí

(2) diseño del programa QT

Mostrar algo de código:


MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    
    
    this->Start_Init();
    this->File_Init();
    this->BuleTooth_Init();
    this->Label_Init();
    this->PushButton_Init();
    this->ColorSlider_Init();
    this->setFocus();
}

MainWindow::~MainWindow()
{
    
    
    bin_save(FileInfo);
    delete ui;
}

//起始代码
void MainWindow::Start_Init()
{
    
    
    //设置背景图片
    this->setStyleSheet("QMainWindow{border-image: url(:/pic/btmenuv2.jpg);}");
    //获取屏幕大小
    QScreen *screen = QApplication::screens().at(0);
    src_w = screen->size().width();
    src_h = screen->size().height();
    if(src_w <= 0  || src_h <= 0)
    {
    
    
        src_h = 2267;src_w = 1080;
        this->setGeometry(0,0,src_w,src_h);//1080   2267
        qDebug() << "src get err ======== "<< src_w <<src_h << endl;
    }
    else
    {
    
    
        this->setGeometry(0,0,src_w,src_h);//1080   2267
        qDebug() << "src get ok ======== "  << src_w <<src_h << endl;
    }

}

//蓝牙初始化
void MainWindow::BuleTooth_Init(void)
{
    
    
    //蓝牙连接初始化代码
    timer_conflag = new QTimer;
    ptimer = new QTimer;
    //QBluetoothDeviceDiscoveryAgent 这个是指扫描周围蓝牙设备!
    discoveryAgent = new QBluetoothDeviceDiscoveryAgent();
    //QBluetoothLocalDevice 是指配置获取设备的蓝牙状态信息等!
    localDevice = new QBluetoothLocalDevice();
    //QBluetoothSocket指进行链接蓝牙设备,读写信息!
    socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);

    //多窗口初始化
    btcwindow = new BTMainWindow(this);
    btcwindow->hide();
    aboutwindow = new AboutMainWindow(this);
    aboutwindow->hide();

    connect(socket,
           SIGNAL(readyRead()),
           this,
           SLOT(readBluetoothDataEvent())
           );
    connect(socket,
           SIGNAL(connected()),
           this,
           SLOT(bluetoothConnectedEvent())
           );
    connect(socket,
           SIGNAL(disconnected()),
           this,
           SLOT(bluetoothDisconnectedEvent())
           );

    localDevice->powerOn();//打开蓝牙
    discoveryAgent->start();//开始扫描
}




//颜色条初始化
void MainWindow::ColorSlider_Init(void)
{
    
    
    QColor color;
    color.setRgb(0x00,0x00,0x00);
    colorslider_R = new ColorSlider(this);
    colorslider_G = new ColorSlider(this);
    colorslider_B = new ColorSlider(this);
    colorslider_A = new ColorSlider(this);

    colorslider_R->init(ColorSlider::RGB,ColorSlider::RED,color,0x00,0xFF);qDebug() << color << endl;
    colorslider_G->init(ColorSlider::RGB,ColorSlider::GREEN,color,0x00,0xff);qDebug() << color << endl;
    colorslider_B->init(ColorSlider::RGB,ColorSlider::BLUE,color,0x00,0xff);qDebug() << color << endl;
    colorslider_A->init(ColorSlider::RGB,ColorSlider::ALPHA,color,0x00,0xff);qDebug() << color << endl;

    colorslider_R->setGeometry(100,200,880,60);
    colorslider_G->setGeometry(100,400,880,60);
    colorslider_B->setGeometry(100,600,880,60);
    colorslider_A->setGeometry(100,800,880,60);
}
//按钮初始化
void MainWindow::PushButton_Init(void)
{
    
    
    //刷新定时器
    static QColor last_Color;
    time1= new QTimer(this);
    time1->start(1000);
    connect(time1,&QTimer::timeout,[=](){
    
    

       time1->start(100);
       if(Connect_Flag == 1)//连接指示
       {
    
    
           Connect_Flag = 0;
           btcwindow->hide();
           this->show();
           QMessageBox::information(this,tr("提示"),tr("蓝牙连接成功!"));

           QByteArray arrayData;    //发送空指令
           QString s = QString("NONE\r\n");
           qDebug() << s << endl;
           arrayData = s.toUtf8();
           socket->write(arrayData);
           s.clear();
           arrayData.clear();
       }
       if(last_Color != Color_sum)//发送指令
       {
    
    
           update();//更新
           unsigned int color_d =   ((Color_sum.alpha()/16)<<24)+(Color_sum.red()<<16) + (Color_sum.green()<<8)
                         + (Color_sum.blue()<<0) ;
           QByteArray arrayData;
           QString s = QString("COLOR:%1\r\n").arg(color_d);
           qDebug() << s << endl;
           arrayData = s.toUtf8();
           socket->write(arrayData);
           s.clear();
           arrayData.clear();
       }
       last_Color = Color_sum;

    });
    //色块按钮
    // QPushButton *phbutton[10];
    for(int i=0; i<10; i++)
    {
    
    
        int r,g,b;
        r = FileInfo->color_tab[i]>>16;
        g = (FileInfo->color_tab[i]>>8)%256;
        b = FileInfo->color_tab[i]%256;
        phbutton[i] = new QPushButton(this);
        if(i<5)phbutton[i]->setGeometry(90+i*200*src_w/1080,1600*src_h/2267,100*src_w/1080,100*src_h/2267);
        else if(i>=5)phbutton[i]->setGeometry(90+(i-5)*200*src_w/1080,1800*src_h/2267,100*src_w/1080,100*src_h/2267);
        QString s = QString("background-color: rgb(%1, %2, %3);").arg(r).arg(g).arg(b);
        phbutton[i]->setStyleSheet(s);
        phbutton[i]->setWindowFlags(Qt::WindowStaysOnTopHint);
        connect( phbutton[i],&myPushButton::clicked,[=](){
    
    
            int r,g,b;
            if(SaveColorFlag != 0)
            {
    
    
                r = Color_sum.red();
                g = Color_sum.green();
                b = Color_sum.blue();
                SaveColorFlag = 0;
                update();
                FileInfo->color_tab[i] = (r<<16)+(g<<8)+b;
                QString s = QString("background-color: rgb(%1, %2, %3);").arg(r).arg(g).arg(b);
                phbutton[i]->setStyleSheet(s);
            }
            else
            {
    
    
                r = FileInfo->color_tab[i]>>16;
                g = (FileInfo->color_tab[i]>>8)%256;
                b = FileInfo->color_tab[i]%256;
                Color_sum.setRgb(r,g,b,Color_sum.alpha());
                ColorSlider_paint_Flag = 2;
            }
        });
    }

(3) diseño de función de aplicación

1. Función de interfaz principal

botón Función descriptiva
boton conectar Ingrese a la interfaz de conexión Bluetooth/haga doble clic para conectar el dispositivo
sobre el botón Ingrese la interfaz MCU de introducción/actualización de software
control deslizante rojo Ajustar el tinte rojo
control deslizante verde Ajustar el tinte verde
control deslizante azul Ajustar tinte azul
deslizador gris Ajustar el brillo general
bola de vista previa de color Vista previa del color de visualización actual
Visualización rápida a color Haga clic para mostrar el color del botón
modo de visualización cambio de modo de visualización
Pantalla de información inferior Mostrar mensaje recibido/mensaje de bienvenida
Pantalla de información de conexión Mostrar estado de conexión actual

Primero haga clic en la bola de vista previa de color, aparecerá un cuadro de selección para guardar
y luego haga clic en el botón de selección de color para guardar el color ajustado actualmenteinserte la descripción de la imagen aquí

2. Interfaz de conexión Bluetooth

botón Función descriptiva
Selección de conexión de dispositivo Haga doble clic para conectar el dispositivo
botón de retroceso Volver a la página de inicio

1. La conexión es exitosa y vuelve automáticamente a la interfaz principal
2. Función de conexión automática: abra la aplicación sin ninguna acción, encuentre automáticamente el dispositivo de linterna Bluetooth y conéctese automáticamente, sin necesidad de conectarse manualmente
inserte la descripción de la imagen aquí

3. Sobre la interfaz

botón Función descriptiva
pantalla de información del autor solo lectura
botón de retroceso Volver a la página de inicio
mostrar versión La señal de respuesta de luz de color bluetooth, por ejemplo, la versión 1.2 parpadea con luz roja una vez y luz verde dos veces
Actualizar MCU Conecte el bluetooth, haga clic en actualizar, puede actualizar el software MCU a la versión actual, la versión del software es la misma, no actualice repetidamente, la actualización puede fallar
barra de progreso de actualización Mostrar el progreso de actualización Después de que falla la actualización de MCU, debe ingresar al modo de actualización para volver a actualizar; de lo contrario, no funcionará normalmente.
inserte la descripción de la imagen aquí

4. Solicitud de código de actualización

tipo de visualización Mostrar contenido
Actualización fallida La luz de bluetooth es roja
actualización exitosa La luz de color bluetooth muestra verde
proceso de actualización La luz de color bluetooth muestra el progreso azul claro

inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/mbs520/article/details/120368384
Recomendado
Clasificación