Skip to content

Instantly share code, notes, and snippets.

@TobeTek
Last active July 23, 2025 15:31
Show Gist options
  • Save TobeTek/3d82e3860a266ec4b185f855fa95ff13 to your computer and use it in GitHub Desktop.
Save TobeTek/3d82e3860a266ec4b185f855fa95ff13 to your computer and use it in GitHub Desktop.
Soil Health Advisor - MATLAB App - Get AI powered advice on how to manage your farm for your crops
classdef app1_exported < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
GetAIpoweredinsightsforyourfarmLabel matlab.ui.control.Label
SoilHealthAdvisorLabel matlab.ui.control.Label
StatusIdleLabel matlab.ui.control.Label
TipsTextArea matlab.ui.control.TextArea
TipsTextAreaLabel matlab.ui.control.Label
GetTipsButton matlab.ui.control.Button
CropTypeEditField matlab.ui.control.EditField
CropTypeEditFieldLabel matlab.ui.control.Label
FarmFieldLocationEditField matlab.ui.control.EditField
FarmFieldLocationEditFieldLabel matlab.ui.control.Label
DepthValue0Label matlab.ui.control.Label
DepthofSoilTextureMeasurementcmSlider matlab.ui.control.Slider
DepthofSoilTextureMeasurementcmSliderLabel matlab.ui.control.Label
SoilTextureDropDown matlab.ui.control.DropDown
SoilTextureDropDownLabel matlab.ui.control.Label
end
% Internal soil texture data
properties (Access = private)
SoilTextureData % Table of texture classes and colors
end
methods (Access = private)
function setupSoilTextures(app)
app.SoilTextureData = table( ...
{'Sand'; 'Loamy Sand'; 'Sandy Loam'; 'Loam'; 'Silt Loam'; 'Clay Loam'; 'Clay'}, ...
{'#F4D35E'; '#F7B32B'; '#FAA916'; '#90BE6D'; '#43AA8B'; '#577590'; '#2F4858'}, ...
'VariableNames', {'Name', 'Color'});
app.SoilTextureDropDown.Items = app.SoilTextureData.Name';
% Each item colored accordingly (MATLAB dropdown does not support item coloring by default,
% so just set dropdown background color to selected color on value change:
app.SoilTextureDropDown.BackgroundColor = '#FFFFFF'; % default white
end
function updateDepthValueLabel(app)
val = round(app.DepthofSoilTextureMeasurementcmSlider.Value);
app.DepthValue0Label.Text = sprintf('%d cm', val);
end
function updateDropdownColor(app)
% Change dropdown background color to selected soil texture color (approximate UI feedback)
idx = find(strcmp(app.SoilTextureDropDown.Value, app.SoilTextureData.Name));
if ~isempty(idx)
color = app.SoilTextureData.Color{idx};
app.SoilTextureDropDown.BackgroundColor = color;
end
end
function onDropdownChanged(app, ~)
app.updateDropdownColor();
end
function onDepthSliderChanged(app, ~)
app.updateDepthValueLabel();
end
function fetchAndDisplayAITips(app)
% Collect user data
texture = app.SoilTextureDropDown.Value;
depth = round(app.DepthofSoilTextureMeasurementcmSlider.Value);
fieldName = app.FarmFieldLocationEditField.Value;
cropType = app.CropTypeEditField.Value;
if isempty(texture)
uialert(app.UIFigure,'Please select a soil texture class.','Input Required');
return
end
% Create prompt for AI assistance
prompt = sprintf(['I am a farmer with soil texture "%s" at %d cm depth. ', ...
'My field is called "%s" and I am growing "%s". ', ...
'Please provide practical tips to improve crop yield and soil health. Format without markdown (plain text). Keep response brief (1 paragraph) and useful and natural sounding. Offer next steps on things I the farmer should do'], ...
texture, depth, fieldName, cropType);
app.StatusIdleLabel.Text = 'Contacting AI service... please wait.';
drawnow;
% HuggingFace inference API public endpoint URL
api_url = 'https://api.groq.com/openai/v1/chat/completions';
api_token = '<REDACTED>';
requestBody = struct( ...
'model', 'llama-3.3-70b-versatile', ...
'messages', {{struct( ...
'role', 'user', ...
'content', prompt ...
)}} ...
);
% Setup web options without API key, JSON content type, 30s timeout
options = weboptions('MediaType','application/json', ...
'Timeout',30, ...
'HeaderFields', {'Authorization', ['Bearer ' api_token]} ...
);
try
response = webwrite(api_url, requestBody, options);
% Extract answer text
if isstruct(response) && isfield(response, 'choices') && ~isempty(response.choices)
if isfield(response.choices(1), 'message') && isfield(response.choices(1).message, 'content')
ai_advice = response.choices(1).message.content;
else
ai_advice = 'AI response message content not found.';
end
else
ai_advice = 'AI response choices not found or empty.';
end
catch ME
ai_advice = sprintf('Error calling AI service:\n%s', ME.message);
end
% Display or use ai_advice
app.TipsTextArea.Value = ai_advice;
app.StatusIdleLabel.Text = 'AI tips updated.';
end
end
% Callbacks that handle component events
methods (Access = private)
% Code that executes after component creation
function startupFcn(app)
setupSoilTextures(app);
end
% Button pushed function: GetTipsButton
function GetTipsButtonPushed(app, event)
app.fetchAndDisplayAITips();
end
% Value changed function: SoilTextureDropDown
function SoilTextureDropDownValueChanged(app, event)
% value = app.SoilTextureDropDown.Value;
app.onDropdownChanged();
end
% Value changed function: DepthofSoilTextureMeasurementcmSlider
function DepthofSoilTextureMeasurementcmSliderValueChanged(app, event)
% value = app.DepthofSoilTextureMeasurementcmSlider.Value;
app.onDepthSliderChanged();
end
end
% Component initialization
methods (Access = private)
% Create UIFigure and components
function createComponents(app)
% Create UIFigure and hide until all components are created
app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Color = [0.9176 0.9804 0.7843];
app.UIFigure.Position = [100 100 640 480];
app.UIFigure.Name = 'MATLAB App';
% Create SoilTextureDropDownLabel
app.SoilTextureDropDownLabel = uilabel(app.UIFigure);
app.SoilTextureDropDownLabel.HorizontalAlignment = 'right';
app.SoilTextureDropDownLabel.Position = [37 166 64 22];
app.SoilTextureDropDownLabel.Text = 'SoilTexture';
% Create SoilTextureDropDown
app.SoilTextureDropDown = uidropdown(app.UIFigure);
app.SoilTextureDropDown.ValueChangedFcn = createCallbackFcn(app, @SoilTextureDropDownValueChanged, true);
app.SoilTextureDropDown.Position = [116 166 100 22];
% Create DepthofSoilTextureMeasurementcmSliderLabel
app.DepthofSoilTextureMeasurementcmSliderLabel = uilabel(app.UIFigure);
app.DepthofSoilTextureMeasurementcmSliderLabel.HorizontalAlignment = 'right';
app.DepthofSoilTextureMeasurementcmSliderLabel.WordWrap = 'on';
app.DepthofSoilTextureMeasurementcmSliderLabel.Position = [37 108 115 44];
app.DepthofSoilTextureMeasurementcmSliderLabel.Text = 'Depth of Soil Texture Measurement (cm)';
% Create DepthofSoilTextureMeasurementcmSlider
app.DepthofSoilTextureMeasurementcmSlider = uislider(app.UIFigure);
app.DepthofSoilTextureMeasurementcmSlider.ValueChangedFcn = createCallbackFcn(app, @DepthofSoilTextureMeasurementcmSliderValueChanged, true);
app.DepthofSoilTextureMeasurementcmSlider.Position = [168 139 150 3];
% Create DepthValue0Label
app.DepthValue0Label = uilabel(app.UIFigure);
app.DepthValue0Label.FontAngle = 'italic';
app.DepthValue0Label.Position = [168 71 84 22];
app.DepthValue0Label.Text = 'Depth Value: 0';
% Create FarmFieldLocationEditFieldLabel
app.FarmFieldLocationEditFieldLabel = uilabel(app.UIFigure);
app.FarmFieldLocationEditFieldLabel.HorizontalAlignment = 'right';
app.FarmFieldLocationEditFieldLabel.Position = [31 217 111 22];
app.FarmFieldLocationEditFieldLabel.Text = 'Farm/Field Location';
% Create FarmFieldLocationEditField
app.FarmFieldLocationEditField = uieditfield(app.UIFigure, 'text');
app.FarmFieldLocationEditField.Placeholder = 'City, country, landmarks, coordinates etc.';
app.FarmFieldLocationEditField.Position = [157 217 233 22];
% Create CropTypeEditFieldLabel
app.CropTypeEditFieldLabel = uilabel(app.UIFigure);
app.CropTypeEditFieldLabel.HorizontalAlignment = 'right';
app.CropTypeEditFieldLabel.Position = [31 268 60 22];
app.CropTypeEditFieldLabel.Text = 'Crop Type';
% Create CropTypeEditField
app.CropTypeEditField = uieditfield(app.UIFigure, 'text');
app.CropTypeEditField.Placeholder = 'Corn, Beans etc. (Botanical names accepted as well)';
app.CropTypeEditField.Position = [106 268 301 22];
% Create GetTipsButton
app.GetTipsButton = uibutton(app.UIFigure, 'push');
app.GetTipsButton.ButtonPushedFcn = createCallbackFcn(app, @GetTipsButtonPushed, true);
app.GetTipsButton.BackgroundColor = [0.4 0.749 0.3373];
app.GetTipsButton.FontName = 'Trebuchet MS';
app.GetTipsButton.FontSize = 24;
app.GetTipsButton.FontWeight = 'bold';
app.GetTipsButton.FontAngle = 'italic';
app.GetTipsButton.Position = [422 278 161 54];
app.GetTipsButton.Text = 'Get Tips!';
% Create TipsTextAreaLabel
app.TipsTextAreaLabel = uilabel(app.UIFigure);
app.TipsTextAreaLabel.HorizontalAlignment = 'right';
app.TipsTextAreaLabel.Position = [501 247 27 22];
app.TipsTextAreaLabel.Text = 'Tips';
% Create TipsTextArea
app.TipsTextArea = uitextarea(app.UIFigure);
app.TipsTextArea.Position = [422 22 185 217];
% Create StatusIdleLabel
app.StatusIdleLabel = uilabel(app.UIFigure);
app.StatusIdleLabel.FontAngle = 'italic';
app.StatusIdleLabel.Position = [215 355 238 22];
app.StatusIdleLabel.Text = 'Status: Idle';
% Create SoilHealthAdvisorLabel
app.SoilHealthAdvisorLabel = uilabel(app.UIFigure);
app.SoilHealthAdvisorLabel.FontName = 'Trebuchet MS';
app.SoilHealthAdvisorLabel.FontSize = 36;
app.SoilHealthAdvisorLabel.Position = [148 421 372 48];
app.SoilHealthAdvisorLabel.Text = 'Soil Health Advisor 🌱';
% Create GetAIpoweredinsightsforyourfarmLabel
app.GetAIpoweredinsightsforyourfarmLabel = uilabel(app.UIFigure);
app.GetAIpoweredinsightsforyourfarmLabel.FontName = 'Trebuchet MS';
app.GetAIpoweredinsightsforyourfarmLabel.FontSize = 18;
app.GetAIpoweredinsightsforyourfarmLabel.Position = [173 399 320 23];
app.GetAIpoweredinsightsforyourfarmLabel.Text = 'Get AI-powered insights for your farm!';
% Show the figure after all components are created
app.UIFigure.Visible = 'on';
end
end
% App creation and deletion
methods (Access = public)
% Construct app
function app = app1_exported
% Create UIFigure and components
createComponents(app)
% Register the app with App Designer
registerApp(app, app.UIFigure)
% Execute the startup function
runStartupFcn(app, @startupFcn)
if nargout == 0
clear app
end
end
% Code that executes before app deletion
function delete(app)
% Delete UIFigure when app is deleted
delete(app.UIFigure)
end
end
end
@TobeTek
Copy link
Author

TobeTek commented Jul 23, 2025

Demo

User Interface Screenshot
chrome_haRZk6HfoT.mp4

This demo showcases a user-friendly application designed to optimize crop yield. Farmers simply input:

  • The planted crop
  • Their farm's location
  • Current soil conditions (e.g., Loamy, Sandy)

In return, they receive tailored advice and actionable recommendations aimed at maximizing their crop's productivity.

Behind the Scenes

At its core, the system leverages a MATLAB App built with App Designer. This application is pre-configured with a comprehensive knowledge base on various soil types.

It integrates with a prompt-tuned Large Language Model (LLM), accessed securely via the GROQ REST API. The LLM processes the farmer's input, combining it with the pre-existing soil data to generate precise, yield-improving insights.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment