Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Hand tools and fabrication machines | ||||||
| ||||||
|
Homebrew Hydrometer
Summary:
We have built a magnetic hydrometer that (with some limitations) measures the alcohol content of beer during fermentation, in real time and non-invasively. In addition we provide 3 new XOD nodes to control a magnetic sensor, a light sensor and to smooth noisy signals.
Introduction
Successful home brewing beer requires rigorous quality control, however equipment for the measurement of many of the important parameters of beer is not widely available to home brewers. Alcohol content can be measured indirectly by monitoring the change in density of the beer during fermentation. As sugars are converted to alcohol, the density of the liquid decreases. By comparing the density before and after fermentation, alcohol content can be calculated. Density is measured using a hydrometer, the height at which this floats in the liquid indicates the density. However, this requires that the fermentation vessel is opened to insertthe hydrometer and take a reading, which risks introducing microbial contaminationduring fermentation.
The aim ofthis project is to develop an automated hydrometer- based on the Arduino and associated kit provided by the Biomaker competition- that provides real-time non-invasive monitoringof beer fermentation.
Results:
Our initial strategy employed the ultrasonic distance sensor provided with the Biomaker kit to measure the height at which the hydrometer was floating. By mounting the sensor on the inside of the lid facing down, above the hydrometer (which had a flat piece of paper mounted on the top)- we could measure the distance to the top of the hydrometer. Converting this to a hydrometer reading requires subtracting it from the distance from the sensor tothe surface of the liquid, then applying a multiplier to convert the distanceto a specific gravity reading.
The distance to the surface of the liquid is first measured using the acoustic sensor without the hydrometer in place. We included a buffer inthe XOD code that stores the reading taken after pressing reset on the board, and uses this as the baseline reading. Then, the hydrometer can then be put inplace, the lid closed and the fermentation allowed to proceed. We connected the I2C 16x2 LCD display to provide a readout of the measured specific gravity.
This unit functioned, however it suffered two significant set-backs. First the acoustic sensor does not provide sufficient resolution to provide accurate measurements of specific gravity. Changes in specific gravityin the region of 0.02 g/cm^3 are required for accurate determination of alcoholcontent correspond to changes in distance of aprox 1 mm. Secondly, the sensor must sit inside the fermentation vessel, which is a warm, wet environment not suitable for electronic devices. Thirdly, the reading generated contains a lot of noise resulting from motion of the hydrometer in the liquid.It would be desirable to calculate a rolling average of the reading to provide a value with the noise removed.
We considered two alternative sensors to overcome theseproblems. A laser-range finder, that measures distance using reflected electromagnetic- rather than acoustic- radiation would provide the required accuracy of measurement and could be set up in a very similar manner as the acoustic sensor. However, this would still require that the sensor be placed inside the fermentation vessel.
Alternatively, a hall-effect sensor that measures the proximity of a magnetic field might be used. By attaching a magnet to the hydrometer, the hall effect sensor can be used to measure the height of thesensor with sub-millimetre resolution, and the sensor can be mounted on the outside of the fermentation vessel. We created a XOD node for the sunfounder analog hall sensor, this can be found in the attached XOD code “New XOD Patches”.
We mounted neodymium magnets on the end of a bamboo kebab skewer, which was attached to the hydrometer so that the magnets protruded into a tubemounted on the lid of the fermentation vessel.
The position of the magnet in the tube depends upon the height the hydrometer is floating in the liquid. The hall-effect sensor was mounted on the outside of the tube, and positioned immediately adjacent to the position of the magnet at the start of fermentation. Movement of the magnet downwards as fermentation proceeds then results in achange in the hall effect sensor reading, which we calibrated to convert to a alcohol concentration.
This provides an accurate read-out, the sensor provides sufficient accuracy to monitor the progression of fermentation and determine alcohol content, and keeps the sensitive electronics outside the moist environment of the fermentation vessel. However, with the set-up we used, the sensor is only accurate over the range of about 1 cm, corresponding to a change in alcohol of about 2% ABV. Thus future efforts will be required to extend the range of the apparatus. This could be achieved by using a more powerful magnet (although due to the inverse square relationship between distance and field strength, this would require something in the order of a 25-fold increase in magnetic field strength). Alternatively, the use of a float with a wider diameter as the hydrometer would result in shorter distance in vertical travel for a given change in density. These experiments are beyond the scope of the current study however.
We also addressed the noise inherent in the hydrometer readings by creating a XOD node that calculates a rolling average. This can be used to smooth any input signal, and can be found in the attached XOD code “New XOD patches”. It takes 4 sequential readings over 4 seconds and calculates theaverage, but the number and frequency of sampling may be easily modified.
Future work aims to extend the useful range of the magnetic hydrometer, as described above. Also we would like to incorporate further sensors to more fully characterise the properties of the beer, such as the temperatureduring fermentation. We have previously built software, AutoBrewControl (ABC), that helps design beer recipes. ABC uses parameters from ingredients (for example, malt diastatic power, hop alpha-acid content, yeast strain efficiency etc..) to model the properties of the resulting beer, returning predicted values for alcohol content, colour, and bitterness. To better asses the accuracy of our models, we would like to be able to quantitatively measure the colour and bitterness, both of which can be determined spectrophotometrically. Thus we envisage a complete brewery monitoring system that also includes a temperature probe and a spectrophotometer.
Magnetic hydrometer assembly pt.2
Magnetic hydrometer assembly pt.3
Magnetic hydrometer assembly pt.4
Acoustic hydrometer code
C/C++{
"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++{
"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++{
"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"
}
}
}
Comments