October 4, 2025

Hydro Dam, Part 2: Building the Dam Control System.


Posted on October 4, 2025 by admin

Part 2 of the hydro dam project: time to build some new stuff. Rather than attempt to get the dial-up-connected 1985 PLC control system to work, I decided to pursue a lifelong dream to have a nucleo connected to something way bigger than it really should be. A plan began to form. It was time to build a hydroelectric dam controller, nucleo edition.

At a high level, the control system of a dam has two functions. Firstly, the system must be operated correctly and safely, doing things like properly executing startup and shutdown routines, and shutting down if anything goes wrong. Secondly, the system must modulate the turbine to maximize facility output power with the changing water flow. If a nucleo can commutate a motor at 40kHz, if can certainly do this, although we may need the help of a few I/O multiplexers. Let’s get to it.

I laid out two boards, a site controller and a valve controller. The sum of them is by far the most complex EE project I’ve done in terms of number of things going on.

At the heart of the site is the main dam board, which manages the operation of the site. I spent about four months laying out this gigantic board. This board uses nearly every single pin on the nucleo, and in addition uses a total of nine multiplexers as well to get even more I/Os. At 360mm x 240mm, this is, for sure, by far the most large and complex board I have ever layed. The nucleo chosen was the Nucleo-H753, which is the biggest single core nucleo available. I have no idea how to program multiple cores, so single core it is. One core is more than enough for this, given that the core runs at 200MHz and the update rate of my loop here is only 100Hz. I guess a second core could allow for some error checking, but that’s what the valve controller is for. The STM32H753ZI has three ADCs and a ton of analog-capable pins. That was nowhere near enough though, this board has three 4:1 analog multiplexers on it, and the 4-20mA daughter cards all have 3:1 multiplexers as well. The nucleo also has loads of communication peripherals and timers, many of which I am using. The board actually really isn’t complex, but there is a lot going on.

I designed this board in EAGLE as I am faster at eagle than I am in Kicad. I designed this board to be extremely overkill, and have way too many I/Os, for as much future proofing as possible. One interesting topic is the many daughter boards on the board. I was too lazy to figure out how to use the “replicate layout” feature in eagle, so I just made any part I wanted to replicate as a physically separate board, and then I laid out that board as a footprint and put a few on there. This is a good idea for another reason: if any of the I/O modules get blown up, I can replace them as a unit, instead of replacing or having to rework the main board.

I got the SMD components placed by JLCBCB and soldered on the thru-hole parts. This was pretty nice.

This board does A LOT of stuff. Here are all the sections of the board, in roughly left-to-right order:

  • Top Left: Front Panel light switches. 12 outputs. These are PTC-protected 300mA SSRs. We may use LEDs on the front panel, or we may use the existing 110V bulbs. I didn’t have enough pins here so I used two shift registers. Annoyingly JLCPCB didn’t have these specific shift registers in their inventory, so I reflowed the tiny shift registers on myself.
  • Center left: front panel button inputs. 16 inputs. I wanted many inputs for future proofing. The I/O cards here have ESD protection diodes and RC filters to prevent static from killing the main board.
  • Lower left Molex mega-fits: 2X 24V PSU inputs. Dual for redundancy. Additionally, if one PSU dies, we can still safely control the dam, and shut it down. Both PSU inputs have fuses as well as voltage and current sensing.
  • Bottom left phoenix contact screw terminals: 24V outputs for whatever is needed.
  • Bottom center-left: non-isolated analog inputs. These were originally intended to go to isolated K-type thermocouple amplifiers, so we could sense the temperature of parts such as the turbine, transformers, etc. However, they can be used for anything really.
  • Top center-left: the nucleo. STM32H753ZI, the 144 pin behemoth. I could have probably laid this out with the bare chip, but I wanted to be able to replace the nucleo as a unit in case it got ESDed or something. This board also has ethernet if we want to do some serious control of something in the future.
  • Under the nucleo: dual SD-card data loggers. Upon further thought, two loggers is really not necessary, but the space is there. Maybe I could have once log once a day and another log only when things change.
  • Under the loggers: Atmospheric pressure and temperature sensors. We need to sense the depth of the pond, and one method of doing this is with water pressure sensors. The pond depth can be calculated by knowing the water pressure. However, the atmospheric pressure must be subtracted from this to get an accurate reading. It is also just good to know. Turns out, after some data logging, we now know that the turbine shack gets to nearly 100 degrees in the summer.
  • To the right of the loggers: some analog multiplexers. There are a lot of analog sensors on this board.
  • Top center of board: 2X isolated CAN transceivers for future expansion. Likely, one of these will talk to a VFD in the future.
  • Center of board: 2X SSD1309 OLED screens. Nice to know what the board is doing. The screens show important data such as grid voltages, currents, output power, main contactor status, valve status, and any fault codes.
  • Center-right: ESP32 for internet connectivity. At some point we may wish to export data from the dam directly onto the internet, or control the dam through a web interface. This is not currently programmed, but could be done in the future.
  • Bottom center-right, 4X cards: 12x isolated 24V 4-20mA sensor inputs. This is for 6 depth sensors and 6 future expansion sensors. Each card has a three-way multiplexer on it, which is in series with the other analog multiplexers on the main board- getting all these ADCs to fire right was very tricky for sure.
  • Bottom right: fiber optic TX and RX for talking to the valve controller. These transmit data over UART to and from the valve controller. The main board transmits a series of bytes in sequence to the valve board, along with the desired valve position. If the main board skips any of this specific sequence for more than a second, the valve controller assumes the main board has gone haywire, and closes the valve.
  • Right side, up from the fiber: 3X isolated hall-effect current sensors for measuring the generator phase current, through current transformers. These sensors are good for 10A, and the current transformers in the panel are 200:5, so 10A is fine. We plan to run at about 100A which maps to 2.5A on the transducer, but this is RMS, so having a 10A current sensor is about right.
  • Right side center: 4X contactor outputs. These contactors control the main contactor, the PFC capacitor relay, and a braking contactor for the motor.
  • Top right: Line voltage ADC. The line is 480V line to line, or 277 line to neutral. Designing a board with 480 (700 peak!!) on it is a bit above my pay grade, and we also did not want 480V wires going into the control side of the cabinet. So, we bought three 480V to 24V transformers and will use these to measure the line voltages. The biggest thing that this has to deal with is surges on the power line, such as if lightning strikes the power line, which is apparently not uncommon. We really do not want a pulse to get in and fry the nucleo. To deal with surges, we have many cascaded layers of protection. Firstly, the any pulse on the 12.7 kV line at the site would have to go through the main transformers. Then, we have the 480V to 24V transformers, which should add a bit more portection. If a pulse gets past this, it has to go through all the board protection. I have a 50mA fuse and a MOV. If the surge stays long enough, it will just blow the fuse as the MOV takes the power. Also, I have a 100k resistor divider, and a further TVS to clamp after the divider. On top of all this, I am using 6000V- rated analog isolators as a further step, so all three phases can float with respect to the rest of the board. So, I think it is very unlikely that a pulse will get through all of this and fry the nucleo.
  • Lastly, to the left of the contactors: a small buzzer. Beep-beep when there are errors.

I tried to design this board as well as I could for some amount of fault tolerance. Isolation helps a lot, in my experience at least if one side of an opto-isolator gets fried, the other side will be ok, so I used either optos or digital isolators for whatever I could. I was mostly worried about either the grid wires getting struck by lightning (which would put a pulse into the line voltage sensors), or the pond getting struck by lightning (which would put electrons up the depth sensors). The depth sensors are shielded, and we can ground the shield, and I guess the pond is grounded too, but still, I didn’t want to take any chances. One piece of advice I got from a very wise EE man was to put very small inductors in front of ESD protector diodes on all the inputs. If a pulse comes in, it can apparently be fast enough to get through before the ESD diodes turn on. So, the inductors slow down the pulse to where the ESD diodes will catch it. If not an inductor, then I used a big resistor. I used some fuses on the main power and contactor outputs, but if these blow, something is really wrong.

Kudos to the great Nick Sorenson for helping me with a design review.

The only thing that fell through the cracks on this whole board was that the contactor drive relays are driven by DRV103U chips, which switch the low side of the contactor, not the high side. I wired them in on the high side, silly me. I fixed with a quick bit of bodge wire:

I call this very good, one error for a board of this size is truly a miracle.

The second board I laid out was the valve controller. This was a bit more of a 3D board. This thing takes in commands over fiber-transmitted UART from the main board, and opens and closes the valve. This board also functions as the watchdog of the site. It has a 8000V-isolated relay which will be wired in series with the main contactor control drive. If the main dam board goes nuts and stops transmitting data to the valve board, this relay opens, which can shut off the site.

Here is the valve controller board.

This board was laid out in a bit of a rush, and so it didn’t go together quite as well as the others. Noticably, one of the buscaps on the upper left intersected with some of the zener diodes, so I chose not to install it. Too bad. I also hand-assembled these boards, because I was worried about tariffs. The battery fuse also kind of intersects the main board relay, so you have to bend it maybe 0.2mm to get it in.. not too bad. But, surprisingly, no bodge wires needed for this board.

Feature list for this board:

  • Bottom left: 48V PSU input. This input is fused and has series resistors. The idea here was that a 48V PSU would trickle-charge the battery through the resistors, but I think we’ll just put a CC/CV charger right on the battery, so this input won’t get used.
  • Right of the 48V PSU input: 48V battery input. As discussed before, the board is mainly powered by the batteries. This enables the valve to close even in the event of a total grid failure, which is critical for the site. This is where the real power comes in to power the board. It has one contactor for precharge and another for power. It also has a 50A fuse.
  • Right of the 48V batt input: motor phase output. This is just a normal H bridge situation. Low side shunts provide current feedback. The motor consumes about 10-20A, but I wanted overkill, so I put two fets in parallel.
  • One more right: motor field drive output. The motor is a wound-field motor, so it requires a field drive. This is a low side drive. In my testing the field consumes only about an amp.
  • Big white relay on the bottom: This is an 8kV rated isolation relay. This is the dead man’s switch for the main contactor. If the valve board stops receiving data over the fiber, it opens this relay.
  • Bottom right phoenix contact connector: limit switch input. There are big limit switches that sense the valve position. There are two switches per side for redundancy.
  • Right center of board: optical fiber TX and RX. These transmit data over UART to and from the main board. The main board commands a valve position, and the valve controller transmits the real measured valve position. If the valve controller does not receive a special character sequence every second, it assumes the main board has had a software crash, and it shuts the valve and opens the main contactor.
  • Top right conntector: Connector for valve position sense potentiometer, and thermal limit switch. The potentiometer senses the valve position. If the thermal limit switch opens, the motor has assumed to be overheated.

The Programming of the setup…..

The programming of the setup was substantial. There is about 2000 lines of C code, not including all the .h files and auto-generated setup garbage.

The code does these things:

  • Measure grid voltage, depth sensors, oil pressure sensors
  • See if any sensors are out of range, raise error flags if they are
  • Measure the front panel control buttons and see if we need to chagne the state
  • Run the state machine depending on front panel buttons and error flags.
  • Communicate with the valve controller.
  • Set the main contactor, PFC relay, brake relay, and hydraulic pump control contactors.
  • Set the front panel lights and the buzzer.
  • Update the screens.

The ADC setup for measuring the grid is also worth noting. I used ADC1 and ADC2 on the H7 to read the analog sensors, and dedicated ADC3 to only sampling the line voltages and currents. The main loop was run at 100Hz, but this is nowhere near fast enough to sample the voltage and current waveforms. So, ADC3 is setup to trigger off a timer and run at 6kHz. This ADC puts data into a buffer. When the main loop fires, it reads this buffer, and calculates the RMS voltage, peak voltage, RMS current, grid power, and grid frequency.

The Brake Relay

One interesting feature of our site is that we decided to modify the turbine to fix the blade pitch. This is definitely overall good, as its much less maintenance and simpler operation. However, it does leave the possibility for turbine overspeed if the grid suddenly drops. Apparently, it is not that uncommon for someone to drive a truck through a utility pole or something like that, which would likely result in all wires no longer being connected. The water continues to flow and exert torque, but all of a sudden the resistance drops to zero- get ready for exciting failure modes. Ideally, we could just shut off the water instantaneously, but this is not possible for two reasons. First of all, the valve takes about 30 seconds to close just because the motor is slow, and secondly, you wouldn’t even want to close it any faster, because you would get water hammer.

Let’s do some simple math, neglecting viscous losses. I assumed that the induction motor rotor has a rotary inertia of about 1kg*m^2. The turbine has a 5.6:1 speed increaser. If the roughly 2000Nm of torque we expect during operation continues to be applied to the prop, the induction motor rotor will spool up by 3600RPM per second, so in 2.5 seconds the rotor would almost certainly explode when the rotor hits 10k RPM. While there is probably enough oil whipping and water sloshing losses to prevent the motor and propeller from really going nuts, I’d prefer not to find out what the true maximum speed of the turbine really is, and if motor rotor detonation does or does not occur at this speed. So, we must figure out a brake.

For a BLDC motor, this is pretty easy: just place a resistor across any two phases and you have a motor brake. Induction motors are a little different. No back-emf is produced by just spinning the rotor, so instead we have to put some amps across two phases. This will turn the motor into an eddy current brake. So, we plan to have a battery, resistor, and contactor to drive some amps across the two phases of motor. This has yet to be implemented in the actual site.

Some more images of board stuff.

Some great protection on the daughter boards. The 4-20mA daughter boards also have 50mA overcurrent protection ICs.

So, now that we got some hardware in hands and some coding done, it is time to test stuff out. But, how on earth do you test a hydroelectric dam?? Especially when the prospect of motor rotor detonation is real??? Read more in the next post.


0