cancel
Showing results for 
Search instead for 
Did you mean: 

DMX decoder using STM32 H7

llama47
Associate

Hello everyone,

I am trying to receiver a DMX frame using STM32 UART interrupts. I'm trying to receive the data byte-by-byte using a state machine logic. The problem I am facing here is that none of the debug LED code to toggles the LEDs when the program hits a certain point. I just need to decode the DMX code byte-by-byte to process the frame and detect the 'break' bit by the Error callback. Is the logic correct or do I need to find another solution? 

It would be massively helpful if anyone could help me with this. 

Here's the code (initialization code excluded and everything initialized as per DMX standard):

#define MAX_BYTES 10


volatile uint8_t current_bytes[MAX_BYTES];
volatile int byte_index = 0;

typedef enum {
WAIT_FOR_BREAK_BYTE,
BREAK_CONDITION,
WAIT_FOR_FIRST_BYTE,
READ_DATA
} USARTStates;

volatile USARTStates USART_state = WAIT_FOR_BREAK_BYTE; // Initialize the state to the initial state of the machine

volatile int IsBreak = 0; // Flag to indicate if a break has been detected

volatile uint8_t DMX_Buffer[513]; // The DMX data buffer; Plus 1 for the start byte.
volatile int DMX_Counter = 0; // Keeps track of the current byte number in the DMX sequence (0-512).
volatile int DMX_address = 1; // The address of the channel you want to listen to
volatile int DMX_index = 0; // Index for storing received DMX bytes in DMX_Buffer
volatile int DMX_channels = 512; // Maximum channels

volatile int valid_DMX = 0; // Flag to indicate if received DMX is valid. You can use this in other parts of your application.


volatile uint8_t DMX_val[10];

 


void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
uint32_t error = HAL_UART_GetError(huart);
if (error & HAL_UART_ERROR_FE)
{
IsBreak = 1;
DMX_Counter = 0; // Reset DMX counter
byte_index = 0; // Reset byte index for current_bytes
}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
switch (USART_state)
{
case WAIT_FOR_BREAK_BYTE:
// Managed by ErrorCallback for detecting break.
break;

case BREAK_CONDITION:
if (current_bytes[byte_index] == 0) // Check for the start code
{
USART_state = WAIT_FOR_FIRST_BYTE;
DMX_Counter = 1;
byte_index = 0; // Reset byte index for next bytes
}
else
{
USART_state = WAIT_FOR_BREAK_BYTE; // Not the start code, wait for next frame
}
break;

case WAIT_FOR_FIRST_BYTE:
byte_index++; // Increment index to store next byte
DMX_Counter++;
if (DMX_Counter == DMX_address)
{
DMX_index = 0; // Reset index for DMX_val
USART_state = READ_DATA;
}
break;

case READ_DATA:
DMX_val[DMX_index++] = current_bytes[byte_index];
DMX_Counter++;
byte_index++; // Increment index to store next byte
if (DMX_index == DMX_channels)
{
USART_state = WAIT_FOR_BREAK_BYTE; // All channels read, wait for next frame
}
break;
}

// Make sure not to overrun the array
if (DMX_Counter <= 512 && byte_index < MAX_BYTES)
{
HAL_UART_Receive_IT(&huart4, &current_bytes[byte_index], 1);
}
}

 

1 REPLY 1
RhSilicon
Lead

Check the docs, maybe it will help to understand the DMX512 logic:

http://www.emcu.it/STM32/Lighting-Control-using-DMX512-protocol-on-STM32/Lighting-Control-using-DMX512-protocol-on-STM32.html


I don't know if it can help in your case, but I found these videos about advanced debugging:

STM32CubeIDE Advanced Debug Features
https://youtube.com/playlist?list=PLnMKNibPkDnEDEsV7IBXNvg7oNn3MfRd6