Across my project I made sure each part of my development was thoroughly tested, making sure that each section functioned properly. Below are the test cases and results.
| Test Case | Expected Result | Actual Result | Pass/Fail |
|---|---|---|---|
| Test if micro:bit turns on | micro:bit should turn on with a flashing orange light at the back | micro:bit turns on with flashing light | Pass |
| Test if code being uploaded to micro:bit is run | If code is run a circle should be displayed on micro:bit screen | Circle is displayed | Pass |
| Sensors connect to micro:bit and read data | A row of sensor values displayed in micro:bit website | Values displayed | Pass |
| Data sent over serial correctly | Code ran in VSCode prints each line of data as it received | Lines are printed out but are sometimes missing values or incorrectly formatted | Fail (fixed in next test case) |
| Data received over serial is discarded if values are incorrect | If a bad line is sent, code does not append it to .csv | Bad lines are not appended to .csv | Pass |
| Correct timestamp added to .csv line | Timestamp added with exact second | Timestamp added with exact second | Pass |
| Plotting software displays each sensor value graphed against time | Air humidity, soil moisture, temperature, light intensity and flame graphed against time | Graph is created with correct values | Pass |
| Test Case | Expected Result | Actual Result | Pass/Fail |
|---|---|---|---|
| Test if mean and standard deviation of each value is found for simulation | Mean and standard deviation printed to console | All values print the mean and standard deviation | Pass |
| Test if fire risk exceeds 50% that the pump and warning light turned on | Drying soil moisture sensor to increase fire risk should turn water pump on | Pump turns on when risk exceeds 50% | Pass |
| Test if Stats are displayed after simulation has run | Trees Burned, trees not burned, percentage of trees burned output to console | Stats outputted | Pass |
| Input | Result |
|---|---|
| 0,23,46,78,97 | Accepted |
| 0,3,67,2 | Rejected as only 4 values are present |
| 1,56,,45,79,,,86 | Rejected as extra commas are present |
| 156,4579,86 | Rejected as there is only 3 values |
Ran into a problem where my code was receiving bad data over serial from the micro:bit.
.csv lines were missing values, had extra commas, or too few commas. This in turn would break my modelling script as it returned an out-of-range error when fetching the values.
I looked online for anyone with a similar issue: Forum post
I found a forum post explaining that having the Makecode website open while my Python code was running was causing garbled values to be sent.
I fixed this problem by closing the Makecode website when my code was running. I also implemented a failsafe if bad values were sent. The addition to my code is shown here, highlighted in red
while True:
try:
line = ser.readline().decode(errors="ignore").strip()
timestamp = datetime.now()
# wildfire_risk_with_timestamp.py
#Read CSV and store values
parts = line.split(",")
light = (int(parts[0]))
temp = (int(parts[1]))
soil =(int(parts[2]))
air =(int(parts[3]))
("Adding New line of Values")
with open("artefact/log.csv", "a") as file:
file.write(f"{timestamp},{line}\n")
def wildfire_risk():
risk = (light/200 +
temp/100+
(1-(soil/100)) +
(1 - (air/100))) / 4
return risk
#Print results with timestamp
prob = wildfire_risk()
ser.write((str(prob) + "\n").encode()) #from my brain
print(f"{timestamp} → Wildfire Risk: {round(prob * 100)}%")
except Exception as e:
print("Bad line of data sent")
time.sleep(10)
continue
The algorithm I used to evaluate fire risk is
risk = (light/200) +
(temp/100)+
(1-(soil/100)) +
(1 - (air/100)) / 4Each value in my equation is read from the sensors. Temperature is generally read between 0 and 100 in the forest, so I divide it by 100 to ensure it is no bigger than 1.
To show this algorithm working, I will sample a line of data from my log.csv file
Timestamp, Light, Temperature, Soil Moisture, Air Humidity, Flame
2026-03-18 09:35:56.238918,93,25,77,16,0 Inputting these values gives
risk = (93/200) +
(25/100)+
(1-(77/100)) +
(1 - (16/100)) / 4
Solving this equation gives 0.446 or a 44.6% risk of fire
Higher soil moisture and air humidity values mean less chance of fire, which is why it is (1-soil_moisture) and (1-air_humidity). All values are divided by the max value that can be detected and then further divided by 4. This ensures the output risk of fire is a decimal between 0 and 1. This number is then multiplied by 100 to get the percentage value. You may notice that light is divided by 200, this is because the sensor had a tendency to read numbers almost exclusively in the 90's reacting very little to tests such as shining a torch on it, increasing only by 1 or 2 points
A limitation I overlooked in development was the possibility of negative temperature values. This could lead to a negative fire risk being returned, which would not break the code but logically does not make sense.