Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:55 02 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : PicoMite Geiger Counter Interrupt Problem - Loop too short?!

     Page 2 of 4    
Author Message
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 01:06pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Pluto said  This is my Geiger-code:
[...]

Thank you for you code! I will try this in my later testings :)

  Pluto said  
Yellow dots and blue grid came just by "accident", but I recognize now that these are also the Ukrainian colors!


I am really speechless what happened in the Ukraine... words can not explain this, but since this is not a political forum...you know...  But a nice coincidence :)

Greetings
Daniel
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 01:34pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Volhout said  Hi Amnesie,

1/ Can you use a variable named "min" used for minutes ? MIN is a basic keyword.
2/ when you declare the variable "redraw" as an integer, you do not need the trailing % (as in "redraw%"). Only when you no declare the variable you must use the % when it is supposed to be an integer.
3/ You use 2 interrupt routines, one for counting pulses, one for redrawing (1x per minute). Maybe this is causing problems.

What is the behaviour you see ???
occasionally missing a pulse ? skipping halve the pulses ? only few pulses are measured ? Or does it see all pulses and the variable "count" is corrupted ?



1/ I deleted all the unimportant parts including this

2/ I suppose this could be the problem, hm..

3/ count variable is not corrupted, this is for shure, I tested it, the "Interrupt Service Routine" does not recognize the interrupt pulse, as said with the PAUSE in the loop it catches all of the interrupts...

I stripped down my code further, with no success so far:


Option Base 0
Option Default None
Option Explicit

SetPin gp0, intl, isr
SetTick 60000, setRedrawFlag

'Declare Drawing variables ++++++++++++++++

Dim integer yRow, xCol, xDash, yDash, xScale, mScaleVal, yScale
Dim integer xProgGraph=50, cGraph, cGraph_old, yGraphAdj=5
Dim float uScaleIndex, uScaleVal=0.096
Dim integer redraw

'Declare Counting variables +++++++++++++++
Dim integer count

CLS

drawAxisGrid()

Sub drawAxisGrid

xProgGraph=50          'Reset Graph x-axis progress pixel to 50

CLS

'Draw dotted Grit -------------------------

For yRow=100 To 300 Step 20 'Draw Rows (300-100=200 -> 200/20 = 10 rows)
 For xCol=50 To 626 Step 24 'Draw Columns (626-50=576 -> 576/24 = 24 columns)
   Line xCol,yRow,xCol,yRow,,RGB(green)
 Next xCol
Next yRow

'Draw solid Axis -------------------------

Line 50,300,626,300,,RGB(green) 'Draw X-axis
Line 50,100,50,300,,RGB(green)  'Draw Y-axis

'Draw dashed lines -----------------------

For xDash=50 To 626 Step 24     'Draw dashed X
 Line xDash,297,xDash,305,,RGB(red)
Next xDash

For yDash=100 To 300 Step 20     'Draw dashed Y
 Line 45,yDash,53,yDash,,RGB(red)
Next yDash

'Labels -------------------------------------------
Text 1,70,"uSv/h ",,1,1  'uSv/h
Text 626,305,"t ",,1,1   'Time

For xScale=40 To 626 Step 120
 Text xScale,310,Str$(mScaleVal),,1,1 'Minutes Scale
 mScaleVal=mScaleVal+30
Next xScale
mScaleVal=0 'Reset value for the next trigger

For yScale=295 To 95 Step -20
 Text 1,yScale,Str$(uScaleIndex),,1,1 'uSv/h Scale
 uScaleIndex=uScaleIndex+uScaleVal
Next yScale
uScaleIndex=0 'Reset value for the next trigger

End Sub


'MAIN LOOP #################################################

Do
 If xProgGraph=626 Then  'If End of Scale redraw
   drawAxisGrid()
 EndIf

 If redraw Then         'every minute progress drawing the Graph
   drawGraph()
   redraw = 0
 EndIf

 Text 470,30,Str$(count),,1,1
 Text 160,30,Str$(count * 0.0241),,1,1

Pause 100 'EXTREMLY IMPORTANT WITHOUT, THE LOOP IS SOMEHOW TO FAST TO REACT?!
Loop

'###########################################################


'Draw Graph -----------------------------------

Sub drawGraph
 xProgGraph = xProgGraph + 4

 cGraph = count * yGraphAdj  'Graph enlargement
 Line xProgGraph-4,300-cGraph_old,xProgGraph,300-cGraph,,RGB(green)
 cGraph_old = cGraph

 count = 0
End Sub



Sub isr 'Interrupt Service Routine triggered by Geiger Counter
count = count + 1
End Sub


Sub setRedrawFlag
redraw = 1
End Sub

 
Plasmamac

Guru

Joined: 31/01/2019
Location: Germany
Posts: 579
Posted: 02:02pm 24 Mar 2022
Copy link to clipboard 
Print this post

if you have a second device (pico is cheap) fire some events with different timings.
even if you have an logikanalyzer or an osziloskop checkt the geiger counter output.

i will check this in the night later
Edited 2022-03-25 00:03 by Plasmamac
Plasma
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5091
Posted: 02:34pm 24 Mar 2022
Copy link to clipboard 
Print this post

Hi Amnesie,

It has taken some time for me to digest this, but I think I know what is happening.

The interrupt is called an "interrupt", but in fact it is "polled".
MMBasic executes basic commands, and whenever it is ready executing a basic command. It polls the IO pin that is connected to the interrupt.

Becuase of this polling method, MMBasic can only detect hardware interrupt signals that  have a duration that is longer than the slowest MMBasic command.

Your main loop has two TEXT commands that draw text on the screen. These commands are (from what I estimate) the slowest commands in the main loop, and have a long duration. Becuase they take long, they also consume much of the loop time. And durint the TEXT command the picomite is "blind" to very short interrupts.(*)

The solution must be either:
- stretch the GEIGER pulses in hardware so each pulse takes longer than the TEXT command.
- remove the TEXT commands from the main loop, and only update TEXT when an actual change has happened. (use a flag, similar to how redraw was implemented).
- an alternative (but I cannot be sure without testing) could be to use the COUNT (setpin xxx.CIN) function in the pico. Maybe tihs count function can capture faster pulses than the interrupt. And you only have to read the count register each minute.

Volhout

(*) when the normal commands are 30us, and the TEXT command is 300us then the loop takes 9x30us + 2x 300us = 870us. But it is blind for 2x300us=600us = 70%. Assume the PAUSE command does not block interrupts, then the loop is 870us+100ms=101ms. And it s blind for 600us=0.06%. That is why you need the PAUSE.
Edited 2022-03-25 00:41 by Volhout
PicomiteVGA PETSCII ROBOTS
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 02:40pm 24 Mar 2022
Copy link to clipboard 
Print this post

@ Volhout

Just saw your recent answer and it is in short what I thought, but you explained
it really really good with interesting solution ideas I will work on / or try at least. Do you think that Peter could "fix" this problem or is it inherent to the way BASIC is working on the pico?

But here my original text before I noticed your answer:



I made some progress, at least somehow:


If I bridge with my fingers the high voltage between anode and cathode of the geiger tube, the pulse and interrupt is counted every time, even without "PAUSE" in the loop. So I set up an Arduino and fired a bunch of pulses through the interrupt of the pico and it worked.

Assumption:

1. interrupt output of the geiger counter does not trigger every time, especially without a pause in the loop, therefore I used an Arduino Uno to check it: works perfect in every scenario.

Must have something to do with the way BASIC or the MMBSAC is acting.

My temporarly solution is to grab the signal NOT directly after the tube, with the pulsewidth of ~240uS @ 3V3 , but after the NE555 (wired as "pulse stretcher, to drive the led and speaker") which stretches the pulse to ~ 10ms ... This works with the pico... But is FAR from optimal, because higher count rates are impossible...

If I find absolutley no soloution I will do a ugly workaround:

Let the Arduino do the counting and sending it via I2C bus to the picoMite for a nice graphical screen....
Edited 2022-03-25 00:48 by Amnesie
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 5091
Posted: 02:46pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Amnesie said  

My temporarly solution is to grab the signal no directly after the tube, with the pulsewidth of ~240uS @ 3V3 , but after the NE555 (wired as "pulse stretcher, to drive the led and speaker") which stretches the pulse to ~ 10ms ... This works with the pico... But is FAR from optimal, because higher count rates are impossible...


See my previous post... Alternatives ...  
An alternative could be to use the frequency counter function. This offloads the whole real time shebang from your code. Frequency measurement goes into the megaHz, so short pulses will be captured.


SETPIN xxx,FIN,60000 (count frequency with a gate time of 60000ms = 60 sec)
PRINT PIN(xx)


But...

The NE555 with 10ms is not too bad.
With 10ms you can register at least 50 counts per SECOND, that is 3000 per minute.

And there is no objection to change the NE555 to 1ms or 2ms. It will also drive the speaker. And you will be able to count 30000 counts per minute.
Edited 2022-03-25 00:52 by Volhout
PicomiteVGA PETSCII ROBOTS
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7937
Posted: 02:51pm 24 Mar 2022
Copy link to clipboard 
Print this post

In MMBasic "interrupts" are in firmware. They are checked at the end of each instruction line.

The Count inputs use on-chip hardware devices, as far as I know. You have to specify the pin(s) used in OPTION COUNT then use SETPIN pin,CIN [,option] to set the counting mode.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 02:52pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Volhout said  
  Amnesie said  

My temporarly solution is to grab the signal no directly after the tube, with the pulsewidth of ~240uS @ 3V3 , but after the NE555 (wired as "pulse stretcher, to drive the led and speaker") which stretches the pulse to ~ 10ms ... This works with the pico... But is FAR from optimal, because higher count rates are impossible...


See my previous post... Alternatives ...  But...

The NE555 with 10ms is not too bad.
With 10ms you can register at least 50 counts per SECOND, that is 3000 per minute.

And there is no objection to change the NE555 to 1ms or 2ms. It will also drive the speaker. And you will be able to count 30000 counts per minute.


If you put it this way, It should be ok, since I didn't want me to exposure to such high doses of radiation. The good thing is, that the NE555 is already on the geiger, just have to grab the pulse on the LED this works fine.

But your explanation is really good!
 
thwill

Guru

Joined: 16/09/2019
Location: United Kingdom
Posts: 4311
Posted: 03:09pm 24 Mar 2022
Copy link to clipboard 
Print this post

It would be good to get @matherp's confirmation, but I've taken a brief but ignorant look at the firmware and it doesn't look there is any sort of "latch" that would capture and hold the fact that a pin transition had occurred, so as @Volhout deduced it looks like it is theoretically possible for very short pulses to be missed if running slow MMBasic commands.

Best wishes,

Tom
MMBasic for Linux, Game*Mite, CMM2 Welcome Tape, Creaky old text adventures
 
twofingers

Guru

Joined: 02/06/2014
Location: Germany
Posts: 1593
Posted: 03:15pm 24 Mar 2022
Copy link to clipboard 
Print this post

You've probably found a solution. Alternatively, consider a CSUB that counts the pulses and fills an array that can then be displayed.

Best regards
Michael

BTW. I just remembered I was supposed to have old incandescent gas mantle (Thorium dioxide) in the shed for testing a Geiger counter ...
causality ≠ correlation ≠ coincidence
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 03:18pm 24 Mar 2022
Copy link to clipboard 
Print this post

Hmm I tried your alternative:

  Volhout said  
SETPIN xxx,FIN,60000 (count frequency with a gate time of 60000ms = 60 sec)
PRINT PIN(xx)



But I realized that it is not possible to show the pulses / counts in realtime, because the measurement takes 60000ms to update... This is sadly a "no go". I need the real time counts.

If Peter (?) has no solution for this I stick to the hardware solution of the NE555 or as last resort but somehow sad: use an Arduino and send the counts via I2C ...
Edited 2022-03-25 01:27 by Amnesie
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 03:28pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Quote  If Peter (?) has no solution for this


setpin n,cin ' proper H/W interrupt

then poll pin(n) in the main loop for changes
Edited 2022-03-25 01:30 by matherp
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 04:03pm 24 Mar 2022
Copy link to clipboard 
Print this post

  matherp said  
  Quote  If Peter (?) has no solution for this


setpin n,cin ' proper H/W interrupt

then poll pin(n) in the main loop for changes


   

Problem solved, case closed, happy again. Everything works just perfect.

Last question:

Is it possible to reset the value of pin(n) (counting input) to zero again and does it at some point overflow?


Greetings
Daniel
Edited 2022-03-25 02:05 by Amnesie
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 04:12pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Quote  Is it possible to reset the value of pin(n) (counting input) to zero again


Yes PIN(n)=0

Only after 9223372036854775807 counts which would probably indicate that the radiation level was rather high
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 04:39pm 24 Mar 2022
Copy link to clipboard 
Print this post

What can I say? I'm so impressed with all the willingness to help by all the people here. BIG THANK YOU TO ALL! I can just share my part of the work, if someone looks for gerber files of my Geiger Counter:


geiger.zip

The circuit is somewhat similar to:

https://sites.google.com/site/diygeigercounter/technical/circuit-description

Greetings
Daniel
 
Plasmamac

Guru

Joined: 31/01/2019
Location: Germany
Posts: 579
Posted: 06:01pm 24 Mar 2022
Copy link to clipboard 
Print this post

try ic2d pin 1 with your first sofware  
Plasma
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 06:29pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Plasmamac said  try ic2d pin 1 with your first sofware  


I just took the high voltage generator part from this schematic, not the part with IC2.
The "pulse stretch" NE555 circuit is different.

But the problem is already solved and everything works perfect!

SetPin (n),CIN,2 was the soloution
(previously config the Pin with OPTION COUNT)
and then polling the Pin, just as Peter suggested.

Now it is time to make the saved CPM values auto adjustable, if a higher countrate occurs, the scale as well as the graph must adjust to it :) Nice way to lern BASIC!
I remember doing this in C with constrain.

Greetings
Daniel
Edited 2022-03-25 04:35 by Amnesie
 
Turbo46

Guru

Joined: 24/12/2017
Location: Australia
Posts: 1642
Posted: 09:31pm 24 Mar 2022
Copy link to clipboard 
Print this post

  Amnesie said  Problem solved, case closed,

Most of this happened while I was asleep. But when I read Volhout's explanation of what may be the problem:
  Volhout said  The interrupt is called an "interrupt", but in fact it is "polled".
MMBasic executes basic commands, and whenever it is ready executing a basic command. It polls the IO pin that is connected to the interrupt.

Becuase of this polling method, MMBasic can only detect hardware interrupt signals that  have a duration that is longer than the slowest MMBasic command.

Your main loop has two TEXT commands that draw text on the screen. These commands are (from what I estimate) the slowest commands in the main loop, and have a long duration. Becuase they take long, they also consume much of the loop time. And durint the TEXT command the picomite is "blind" to very short interrupts.

I though that it was a good explanation and it would be helpful if that sort of thing was included in the various manuals. Thanks Volhout.

It doesn't matter now because the problem is solved, but I though as I was reading the various posts that, rather than stretch the pulse with a monostable, I would suggest using a simple latch. Use the input pulse to set the latch, the output of which will cause the interrupt and the interrupt routine will reset the latch and ready it for the next one.

Just for what's it worth now.

Bill
Keep safe. Live long and prosper.
 
Amnesie
Guru

Joined: 30/06/2020
Location: Germany
Posts: 675
Posted: 10:15am 25 Mar 2022
Copy link to clipboard 
Print this post

  Turbo46 said  
I though that it was a good explanation and it would be helpful if that sort of thing was included in the various manuals. Thanks Volhout.


That was what I also thought!

But I am glad, that the solution was really simple. But as a BASIC beginner, a good UPDATED manual would be nice at some point in time. I am aware of the hard work putting this into a open source / free project, but in the long run it would make a lot of things easier. I do look in the existing manual, but there are some obsolete commands mentioned and some which are so new due to the frequently updated versions, that I have a hard start into it. This is NOT a critic, because it is impossible to update the manual in real time as new beta versions appear, but if "we" / Peter reaches the final (almost) versions of picoBasic a real good manual is more worth than a ton of more features. MMBASIC is by far the most advanced BASIC dialect (at least) I know of.

It is just impressive and makes a lot of fun discovering it!
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 7937
Posted: 10:46am 25 Mar 2022
Copy link to clipboard 
Print this post

It is NOT easy to keep the manuals updated. This is something that I've tried.  :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
     Page 2 of 4    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025