Prototyping a solution to detect food quality — a summary

George Soloupis
Google for Developers Europe
6 min readJun 11, 2022

Written by George Soloupis ML GDE.

This is a blog post that summarizes the effort to prototype a simple solution to detect food quality for people with impaired or loss of smell with the help of a single board computer (Raspberry Pi 4B), a bunch of simple air sensors and Machine Learning.

The idea came to me accidentally when a friend of mine told me that as a result of a bike crash, he had lost his sense of smell and sometimes he had to ask other people to smell his food to see if he should consume it. Having attended multiple IT events for machine learning, I have never heard of a solution for that problem and it made me think if the power of ML is so big that it can handle this situation. Having great bonds with the Athens GDG, I contacted some other brilliant developers and we teamed up to come up with a solution. We had great support from Google Developers as part of the Social Impact Fund and after a few online meetups, we concluded that we had to create a device that would be affordable, accurate and could be used by anyone with no knowledge of computers and programming.

Our first goal was to find solid yet inexpensive materials. Some of them were sensors with a soldered PCB, because no further cabling is required and the use of resistors and capacitors is necessary to create such a device. Check how MQ-X sensors are made and how they work at this article.

MQ-2 module.

We also needed an ADC (which stands for analog-to-digital converter). We decided to use an 8 channel MCP3008 module which was connected to the Raspberry’s enabled SPI serial connection.

MCP3008 converter.

The connection between the sensors and the ADC can be done either through a TTL which is a logic level converter or with a simple usage of resistors and voltage division to convert the 0 to 5V of the sensors’ output to the 0 to 3,3V the ADC expects. Either options should work fine.

Once you have a wiring, a library would be needed. It has to be installed to take advantage of the MCP3008 usage. The latest version of the software is called CircuitPython and has been uploaded here.

When everything is set up correctly you will end up with a breadboard that should look like this:

Breadboard and MQ-2 sensor.

You can find an extensive guide with all the details and code at this Medium blog post.

In addition to the work for a single sensor we had to find the info for the rest that we used in our experiment. The whole set up consists of these sensors:

  • MQ-2 (Methane, Butane, LPG, smoke)
  • MQ-3 (Alcohol, Ethanol, smoke)
  • MQ-4 (Methane, CNG Gas)
  • MQ-135 (Benzene, Alcohol, smoke)
  • MQ-6 (LPG, butane gas)
  • MQ-7 (Carbon Monoxide)
  • MQ-8 (Hydrogen Gas)
  • MQ-9 (Carbon Monoxide, flammable gasses)

After putting them on, the breadboard had this setup:

Breadboard with sensors.

Through the SPI interface of the Raspberry we started collecting data every one minute after placing the sensors above cheese.

Breadboard and cheese together.

We even created different prototypes with sensor on PCBs:

Electronic circuit with sensors.

and used it for the experiment:

Circuit over food.

Or sensors on simple sockets:

Sensors on sockets.

Check the schematic Akis Vlissidis has provided:

Schematic for the prototype.

You can find more info about the different sensors, their usage and code to use them at this Medium blog post.

Data had to be processed with TensorFlow (Machine Learning framework) to help us determine the quality of the food. For every experiment we were collecting data for one day.

Data in the form of a .csv file.

Inference inside Raspberry is done with the help of the tflite-runtime to save resources. By examining the installed version of that library we have to use the same TensorFlow one to process the data. The MCP3008 provides values from 0 to 65472 for every sensor due to the CircuitPython library that was used. We tag the first hours with number “0” and the final of the time with the number “1”:

Divided data.

A typical diagram of each sensor was like this:

MQ-3 diagram.

The train, validation and test data were created and we categorized the food as edible and non edible. Machine Learning once again proved its power by providing a model that was over 90% accurate!

Training and validation loss over time.

At the end we had a .tflite file that we could place inside the Raspberry and perform inference with raw sensors data at any time. For detailed information about the processing of the data follow along this Medium blog post.

Inference inside the Raspberry is done with the help of tflite-runtime. Limited resources of the Raspberry Pi forced us to use lighter solutions than installing the whole TensorFlow package. First we had to pay attention to the version of the package inside the single board computer. This version had to be used to train the Machine Learning model which would then be converted to tflite format.

After that, the procedure is pretty straightforward. We load the .tflite file and we feed the interpreter with the array of the data that we get directly from the sensors:

input_array = []            
for item in lst:
input_array.append(float(item))

test_features = np.array(input_array).astype(np.float32) test_features = np.expand_dims(test_features, axis=0)

# Load the TFLite model and allocate tensors.
interpreter = tflite_runtime.Interpreter(model_path="food_model_250.tflite") interpreter.allocate_tensors()

# Get input and output tensors details.
input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() print(input_details)
print(output_details)interpreter.set_tensor(input_details[0]['index'], test_features)
interpreter.invoke()

# The function `get_tensor()` returns a copy of the tensor data. # Use `tensor()` in order to get a pointer to the tensor. output_data = interpreter.get_tensor(output_details[0]['index']) print(output_data)

The output data is in the form of an array from which we get the max value. Then we pass the value to an android device so we have a visual result of the inference:

Android application with result.

Check a well written blog post from Konstantinos Michelis that analyses how you can connect the Raspberry with an android device.

Conclusion
With limited resources we are showing clearly that the power of Machine Learning is so big that it can process data of simple air sensors and output a score if the food is edible or not with the help of a small but handy Raspberry Pi. The full information and code snippets can be found at this Github repository.

Future improvements
1. Use different RL resistors to change the sensitivity of each sensor.
2. Experiment also with MQ-131, MQ-136, MQ-137, MQ138 sensors.
3. Shrink the size of the prototype.
4. Experiment with more than 8 sensors by enabling the 2nd SPI of the Raspberry.

Experiment:
Georgios Soloupis
Pharmacist, Senior Android developer, ML GDE.
LinkedIn
Github
Medium

Akis Vlissidis
IT Applications Manager/Folli Follie Group.
LinkedIn
Twitter
Github

Twitter

Android app:
Konstantinos Michelis
Freelancer Android Developer — Full-time engineer at Hellenic Air Force but working part-time on personal projects in Android since 2016.
Github
LinkedIn

Resources:
Dimitris Panagopoulos
Research (Pure) Mathematician, Data Science Professional
LinkedIn

George Kandilogiannakis
Computer Engineering — Informatics teacher
LinkedIn

--

--

George Soloupis
Google for Developers Europe

I am a pharmacist turned android developer and machine learning engineer. Right now I’m a senior android developer at Invisalign, a ML & Android GDE.