在我们之前的一个教程中,我们研究了DIY盖革计数器显示“可指导”用户的努力Prabhat他结合了ESP8266和触摸屏显示器,创造了一个真正直观的盖革计数器版本。他最近创建了一个更新版本,今天的教程将重点介绍如何复制这个新版本的盖革计数器。
带WiFi的新改进盖革计数器
这个盖革计数器是用来探测和测量电离辐射的仪器。它是世界上最著名的辐射检测仪器之一,因为它可以用来检测电离辐射,例如阿尔法粒子,贝塔粒子,以及伽马射线射线和its通常被用作手持辐射测量仪器,当处于危险的环境辐射水平区域时,用一种非常熟悉的咔嗒声警告用户。
虽然这个项目保留了第一版的一些功能,比如ESP8266触摸屏界面,而不是像第一个版本那样实现辐射水平的检测,它结合了盖革计数器,一个剂量计,和辐射监测在一个单独的软件包中,它的厚度减少了50%,并且有很多新的软件功能!一些新功能包括:
- 更直观的图形用户界面
- 在主屏幕上显示每分钟计数、当前剂量和累积剂量
- 灵敏可靠SBM-20盖革-穆勒管
- 平均剂量率的可变积分时间
- 测量低剂量的定时计数模式
- 用户可以选择Sieverts和Rems显示为剂量单位的剂量率
- 用户可调警报阈值
- 可调校准,将CPM与各种同位素的剂量率联系起来
- 离线数据记录
- 将大容量日志数据发布到云服务(说话)绘图、分析和/或保存到计算机
- 监测站模式:设备保持与WiFi的连接,并定期向东西说话通道
- 2000毫安时可充电锂电池,运行时间为16小时,配有微型USB充电端口
- 由于WiFi设置是通过用户界面处理的,因此无需终端用户编程。
虽然这些升级对一个没有辐射的书呆子来说是没有意义的,但与市面上常见的盖革计数器相比,这些更新将设备提升到了一个更强大的水平。
Wemos D1迷你板
这个ESP8266保留了以前的版本,但是WEMOS D1迷你被用来代替NodeMCU减少项目的总体规模。这个SBM-20 Geiger Muller管子和2.8英寸SPI触摸屏也保留了。另外还使用了其他一些分立元件,其中大多数都是贴片型元件,以使器件紧凑。
在本教程的最后,您将不仅知道如何复制这个项目,还将知道如何实现诸如构建能够将数据上载到的物联网设备等任务东西说话,使用GUI更新WiFi详细信息,而不需要更改代码和其他许多有趣的事情。
所需组件
下表列出了完成项目完整组装所需的组件。该列表不包括将在表中提供的离散组件,因此不会造成混乱。
- WEMOS D1 Mini或克隆
- 2.8英寸SPI触摸屏
- 端部脱落的SBM-20盖革管(许多供应商在线)
- 3.7V LiPo充电器板
- Turnigy 3.7 V 1S 1C LiPo battery (49 x 34 x 10mm) with JST-PH connector
- M3 x 22 mm沉头螺钉
- M3 x 8 mm六角机螺钉
- M3黄铜螺纹嵌件
- 导电铜带
SMB-20管电气规格:
- 工作电压:350至475 V DC
- 最小阳极电阻:1 MΩ(额定电压至少500 V)
- 推荐阳极电阻:5.1MΩ(额定电压至少500V)
- 平台长度:至少100 V
- 高原坡度:0.1%/1V
- 最小死区时间:190μs(400V时)
SMB-20管物理规格
- 直径:11 mm
- 长度:108毫米(毫米)
- 重量:10克
- 额定温度:-60至70°C
下表提供了其他使用的离散零部件,整个BOM表作为.CSV文件附在下载部分下。
包含所使用的分立元件的表
所有用于该项目的分立器件都是从立创商城:上采购的,因此在搜索栏中输入零件号将显示精确的零部件。
立创商城
原理图
这个项目是用印刷电路板来实现的,以使东西紧凑整洁。如前所述,大多数使用的电子部件都是SMD类型,这样做是为了尽可能减小设备的尺寸。项目原理图具体如下:
为了使那些想要修改或复制PCB的人更容易,所有的项目文件,包括原理图和PCB是用Kicad,也可以从zip下载和下载Prabhat’s GitHub第页
所有无源元件(电阻器、电容器)封装均采用0603,而晶体管是用SOT-23,LDO输入SOT-89,555个计时器SOIC-8.定制的脚印为电感器,开关和蜂鸣器和他们所需的文件也压缩与其他文件在下载部分。
印刷电路板
制造后的PCB将如下图所示;
外壳设计
两个版本之间组件的设计和位置的更改意味着我们还需要为今天的项目创建另一个外壳。
这个外壳的设计与新的缩小尺寸的设备相匹配。与第一个版本相比,它包含的零件更少(只有两个),而且在装配中仍然使用螺钉。而不是像第一个版本那样把盖革-穆勒管放在顶部,而是放在外壳的侧面,以消除对设备顶部额外空间的需要。
附件所有部分的.STL文件都附在下载部分下面的zip文件中。
外壳三维视图
设置THINGSPEAK
正如在介绍中提到的,这个版本的项目将能够在3种模式下运行,或者作为Datalogger, Monitoring车站还是普通的盖革计数器. 当用作数据记录器或监控站时,设备将其数据发送到云端,因此Thingspeak被用作设备云平台。因此,创建一个Thingspeak账户并获得所有必要的凭证,如:;API密钥和频道ID因为在项目进一步开发时需要它们。
按照以下步骤设置Thingspeak帐户;
1去东西说话如果你已经有一个账户,注册或者登录。
2登录后,单击“频道”按钮。这将引导您进入频道页面。“频道”页面提供已创建的所有频道的列表。单击添加新频道按钮添加新频道。
三。这将引导您进入一个页面,您需要在其中填写频道的详细信息。输入姓名,短说明,和领域对于这个项目,我们将创建两个频道。第一个将保持鈥每分钟记录计数 Data with a field to hold the holmiumCPM”
4而第二个将保持鈥CPM实时更新 Data with a field called实时更新“. 填写详细信息后,单击“确定”按钮。
5这两个频道现在应该添加到您的频道列表,如下图所示。
6通过单击每个频道,您将被重定向到该频道的仪表板,您将看到它的频道ID. 复制两个通道的通道ID,因为我们将在代码中使用它们。
7在频道仪表板上,也单击密钥API. 这将向您显示读和写通道的API键。复制并保留Write API密钥,因为我们的目的是写入通道。
完成这项工作后,我们就可以编写代码了。
装置总成
在PCB组装完成后,按照以下步骤将设备组装在一起。
- 首先使用热风焊接站或回流焊炉将所有SMD元件焊接到主PCB
- 此外,将电池充电器板焊接到焊盘上,并将通孔组件焊接到主PCB上。
- 从LCD显示屏上卸下SD卡读卡器,以防止其在数据记录过程中与进程交互。
- 将LCD板焊接到末端的PCB上。在这之后,您将无法对D1 Mini进行去焊接。另一个选择是安装D1迷你使用头引脚,这样就不需要焊接它,它将有可能随意删除它。
- 确保没有突出的LED,并且所有部件都正确焊接。
- 取两根绞合线,将第一根线的一端焊接到SBM-20的一端(阳极),并将第二根线的一端连接到SBM-2o的主体上,用铜带固定。将两根导线的另一端分别连接到板上的阳极和阴极连接。注意确保极性正确。
- 3D打印外壳和封盖,并在机箱内布置组件,用3.8mm螺钉固定组装好的PCB。另外,把盖革管放在烤架旁边,并用胶带固定,以防脱落。连接所有电线和电池,并用盖子封闭外壳。你现在应该准备好了。
组装完成后,在安装后盖之前,设备应如下图所示。
组装盖革计数器
代码
与上一个版本一样,这个版本的代码也是使用鈥开发的PlatformIO IDE “.这意味着,如果你没有设置在上一个教程,你有另一个机会完成它现在。按照我们之前创建的教程学习如何用Pla编程Arduino和ESP8266板,来整理它
这个项目的草图很大程度上依赖于Adafruit_ILI9341,这个Adafruit GFX,WiFi管理器图书馆。ILI9341库允许我们直接与显示器交互,因为它用于创建显示器的用户界面,而WiFi管理器允许用户更改存储在设备上的密码,而无需对代码进行任何更改,从而无需编辑代码以添加WiFi凭据。除了这些库之外,我们还将使用其他几个库,比如XPT2046_Touchscreen图书馆EEPROM图书馆SPI库在其他中。XPT2046_触摸屏库允许我们使用显示器的触摸屏功能,而EEPROM库则允许我们执行与第一版相同的任务;保存包括WiFi凭据在内的所有设置,这样当电源被回收时,数据不会丢失,用户无需提供这些设置再次提供信息。所有这些库都可以通过Arduino库管理器安装。
这个草图与我们上一个教程的草图非常相似,但是像往常一样,我将对代码的一些重要部分做一个快速的解释。
我们首先声明将要使用的库。除了上面提到的库,我们还将添加两个字体库,用于在显示器上显示文本。
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <E;
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <Wi;
#include <EEPROM.h>
#include "SPI.h"
#include "Ada;
#include <Fon;
#include <Fon;
#include "Ada;
#include <XPT2046_Touc;
接下来,我们创建一个以CS管脚为参数的触摸屏库对象,然后创建变量来保存触摸屏的(4个极端)校准点,并指定显示器的DC和CS管脚所连接的Arduino的管脚。
#define CS_PIN D2
XPT2046_Touchscreen ts(CS_PIN);
#define TS_MINX 250
#define TS_MINY 200 // calibration points for touchscreen
#define TS_MAXX 3800
#define TS_MAXY 3750
#define TFT_DC D4
#define TFT_CS D8
我们还创建变量来保存十六进制值,这些值表示我们将使用的不同颜色,然后创建变量来保存各种WiFi/数据上载参数,如从Thingspeak、Thingspeak服务器地址等获得的密码、SSID、API密钥和频道ID。
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF
#define DOSEBACKGROUND 0x0455
// WiFi variables
unsigned long currentUploadTime;
unsigned long previousUploadTime;
int passwordLength;
int SSIDLength;
int channelIDLength;
int writeAPILength;
char ssid[20];
char password[20];
char channelID[20]; // = "864288";
char channelAPIkey[20]; // = "37SAHQPEQ7FOBC20";
char server[] = "a;;
int attempts; // number of connection attempts when device starts up in monitoring mode
接下来,我们创建一个WiFi,通过它设备可以通过web进行通信,并创建Adafruit TFT库的一个实例。
WiFiClient client;
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
然后创建其他变量,这些变量将用于Thingspeak上的数据记录、监测电池、在EEPROM中保存数据以及计算计量单位。
const int interruptPin = 5;
long count[61];
long fastCount[6]; // arrays to store running counts
long slowCount[181];
int i = 0; // array elements
int j = 0;
int k = 0;
int page = 0;
long currentMillis;
long previousMillis;
unsigned long currentMicros;
unsigned long previousMicros;
unsigned long averageCount;
unsigned long currentCount; // incremented by interrupt
unsigned long previousCount; // to activate buzzer and LED
unsigned long cumulativeCount;
float doseRate;
float totalDose;
char dose[5];
int doseLevel; // determines home screen warning signs
int previousDoseLevel;
bool ledSwitch = 1;
bool buzzerSwitch = 1;
bool wasTouched;
int integrationMode = 0; // 0 = medium, 1 = fast, 2 == slow;
bool doseUnits = 0; // 0 = Sievert, 1 = Rem
unsigned int alarmThreshold = 5;
unsigned int conversionFactor = 175;
int x, y; // touch points
// Battery indicator variables
int batteryInput;
int batteryPercent;
int batteryMapped = 212; // pixel location of battery icon
int batteryUpdateCounter = 29;
// EEPROM variables
const int saveUnits = 0;
const int saveAlertThreshold = 1; // Addresses for storing settings data in the EEPROM
const int saveCalibration = 2;
const int saveDeviceMode = 3;
const int saveLoggingMode = 4;
const int saveSSIDLen = 5;
const int savePWLen = 6;
const int saveIDLen = 7;
const int saveAPILen = 8;
// Data Logging variables
int addr = 200; // starting address for data logging
char jsonBuffer[14000] = "[";
char data[14500] = "{\"write_api_key\":\"";
unsigned long currentLogTime;
unsigned long previousLogTime;
// Timed Count Variables:
int interval = 5;
unsigned long intervalMillis;
unsigned long startMillis;
unsigned long elapsedTime;
int progress;
float cpm;
bool completed = 0;
int intervalSize; // stores how many digits are in the interval
// Logging variables
bool isLogging;
bool deviceMode;
// interrupt routine declaration
void ICACHE_RAM_ATTR isr();
unsigned int previousIntMicros; // timers to limit count increment rate in the ISR
接下来,我们创建变量来保存不同位图图像的字符等价物。我们在上一个教程是关于在LCD上显示位图图像的。
const unsigned char gammaBitmap [] PROGMEM = {
0x30, 0x00, 0x78, 0x70, 0xe8, 0xe0, 0xc4, 0xe0, 0x84, 0xc0, 0x05, 0xc0, 0x05, 0x80, 0x07, 0x80,
0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x3e, 0x00,
0x1c, 0x00, 0x00, 0x00
};
const unsigned char betaBitmap [] PROGMEM = {
0x00, 0xc0, 0x00, 0x03, 0xf0, 0x00, 0x07, 0x18, 0x00, 0x06, 0x18, 0x00, 0x0e, 0x18, 0x00, 0x0e,
0x18, 0x00, 0x0e, 0xf8, 0x00, 0x0e, 0x1c, 0x00, 0x0e, 0x0c, 0x00, 0x0e, 0x0c, 0x00, 0x0e, 0x0c,
0x00, 0x0e, 0x0c, 0x00, 0x0f, 0x1c, 0x00, 0x0f, 0xf8, 0x00, 0x0e, 0x00, 0x00, 0x0e, 0x00, 0x00,
0x0c, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char wifiBitmap [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x00, 0x0f, 0xfe, 0x00, 0x3f, 0xff, 0x80, 0x78,
0x03, 0xc0, 0xe0, 0x00, 0xe0, 0x47, 0xfc, 0x40, 0x0f, 0xfe, 0x00, 0x1c, 0x07, 0x00, 0x08, 0x02,
0x00, 0x01, 0xf0, 0x00, 0x03, 0xf8, 0x00, 0x01, 0x10, 0x00, 0x00, 0x40, 0x00, 0x00, 0xe0, 0x00,
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
const unsigned char settingsBitmap[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00,
0x00, 0x01, 0xc0, 0x7f, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x7f, 0xe0, 0xfc, 0x00, 0x00,
0x00, 0x07, 0xf9, 0xff, 0xf9, 0xfe, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xf0, 0x7f, 0xfc, 0x00, 0x00,
0x00, 0x03, 0xff, 0xc0, 0x3f, 0xfc, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x80, 0x1f, 0xff, 0x80, 0x00,
0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00, 0x01, 0xff, 0xff, 0x00, 0x07, 0xff, 0xf8, 0x00,
0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00,
0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00,
0x01, 0xff, 0xfe, 0x00, 0x07, 0xff, 0xf8, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0f, 0xff, 0xf0, 0x00,
0x00, 0x1f, 0xff, 0x80, 0x1f, 0xff, 0x80, 0x00, 0x00, 0x03, 0xff, 0xc0, 0x3f, 0xfc, 0x00, 0x00,
0x00, 0x03, 0xff, 0xe0, 0x7f, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x07, 0xf9, 0xff, 0xf9, 0xfe, 0x00, 0x00,
0x00, 0x03, 0xf0, 0x7f, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x7f, 0xe0, 0x38, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char buzzerOnBitmap[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0c, 0x00,
0x00, 0x00, 0x07, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x80,
0x07, 0x00, 0x00, 0x00, 0x3f, 0x80, 0xc7, 0x80, 0x00, 0x00, 0xff, 0x80, 0xe3, 0x80, 0x00, 0x01,
0xff, 0x80, 0xf3, 0xc0, 0x00, 0x03, 0xff, 0x80, 0x71, 0xc0, 0x00, 0x07, 0xff, 0x8c, 0x79, 0xc0,
0x3f, 0xff, 0xff, 0x9e, 0x38, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x38, 0xe0, 0x3f, 0xff, 0xff, 0x8e,
0x3c, 0xe0, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0xe0, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x60, 0x3f, 0xff,
0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70,
0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87, 0x1c, 0x70, 0x3f, 0xff, 0xff, 0x87,
0x1c, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x3c, 0xe0, 0x3f, 0xff, 0xff, 0x8e, 0x38, 0xe0, 0x3f, 0xff,
0xff, 0x9e, 0x38, 0xe0, 0x00, 0x07, 0xff, 0x8c, 0x79, 0xc0, 0x00, 0x03, 0xff, 0x80, 0x71, 0xc0,
0x00, 0x00, 0xff, 0x80, 0xf1, 0xc0, 0x00, 0x00, 0x7f, 0x80, 0xe3, 0x80, 0x00, 0x00, 0x3f, 0x80,
0xc7, 0x80, 0x00, 0x00, 0x1f, 0x80, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x0f, 0x00, 0x00, 0x00,
0x07, 0x80, 0x0e, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char buzzerOffBitmap[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80,
0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
0x3f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00,
0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x0f, 0xff, 0x80,
0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x3f, 0xff,
0xff, 0x8f, 0x00, 0x78, 0x7f, 0xff, 0xff, 0x8f, 0x80, 0xf8, 0x7f, 0xff, 0xff, 0x8f, 0xc1, 0xf8,
0x7f, 0xff, 0xff, 0x87, 0xe3, 0xf0, 0x7f, 0xff, 0xff, 0x83, 0xf7, 0xe0, 0x7f, 0xff, 0xff, 0x81,
0xff, 0xc0, 0x7f, 0xff, 0xff, 0x80, 0xff, 0x80, 0x7f, 0xff, 0xff, 0x80, 0x7f, 0x00, 0x7f, 0xff,
0xff, 0x80, 0x7f, 0x00, 0x7f, 0xff, 0xff, 0x80, 0xff, 0x80, 0x7f, 0xff, 0xff, 0x81, 0xff, 0xc0,
0x7f, 0xff, 0xff, 0x83, 0xf7, 0xe0, 0x7f, 0xff, 0xff, 0x87, 0xe3, 0xf0, 0x7f, 0xff, 0xff, 0x8f,
0xc1, 0xf0, 0x7f, 0xff, 0xff, 0x8f, 0x80, 0xf8, 0x3f, 0xff, 0xff, 0x8f, 0x00, 0x70, 0x3f, 0xff,
0xff, 0x84, 0x00, 0x20, 0x1f, 0xff, 0xff, 0x80, 0x00, 0x00, 0x0f, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x07, 0xff, 0x80, 0x00, 0x00, 0x00, 0x03, 0xff, 0x80, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80,
0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00,
0x1f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0x00,
0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
const unsigned char ledOnBitmap[] PROGMEM = {
0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
0x00, 0x00, 0x00, 0x18, 0x07, 0x00, 0xc0, 0x00, 0x00, 0x1c, 0x07, 0x01, 0xc0, 0x00, 0x00, 0x1e,
0x07, 0x03, 0xc0, 0x00, 0x00, 0x0e, 0x07, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1e, 0x00, 0x1f, 0xc0, 0x03, 0xc0, 0x0f, 0x80, 0x7f, 0xf0, 0x0f, 0x80, 0x07, 0xc1,
0xff, 0xfc, 0x1f, 0x00, 0x03, 0xc3, 0xe0, 0x3e, 0x1e, 0x00, 0x00, 0x07, 0xc0, 0x0f, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03,
0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x7f, 0x1c,
0x00, 0x01, 0xc3, 0xf0, 0x7f, 0x1c, 0x00, 0x01, 0xc7, 0xf0, 0x3c, 0x0e, 0x00, 0x03, 0x81, 0xe0,
0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x07,
0x80, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0f, 0x00, 0x00, 0x01, 0xc3,
0xc0, 0x1e, 0x1c, 0x00, 0x07, 0xc1, 0xc0, 0x1c, 0x1f, 0x00, 0x0f, 0x81, 0xe0, 0x3c, 0x0f, 0x80,
0x1e, 0x00, 0xe0, 0x38, 0x03, 0xc0, 0x0c, 0x00, 0xe0, 0x38, 0x01, 0x80, 0x00, 0x00, 0xf0, 0x78,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
const unsigned char ledOffBitmap[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x01,
0xff, 0xfc, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x3e, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x0f, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x07, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03,
0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x1c,
0x00, 0x01, 0xc0, 0x00, 0x00, 0x1c, 0x00, 0x01, 0xc0, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00,
0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x80, 0x00, 0x00, 0x0f, 0x00, 0x07,
0x80, 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x03,
0xc0, 0x1e, 0x00, 0x00, 0x00, 0x01, 0xc0, 0x1c, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x3c, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x78,
0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00,
0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0,
0x00, 0x00, 0x00, 0x00, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00};
const unsigned char backBitmap [] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x01, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xc0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
接下来,我们声明将要使用的所有函数。需要注意的是,这可能不是必需的,但它只是防止某些C/C编译器可能遇到的错误。
void drawHomePage(); // page 0
void drawSettingsPage(); // page 1
void drawUnitsPage(); // page 2
void drawAlertPage(); // page 3
void drawCalibrationPage(); // page 4
void drawWifiPage(); // page 5
void drawTimedCountPage(); // page 6
void drawTimedCountRunningPage(int duration, int size); // page 7
void drawDeviceModePage(); // page 8
void drawFrame();
void drawBackButton();
void drawCancelButton();
void drawCloseButton();
void drawBlankDialogueBox();
long EEPROMReadlong(long address);
void EEPROMWritelong(int address, long value); // logging functions
void createJsonFile();
void clearLogs();
完成后,我们就转到无效设置()功能
我们开始无效设置()通过初始化串行监视器将波特率设置为 thirty-eight thousand and four hundred您可以随意将其设置为任何您想要的,只需确保串行监视器设置为相同的波特率。
void setup()
{
Serial.begin(38400);
然后,我们使用begin命令初始化触摸屏(ts)和TFT,并将旋转设置为适合我们的方向(在本例中为2)。我们还用黑色填充屏幕以创建一种黑色背景。
();
(2);
();
(2);
(ILI9341_BLACK);
完成后,我们初始化连接状态LED和蜂鸣器的引脚,将它们的引脚模式设置为输出,并将两者都关闭。
pinMode(D0, OUTPUT); // buzzer switch
pinMode(D3, OUTPUT); // LED
digitalWrite(D3, LOW);
digitalWrite(D0, LOW);
接下来我们初始化EEPROM并初始化几个变量,包括doseUnits, alarmThreshold和conversionFactor ,设备模式 ,SSIDLength ,频道ID,等,使用存储在EEPROM上的数据。
EEPROM.begin(4096); // initialize emulated EEPROM sector with 4 kb
doseUnits = EEPROM.read(saveUnits);
alarmThreshold = EEPROM.read(saveAlertThreshold);
conversionFactor = EEPROM.read(saveCalibration);
deviceMode = EEPROM.read(saveDeviceMode);
isLogging = EEPROM.read(saveLoggingMode);
addr = EEPROMReadlong(96);
SSIDLength = EEPROM.read(saveSSIDLen);
passwordLength = EEPROM.read(savePWLen);
channelIDLength = EEPROM.read(saveIDLen);
writeAPILength = EEPROM.read(saveAPILen);
然后使用SSIDLength、passwordLength、ChannelIDlength和writepailength作为指针,分别从EEPROM获取SSID、Password、ChannelID和APIkey。
for (int i = 10; i < 10 + SSIDLength; i++)
{
ssid[i - 10] = EEPROM.read(i);
}
Serial.println(ssid);
for (int j = 30; j < 30 + passwordLength; j++)
{
password[j - 30] = EEPROM.read(j);
}
Serial.println(password);
for (int k = 50; k < 50 + channelIDLength; k++)
{
channelID[k - 50] = EEPROM.read(k);
}
Serial.println(channelID);
for (int l = 70; l < 70 + writeAPILength; l++)
{
channelAPIkey[l - 70] = EEPROM.read(l);
}
Serial.println(channelAPIkey);
接下来,我们调用drawHomePage()函数显示主页
drawHomePage();
结束无效设置(),我们检查是否为设备选择了模式。如果未选择模式,则ESP8266 WiFi功能将关闭。但如果选择了模式,则会设置WiFi详细信息,并显示连接进度和状态。的另一个实例drawHomePage在设备成功连接到internet后调用。
if (!deviceMode)
{
WiFi.mode( WIFI_OFF ); // turn off wifi
WiFi.forceSleepBegin();
delay(1);
}
else
{
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
drawBlankDialogueBox();
(1);
(&FreeSans9pt7b);
(ILI9341_WHITE);
(38, 140);
("Connecting to WiFi..");
while () != WL_CONNECTED) && (attempts < 300))
{
delay(100);
attempts ++;
}
if (attempts >= 300)
{
deviceMode = 0;
(45, 200);
("Failed to connect.");
delay(1000);
}
else
{
(68, 200);
("Connected!");
delay(1000);
}
drawHomePage();
}
}
完成后,我们转到void setup函数。
接下来是空洞环功能。这就是所有行动发生的地方。void循环显然太长了,无法解释,但由于使用了非常描述性的变量名,因此应该很容易理解。剂量率受剂量率的影响,剂量率的变化受剂量率的影响。当剂量水平达到特定阈值时,它会触发警报并显示当前所经历的辐射临界水平。还有一部分void循环代码创建一个JSON文件,其中包含从设备获取的读数并将其上载到东西说话定期或只要有WiFi/互联网接入。void loop函数中的其他代码片段与显示数据和在显示上维护良好的UI有关。
由于其庞大,项目的完整代码与其他资源一起附在下载部分。
编程
代码的编译和上载是使用PlatformIO IDE如上所述。这是用于嵌入式C/C开发的新一代工具集,您需要安装它才能使用上面的代码。你需要先下载并安装Microsoft的Visual Studio代码作为PlatformIO IDE是建在上面的。为此,请遵循简短的说明在这里. 然后重新启动Visual Studio代码应用更改。现在,您将看到PlarformIO扩展处于活动状态,如下所示:
PlarformIO安装在Microsoft Visual Studio代码上
Next click “New Project” -> Add a project name -> Select board:wemos D1迷你建兴-> Framework: Arduino -> Finish. You will then see a list of directories and files on the left. Select the main.cpp并将上面找到的代码粘贴到编辑器中。现在是时候编译代码并检查是否一切正常。在此之前,我建议您添加:#include <Wire.h>库,因为这是编译期间需要的。另外,请确保从库管理器安装必要的库:
PlatformIO图书馆经理
所需的库包括:
- Adafruit GFX库
- Adafruit ILI9341
- Adafruit TouchScreen
- WifiManager
- XPT2046_Touchscreen
在我们的例子中,我们必须手动下载Adafruit_TouchScreen库并将其放置在以下路径中:
C:\Users\<your username>\.platformio\lib
As the library from the build in manager did "work for us. Now it" time to compile the code using the " Build按钮。如果一切正常,代码应该编译成功。
成功生成
接下来,我们准备将代码上传到wemosd1板。要执行此操作,请单击鈥上传”按钮。等待几秒钟,代码将成功上载。
演示
现在,您应该会看到显示主页的屏幕,如下图所示。
用各种放射源测试盖革计数器
为了测试该设备,一些辐射源放在它旁边,并被检测到,如下面的视频所示:
示波器测量
黄色:电子管阴极上γ光子探测的电压尖峰。绿色:脉冲检测电路产生的INT信号,驱动WEMOSD1的D1引脚
同上,无需测量标记,以获得更好的可视性
黄色:管子阳极上γ光子探测的电压尖峰(我们看到电压从278V下降到几乎一半)绿色:脉冲探测电路产生的INT信号,驱动WEMOSD1的D1引脚
555定时器IC引脚6上的放电电压
改进
盖革高原曲线(来源:wikimedia.org)
虽然盖革计数器似乎可以很好地检测硬β和γ光子,但我们应该注意到,管工作电压可以达到280伏直流电使用上述555定时器振荡器。此电压低于建议的工作电压(350–475V)SBM-20并且似乎在平坦区域(100V长度)外工作,在该区域中,管的响应是平坦的。因此,我们建议改进高压电源,以产生更高的电压。这将有助于在制造商建议的电压下操作管。
结论
这个气相色谱仪-20Prabhat提供了一些新功能,允许用户通过用户界面对配置/设置进行多次更改,为了便于操作,Prabhat为该设备创建了一本用户手册,以展示如何使用它。经历手册也可能有助于更好地了解代码的工作原理。
盖革计数器的改进和特点Prabhat与市场上的常规产品相比,它更具吸引力,这也显示了DIY可以给项目带来的改进力量。
所有的项目文件都附在下载部分下,如果你在复制项目时有任何困难,请随时通过评论部分联系我。
项目的视频演示Prabhat可以在上找到Youtube网站 .
参考文献:
下载
另外需要下载以下项目资料,可以私信我。