Does dir portd.2 in make the pin use it's pull up resistor on mega328p? I am refering to c code that turns the pull up on. DDRD &= ~(1 << DDD2); // Clear the PD2 pin
// PD2 (PCINT0 pin) is now an input
PORTD |= (1 << PORTD2); // turn On the Pull-up
// PD2 is now an input with pull-up enabled
This code should produce a square wave from portb.0 from a square wave input on portd.2 but doesn't.
using gcb rc2
~~~
#chip mega328p, 16
option explicit
dir portd.2 in ;pcint0 pin
PCINT0 = 1 ;hardware interrupt on
dir portb.0 out
On Interrupt PinChange0 Call pulsout
do
loop
sub pulsout
portb.0 = !portb.0
end sub
~~~
Last edit: stan cartwright 2017-06-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
then, when have sorted PCINT0 port out, you will need to change the port in the interrupt handler so you have a different port as you output signal port.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
RE portb.0 = !portb.0 -- I can scope b.0 to check the int is working and NOT won't compile.
Chris,thanks. You got away with it https://sourceforge.net/p/gcbasic/discussion/579126/thread/32b9f9db/
I knew << was shift left and | is OR so it's portd = portd or (1<<portd.2).
So, if portd.2=0 then portd bit 0 is set
and if portd.2=1 then portd bit 1 is set.
How does that turn on weak pull ups?
You don't get this problem cycling..
Last edit: stan cartwright 2017-06-26
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
re portb.0 = !portb.0 last January we spent many hours working in the Help to explain how this is NOT the way to read the port. You are currently reading the status of the pull-up.
portb.0 = !pinb.0 Is the correct method for AVR. Remember?
This will not make your code work but this is the correct method. This will resolve #1 in my posting above. So, make that change.
Then, sort #2 and #3.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Working example. This is very, very similar to the demonstration in the Interrupt Solution folder..
#chip mega328p, 16#option explicitdirportb.0inPCINT0=1'set out signal port as an outputdirportB.5outOnInterruptPinChange0CallTogglePindoloopsubtogglePinportb.5=!pinb.5endsub
The corrections to the code posted are:
Use pin.bit to read a port. See the Help for details. But, essentially portb.5 = !pinb.5 reads and NOT the results to set the port to the NOT status. Even though reading the port may seem to work - always use pin to read. As stated in the Help and the datasheet.
Use the correct pin as the source for PCINT0. As PCINT0 is a interrupt source mask for Portb.0 is is essential the portb.0 is an input.
Change the togglepin, the output signal, to something that is not the input interrupt signal. I have used portb.5
Validation.
Connect 1.00Mhz square wave signal to Portb.0 (UNO pin#8) and the output signal will be reflected to the interrupt on Portb.5 (UNO LED pin#13).
For an input of 1.00Mhz square wave signal you will get a 1.00Mhz square wave signal output.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes,that works.Ta. Faster than my scope I made lots of mistakes from misreading data sheets to testing wrong pins.Wearyness. It seems the on int stuff is figureing data sheets.The working code above would be useful in the help.
Adding EICRA=0 to 3. Is that enough to change trig on leading edge,trailing,low,any? Scope doesn't show any difference.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I see you have figured out that you were using the wrong interrupt source relative to the pins selected. Since you did not reveal what changes you made to correct the code, I will take a guess and do so.
If the interrupt source is to be pind.2 then it must be ExtInt0 rather than PCINTO which is on pinb.0.
The interrupt mask register EICRA determines if the interrupt is on a rising edge, falling edge, low level, or change. I will assume a falling edge with a pullup on Pind,2. Here is what the code should now look like.
.
#chipmega328p,16#optionexplicitdirportd.2in;//INTO pindirportb.0outINT0=1;// Set INT0 Bit of Mask register (EIMSK)EICRA=b'00000010';// Set int on falling edgeOnInterruptExtInt0CallTogglePindo'// Waiting for interrupt loopsubTogglePinportb.0=!pinb.0endsubEND
Last edit: William Roth 2017-06-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you Mr Roth for posting that code. I find examples are very useful for learning. Most AVR info is arduino c and converting to GCB is not trivial for me...but so is converting rosettacode other Basic examples.
I'm just experimenting on ways of making a frequency meter. Pinchange is one way.Using timers is another. I'm interested in pin events stopping timer1 count. I tried this method, it's not accurate but was interesting.Bits of different example code snippets stuck together.I tried scaling the 65535 to 0 timer ,to 0 to 100000 but I think that the wrong way.
Using leading edge, maybe I could use two pins fed with the same signal. One pin leading edge and starting a timer and the other pin low triggering to stop the timer and measure high time then measure low time by start timer on low trig then stop timer on high trig. Then add results for total period.
#chip mega328p ;from code examples c/o gcb dev team#option explicit#include<glcd.h>#define GLCD_TYPE GLCD_TYPE_ILI9341'PinmappingsforSPI-thisGLCDdriversupportsHardwareSPIandSoftwareSPI#define GLCD_DC portb.2 ; DIGITAL_10 'HW Data command line DC#define GLCD_CS portd.7 ; DIGITAL_7 ' Chip select line CS#define GLCD_RESET portd.4 ; DIGITAL_4 ' Reset line Tie high..not needed#define GLCD_DO portb.3 ; DIGITAL 11 'HW Data out | MOSI SDI#define GLCD_SCK portb.5 ; DIGITAL_13 'HW Clock Line SCK#define ILI9341_HardwareSPI ' remove/comment out to use software SPI.#define GLCD_EXTENDEDFONTSET1GLCDfntDefaultsize=1;----init.----dimcounterasworddimfinalcountaswordfinalcount=0counter=0dirportb.0inPCINT0=1OnInterruptPinChange0Callportb0change;OnInterruptTimer0OverflowCallevery1ms'Initialisethetimer-thisisrequired'Setprescalerto64andthenstartthetimerInitTimer0Osc,PS_0_64'Startthetimer-thisisrequiredStartTimer0;----start----doglcdprint(0,20,str(finalcount)+" ",ILI9341_WHITE)wait100msloop;-----end-----subportb0changecounter++EndSub'PWMsub'----ThiswillbecalledwhentheTimeroverflows----Subevery1ms'ThissetstheTCNT0registertogiveusthe1msInterrupt.'Thismeansthereare255-TCNT0+1clockscyclestothenextevent.Why1?BecuasetheTOPvalueis0not255.Settimer0,6'1.002ms;codeherefinalcount=countercounter=0EndSub
Last edit: stan cartwright 2017-06-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
For an accurate frequency meter you could count pulses (signal in') for a speciic time period, What what count period is used depends upon the lowest frequency you need to measure.
Use 1 timer as an external counter. Use another timer to start and stop the first counter for an exact period of time. The number of pulses counted by the first timer during the count period will tell you the frequency.
Example. Timer 1 (Counter 1) counts 1,000,000 pulses over a period of 1 second, The frequency will obviously be 1 MHz, In order to count millions of pulses, you will need to increment a variable at each rollover of the counter timer via an interrupt,
So for a signal in of 1MHz, and if the counter timer is a 16-bit timer, it will rollover 15 times and will have a remaining value of 16,960 when stopped at exactly 1 sec.
Thanks again. That was the method I was reading about but it's in arduino c :(. It counts the timer 1 overflows from a timer2 1ms gate but uses a pin change to start timer1 which is preloaded.... and it's c.
I'll try using the method you suggest. I had wondered how it could count so fast. The c code was supposed to be accurate to over 8MHz.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Mr Roth- "For an accurate frequency meter you could count pulses (signal in') for a speciic time period"
So... load timer1 with value.
Start timer1 on pin change.
count timer1 overflows in 1 ms gate time from timer0
The c code reset timer1 but I can't find the link :(
Any tips for Timer1Capture -- An input event on the pin ICP1 has caused the value of Timer 1 to be captured in the ICR1 register -- AVR ... from GCB help would be apreciated by me. I gave up reading other GCB users minds. I like examples.To see is to learn...to do is to know. No see ,no do.
did I say I don't like c...or python?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Speaking of reading minds ....First you need to clearly define the application.
1 What frequency measurement range?
2. What measurement resolution?
3, Expected accuracy?
4. What is the max refresh/update rate ? .
5, What type of input signal. Sine, square, other ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It's just an experiment to see different methods from adding pulsein+pulseininv to counting hi/lo time.
My cheapo usb scopes frequency meter only works to 180 KHz. My multimeters freq range works to 834 KHz. My sig gen only goes to 999999 Hz.
I suppose 1 to 1000000 Hz would be handy. I can wait 1 second for it to ubdate. I could add a schmitt trigger for a sine wave. Maybe a divider chip as well. Not much use if it's not accurate. Would I% accuracy be optimistic? Like 10V reading 9.9V or 10.1V....1000Hz displaying as 999Hz or 1001Hz.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Below is PIC code that uses the method I described. It is up to you to modify as needed for AVR/UNO. Easily measures from 1 Hz to 2 MHz to a resolution of 1 Hz.
.
#chip 16f18346, 32
#config FEXTOSC = OFF, RSTOSC = HFINT32
#config MCLRE = ON, WDTE=OFF
#option explicit
'Define I2C settings - CHANGE PORTS
#define I2C_MODE Master
#define I2C_DATA PORTB.6
#define I2C_CLOCK PORTB.5
#define I2C_DISABLE_INTERRUPTS ON
'''Set up LCD
#define LCD_IO 10
#define LCD_I2C_Address_1 0x7E
CLS
Dim Counts as word
Dim Frequency as Long
'// Configure timer1 as counter on ext pin
Inittimer1 (EXT, PRE0_1)
On interrupt Timer1Overflow Call CountOverflows
Do '// Main Loop
Cleartimer 1
Counts = 0
Starttimer 1
'// These delays determine acquisition time (1 sec)
'// This could be handeled by another timer if desired
'// Adjust microseconds to calibrate
Wait 1003 ms
Wait 770 us
Stoptimer 1 '// after exactly 1 sec
'// Calculate Frequency
Frequency = Counts * 65536 + timer1
'// Display Result on LCD Display
Locate 0,0 : Print "Freq: "
Locate 0,6 : Print Frequency : LCDSPACE 1
Print "Hz" : LCDSPACE 4
Loop
sub CountOverflows
Counts++
End Sub
Last edit: William Roth 2017-07-01
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I would like to comment on Bill's code/comment style. I find his code very clear and very well commented. I often save his code for future reference and to help with GCB statements I have yet to use, in this case "timers".
Thanks Mr. William Roth, Anobium, and others for all your past help also.
Paul
Last edit: Paul Haug 2017-07-01
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Works on mega328p with header and delete next 2 lines.
PortD.5 is input.
I didn't know Inittimer1 (EXT, PRE0_1), I was going to use TCCR1B = TCCR1B OR 0B00000111, or cs12=1:cs11=1:cs10=1 which do the same and easier for me to find.
65184 Hz gave frequency as 65535. I Hz higher gives 0 Hz.
Handy code, cheers.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
You get to know GCB and its commands by reading the Help, programming a chip with code and testing/debugging. Certainly "inittimer1" is not that hard to find in the help file.
If the ouput goes from 65535 to zero, then there is an error in the code. Post the code and we will sort it out.
Last edit: William Roth 2017-07-02
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I changed counts to long but then frequency is same 5 digit number.. 28xxx.
I'd like more detail in the help when it comes to setting the timers up and the names used for changing relevent registers used and GCB key words used to do that. Searching for info it seems other people find interpretting data sheets bit difficult to. There's plenty of commented c code to examine but I don't follow c easily.
#chip mega328p, 16#option explicit#include<glcd.h>;#define GLCD_TYPE GLCD_TYPE_ILI9341#define GLCD_DC portb.2 ; DIGITAL_10#define GLCD_CS portd.7 ; DIGITAL_7 #define GLCD_RESET portd.4 ; DIGITAL_4 ' Reset line Tie high..not needed#define GLCD_DO portb.3#define GLCD_SCK portb.5#define ILI9341_HardwareSPI#define GLCD_EXTENDEDFONTSET1GLCDfntDefaultsize=2GLCDRotate(landscape);DimCountsaswordDimFrequencyasLong;Inittimer1(EXT,PRE0_1);THISISNOTEXPLAINEDINHELP;TCCR1B=TCCR1Bor0B00000111;setCS12,CS11andCS10to"1"portd.5inputcs12=1:cs11=1:cs10=1OninterruptTimer1OverflowCallCountOverflowsDo'// Main LoopCleartimer1Counts=0Starttimer1'// These delays determine acquisition time (1 sec)'// This could be handeled by another timer if desired'// Adjust microseconds to calibrateWait1000ms;wait770usStoptimer1'// after exactly 1 sec'// Calculate FrequencyFrequency=Counts*65535+timer1glcdPrint(0,0,"Frequency",ILI9341_YELLOW)glcdPrint(0,16,str(Frequency)+" Hz ",ILI9341_AQUA)LoopsubCountOverflowsCounts++EndSub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Stan, the attached code works well and was tested from 15 Hz to 4 MHz. Add your GLCD stuff as necessary.
I noticed that for some unown reason you changed the calculation to use 65535 as the count multiplier, You should not do this. "0" is a "whole number" and is included in the counting. Use 65536 as in the the attached code. If accuracy needs to be tuned , do that with the 1 sec delay period instead.
Does dir portd.2 in make the pin use it's pull up resistor on mega328p? I am refering to c code that turns the pull up on. DDRD &= ~(1 << DDD2); // Clear the PD2 pin
// PD2 (PCINT0 pin) is now an input
This code should produce a square wave from portb.0 from a square wave input on portd.2 but doesn't.
using gcb rc2
~~~
#chip mega328p, 16
option explicit
dir portd.2 in ;pcint0 pin
PCINT0 = 1 ;hardware interrupt on
dir portb.0 out
On Interrupt PinChange0 Call pulsout
do
loop
sub pulsout
portb.0 = !portb.0
end sub
~~~
Last edit: stan cartwright 2017-06-26
I don't see where you are setting the pullup in your code but this line should be the equivelent of your C snippet:
I don't use AVR so am not able to test.
Cheers
Chris
I do not think this is related to Pullups.
What is the line of code shown below doing? What is the intent? Have a look at the Help URL also shown below.
portb.0 = !portb.0
http://gcbasic.sourceforge.net/help/_inputs_outputs.html
Once we have resolved this question - if this does not fix the issue then we can have a look at any potential impact of the pullups.
I know this is not related to the pull-ups.
RE portb.0 = !portb.0 -- I can scope b.0 to check the int is working and NOT won't compile.
Chris,thanks. You got away with it https://sourceforge.net/p/gcbasic/discussion/579126/thread/32b9f9db/
I knew << was shift left and | is OR so it's portd = portd or (1<<portd.2).
So, if portd.2=0 then portd bit 0 is set
and if portd.2=1 then portd bit 1 is set.
How does that turn on weak pull ups?
You don't get this problem cycling..
Last edit: stan cartwright 2017-06-26
re portb.0 = !portb.0 last January we spent many hours working in the Help to explain how this is NOT the way to read the port. You are currently reading the status of the pull-up.
portb.0 = !pinb.0
Is the correct method for AVR. Remember?This will not make your code work but this is the correct method. This will resolve #1 in my posting above. So, make that change.
Then, sort #2 and #3.
It is just part of the AVR hardware architecture.
The register that controls the Pull ups has the same physical address as the Port.
When the Port is an output the Pull Ups are inactive and anything written to that address will appear on the output pins.
When the Port is an input nothing can be output so anything written to that address will set or clear the pullup associated with that pin instead.
Seems like. I never thought of the microchip 328p data sheet.It's got an index!
18.2.1. Configuring the Pin. Cheers.
Working example. This is very, very similar to the demonstration in the Interrupt Solution folder..
The corrections to the code posted are:
portb.5 = !pinb.5
reads and NOT the results to set the port to the NOT status. Even though reading the port may seem to work - always use pin to read. As stated in the Help and the datasheet.Validation.
Connect 1.00Mhz square wave signal to Portb.0 (UNO pin#8) and the output signal will be reflected to the interrupt on Portb.5 (UNO LED pin#13).
For an input of 1.00Mhz square wave signal you will get a 1.00Mhz square wave signal output.
Yes,that works.Ta. Faster than my scope I made lots of mistakes from misreading data sheets to testing wrong pins.Wearyness. It seems the on int stuff is figureing data sheets.The working code above would be useful in the help.
Adding EICRA=0 to 3. Is that enough to change trig on leading edge,trailing,low,any? Scope doesn't show any difference.
@Stan
I see you have figured out that you were using the wrong interrupt source relative to the pins selected. Since you did not reveal what changes you made to correct the code, I will take a guess and do so.
If the interrupt source is to be pind.2 then it must be ExtInt0 rather than PCINTO which is on pinb.0.
The interrupt mask register EICRA determines if the interrupt is on a rising edge, falling edge, low level, or change. I will assume a falling edge with a pullup on Pind,2. Here is what the code should now look like.
.
Last edit: William Roth 2017-06-27
Thank you Mr Roth for posting that code. I find examples are very useful for learning. Most AVR info is arduino c and converting to GCB is not trivial for me...but so is converting rosettacode other Basic examples.
I'm just experimenting on ways of making a frequency meter. Pinchange is one way.Using timers is another. I'm interested in pin events stopping timer1 count. I tried this method, it's not accurate but was interesting.Bits of different example code snippets stuck together.I tried scaling the 65535 to 0 timer ,to 0 to 100000 but I think that the wrong way.
Using leading edge, maybe I could use two pins fed with the same signal. One pin leading edge and starting a timer and the other pin low triggering to stop the timer and measure high time then measure low time by start timer on low trig then stop timer on high trig. Then add results for total period.
Last edit: stan cartwright 2017-06-27
For an accurate frequency meter you could count pulses (signal in') for a speciic time period, What what count period is used depends upon the lowest frequency you need to measure.
Use 1 timer as an external counter. Use another timer to start and stop the first counter for an exact period of time. The number of pulses counted by the first timer during the count period will tell you the frequency.
Example. Timer 1 (Counter 1) counts 1,000,000 pulses over a period of 1 second, The frequency will obviously be 1 MHz, In order to count millions of pulses, you will need to increment a variable at each rollover of the counter timer via an interrupt,
So for a signal in of 1MHz, and if the counter timer is a 16-bit timer, it will rollover 15 times and will have a remaining value of 16,960 when stopped at exactly 1 sec.
15 * 65536 = 983040 ..... 983040 + 16960 = 1,000,000
If the counter timer is an 8-bit timer it will roll over 3906 times and will have a remainig value of 64 when stopped at exactly 1 sec.
A 1 second count period will allow measuring frequencies as low as 1 Hz and up to about 50 MHz depending upon the chip used,
Last edit: William Roth 2017-06-27
Thanks again. That was the method I was reading about but it's in arduino c :(. It counts the timer 1 overflows from a timer2 1ms gate but uses a pin change to start timer1 which is preloaded.... and it's c.
I'll try using the method you suggest. I had wondered how it could count so fast. The c code was supposed to be accurate to over 8MHz.
Mr Roth- "For an accurate frequency meter you could count pulses (signal in') for a speciic time period"
So... load timer1 with value.
Start timer1 on pin change.
count timer1 overflows in 1 ms gate time from timer0
The c code reset timer1 but I can't find the link :(
Any tips for Timer1Capture -- An input event on the pin ICP1 has caused the value of Timer 1 to be captured in the ICR1 register -- AVR ... from GCB help would be apreciated by me. I gave up reading other GCB users minds. I like examples.To see is to learn...to do is to know. No see ,no do.
did I say I don't like c...or python?
Speaking of reading minds ....First you need to clearly define the application.
1 What frequency measurement range?
2. What measurement resolution?
3, Expected accuracy?
4. What is the max refresh/update rate ? .
5, What type of input signal. Sine, square, other ?
It's just an experiment to see different methods from adding pulsein+pulseininv to counting hi/lo time.
My cheapo usb scopes frequency meter only works to 180 KHz. My multimeters freq range works to 834 KHz. My sig gen only goes to 999999 Hz.
I suppose 1 to 1000000 Hz would be handy. I can wait 1 second for it to ubdate. I could add a schmitt trigger for a sine wave. Maybe a divider chip as well. Not much use if it's not accurate. Would I% accuracy be optimistic? Like 10V reading 9.9V or 10.1V....1000Hz displaying as 999Hz or 1001Hz.
Below is PIC code that uses the method I described. It is up to you to modify as needed for AVR/UNO. Easily measures from 1 Hz to 2 MHz to a resolution of 1 Hz.
.
Last edit: William Roth 2017-07-01
I would like to comment on Bill's code/comment style. I find his code very clear and very well commented. I often save his code for future reference and to help with GCB statements I have yet to use, in this case "timers".
Thanks Mr. William Roth, Anobium, and others for all your past help also.
Paul
Last edit: Paul Haug 2017-07-01
Works on mega328p with header and delete next 2 lines.
PortD.5 is input.
I didn't know Inittimer1 (EXT, PRE0_1), I was going to use TCCR1B = TCCR1B OR 0B00000111, or cs12=1:cs11=1:cs10=1 which do the same and easier for me to find.
65184 Hz gave frequency as 65535. I Hz higher gives 0 Hz.
Handy code, cheers.
You get to know GCB and its commands by reading the Help, programming a chip with code and testing/debugging. Certainly "inittimer1" is not that hard to find in the help file.
If the ouput goes from 65535 to zero, then there is an error in the code. Post the code and we will sort it out.
Last edit: William Roth 2017-07-02
I changed counts to long but then frequency is same 5 digit number.. 28xxx.
I'd like more detail in the help when it comes to setting the timers up and the names used for changing relevent registers used and GCB key words used to do that. Searching for info it seems other people find interpretting data sheets bit difficult to. There's plenty of commented c code to examine but I don't follow c easily.
@Stan
@All
It seems that using "++" to increment a variable only works for PIC Microcontrollers. In the code above change "Counts++" to "Counts = Counts + 1" .
Stan,
Change Counts++ to Counts = Counts + 1. This is a compiler issue.
Bill
Last edit: William Roth 2017-07-02
Stan, the attached code works well and was tested from 15 Hz to 4 MHz. Add your GLCD stuff as necessary.
I noticed that for some unown reason you changed the calculation to use 65535 as the count multiplier, You should not do this. "0" is a "whole number" and is included in the counting. Use 65536 as in the the attached code. If accuracy needs to be tuned , do that with the 1 sec delay period instead.