Firmware                                                                        Latest update 2024-08-19
 
In brief:
Some notes about the Arduino firmware in the Download Package.
I can give some support for the source code I provide here, but not for the development environment(s).

The firmware was made with the Arduino environment 1.8.16.

FW_jjmmdd.ino
contains setup(), loop() and a number of routines for the climate sensors, eeprom management, and diagnostics.

Meesages.cpp
handles the ETHernet communication with the PC-program (sometimes called GUI)

Globals.h
contains global variables and defininitions for I/O and dignostics.

BobControl.cpp

Most of the work is done in an interrupt routine ISR (TIMER1_COMPA_vect) called at a 10 kHz rate.
In successive calls the 7 AD-channels are converted, so we have effectively a 1.4 kHz sample frequency. I use 8 bit A/D conversions here.
The values from the Hall sensors are not further processed, they go into the message as is.

The workhorse is:  switch (State) { ....... }
The Center signal is at half-scale when the Bob is far away. When the Bob approaches, the signal rises at first and goes down through the midscale level when the Bob is exactly over the Center Coil. While waiting for this to happen the peak value is tracked and frozen until the message can be sent.
After the Center Pass has been detected the first message will contain the time of passing derived from the PositionCounter, which just counts 10 kHz ticks. Also the PositionCounter is set to zero to start a new sequence for timing the Drive pulse.

The Rim-1 signal also rises when the Bob approaches, but it is at its peak value when the Bob is just over the Rim Coil. So we track the signal while it rises and when it goes down again we freeze the Rim-1 Pass time and signal amplitude.
The Rim_1 passage time is used to calulate the amplitude of the swing. 
The Rim-2 works the same as Rim_1, but the signal is inverted because the bob approaches the rim coil from the outside.

Waiting for certain events is hold-off during certain times, in particular when the drive pulse is to be expected. This pulse will disturb the Center- and Rim sense signals.
We also have Time-Out criteria to decide that bob passes are much to late. This may lead to a ForceResync, where the statemachine is kicked to the state where evrything has to start again.

The signal for the Drive Coil is activated from TMidDrive - Width to TMidDrive + Width, where Width is either TMaximalDriveWidth or TMinimalDriveWidth, depending on the difference between the position measurement of the amplitude at the Rim_1 Passage and the setpoint.
So the DrivePulse is always centered around the setpoint.

The loop() function calls Update_Messages() which looks for incoming data from the GUI.
Every message is responded to, by sending all relevant information to the GUI.

Here and there diagnostic code was used during testing and debugging, most is commented out now.

Some code is preparing for operation with battery backup and charge management. Currently this is incomplete, not tested and not used.