The BOR level nobody set: why our controllers reset when the farmer's motor starts
Contents
Field returns from farms in Tiruppur district. Controllers resetting at random, and some of them came back with the settings corrupted: pressure set point became 0, or the pump type changed by itself. Bench test: perfect, 2 weeks, zero resets. "Lab bench power supply never shows this. Farm shows it on day one only." I say this sentence to every new engineer now.
Going to site
One farm, 200 m of cable from the transformer to the pump house, a 7.5 HP motor started direct on line, and our controller on the same supply. Scope, two channels: CH1 on our 3.3 V rail, CH2 on the motor contactor coil. Trigger on CH2. Every motor start:
- Mains sags hard for a few cycles (long cable, big inrush current)
- Our cheap SMPS output droops, and the 3.3 V rail went down to 2.38 V for 34 ms
Why that is a problem
The STM32F4 brown-out reset (BOR) threshold is set in the option bytes. Factory default: BOR off. "Off" means only the power-on / power-down reset at around 1.8 V protects you. So between ~1.8 V and the voltage where the chip is actually happy, the MCU keeps running in a grey zone. Flash reads can go wrong, and if you are writing to flash at that moment (we save settings in emulated EEPROM when the user changes them, and also... at every motor start, to count starts, I know, I know), the write gets corrupted.
BOR level 3 on F4 is ~2.7 V. Below that the chip goes into reset cleanly instead of running half alive.
The fixes
1. Set BOR level 3 in the option bytes at first boot (or with STM32CubeProgrammer in production):
FLASH_OBProgramInitTypeDef ob = {0};
HAL_FLASH_OB_GetConfig(&ob);
if (ob.BORLevel != OB_BOR_LEVEL3) {
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
ob.OptionType = OPTIONBYTE_BOR;
ob.BORLevel = OB_BOR_LEVEL3; /* ~2.7 V */
HAL_FLASHEx_OBProgram(&ob);
HAL_FLASH_OB_Launch(); /* apply the new option bytes */
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}
2. PVD (programmable voltage detector) interrupt at ~2.9 V: when the rail starts falling, stop any flash write, save the run state to backup RAM, and wait. It is the early warning before BOR.
3. Settings stored double-buffered with CRC. Write the new copy, verify, then mark it valid. If power dies in the middle, the old copy is still good.
4. Stop counting motor starts in flash at the moment of the motor start. The most stupid write at the most stupid time. Now counted in RAM, saved every hour.
5. Hardware for the next revision: bigger bulk capacitor after the SMPS, and an SMPS with real hold-up time. The datasheet said 50 ms hold-up. I measured 12 ms.
Result: firmware update on 214 units in the field (by our service team with laptops, on bikes, in the sun, respect to them). Zero corrupted settings in the 2 months since. Resets still happen on the worst sites during motor start, but now they are clean resets, and the controller comes back in 300 ms with the right settings.
If your product goes to a farm, a factory, or anywhere with motors: set your BOR level. Today.
Get the best of #bare_metal weekly
One email each Monday with the most useful posts. No spam; unsubscribe in one click.
Comments
Sign in to join the conversation.
Sign in to comment