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 KingdomPosts: 1676 |
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 |
||||
lew247 Guru Joined: 23/12/2015 Location: United KingdomPosts: 1676 |
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 endsub |
||||
circuit Senior Member Joined: 10/01/2016 Location: United KingdomPosts: 232 |
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 KingdomPosts: 1676 |
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 |
||||
lew247 Guru Joined: 23/12/2015 Location: United KingdomPosts: 1676 |
last post edited* |
||||
palcal Guru Joined: 12/10/2011 Location: AustraliaPosts: 1805 |
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 KingdomPosts: 1676 |
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: AustraliaPosts: 139 |
@ 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] 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: AustraliaPosts: 5923 |
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 KingdomPosts: 1676 |
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 |
||||
matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 8605 |
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. |
||||
MikeO Senior Member Joined: 11/09/2011 Location: AustraliaPosts: 275 |
@ 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 KingdomPosts: 1676 |
Thanks everyone |
||||
Print this page |