โ ๏ธ Content Warning
The imagery in this post depicts up close details of fungi including: mycelium at various stages, decomposition of organic material, such as wood and/or cardboard (specifically, Amazon boxes), gills of Blue, Golden and King Oyster mushrooms, fibrils of Chestnut mushrooms, teeth of Lion's Mane mushrooms and pores of Turkey Tail mushrooms.
Some imagery may be uncomfortable for those with Mycophobia, Trypophobia, a general aversion to macro images of fungi, or an affinity for Amazon boxes.
๐ Introduction
My goal with MycoBot is to enable the management of distributed micro farms, where each farm is controlled by a MycoBot, who can be influenced by each other, and controlled by a central web application.
Non-technically, enabling the growing of a sustainable food source, at scale, with limited available space is the main goal.
In this post I'm going to cover:
- A brief intro to Mycology
- Conditions for growing Gourmet Mushrooms
- The Tech Stack
- Shipping V1
- Scaling Up
- Conclusion
๐ฌ A Brief Intro to Mycology
Mycology is a branch of biology focusing on the study of fungi, and it's a wide-ranging topic consisting of many fields of study, such as fungal taxonomy, ecology, medical mycology, mycorrhizal symbiosis, fungal biotechnology, and mycological conservation.
We used to consider Mycology a branch of botany, until we discovered that evolutionary, fungi are more closely related to animals than plants.
Why study such a thing? Well, turns out, fungi are fundamental for life on earth. They are the sole decomposers of certain biochemical bonds, like lignin, the thing that holds wood together, certain pollutants like xenobiotics (essentially carcinogens), petroleum and many other complex hydrocarbon bonds.
As symbionts, via forming mycorrhizal relationships with many plants they foster the transfer of critical nutrients beneath the soil via a network of mycelium. Similar to how the internet works, or how distributed Erlang works ;). Maybe you're starting to see where two of my obsessions start to overlap.
Fungi have served us very well, ever heard of the genus Penicillium? Well, some members happen to produce what we call penecillin which was finally mass produced in 1944 just before the invasion of Normandy, playing a pretty significant role in the end of WWII. The wild part, a mouldy cantaloupe at a Peoria, Illinois market was found to be hosting the best strain for mass production. So next time you see some mouldy fruit, maybe it's of the genus Penicillium.
Conditions for growing Gourmet Mushrooms
So, how do they grow? What conditions will we need to reproduce, monitor and automate? What elements are involved?
Remember when I said fungi are closer to animals than plants? It gets weirder, we share some 50% of our DNA with fungi, they rely on oxygen to fruit and produce Co2 as a byproduct of decomposing the material they grow on.
Mushrooms, unlike plants, do not require sunlight to grow, they do not photosynthesize. They do require indirect light, or technically light of a certain spectrum, that of shade. You know how you always find them under a tree? They love the shade. So we need to mimic light of a similar color.
They also require relatively high humidity, 80-90%, to be exact. Finally, temperature is critical, the species we're talking about prefer a range of 55 - 65F (12 - 18C).
Imagine a fall day in the forest, it's usually cool and damp, these are the conditions we will try to create, monitor and maintain.
๐ค The Tech Stack
Enter Elixir, Nerves, Raspberry Pi, a bunch of hardware components and whole host of sensors. Here's my initial sketch of what I was setting out to build and automate:
All of the components required to create and maintain optimal conditions are there. We have:
- A fogger, with an auto fill valve, to regulate humidity.
- Fresh air intake.
- Venting, to remove excess Co2.
- Lighting, ~6500k roughly that of cool daylight.
- Circulation fans.
MycoBot takes in environment data through sensors and, along with other custom logic, manages all of the above to provide ideal conditions 24/7. Oh, all while sending sensor data to an Influx DB instance with PagerDuty hooked up to alert if critical conditions are met. Yes, I've been paged in the very early AM when humidity dropped or the temperature rose too high, but hey, I kept everything alive at least :|
Early Prototypes
I knew the end state I wanted, but I had a lot to learn and needed to validate my assumptions. Here's my first prototype, I had purchased a simple relay and a temperature and humidity sensor (that I later destroyed with too much humidity). My first milestone was to be able to turn the fogger on/off based on humidity dropping below ~90%:
Architecture
To me, it made so much sense to orient the design of MycoBot around the concept of telemetry. Once I had written the drivers and instrumented telemetry events, all I had to do was handle them:
# MycoBot.Inputs.SI7021 emits a 'read' event
def handle_event([:myco_bot, :si7021, :read], measurements, _meta, _config) do
Logger.debug("[MYCOBOT] Received reading from SI7021 #{inspect(measurements)}")
# MycoBot.Environment is a GenServer holding config state.
if measurements.humidity >= MycoBot.Environment.fetch(:max_humidity) do
# Humidity is high enough, turn the fogger off.
# MycoBot.GPIO is an abstraction to work with RPi gpio pins.
MycoBot.GPIO.down(9) # Fog
else
# Humidity is too low, turn the fogger on.
MycoBot.GPIO.up(9) # Fog
end
end
This is the pattern for any "input", where the input is usually a sensor, but can also be user input, for example I can change the max_humidity, or any environment config, from MycoBotUI (a separate Phoenix LiveView app):
def handle_event([:myco_bot_ui, :environment, :change], _measurements, meta, _config) do
Logger.debug("[MYCOBOT] [:myco_bot_ui, :environment, :change]: #{inspect(meta)}")
# Update the Environment state
MycoBot.Environment.set(meta.key, meta.value)
end
I'm very happy with how little coupling there is between inputs (sensors and UI) and outputs (GPIO, Relays, or UI). With this design it's so easy to add or swap out sensors.
Here are some of the drivers I wrote, I learned a lot about translating data sheets into functioning Elixir:
Shipping v1
Like I said, the first milestone, turn a fogger on and off. Here's my first setup, and it worked! I ended up using a RPi Zero for its built in wifi and small form factor:
I also experimented with Amazon boxes as a substrate (with nothing but shredded cardboard, we can grow food!), here, blue oyster mushrooms are growing ok using this very basic first attempt. If you look closely, they're a little fuzzy at the base of their stipe, a sign of conditions being not quite right. Specifically, there is not enough "FAE" (Fresh Air Exchange). The reason this happens is complex, but a simplified explanation is, when Co2 is higher, it must mean "we" are underground, or, "we" haven't yet reached high enough to fruit, if that's the case, continue to expand, otherwise, if Co2 is low, there must be fresh air about, FRUIT AND SPREAD SPORES! Luckily, there happened to be enough FEA, even if it wasn't perfect :)
There's another phenomena that occurs in this state as well, part of the lifecycle of mushrooms is a sort of "reverse decomposition", meaning, the fruiting body will decompose after it's spread it's spores and return back to a vegetative state and distribute mycorrhizae and start the whole reproduction cycle over. So, that fuzz you saw, is the organism testing it's environment and adapting. Here's another experiment I ran, literally grabbing trash wood chips from my neighborhood, inoculating it with Oyster Mushroom mycelium, and leaving it outside to do it's thing. I also threw a bunch of "dead" half decomposed oyster mushroom on top, you can see them "reversing" AND reproducing:
This technique is called a "bucket grow", the intention is to fruit out of smaller holes in the side, but I couldn't resist running the extra experiment on the top as well :)
Scaling Up
After destroying a few sensors, and my "Martha Tent" falling apart, it was time to take the next step, towards implementing the drawing in my notebook. It was time to work with high voltage from scratch... I was very Nerves(ous) ;)
Step 1
Get a beefy relay to handle 120v (in the US), wire up 4 (2) outlets. NOTE, this is my prototype, and these ARE NOT GFCI (ground fault circuit interrupter) outlets. GFCI outlets are what you find in your kitchen, and bathroom, basically, if theres a fault (you splash it with water), they cut the circuit at the source and won't burn down your house. Given MycoBot will be running in unknown conditions, using GFCI circuitry will be used in production units.
Step 2
Wire up GPIO, to also be wired up to the RPi, now MycoBot can flip 8 power sources on/off based on sensory input.
Then, box it up, and wire up the main power source / switch:
Double check wiring is connected (while NOT plugged in):
Setup Dev environment, now, I've got my larger prototype connected to my RPi 0, via my breadboard and can quickly iterate. Here, I'm using an LED lamp as my "fogger" stand in. You can also see my water proof humidity sensor, I used shrink rubber to waterproof the exposed bits... And this thing NEVER died, it can handle 90% humidity 24/7... the metal components did start to rust a bit, however.
Once I got everything mapped out on the breadboard, it's time to wire straight into the RPi 0, keeping my USB interface (how I'm flashing Nerves to the Rpi 0):
Here's the final MycoBot prototype, everything is attached and contained. That first outlet is always on, so the RPi is always powered:
That's kind of it, it works well enough to continue experimenting.
Scaling Up Production
Here's where my sketch starts to come to life, a much larger tent, with much higher capacity:
MycoBot is on the floor to the left of this image, now driving:
- Lighting on the correct cycle.
- Maintaining Humidity levels.
- Circulating fresh air, maintaining CO2 levels.
- Refilling fresh water for the fogger when the reservoir gets low.
- Triggering PagerDuty if: a. The temperature rises too high. b. Humidity drops too low.
At this point, the entire process is automated. Once colonized substrate is placed into this chamber, we will have several pounds of gourmet mushrooms within two weeks.
Here's what one side looks like, and not even at full capacity. These are 5lb "Masters Mix" blocks, over two flushes they will yield 3-5lbs each.
From top to bottom we have:
- Maitake (Grifola frondosa), also called โhen of the woodsโ.
- Lions Mane (Hericium erinaceus).
- Turkey Tail (Trametes versicolor).
- King Oyster (Pleurotus eryngii).
And some results:
Lions Mane
Chestnut:
King Oyster:
Golden Oyster:
Dinner: :)
Conclusion
As usual, the source is on github: jonlunsford/myco_bot and jonlunsford/myco_bot_ui - I unfortunately didn't get around to releasing the drivers as individual packages, I think by now there much better options available anyways.





















Top comments (1)
์ผ์์ UI ์ ๋ ฅ์ ๊ฐ์ ํ ๋ ๋ฉํธ๋ฆฌ ํ๋ฆ์ผ๋ก ๋ฐ๊ณ ์ถ๋ ฅ๊ณผ ๊ฒฐํฉ์ ๋ฎ์ถ ์ค๋ช ์ด ํฅ๋ฏธ๋ก์์. ์ต๋๋ก ์ผ์๊ฐ ์์๋ ๊ฒฝํ์ ์ฝ์ผ๋, ์ ์ ๋ฒ์์ ๊ฐ์ธ์ง๋ฟ ์๋๋ผ ๋ง์ง๋ง ์ธก์ ์ด ์ธ์ ๋ค์ด์๋์ง๋ UI์์ ๊ตฌ๋ถํ๋ฉด ์ด์์ ๋์์ด ๋ ๊ฒ ๊ฐ๋ค์. ์ผ์๊ฐ ๊ฐ์ ๋ณด๋ด์ง ์๋ ์ํฉ๊ณผ ์ค์ ํ๊ฒฝ ๋ณํ์ ๋ํ ์๋ฆผ์ ์ด๋ป๊ฒ ๋๋๊ณ ๊ณ์ ์ง๋ ๊ถ๊ธํฉ๋๋ค.