Compare commits

...

9 Commits

Author SHA1 Message Date
Bartosz Mazurczak
ce69c34ce0 add todo 2025-01-14 11:59:06 +01:00
Bartosz Mazurczak
83887c1b8e add radioactive at home link 2025-01-14 11:35:55 +01:00
Bartosz Mazurczak
962eddbd40 RadMon support 2025-01-14 11:33:57 +01:00
55578b5636 Update README.md 2025-01-12 19:52:23 +01:00
ace8ec01e8 Update README.md 2025-01-12 19:50:03 +01:00
Bartosz Mazurczak
ebd10751fa add radmon support 2025-01-12 19:46:34 +01:00
9dbc2dec58 Merge pull request 'oled' (#1) from oled into main
Reviewed-on: #1
2025-01-12 19:06:20 +01:00
54f325a4bb Update README.md 2025-01-12 19:00:01 +01:00
Bartosz Mazurczak
08dde0f633 edit README 2025-01-12 18:57:34 +01:00
2 changed files with 115 additions and 44 deletions

View File

@@ -1,15 +1,18 @@
# Geiger-interface - WIP
#### TODO:
- RadMon integration
- ~~RadMon integration~~
- Clean code
- check MQTT reliability
- OLED display support
- Check MQTT reliability
- ~~OLED display support~~
- Radioactive@home integration (as a standalone sensor without Boinc client)
- Fix saving params after DRD
### Hardware
**RadiationD v1.1 (CAJOE)** it's a cheap(est) Geiger counter that you can found on China market. I recommend to order assembled ;) due lacks of documentations. Next one is ESP32. I like generic dev boards like **HW-394 - ESP32-WROOM-32** - they are cheap, have many gpio, now they have even USB-C ;) Let's go connect it together. My CAJOE arrived with DuPont jumper wire, but don't be confused: **VIN** on CAJOE is an signal output! After everything is connected, you can flash ESP with **Geiger-interface.ino**. On first boot, WiFiManager create access point named **ESP_xxxxxx**. After connect there will be captive portal (or under address http://192.168.4.1) where you can configure:
- Wifi connection
- MQTT server address
- GMC accound and geiger ID
- RadMon Username and Password
After **save** interface should connect to Wifi and send data :) If you provide wrong data you can enable captive portal by double reset of ESP.
@@ -43,7 +46,8 @@ reload configuration and voilà!
<img src="assets/ha2.png" width="600">
### RadMon integration
**TBD**
- Create account on https://radmon.org/
- Login, go to **Control Panel** -> fill form to add sensor
### J3x5 Tube specification
| Property | J3x5 |
@@ -64,7 +68,8 @@ About J305 Tube conversion factor, you can read intresting article on: https://i
### 3D Printed case
Files download here https://git.noop.re/drops/Geiger-interface/src/branch/main/stl
Files download here https://git.noop.re/drops/Geiger-interface/src/branch/main/stl - case_bottom_oled.stl have more height due a gold pins on oled display and esp32 board.
If you have / order boards without gold pins and you use soldering wires to connect, you can print standard case.
<img src="assets/bottom1.png" width="600"><br>
<img src="assets/case1.png" width="600"><br>
@@ -72,8 +77,12 @@ Files download here https://git.noop.re/drops/Geiger-interface/src/branch/main/s
<img src="assets/photo4.jpg" width="600"><br>
<img src="assets/photo1.jpg" width="600"><br>
<img src="assets/photo3.jpg" width="600"><br>
<img src="assets/photo5.jpg" width="600"><br>
<img src="assets/photo6.jpg" width="600"><br>
<img src="assets/photo7.jpg" width="600"><br>
### Resources
- https://iot-devices.com.ua/
- https://www.gmcmap.com/
- https://radmon.org/
- https://radmon.org/
- http://radioactiveathome.org/

View File

@@ -43,6 +43,8 @@ char mqttUser[50] = "";
char mqttPass[50] = "";
char gmcAccountID[50] = "";
char gmcDeviceID[50] = "";
char rmUser[50] = "";
char rmPass[50] = "";
bool shouldSaveConfig = false;
char buf[10];
@@ -84,6 +86,8 @@ void saveConfigFile()
json["mqttPass"] = mqttPass;
json["gmcAccountID"] = gmcAccountID;
json["gmcDeviceID"] = gmcDeviceID;
json["rmUser"] = rmUser;
json["rmPass"] = rmPass;
File configFile = FileFS.open(JSON_CONFIG_FILE, "w");
if (!configFile)
@@ -127,7 +131,8 @@ bool loadConfigFile()
strcpy(mqttPass, json["mqttPass"]);
strcpy(gmcAccountID, json["gmcAccountID"]);
strcpy(gmcDeviceID, json["gmcDeviceID"]);
strcpy(rmUser, json["rmUser"]);
strcpy(rmPass, json["rmPass"]);
return true;
}
@@ -201,6 +206,71 @@ String printLocalTime()
return String(buffer);
}
void radmonUpload(int cpm) {
const char *cmdFormat = "http://radmon.org/radmon.php?function=submit&user=%s&password=%s&value=%d&unit=CPM";
char url[256];
HTTPClient http2;
// create the request URL
sprintf(url, cmdFormat, rmUser, rmPass, cpm);
Serial.print("[HTTP] begin: ");
Serial.println(url);
if (http2.begin(espClient2, url)) {
Serial.print("[HTTP] GET...");
// start connection and send HTTP header
int httpCode = http2.GET();
// HTTP header has been sent and server response header has been handled
Serial.printf(" code: %d\n", httpCode);
// httpCode will be negative on error
if (httpCode > 0) {
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http2.getString();
Serial.println(payload);
}
}
else {
Serial.printf("[HTTP] GET failed, error: %s\n", http2.errorToString(httpCode).c_str());
}
http2.end();
}
}
void gmcUpload() {
Serial.print("[HTTP] begin...\n");
GMCMap_Request = GMCMap_Request_payload + "?AID=" + gmcAccountID + "&GID=" + gmcDeviceID + "&CPM=" + buf + "&ACPM=" + buf + "&uSV=" + buf2;
Serial.println(GMCMap_Request);
HTTPClient http;
if (http.begin(espClient2, GMCMap_Request)) { // HTTP
Serial.print("[HTTP] GET...\n");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http.getString();
Serial.println(payload);
if (payload.indexOf("ERR0") > 0) GMCMap = "OK";
if (payload.indexOf("ERR1") > 0) GMCMap = "Error! User is not found";
if (payload.indexOf("ERR2") > 0) GMCMap = "Error! Geiger Counter is not found";
if (payload.indexOf("Warning") > 0) GMCMap = "Warning! The Geiger Counter location changed, please confirm the location";
Serial.println(GMCMap);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
GMCMap = http.errorToString(httpCode).c_str();
}
http.end();
} else {
Serial.println("[HTTP] Unable to connect");
GMCMap = "Unable to connect";
}
}
void setup() {
// WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
// it is a good practice to make sure your code sets wifi mode how you want it.
@@ -211,7 +281,7 @@ void setup() {
initLittleFS();
display.begin(i2c_Address, true);
display.setContrast (0);
lcdPrint("Geiger Interace");
drd = new DoubleResetDetector(DRD_TIMEOUT, DRD_ADDRESS);
@@ -228,6 +298,8 @@ void setup() {
WiFiManagerParameter custom_mqttPass("mqttPass", "MQTT Password", mqttPass, 50);
WiFiManagerParameter custom_gmcAccountID("gmcAccountID", "GMC MAP Account ID", gmcAccountID, 50);
WiFiManagerParameter custom_gmcDeviceID("gmcDeviceID", "GMC MAP Device ID", gmcDeviceID, 50);
WiFiManagerParameter custom_rmUser("rmUser", "RadMon User", rmUser, 50);
WiFiManagerParameter custom_rmPass("rmPass", "RadMon Password", rmPass, 50);
wm.addParameter(&custom_mqttServer);
@@ -235,6 +307,8 @@ void setup() {
wm.addParameter(&custom_mqttPass);
wm.addParameter(&custom_gmcAccountID);
wm.addParameter(&custom_gmcDeviceID);
wm.addParameter(&custom_rmUser);
wm.addParameter(&custom_rmPass);
// wm.resetSettings();
bool res;
@@ -263,12 +337,16 @@ void setup() {
strcpy(mqttPass, custom_mqttPass.getValue());
strcpy(gmcAccountID, custom_gmcAccountID.getValue());
strcpy(gmcDeviceID, custom_gmcDeviceID.getValue());
strcpy(rmUser, custom_rmUser.getValue());
strcpy(rmPass, custom_rmPass.getValue());
Serial.println("The values in the file are: ");
Serial.println("\tmqtt_server : " + String(mqttServer));
Serial.println("\tmqtt_user : " + String(mqttUser));
Serial.println("\tmqtt_pass : " + String(mqttPass));
Serial.println("\tgmc_AccountID : " + String(gmcAccountID));
Serial.println("\tgmc_DeviceID : " + String(gmcDeviceID));
Serial.println("\trm_User : " + String(rmUser));
Serial.println("\trm_Pass : " + String(rmPass));
if (shouldSaveConfig)
{
@@ -286,6 +364,7 @@ void setup() {
}
void loop() {
// Double Reset Detection
drd->loop();
// if MQTT server provided
@@ -294,12 +373,6 @@ void loop() {
reconnect();
}
if(millis() >= time_now + 5000){
time_now += 5000;
client.publish("esp32/heartbeat", "PING");
}
if (millis() >= mold + 60000) {
ltoa(GeigerCounts, buf, 10);
dtostrf(GeigerCounts*TUBE_FACTOR, -4, 2, buf2);
@@ -310,45 +383,34 @@ void loop() {
lcdUpdate();
}
client.loop();
//if(millis() >= time_now + 5000){
// time_now += 5000;
// client.publish("esp32/heartbeat", "PING");
//}
}
// Update time on LCD
getLocalTime(&timeinfo);
if (timeinfo.tm_sec == 0){
lcdUpdate();
}
// if GMC IDs provided
if (String(gmcAccountID) != "") {
currentMillis = millis();
// Sending HTTP requests in every 10 minutes
currentMillis = millis();
if (currentMillis - previousMillis_10m >= interval_10m) {
previousMillis_10m = currentMillis;
Serial.print("[HTTP] begin...\n");
GMCMap_Request = GMCMap_Request_payload + "?AID=" + gmcAccountID + "&GID=" + gmcDeviceID + "&CPM=" + buf + "&ACPM=" + buf + "&uSV=" + buf2;
Serial.println(GMCMap_Request);
HTTPClient http;
if (http.begin(espClient2, GMCMap_Request)) { // HTTP
Serial.print("[HTTP] GET...\n");
int httpCode = http.GET();
if (httpCode > 0) {
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = http.getString();
Serial.println(payload);
if (payload.indexOf("ERR0") > 0) GMCMap = "OK";
if (payload.indexOf("ERR1") > 0) GMCMap = "Error! User is not found";
if (payload.indexOf("ERR2") > 0) GMCMap = "Error! Geiger Counter is not found";
if (payload.indexOf("Warning") > 0) GMCMap = "Warning! The Geiger Counter location changed, please confirm the location";
Serial.println(GMCMap);
}
} else {
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
GMCMap = http.errorToString(httpCode).c_str();
}
http.end();
} else {
Serial.println("[HTTP] Unable to connect");
GMCMap = "Unable to connect";
// if RadMon username provided
if (String(rmUser) != "") {
radmonUpload(atoi(buf));
}
// if GMC IDs provided
if (String(gmcAccountID) != "") {
gmcUpload();
}
}
}
}