STM32 se conecta al puerto serie de la cámara OV2640 para mostrar la interfaz de video en la interfaz PyQt5 y usa MQTT para la visualización.

STM32 conecta la fuente de video OV2640 a la interfaz PyQt5
. Como entrada del modelo AI, la transmisión de video es muy importante. En este artículo, presentaremos cómo conectar el STM32 a la cámara OV2640 y conectar la transmisión de video a la interfaz PyQt5.

Conexión de hardware
Primero, necesitamos conectar la cámara OV2640 al STM32. Podemos utilizar los siguientes métodos de conexión:

OV2640 | STM32 ------|------ SIOC | PB8 SIOD | PB9 XCLK | PA8 PCLK | PA6 VSYNC | PA4 HREF | PA7 D0 | PC0 D1 | CP1 D2 | PC2 D3 | PC3 D4 | PC4 D5 | PB6 D6 | PB7 D7 | PA9

Código STM32
A continuación, debemos escribir el código STM32 para controlar la cámara OV2640 y transmitir el video a la PC. Podemos usar el siguiente código:

#incluir “stm32f4xx.h”
#incluir “stm32f4xx_gpio.h”
#incluir “stm32f4xx_rcc.h”
#incluir “stm32f4xx_dma.h”
#incluir “stm32f4xx_dcmi.h”

#definir BUFFER_SIZE 320 240 2

uint8_t buffer[BUFFER_SIZE];

vacío DCMI_Config(void)
{ DCMI_InitTypeDef DCMI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure;


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_DCMI);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &GPIO_InitStructure);

DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Falling;
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;
DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
DCMI_Init(&DCMI_InitStructure);

DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DCMI->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);

DCMI_Cmd(ENABLE);
DMA_Cmd(DMA2_Stream1, ENABLE);
DCMI_CaptureCmd(ENABLE);

}

int principal(vacío)
{ DCMI_Config();

while (1)
{
}

}
Código PyQt5
Finalmente, necesitamos escribir código PyQt5 para recibir la transmisión de video transmitida por STM32 y mostrarla en la interfaz. Podemos usar el siguiente código:

importar sys
desde PyQt5.QtWidgets importar QApplication, QWidget, QLabel
desde PyQt5.QtGui importar QImage, QPixmap
desde PyQt5.QtCore importar QTimer
importar serial

ser = serial.Serial('COM3', 115200)

clase App(QWidget):
def init (self):
super(). init ()
self.title = 'STM32 Video Stream'
self.left = 100
self.top = 100
self.width = 320
self.height = 240
self.initUI()

def initUI(self):
    self.setWindowTitle(self.title)
    self.setGeometry(self.left, self.top, self.width, self.height)

    self.label = QLabel(self)
    self.label.setGeometry(0, 0, self.width, self.height)

    self.timer = QTimer(self)
    self.timer.timeout.connect(self.update_frame)
    self.timer.start(1)

    self.show()

def update_frame(self):
    if ser.in_waiting > 0:
        data = ser.read(320*240*2)
        img = QImage(data, 320, 240, QImage.Format_RGB16)
        pixmap = QPixmap.fromImage(img)
        self.label.setPixmap(pixmap)

if name == ' main ':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
En este ejemplo, usamos el control QLabel de PyQt5 para mostrar la transmisión de video. También utilizamos un temporizador para actualizar la transmisión de vídeo periódicamente. Finalmente, usamos el puerto serie para conectarnos al STM32 y recibir la transmisión de video.

Resumir

En este artículo, presentamos cómo conectar STM32 a la cámara OV2640 y conectar la transmisión de video a la interfaz PyQt5. Este ejemplo puede ayudarlo a comprender cómo usar STM32 para controlar periféricos y transferir datos a una PC.

Si usa MQTT para transmitir transmisiones de video
, puede usar el modo de publicación/suscripción del protocolo MQTT. Los pasos específicos son los siguientes:

Escriba código en STM32 para convertir la transmisión de video en datos binarios y publique los datos en el servidor MQTT utilizando el protocolo MQTT.

Escriba código en el lado de la PC, use el protocolo MQTT para suscribirse a los datos de la transmisión de video desde el servidor MQTT y convierta los datos en una transmisión de video para su visualización.

Aquí hay un código de ejemplo simple:

Código STM32:

#incluir “stm32f4xx.h”
#incluir “stm32f4xx_gpio.h” #incluir “stm32f4xx_rcc.h

#incluir “stm32f4xx_dma.h”
#incluir “stm32f4xx_dcmi.h”
#incluir “MQTTClient.h”

#definir BUFFER_SIZE 320 240 2

uint8_t buffer[BUFFER_SIZE];

vacío DCMI_Config(void)
{ DCMI_InitTypeDef DCMI_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; DMA_InitTypeDef DMA_InitStructure;


RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC, ENABLE);
RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_DCMI, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource2, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource4, GPIO_AF_DCMI);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &GPIO_InitStructure);

DCMI_InitStructure.DCMI_CaptureMode = DCMI_CaptureMode_Continuous;
DCMI_InitStructure.DCMI_SynchroMode = DCMI_SynchroMode_Hardware;
DCMI_InitStructure.DCMI_PCKPolarity = DCMI_PCKPolarity_Falling;
DCMI_InitStructure.DCMI_VSPolarity = DCMI_VSPolarity_High;
DCMI_InitStructure.DCMI_HSPolarity = DCMI_HSPolarity_Low;
DCMI_InitStructure.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame;
DCMI_InitStructure.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b;
DCMI_Init(&DCMI_InitStructure);

DMA_InitStructure.DMA_Channel = DMA_Channel_1;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&DCMI->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)buffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);

DCMI_Cmd(ENABLE);
DMA_Cmd(DMA2_Stream1, ENABLE);
DCMI_CaptureCmd(ENABLE);

}

int principal(vacío)
{ DCMI_Config();

Network network;
MQTTClient client;
NetworkInit(&network);
MQTTClientInit(&client, &network, 30000, NULL, 0, NULL, 0);

char* address = "tcp://localhost:1883";
int rc = NetworkConnect(&network, address, 1883);
if (rc != 0) {
    printf("Failed to connect to MQTT broker: %d

", rc);
retorno -1;
}

MQTTMessage message;
message.qos = QOS0;
message.retained = 0;
message.payload = buffer;
message.payloadlen = BUFFER_SIZE;

while (1)
{
    rc = MQTTClientPublish(&client, "video_stream", &message);
    if (rc != 0) {
        printf("Failed to publish video stream: %d

", rc);
}
}
}
Código de PC:

importar paho.mqtt.client como mqtt
importar cv2
importar numpy como np

def on_connect(cliente, datos de usuario, banderas, rc):
print("Conectado con el código de resultado "+str(rc))
client.subscribe(“video_stream”)

def on_message(cliente, datos de usuario, mensaje):
datos = np.frombuffer(msg.payload, dtype=np.uint8)
img = cv2.imdecode(datos, cv2.IMREAD_COLOR)
cv2.imshow(“Transmisión de video”, img)
cv2 .esperaClave(1)

cliente = mqtt.Client()
cliente.on_connect = on_connect
cliente.on_message = on_message

cliente.connect(“localhost”, 1883, 60)

while True:
client.loop_forever()
En este ejemplo, utilizamos la biblioteca paho-mqtt para implementar la función de publicación/suscripción del protocolo MQTT. En el código STM32, utilizamos la biblioteca MQTTClient para publicar datos de transmisión de video en el servidor MQTT. En el código del lado de la PC, usamos la biblioteca OpenCV para convertir datos binarios en transmisiones de video y usamos el protocolo MQTT para suscribirnos a los datos de la transmisión de video desde el servidor MQTT.

Resumir

En este artículo, presentamos cómo utilizar el protocolo MQTT para la transmisión de vídeo en streaming. Este ejemplo puede ayudarlo a comprender cómo utilizar el protocolo MQTT para implementar el modo de publicación/suscripción y transmitir datos de transmisión de video a la PC para su visualización.

Supongo que te gusta

Origin blog.csdn.net/qq_56152172/article/details/129672576
Recomendado
Clasificación