By having the inputs floating, the results will be indeterminate. Either put a 10k resistor to 5V on each of the inputs or enable the internal pullups. To activate the ‘switch’, connect the required port pin to 0V.
Posted by avrcandies: Tue. Jul 10, 2018 - 12:05 AM
1
2
3
4
5
Total votes: 0
You don't get it yet. able to make the test to the 2 pins with only 1x 10k ohm resistor, instead of having 2x 10k ohm resistor, 1 for each pin.
Why do you keep talking about & showing only one resistor? Does your setup match the correct drawing given by Clawson?
There must be TWO resistors, one going from 5v to PD2, and another resistor going from 5V to PD3. It really can't be any simpler (other than using the built-in pullups)...It is better to add your own for now, since you are sure they are taking effect. The built-ins, require your software to be correct in order to activate those.
You can use wires to gnd to pull either or both pins to gnd as desired (or get some switches). Why are you messing with debouncing switches, when you don't have any (just wondering)?
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
Posted by PsySc0rpi0n: Tue. Jul 10, 2018 - 06:14 AM
1
2
3
4
5
Total votes: 0
Kartman already understood what I was trying to say. And I already understood you you all are saying. And I'll make the changes to match what I need to have.
avrcandies, I was talking and showing what I had in hardware because it was what I had in hardware in fact. Ok, its not correct, but it was what I had, ok? Got it? My mistake might only be to have one of the 2 pins floating when I shouldn't and I'll fix that later today, but that was what I had on the breadboard.
And I've already ordered a complete set of several different push-button from eBay, but they will take quite a while to arrive, so as we use to say around "if you don't have a dog, you'll have to hunt with a cat..."
Later today, after work ill be back to my tests.
Thanks
Posted by avrcandies: Tue. Jul 10, 2018 - 07:00 AM
1
2
3
4
5
Total votes: 0
That's good that your are fixing up your setup...having real switches will make checking things out a lot better. Things may start off rocky, but you'll get there step-by-step. Keep experimenting and live the dream!
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
There are four possible causes for your problems...
1) Hardware Design - what your hardware should look like
2) Hardware Implementation - what you actually built, including any faults
3) Software Design - the algorithm used
4) Software Implementation - What the compiler outputs
It sounds like 1) is sorted when you follow the advice given above. We know 3) is OK because I've used your exact code and it works on my board here. So that leaves 2) or 4).
With regards to 4) there has been some discussion about the use of 'volatile'. I have proved that on one version of the compiler it doesn't matter. On other versions it might (although there is a different argument about whether that behavior is correct).
To help eliminate 4), and hence prove your problem lies with 2) could you...
a) compile the non-working code as you posted back in post #19
b) find the .LSS file generated
c) copy and paste the whole .LSS file into this topic
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
Posted by PsySc0rpi0n: Tue. Jul 10, 2018 - 10:00 PM
1
2
3
4
5
Total votes: 0
Hello.
Sorry for the late reply.
Today was a rough day. My only spare time was last 10 minutes I took to add an extra 10k ohm resistor to PD3 (PD2 already had one) and try to load the code again and test. LED is always ON even so!
I couldn't do any more testing and I'm about to go to bed. Just time to tell the files I have after compilation:
debounce.srec
debounce.o
debounce.map
debounce.lst
debounce.hex
debounce.elf
debounce.c
debounce.bin
debounce_eeprom.srec
debounce_eeprom.hex
debounce_eeprom.bin
no .LSS file.
Let me know what else you need. I had no time to perform all the other fail safe checks that Brain told me! Tomorrow I'll try to re-check wirings and hardware and paste here compilation output if needed, and also my Makefile!
I suggest that instead of learning to understand the Mega328P AVR microcontroller as a device, learn instead how to interface simple and cheap module boards to the Mega328P that is the key component of the Arduino system. I suggest thinking of the Arduino UNO or Nano as the lowest level of hardware that you should spend time learning. Instead, learn I2C {TWI in Atmel language, Wire.h in Arduino language} by connecting a cheap DS3231 clock module to the AVR (on the standardized single-board hardware development platform, the Arduino). Get an LCD 16x2 char display or a ST7735 TFT 160x128 SPI display and add it to the system. Download the libraries for Arduino in GitHub for these parts. Study the code. This is the place where everybody tries to show that Arduino is not a toy by using every academic trick that they learned in C++ programming school in the library application that they are offering. So you will get a crash, "sink or swim" course in C++ coding. Most of the time, when you have the hardware connected correctly, and the example code will compile correctly, then your application /.ino /sketch/program/ will run its demo correctly. Even if you are not exactly sure what is happening, or what the data that you are receiving means.
Other cheap interesting interface-module boards on eBay are the RDA5807M FM-radio receiver, the INA219 I2C voltage/amp meter, the AD9833 Sine/Triangle/Square programmable function generator, the DFPlayer MP3 module that reads music directly from SD chip/cards, the VS1053 MP3 player/Ogg recorder/MIDI tone module audio-processor board, the compass-gyro-accelemeter MEMS ICs.
It's better to learn CPU to peripheral interfacing and user-interaction systems than it is to learn the internals of an individual processor.
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
Err no - it's unlinked. It's the LSS that is created by an "objdump -S" from the ELF that is more useful. As7 has a tick box somewhere in the project setting to say "and create an LSS". I though this was enabled by default but I guess OP must have disabled it.
Err no - it's unlinked. It's the LSS that is created by an "objdump -S" from the ELF that is more useful. As7 has a tick box somewhere in the project setting to say "and create an LSS". I though this was enabled by default but I guess OP must have disabled it.
Thanks. So, @OP, it's the .LSS we want.
(boy, you GCC types have it tough, so many hoops to jump through and options to set. )
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
(boy, you GCC types have it tough, so many hoops to jump through and options to set.
And yet that is why most of us love GCC as it has literally hundreds of options which mean you can get it to do pretty much anything you ever hoped to achieve with a compiler. In fact GC+binutils have grown organically with 10,000's of programmers, each with their own requirements, saying "if only the compiler/linker could do this too" so each one adds the feature they are looking for and as long as it's considered an attractive feature to have and is implemented without obvious bugs the core team permit these things to be added making GCC perhaps the most configurable compiler/linker toolchain you can use. This is the joy of FOSS software!
Of course the downside is that there are myriad options and a beginner does not know which are the vital "must have" things and which are some esoteric mind trip only of use to some Icelandic code hacker on every third Thursday in July. Take optimisation for instance. Some compilers just have "on / off" or "on / mild / aggressive" and while GCC does have "grouping" options such as -O0, -O1, -O2, -O3, -Os, -Og these are just picking 10 or 20 or 30 options to be applied all at once. But every last optimisation option is individually switchable:
That page documents just the options to control optimization in GCC and that page is 1,900 lines long!! It can take a lifetime's work to study and understand every last option that GCC offers (I learn something new at least once a week if not once a day!) so yeah, I guess that could be considered "jumping through hoops". But personally I wouldn't have it any other way.
(I first started to use GCC for ARM projects in the early 90's - almost 30 years later and I'm still learning!)
Posted by PsySc0rpi0n: Fri. Jul 13, 2018 - 07:28 PM
1
2
3
4
5
Total votes: 0
Ok, beyond the fact that I was using active-low (resistor from pin to +5VDC and wire to short to GND when I wanted something to happen), I already reversed this situation and connected PD2 and PD3 to GND through 2 10k ohm resistors and used a wire to touch +5VDC to make the LED to switch state, but still not happening.
Posted by PsySc0rpi0n: Fri. Jul 13, 2018 - 08:37 PM
1
2
3
4
5
Total votes: 0
Well, as I remember that someone said here these 2 pins, PD2 and PD3, should be active-high for this code, I connected both 10k ohm resistors, each one from each pin to GND and I'm using a wire to short either of these 2 pins to +5VDC and I was expecting to see LED going ON/OFF but LED is always ON.
Posted by PsySc0rpi0n: Fri. Jul 13, 2018 - 09:38 PM
1
2
3
4
5
Total votes: 0
Ok, but I'll be reading a bit about the timer thing in the datasheet, so I might take longer. I don't know how to set the time I want the overflow to occur (1/200 of a sec), so I need to read to see if I can figure it out!
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
Debouncing is pretty straightforward, not sure why you're messing around so much.
It is, and the code the OP posted back in #19 works.
And it works for either active-high or active-low inputs. (Think about it, we debounce both rising and falling edges of a switch closing/opening. The software does not care what the inactive state of the switch is. It's only when we come to interpret the result that it matters).
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
How can counter be less than 0? You can simplify your logic by using a downcounter. If he pin is high, then counter = COUNT else if counter > 0 then counter—
If counter equal 0 then the pin has been sampled as low for COUNT times. Simples.
Posted by PsySc0rpi0n: Sat. Jul 14, 2018 - 11:10 AM
1
2
3
4
5
Total votes: 0
Kartman wrote:
How can counter be less than 0? You can simplify your logic by using a downcounter. If he pin is high, then counter = COUNT else if counter > 0 then counter— If counter equal 0 then the pin has been sampled as low for COUNT times. Simples.
A variable can contain sign or not, right? That's why there are signed and unsigned types of variables. Despite of that I just tried to follow avrcandies instructions and he said specifically to not let it go under 0.
I think I found a bug on my test program. I used in main() "if counter == COUNT" and maybe I should use '>' instead of '=='.
I'm sorry that I'm changing what I'm trying to do but I'm following suggestions and some of you says to do "this" and others says to do "that" and this might become a bit messy but I?ll try to follow up!
OK, so I take your hex file posted above and use it to program a 328P sitting in a known working test PCB (the one I posted a picture of earlier). The PCB uses active low switches and active low LEDs. I make NO changes to the file at all.
IT WORKS!
If I press the switch connected to PortD.2 it toggles on and off the LED connected to PortB.4. If I press the switch on PortD.3 the LED on B.5 toggles.
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
Posted by PsySc0rpi0n: Sat. Jul 14, 2018 - 01:26 PM
1
2
3
4
5
Total votes: 0
Brian Fairchild wrote:
PsySc0rpi0n wrote:
Either ways, .hex file content is this:
Thankyou.
PsySc0rpi0n wrote:
But still not working either!
OK, so I take your hex file posted above and use it to program a 328P sitting in a known working test PCB (the one I posted a picture of earlier). The PCB uses active low switches and active low LEDs. I make NO changes to the file at all.
IT WORKS!
If I press the switch connected to PortD.2 it toggles on and off the LED connected to PortB.4. If I press the switch on PortD.3 the LED on B.5 toggles.
Why you are talking about PortB.4 and PortB.5? I thought it was PB1 or PortB.1. That's what I have in my code.
Edited;
Ah ok, I think any PortB pin should work as it was the whole port set as output!
Why you are talking about PortB.4 and PortB.5? I thought it was PB1 or PortB.1. That's what I have in my code.
My bad, I had the jumper cable off by a row. It's actually PortB.2 and Port B.3 (pins 16 and 17 on the chip)
I think you misunderstand the return value from get_key_press(). It returns a bit mask of which keys are pressed within your mask value. So if you send 0x0C to it, it will look at bits/switches 2 and 3 and return the state of those switches, once debounced, in bits 2 and 3.
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
Posted by PsySc0rpi0n: Sat. Jul 14, 2018 - 07:26 PM
1
2
3
4
5
Total votes: 0
Brian Fairchild wrote:
PsySc0rpi0n wrote:
Why you are talking about PortB.4 and PortB.5? I thought it was PB1 or PortB.1. That's what I have in my code.
My bad, I had the jumper cable off by a row. It's actually PortB.2 and Port B.3 (pins 16 and 17 on the chip)
I think you misunderstand the return value from get_key_press(). It returns a bit mask of which keys are pressed within your mask value. So if you send 0x0C to it, it will look at bits/switches 2 and 3 and return the state of those switches, once debounced, in bits 2 and 3.
Regardless of that, the code is still not working here! But I'm at the moment trying to do what avrcandies said!
Posted by avrcandies: Sat. Jul 14, 2018 - 08:05 PM
1
2
3
4
5
Total votes: 0
Quit using concatenated logic, keep it simple & do one thing at a time--not 5 things in one statement!
if (pind & (1<<PD2)) {
if (counter<COUNT)
counter++;
}
else
if (counter>0)
counter--;
In main DO NOT check for = check for >=...the count will be increasing rapidly & you will miss the exact matching & wonder why you never get a hit.
You must pick a check that is perhaps halfway to the max limit (COUNT/2) ..NOT the max, or you will lose holding debounce protection (like when you have a weak finger)
Simple Summary:
When the button not pushed, counts down to zero limit
When the button is pushed, counts up to MAX limit
When the count>= MAX/2 , you have a valid press....easy??
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
Posted by PsySc0rpi0n: Sat. Jul 14, 2018 - 09:49 PM
1
2
3
4
5
Total votes: 0
Brian Fairchild wrote:
PsySc0rpi0n wrote:
Regardless of that, the code is still not working here!
So your code works here on my known working good hardware but not on your hardware. What does that suggest?
My hardware is working with other codes! I have no idea why that code is not working here! But yes, it suggests my hardware is probably not matching the code. I wonder why!
remember this flipping will provide 1/2 the irq freq. An irq of 1000Hz will show as 500 pulses per sec (1000 edges going up & down)
desired 200Hz irq (edges) will show as 100Hz pulses. This hidden factor of two often knocks programmers out of their car seats.
Thanks for warning. I noticed it and that's why OCR1A is set with 625 and not the value that results in 5ms delay which would be 1250. 625 is actually for 2.5ms delay. Tomorrow I'll proceed to next step.
Posted by avrcandies: Sun. Jul 15, 2018 - 04:05 AM
1
2
3
4
5
Total votes: 0
I noticed it and that's why OCR1A is set with 625
Sorry chief, you got it backwards. We want 200 irqs/sec (led toggle edges)... If you toggle at 4 times a sec (4Hz), due to toggling you'd see the led flash at 2Hz.
So 200 toggles a sec will flash the led at 100Hz. So if you scope it beware ONLY THEN so you don't say why don't I see 200Hz?
Anyhow, 200 something a second is 5ms (0.005 sec) separation between them.
Note dividing by period is same as mult by freq, which is 16000000/64
So the count needed is [0.005*16000000/64] minus 1 or 1249 ...this will check the switch 200 times a sec--one SwitchAcount and SwitchBcount every 5ms
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
Ok, so if the idea is the 200 times a second, that will be in fact 100Hz and 1249 counts. I just need to change the counting value in OCR1A.
Now that this in between task is done, I'm going back to the code from post #19 and try again to make it work!
And to make it clear, please confirm or deny each of the following:
1 - Active-Low means that "something happens" when I short whatever it is to GND. In other words, the normal state is at about 5V, and when a button (or whatever is pressed), the voltage goes momentarily to 0V.
2 - Active-High means that "something happens" when I short whatever it is to +5VDC. In other words, the normal state is at about 0V, and when a button (or whatever is pressed), the voltage goes momentarily to 5V.
3 - The code in question (from post #19) is supposed to be for hardware in Active-Low or Active-High?
4 - The LED the will toggle in 3, is to be Active-Low or Active-High?
Posted by PsySc0rpi0n: Sun. Jul 15, 2018 - 09:39 AM
1
2
3
4
5
Total votes: 0
Ok, I did the following test with the code from post #19.
I commented the following line in main():
LED_OUTPUT ^= get_key_press(0x0c);
and added the following to check if timer was running:
if(TIFR0 & (1 << TOV0))
PORTB ^= (1 << PB1);
I'm not sure this is the best approach but I get a frequency on scope of 61Hz. So, even if this is not the best was to check if timer is overflowing and triggering an interrupt, at least I know that TOV0 is being set. That tells me the timer is running, right?
And I have another question about the code, or better, the comments in the code. Why in the line where the prescaler is set, there is a comment saying "divide 256 * 256". What is this supposed to mean?
Also in my case, I'm not sure if this frequency of 61Hz is exactly the frequency the count gives. I mean, if I use a prescaler of 256, I get 16Mhz/256 = 62.5Khz. This means a tick (or count) every 1/62500 of a second or 16us. As this is an 8 bit counter, the overflow occurs every 256 ticks, meaning after 16us * 256 = 4096 us. This means a frequency of 244.14Hz. On scope will show up a half of this value due to toggling. Curiously the frequency showing up on scope is half of hlaf of 244Hz, I mean 61Hz * 4 = 244Hz.
So where the 61Hz comes from? Or am I going wrong with the math?
Posted by avrcandies: Sun. Jul 15, 2018 - 03:05 PM
1
2
3
4
5
Total votes: 0
Ok, so if the idea is the 200 times a second, that will be in fact 100Hz and 1249 counts. I just need to change the counting value in OCR1A.
Now that this in between task is done, I'm going back to the code from post #19 and try again to make it work!
Does the 200Hz debounce work? Once you have the IRQ running, it is only a few minutes to have it all ready.
Its like you are wandering in the AVR desert, going from town to town
So where the 61Hz comes from
if you are getting 16000000/256/256=244 irqs per second, why do you think you see a 122 square wave? Are you sure you see 61Hz?
could be, since you are checking the irqflag in main, you only catch it half the time (since it is immediately handled)...that would make tha apparent freq less.
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
Posted by PsySc0rpi0n: Sun. Jul 15, 2018 - 04:39 PM
1
2
3
4
5
Total votes: 0
avrcandies wrote:
Ok, so if the idea is the 200 times a second, that will be in fact 100Hz and 1249 counts. I just need to change the counting value in OCR1A.
Now that this in between task is done, I'm going back to the code from post #19 and try again to make it work!
Does the 200Hz debounce work? Once you have the IRQ running, it is only a few minutes to have it all ready.
Its like you are wandering in the AVR desert, going from town to town
So where the 61Hz comes from
if you are getting 16000000/256/256=244 irqs per second, why do you think you see a 122 square wave? Are you sure you see 61Hz?
could be, since you are checking the irqflag in main, you only catch it half the time (since it is immediately handled)...that would make tha apparent freq less.
Indeed... I made the toggle inside the ISR vector and it shows correct frequency! 122Hz is because of the toggling thing.
About the original code from post #19, now I need to find a way of checking if it is working!
And the math I do is:
Crystal Freq / Prescaler factor
16Mhz / 256 = 62.5Khz
This means 1/62.5Khz seconds = 16us for each increment in TCNT0.
As Timer0 is 8-bit, the overflow takes 16us * 256 = 4096us to occur.
This means the flag will be set at a rate of 1/4096us = 244.14Hz.
I'm just not sure how it makes of this a 50% Duty Cycle and why this is not more like a pulse and then the TVO0 flag would be set to 0 because the ISR routine is just a line of code and the remaining time was at 0V.
Something like this:
____|____|____|____
where each '|' is the TOV0 is set to 1 and immediately set to 0 because the ISR is just that line of code.
Instead, we have something like:
__|--|__|--|__|--|__
Anyway, I want to move on!
So, about the code of post #19, I'm going to try to use only a push-button at PD2 and a LED at PB1.
Push-Button is Active-Low. Meaning that the pin is using a 10k ohm pull-up resistor and the push-button has one lead to that uC pin and the other lead to GND. When I press the push-button, it sets 0V at PD2.
LED at PB1 has one lead (+ lead) connected to PB1 and the other lead (- lead) connected to a 470 ohm resistor that is connected to GND.
Is this the way the hardware should be set to work correctly with the code?
Posted by PsySc0rpi0n: Mon. Jul 16, 2018 - 06:38 PM
1
2
3
4
5
Total votes: 0
Where is that link to a post where there was sort of a table with the current result of all the bitwise operations taking place inside the ISR of code from post #19? I can't find it.
Posted by PsySc0rpi0n: Mon. Jul 16, 2018 - 07:04 PM
1
2
3
4
5
Total votes: 0
clawson wrote:
I have a feeling it was a link I gave to an analysis of danni's code by Johan Ekdahl
Yes it was! I think the code is working and the return of the get_key_press() is just the address of the button pressed after debounced, right? In that case, if I want a LED to light ON I need to have a LED connected to the pin the push-button is connected to, no?
Posted by avrcandies: Mon. Jul 16, 2018 - 07:18 PM
1
2
3
4
5
Total votes: 0
Personally, I think you should stick with the simple counter method---why? it is simple to understand and debug & get working. Getting the IRQ running is the hardest part & you already have that going (with a few fumbles along the way).
The other method is (Danni) great, but you will fall into an evil cave & need rescued over & over because it has more complex/convoluted details. Even though what you have should already be working, it is not--so you are about to wander into that cave seeking many solutions from the medicine man.
Soon you will be in the winners circle, lapping up the adulation, big prize money, and maybe a free t-shirt.
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
Posted by PsySc0rpi0n: Mon. Jul 16, 2018 - 07:22 PM
1
2
3
4
5
Total votes: 0
Well, if I get my questions answered I bet with myself I'll get there! What I can't do is changing my mind constantly which I already did to try to accomplish your last suggestion (the 200Hz thing). I need to stick to this and I don't need to understand all and every detail of the code. I'll be happy to just understand the way it works so that I can adapt it to my code! That's all.
And I have a couple of questions about it! I was reading the walkthrough I just posted about and it's said that the variables all starts with 0. But any of the variables were assigned with a 0. So how do we know they don't have trash by the start of the program?
Another question is that one I made above about the return value of that function!
If I get these answer I might start doing the thing on my own I guess!
I was going to say that Danni's code is not rocket science though I guess it is a bit. But anyway all it ultimately does is monitor between 1 and 8 bits in a port. You pass in a mask to say which and how many you want to know about. In your case the mask value 0x0C means "two bits, bits 2 and 3 (counting 0 to 7)" it then returns 1 bits in bit position 2 or 3 or both or neither to indicate which of the two are pressed. So it will return 0x00 if neither are pressed, 0x04 if only bit 2 is pressed, 0x08 if only bit 3 is pressed or 0x0C if both 2 and 3 are pressed. It really is as simple as that (and hence not rocket science - even if it really is!)
By having the inputs floating, the results will be indeterminate. Either put a 10k resistor to 5V on each of the inputs or enable the internal pullups. To activate the ‘switch’, connect the required port pin to 0V.
- Log in or register to post comments
TopYou don't get it yet. able to make the test to the 2 pins with only 1x 10k ohm resistor, instead of having 2x 10k ohm resistor, 1 for each pin.
Why do you keep talking about & showing only one resistor? Does your setup match the correct drawing given by Clawson?
There must be TWO resistors, one going from 5v to PD2, and another resistor going from 5V to PD3. It really can't be any simpler (other than using the built-in pullups)...It is better to add your own for now, since you are sure they are taking effect. The built-ins, require your software to be correct in order to activate those.
You can use wires to gnd to pull either or both pins to gnd as desired (or get some switches). Why are you messing with debouncing switches, when you don't have any (just wondering)?
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopKartman already understood what I was trying to say. And I already understood you you all are saying. And I'll make the changes to match what I need to have.
avrcandies, I was talking and showing what I had in hardware because it was what I had in hardware in fact. Ok, its not correct, but it was what I had, ok? Got it? My mistake might only be to have one of the 2 pins floating when I shouldn't and I'll fix that later today, but that was what I had on the breadboard.
And I've already ordered a complete set of several different push-button from eBay, but they will take quite a while to arrive, so as we use to say around "if you don't have a dog, you'll have to hunt with a cat..."
Later today, after work ill be back to my tests.
Thanks
- Log in or register to post comments
TopThat's good that your are fixing up your setup...having real switches will make checking things out a lot better. Things may start off rocky, but you'll get there step-by-step. Keep experimenting and live the dream!
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopThere are four possible causes for your problems...
1) Hardware Design - what your hardware should look like
2) Hardware Implementation - what you actually built, including any faults
3) Software Design - the algorithm used
4) Software Implementation - What the compiler outputs
It sounds like 1) is sorted when you follow the advice given above. We know 3) is OK because I've used your exact code and it works on my board here. So that leaves 2) or 4).
With regards to 4) there has been some discussion about the use of 'volatile'. I have proved that on one version of the compiler it doesn't matter. On other versions it might (although there is a different argument about whether that behavior is correct).
To help eliminate 4), and hence prove your problem lies with 2) could you...
a) compile the non-working code as you posted back in post #19
b) find the .LSS file generated
c) copy and paste the whole .LSS file into this topic
Thanks.
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopHello.
Sorry for the late reply.
Today was a rough day. My only spare time was last 10 minutes I took to add an extra 10k ohm resistor to PD3 (PD2 already had one) and try to load the code again and test. LED is always ON even so!
I couldn't do any more testing and I'm about to go to bed. Just time to tell the files I have after compilation:
debounce.srec
debounce.o
debounce.map
debounce.lst
debounce.hex
debounce.elf
debounce.c
debounce.bin
debounce_eeprom.srec
debounce_eeprom.hex
debounce_eeprom.bin
no .LSS file.
Let me know what else you need. I had no time to perform all the other fail safe checks that Brain told me! Tomorrow I'll try to re-check wirings and hardware and paste here compilation output if needed, and also my Makefile!
Thanks
Psy
- Log in or register to post comments
TopHello,
I suggest that instead of learning to understand the Mega328P AVR microcontroller as a device, learn instead how to interface simple and cheap module boards to the Mega328P that is the key component of the Arduino system. I suggest thinking of the Arduino UNO or Nano as the lowest level of hardware that you should spend time learning. Instead, learn I2C {TWI in Atmel language, Wire.h in Arduino language} by connecting a cheap DS3231 clock module to the AVR (on the standardized single-board hardware development platform, the Arduino). Get an LCD 16x2 char display or a ST7735 TFT 160x128 SPI display and add it to the system. Download the libraries for Arduino in GitHub for these parts. Study the code. This is the place where everybody tries to show that Arduino is not a toy by using every academic trick that they learned in C++ programming school in the library application that they are offering. So you will get a crash, "sink or swim" course in C++ coding. Most of the time, when you have the hardware connected correctly, and the example code will compile correctly, then your application /.ino /sketch/program/ will run its demo correctly. Even if you are not exactly sure what is happening, or what the data that you are receiving means.
Other cheap interesting interface-module boards on eBay are the RDA5807M FM-radio receiver, the INA219 I2C voltage/amp meter, the AD9833 Sine/Triangle/Square programmable function generator, the DFPlayer MP3 module that reads music directly from SD chip/cards, the VS1053 MP3 player/Ogg recorder/MIDI tone module audio-processor board, the compass-gyro-accelemeter MEMS ICs.
It's better to learn CPU to peripheral interfacing and user-interaction systems than it is to learn the internals of an individual processor.
My two cents worth.
- Log in or register to post comments
Topdebounce.lst will do just fine thankyou.
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
Top- Log in or register to post comments
TopThanks. So, @OP, it's the .LSS we want.
(boy, you GCC types have it tough, so many hoops to jump through and options to set.
)
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopOf course the downside is that there are myriad options and a beginner does not know which are the vital "must have" things and which are some esoteric mind trip only of use to some Icelandic code hacker on every third Thursday in July. Take optimisation for instance. Some compilers just have "on / off" or "on / mild / aggressive" and while GCC does have "grouping" options such as -O0, -O1, -O2, -O3, -Os, -Og these are just picking 10 or 20 or 30 options to be applied all at once. But every last optimisation option is individually switchable:
https://gcc.gnu.org/onlinedocs/g...
That page documents just the options to control optimization in GCC and that page is 1,900 lines long!! It can take a lifetime's work to study and understand every last option that GCC offers (I learn something new at least once a week if not once a day!) so yeah, I guess that could be considered "jumping through hoops". But personally I wouldn't have it any other way.
(I first started to use GCC for ARM projects in the early 90's - almost 30 years later and I'm still learning!)
- Log in or register to post comments
TopHello.
Which then is the option to enable the creation of these .LSS files? I have -Os enabled in my Makefile.
Edited;
I have this in my Makefile:
So, maybe the .LSS file you're looking for is probably with the same content as my actual .lst, no?
- Log in or register to post comments
TopOk, beyond the fact that I was using active-low (resistor from pin to +5VDC and wire to short to GND when I wanted something to happen), I already reversed this situation and connected PD2 and PD3 to GND through 2 10k ohm resistors and used a wire to touch +5VDC to make the LED to switch state, but still not happening.
Here is .LSS file content:
- Log in or register to post comments
TopOk so what do you expect to happen? What actually happens?
- Log in or register to post comments
TopWell, as I remember that someone said here these 2 pins, PD2 and PD3, should be active-high for this code, I connected both 10k ohm resistors, each one from each pin to GND and I'm using a wire to short either of these 2 pins to +5VDC and I was expecting to see LED going ON/OFF but LED is always ON.
- Log in or register to post comments
TopWhat do you mean LED? Shouldn't you have two of them? How would two switches control an LED (maybe if either is pressed, then light the led).
Debouncing is pretty straightforward, not sure why you're messing around so much.
Make it easy:
set up a timer irq that fires 200 times a sec
in the irq check switch A, if it is pressed:
increment countA, limit the count to 40 max
else decrement countA, don't let it go below zero
Do the same thing for switch B (countB)
===============
in your main code if countA is > 20 then the switch is pressed & do what you want
likewise for B
You can write this in 15 minutes and be done. That's as dirt-quick as it gets & works GRRRRRRREAT.
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopOk, but I'll be reading a bit about the timer thing in the datasheet, so I might take longer. I don't know how to set the time I want the overflow to occur (1/200 of a sec), so I need to read to see if I can figure it out!
- Log in or register to post comments
TopHere fellow freak; this gives you everything you need for the timer0 setup
http://maxembedded.com/2011/07/avr-timers-ctc-mode/
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopThat was one of the resources I was reading, thank you! :)
- Log in or register to post comments
TopWell, unless I've missed something, the lack of 'volatile' is not the cause of your problems here.
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopIt is, and the code the OP posted back in #19 works.
And it works for either active-high or active-low inputs. (Think about it, we debounce both rising and falling edges of a switch closing/opening. The software does not care what the inactive state of the switch is. It's only when we come to interpret the result that it matters).
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
Top@OP can you post the .hex file and I'll run it on known working hardware.
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopSo, to clear things out:
Does it matters if I'm using active-low or active high in PD2 and PD3 or not?
Either ways, .hex file content is this:
And I was now testing a code made by myself, trying to follow post #67 suggestions from avrcandies.
But still not working either!
- Log in or register to post comments
TopHow can counter be less than 0? You can simplify your logic by using a downcounter. If he pin is high, then counter = COUNT else if counter > 0 then counter—
If counter equal 0 then the pin has been sampled as low for COUNT times. Simples.
- Log in or register to post comments
TopA variable can contain sign or not, right? That's why there are signed and unsigned types of variables. Despite of that I just tried to follow avrcandies instructions and he said specifically to not let it go under 0.
I think I found a bug on my test program. I used in main() "if counter == COUNT" and maybe I should use '>' instead of '=='.
I'm sorry that I'm changing what I'm trying to do but I'm following suggestions and some of you says to do "this" and others says to do "that" and this might become a bit messy but I?ll try to follow up!
- Log in or register to post comments
TopThankyou.
OK, so I take your hex file posted above and use it to program a 328P sitting in a known working test PCB (the one I posted a picture of earlier). The PCB uses active low switches and active low LEDs. I make NO changes to the file at all.
IT WORKS!
If I press the switch connected to PortD.2 it toggles on and off the LED connected to PortB.4. If I press the switch on PortD.3 the LED on B.5 toggles.
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopWhy you are talking about PortB.4 and PortB.5? I thought it was PB1 or PortB.1. That's what I have in my code.
Edited;
Ah ok, I think any PortB pin should work as it was the whole port set as output!
- Log in or register to post comments
TopMy bad, I had the jumper cable off by a row. It's actually PortB.2 and Port B.3 (pins 16 and 17 on the chip)
I think you misunderstand the return value from get_key_press(). It returns a bit mask of which keys are pressed within your mask value. So if you send 0x0C to it, it will look at bits/switches 2 and 3 and return the state of those switches, once debounced, in bits 2 and 3.
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopRegardless of that, the code is still not working here! But I'm at the moment trying to do what avrcandies said!
- Log in or register to post comments
TopQuit using concatenated logic, keep it simple & do one thing at a time--not 5 things in one statement!
In main DO NOT check for = check for >=...the count will be increasing rapidly & you will miss the exact matching & wonder why you never get a hit.
You must pick a check that is perhaps halfway to the max limit (COUNT/2) ..NOT the max, or you will lose holding debounce protection (like when you have a weak finger)
Simple Summary:
When the button not pushed, counts down to zero limit
When the button is pushed, counts up to MAX limit
When the count>= MAX/2 , you have a valid press....easy??
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopAlso I'd reduce it to one button not two for starters so not 0x0C but a mask with just one bit set until you understand it.
- Log in or register to post comments
TopSo your code works here on my known working good hardware but not on your hardware. What does that suggest?
#1 Hardware Problem? https://www.avrfreaks.net/forum/...
#2 Hardware Problem? Read AVR042.
#3 All grounds are not created equal
#4 Have you proved your chip is running at xxMHz?
#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."
- Log in or register to post comments
TopOk, still about avrcandies suggestion, I made the code to work but I didn't understood something.
The code is as follows:
What I didn't understood is why I had to read bit 12 of TCNT1 to get the 200Hz on the scope. I did this by trial and error!
- Log in or register to post comments
TopMy hardware is working with other codes! I have no idea why that code is not working here! But yes, it suggests my hardware is probably not matching the code. I wonder why!
- Log in or register to post comments
TopOk, apparently it's not reasonable to try to do that.
Anyway, I made it working for 200Hz using interrupts. Here is the code:
- Log in or register to post comments
Topremember this flipping will provide 1/2 the irq freq. An irq of 1000Hz will show as 500 pulses per sec (1000 edges going up & down)
desired 200Hz irq (edges) will show as 100Hz pulses. This hidden factor of two often knocks programmers out of their car seats.
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopThanks for warning. I noticed it and that's why OCR1A is set with 625 and not the value that results in 5ms delay which would be 1250. 625 is actually for 2.5ms delay. Tomorrow I'll proceed to next step.
- Log in or register to post comments
TopSorry chief, you got it backwards. We want 200 irqs/sec (led toggle edges)... If you toggle at 4 times a sec (4Hz), due to toggling you'd see the led flash at 2Hz.
So 200 toggles a sec will flash the led at 100Hz. So if you scope it beware ONLY THEN so you don't say why don't I see 200Hz?
Anyhow, 200 something a second is 5ms (0.005 sec) separation between them.
Note dividing by period is same as mult by freq, which is 16000000/64
So the count needed is [0.005*16000000/64] minus 1 or 1249 ...this will check the switch 200 times a sec--one SwitchAcount and SwitchBcount every 5ms
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopOk, so if the idea is the 200 times a second, that will be in fact 100Hz and 1249 counts. I just need to change the counting value in OCR1A.
Now that this in between task is done, I'm going back to the code from post #19 and try again to make it work!
And to make it clear, please confirm or deny each of the following:
1 - Active-Low means that "something happens" when I short whatever it is to GND. In other words, the normal state is at about 5V, and when a button (or whatever is pressed), the voltage goes momentarily to 0V.
2 - Active-High means that "something happens" when I short whatever it is to +5VDC. In other words, the normal state is at about 0V, and when a button (or whatever is pressed), the voltage goes momentarily to 5V.
3 - The code in question (from post #19) is supposed to be for hardware in Active-Low or Active-High?
4 - The LED the will toggle in 3, is to be Active-Low or Active-High?
Thanks
Psy
- Log in or register to post comments
TopOk, I did the following test with the code from post #19.
I commented the following line in main():
and added the following to check if timer was running:
I'm not sure this is the best approach but I get a frequency on scope of 61Hz. So, even if this is not the best was to check if timer is overflowing and triggering an interrupt, at least I know that TOV0 is being set. That tells me the timer is running, right?
And I have another question about the code, or better, the comments in the code. Why in the line where the prescaler is set, there is a comment saying "divide 256 * 256". What is this supposed to mean?
Also in my case, I'm not sure if this frequency of 61Hz is exactly the frequency the count gives. I mean, if I use a prescaler of 256, I get 16Mhz/256 = 62.5Khz. This means a tick (or count) every 1/62500 of a second or 16us. As this is an 8 bit counter, the overflow occurs every 256 ticks, meaning after 16us * 256 = 4096 us. This means a frequency of 244.14Hz. On scope will show up a half of this value due to toggling. Curiously the frequency showing up on scope is half of hlaf of 244Hz, I mean 61Hz * 4 = 244Hz.
So where the 61Hz comes from? Or am I going wrong with the math?
- Log in or register to post comments
TopDoes the 200Hz debounce work? Once you have the IRQ running, it is only a few minutes to have it all ready.
Its like you are wandering in the AVR desert, going from town to town
if you are getting 16000000/256/256=244 irqs per second, why do you think you see a 122 square wave? Are you sure you see 61Hz?
could be, since you are checking the irqflag in main, you only catch it half the time (since it is immediately handled)...that would make tha apparent freq less.
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopIndeed... I made the toggle inside the ISR vector and it shows correct frequency! 122Hz is because of the toggling thing.
About the original code from post #19, now I need to find a way of checking if it is working!
And the math I do is:
Crystal Freq / Prescaler factor
16Mhz / 256 = 62.5Khz
This means 1/62.5Khz seconds = 16us for each increment in TCNT0.
As Timer0 is 8-bit, the overflow takes 16us * 256 = 4096us to occur.
This means the flag will be set at a rate of 1/4096us = 244.14Hz.
I'm just not sure how it makes of this a 50% Duty Cycle and why this is not more like a pulse and then the TVO0 flag would be set to 0 because the ISR routine is just a line of code and the remaining time was at 0V.
Something like this:
____|____|____|____
where each '|' is the TOV0 is set to 1 and immediately set to 0 because the ISR is just that line of code.
Instead, we have something like:
__|--|__|--|__|--|__
Anyway, I want to move on!
So, about the code of post #19, I'm going to try to use only a push-button at PD2 and a LED at PB1.
Push-Button is Active-Low. Meaning that the pin is using a 10k ohm pull-up resistor and the push-button has one lead to that uC pin and the other lead to GND. When I press the push-button, it sets 0V at PD2.
LED at PB1 has one lead (+ lead) connected to PB1 and the other lead (- lead) connected to a 470 ohm resistor that is connected to GND.
Is this the way the hardware should be set to work correctly with the code?
- Log in or register to post comments
TopWhere is that link to a post where there was sort of a table with the current result of all the bitwise operations taking place inside the ISR of code from post #19? I can't find it.
- Log in or register to post comments
TopI have a feeling it was a link I gave to an analysis of danni's code by Johan Ekdahl
- Log in or register to post comments
TopYes it was! I think the code is working and the return of the get_key_press() is just the address of the button pressed after debounced, right? In that case, if I want a LED to light ON I need to have a LED connected to the pin the push-button is connected to, no?
- Log in or register to post comments
TopI found the link:
Here for future reference.
- Log in or register to post comments
TopPersonally, I think you should stick with the simple counter method---why? it is simple to understand and debug & get working. Getting the IRQ running is the hardest part & you already have that going (with a few fumbles along the way).
The other method is (Danni) great, but you will fall into an evil cave & need rescued over & over because it has more complex/convoluted details. Even though what you have should already be working, it is not--so you are about to wander into that cave seeking many solutions from the medicine man.
Soon you will be in the winners circle, lapping up the adulation, big prize money, and maybe a free t-shirt.
When in the dark remember-the future looks brighter than ever. I look forward to being able to predict the future!
- Log in or register to post comments
TopWell, if I get my questions answered I bet with myself I'll get there! What I can't do is changing my mind constantly which I already did to try to accomplish your last suggestion (the 200Hz thing). I need to stick to this and I don't need to understand all and every detail of the code. I'll be happy to just understand the way it works so that I can adapt it to my code! That's all.
And I have a couple of questions about it! I was reading the walkthrough I just posted about and it's said that the variables all starts with 0. But any of the variables were assigned with a 0. So how do we know they don't have trash by the start of the program?
Another question is that one I made above about the return value of that function!
If I get these answer I might start doing the thing on my own I guess!
- Log in or register to post comments
TopI was going to say that Danni's code is not rocket science though I guess it is a bit. But anyway all it ultimately does is monitor between 1 and 8 bits in a port. You pass in a mask to say which and how many you want to know about. In your case the mask value 0x0C means "two bits, bits 2 and 3 (counting 0 to 7)" it then returns 1 bits in bit position 2 or 3 or both or neither to indicate which of the two are pressed. So it will return 0x00 if neither are pressed, 0x04 if only bit 2 is pressed, 0x08 if only bit 3 is pressed or 0x0C if both 2 and 3 are pressed. It really is as simple as that (and hence not rocket science - even if it really is!)
- Log in or register to post comments
TopSo, in my case, I'll have to check when any of the buttons is pressed to take an action when it is, right?
- Log in or register to post comments
TopPages