Welcome to Hackster!
Hackster is a community dedicated to learning hardware, from beginner to pro. Join us, it's free!
Eric Pietrowicz
Published © MIT

Making a Honey Stand with Stripe, Thingio, and an ESP32

A family member has recently started beekeeping. So, I thought it would be fun to take a crack at building a "honey vending machine".

BeginnerFull instructions provided5 hours2,825
Making a Honey Stand with Stripe, Thingio, and an ESP32

Things used in this project

Hardware components

XIAO ESP32C3
Seeed Studio XIAO ESP32C3
×1
High-Power MOSFET Trigger Switch
×1
DC-DC Step Down Variable Voltage Regulator
×1
Electric Latch Lock
×1
12V 2A Power Supply
×1
Micro Limit Switch
×1
Analog Digital Multiplexer Breakout Board
×1
10k ohm Pull up Resistors
×1

Software apps and online services

Thingio
KiCad
KiCad
Arduino IDE
Arduino IDE
Onshape

Story

Read more

Schematics

Controller board

The main carrier board for all of the control modules

Code

hayes-honey-controller.ino

Arduino
The main Arduino logic
#include <WiFiClientSecure.h>
#include <MQTTClient.h>
#include <ArduinoJson.h>

#include "secrets.h"

#define SLEEP_MS 1000

#define SOLENOID_1_PIN 2
#define SOLENOID_2_PIN 3

#define SOLENOID_FB_1 20
#define SOLENOID_FB_2 9

//Mux control pins
#define EN_PIN 4

#define MUX_S0 5
#define MUX_S1 6
#define MUX_S2 7
#define MUX_S3 21

//Mux in "SIG" pin
#define SIG_PIN 10

int jarPositions[] = {
  2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15
};

WiFiClientSecure net = WiFiClientSecure();
MQTTClient client = MQTTClient(256);

void handleUnlock() {
  digitalWrite(SOLENOID_1_PIN, HIGH);
  delay(500);
  digitalWrite(SOLENOID_1_PIN, LOW);
  delay(500);

  digitalWrite(SOLENOID_2_PIN, HIGH);
  delay(500);
  digitalWrite(SOLENOID_2_PIN, LOW);
  delay(500);
}

void callback(String &topic, String &payload) {
  StaticJsonDocument<512> doc;
  deserializeJson(doc, payload);
  const bool paymentCompleted = doc["paymentCompleted"];
  if (paymentCompleted) {
    Serial.println("Payment completed!");
    handleUnlock();
  }
}


void connectThingioCloud() {
  WiFi.mode(WIFI_STA);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.println("Connecting to Wi-Fi");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  net.setCACert(CERT_CA);
  net.setCertificate(DEVICE_CERTIFICATE);
  net.setPrivateKey(PRIVATE_KEY);

  client.begin(ENDPOINT, 8883, net);
  client.onMessage(callback);  // Add the incoming message handler

  Serial.println("Connecting to Thingio Cloud");

  while (!client.connect(THING_NAME)) {
    Serial.print(".");
    delay(100);
  }

  if (!client.connected()) {
    Serial.println("Cannot connect to cloud, re-trying.");
    ESP.restart();
    return;
  }
  client.subscribe(THINGIO_CLOUD_SUB);  // Subscribe to the "listener" endpoint
  Serial.println("Thingio Cloud Connected!");
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting connection...");
    // Attempt to connect
    if (client.connect(THING_NAME)) {
      client.subscribe(THINGIO_CLOUD_SUB);
      Serial.println("connected");
    } else {
      Serial.println("Failed, try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}


int readMux(int channel) {
  int controlPin[] = { MUX_S0, MUX_S1, MUX_S2, MUX_S3 };

  int muxChannel[16][4] = {
    { 0, 0, 0, 0 },  //channel 0
    { 1, 0, 0, 0 },  //channel 1
    { 0, 1, 0, 0 },  //channel 2
    { 1, 1, 0, 0 },  //channel 3
    { 0, 0, 1, 0 },  //channel 4
    { 1, 0, 1, 0 },  //channel 5
    { 0, 1, 1, 0 },  //channel 6
    { 1, 1, 1, 0 },  //channel 7
    { 0, 0, 0, 1 },  //channel 8
    { 1, 0, 0, 1 },  //channel 9
    { 0, 1, 0, 1 },  //channel 10
    { 1, 1, 0, 1 },  //channel 11
    { 0, 0, 1, 1 },  //channel 12
    { 1, 0, 1, 1 },  //channel 13
    { 0, 1, 1, 1 },  //channel 14
    { 1, 1, 1, 1 }   //channel 15
  };

  //loop through the 4 sig
  for (int i = 0; i < 4; i++) {
    digitalWrite(controlPin[i], muxChannel[channel][i]);
  }

  //read the value at the SIG pin
  int val = digitalRead(SIG_PIN);

  //return the value
  return val;
}


void setup() {
  delay(1000);
  Serial.begin(115200);
  Serial.println("Starting Stripe Thing");

  pinMode(SOLENOID_1_PIN, OUTPUT);
  pinMode(SOLENOID_2_PIN, OUTPUT);

  pinMode(SOLENOID_FB_1, INPUT_PULLUP);
  pinMode(SOLENOID_FB_2, INPUT_PULLUP);

  pinMode(MUX_S0, OUTPUT);
  pinMode(MUX_S1, OUTPUT);
  pinMode(MUX_S2, OUTPUT);
  pinMode(MUX_S3, OUTPUT);

  pinMode(SIG_PIN, INPUT);

  digitalWrite(MUX_S0, LOW);
  digitalWrite(MUX_S1, LOW);
  digitalWrite(MUX_S2, LOW);
  digitalWrite(MUX_S3, LOW);

  digitalWrite(SOLENOID_1_PIN, LOW);
  digitalWrite(SOLENOID_2_PIN, LOW);

  // Connect to the cloud
  connectThingioCloud();
}

void loop() {
  client.loop();
  if (!client.connected()) {
    reconnect();
  }

  int jarsRemaining = 0;
  for (int i = 0; i < 12; i++) {
    int isJarPresent = readMux(jarPositions[i]);
    Serial.print(isJarPresent);
    jarsRemaining += isJarPresent;
  }
  Serial.println("");
  Serial.println("------------");

  bool lidClosed = readMux(0);
  bool bothDoorsOpen = digitalRead(SOLENOID_FB_1) & digitalRead(SOLENOID_FB_2);

  Serial.print("Doors: ");
  Serial.print(bothDoorsOpen ? "Open. " : "Closed. ");

  Serial.print(" Lid: ");
  Serial.print(lidClosed ? "Closed. " : "Open. ");

  Serial.print("Jars Remaining: ");
  Serial.println(jarsRemaining);

  Serial.println("------------");

  if ((!bothDoorsOpen) & (jarsRemaining == 0) & lidClosed) {
    handleUnlock();
    Serial.println("No jars left, keep doors open!");
  }

  if (!lidClosed & !bothDoorsOpen) {
    handleUnlock();
  }

  delay(SLEEP_MS);
}

Credits

Eric Pietrowicz
6 projects • 4 followers
Hackin' on stuff that connects to the internet
Contact

Comments

Please log in or sign up to comment.