0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用 Windows 10 UWP制作一个扎啤机

科技观察员 来源:Kevin D Wolf 作者:Kevin D Wolf 2022-09-07 15:24 次阅读

使用 Windows 10 UWP 应用程序的强大功能来控制和监控啤酒桶,让您的饮料保持凉爽、新鲜和随时可用。

注意:首先,这个项目绝不会提倡使用或滥用酒精,这完全取决于用户在这个 kegerator 中的内容是什么饮料。

这个项目的诞生是为了更好地管理扎啤机。扎啤机的基本原理是保持饮料低温以及将饮料碳酸保持在一定的 PSI 下。此外,仅仅给自己倒一杯冷饮,你根本不知道桶里还剩多少。

所以这个项目的目标是:

保持饮料的一致温度,确保饮料不会过热或过冷并冻结

确保将可接受的碳酸化量应用于小桶以保持最佳风味

跟踪每个桶中的饮料量并提供视觉反馈,以确保为大型比赛准备充足的饮料。

跟踪用于碳酸饮料的罐中剩余的二氧化碳量

基本电子元件及其用途:

冷藏柜用于冷却装置并提供框架以制作精美的家具

Raspberry PI 2 Running Windows 10 IoT core 被用作操作的大脑

小型邮资秤用于测量每个小桶和二氧化碳罐的重量,这些邮资秤移除了电子设备,并在秤中内置了称重传感器放大器和小型 Arduino。这些秤将通过 I2C 与 Raspberry PI 2 通信(稍后会详细介绍)

设备上安装了 5 个数字温度传感器,一个在冷冻柜的底部,一个安装在顶部的下侧,一个安装在水龙头把手所在的塔架上(稍后会详细介绍)和一个安装在设备外部以测量环境温度。这些温度传感器连接到一个小型 Arduino,还通过 I2C 与 Raspberry PI 2 通信

霍尼韦尔压力传感器连接到用于为小桶提供碳酸化作用的空气管路上。虽然 PSI 的调整是手动的(目前),但这将提供一个准确的计量器来确定桶中的二氧化碳量。

5V 电源用于为 Raspberry PI2 供电。选择了更大的版本(提供高达 6 安培),因此它也可以为可寻址的 LED 灯条供电。

一个简单的继电器与压缩机电源串联。使用这个继电器,可以从压缩机施加和断开电源,然后压缩机将依次控制 kegerator 的温度(稍后会详细介绍)

云连接

Ultimate Kegerator 包含一个 Web 服务器,允许通过 REST 服务进行远程配置以及当前状态的简单静态视图。可以通过http://slsys.homeip.net:9501访问该网站 。

此外,Ultimate Kegerator 将其重要统计数据上传到 Windows Azure 事件中心。虽然无法使用标准 Nuget 包与事件中心对话,但是你可以使用 Windows Embedded MVP Paolo Patierno提供的易于实现的库,网址为

https://www.nuget.org/packages/AzureSBLite/

数据被推送到WindowsAzure上的事件中心:

poYBAGMYRkaAZ7a_AACr1RTuysU158.png

通过流分析进行最终处理

WindowsAzure上的流分析正在处理的数据:

pYYBAGMYRl6AZ_8KAAD3PCI0Ixo975.png

流分析的最终计划是:

1) 监控并通知温度是否过热或过冷

2) 监测并通知 CO2 罐何时过低

3) 监测并通知 CO2 罐是否检测到泄漏(重量逐渐减轻)

以下是组装过程的一些附加图片:

电子秤组装

pYYBAGMYRlKASLq2AANiH83HwZ0441.png

称重传感器:

pYYBAGMYRmCAIeJZAAHZ_sZEhQw412.png

测试+5VDC 稳压器:

poYBAGMYRleATX53AAN07vv27_I878.png

在测试压缩机继电器时准备连接:

poYBAGMYRmWAOaN_AANkxhqAtYQ949.png

电源:

pYYBAGMYRmmAL74aAAPa_l7nfTM683.png

CPU

poYBAGMYRm2AF385AAQ1FhbjzMY148.png

连接温度传感器:

pYYBAGMYRnWAeHRZAANh4z2IWZg308.png

Arduino的最终封装:

poYBAGMYRneAflQ7AALOJXET4Ng192.png

压力传感器及其+5VDC至+3.3VDC稳压器:

pYYBAGMYRoGAGyh8AAOHmCxKcww556.png

最终成果:

poYBAGMYRoOAUqofAANdyy8dido024.png

Kegerator Class:

using LagoVista.Common.Commanding;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Windows.Devices.Enumeration;
using Windows.Devices.I2c;

namespace LagoVista.IoT.Common.Kegerator
{
public class Kegerator : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private Models.Keg _keg1;
private Models.Keg _keg2;
private Models.Keg _keg3;
private Models.Keg _keg4;
private CO2.CO2Tank _co2Tank;

private Kegerator() { }

public List _devices = new List();

private void RaisePropertyChanged([CallerMemberName] string propertyName = null)
{
var eventHandler = this.PropertyChanged;
if (eventHandler != null)
{
eventHandler(this, new PropertyChangedEventArgs(propertyName));
}
}

private bool Set(ref T storage, T value, string columnName = null, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return false;

storage = value;
this.RaisePropertyChanged(propertyName);
return true;
}

byte[] _scalesAddresses = { 0x43, 0x41, 0x40, 0x42 };

private const string I2C_CONTROLLER_NAME = "I2C1";

private Thermo.Temperatures _temperatures;
private Thermo.Controller _tempController;

private Scales.Scale _co2Scale;
private Dictionary _kegScales;

private CO2.PressureSensor _pressureSensor;
private LED.LEDManager _ledManager;

private REST.KegeratorServices _kegServices;

private static Kegerator _kegerator = new Kegerator();
public static Kegerator Instance { get { return _kegerator; } }

private CloudServices.EventHubClient _eventHubClient;

System.Threading.Timer _timer;


private bool _initialized = false;

public async Task Init()
{
if (!_initialized)
{
_initialized = true;
var selector = I2cDevice.GetDeviceSelector(I2C_CONTROLLER_NAME); /* Find the selector string for the I2C bus controller */
var deviceInfo = (await DeviceInformation.FindAllAsync(selector)).FirstOrDefault(); /* Find the I2C bus controller device with our selector string */

var deviceId = deviceInfo == null ? (string)null : deviceInfo.Id;
_temperatures = new Thermo.Temperatures(0x48);
await _temperatures.Init(deviceId);
_devices.Add(_temperatures);

_tempController = new Thermo.Controller();
_tempController.Init(_temperatures);
_devices.Add(_tempController);

_pressureSensor = new CO2.PressureSensor();
await _pressureSensor.Init(deviceId, TimeSpan.FromSeconds(1));
_devices.Add(_pressureSensor);

_co2Scale = new Scales.Scale(0x44);
await _co2Scale.Init(deviceId, TimeSpan.FromSeconds(1));
_devices.Add(_co2Scale);

_co2Tank = new CO2.CO2Tank(_co2Scale, TimeSpan.FromSeconds(2));
_co2Tank.Load();
_devices.Add(_co2Tank);

_kegScales = new Dictionary();

_eventHubClient = new CloudServices.EventHubClient(this, TimeSpan.FromSeconds(2));
_devices.Add(_eventHubClient);

for (var idx = 0; idx < 4; ++idx)
{
var scale = new Scales.Scale(_scalesAddresses[idx]);
await scale.Init(deviceId, TimeSpan.FromMilliseconds(500));
_kegScales.Add(idx, scale);
_devices.Add(scale);
}

_keg1 = new Models.Keg(1, _kegScales[0], TimeSpan.FromMilliseconds(500));
_keg1.Load();
_devices.Add(_keg1);
_keg2 = new Models.Keg(2, _kegScales[1], TimeSpan.FromMilliseconds(500));
_keg2.Load();
_devices.Add(_keg2);
_keg3 = new Models.Keg(3, _kegScales[2], TimeSpan.FromMilliseconds(500));
_keg3.Load();
_devices.Add(_keg3);
_keg4 = new Models.Keg(4, _kegScales[3], TimeSpan.FromMilliseconds(500));
_keg4.Load();
_devices.Add(_keg4);

DateInitialized = DateTime.Now.ToString();

Web.WebServer.Instance.StartServer();

_kegServices = new REST.KegeratorServices() { Port = 9500 };
_kegServices.EventContent += _kegServices_EventContent;
_kegServices.StartServer();

_timer = new System.Threading.Timer((state) =>
{
Refresh();
}, null, 0, 250);
}

}

private void _kegServices_EventContent(object sender, string e)
{
var parts = e.Split('/');
if (parts.Count() > 0)
{
switch (parts[1])
{
case "zero":
{
var scaleIndex = Convert.ToInt32(parts[2]);
_kegScales[scaleIndex].StoreOffset();
}
break;
case "cal":
{
var scaleIndex = Convert.ToInt32(parts[2]);
_kegScales[scaleIndex].CalibrationWeight = Convert.ToDouble(parts[3]);
_kegScales[scaleIndex].Calibrate();
}
break;
}
}
}

public void Refresh()
{
foreach (var device in _devices)
{
if (DateTime.Now > (device.LastUpdated + device.UpdateInterval))
device.Refresh();
}

LagoVista.Common.PlatformSupport.Services.DispatcherServices.Invoke(() =>
{
CurrentTimeDisplay = DateTime.Now.ToString();
RaisePropertyChanged("CurrentTimeDisplay");
});
}

public Thermo.Temperatures Temperatures { get { return _temperatures; } }


public Thermo.Controller TemperatureController { get { return _tempController; } }


private String _statusMessage;
public String StatusMessage
{
get { return _statusMessage; }
set { Set(ref _statusMessage, value); }
}

public List KegScales
{
get { return _kegScales.Values.ToList(); }
}

public void ToggleCompressor()
{
if (_tempController.IsCompressorOn)
_tempController.CompressorOff();
else
_tempController.CompressorOn();
}

public String DateInitialized
{
get;
set;
}

public String CurrentTimeDisplay
{
get;
set;
}

public Scales.Scale CO2Scale
{
get { return _co2Scale; }
}

public CO2.PressureSensor PressureSensor
{
get { return _pressureSensor; }
}


public Models.Keg Keg1 { get { return _keg1; } }
public Models.Keg Keg2 { get { return _keg2; } }
public Models.Keg Keg3 { get { return _keg3; } }
public Models.Keg Keg4 { get { return _keg4; } }

public CO2.CO2Tank CO2Tank { get { return _co2Tank; } }

public RelayCommand ToggleCompressorCommand { get { return new RelayCommand(ToggleCompressor); } }
}
}

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • WINDOWS
    +关注

    关注

    3

    文章

    3440

    浏览量

    87145
  • 应用程序
    +关注

    关注

    37

    文章

    3136

    浏览量

    56405
  • DIY设计
    +关注

    关注

    2

    文章

    59

    浏览量

    19706
收藏 人收藏

    评论

    相关推荐

    Windows 10 IoT版本之间有什么区别?

    native和UWPapps与过去的Windows CE不同,Windows 10 IoT Core是Windows 10
    发表于 05-03 11:16

    安信Windows驱动开发教程:什么是通用 Windows 平台 (UWP) 应用程序?有什么功能?

    API 提供强大的 UI 和高级异步功能,这些功能非常适合联网设备。 若要下载开始创建 UWP 应用所需的工具,请参阅设置,然后编写你的第一个应用。Windows驱动开发定制UWP
    发表于 09-09 17:50

    安信Windows驱动开发教程:创建简单的 Windows 11 应用

    安信Windows驱动开发教程:创建简单的 Windows 11 应用 本文将引导您完成创建简单 Windows 11 应用程序的步骤,
    发表于 09-09 17:52

    安信Windows驱动开发教程:适用于 Windows 的 React Native

    安信Windows驱动开发教程:适用于 Windows 的 React NativeReact Native是 Facebook 的开发平台,允许构建跨平台应用程序。 React
    发表于 09-09 17:54

    Ubuntu今天正式以UWP应用的身份上架Win10应用商店

    Ubuntu今天正式以UWP应用的身份上架Win10应用商店。Windows Insider用户升级到Win10秋季创意者更新预览版Build 16190及以上就可以下载和安装Ubun
    发表于 07-12 11:40 2132次阅读

    Windows 10虚拟机进入免费试用阶段,1月15日截止

    如果想创建UWP应用程序,有比这更好的方法。首先,有一个Windows UWP社区工具包。这是一个开源工具包,可以为Windows 10设备
    发表于 11-28 09:08 1343次阅读

    Windows 10 ARM笔记本20小时的长续航遭怀疑 高通出面解说

    高通和微软共同推出的Windows 10 ARM笔记本具有超强的续航能力,但是长续航却遭到了用户的怀疑,认为仅使用Windows 10 UWP
    发表于 01-24 13:44 684次阅读
    <b class='flag-5'>Windows</b> <b class='flag-5'>10</b> ARM笔记本20小时的长续航遭怀疑 高通出面解说

    如何在Windows 10X上运行Win32应用

    尽管微软新推出的 Windows 10X 操作系统主要侧重于 UWP 和 Web 应用程序,但该公司也充分了解传统 Win32 对自家老用户的重要性。
    的头像 发表于 02-12 14:17 1802次阅读

    Facebook宣布UWP客户端彻底停用

    两周前,Facebook 就已经宣布了将从 Windows 10 应用商店撤下 UWP 客户端的消息。随着这一的正式到来,我们已无法再通过 Microsoft Store 下载该应用。
    的头像 发表于 02-29 15:37 1549次阅读

    微软Windows 10X系统支持UWP应用和Win32应用程序运行

    微软确认Windows 10X系统能够运行UWP应用、网页应用以及传统的Win32应用程序。Win32、UWP和PWA应用程序都会通过Windows
    的头像 发表于 05-15 17:04 2073次阅读

    Windows 10中,UWP应用程序还有前途吗?

    早在Windows 8发布时,微软就承诺要在现代和传统计算之间架起桥梁。在传统的Win32应用程序之外,Windows 8还为触屏设备提供了现代应用程序,也就是微软所说的UWP应用程序。
    的头像 发表于 09-10 10:12 2719次阅读

    UWP 版 QQ 已处于断连状态,无法登录

    5.4 版本。从 Windows 商店查询可知,Win10 UWP 版 QQ 今年年初还更新了 5.6 版本,主要是
    的头像 发表于 12-29 15:41 1.3w次阅读

    Windows 10、macOS 系统的全新电子邮件客户端:基于网页端Outlook

    微软此前曾表示正制作适用于 Windows 10 和 macOS 系统的全新电子邮件客户端,而根据最新掌握的信息该客户端将会基于网页端 Outlook 优化而来。此外微软还计划淘汰 2015 年推出
    的头像 发表于 01-08 12:55 2328次阅读

    使用Lattepanda板及Windows10开发板制作游戏PC

    电子发烧友网站提供《使用Lattepanda板及Windows10开发板制作游戏PC.zip》资料免费下载
    发表于 11-16 09:47 0次下载
    使用Lattepanda板及<b class='flag-5'>Windows10</b>开发板<b class='flag-5'>制作</b>游戏PC

    基于Raspberry Pi和通用Windows平台(UWP)的无人机

    电子发烧友网站提供《基于Raspberry Pi和通用Windows平台(UWP)的无人机.zip》资料免费下载
    发表于 07-03 14:49 0次下载
    基于Raspberry Pi和通用<b class='flag-5'>Windows</b>平台(<b class='flag-5'>UWP</b>)的无人机