{"id":2822,"date":"2023-03-29T14:50:27","date_gmt":"2023-03-29T11:50:27","guid":{"rendered":"https:\/\/iot-devices.com.ua\/?p=2822"},"modified":"2023-03-30T08:02:38","modified_gmt":"2023-03-30T05:02:38","slug":"geiger-counter-emulator-ggreg20_v3-module-by-means-of-esp8266-part2","status":"publish","type":"post","link":"https:\/\/iot-devices.com.ua\/en\/geiger-counter-emulator-ggreg20_v3-module-by-means-of-esp8266-part2\/","title":{"rendered":"Geiger counter emulator of GGreg20_V3 module by means of ESP8266 Part 2 Building the Emulator"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"block-786c35cc-31be-43f0-a658-40945e2c73d7\">Geiger counter emulator: what we need<\/h2>\n\n<p>To build the Geiger counter module emulator, we&#8217;ll need the following parts and materials:<\/p>\n\n<ul class=\"wp-block-list\"><li>ESP8266 #1 as the main one (MCU_A, NodeMCU module);<\/li><li>ESP8266 #2 as GGreg20_V3 emulator (MCU_B, ESP12.OLED module);<\/li><li>Jumper wires;<\/li><li>USB cable for programming and power.<\/li><\/ul>\n\n<p>Next, we&#8217;ll need to program the main controller MCU_A and emulation software script code GGreg20_V3 for MCU_B.<\/p>\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Note 3<\/strong>. We will give examples in this publication with our own <a href=\"https:\/\/iot-devices.com.ua\/en\/product\/esp12oled-universal-esp8266-mcuboard-oled-en\/\">ESP12.OLED<\/a> modules. However, if you do not have an ESP12.OLED module, you can also use an ESP8266-based development board such as the NodeMCU and develop the software yourself, following the examples in the text. If you wish to use an off-the-shelf device please read the rest of this article because we have provided a link to our ready-to-use emulator module which you can buy further on.<\/p><\/blockquote>\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Note 4.<\/strong> In this, as in other publications, we will give examples using the simple and powerful Lua scripting language available in the popular NodeMCU firmware.<\/p><\/blockquote>\n\n<h2 class=\"wp-block-heading\" id=\"block-fa9009c2-5b8c-41b0-bb8a-10108721c789\">The budget of the inputs\/outputs we need<\/h2>\n\n<p id=\"block-72e01d54-951b-4117-8327-b53872654d3a\">On the main layout controller, we must define the input\/output ports that will perform the task of recording input pulses from the Geiger counter emulator module.<\/p>\n\n<p id=\"block-dc43f265-c4cd-4a94-8940-0af029bf502d\">On the Geiger counter emulator module we need a bit more ports. Here we need I\/O ports: for emulation of output pulses, for RGB LED and for the switch button of the emulator operation mode.<\/p>\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><br\/><\/td><td>MCU_A role (Main Contr.)<\/td><td>MCU_B role (GC emulator)<\/td><\/tr><tr><td>1 \u0445 GPIO of input pulse counter<\/td><td>NodeMCU<\/td><td>&#8211;<\/td><\/tr><tr><td>1 \u0445 GGreg20_V3 output emulation GPIO<\/td><td>&#8211;<\/td><td>ESP12.OLED<\/td><\/tr><tr><td>3 \u0445 RGB LED GPIO for GGreg20_V3 output pulses indication<\/td><td>&#8211;<\/td><td>ESP12.OLED<\/td><\/tr><tr><td>1\u0445 GPIO of the emulator mode switch button<\/td><td>&#8211;<\/td><td>ESP12.OLED<\/td><\/tr><\/tbody><\/table><\/figure>\n\n<p>Wiring diagram<\/p>\n\n<p id=\"block-c6b2cc85-b3fb-4407-a53a-677106212716\">To make the interaction between the main controller and the GGreg20_V3 module emulator look realistic, we suggest taking advantage of the built-in properties of some I\/O ports of the ESP12.OLED board and select the following GPIOs on the MCU_B emulator controller:<\/p>\n\n<ul class=\"wp-block-list\" id=\"block-f010198d-685b-4fee-b4d6-3e1d8f38aeb3\"><li>we recommend using GPIO4\/D2 (GPIO D-index in Lua) to emulate the pulse output of GGreg20_V3;<\/li><li>we can use the Flash button (GPIO0\/D3) built into the ESP12.OLED board to switch the emulator operation modes;<\/li><li>the built-in RGB LED on the ESP12.OLED module takes GPIO14\/D5; GPIO12\/D6; GPIO13\/D7;<\/li><\/ul>\n\n<p id=\"block-2527070a-42a1-48e0-983b-6cfc16e216fc\">On the main module of the MCU_A controller we propose to select the following port for the input pulse counter:<\/p>\n\n<ul class=\"wp-block-list\" id=\"block-c8feffc1-6e34-42d2-b70e-3b3631fb85fb\"><li>GPIO14 \/ D5.<\/li><\/ul>\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Note 5<\/strong>. We recommend the following materials as background information on port numbering: <\/p><p>The standard for planning and applying pins was developed by alterstrategy.lab: <a href=\"https:\/\/alterstrategy.com\/recommended-pin-use-standard\/\" target=\"_blank\" rel=\"noopener\">https:\/\/alterstrategy.com\/recommended-pin-use-standard\/<\/a> <\/p><p>NodeMCU firmware documentation: <a href=\"https:\/\/nodemcu.readthedocs.io\/en\/latest\/modules\/gpio\/\" target=\"_blank\" rel=\"noopener\">https:\/\/nodemcu.readthedocs.io\/en\/latest\/modules\/gpio\/<\/a> <\/p><p>Documentation for the ESP12.OLED module is on the website: <a href=\"https:\/\/iot-devices.com.ua\/en\/product\/esp12oled-universal-esp8266-mcuboard-oled-en\/\">https:\/\/iot-devices.com.ua\/en\/product\/esp12oled-universal-esp8266-mcuboard-oled-en\/<\/a> <\/p><p>and on Tindie: <a href=\"https:\/\/www.tindie.com\/products\/iotdev\/esp12oled-universal-esp8266096oled-mcu-board\/\" target=\"_blank\" rel=\"noopener\">https:\/\/www.tindie.com\/products\/iotdev\/esp12oled-universal-esp8266096oled-mcu-board\/<\/a><\/p><\/blockquote>\n\n<p id=\"block-0017d8d7-e663-4e4b-8d4e-d20072cdf305\">Let&#8217;s update the table with the specific I\/O ports we selected:<\/p>\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><br\/><\/td><td>MCU_A role<\/td><td>MCU_B role<\/td><\/tr><tr><td>1 \u0445 GPIO of input pulse counter<\/td><td>NodeMCU GPIO14\/ D5<\/td><td>&#8211;<\/td><\/tr><tr><td>1 \u0445 GGreg20_V3 output emulation GPIO<\/td><td>&#8211;<\/td><td>ESP12.OLED GPIO4 \/ D2<\/td><\/tr><tr><td>3 \u0445 RGB LED GPIO for GGreg20_V3 output pulses indication<\/td><td>&#8211;<\/td><td>ESP12.OLED GPIO14 \/ D5 GPIO12 \/ D6 GPIO13 \/ D7<\/td><\/tr><tr><td>1\u0445 GPIO of the emulator mode switch button<\/td><td>&#8211;<\/td><td>ESP12.OLED GPIO0 \/ D3<\/td><\/tr><\/tbody><\/table><\/figure>\n\n<p>\ufeff<\/p>\n\n<figure class=\"wp-block-image size-full\" id=\"block-3e816c74-b488-4f9c-af8a-46e7b768c80c\"><a href=\"https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram.jpg\"><img fetchpriority=\"high\" decoding=\"async\" width=\"960\" height=\"540\" src=\"https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram.jpg\" alt=\"\" class=\"wp-image-2587\" srcset=\"https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram.jpg 960w, https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram-300x169.jpg 300w, https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram-768x432.jpg 768w, https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram-800x450.jpg 800w, https:\/\/iot-devices.com.ua\/wp-content\/uploads\/2023\/01\/10-the-esp12.oled-geiger-counter-emulator-and-nodemcu-wiring-diagram-454x255.jpg 454w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><\/a><figcaption>Fig. Connection of modules using two ESP8266 hardware controllers. As MCU_B &#8211; ESP12.OLED module. As MCU_A &#8211; NodeMCU module.<\/figcaption><\/figure>\n\n<h2 class=\"wp-block-heading\" id=\"block-cb422977-8184-4a88-9c04-66d8e4c95e9d\"><br\/>Emulator operating modes<\/h2>\n\n<p id=\"block-4228e826-79a4-4376-aad4-045e96815dc7\">In order for our GGreg20_V3 emulator to be able to simulate operation under conditions of different radiation levels, we propose to implement the possibility to switch the radiation power range, which is as if measured by the device and fed to the pulse output.<\/p>\n\n<p id=\"block-4e0350bb-494c-480f-b831-a6e3d0c4b3ce\">By pressing the Flash button (D3), the user can alternately switch modes to select the desired one.<\/p>\n\n<p id=\"block-8566cf3a-6d34-494a-a1c4-9783454ba6ad\">To make the emulator easy to use, the ESP12.OLED&#8217;s RGB LED flashes in different colors that can be easily distinguished by the human eye. Each emulator operating mode has its own color assigned to it. Therefore, when the emulator gives the pulse output a signal about a simulated detection the LED will also blink in the color of the current mode of operation.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"block-63c378b0-b723-4c14-a913-697192337a31\">Radiation level ranges<\/h2>\n\n<p id=\"block-d791023e-f3f0-4cb0-a8d6-56b4f2d848c6\">We propose to implement the emulation of the following ranges of ambient radiation, which MCU_B will simulate:<\/p>\n\n<p id=\"block-b19d8848-2821-488d-9731-af30f8d6a932\">Mode 0. No pulses (sensor error simulation);<\/p>\n\n<p id=\"block-b78e9cf4-f0ce-4bb5-a037-2e465dbc7279\">Mode 1. Natural background radiation: 0.1 &#8211; 0.2 \u00b5Sv\/h;<\/p>\n\n<p id=\"block-fcdb4d5e-1a51-47d4-b7eb-656d53f9f600\">Mode 2. Acceptable level: 0.2 &#8211; 0.3 \u00b5Sv\/h;<\/p>\n\n<p id=\"block-2b79a053-b8bb-4548-ad17-d8f31bb58219\">Mode 3. Increased level: 0.3 &#8211; 0.6 \u00b5Sv\/hour;<\/p>\n\n<p id=\"block-555eda96-59ee-425b-b6bb-29b4d1775ecf\">Mode 4. Dangerous level: 0.6 \u00b5Sv\/hour &#8211; 1.5 \u00b5Sv\/hour.<\/p>\n\n<p id=\"block-636beefb-1875-4800-b434-371a282b0432\">By default, the module will start after applying power, from &#8220;Mode 1&#8221;. We chose this mode as the initial one only because it is convenient when, after applying power, we immediately receive pulses at the level of background radiation.<\/p>\n\n<p id=\"block-e688333a-52ff-469c-b8f4-9f9559f976a6\">The real GGreg20_V3 module is equipped with a Soviet-made SBM-20 Geiger tube. This tube has the following conversion factor of pulses per minute to microsieverts per hour:<\/p>\n\n<p class=\"has-text-align-center\" id=\"block-57d145ae-f971-436c-9dc2-ea5b1f3946aa\">\u03bcSv per hour = CPM * 0.0057<\/p>\n\n<p id=\"block-5f2d88d1-fa2a-4c1c-b998-6c2d35b5188d\">Let\u2019s perform the reverse operation to calculate for the radiation ranges the appropriate number of pulses per hour that the emulator would have to generate while operating in a certain mode:<\/p>\n\n<p class=\"has-text-align-center\" id=\"block-1a1a2729-0148-4991-a7c5-b8d7190e5969\">CPM = \u03bcSv per hour\/ 0.0057<\/p>\n\n<p id=\"block-939c0593-7e19-41fe-940b-0d34f5a5af24\">We make a rough calculation so as to form power ranges which do not overlap in value:<\/p>\n\n<p id=\"block-a0935c72-ddee-4500-92dd-caa443833e00\">Mode 0. 0 CPM;<\/p>\n\n<p id=\"block-bfbf37c0-e77a-40bb-a524-aecffb2f5ffc\">Mode 1. 18 CPM to 35 CPM;<\/p>\n\n<p id=\"block-9b5a7549-1217-4a21-862e-6123d5f1fcc0\">Mode 2. 36 CPM to 52 CPM;<\/p>\n\n<p id=\"block-a28b6f7b-2535-426d-97c5-289e31330abe\">Mode 3. 53 CPM to 105 CPM;<\/p>\n\n<p id=\"block-4d52fbd2-bff2-4f66-b1a7-44a17677efb3\">Mode 4. \u0432\u0456\u0434 106 CPM \u0434\u043e 264 CPM.<\/p>\n\n<p id=\"block-0761ad79-1104-4eb4-8586-2b413119bad9\">The correlation of the color of the RGB LED flashes to a certain mode of operation is as follows:<\/p>\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Operation mode<\/strong><\/td><td><strong>Flash color<\/strong><\/td><td><strong>R<\/strong><\/td><td><strong>G<\/strong><\/td><td><strong>B<\/strong><\/td><\/tr><tr><td>Mode 0<\/td><td>no flashes black<\/td><td>0<\/td><td>0<\/td><td>0<\/td><\/tr><tr><td>Mode 1<\/td><td>cyan<\/td><td>0<\/td><td>1<\/td><td>1<\/td><\/tr><tr><td>Mode 2<\/td><td>green<\/td><td>0<\/td><td>1<\/td><td>0<\/td><\/tr><tr><td>Mode 3<\/td><td>red<\/td><td>1<\/td><td>0<\/td><td>0<\/td><\/tr><tr><td>Mode 4<\/td><td>magenta<\/td><td>1<\/td><td>0<\/td><td>1<\/td><\/tr><\/tbody><\/table><\/figure>\n\n<p>Now we have to write the appropriate Lua-code for the MCU_A role and for the MCU_B role.<\/p>\n\n<h2 class=\"wp-block-heading\" id=\"block-f6fa38ba-c4f6-4484-9e32-cb4c380574d4\"><strong>Example<\/strong>. Geiger counter code for the main controller (MCU_A role)<\/h2>\n\n<p id=\"block-923bc983-837f-4384-9148-96385e6b3e3b\">We take this code from GitHub here:<\/p>\n\n<p><a href=\"https:\/\/github.com\/iotdevicesdev\/ggreg20-v3-nodemcu-lua-example\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/iotdevicesdev\/ggreg20-v3-nodemcu-lua-example<\/a><\/p>\n\n<p id=\"block-0979654a-2651-4027-abcd-2ff33ce599d4\">The code from GitHub is completely ready to use. To run the code, you need to download it from the Internet and upload it to the controller, for example to the NodeMCU module, as in our case. You also need to write another Lua-script and load it into the controller as well:<\/p>\n\n<pre class=\"wp-block-code\"><code>-- filename: mcu_a.lua\n-- MCU_A Lua code example\n-- Copyright 2022 IoT-devices LLC, Kyiv, Ukraine\ndofile('ggreg20_v3_nodemcu_firmware_lua_example.lua')\ninit(5, 1, 60000)\n\nfunction snsrUpd()\nma5_rad_lvl, cpm, minutes = read()\nprint(ma5_rad_lvl, cpm, minutes)\nend\n\nsnsrUpd_tmr = tmr.create()\nsnsrUpd_tmr:register(60000, tmr.ALARM_AUTO, function() snsrUpd() end)\nsnsrUpd_tmr:start()<\/code><\/pre>\n\n<h2 class=\"wp-block-heading\" id=\"block-245d7efc-1d20-42e3-b2d1-14d29e6b7cb1\"><strong>Example<\/strong>. Code for the GGreg20_V3 module emulator (MCU_B role)<\/h2>\n\n<p id=\"block-6f398d6f-0323-4900-81bf-fb082b4bb006\">The Lua documentation tells us that in high-speed tasks we need to reassign global identifiers to local identifiers, which increases execution speed by a factor of ten. Therefore, we will do it as follows:<\/p>\n\n<pre class=\"wp-block-code\"><code>local gpio = gpio\nlocal mode = gpio.mode\nlocal trig = gpio.trig\nlocal write = gpio.write\nlocal read = gpio.read\nlocal INT = gpio.INT\nlocal OUTPUT = gpio.OUTPUT\nlocal FLOAT = gpio.FLOAT\nlocal HIGH = gpio.HIGH\nlocal LOW = gpio.LOW\nlocal PULLUP = gpio.PULLUP\nlocal print = print\n\nlocal tmr = tmr\nlocal create = tmr.create\nlocal now = tmr.now\nlocal delay = tmr.delay\nlocal alarm = tmr.alarm\nlocal ALARM_SINGLE = tmr.ALARM_SINGLE\nlocal ALARM_SEMI = tmr.ALARM_SEMI\nlocal ALARM_AUTO = tmr.ALARM_AUTO\nlocal register = tmr.register\nlocal start = tmr.start\nlocal stop = tmr.stop\n\nlocal node = node\nlocal heap = node.heap\nlocal random = node.random<\/code><\/pre>\n\n<p id=\"block-02068264-0668-452a-a175-d7f2197ecf05\">We also need to configure the GPIOs that will be responsible for their functions (see above):<\/p>\n\n<pre class=\"wp-block-code\"><code>mode(3,INT,FLOAT)\nmode(4,OUTPUT, PULLUP)\nwrite(4, HIGH)<\/code><\/pre>\n\n<p id=\"block-67fa4fe3-dab6-44c3-b317-89d685a65809\">To generate pulses that simulate the output interface of GGreg20_V3, we need to randomly run the following function:<\/p>\n\n<pre class=\"wp-block-code\"><code>local function pulseOut()\n\twrite(4, LOW)\n\tdelay(10)\n\twrite(4, HIGH)\nend<\/code><\/pre>\n\n<p id=\"block-76bde581-ad02-443e-9b0e-1b0b5a802151\">But in order to fully emulate the Geiger counter, it is not enough to just run <code>pulseOut()<\/code> a certain number of times per minute. In fact it is more complicated and we need to run<code>pulseOut()<\/code>, in such a way that the real randomness of the appearance of pulses on the ESP8266 output is performed.<\/p>\n\n<p id=\"block-45dc16f8-88b4-48cc-b315-92da5ffdc8af\">Given the extensive capabilities of the platform, we could even suggest several ways to implement this functionality, but we will limit ourselves to one of them, the one that, in our opinion, reproduces the pulse randomness of the real Geiger counter module as much as possible.<\/p>\n\n<p id=\"block-0b0c2c3e-e7e7-4aaf-a30c-395557aa8674\">To do that we need to use a random number generator, which, according to the NodeMCU firmware documentation, is capable of generating real random numbers. The firmware has a ready-made method node.random() for this purpose. <code>node.random().<\/code><\/p>\n\n<p id=\"block-c0c54a29-d8c5-4824-896e-cc3ce2eae785\">To distribute a chosen number of pulses chaotically for one minute, we will use timers, which can be created in a theoretically unlimited number:<\/p>\n\n<pre class=\"wp-block-code\"><code>create():alarm(timer timeout, timer type, callback function)<\/code><\/pre>\n\n<p id=\"block-a4766066-59e9-40ea-9b6e-8cfbb48c83e8\">The only limitation is the amount of free RAM of the controller. Experimentally, we found that we can easily create about 260 pulses per minute in this way, which fits into our requirements for the maximum level of virtual radiation that our emulator can reproduce.<\/p>\n\n<p id=\"block-cc004032-5661-4186-9c8c-e28b279f3726\">Thus, the function that creates random<code>pulseOut(),<\/code> start timeouts in the loop looks like this<\/p>\n\n<pre class=\"wp-block-code\"><code>local t_start = 0\nlocal count = 0\nlocal function randGen(pulses)\n\tfor i = 1, pulses do -- pulses\n\t\t\tcreate():alarm(random(60000), ALARM_SINGLE, \n\t\t\t\tfunction()\n\t\t\t\t\t\tprint(heap(), count, i, (now() - t_start)\/1000000)\n\t\t\t\t\t\tpulseOut()\n\t\t\t\tend\n\t\t\t)\n\tend\nend<\/code><\/pre>\n\n<p id=\"block-2b32df03-eab1-4d84-b60f-00e71a4c3ead\">Working together, our developed functions <code>randGen(<em>pulses<\/em>)<\/code> and <code>pulseOut()<\/code> create on the ESP8266 output the necessary number of absolutely random pulses of 10 microseconds each per one minute.<\/p>\n\n<p id=\"block-70e9c748-19dd-4028-bbb7-5fe1f0280797\">We set the number of pulses per minute with the parameter <em><code>pulses<\/code><\/em>.<\/p>\n\n<p id=\"block-4a90ceb2-c169-4711-9d49-5b43bb34435e\">In order for the emulator to work in different power modes of simulated radiation it is necessary to provide a random value of the number of impulses <code><em>pulses<\/em>,<\/code> falling as a task at the input of the randGen() function <code>randGen().<\/code> . This can be done as follows:<\/p>\n\n<pre class=\"wp-block-code\"><code>radMode = 1\nrand_tmr = create()\nrand_tmr:register(1000, ALARM_AUTO, \n\tfunction()\n\t\tif radMode == 0 and running == 0 then \n\t\t\tprint(heap(), 'Mode0:Snsr Err emu')\n\t\t\treturn 0\n\t\tend\n\t\tlocal num = 0\n\t\tif radMode == 1 then \n\t\t\tnum = random(math.ceil(18),math.ceil(35))\n\t\telseif radMode == 2 then\n\t\t\tnum = random(math.ceil(36),math.ceil(52))\n\t\telseif radMode == 3 then\n\t\t\tnum = random(math.ceil(53),math.ceil(105))\n\t\telseif radMode == 4 then\n\t\t\tnum = random(math.ceil(106),math.ceil(264))\n\t\tend\n\t\tif num ~= 0 then print('count:',count + 1,'mode:',radMode, 'num:',num); randGen(num) end\n\tend\n)\n\nrand_tmr:start()<\/code><\/pre>\n\n<p id=\"block-e5b05b89-d43b-4a2d-8e18-2bffffe503be\">By setting the value of the global variable <em><code>radMode<\/code><\/em>, the user can specify one of five modes of ionizing radiation power reproduced at the emulator output.<\/p>\n\n<p id=\"block-601d0a86-27e4-4066-a9a4-61d3770b1b94\">The last thing we need to provide in the emulator is to switch the radiation power mode using the built-in Flash\/GPIO0\/D3 button:<\/p>\n\n<pre class=\"wp-block-code\"><code>trig(3, 'down', \n\tfunction(lvl, ts, cnt)\n\t\tif radMode &lt; 4 then radMode = radMode + 1 else radMode = 0 end\n\t\tprint ('New radMode:', radMode)\n\tend\n)<\/code><\/pre>\n\n<h3 class=\"wp-block-heading\" id=\"block-1b688a62-cea2-48b8-811d-2e5cde4c87b1\">Full emulator software code<\/h3>\n\n<p id=\"block-be1e5721-a28c-4eb4-9552-eb301bf23577\">We don&#8217;t have a ready-made example for this controller role, as was the case with the main controller (MCU_A). So we will write the necessary code from scratch. Here is the minimum required code capable of emulating Geiger counter pulses.<\/p>\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Note 6.<\/strong> The code in this section is an example. You can download and set up this example yourself in your own Geiger counter emulator, or purchase a ready-to-use hardware module with firmware and fully functional software from our shop or Tindie at the following links:<\/p><p>IoT-devices.com.ua: <a href=\"https:\/\/iot-devices.com.ua\/en\/product\/gcemu20_v1-geiger-counter-emulator\/\">GCcemu20_V1<\/a><\/p><p>Tindie: <a href=\"https:\/\/www.tindie.com\/products\/iotdev\/gcemu20_v1-geiger-counter-emulator\/\" target=\"_blank\" rel=\"noopener\">GCcemu20_V1<\/a><\/p><\/blockquote>\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\"><p><strong>Warning!<\/strong> This example code has its own limitations and differs significantly from the code we have developed for commercial use and sell as part of the emulator product on our website and other commercial sites.<\/p><\/blockquote>\n\n<pre class=\"wp-block-code\"><code>-- filename: mcu_b.lua\n-- MCU_B Lua code example\n-- Copyright 2022 IoT-devices LLC, Kyiv, Ukraine\nlocal t_start = 0\nlocal count = 0\nradMode = 0\n\nlocal gpio = gpio\nlocal mode = gpio.mode\nlocal trig = gpio.trig\nlocal write = gpio.write\nlocal read = gpio.read\nlocal INT = gpio.INT\nlocal OUTPUT = gpio.OUTPUT\nlocal FLOAT = gpio.FLOAT\nlocal HIGH = gpio.HIGH\nlocal LOW = gpio.LOW\nlocal PULLUP = gpio.PULLUP\nlocal print = print\n\nlocal tmr = tmr\nlocal create = tmr.create\nlocal now = tmr.now\nlocal delay = tmr.delay\nlocal alarm = tmr.alarm\nlocal ALARM_SINGLE = tmr.ALARM_SINGLE\nlocal ALARM_SEMI = tmr.ALARM_SEMI\nlocal ALARM_AUTO = tmr.ALARM_AUTO\nlocal register = tmr.register\nlocal start = tmr.start\nlocal stop = tmr.stop\n\nlocal node = node\nlocal heap = node.heap\nlocal random = node.random\n\nmode(3,INT,FLOAT)\nmode(4,OUTPUT, PULLUP)\nwrite(4, HIGH)\n\nlocal function pulseOut()\n\twrite(4, LOW)\n\tdelay(10)\n\twrite(4, HIGH)\nend\n\nlocal function randGen(pulses)\n\tfor i = 1, pulses do -- pulses\n\t\t\tcreate():alarm(random(60000), ALARM_SINGLE, \n\t\t\t\tfunction()\n\t\t\t\t\t\tprint(heap(), count, i, (now() - t_start)\/1000000)\n\t\t\t\t\t\tpulseOut()\n\t\t\t\tend\n\t\t\t)\n\tend\nend\n\nrand_tmr = create()\nrand_tmr:register(1000, ALARM_AUTO, \n\tfunction()\n\t\tif radMode == 0 and running == 0 then \n\t\t\tprint(heap(), 'Mode0:Snsr Err emu')\n\t\t\treturn 0\n\t\tend\n\t\tlocal num = 0\n\t\tif radMode == 1 then \n\t\t\tnum = random(math.ceil(18),math.ceil(35))\n\t\telseif radMode == 2 then\n\t\t\tnum = random(math.ceil(36),math.ceil(52))\n\t\telseif radMode == 3 then\n\t\t\tnum = random(math.ceil(53),math.ceil(105))\n\t\telseif radMode == 4 then\n\t\t\tnum = random(math.ceil(106),math.ceil(264))\n\t\tend\n\t\tif num ~= 0 then print('count:',count + 1,'mode:',radMode, 'num:',num); randGen(num) end\n\tend\n)\n\nrand_tmr:start()\n\ntrig(3, 'down', \n\tfunction(lvl, ts, cnt)\n\t\tif radMode &lt; 4 then radMode = radMode + 1 else radMode = 0 end\n\t\tprint ('New radMode:', radMode)\n\tend\n)<\/code><\/pre>\n\n<p>\u041f\u043e\u0447\u0430\u0442\u043e\u043a \u0441\u0442\u0430\u0442\u0442\u0456: <a href=\"https:\/\/iot-devices.com.ua\/en\/geiger-counter-emulator-ggreg20_v3-module-by-means-of-esp8266-part1\/\">Geiger counter emulator of GGreg20_V3 module by means of ESP8266: Part 1. Introduction and Overview <\/a><\/p>\n\n<p>The conclusion of the article will be in the next publication in a few days:<br\/>Geiger counter emulator of GGreg20_V3 module by means of ESP8266: Part 3. Testing and Conclusion<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Geiger counter emulator: what we need To build the Geiger counter module emulator, we&#8217;ll need the following parts and materials: ESP8266 #1 as the main one (MCU_A, NodeMCU module); ESP8266 #2 as GGreg20_V3 emulator (MCU_B, ESP12.OLED module); Jumper wires; USB cable for programming and power. Next, we&#8217;ll need to program the main controller MCU_A and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2587,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"0","ocean_second_sidebar":"0","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"0","ocean_custom_header_template":"0","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"0","ocean_menu_typo_font_family":"0","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"0","omw_enable_modal_window":"enable","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"off","ocean_gallery_id":[],"footnotes":""},"categories":[89,90,88],"tags":[145,306,262,94,220,142,226,96,97,276,101,104,211,141,305],"class_list":["post-2822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","category-testing","category-tips-en","tag-diy-en","tag-emulator-en","tag-esp12-oled-en","tag-esp8266-en","tag-expressive","tag-geiger-en","tag-geiger-counter-en","tag-ggreg20_v3-en","tag-gpio-en","tag-iot-en","tag-lua-en","tag-nodemcu-en","tag-sbm20-en","tag-tindie-en","tag-unit-test-en","entry","has-media","owp-thumbs-layout-horizontal","owp-btn-normal","owp-tabs-layout-horizontal","has-no-thumbnails","has-product-nav"],"_links":{"self":[{"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/posts\/2822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/comments?post=2822"}],"version-history":[{"count":2,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/posts\/2822\/revisions"}],"predecessor-version":[{"id":2840,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/posts\/2822\/revisions\/2840"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/media\/2587"}],"wp:attachment":[{"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/media?parent=2822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/categories?post=2822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iot-devices.com.ua\/en\/wp-json\/wp\/v2\/tags?post=2822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}