盖革计数器笔记

硬件

看了HBO的《切尔诺贝利》之后,觉得是时候重新填坑了
把前两年买的盖格计数器翻出来Geiger-Counter-RadiationD-v1.1-CAJOE
它和NodeMCU连接如下

NodeMCU geiger(p3)
Vin(5V) 5V
GND GND
D2(IO4) VIN

加了块OLED显示器,连接如下

NodeMCU OLED
3V3 3V3
GND GND
D4(IO2) SCL
D3(IO0) SDA

软件

程序如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <ESP8266WiFi.h>
#include <Thread.h>
#include <SoftwareSerial.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>

#define OLED_RESET 5
Adafruit_SSD1306 display(OLED_RESET);

// Update these with values suitable for your network.
const char* ssid = "xxxxx";
const char* password = "xxxxx";
const char* mqtt_server = "192.168.1.110";

const char* clientID = "espgeiger";
const char* mqtt_topic = "Home/Global";

WiFiClient espClient;
PubSubClient client(espClient);

Thread geigerThread = Thread();

//geiger
volatile unsigned long counts = 0; // Tube events
unsigned long cpm = 0; // CPM
unsigned long previousMillis; // Time measurement
const int geigerPin = 4;
unsigned long currentMillis = millis();

#define LOG_PERIOD 30000 //Logging period in milliseconds
#define MINUTE_PERIOD 60000

void ICACHE_RAM_ATTR ISR_impulse ();
void ISR_impulse() { // Captures count of events from Geiger counter board
counts++;
}

void geigerCallback(){
currentMillis = millis();
if (currentMillis - previousMillis > LOG_PERIOD) {

previousMillis = currentMillis;
cpm = counts * MINUTE_PERIOD / LOG_PERIOD;
counts = 0;
}
}

void setup() {
Wire.begin(0, 2);
Serial.begin(115200);
pinMode(geigerPin, INPUT); // Set pin for capturing Tube events
interrupts(); // Enable interrupts
attachInterrupt(digitalPinToInterrupt(geigerPin), ISR_impulse, FALLING); // Define interrupt on falling edge
unsigned long clock1 = millis();

geigerThread.onRun(geigerCallback);
geigerThread.setInterval(1000);

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
display.println("booting");
display.display();

Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

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

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());

client.setServer(mqtt_server, 1883);
}

void reconnect() {
while (!client.connected()) {
Serial.print("AtDHTting MQTT connection...");
if (client.connect(clientID)) {
Serial.println("connected");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}

void loop(){

if(geigerThread.shouldRun())
geigerThread.run();
delay(30000);

if (!client.connected()) {
reconnect();
}
client.loop();
if (cpm==0) {
Serial.println("try to read sensor again!");
return;
}

StaticJsonBuffer<300> JSONbuffer;
JsonObject& JSONencoder = JSONbuffer.createObject();
JSONencoder["cpm"] = cpm;
float usvh = cpm/151.0;
JSONencoder["usvh"] = usvh;

char JSONmessageBuffer[300];
JSONencoder.prettyPrintTo(JSONmessageBuffer, sizeof(JSONmessageBuffer));
Serial.println(JSONmessageBuffer);

boolean isOK = client.publish(mqtt_topic, JSONmessageBuffer, true);
Serial.println(isOK);
display.clearDisplay();

char str[100];
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);
snprintf(str,16, "cpm=%d", cpm);
display.println(str);
snprintf(str,16, "usvh=%.3f", usvh);
display.println(str);
display.display();
}

修改homeassistantconfiguration.yaml

编辑/docker/homeassistantconfiguration.yaml在末尾加入

1
2
3
4
5
6
7
8
9
10
11
sensor:
- platform: mqtt
state_topic: "Home/Global"
name: 'cpm'
unit_of_measurement: 'cpm'
value_template: '{{ value_json.cpm }}'
- platform: mqtt
state_topic: "Home/Global"
name: 'usvh'
unit_of_measurement: 'usv/h'
value_template: '{{ value_json.usvh }}'

重启服务即可

引用

https://github.com/SensorsIot/Geiger-Counter-RadiationD-v1.1-CAJOE-/
https://www.youtube.com/watch?v=K28Az3-gV7E&feature=youtu.be
https://zh.wikipedia.org/wiki/%E8%A5%BF%E5%BC%97
https://github.com/SensorsIot/Geiger-Counter-RadiationD-v1.1-CAJOE-/blob/master/Geiger_Counter.ino