Announcement

Collapse
No announcement yet.

555 countdown timer design question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Re: 555 countdown timer design question

    Err, I meant real, compileable/assembleable code mapped to a specific microcontroller - not pseudocode, much like the actual schematics for the discrete implementation...

    Comment


      Re: 555 countdown timer design question

      Ok guys, made a bit of progress on my own. Here's the (incomplete !) code. Let me know if you can open INO files or I need to paste it as plain text. What I managed to achieve so far is the long press to happen once and only once, then stopping that with a short press until the long press can be performed again. Now I need to figure out how to create a countdown and then plop that into the "short press action". There's also that buzzer I was mentioning just because It's probably a messy and amateurish code but it gets the job done so far and doesn't seem to glitch, though as some of you pointed out, something may eventually overflow and mess up....that's what testing is for, it's a work in progress
      Attached Files
      Wattevah...

      Comment


        Re: 555 countdown timer design question

        Originally posted by eccerr0r View Post
        Err, I meant real, compileable/assembleable code mapped to a specific microcontroller - not pseudocode, much like the actual schematics for the discrete implementation...
        Ah, you're a script kiddie? Can't work from an algorithm's description but have to poke at someone else's "finished code"? (always fun handing folks a BLANK sheet of paper in an interview and watching them struggle to figure out how to get started!)

        Attached is something that should work -- assuming there are no typographical errors (I just wrote it in Notepad so nothing to check syntax, unresolved symbols, etc. so I fully expect there to be apparently ambiguous SOME_SYMBOL, SomeSymbol and SOMESYMBOL instances).

        Note that there are:
        • no interrupts involved
        • no counter/timers
        • no "I/O" instructions
        • two input pins (SWITCH and LFC) and one output pin (LAMP)
        • nothing more expensive than integer add/subtract at runtime
        • a maximum stack penetration of just a few words (3?)
        • minimum CPU frequency required is probably 20KHz (but I'll need to cycle count to get a real figure)
        • trivial to add features like an "early warning blink" for the last few seconds before timeout
        • easily ported to a variety of different processors without changing the algorithm
        • switch debounce not included (but a trivial addition)


        I guesstimate it consumes about 400 bytes of ROM and 35 bytes of RAM (including the stack). Nothing there besides bare metal -- no "helper routines", etc. With a little bit of effort, you should be able to trim 30% of the RAM away.

        Once you understand the approach, you'd have no problem porting it to a PIC12, for example (an excellent way to test your understanding as the PIC12's have an unusual programming model). An ATtiny would be a good alternate choice.

        [I was going to code for an 8x305 but figured that would be too brutal of an example for most folks to follow; and virtually impossible for folks to find viable tools!]

        I will attempt to locate an appropriate assembler/linkage editor tomorrow; today was "goodie day" so I've spent the last 10 hours trying to integrate a fair bit of new kit and don't have access to my software development workstation until I finish these additions. I'd like to be able to discard the kit that's being replaced, ASAP (i.e., tomorrow) so that's the priority!

        Comment


          Re: 555 countdown timer design question

          Originally posted by Curious.George View Post
          Ah, you're a script kiddie? Can't work from an algorithm's description but have to poke at someone else's "finished code"? (always fun handing folks a BLANK sheet of paper in an interview and watching them struggle to figure out how to get started!)
          Never claimed I knew anything - just enough to get by Never took coding training courses or anything
          Wattevah...

          Comment


            Re: 555 countdown timer design question

            Also only part of that code was adapted, I added some stuff myself
            Wattevah...

            Comment


              Re: 555 countdown timer design question

              whatever works

              Comment


                Re: 555 countdown timer design question

                Hey, it's not my project...
                And a theoretical implementation is useless, need a real world implementation, or you can do it without a microcontroller - use a real 555!

                Comment


                  Re: 555 countdown timer design question

                  Originally posted by eccerr0r View Post
                  Hey, it's not my project...
                  And a theoretical implementation is useless, need a real world implementation, or you can do it without a microcontroller - use a real 555!
                  That was actually where this whole craze actually started: a 555
                  Wattevah...

                  Comment


                    Re: 555 countdown timer design question

                    Hang in there Dannyx, programming the MCU is the hardest part.

                    I needed a 2 minute time delay for a heating zone valve. I was going to use a 555 and then switched over to Arduino. Long delays not so good with 555.
                    I read a trimpot for the time delay value, and turn on a TRIAC when done.
                    Very simple, but I used a simple state-machine in software so the MCU does not "busy wait" generating time delay, so the MCU could do other things like scan buttons, blink LED's etc.

                    I tested and debugged using the Uno, then went to ATtiny85 (DIP-8) for the final board.

                    I also made the same timer thing for my car, a 3-hour timer (ign key off) for the stereo and cigarette-lighter power, dash-cam etc. Mainly so I can charge stuff or listen to tunes in my car with no key in the ignition and no dead battery if I forget things.

                    Comment


                      Re: 555 countdown timer design question

                      Originally posted by redwire View Post
                      Hang in there Dannyx, programming the MCU is the hardest part.

                      I needed a 2 minute time delay for a heating zone valve. I was going to use a 555 and then switched over to Arduino. Long delays not so good with 555.
                      I read a trimpot for the time delay value, and turn on a TRIAC when done.
                      Very simple, but I used a simple state-machine in software so the MCU does not "busy wait" generating time delay, so the MCU could do other things like scan buttons, blink LED's etc.

                      I tested and debugged using the Uno, then went to ATtiny85 (DIP-8) for the final board.

                      I also made the same timer thing for my car, a 3-hour timer (ign key off) for the stereo and cigarette-lighter power, dash-cam etc. Mainly so I can charge stuff or listen to tunes in my car with no key in the ignition and no dead battery if I forget things.
                      Valid points all, though I believe I didn't use a single delay in my code for the very reason you clearly pointed out, since I was aware of this issue ever since I've used my first Arduino, a Mega (<<<irrelevant detail but what the hey)
                      Wattevah...

                      Comment


                        Re: 555 countdown timer design question

                        Hey, Tektronix made a 9 minute delay with an RC delay and an op amp for my 'scope.
                        I could not believe they did it this way, but it works!

                        3 hours however, this definitely should go into the digital realm to combat leakage inaccuracies...

                        Comment


                          Re: 555 countdown timer design question

                          Attached is something that should work -- assuming there are no typographical errors (I just wrote it in Notepad so nothing to check syntax, unresolved symbols, etc. so I fully expect there to be apparently ambiguous SOME_SYMBOL, SomeSymbol and SOMESYMBOL instances).
                          Crap, I don't see my attachment! Let's try this, again... (ah, apparently have to click UPLOAD for any attachments -- and, previewing this post I now see it, so, fingers crossed...)

                          I will attempt to locate an appropriate assembler/linkage editor tomorrow; today was "goodie day" so I've spent the last 10 hours trying to integrate a fair bit of new kit and don't have access to my software development workstation until I finish these additions. I'd like to be able to discard the kit that's being replaced, ASAP (i.e., tomorrow) so that's the priority!
                          Sadly, haven't had time to chase down those tools -- too much kit to sort through and Uncle Sam insists that I have it done by end of calendar year.

                          [Of course, each year, I know that year end is coming so you'd think I would learn to start the equipment shuffle earlier...
                          Attached Files

                          Comment


                            Re: 555 countdown timer design question

                            Originally posted by Dannyx View Post
                            Never claimed I knew anything - just enough to get by Never took coding training courses or anything
                            Most folks are terrified of a "blank sheet of paper", in whatever form it takes.

                            I've had innumerable clients completely clueless as to what they wanted their product to do. They needed to see something (i.e., someone else's ideas) -- which they could then criticize: "That's not what I want!"

                            In the free software world (FOSS), this is evidenced by the large numbers of people who can "maintain" someone else's codebase -- even contributing significant enhancements! -- compared to the scant few folks who can "create" original works.

                            Comment


                              Re: 555 countdown timer design question

                              Here's what I believe to be the completed project. Thoughts, possible issues, opinions are all welcome, just don't sound too professional Does it work ? Yes it does, otherwise I wouldn't have posted it here Ok, so there are a few insignificant details that need to be addressed, like increasing the countdown timer from 2 seconds to 60 seconds, since it was used for testing the functionality of the code and waiting for 60 seconds to elapse every time would've driven me mad The output to the relay is called LED1 but it doesn't matter, that's what I meant by "insignificant details" - things that don't affect the functionality of the code.

                              So far it appears to be running OK in both states and the combinations between them, since that was actually the biggest challenge: telling the thing what to do when you're in a state and you issue it a command for the OTHER state.
                              Attached Files
                              Wattevah...

                              Comment


                                Re: 555 countdown timer design question

                                Originally posted by Dannyx View Post
                                Here's what I believe to be the completed project. Thoughts, possible issues, opinions are all welcome, just don't sound too professional
                                There are two schools of thought regarding this sort of thing.
                                • The first is, "if it works, nothing else matters".
                                • The second is, "if it works NOW, will it continue to work when someone tries to change it, later?" (could you revisit this code in 3 months and make a significant change WITHOUT BREAKING IT?)

                                The (longterm) problem with this style of coding is that you can't "see" what's happening; you have to wade through all of the details to understand just the basics of what it's trying to accomplish.

                                [Contrast that with the state tables in the source code I posted -- even if you don't understand the code itself -- and you can make a good guess as to what is happening, there!]

                                For example, my code adds a "Precharge delay" after the lamp extinguishes that forces the lamp to stay off for 3 seconds before it can be relit. How hard would that be to work into your code? How hard would it be to add that feature a few months from now (when you've forgotten how your code works)? How hard would it be for someone else to add that to your code?

                                Or, add a feature that causes the lamp to flash for the last 5 seconds before it shuts off (so folks walking ddown a long hall don't SUDDENLY find themselves in the dark).

                                Having said all that, some specifics regarding your "style":

                                Using names for things (like "longPressTime") is a win. It lets you make LIKELY changes without having to chase down weird "numbers" in the code. But, there is nothing that tells me (the guy who has to tweek your code after you've gone) how they are used. E.g., that one represents a time expressed in milliseconds (not seconds, etc.).

                                Additionally, there is nothing that tells me that longPressTime is actually a CONSTANT while longPressMoment is a VARIABLE that you happen to be initializing to "0".

                                Worse, there is nothing that tells the code these things (so the compiler can't help you catch your mistakes). E.g., imagine writing

                                if (longPressTime = millis() - longPressMoment) ...

                                when you meant to write

                                if (longPressTime == millis() - longPressMoment) ...

                                In the former case, longPressTime would CHANGE from the constant value that you intended to some value that depends on millis() and longPressMoment. Modern compilers will catch this sort of thing.

                                Consider adding another variable called "now" (or similar). At the top of the loop, assign the value of millis() to this variable. Thereafter, use "now" in the body of the loop. This is marginally more efficient (there is a cost to getting the current time via millis() which in many systems can be considerably larger than just reading a STORED time from a variable). While your current system may have no/little added cost to the millis() reference, when you borrow this code fragment for some future application, you may be chagrined to discover that it is a hugely expensive operation on that "new" system.

                                But, the subtler reason is that your code probably hasn't considered the case where millis() changes during a single iteration of the loop. This can cause really hard to locate bugs to creep into the code cuz your mind assumes that millis() on line Y is the same value (point in time) as it was on line X -- even though it could have changed!

                                Use whitespace liberally in your code. Note how I injected blank lines and broke lines into paragraphs/stanzas in my source code. Its easier for folks to read a series of statements expressed one per line than it is to see them all crammed onto the same line.

                                Develop a personal preference (no real right answer, here) for how you create identifiers. E.g., do you use all caps for constants? (true, false) Do you use CamelCase or under_scores for complex identifiers?

                                Nothing references "setup()". I have to assume this is peculiar to the environment you're coding in and some magical entity invokes it BEFORE it invokes loop(). Likewise, I am left guessing what pinMode(), millis(), etc. actually do and the proper way to use them.

                                I'm also curious as to the resource utilization, here -- how much CODE, how much DATA -- so you can see how small the potential devices could be to host the application (e.g., nothing indicates the need for longs over ints where you've used them). How do you know it will fit in the particular part you've chosen? How do you know how much you have "to spare" for future additions?

                                Comment


                                  Re: 555 countdown timer design question

                                  Of course it's going to be a mess - it's my first go at me, your average Joe, writing...though that's an overstatement....messing around with a code this long

                                  Nobody is going to mess with the code besides me and it's a work in progress, so comments on each line could come in handy and SHALL be added - true that. For formatting, since I haven't done this before and thus had no definitive style (and there's definitely no rule for this AFAIK - though I may be proven wrong) I chose what I thought would be easy FOR ME to follow. I do favor what you call "CamelCase" - makes the most sense to me. Lined up the If statements with their actions and their "elses"....threw in a blank space between major blocks....just how I thought it should look - no real reason.

                                  True, I did make the equal vs DOUBLE equal sign error a lot, but I had no idea the environment could be able to differentiate between this being an error or intended, since the symbol is correct either way code-wise and won't stop it from compiling, like a missing { or ; does.

                                  Not sure what you mean about setup not being used correctly there.

                                  The "NOW" idea is doable. I just had no idea there's a difference in accuracy. Might implement that too.

                                  My work procedure involves creating backups as I go, so I'd have like "shortPressTest" > "shortPressWorking"...timer test > timer working (just some examples), then combine the two, so if I screwed up at any point and could no longer follow along with my own code (which rarely happened despite what it looks like), I could backtrack and also keep the work safe. This goes for every work, written or otherwise, that I do: backup the hell out of it !

                                  Reading your feedback, which is very professional indeed and leaves very little room for comment, there are some parts which hint you may not be fully aware of the hardware I'm using, so it's an ArduinoProMini (there's your CamelCase ), so an atmega328p, though I do get your point: you're trying to be cross-compatible and make the codes/language whatever as universally applicable as possible, not just restrict them to this setup...goes to show you know your stuff. Cheers
                                  Wattevah...

                                  Comment


                                    Re: 555 countdown timer design question

                                    Originally posted by Dannyx View Post
                                    Of course it's going to be a mess - it's my first go at me, your average Joe, writing...though that's an overstatement....messing around with a code this long
                                    Even after you "clean it up", you will find it hard to understand (without reading every statement) the BASIC actions that you're presenting. I.e., that you're watching for one of two different types of button presses and doing different things based on where the code is at that time. The "states" in the code aren't readily apparent.

                                    True, I did make the equal vs DOUBLE equal sign error a lot, but I had no idea the environment could be able to differentiate between this being an error or intended, since the symbol is correct either way code-wise and won't stop it from compiling, like a missing { or ; does.
                                    If you declare certain identifiers to be constants, then the compiler will (can) tell you if you do something (stupid) like try to change one of them after it has been assigned its ONE initial value. So, anything that tries to change longPressTime will generate an error!

                                    (Imagine what would happen if you could write "true = false"!)

                                    There was a time (before compilers got smarter) when you would write things like:

                                    if (12 == count)

                                    instead of:

                                    if (count == 12)

                                    because screwing up the "==" in the first case would be flagged as an error (can't RESET the value of "12" to whatever "count" is, presently). But, this is really hard to read (it feels backwards) AND doesn't handle all cases:

                                    boxfull = (LARGE == boxsize) 144 : 12;
                                    if (boxfull == count) ...

                                    I.e., boxfull is a variable so where should it sit relative to the "=="?

                                    Not sure what you mean about setup not being used correctly there.
                                    I'm not saying it is incorrectly used. Rather, that I (without intimate knowledge of the programming environment that you're using) have no idea of how it is supposed to be used and the role it plays. I can only make educated guesses -- assumptions (the root cause of ALL bugs!).

                                    For example, if I gave you that code for an unknown processor and it contained something called "initialize()" with a bunch of code, you'd probably ASSUME that it was serving the role of your "setup()". In fact, it could have been dead code (code that isn't used!). So, you'd read it and ASSUME that all of those things were being done when, in fact, none of them were! You would miss the bugs that they're absence was actually causing:

                                    "Gee, the software behaves as if longPressTime was not initialized. Yet, I can see that it is, right over here..." (nope! that code is not running)

                                    The "NOW" idea is doable. I just had no idea there's a difference in accuracy. Might implement that too.
                                    There is no way the "environment" (support library) can know that you're expecting millis() to have the same value it did previously.

                                    x = millis();
                                    y = millis() + 1;
                                    if (millis() > y) ...

                                    this looks like the conditional is taken one millisecond after time x. But, in fact, x might be 45 and y can be 47 (in the case where millis() had advanced to 46 just after the assignment to x and before the assignment to y).

                                    Reading your feedback, which is very professional indeed and leaves very little room for comment, there are some parts which hint you may not be fully aware of the hardware I'm using, so it's an ArduinoProMini (there's your CamelCase ), so an atmega328p, though I do get your point: you're trying to be cross-compatible and make the codes/language whatever as universally applicable as possible, not just restrict them to this setup...goes to show you know your stuff. Cheers
                                    Exactly. I shouldn't have to have intimate knowledge of your target platform to understand your code. That makes it less portable, less understandable.

                                    If there is something that is intentionally unique about an implementation, you want to draw attention to it -- unless you can reasonably expect readers to know it ahead of time.

                                    For example: "You are parked immediately to the right of another vehicle. So, be sure to ONLY turn the steering wheel hard to the LEFT when moving forward!"

                                    This appears to be exactly backwards as turning the wheel to the left would cause your car's nose to crash into the adjacent vehicle! OTOH, if "you" are driving a forklift, turning the wheel to the RIGHT would actually cause the damage as the ass-end of the truck would crush the adjacent vehicle (cuz forklifts steer from the back; turning RIGHT causes the ass-end to move to the LEFT so the front end heads off to the right.)

                                    If I was writing for a forkllift operator, I wouldn't add this explanation. OTOH, if I had no control over my audience, I'd be obligated to include it lest they ASSUME that I had been mistaken in my initial comment (to steer LEFT).

                                    Comment


                                      Re: 555 countdown timer design question

                                      Originally posted by Curious.George View Post
                                      Lamp hack.txt
                                      OMG it's Z-80 assembly language! You are dating yourself, I did that kind of coding in the 1980's. But single chip MCU's are much easier for the hardware build, and higher level languages like C with library routines make software easier.

                                      Comment


                                        Re: 555 countdown timer design question

                                        After the end of use of z80s or general purpose computers, they used them extensively for ... microcontrollers. I don't think they were that much more difficult for hardware builds but yes they required more chips due to integration. However I don't think all "modern" microcontrollers are well suited for arbitrary high level languages, especially PIC. The assembly for PIC has so many limitations that doing translation from a higher level language that have scope would be quite messy, though I think PIC is still Turing complete.

                                        Now the question is who used HC11's and 8051, those were much more popular as well integrated microcontrollers.

                                        Comment


                                          Re: 555 countdown timer design question

                                          Originally posted by redwire View Post
                                          OMG it's Z-80 assembly language! You are dating yourself, I did that kind of coding in the 1980's.
                                          I deliberately picked an ASSEMBLY language that was easy for folks to understand. Had I written it for a T-11 or Cortex A5, it would have stumped too many. Selecting a single accumulator machine would clutter the code with lots of loads and stores -- and dramatically increased the RAM requirement.

                                          I explicitly opted NOT to use any "current" processor as I wasn't inclined to solve anyone's problem "for free"; they'd have to at least invest the time to understand the code and "translate" it to their MCU of choice. Yet, there are still tools available to let someone "motivated" run/simulate the code if they needed proof of its functionality.

                                          But single chip MCU's are much easier for the hardware build, and higher level languages like C with library routines make software easier.
                                          HLL's complicate the design in ways that would require far too much effort (on my part) to explain. I.e., try supporting multiple tasks in your HLL implementation of choice without also having to write a fleshier multitasking executive -- and then having to explain how THAT works! I invite you to offer such a solution!

                                          You'd also need knowledge of the code generator's capabilities so the multitasking executive knows how much state resides on the stack at any given time -- or, add support for a separate stack for each task, etc. I was very clear that the entire application is included in that code -- no support libraries that are buried in some board's firmware.

                                          Note that there is nothing preventing the pseudocode initially offered from being ported to a HLL environment. But, as it is inherently a multithreaded solution, any such implementation would require illustrating the support (MTOS) required for it, right?

                                          It's silly to resort to tools that are fancier than necessary. Casually throw in a printf() for debugging and be amazed at how dramatically the code increases in size. <grin>

                                          Comment

                                          Working...
                                          X