Building a DIY Wheat Protein Sensor with Raspberry Pi and Arduino
Here’s a complete English guide for building a wheat protein estimation device using Raspberry Pi + Arduino, based on visible/near-infrared (Vis/NIR) spectroscopy.
🌾 1) Concept Overview
Protein content in wheat kernels correlates with light absorption in the near-infrared region (NIR).
We measure reflected or transmitted light at several wavelengths and use a regression model (PLS) to estimate protein percentage.
🧠 System flow:
LEDs → Sample → Spectral Sensor → Arduino (data capture) → Raspberry Pi (data processing + display)
⚠️ Note: This is a calibration-based monitoring device, not a lab-accurate analyzer. Still, it’s great for real-time field or combine harvester use.
🔧 2) Hardware Components
Option A – Basic Prototype
- Raspberry Pi 4 (or Zero 2 W)
- Arduino Nano / Pro Mini (optional, for fast sensor reads)
- AS7341 multispectral sensor (visible + near IR, ~20€)
- White + NIR LEDs (940 nm)
- Tube enclosure with matte black interior
- DC-DC 12→5 V converter and I²C wiring
Option B – Recommended Field Version
- AS7265x “Triad” sensor (18 bands, 410–940 nm, ~80–100 €)
- NIR LEDs (940/1050/1200 nm) with constant current driver
- Simple in-line grain chute with quartz window
- Optional NIR photodiode for reference channel
Option C – Semi-Pro
- Mini spectrometer (e.g., Hamamatsu C12880MA)
- Diffraction optics or fiber input
- Stable NIR lamp source
- Higher precision, higher cost
⚙️ 3) Optical & Mechanical Setup
- LED at ~45°, sensor near perpendicular → diffuse reflection geometry.
- Paint interior black (to reduce stray light).
- Keep sample layer thickness consistent.
- Add temperature sensor for compensation.
- Protect window from dust (compressed air or brush).
🔌 4) Wiring (Example for AS7265x via I²C)
- VCC → 3.3 V
- GND → GND
- SDA → GPIO2
- SCL → GPIO3
- LEDs → current driver, controlled via GPIO or Arduino pin
- Arduino → USB serial connection to Pi
💻 5) Software Flow
Arduino (Sensor Reader)
include
include “AS7265X.h”
AS7265X sensor;
void setup() {
Serial.begin(115200);
Wire.begin();
if(!sensor.begin()) { Serial.println(“No sensor found”); while(1); }
sensor.setMeasurementMode(AS7265X_MEASUREMENT_MODE_6CHAN_CONTINUOUS);
sensor.setIntegrationTime(50);
sensor.setGain(AS7265X_GAIN_64X);
}
void loop() {
sensor.takeMeasurements();
Serial.print("{\"bands\":[");
for(int i=0;i<18;i++){
Serial.print(sensor.getCalibratedValue(i),3);
if(i<17) Serial.print(",");
}
Serial.println("]}");
delay(100);
}
Raspberry Pi (Python Data Processing)
import serial, json, time, numpy as np, joblib
ser = serial.Serial('/dev/ttyACM0', 115200, timeout=1)
pls = joblib.load('pls_model.pkl')
scaler = joblib.load('scaler.pkl')
while True:
line = ser.readline().decode('utf-8', 'ignore').strip()
if not line: continue
try:
x = np.array(json.loads(line)['bands']).reshape(1, -1)
x = scaler.transform(x)
y = pls.predict(x)[0, 0]
print(f"{time.strftime('%H:%M:%S')} Protein: {y:.2f}%")
except Exception:
pass
6) Calibration – The Key Step
- Collect grain samples during harvest under varied conditions (varieties, moisture).
- For each sample:
- Record 100–200 spectra (average them).
- Get lab reference protein values (Kjeldahl/NIR).
- Combine data:
- X = spectra; y = lab protein %.
- Preprocess:
- Apply SNV or 1st derivative (Savitzky–Golay).
- Train PLSRegression model (choose components via cross-validation).
- Validate with test set, report R² and RMSEP.
- Save model (
pls_model.pkl) and scaler (scaler.pkl) for deployment.
🌡️ Include grain moisture as a feature or ensure calibration covers similar moisture range.
🚜 7) Mounting on Combine
- Best location: clean grain elevator or outlet, where grain flows evenly.
- Use anti-vibration mount.
- Dust protection: glass window + low airflow cleaning.
- Power via 12 V→5 V converter.
- Keep LEDs/sensor cool.
💰 8) Cost Estimate (Option B)
| Component | Approx. Cost (€) |
|---|---|
| Raspberry Pi 4 | 70 |
| Arduino Nano | 8 |
| AS7265x sensor | 90 |
| NIR LEDs + driver | 30 |
| Enclosure / 3D print | 40 |
| Power + wiring | 30 |
| Total | ~250 € |

