Hackster is hosting Hackster Holidays, Ep. 6: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Monday!Stream Hackster Holidays, Ep. 6 on Monday!
Sam MugfordBen DewhurstLawrence Percival-Alwyn
Published © GPL3+

Homebrew Fermentation Monitor

We aim to develop a tool to monitor the progress of beer fermentation in real-time and non-invasively.

BeginnerShowcase (no instructions)2 hours3,967
Homebrew Fermentation Monitor

Things used in this project

Hardware components

Analog hall effect sensor
×1
Rich UNO R3 Arduino
×1
Standard LCD - 16x2 White on Blue
Adafruit Standard LCD - 16x2 White on Blue
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
IO expansion shield
×1

Hand tools and fabrication machines

Neodymium Magnets
Hydrometer

Story

Read more

Schematics

Acoustic sensor circuit

Acoustic sensor to detect the height of a hydrometer and report the specific gravity of the fluid via LCD display

Magnetic sensory circuit

Hall-effect detector to detect the height of a hydrometer and report the % alcohol in the fluid via LCD display

Magnetic hydrometer assembly

Five 5x5x1mm Neodymium magnets super-glued to the end of a bamboo kebab skewer. The south pole of the magnet is indicated by the black spot on the stick.

Magnetic hydrometer assembly pt.2

Neodymium magnets mounted on bamboo skewer attached to hydromter as shown. The external aparatus to be mounted on the lid of the fermenter consists of a c~20cm legnth of 8mm internal diameter plasti tubing fitted onto a rubber seal from a fermenter airlock, and attached to a bamboo skewer to hold it upright.

Magnetic hydrometer assembly pt.3

External apparatus mounted on fermenter lid, rubber seal placed in 1.5 cm hole in lid. Neodymium magnet-hydrometer assembly inserted with magnet inside the tube. The lid should then be placed on the fermenter so that the hydrometer floats freely. All components coming into contact with the inside of the fermenter should be carefuly steralised first.

Magnetic hydrometer assembly pt.4

Hall-effect sensor mounted on the external apparatus. The sensor should be possitioned adjacent (here we used sticky-tape) to the south pole of the neodymium magnet at the start of the fermentation. As fermentation proceeds the magnet will move down, and the unit will record the change in alcohol content.

Code

Acoustic hydrometer code

C/C++
XOD code for automatic hydrometer using an acoustic sensor to monitor the height of a hydrometer in fluid, and report the specific gravity of the fluid via the LCD display.
{
  "name": "",
  "patches": {
    "@/main": {
      "comments": {
        "B1ZjM5wMV": {
          "content": "conversion of distance to hydrometer reading based on y=mx+c callibration of my hydrometer",
          "id": "B1ZjM5wMV",
          "position": {
            "x": 34,
            "y": 102
          },
          "size": {
            "height": 51,
            "width": 272
          }
        },
        "ByW_IuvzN": {
          "content": "Remove hydrometer and press reset, The buffer stores the distance from the sensor to the liquid surface and feeds it into the subraction \n",
          "id": "ByW_IuvzN",
          "position": {
            "x": -408,
            "y": -204
          },
          "size": {
            "height": 153,
            "width": 170
          }
        },
        "HJhumXSzE": {
          "content": "Calculation to convert distance measured into a SG\n\n",
          "id": "HJhumXSzE",
          "position": {
            "x": -204,
            "y": -408
          },
          "size": {
            "height": 51,
            "width": 408
          }
        },
        "HyyAf5PzE": {
          "content": "Output to LCD display- 16x2 i2c display, using address 56d, connect to I2C scl and sda pins on IO sheild",
          "id": "HyyAf5PzE",
          "position": {
            "x": 204,
            "y": 204
          },
          "size": {
            "height": 51,
            "width": 272
          }
        },
        "S1yEMcDMV": {
          "content": "distance from sensor to object (surface or hydrometer) in mm",
          "id": "S1yEMcDMV",
          "position": {
            "x": 102,
            "y": -204
          },
          "size": {
            "height": 51,
            "width": 204
          }
        },
        "r1PPG9DM4": {
          "content": "distance from surface to top of hydrometer",
          "id": "r1PPG9DM4",
          "position": {
            "x": 34,
            "y": 0
          },
          "size": {
            "height": 51,
            "width": 204
          }
        },
        "r1shMcDf4": {
          "content": "Hydrometer reading",
          "id": "r1shMcDf4",
          "position": {
            "x": -272,
            "y": 204
          },
          "size": {
            "height": 51,
            "width": 170
          }
        }
      },
      "links": {
        "H1wS8_wMV": {
          "id": "H1wS8_wMV",
          "input": {
            "nodeId": "HkGeLODGV",
            "pinKey": "HkXm80uHPyb"
          },
          "output": {
            "nodeId": "rJ2KbNHGN",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "HJLcRXBMN": {
          "id": "HJLcRXBMN",
          "input": {
            "nodeId": "Bkm9RmSzV",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "B1e8TXHM4",
            "pinKey": "BkqLCOSw1W"
          }
        },
        "Hkr8pQSfE": {
          "id": "Hkr8pQSfE",
          "input": {
            "nodeId": "B1e8TXHM4",
            "pinKey": "SkdIRuBD1b"
          },
          "output": {
            "nodeId": "HJDbaQHGN",
            "pinKey": "SyomIRurDJ-"
          }
        },
        "Hy-RWESfN": {
          "id": "Hy-RWESfN",
          "input": {
            "nodeId": "HyhTZNrMV",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "rJxjyVrGE",
            "pinKey": "BJllkG0Ub"
          }
        },
        "S1oYtBwG4": {
          "id": "S1oYtBwG4",
          "input": {
            "nodeId": "HJVYFrwzV",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "rJ2KbNHGN",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "SJY78ODGV": {
          "id": "SJY78ODGV",
          "input": {
            "nodeId": "HJlxrYHDfN",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "HkGeLODGV",
            "pinKey": "r1lQLAOBwJb"
          }
        },
        "SkCWTXBfN": {
          "id": "SkCWTXBfN",
          "input": {
            "nodeId": "HJDbaQHGN",
            "pinKey": "BJnQUR_BwyZ"
          },
          "output": {
            "nodeId": "HJCJhXSfN",
            "pinKey": "HyRmUCdBDkZ"
          }
        },
        "Skq4YBPME": {
          "id": "Skq4YBPME",
          "input": {
            "nodeId": "r1v4FrwMN",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "HJCJhXSfN",
            "pinKey": "HyRmUCdBDkZ"
          }
        },
        "SyOnIrwfV": {
          "id": "SyOnIrwfV",
          "input": {
            "nodeId": "HJCJhXSfN",
            "pinKey": "rkJ4URuHDJ-"
          },
          "output": {
            "nodeId": "rJ2KbNHGN",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "rJozUuDMV": {
          "id": "rJozUuDMV",
          "input": {
            "nodeId": "HJCJhXSfN",
            "pinKey": "BypX80uSD1Z"
          },
          "output": {
            "nodeId": "HkGeLODGV",
            "pinKey": "r1lQLAOBwJb"
          }
        },
        "rkgq-4rMV": {
          "id": "rkgq-4rMV",
          "input": {
            "nodeId": "rJ2KbNHGN",
            "pinKey": "B1GfLR_SPk-"
          },
          "output": {
            "nodeId": "rJxjyVrGE",
            "pinKey": "BJllkG0Ub"
          }
        },
        "ry-loYDzV": {
          "id": "ry-loYDzV",
          "input": {
            "nodeId": "rkMh_FDfN",
            "pinKey": "H1bLN9F-b"
          },
          "output": {
            "nodeId": "B1e8TXHM4",
            "pinKey": "BkqLCOSw1W"
          }
        }
      },
      "nodes": {
        "B1e8TXHM4": {
          "boundLiterals": {
            "BytUCdHD1-": "532.88"
          },
          "id": "B1e8TXHM4",
          "position": {
            "x": -34,
            "y": 102
          },
          "type": "xod/core/divide"
        },
        "Bkm9RmSzV": {
          "id": "Bkm9RmSzV",
          "position": {
            "x": -102,
            "y": 204
          },
          "size": {
            "height": 51,
            "width": 136
          },
          "type": "xod/core/watch"
        },
        "HJCJhXSfN": {
          "boundLiterals": {
            "BypX80uSD1Z": "139.5"
          },
          "id": "HJCJhXSfN",
          "position": {
            "x": -102,
            "y": 0
          },
          "type": "xod/core/subtract"
        },
        "HJDbaQHGN": {
          "boundLiterals": {
            "HkqmLAOrD1W": "500.29"
          },
          "id": "HJDbaQHGN",
          "position": {
            "x": -102,
            "y": 102
          },
          "type": "xod/core/add"
        },
        "HJVYFrwzV": {
          "id": "HJVYFrwzV",
          "position": {
            "x": 34,
            "y": -204
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "HJlxrYHDfN": {
          "id": "HJlxrYHDfN",
          "position": {
            "x": -238,
            "y": -102
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "HkGeLODGV": {
          "boundLiterals": {
            "Hy-QUR_BPkZ": "On Boot"
          },
          "id": "HkGeLODGV",
          "position": {
            "x": -170,
            "y": -102
          },
          "type": "xod/core/buffer"
        },
        "HyhTZNrMV": {
          "id": "HyhTZNrMV",
          "position": {
            "x": -102,
            "y": -306
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "r1v4FrwMN": {
          "id": "r1v4FrwMN",
          "position": {
            "x": -34,
            "y": 0
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "rJ2KbNHGN": {
          "boundLiterals": {
            "SJ4zUC_BD1-": "1000"
          },
          "id": "rJ2KbNHGN",
          "position": {
            "x": -34,
            "y": -204
          },
          "type": "xod/core/multiply"
        },
        "rJxjyVrGE": {
          "boundLiterals": {
            "r1xoR-C8-": "D9",
            "rJa50WCL-": "D6"
          },
          "id": "rJxjyVrGE",
          "position": {
            "x": -34,
            "y": -306
          },
          "type": "xod/common-hardware/hc-sr04-ultrasonic-range"
        },
        "rkMh_FDfN": {
          "boundLiterals": {
            "B1TSE9tZ-": "\"SG\"",
            "SkkWMb9A-": "True",
            "rJlYT7EfW": "56d"
          },
          "id": "rkMh_FDfN",
          "position": {
            "x": 34,
            "y": 204
          },
          "type": "xod/common-hardware/text-lcd-16x2-i2c"
        }
      },
      "path": "@/main"
    }
  }
}

Magnetic hydrometer code

C/C++
XOD code for an automated hydrometer using a hall-effect sensor to measure the height of a hydromter in a fluid, and to report the alcohol concentration via the LCD display
{
  "name": "",
  "patches": {
    "@/hall-sensor": {
      "links": {
        "BJdfFrhYXV": {
          "id": "BJdfFrhYXV",
          "input": {
            "nodeId": "rJEfKr2YQV",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "rylMFSnFmE",
            "pinKey": "H1P1711gm"
          }
        },
        "BykgftBnYmV": {
          "id": "BykgftBnYmV",
          "input": {
            "nodeId": "ByQzYH2Km4",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "rylMFSnFmE",
            "pinKey": "BJdJV9RkX"
          }
        },
        "H1TGKH3KQN": {
          "id": "H1TGKH3KQN",
          "input": {
            "nodeId": "BkMKrnFQN",
            "pinKey": "SyLCdSwJZ"
          },
          "output": {
            "nodeId": "BJUzFS2KX4",
            "pinKey": "__out__"
          }
        },
        "HJqfYH2FX4": {
          "id": "HJqfYH2FX4",
          "input": {
            "nodeId": "BkMKrnFQN",
            "pinKey": "B143qAq1Q"
          },
          "output": {
            "nodeId": "HkWMKShKQN",
            "pinKey": "__out__"
          }
        },
        "Hy0MFH3YmN": {
          "id": "Hy0MFH3YmN",
          "input": {
            "nodeId": "HkvztB2YXN",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "rylMFSnFmE",
            "pinKey": "BkoeN9Ay7"
          }
        },
        "SkKMYB3YX4": {
          "id": "SkKMYB3YX4",
          "input": {
            "nodeId": "rylMFSnFmE",
            "pinKey": "r1l3XcR17"
          },
          "output": {
            "nodeId": "H1SMKrnYmN",
            "pinKey": "__out__"
          }
        },
        "Sy3fYrnKm4": {
          "id": "Sy3fYrnKm4",
          "input": {
            "nodeId": "HJMGYB3FmV",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "BkMKrnFQN",
            "pinKey": "B1gI0urv1W"
          }
        },
        "r1sfKrntXE": {
          "id": "r1sfKrntXE",
          "input": {
            "nodeId": "rylMFSnFmE",
            "pinKey": "SkUhQ5RkQ"
          },
          "output": {
            "nodeId": "BJUzFS2KX4",
            "pinKey": "__out__"
          }
        }
      },
      "nodes": {
        "BJUzFS2KX4": {
          "boundLiterals": {
            "__out__": "Continuously"
          },
          "description": "Triggers new read",
          "id": "BJUzFS2KX4",
          "label": "UPD",
          "position": {
            "x": 67,
            "y": -1
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "BkMKrnFQN": {
          "id": "BkMKrnFQN",
          "position": {
            "x": 237,
            "y": 101
          },
          "type": "xod/gpio/digital-read"
        },
        "ByQzYH2Km4": {
          "description": "Fires on reading complete",
          "id": "ByQzYH2Km4",
          "label": "DONE",
          "position": {
            "x": 67,
            "y": 203
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "H1SMKrnYmN": {
          "boundLiterals": {
            "__out__": "A0"
          },
          "id": "H1SMKrnYmN",
          "position": {
            "x": -1,
            "y": -1
          },
          "type": "xod/patch-nodes/input-port"
        },
        "HJMGYB3FmV": {
          "description": "Last read value. Equals to `true` while the button is pressed (hold down) and `false` while it is released.",
          "id": "HJMGYB3FmV",
          "label": "PRS",
          "position": {
            "x": 237,
            "y": 203
          },
          "type": "xod/patch-nodes/output-boolean"
        },
        "HkWMKShKQN": {
          "boundLiterals": {
            "__out__": "D3"
          },
          "id": "HkWMKShKQN",
          "position": {
            "x": 237,
            "y": -1
          },
          "type": "xod/patch-nodes/input-port"
        },
        "HkvztB2YXN": {
          "description": "The last read potentiometer position in range [0.0, 1.0].",
          "id": "HkvztB2YXN",
          "label": "VAL",
          "position": {
            "x": -1,
            "y": 203
          },
          "type": "xod/patch-nodes/output-number"
        },
        "rJEfKr2YQV": {
          "description": "Fires if update failed.",
          "id": "rJEfKr2YQV",
          "label": "ERR",
          "position": {
            "x": 135,
            "y": 203
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "rylMFSnFmE": {
          "id": "rylMFSnFmE",
          "position": {
            "x": -1,
            "y": 101
          },
          "type": "xod/common-hardware/analog-sensor"
        }
      },
      "path": "@/hall-sensor"
    },
    "@/main": {
      "comments": {
        "B1cnlBmV4": {
          "content": "\nConvert distance to change in density, based on my hydrometer where 1mm = 0.001887 g/cm^3 change",
          "id": "B1cnlBmV4",
          "position": {
            "x": 408,
            "y": 408
          },
          "size": {
            "height": 51,
            "width": 306
          }
        },
        "HkKgRjS3FmE": {
          "content": "Calculation to convert distance measured into a SG\n\n",
          "id": "HkKgRjS3FmE",
          "position": {
            "x": 238,
            "y": -102
          },
          "size": {
            "height": 51,
            "width": 408
          }
        },
        "Hy9xCjr3Y7E": {
          "content": "Output to LCD display- 16x2 i2c display, using address 56d, connect to I2C scl and sda pins on IO sheild",
          "id": "Hy9xCjr3Y7E",
          "position": {
            "x": 34,
            "y": 612
          },
          "size": {
            "height": 51,
            "width": 272
          }
        },
        "HydaA6YXV": {
          "content": "\nconversion to distance part 2: converts 1/(distance)^2 to distance (in mm)",
          "id": "HydaA6YXV",
          "position": {
            "x": 408,
            "y": 306
          },
          "size": {
            "height": 51,
            "width": 306
          }
        },
        "SysqouVV4": {
          "content": "\nConvert specific garvity change to acohol content (% ABV)",
          "id": "SysqouVV4",
          "position": {
            "x": 374,
            "y": 510
          },
          "size": {
            "height": 51,
            "width": 306
          }
        },
        "rJzWoJ9XN": {
          "content": "Multiply hall sensor outout by 1000 to get more significant figures",
          "id": "rJzWoJ9XN",
          "position": {
            "x": 374,
            "y": 102
          },
          "size": {
            "height": 51,
            "width": 306
          }
        },
        "rkBcuJ9X4": {
          "content": "\nconversion to distance part 1, based on calibation of hall sensor,5 stacked 5x5x1mm neodymium magnets (from guys magnets)inside a 1.5mm plastic tube perpendicular to the hall sensor, shows, where Y= hall sensor readout (x1000) , and X = 1(distance)^2 :X= (Y-456.86)/2909.5",
          "id": "rkBcuJ9X4",
          "position": {
            "x": 408,
            "y": 204
          },
          "size": {
            "height": 51,
            "width": 748
          }
        }
      },
      "links": {
        "BJCFqV74V": {
          "id": "BJCFqV74V",
          "input": {
            "nodeId": "r1jFqNmEE",
            "pinKey": "SkdIRuBD1b"
          },
          "output": {
            "nodeId": "BkIcdAKmV",
            "pinKey": "HyRmUCdBDkZ"
          }
        },
        "BJKqK3FmE": {
          "id": "BJKqK3FmE",
          "input": {
            "nodeId": "ByI0iHntXE",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "BkkqY3YmE",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "HJAh5474E": {
          "id": "HJAh5474E",
          "input": {
            "nodeId": "SywNKAY74",
            "pinKey": "BytUCdHD1-"
          },
          "output": {
            "nodeId": "r1jFqNmEE",
            "pinKey": "BkqLCOSw1W"
          }
        },
        "Hk3QyHX4N": {
          "id": "Hk3QyHX4N",
          "input": {
            "nodeId": "HJ8XyB74V",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "r1jFqNmEE",
            "pinKey": "BkqLCOSw1W"
          }
        },
        "Hki8fBX4N": {
          "id": "Hki8fBX4N",
          "input": {
            "nodeId": "BJcAiB2F7E",
            "pinKey": "H1bLN9F-b"
          },
          "output": {
            "nodeId": "SywSfBmEN",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "SJ7qYnFmN": {
          "id": "SJ7qYnFmN",
          "input": {
            "nodeId": "BkkqY3YmE",
            "pinKey": "B1GfLR_SPk-"
          },
          "output": {
            "nodeId": "SkHnB3K74",
            "pinKey": "HkvztB2YXN"
          }
        },
        "SJRv9VX44": {
          "id": "SJRv9VX44",
          "input": {
            "nodeId": "BkIcdAKmV",
            "pinKey": "BypX80uSD1Z"
          },
          "output": {
            "nodeId": "BkkqY3YmE",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "SkCUzBQV4": {
          "id": "SkCUzBQV4",
          "input": {
            "nodeId": "SJjIKRtXN",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "SywSfBmEN",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "rJP8fS74V": {
          "id": "rJP8fS74V",
          "input": {
            "nodeId": "SywSfBmEN",
            "pinKey": "B1GfLR_SPk-"
          },
          "output": {
            "nodeId": "S1-5eBQ44",
            "pinKey": "BkQzLCurwJZ"
          }
        },
        "rJhrKRK7V": {
          "id": "rJhrKRK7V",
          "input": {
            "nodeId": "H1FSYAFXN",
            "pinKey": "ByZ7_hnUb"
          },
          "output": {
            "nodeId": "SywNKAY74",
            "pinKey": "BkqLCOSw1W"
          }
        },
        "rygjlBmVN": {
          "id": "rygjlBmVN",
          "input": {
            "nodeId": "S1-5eBQ44",
            "pinKey": "B1GfLR_SPk-"
          },
          "output": {
            "nodeId": "H1FSYAFXN",
            "pinKey": "B1QQ_nhUb"
          }
        }
      },
      "nodes": {
        "BJcAiB2F7E": {
          "boundLiterals": {
            "B1TSE9tZ-": "\"Alcohol %\"",
            "SkkWMb9A-": "True",
            "rJlYT7EfW": "56d"
          },
          "id": "BJcAiB2F7E",
          "position": {
            "x": 306,
            "y": 612
          },
          "type": "xod/common-hardware/text-lcd-16x2-i2c"
        },
        "BkIcdAKmV": {
          "boundLiterals": {
            "rkJ4URuHDJ-": "456.86"
          },
          "id": "BkIcdAKmV",
          "position": {
            "x": 272,
            "y": 204
          },
          "type": "xod/core/subtract"
        },
        "BkkqY3YmE": {
          "boundLiterals": {
            "SJ4zUC_BD1-": "1000"
          },
          "id": "BkkqY3YmE",
          "position": {
            "x": 306,
            "y": 102
          },
          "type": "xod/core/multiply"
        },
        "ByI0iHntXE": {
          "id": "ByI0iHntXE",
          "position": {
            "x": 102,
            "y": 102
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "H1FSYAFXN": {
          "id": "H1FSYAFXN",
          "position": {
            "x": 374,
            "y": 306
          },
          "type": "xod/math/sqrt"
        },
        "HJ8XyB74V": {
          "id": "HJ8XyB74V",
          "position": {
            "x": 68,
            "y": 204
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "S1-5eBQ44": {
          "boundLiterals": {
            "SJ4zUC_BD1-": "0.001887925"
          },
          "id": "S1-5eBQ44",
          "position": {
            "x": 306,
            "y": 408
          },
          "type": "xod/core/multiply"
        },
        "SJjIKRtXN": {
          "id": "SJjIKRtXN",
          "position": {
            "x": 476,
            "y": 612
          },
          "size": {
            "height": 51,
            "width": 68
          },
          "type": "xod/core/watch"
        },
        "SkHnB3K74": {
          "id": "SkHnB3K74",
          "position": {
            "x": 136,
            "y": 0
          },
          "type": "@/hall-sensor"
        },
        "SywNKAY74": {
          "boundLiterals": {
            "SkdIRuBD1b": "1"
          },
          "id": "SywNKAY74",
          "position": {
            "x": 306,
            "y": 306
          },
          "type": "xod/core/divide"
        },
        "SywSfBmEN": {
          "boundLiterals": {
            "SJ4zUC_BD1-": "131.25"
          },
          "id": "SywSfBmEN",
          "position": {
            "x": 272,
            "y": 510
          },
          "type": "xod/core/multiply"
        },
        "r1jFqNmEE": {
          "boundLiterals": {
            "BytUCdHD1-": "2909.5"
          },
          "id": "r1jFqNmEE",
          "position": {
            "x": 340,
            "y": 204
          },
          "type": "xod/core/divide"
        }
      },
      "path": "@/main"
    }
  }
}

New XOD Patches

C/C++
New XOD Patches, including node to control Sunfounder analog hall-switch, node to control light sensor, and a node to take a noisy input signal and smooth the signal using a rolling average
{
  "name": "",
  "patches": {
    "@/hall-sensor": {
      "links": {
        "BkFquSixQE": {
          "id": "BkFquSixQE",
          "input": {
            "nodeId": "r1xqurjxXV",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "BkVcuHogQV",
            "pinKey": "H1P1711gm"
          }
        },
        "BkHquBslXE": {
          "id": "BkHquBslXE",
          "input": {
            "nodeId": "BkVcuHogQV",
            "pinKey": "r1l3XcR17"
          },
          "output": {
            "nodeId": "rJZcurol7V",
            "pinKey": "__out__"
          }
        },
        "ByUUKril7E": {
          "id": "ByUUKril7E",
          "input": {
            "nodeId": "B1E8FrsgQE",
            "pinKey": "B143qAq1Q"
          },
          "output": {
            "nodeId": "BkXUYSigX4",
            "pinKey": "__out__"
          }
        },
        "H1d5drjlQ4": {
          "id": "H1d5drjlQ4",
          "input": {
            "nodeId": "BkVcuHogQV",
            "pinKey": "SkUhQ5RkQ"
          },
          "output": {
            "nodeId": "rJcdHil7E",
            "pinKey": "__out__"
          }
        },
        "HJDIYBogm4": {
          "id": "HJDIYBogm4",
          "input": {
            "nodeId": "ByZIFHsxm4",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "B1E8FrsgQE",
            "pinKey": "B1gI0urv1W"
          }
        },
        "SJYqBsxQ4": {
          "id": "SJYqBsxQ4",
          "input": {
            "nodeId": "B1E8FrsgQE",
            "pinKey": "SyLCdSwJZ"
          },
          "output": {
            "nodeId": "rJcdHil7E",
            "pinKey": "__out__"
          }
        },
        "SkLqOSjgX4": {
          "id": "SkLqOSjgX4",
          "input": {
            "nodeId": "rJm5urogQE",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "BkVcuHogQV",
            "pinKey": "BkoeN9Ay7"
          }
        },
        "SkORHjlXN": {
          "id": "SkORHjlXN",
          "input": {
            "nodeId": "SkG9dBjgX4",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "BkVcuHogQV",
            "pinKey": "BJdJV9RkX"
          }
        }
      },
      "nodes": {
        "B1E8FrsgQE": {
          "id": "B1E8FrsgQE",
          "position": {
            "x": 340,
            "y": 204
          },
          "type": "xod/gpio/digital-read"
        },
        "BkVcuHogQV": {
          "id": "BkVcuHogQV",
          "position": {
            "x": 102,
            "y": 204
          },
          "type": "xod/common-hardware/analog-sensor"
        },
        "BkXUYSigX4": {
          "boundLiterals": {
            "__out__": "D3"
          },
          "id": "BkXUYSigX4",
          "position": {
            "x": 340,
            "y": 102
          },
          "type": "xod/patch-nodes/input-port"
        },
        "ByZIFHsxm4": {
          "description": "Last read value. Equals to `true` while the button is pressed (hold down) and `false` while it is released.",
          "id": "ByZIFHsxm4",
          "label": "PRS",
          "position": {
            "x": 340,
            "y": 306
          },
          "type": "xod/patch-nodes/output-boolean"
        },
        "SkG9dBjgX4": {
          "description": "Fires on reading complete",
          "id": "SkG9dBjgX4",
          "label": "DONE",
          "position": {
            "x": 170,
            "y": 306
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "r1xqurjxXV": {
          "description": "Fires if update failed.",
          "id": "r1xqurjxXV",
          "label": "ERR",
          "position": {
            "x": 238,
            "y": 306
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "rJZcurol7V": {
          "boundLiterals": {
            "__out__": "A0"
          },
          "id": "rJZcurol7V",
          "position": {
            "x": 102,
            "y": 102
          },
          "type": "xod/patch-nodes/input-port"
        },
        "rJcdHil7E": {
          "boundLiterals": {
            "__out__": "Continuously"
          },
          "description": "Triggers new read",
          "id": "rJcdHil7E",
          "label": "UPD",
          "position": {
            "x": 170,
            "y": 102
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "rJm5urogQE": {
          "description": "The last read potentiometer position in range [0.0, 1.0].",
          "id": "rJm5urogQE",
          "label": "VAL",
          "position": {
            "x": 102,
            "y": 306
          },
          "type": "xod/patch-nodes/output-number"
        }
      },
      "path": "@/hall-sensor"
    },
    "@/light-sensor": {
      "links": {
        "B1YxneufV": {
          "id": "B1YxneufV",
          "input": {
            "nodeId": "ryhColuME",
            "pinKey": "r1l3XcR17"
          },
          "output": {
            "nodeId": "S1GghguMV",
            "pinKey": "__out__"
          }
        },
        "H1zzhldGN": {
          "id": "H1zzhldGN",
          "input": {
            "nodeId": "rJpb2x_fN",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "ryhColuME",
            "pinKey": "BkoeN9Ay7"
          }
        },
        "HJ7V2xufN": {
          "id": "HJ7V2xufN",
          "input": {
            "nodeId": "rJAX3edfV",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "ryhColuME",
            "pinKey": "BJdJV9RkX"
          }
        },
        "HkxXnedMN": {
          "id": "HkxXnedMN",
          "input": {
            "nodeId": "ryhColuME",
            "pinKey": "SkUhQ5RkQ"
          },
          "output": {
            "nodeId": "Bkcfhedz4",
            "pinKey": "__out__"
          }
        },
        "HyxB3guG4": {
          "id": "HyxB3guG4",
          "input": {
            "nodeId": "ByiV2g_G4",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "ryhColuME",
            "pinKey": "H1P1711gm"
          }
        }
      },
      "nodes": {
        "Bkcfhedz4": {
          "boundLiterals": {
            "__out__": "Continuously"
          },
          "description": "Triggers new read",
          "id": "Bkcfhedz4",
          "label": "UPD",
          "position": {
            "x": 272,
            "y": 0
          },
          "type": "xod/patch-nodes/input-pulse"
        },
        "ByiV2g_G4": {
          "description": "Fires if update failed.",
          "id": "ByiV2g_G4",
          "label": "ERR",
          "position": {
            "x": 340,
            "y": 204
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "S1GghguMV": {
          "boundLiterals": {
            "__out__": "A0"
          },
          "id": "S1GghguMV",
          "position": {
            "x": 204,
            "y": 0
          },
          "type": "xod/patch-nodes/input-port"
        },
        "rJAX3edfV": {
          "description": "Fires on reading complete",
          "id": "rJAX3edfV",
          "label": "DONE",
          "position": {
            "x": 272,
            "y": 204
          },
          "type": "xod/patch-nodes/output-pulse"
        },
        "rJpb2x_fN": {
          "description": "The last read potentiometer position in range [0.0, 1.0].",
          "id": "rJpb2x_fN",
          "label": "VAL",
          "position": {
            "x": 204,
            "y": 204
          },
          "type": "xod/patch-nodes/output-number"
        },
        "ryhColuME": {
          "id": "ryhColuME",
          "position": {
            "x": 204,
            "y": 102
          },
          "type": "xod/common-hardware/analog-sensor"
        }
      },
      "path": "@/light-sensor"
    },
    "@/main": {
      "path": "@/main"
    },
    "@/rolling-average": {
      "comments": {
        "BJqWrxAPcGN": {
          "content": "Takes a fluctuating numerical input and calculates a rolling average from 4 sequential reading taken one per second. The rolling average is output as a numerical value. \n\nTo adjust the frequency of sampling change the IVAL in the clock patch",
          "id": "BJqWrxAPcGN",
          "position": {
            "x": 603.7499995231628,
            "y": 101
          },
          "size": {
            "height": 153,
            "width": 238
          }
        }
      },
      "links": {
        "B1LgHgAvcGE": {
          "id": "B1LgHgAvcGE",
          "input": {
            "nodeId": "BkIBx0wqME",
            "pinKey": "HkXm80uHPyb"
          },
          "output": {
            "nodeId": "rynHlAD9zV",
            "pinKey": "HyZHD8tcW"
          }
        },
        "B1pxSxRDqGN": {
          "id": "B1pxSxRDqGN",
          "input": {
            "nodeId": "H1mSxRP9zE",
            "pinKey": "HkqmLAOrD1W-$3"
          },
          "output": {
            "nodeId": "SyylBgRw5fV",
            "pinKey": "HyZHD8tcW"
          }
        },
        "BkAxrgADcGE": {
          "id": "BkAxrgADcGE",
          "input": {
            "nodeId": "H1wSg0D5MV",
            "pinKey": "__in__"
          },
          "output": {
            "nodeId": "rkeBlCw9fN",
            "pinKey": "BkqLCOSw1W"
          }
        },
        "BkOxBxCw5fV": {
          "id": "BkOxBxCw5fV",
          "input": {
            "nodeId": "rJ9rl0vqMV",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "rynHlAD9zV",
            "pinKey": "HyZHD8tcW"
          }
        },
        "BybZBeRv5zV": {
          "id": "BybZBeRv5zV",
          "input": {
            "nodeId": "SyylBgRw5fV",
            "pinKey": "B15NPUY9W"
          },
          "output": {
            "nodeId": "ryBBlRw5zV",
            "pinKey": "r1lQLAOBwJb"
          }
        },
        "H1GgHgRvqME": {
          "id": "H1GgHgRvqME",
          "input": {
            "nodeId": "H1mSxRP9zE",
            "pinKey": "HkqmLAOrD1W-$2"
          },
          "output": {
            "nodeId": "rJTSlADqf4",
            "pinKey": "HyZHD8tcW"
          }
        },
        "H1S-HeCvcGV": {
          "id": "H1S-HeCvcGV",
          "input": {
            "nodeId": "Hy0BlCDqME",
            "pinKey": "Hy-QUR_BPkZ"
          },
          "output": {
            "nodeId": "S1sBe0v5fN",
            "pinKey": "HJU8CE2lW"
          }
        },
        "HJEWHgRPczE": {
          "id": "HJEWHgRPczE",
          "input": {
            "nodeId": "BkIBx0wqME",
            "pinKey": "Hy-QUR_BPkZ"
          },
          "output": {
            "nodeId": "S1sBe0v5fN",
            "pinKey": "HJU8CE2lW"
          }
        },
        "Hy7grx0v9M4": {
          "id": "Hy7grx0v9M4",
          "input": {
            "nodeId": "H1GreCvcME",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "rJTSlADqf4",
            "pinKey": "HyZHD8tcW"
          }
        },
        "HyDeBeCvczE": {
          "id": "HyDeBeCvczE",
          "input": {
            "nodeId": "By_Sx0wcME",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "H1breRvcfN",
            "pinKey": "HyZHD8tcW"
          }
        },
        "HyVlHlCw9M4": {
          "id": "HyVlHlCw9M4",
          "input": {
            "nodeId": "rynHlAD9zV",
            "pinKey": "B15NPUY9W"
          },
          "output": {
            "nodeId": "HJKBgCw5zE",
            "pinKey": "r1lQLAOBwJb"
          }
        },
        "HygWBgRv5GV": {
          "id": "HygWBgRv5GV",
          "input": {
            "nodeId": "rJTSlADqf4",
            "pinKey": "B15NPUY9W"
          },
          "output": {
            "nodeId": "Hy0BlCDqME",
            "pinKey": "r1lQLAOBwJb"
          }
        },
        "HyuZrx0v9MN": {
          "id": "HyuZrx0v9MN",
          "input": {
            "nodeId": "HJKBgCw5zE",
            "pinKey": "HkXm80uHPyb"
          },
          "output": {
            "nodeId": "BkxxBxRw9GN",
            "pinKey": "__out__"
          }
        },
        "S1sgSe0w9zN": {
          "id": "S1sgSe0w9zN",
          "input": {
            "nodeId": "H1mSxRP9zE",
            "pinKey": "HkqmLAOrD1W-$1"
          },
          "output": {
            "nodeId": "H1breRvcfN",
            "pinKey": "HyZHD8tcW"
          }
        },
        "SJDZre0DqME": {
          "id": "SJDZre0DqME",
          "input": {
            "nodeId": "H1-lBxCD5M4",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "rkeBlCw9fN",
            "pinKey": "BkqLCOSw1W"
          }
        },
        "SJGZHxRvqzE": {
          "id": "SJGZHxRvqzE",
          "input": {
            "nodeId": "HyNHgCD5zV",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "SyylBgRw5fV",
            "pinKey": "HyZHD8tcW"
          }
        },
        "SkFZBeCw9fV": {
          "id": "SkFZBeCw9fV",
          "input": {
            "nodeId": "rkSeRD5f4",
            "pinKey": "HkXK-dGob"
          },
          "output": {
            "nodeId": "BkxxBxRw9GN",
            "pinKey": "__out__"
          }
        },
        "SkqxSe0w9GE": {
          "id": "SkqxSe0w9GE",
          "input": {
            "nodeId": "ryBBlRw5zV",
            "pinKey": "HkXm80uHPyb"
          },
          "output": {
            "nodeId": "rJTSlADqf4",
            "pinKey": "HyZHD8tcW"
          }
        },
        "SyFlBlRD5f4": {
          "id": "SyFlBlRD5f4",
          "input": {
            "nodeId": "Hy0BlCDqME",
            "pinKey": "HkXm80uHPyb"
          },
          "output": {
            "nodeId": "H1breRvcfN",
            "pinKey": "HyZHD8tcW"
          }
        },
        "SyLbSeAP9fN": {
          "id": "SyLbSeAP9fN",
          "input": {
            "nodeId": "ryBBlRw5zV",
            "pinKey": "Hy-QUR_BPkZ"
          },
          "output": {
            "nodeId": "S1sBe0v5fN",
            "pinKey": "HJU8CE2lW"
          }
        },
        "SySgHlCw5GV": {
          "id": "SySgHlCw5GV",
          "input": {
            "nodeId": "HJKBgCw5zE",
            "pinKey": "Hy-QUR_BPkZ"
          },
          "output": {
            "nodeId": "S1sBe0v5fN",
            "pinKey": "HJU8CE2lW"
          }
        },
        "rJ7bSgAv9GE": {
          "id": "rJ7bSgAv9GE",
          "input": {
            "nodeId": "H1mSxRP9zE",
            "pinKey": "HkqmLAOrD1W"
          },
          "output": {
            "nodeId": "rynHlAD9zV",
            "pinKey": "HyZHD8tcW"
          }
        },
        "rkJ-HlCP9MV": {
          "id": "rkJ-HlCP9MV",
          "input": {
            "nodeId": "H1breRvcfN",
            "pinKey": "B15NPUY9W"
          },
          "output": {
            "nodeId": "BkIBx0wqME",
            "pinKey": "r1lQLAOBwJb"
          }
        },
        "rkngBlAw9zV": {
          "id": "rkngBlAw9zV",
          "input": {
            "nodeId": "rkeBlCw9fN",
            "pinKey": "SkdIRuBD1b"
          },
          "output": {
            "nodeId": "H1mSxRP9zE",
            "pinKey": "SyomIRurDJ-"
          }
        }
      },
      "nodes": {
        "BkIBx0wqME": {
          "id": "BkIBx0wqME",
          "position": {
            "x": 203,
            "y": 101
          },
          "type": "xod/core/buffer"
        },
        "BkxxBxRw9GN": {
          "id": "BkxxBxRw9GN",
          "position": {
            "x": -43.25000047683716,
            "y": -2
          },
          "type": "xod/patch-nodes/input-number"
        },
        "By_Sx0wcME": {
          "id": "By_Sx0wcME",
          "position": {
            "x": 135,
            "y": 203
          },
          "type": "xod/core/watch"
        },
        "H1-lBxCD5M4": {
          "id": "H1-lBxCD5M4",
          "position": {
            "x": 93.74999952316284,
            "y": 305
          },
          "type": "xod/core/watch"
        },
        "H1GreCvcME": {
          "id": "H1GreCvcME",
          "position": {
            "x": 169,
            "y": 203
          },
          "type": "xod/core/watch"
        },
        "H1breRvcfN": {
          "id": "H1breRvcfN",
          "position": {
            "x": 271,
            "y": 101
          },
          "type": "xod/core/defer(number)"
        },
        "H1mSxRP9zE": {
          "arityLevel": 4,
          "id": "H1mSxRP9zE",
          "position": {
            "x": 203,
            "y": 305
          },
          "type": "xod/core/add"
        },
        "H1wSg0D5MV": {
          "description": "The last read potentiometer position in range [0.0, 1.0].",
          "id": "H1wSg0D5MV",
          "label": "VAL",
          "position": {
            "x": 339,
            "y": 407
          },
          "type": "xod/patch-nodes/output-number"
        },
        "HJKBgCw5zE": {
          "id": "HJKBgCw5zE",
          "position": {
            "x": 67,
            "y": 101
          },
          "type": "xod/core/buffer"
        },
        "Hy0BlCDqME": {
          "id": "Hy0BlCDqME",
          "position": {
            "x": 339,
            "y": 101
          },
          "type": "xod/core/buffer"
        },
        "HyNHgCD5zV": {
          "id": "HyNHgCD5zV",
          "position": {
            "x": 203,
            "y": 203
          },
          "type": "xod/core/watch"
        },
        "S1sBe0v5fN": {
          "id": "S1sBe0v5fN",
          "position": {
            "x": 271,
            "y": -1
          },
          "type": "xod/core/clock"
        },
        "SyylBgRw5fV": {
          "id": "SyylBgRw5fV",
          "position": {
            "x": 543,
            "y": 101
          },
          "type": "xod/core/defer(number)"
        },
        "rJ9rl0vqMV": {
          "id": "rJ9rl0vqMV",
          "position": {
            "x": 101,
            "y": 203
          },
          "type": "xod/core/watch"
        },
        "rJTSlADqf4": {
          "id": "rJTSlADqf4",
          "position": {
            "x": 407,
            "y": 101
          },
          "type": "xod/core/defer(number)"
        },
        "rkSeRD5f4": {
          "id": "rkSeRD5f4",
          "position": {
            "x": 67,
            "y": 203
          },
          "type": "xod/core/watch"
        },
        "rkeBlCw9fN": {
          "boundLiterals": {
            "BytUCdHD1-": "4"
          },
          "id": "rkeBlCw9fN",
          "position": {
            "x": 203,
            "y": 407
          },
          "type": "xod/core/divide"
        },
        "ryBBlRw5zV": {
          "id": "ryBBlRw5zV",
          "position": {
            "x": 475,
            "y": 101
          },
          "type": "xod/core/buffer"
        },
        "rynHlAD9zV": {
          "id": "rynHlAD9zV",
          "position": {
            "x": 135,
            "y": 101
          },
          "type": "xod/core/defer(number)"
        }
      },
      "path": "@/rolling-average"
    }
  }
}

Credits

Sam Mugford

Sam Mugford

4 projects • 3 followers
Ben Dewhurst

Ben Dewhurst

1 project • 2 followers
Lawrence Percival-Alwyn

Lawrence Percival-Alwyn

5 projects • 4 followers

Comments