Hard faults usually have to do with buffer overruns or bad or unassigned pointers.
Oops - Usage Fault is often due to misaligned addresses (non-four-byte boundaries) or zero-div.
UsageFault
A UsageFault is an exception that occurs because of a fault related to instruction execution. This includes:
an undefined instruction
an illegal unaligned access
invalid state on instruction execution
an error on exception return.
The following can cause a UsageFault when the core is configured to report them:
an unaligned address on word and halfword memory access
division by zero.
I’ll have a look at your code if you can narrow down how far your code runs before it happens.
e.g. add Serial.print() statements.
How long is your program running before it happens?
If you want to get into serious debugging you’d need a Programmer Shield or a JTAG/ST-LINK