STM32_03.StartCar_STM32F411CEU6

Start Car engine Controller

Car engine starter controller with LoRa communication. Reads temperature and battery voltage, sending data to the main control unit.

STM32F4CHALControl moduleAutomotiveLoRaTemperatureVoltageds18b20JSONCommunication

Project facts

  • Repository: STM32_03.StartCar_STM32F411CEU6
  • Board / area: STM32F411CEU6
  • Category: Embedded controller
  • Status: Public repository

Technical description

  • The firmware controls car engine starting through LoRa communication and reads data from temperature sensors and battery voltage monitors.
  • The system consists of an engine-starting control module, ds18b20 temperature sensors, ADC for battery voltage reading, and a LoRa module for communication.
  • The module handles LoRa commands to enable/disable the engine and sends data to the main unit: interior car temperature and battery charge level.
  • The project integrates hardware components with wireless communication, creating a complete automotive control module.
  • The code uses the cJSON library for parsing and transmitting data in JSON format, facilitating integration with the central system.

What happens in the code

Selected key mechanisms from the project code. This is not a full repository dump, but an analysis of the parts responsible for the main firmware logic.

  • The module controls car engine starting through LoRa communication and sends data to the main unit.
  • It uses ds18b20 temperature sensors for measuring interior car temperature and ADC for battery voltage readings.
  • LoRa communication handles enable/disable engine commands and sending system status data.
  • Data is transmitted in JSON format using the cJSON library, ensuring consistency and easy integration.
  • USART is used for debugging and transmitting diagnostic information from the module.
  • The module handles both receiving LoRa commands and sending data to the central unit.

Key code excerpts

The code is shortened to the parts that matter for understanding the project.

Temperature reading from ds18b20

Core/Src/ds18b20.c
float DS18B20_ReadTemp(void)
{
  uint8_t addr[8];
  uint8_t data[12];
  float temperature;
  
  if (DS18B20_Start() == 0) {
    DS18B20_WriteByte(DS18B20_SKIP_ROM);
    DS18B20_WriteByte(DS18B20_CONVERT_T);
    
    HAL_Delay(750);
    
    DS18B20_Start();
    DS18B20_WriteByte(DS18B20_SKIP_ROM);
    DS18B20_WriteByte(DS18B20_READ_SCRATCHPAD);
    
    for (int i = 0; i < 9; i++) {
      data[i] = DS18B20_ReadByte();
    }
    
    temperature = (float)((data[1] << 8) | data[0]) / 16.0;
    return temperature;
  }
  
  return -127.0;
}

The function reads temperature from the ds18b20 sensor. It performs a 1-Wire communication sequence, reads data from the sensor memory, and converts it to a float value.

Voltage reading from ADC

Core/Src/adc.c
float ReadBatteryVoltage(void)
{
  uint32_t adc_value;
  float voltage;
  
  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
  adc_value = HAL_ADC_GetValue(&hadc1);
  HAL_ADC_Stop(&hadc1);
  
  voltage = (adc_value * 3.3f) / 4095.0f;
  voltage = voltage * 2.0f; // Due to voltage divider (1:2)
  
  return voltage;
}

The function reads battery voltage using ADC. It performs conversion, transforms the digital value to volts, and applies correction for the voltage divider circuit.

Sending data via LoRa in JSON format

Core/Src/CommunicationMessagesV2.c
void SendCarStatusData(void)
{
  char json_buffer[256];
  cJSON *root = cJSON_CreateObject();
  
  float temperature = DS18B20_ReadTemp();
  float voltage = ReadBatteryVoltage();
  
  cJSON_AddNumberToObject(root, "temperature", temperature);
  cJSON_AddNumberToObject(root, "voltage", voltage);
  cJSON_AddStringToObject(root, "device_id", "car_engine_module");
  
  strcpy(json_buffer, cJSON_Print(root));
  cJSON_Delete(root);
  
  // Send via LoRa
  LoRa_SendData((uint8_t*)json_buffer, strlen(json_buffer));
}

The function creates data in JSON format containing temperature and voltage, then sends it via LoRa. It uses the cJSON library to generate the JSON structure.

Receiving LoRa command

Core/Src/CommunicationMessagesV2.c
void ProcessLoRaCommand(uint8_t *data, uint16_t length)
{
  cJSON *root = cJSON_Parse((const char*)data);
  
  if (root != NULL) {
    const char *command = cJSON_GetObjectItemCaseSensitive(root, "command")->valuestring;
    
    if (strcmp(command, "start_engine") == 0) {
      // Start engine logic
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_SET);
      SendAcknowledge("Engine started");
    } else if (strcmp(command, "stop_engine") == 0) {
      // Stop engine logic
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);
      SendAcknowledge("Engine stopped");
    }
    
    cJSON_Delete(root);
  }
}

The function processes received LoRa command. It parses the JSON data and performs appropriate actions depending on the command: starting or stopping the engine.