Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 15:19 19 May 2024 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 : Debounce - CIN question

Author Message
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 02:10am 19 Feb 2016
Copy link to clipboard 
Print this post

I've been trying to figure out how to do debouncing on MMBasic but my brain is stuck
I have a counter input (from an anemometer) that is going to have a maximum count of 400 times a second which means each pulse will be a maximum of 2.5mS

Is there any way I can tell it to ignore pulses shorter than say 2mS?

I'm thinking it would be something like if CIN >400 (2.5mS) then ignore? but not sure how to phrase it

Basically I need to tell it to wait a minimum period of time before it counts the next pulse

I.E. Any pulse shorted than 2.6mS it should ignore
Edited by lew247 2016-02-20
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 03:31am 19 Feb 2016
Copy link to clipboard 
Print this post

I;m guessing here but would something like the following work (if it was put in the right format)


SETPIN 15,CIN)
pin(2) = 0
gosub buttonpress
print pin(15)

sub buttonpress
if buttonpresstime <2.5mS then gosub buttonpress
else continue
endsubEdited by lew247 2016-02-20
 
circuit
Senior Member

Joined: 10/01/2016
Location: United Kingdom
Posts: 232
Posted: 05:40am 19 Feb 2016
Copy link to clipboard 
Print this post

It is simple to measure the pulse duration with PULSIN(pin,polarity, t1, t2). But that might not be what is needed. If you are talking about debouncing a mechanical switch then a small capacitor across the switch contacts might do the trick. Alternatively, upon a trigger pulse, pause for 2ms and then check the pin again to make sure that it is still switched.
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 07:05am 19 Feb 2016
Copy link to clipboard 
Print this post

Would something like this work

I know it's not right, I cant figure out how to put it exactly

SETPIN 15, FIN
SETPIN 16, Dout
Do
Pin (16) = 1
if Pin (15) = 1 then pause 2
if Pin (15) = 1 then gosub count
print (nbr)

SUB count ( nbr )
LOCAL INTEGER count
FOR count = 1 TO nbr
NEXT count
END SUB

basically set pin 16 high, anemometer connected between pins 15 and 16, and count the number of high pulses on pin 15
if pin 15 goes high wait 2ms then if its still high count the number of pulses in one second
Edited by lew247 2016-02-20
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 10:07am 19 Feb 2016
Copy link to clipboard 
Print this post

last post edited*
 
palcal

Guru

Joined: 12/10/2011
Location: Australia
Posts: 1805
Posted: 11:23am 19 Feb 2016
Copy link to clipboard 
Print this post

Are you sure the switch in the anemometer is indeed mechanical, ie a reed switch and magnet. I seem to remember the anemometer you have is quite a good one.
Paul.
"It is better to be ignorant and ask a stupid question than to be plain Stupid and not ask at all"
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 11:36am 19 Feb 2016
Copy link to clipboard 
Print this post

Yes, it's a reed switch with 3 magnets
"The rotation of the cups is sensed by a magnetically activated switch. The
switch is in a fixed position while three magnets are fastened to the rotating cup
housing."
200-ws-23 manual
 
MM_Wombat
Senior Member

Joined: 12/12/2011
Location: Australia
Posts: 139
Posted: 01:38pm 19 Feb 2016
Copy link to clipboard 
Print this post

@ lew247

Looking at the manual, wouldn't you just connect pin 16 to the ground circuit, and set pin 15 to analog (AIN) and using a suitable load resistor of between 100 and 250 ohm +/- 1 %, and measure the voltage. Each 0.2 V is 12.5 mph across the range of 0 to 2 V. So 1 mph would be 0.016 V.

So mph = Pin(15)/0.016

MM_Wombat

[edit] I couldn't see 400 pulses per second anywhere in the referred document[/edit]Edited by MM_Wombat 2016-02-20
Keep plugging away, it is fun learning
But can be expensive (if you keep blowing things up).

Maximite, ColourMaximite, MM+
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5923
Posted: 01:38pm 19 Feb 2016
Copy link to clipboard 
Print this post

Reed switches are unlikely to bounce.
If you are concerned, I would use an external resistor/capacitor to remove any bounces.
You can use counting or frequency to get the count from the device.

Jim
VK7JH
MMedit   MMBasic Help
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 12:16am 20 Feb 2016
Copy link to clipboard 
Print this post

MM_Wombat maximum speed = 125Mph, each rotation is 3 pulses on the reed switch, and 1 rotation = 1.25Mph
1 pulse = 0.4166666666666667 Mph
I rounded it up to a maximum of 400 pulses per second which would be just over 166Mph as it was easier for me to round it up as the maximum amount of pulses per second.

That's how I came up with "if I got it to ignore pulses of less than 2.5ms it would only count genuine pulses"

IF I used the control box that came with the anemometer. then I'd have to supply it with a 12v source, and "simply" measure the current on the 2 outputs on the control box
Both the anemometer and the wind direction indicator have 0-20mA outputs directly relating to 0-125MPh and 0-360° direction

IF I knew how to make the pic chip measure current reliably and write the code for it, I guess this would be the best way

but

I figured counting the pulses on the anemometer would be easier and as to the direction indicator it would be analog input and measure the voltage in 0-1023 steps

As you can tell I'm really new with the microprocessor stuff and I really know very little and I'm basically learning as I go along
Edited by lew247 2016-02-21
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8605
Posted: 01:25am 20 Feb 2016
Copy link to clipboard 
Print this post

Here is how I would do it for an input at this rate:


const reedinput=2 'any pin with interrupt capability
const readrate=2000' time in msec between sampling counter
setpin reedinput,INTL,countpulses, PULLUP 'set up an interrupt on negative going edges
settick readrate,updatepulserate 'set up an interrupt every "readrate" milliseconds
DIM integer pulserate, pulsecounter=0

do
print pulserate
pause readrate
loop

sub countpulses 'interrupt routine called when a negative going pulse arrives
pulsecounter=pulsecounter+1
end sub

sub updatepulserate 'called every readrate milliseconds
pulserate=pulsecounter
pulsecounter=0
end sub


The way the pin interrupt system works is that the pin is actually polled after each Basic statement or every millisecond if the program is paused. This automatically creates a small debounce affect as the polling is likely to miss "bounces". If you want to increase the debounce effect just add a pause statement (1 or 2 msec) in the countpulses interrupt routine (bad practice generally but OK for this application)

As previously stated reed relays are not subject to much noise anyway so this approach coupled with a RC filter should give accurate results.

Edited by matherp 2016-02-21
 
MikeO
Senior Member

Joined: 11/09/2011
Location: Australia
Posts: 275
Posted: 05:36pm 20 Feb 2016
Copy link to clipboard 
Print this post

@ Lew247

Hi I use a weather station based on uMite170, the code for Wind sensors is based on arduino code for Sparkfun weather sensors. The Anenometer only has 1 reed switch , yours would be producing a lot more pulses so you may have to change some values like shortening the measuretime for higher wind speeds , currently its 30 secs.
This is only an extract of the code for brevity.

Cheers Mike.

'
'Michael Ogden
'April 2015
'
'Weather Station. metxx.bas

'Wind and Rain sensor code adapted from Sparkfun code

'
'Option Explicit
'Option Default Integer
Option autorun On
Cpu 48

'Constants
Const swVer="0.5"
Const redLed=9
Const DHT22pin=15
Const wSpeedPin=6
Const wDirPin=7
Const WindFactor=2.4
Const TestPause=30000
Const RainPin=5
Const RainFactor=0.2794
Const ADCFactor=0.0032258




' Setup BMP085/BMP185 pressure sensors
' TassyJim 28 Oct 2014

Dim BMPData(2) ' store data from BMP085
Dim cal(11) ' calibration data
oss = 0 ' over sampling 0 to 3
alt = 86 ' your altitude in metres

BMP085calMEM = &HAA ' start of 11 calibration values
BMP085address = &H77 ' BMP085 address
BMP085control = &HF4 ' BMP085 control register
BMP085temp = &H2E ' BMP085 temperature command
BMP085pres = &H34 ' BMP085 pressure command
BMP085pres = BMP085pres + oss*&H40 ' adjust command for oversampling
BMP085reading = &HF6 ' register for results of reading

I2c Open 400, 200 ' Enable I2C. use slow speeds for long leads
Pause 20
z = Calibrate() ' read the calibration data
' End Setup BMP085/BMP185 pressure sensors

'Define I/O

Setpin redLed,Dout
Setpin wSpeedPin, Intl,anemometerClick,Pullup
Setpin RainPin, Intl,rainguageClick,Pullup
Setpin wDirPin,Ain

' Array
Dim wArray(10)
Dim wdArray(10)
'
' Global variables
anem_count=0
anem_last=0
anem_min=1000
HGust=0
rain_count=0
rain_last=0
wCount=1
wdCount=1
'

'Init xb communications
InitxbComm 'initialise comms
iDeviceID=25 'Device ID
Status=3 'Callhome
xbWake 'Xbee wake

Init:
Watchdog 8000
'interupts
Settick 1000 ,T1,1 'establish seconds "Tick Timer"


Pause 1000
iCheckTimeFlag=1

'*** start main program loop
Main:
Do
'StartTime = Timer
Pause 1000
Watchdog 8000
Pulse RedLed, 200
If iCheckTimeFlag=1 Then ReqNetworkTime 'Periodic time Update from Server
'Print "Seconds:";secs
Select Case secs Mod 5

'every 5 secs
Case 0

windDirProc
Print wDir;" ";wadc;" ";wHeading
'SendDataUpdate

End Select

Select Case secs
Case 30
windSpeedProc
Case 60
windSpeedProc
rainProc
readhumidity
BMP085read
Print ""
Print "Time:";Time$
Print wDir;" ";wadc;" ";wHeading
Print "AvgWindSpeed:";wspeed
Print "Windgust:";wgust
Print "Highest Daily Windgust:";Hgust
Print "Rain:";mmrain
Print "Outside Temperature: " Str$(dhtTEMP,3,1);" Humidity: " Str$(dhtHUMID,3,1)
Print "T(BMP085):";Str$(t,3,1);" P(sl):";Str$(p0/100,5,1)

SendDataUpdate
End Select

Select Case mins

Case 5,10,15,20,25,30,35,40,45,50,55,60
'Print "5 mins_ Sending Data Update"
'SendDataUpdate
End Select

'Periodic housekeeping


'Print "Loop elapsed time"; Timer-StartTime
Loop
End
'***** End main program loop

'Sub routines
'rainguage sensor interrupt
Sub rainguageClick
thistime=Timer-rain_last
rain_last=Timer
If thistime>10 Then
rain_count=rain_count+1
'Print "Rain click"
End If

End Sub

'Wind speed sensor interrupt
Sub anemometerClick
thistime=Timer-anem_last
anem_last=Timer
If thistime>2 Then 'only process if > 2mSec, for debounce
anem_count=anem_count+1
If thistime<anem_min Then
anem_min=thistime 'gust
End If
'Print "Wind click"
Else
anem_count=0
End If
'print "Counts:";anem_count;" Time:";thistime;" Min Time:";anem_min
End Sub

'Wind Direction data process
Sub WindDirProc
wdResult=0
wDir=Pin(wDirPin)
'wADC=Int(wDir/ADCfactor) 'convert voltage to adc value
'wDirADC=Int(Pin(wDirPin)*0.00324)
select case wdir
case 2.4 to 2.6
wheading=0
'case 1.15 to 1.25
'wheading=22.5
case 1.4 to 1.6
wheading=45.0
'case .25 to .27
'wheading=67.5
case .35 to .65
wheading=90.0
'case .2 to .25
'wheading=112.5
case .66 to .95
wheading=135.0
'case .
'wheading=157.5
case .85 to 1.15
wheading=180.0
'case 291 to 304
'wheading=202.5
case 1.95 to 2.15
wheading=225.0
'case 585 to 605
'wheading=247.5
case 2.85 to 3.15
wheading=270.0
'case 816 to 836
'wheading=292.5
case 2.7 to 2.95
wheading=315.0
'case 692 to 712
'wheading=337.5
case ELSE
wheading=lastreading
end select
'For x=1 To 9 'move data up array
' wdArray(x)=wdArray(x+1)
'Next x
'wdArray(10)=wHeading 'place latest reading in Array
'For x=1 To 10 'addup all data in array
' wdResult=wdResult+wdArray(x)
'Next x
'wdCount=wdCount+1
'If wdCount=10 Then wdCount=1
'wHeading=wdResult/10 'get average the the last 10 wind dir samples
lastreading=wheading
End Sub

'Wind Speed data process
Sub WindSpeedProc
wResult=0
'Print "Counts:";anem_count;" Time:";thistime;" Min Time:";anem_min
'calc wind average
reading=anem_count
anem_count=0
wSpeed=(windfactor*reading)/(testpause/1000)
'calc Gust
'Print "Wind Count:";wcount
'Print "ActualWindSpeed:";wspeed
reading=anem_min
anem_min=1000
wGust=(1/(reading/1000))*windfactor
For x=1 To 9 'move data up array
wArray(x)=wArray(x+1)
Next x
wArray(10)=wSpeed 'place latest reading in Array
For x=1 To 10 'addup all data in array
wResult=wResult+wArray(x)
Next x
wCount=wCount+1
If wCount>10 Then wCount=1
wSpeed=wResult/10 'get average the the last 10 wind samples
If wgust>hgust Then hgust=wgust
'Print "WindSpeedArray:";wresult
'Print "AvgWindSpeed:";wspeed
'Print "Windgust:";wgust
'Print "Highest Windgust:";Hgust
End Sub

'Rain sensor process
Sub RainProc
reading=rain_count
rain_count=0
mmRain=mmRain + (reading*rainfactor)
'Print "Rain:";mmrain
End Sub

'Humidity Sensor
Sub readhumidity
Dht22 DHT22pin, dhtTEMP, dhtHUMID ' dump stale reading
'Print Time$;" Temperature: " Str$(dhtTEMP,3,1);" Humidity: " Str$(dhtHUMID,3,1)
End Sub

'End of Sensor routines

Codenquilts
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 01:32am 21 Feb 2016
Copy link to clipboard 
Print this post

Thanks everyone
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024