Wifi LED CPM Display for displaying station count

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Nuts about radioactive everything!
More
6 months 5 days ago - 6 months 3 days ago #5932 by Simomax
[Updated: 22/12/2021]

Its the first day of holidays and I'm bored already.... So I cooked up a neat wifi/wemos d1 mini/arduino/LED display for displaying a station's current CPM.

It works by simply connecting to one's wifi and then goes to the URL, pulls the data, strips the first space and everything afterwards then converts what is left to a float (the CPM count from the start of the string) and displays it. The bar graph LEDs are mapped from 0 to 100 CPM at full scale deflection, but the 7 segment display will display up to 999.9 CPM, and after that will just display - - - - lol. It's super easy to build (5 wires and no more!) and cost about a tenner (Ten Great Britain Pounds Sterling) in all. The display is actually for another project, but I'm waiting on parts for that so thought I would learn how the display works and made this! I think I'll keep it and house it in something nice. Maybe a vintage round desk clock case or something. I am struggling with the speaker on the display and it just sounds like crap when I try to use it. It may only be compatible with an arduino, not the wemos d1 mini. The pictures are less than desirable, but meh.... You get the idea! 

I have added a feature to display in uSv/hr instead of CPM - Selectable in code.

I wrote a very simple PHP page that generates a random number between 10 and 100 for testing purposes. It emulates the 'last reading' page from Radmon.org so can be used in testing playing with the string also. (For parsing etc.) You can use it here: wasabi.schmoozie.co.uk/radmon/random_cpm.php and source below.

The display module is from www.mottramlabs.com (shop on ebay) and the MCU is just a Wemos D1 Mini R2.

 

This is reading 336.2 CPM (fudged, so it will show the full bar)

 

A couple of Youtubes of the display in action. This is using a random CPM generator mentioned above.

Without decimal:


With decimal:


Arduino code:
/*
    LED display with bar graph for displaying Radmon.org CPM By Simomax

    -------------------------------------------------------------
    Display:

    MAX7219 Power Display Round Type - Tester and Soak Tester
    Version 1 - 6th May 2021
    Board: Arduino UNO

    Pin connections
    Name      Arduino     MAX7219 7 Segment display
    -----------------------------------------------
              +5V         VCC
              GND         GND
    DIN       D11/MOSI    DIN         Wemos D7
    CS        D10/SS      CS          Wemos D8
    CLK       D13/SCK     CLK         Wemos D5

    David Mottram www.mottramlabs.com
    MAX7219 Library & Documentation: https://github.com/Mottramlabs/MAX7219-7-Segment-Driver
    -------------------------------------------------------------
    
    Ver 1.3 22/12/2021

    Change Log:
    1.0 - Initial release
    1.1 - Added animation 
    1.2 - Tidied code. Added user variables to make it easier for newbie programmers/builders (and me!)
    1.3 - Added feature to display in uSv/hr
    
*/

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <SPI.h>                        // SPI library needed for the MAX7219 library
#include <MAX7219_Digits.h>
#define MAX7219_CS D8                   // CS pin used on Arduino

MAX7219_Digit My_Display(MAX7219_CS);   // Make an instance of MAX7219_Digit called My_Display and set CS pin

int Bar_1[25] {0, 128, 192, 224, 240, 248, 252, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
int Bar_2[25] {0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 192, 224, 240, 248, 252, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255};
int Bar_3[25] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 192, 224, 240, 248, 252, 254, 255};

String payload;
float cpm;
float dispcpm;
float oldcpm;

//User variables ------------------------------------------

bool useuSv = false;               // Display microsieverts per hour (uSv/hr) instead of CPM. Requires the conversion factor to be that of the GM tube in the counter.
float conversionFactor = 0.0057;  // onversion factor for uSV. 0.00833 for LND712 / 0.0057 for SBM-20 / 0.00812 for J305B.
int brightness = 2;               // 0-15 brightness.
int interval = 60000;              // Interval to check the page and get the latest CPM. For Radmon.org 60000 (60 seconds) is recommended as the minimum value. For testing with the random CPM generator, 5000 is suggested minimum: (http://wasabi.schmoozie.co.uk/radmon/random_cpm.php).
#define usedecimal 1              // 0 for no decimal point and 1, 2 or 3 for a decimal point and the number of 0's after. This has no effect when 'useuSv' is true.
//String url = "http://wasabi.schmoozie.co.uk/radmon/random_cpm.php";           // Can be used for testing. Set the interval to 5000 when testing.
String url = "http://radmon.org/radmon.php?function=lastreading&user=radspod_suburb";

//End user variables --------------------------------------

ESP8266WiFiMulti WiFiMulti;

void setup() {

  Serial.begin(115200); Serial.println(""); Serial.println("Clackin!");
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP("Your_WiFi_SSID", "Your_WiFi_Password");
}

void loop() {

  // wait for WiFi connection
  if ((WiFiMulti.run() == WL_CONNECTED)) {

    HTTPClient http;
    Serial.print("[HTTP] begin...\n");
    // configure traged server and url
    //http.begin(url, "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS - can't get this to work
    //http.begin(url); //HTTP
    http.begin(url); //HTTP

    Serial.print("[HTTP] GET...\n");
    // start connection and send HTTP header
    int httpCode = http.GET();

    // httpCode will be negative on error
    if (httpCode > 0) {
      // HTTP header has been send and Server response header has been handled
      Serial.printf("[HTTP] GET... code: %d\n", httpCode);

      // file found at server
      if (httpCode == HTTP_CODE_OK) {
        payload = http.getString();
        Serial.println(payload);
      }

      String firstPart = getValue(payload, ' ', 0);
      Serial.println(firstPart);
      cpm = firstPart.toFloat();
    } else {
      Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
    }
    http.end();
  }
  
  int steps;
  
  if (oldcpm == cpm) { //------------------------------------------------ do nothing
    Serial.println("Doing nothing....");
  }
  
  else if (oldcpm < cpm) { //------------------------------------------------ count up
    Serial.println("Count up!");
    My_Display.Begin();
    My_Display.Brightness(brightness);    // Set brightness 0-15
    while (oldcpm < cpm) {
      if (useuSv) {
        float tempuSv = oldcpm * conversionFactor;
        My_Display.Display_Value(1, tempuSv, 3, 0x00);
      }
      else {
        My_Display.Display_Value(1, oldcpm, usedecimal, 0x00);
      }
      int xcpm;
      if (oldcpm > 99) {
        xcpm = 99;
      }
      else {
        xcpm = oldcpm;
      }
      int xx = map(xcpm, 0, 100, 0, 25);
      My_Display.MAX7219_Write(5, Bar_1[xx]);
      My_Display.MAX7219_Write(6, Bar_2[xx]);
      My_Display.MAX7219_Write(7, Bar_3[xx]);
      oldcpm += 0.1;
      if ((cpm - oldcpm) <= 1) { // these delays slow the display down when reaching its destined number. Gives it a 'dampened' feel
        delay(50);
      }
      else if ((cpm - oldcpm) <= 2) {
        delay(40);
      }
      else if ((cpm - oldcpm) <= 3) {
        delay(30);
      }
      else if ((cpm - oldcpm) <= 5) {
        delay(20);
      }
      else if ((cpm - oldcpm) <= 10) {
        delay(10);
      }
      else {
        delay(5);
      }
    }
  }
  
  else if (oldcpm > cpm) {//------------------------------------------------ count down
    Serial.println("Count Down!");
    My_Display.Begin();
    My_Display.Brightness(brightness);    // Set brightness 0-15
    while (oldcpm > cpm) {
      if (useuSv) {
        float tempuSv = oldcpm * conversionFactor;
        My_Display.Display_Value(1, tempuSv, 3, 0x00);
      }
      else {
        My_Display.Display_Value(1, oldcpm, usedecimal, 0x00);
      }
      int xcpm;
      if (cpm > 99) {
        xcpm = 99;
      }
      else {
        xcpm = oldcpm;
      }
      int xx = map(xcpm, 0, 100, 0, 25);
      My_Display.MAX7219_Write(5, Bar_1[xx]);
      My_Display.MAX7219_Write(6, Bar_2[xx]);
      My_Display.MAX7219_Write(7, Bar_3[xx]);
      oldcpm -= 0.1;
      if ((oldcpm - cpm) <= 1) { // these delays slow the display down when reaching its destined number. Gives it a 'dampened' feel
        delay(50);
      }
      else if ((oldcpm - cpm) <= 2) {
        delay(40);
      }
      else if ((oldcpm - cpm) <= 3) {
        delay(30);
      }
      else if ((oldcpm - cpm) <= 5) {
        delay(20);
      }
      else if ((oldcpm - cpm) <= 10) {
        delay(10);
      }
      else {
        delay(5);
      }
    }
  }

  My_Display.Begin(); //---------------------------------------------------- just set the damn thing as sometimes it will be 0.1 out and I can't be bothered chasing it in code.
  My_Display.Brightness(brightness);    // Set brightness 0-15
      if (useuSv) {
        float tempuSv = cpm * conversionFactor;
        My_Display.Display_Value(1, tempuSv, 3, 0x00);
      }
      else {
        My_Display.Display_Value(1, cpm, usedecimal, 0x00);
      }
  int xcpm;
  if (cpm > 99) {
    xcpm = 99;
  }
  else {
    xcpm = cpm;
  }
  int xx = map(xcpm, 0, 100, 0, 25);
  My_Display.MAX7219_Write(5, Bar_1[xx]);
  My_Display.MAX7219_Write(6, Bar_2[xx]);
  My_Display.MAX7219_Write(7, Bar_3[xx]);

  if ((WiFiMulti.run() == WL_CONNECTED)) {
    oldcpm = cpm;
    delay(interval);
  }
}

String getValue(String data, char separator, int index) // function used to get the first part of the string received
{
  int found = 0;
  int strIndex = {0, -1};
  int maxIndex = data.length() - 1;

  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++;
      strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }

  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

PHP random CPM code:
<?php
echo(rand(10,100) . " CPM on " . date('Y-m-j h:i:s') . "UTC at Random_CPM, Generator, UK");
?>
Attachments:
Last edit: 6 months 3 days ago by Simomax.
The following user(s) said Thank You: mw0uzo

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Nuts about radioactive everything!
More
6 months 5 days ago - 6 months 5 days ago #5933 by Simomax
Updated the code to include a bit of animation. It was boring with the display simply changing to a new number and the bar graph doing the same, so now it counts up and down and the bar graph increases and decreases incrementally. Is much nicer on the eyes! 
Last edit: 6 months 5 days ago by Simomax.
The following user(s) said Thank You: mw0uzo

Please Log in or Create an account to join the conversation.

More
6 months 4 days ago #5938 by mw0uzo
This is all very cool. Thank you for posting the ideas and source, they will surely be helpful for others. I actually wonder if you want to help out tinkering with radmon.org to improve some things that have been waiting for ages and add some new stuff?

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Nuts about radioactive everything!
More
6 months 4 days ago #5940 by Simomax

I actually wonder if you want to help out tinkering with radmon.org to improve some things that have been waiting for ages and add some new stuff?


Sure! What is it you have in mind? I'm no great programmer, but I will certainly help if I can. 

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Nuts about radioactive everything!
More
6 months 3 days ago #5945 by Simomax
Update!

I have updated the code a little. Added some variables to make it easier to setup and run. I have also written a neat random CPM generator that emulates the format of the 'last reading' page. Every time the page is loaded it spits out a random CPM from 10 to 100. I used this when demonstrating in a couple of videos I have made showing it running. I have included the videos in the original post with updates.

Enjoy! 

Please Log in or Create an account to join the conversation.

  • Simomax
  • Simomax's Avatar Topic Author
  • Offline
  • Platinum Member
  • Platinum Member
  • Nuts about radioactive everything!
More
6 months 3 days ago #5947 by Simomax
Updated again! This time adding a feature to display uSv/hr instead of CPM. 

Please Log in or Create an account to join the conversation.

Time to create page: 0.425 seconds
Powered by Kunena Forum
Solar powered Raspberry Pi 4 server stats: CPU 56% Memory 17% Swap 14% CPU temp=65.7'C Uptime 13 Days