Ahmad Radhy
Published © Apache-2.0

Fermentation Monitoring in Post-Harvest Coffee Processing

My solution is fermentation monitoring for post-harvesting coffee processing

AdvancedWork in progressOver 7 days156

Things used in this project

Story

Read more

Schematics

A

B

Code

ADC Testing

Objective-C
/*
 * Copyright (c) 2020 Libre Solar Technologies GmbH
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>

#include <zephyr/device.h>
#include <zephyr/devicetree.h>
#include <zephyr/drivers/adc.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/util.h>

#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
	!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif

#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
	ADC_DT_SPEC_GET_BY_IDX(node_id, idx),

/* Data of ADC io-channels specified in devicetree. */
static const struct adc_dt_spec adc_channels[] = {
	DT_FOREACH_PROP_ELEM(DT_PATH(zephyr_user), io_channels,
			     DT_SPEC_AND_COMMA)
};

int main(void)
{
	int err;
	uint32_t count = 0;
	uint16_t buf;
	struct adc_sequence sequence = {
		.buffer = &buf,
		/* buffer size in bytes, not number of samples */
		.buffer_size = sizeof(buf),
	};

	/* Configure channels individually prior to sampling. */
	for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
		if (!adc_is_ready_dt(&adc_channels[i])) {
			printk("ADC controller device %s not ready\n", adc_channels[i].dev->name);
			return 0;
		}

		err = adc_channel_setup_dt(&adc_channels[i]);
		if (err < 0) {
			printk("Could not setup channel #%d (%d)\n", i, err);
			return 0;
		}
	}

#ifndef CONFIG_COVERAGE
	while (1) {
#else
	for (int k = 0; k < 10; k++) {
#endif
		printk("ADC reading[%u]:\n", count++);
		for (size_t i = 0U; i < ARRAY_SIZE(adc_channels); i++) {
			int32_t val_mv;

			printk("- %s, channel %d: ",
			       adc_channels[i].dev->name,
			       adc_channels[i].channel_id);

			(void)adc_sequence_init_dt(&adc_channels[i], &sequence);

			err = adc_read_dt(&adc_channels[i], &sequence);
			if (err < 0) {
				printk("Could not read (%d)\n", err);
				continue;
			}

			/*
			 * If using differential mode, the 16 bit value
			 * in the ADC sample buffer should be a signed 2's
			 * complement value.
			 */
			if (adc_channels[i].channel_cfg.differential) {
				val_mv = (int32_t)((int16_t)buf);
			} else {
				val_mv = (int32_t)buf;
			}
			printk("%"PRId32, val_mv);
			err = adc_raw_to_millivolts_dt(&adc_channels[i],
						       &val_mv);
			/* conversion to mV may not be supported, skip if not */
			if (err < 0) {
				printk(" (value in mV not available)\n");
			} else {
				printk(" = %"PRId32" mV\n", val_mv);
			}
		}

		k_sleep(K_MSEC(1000));
	}
	return 0;
}

Fermentation DAQ

Arduino
#include <Arduino.h>
#include <ArduinoJson.h>
#include <SPI.h>
#include <Adafruit_ADS1X15.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <SPI.h>
#include <Adafruit_I2CDevice.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>

void initialize_sensor();
void initialize_wifi();
boolean reconnect();
void update_sensor();
void initialize_tft();

struct dataSensor
{
  float ph = 0.0F;
  float temperature = 0.0F;
};

static dataSensor data;
static char payload[256];
StaticJsonDocument<256>doc;

const char ssid[] = "";
const char password[] = "";

AsyncWebServer server(80);



WiFiClient net;
PubSubClient mqttClient(net);
const char mqtt_broker[] =  ""; 
const char publish_Topic[] = "";


const char meas_Topic[] = "";
#define CLIENT_ID  ""

#define MQTT_USERNAME ""
#define MQTT_PASSWORD ""

long lastReconnectAttempt = 0;

Adafruit_ADS1115 ads;

#define ONE_WIRE_BUS 4
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature onewire_sensor(&oneWire);

long lastData = 0;

#define TFT_CS 14
#define TFT_RST 15
#define TFT_DC 32

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

void initialize_sensor()
{
  if (!ads.begin())
  {
    Serial.println("Failed to initialize ADS.");
    while(1);
  }
  onewire_sensor.begin();

}

void initialize_wifi(){

  delay(10);


  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  Serial.println();
  Serial.print("Connecting WiFi to: ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);

  while (true)
  {
    delay(10);
    Serial.print(".");
    if (WiFi.status() == WL_CONNECTED)
    {
      Serial.println("WiFi Connected");
      Serial.print("IP Address: ");
      Serial.println(WiFi.localIP());
      Serial.print("RSSI: ");
      Serial.println(WiFi.RSSI());
      break;
    }

  }

}

boolean reconnect(){

  Serial.println("Attempting to connect MQTT");

  if (mqttClient.connect(CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD))
  {
    Serial.println("Connected to MQTT broker");
    mqttClient.publish(publish_Topic, "");
  }

  return mqttClient.connected();
}

void update_sensor()
{
  int16_t adc0;
  float voltage = 0.0F;
  float pH = 0.0F;

  adc0 = ads.readADC_SingleEnded(0);
  voltage = ads.computeVolts(adc0);

  int16_t count = 0;
  while (count < 57)
  {
    pH += (-voltage*5.8582) + 15.8019; //for sensor
    count++;
    //delay(10);
  }

  data.ph = pH/57;

  onewire_sensor.requestTemperatures();
  float temperature = onewire_sensor.getTempCByIndex(0);
  data.temperature = temperature;

  doc["ph"] = data.ph;
  doc["temperature"] = data.temperature;
  serializeJsonPretty(doc, payload);
  Serial.println(payload);
  mqttClient.publish(meas_Topic, payload);

  tft.setRotation(3);
  tft.fillScreen(ST7735_BLACK);

  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(1.5);
  tft.setCursor(50,0);
  tft.print("FE-01:");

  tft.setTextSize(2);
  tft.setCursor(0,50);
  tft.print("pH:");
  tft.println(pH/57);

  tft.setTextSize(2);
  tft.setCursor(0,70);
  tft.print("Temp:");
  tft.println(temperature);

}

void initialize_tft()
{
  tft.initR(INITR_BLACKTAB);
  tft.setRotation(3);
  tft.fillScreen(ST7735_BLACK);
  tft.setCursor(20,10);
  tft.setTextColor(ST7735_RED);
  tft.setTextSize(2);
  tft.print("fer-data");
  tft.setCursor(20,30);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(2);
  tft.print("Sensor");

  tft.setCursor(20,80);
  tft.setTextColor(ST7735_YELLOW);
  tft.setTextSize(1);
  tft.print("Fermentation Process");

  tft.setCursor(20,120);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(1);
  tft.print("fermentation data");
  delay(5000);

  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST7735_WHITE);
  tft.setTextSize(2);
  tft.setCursor(0,10);
  tft.println("Connecting");
  tft.setTextColor(ST7735_GREEN);
  tft.setTextSize(1);
  tft.setCursor(10,50);
  tft.println("Loading......");
  
  delay(1000);

}

void setup() {

  Serial.begin(9600);

  onewire_sensor.requestTemperatures();
  float temperature = onewire_sensor.getTempCByIndex(0);

  tft.setRotation(3);
  initialize_sensor();
  initialize_tft();
  //tft.setRotation(3);
  initialize_wifi();
  mqttClient.setServer(mqtt_broker, 1883);
  lastReconnectAttempt = 0;


}

void loop() {

  tft.setRotation(3);
  if (WiFi.status() != WL_CONNECTED)
  {
    initialize_wifi();
  }

  if (WiFi.status() == WL_CONNECTED && !mqttClient.connected())
  {
    long now = millis();

    if (now - lastReconnectAttempt > 2000)
    {
      lastReconnectAttempt = now;

      if (reconnect())
      {
        lastReconnectAttempt = 0;
      }

    }

  }

  else
  {
    mqttClient.loop();
  }

  long now = millis();
  if (now - lastData > 60000) //update data sensor tiap 1 menit ke gateway raspberry
  {
    lastData = now;
    update_sensor();
  }

}

Credits

Ahmad Radhy
26 projects • 50 followers
Physicist and Lecturer in Engineering
Contact

Comments

Please log in or sign up to comment.