Displaying Time  to LCD - Page 1
Forum section: electronics / general

author: asadulhuq
author_rank: Contributor
timestamp: August 25, 2020, 04:20:25 am
content: Dear All,I am trying to implement a count down timer with a PIC16F628A. I am using <MikroC pro for PIC> for coding.My code starts with following defines:#define Lo(param) ((char *)&param)#define Hi(param) ((char *)&param)......Also, I have declared variables in my code like:short minutes, seconds, hours;...Also I read from EEPROM like -...Dealy_ms(30);Lo(minutes) = EEPROM_Read(0x12);Delay_ms(30);Hi(minutes) = EEPROM_Read(0x13);Delay_ms(30);Lo(seconds) = EEPROM_Read(0x14);Delay_ms(30);Lo(seconds) = EEPROM_Read(0x14);...Now I need to display two minutes digits and two seconds digits on the LCD in the following format:MM:SS (eg., 30:20).I tried like-Lcd_Chr(1, 8, 'Hi(minutes)');or even, Lcd_Chr(1, 9, 'minutes'+48);But failed to display correct digits.I suppose Lo(minutes) returns 8 bits data. But I do not know how to display that data as a number on LCD!Need assistance.Would you please tell me how to display the minutes and seconds on the LCD as shown above? Thanks.

author: ledtester
author_rank: Super Contributor
timestamp: August 25, 2020, 05:31:14 am
content: This thread might help:https://www.edaboard.com/threads/integer-to-string-convertor-for-mikroc.325338/

author: Ian.M
author_rank: Super Contributor
timestamp: August 25, 2020, 06:27:12 am
content: You cant break up a short into two bytes (char) and get a decimal result. You have to process it as a whole.For a clock, you probably want the string padded with leading zeros, and although one could do that using sprintf() and a carefully chosen format specifier, the printf() family of functions are extremely large and complex, and will probably take up all your code space! The phrase "Using a Sledgehammer to crack a nut" comes to mind.As a lighter weight alternative, see K&R section 3.6 for one possible itoa() implementation (or. You'ld have to tweak it a bit to implement leading zero padding.Also seehttps://download.mikroe.com/documents/compilers/mikroc/pic/help/conversions_library.htmN.B. Number to string functions are commonly called itoa() because they are the inverse of the standard library function atoi(), but there is no itoa() function in the ANSI C standard.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 25, 2020, 08:41:39 am
content: Do you need do go over 59 seconds or 59 minutes ? If not, than a simple uint8_t is enough to store the values and you don't need the "Lo" and "Hi".Also, I see your code reads twice Lo(seconds). Is it normal ?Then, a single "divide by 10" gives you the first digit:Code:uint8_t d1,d2,c1,c2;uint8_t minutes;minutes = 59; // just an exempled1 = minutes / 10; // -> 5;Modulo give you the second digit:Code:d2 = minutes % 10 ; // -> 9Then, to obtain the characters for the display, simply add '0'Code:c1 = d1 + (uint8_t)'0'; // code for digit '5'c2 = d2 + (uint8_t)'0'; // code for digit '9'Of course, when you do a division and then a modulo, you do more of less twice the same thing and that's time consuming. It's better to replace the modulo by a multiplication and a subtraction (multiplication is done by hardware and is fast):Code:d2 = minutes - (d1 * 10); // equivalent to d2 = minutes % 10Correction:16F628 has no hardware multiplier

author: asadulhuq
author_rank: Contributor
timestamp: August 25, 2020, 09:15:36 am
content: ggchab (on: 25-Aug-2020 at 08:41:39 am),Thanks a lot. Probably my problem will be solved using your procedure.BTW, <Also, I see your code reads twice Lo(seconds). Is it normal ?>, that was a copy paste issue.Thanks again.

author: asadulhuq
author_rank: Contributor
timestamp: August 25, 2020, 12:16:09 pm
content: ggchab<<Your method works. I am implementing a count down timer. When I start the timer the display value always shows the remaining time. This is good and needed. However, I also want to display the set up time in the 1st line on the LCD. (In the 2nd line 'remaining time' while the timer is running, which is implemented now). Do you have any idea of how to display the setup time from the EEPROM (this time will not change untilI I write a new setup time in EEPROM)? You may have a look on the complete timer code bellow. Thanks.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 25, 2020, 02:58:13 pm
content: I am not sure I understand what you want to do because there should be no difference between displaying the value of a counter or a fixed value ?I don't know why, but I could not download your code.

author: asadulhuq
author_rank: Contributor
timestamp: August 25, 2020, 03:28:09 pm
content: ggchab<<Now you can download. Please try again. I want that Lcd line 1 will show like "Preset on time: 30 minutes' once power is aplied or start button is pushed. However, the Line 2 will show 'Remaining Time' like 30.. 29...28....3..2..1..0.. minutes and the relay will be OFF. Preset time will not change untill it is adjusted.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 25, 2020, 03:48:57 pm
content: I still don't understand what is your problemWhy not using the functionCode:Lcd_Chr(1,1,"some text")to write what you want on the first line of the LCD ?

author: asadulhuq
author_rank: Contributor
timestamp: August 25, 2020, 03:56:24 pm
content: ggchab<<I want to adjust that 'Preset time' with push button switches when required. I want to use this timer to control my water heater. In winter the preset time will be 50 minutes for example. In summer it will be 15 minutes. Also, day time preset will be lower than the night time preset ON time. So, it will be convenient to display the current preset time.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 25, 2020, 04:40:23 pm
content: I see you have commented the "display_time();" after the LCD initialization. You may re-use this function to display the initial time on the first line if you simply add a parameter to the function:Code:// Displays minutes and seconds on line 'line' (1 or 2) at position 8void display_time(unsigned short line) {md1 = ......Lcd_Out(line,8,"[");...}Then, in your code, call the function and specify the line:Code:display_time(1); // Displays minutes and seconds on line 1I think there are some big errors in your code, especially when reading data from the eeprom: with the "Lo", "Hi", you assign 16 bit values to 8 bit variables (unsigned short). You are lucky this is working: when you initialize "seconds", you probably overwrite the content of minutes, ...You don't need 16 bit values to store seconds, minutes, hours if they are limited to 59,59, less than 255.So, use only one eeprom byte for each variable:Code:hours = EEPROM_Read(0x10); //Load from eepromDelay_ms(30);minutes = EEPROM_Read(0x11);Delay_ms(30);seconds = EEPROM_Read(0x12);Same thing when you write the eeprom:Code:EEPROM_Write(0x12,seconds);Delay_ms(50);EEPROM_Write(0x11,minutes);Delay_ms(50);EEPROM_Write(0x10,hours);Delay_ms(50);

author: asadulhuq
author_rank: Contributor
timestamp: August 25, 2020, 04:57:07 pm
content: ggchab<<Lot of thanks again. I will try to apply your recommendation on my code and surely I will let you know the result.But what will happen to the top 2 lines of the code? Seems that these are MikroC inline routines. They may be found in MikroC library.#define Lo(param) ((char *)&param)#define Hi(param) ((char *)&param)Don't I need to modify those 2 lines? I do not understand these 2 lines well. Could you please explain the meaning of the lines? Or is there a way to simplify these lines?Actually, am new to the programming world. My hobby is Analog electronic circuit and system design. In this Covid time I stay home. So, I started microcontroller programming to utilize this time. It is clear that you are expert in programming. Thank you for your nice and clear explanations.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 25, 2020, 05:31:39 pm
content: You don't need those 2 lines. They are used to initialize a 16 bit variable from two 8 bit values. They "transform" a 16 bit variable into an array of 2 char, each char then being initialized with a 8 bit value.&param -> pointer to 'param' that is a 16 bit variable(char*) tells the compiler the pointer is no longer a pointer to a 16 bit value but to a 8 bit valueThis pointer can also be seen as an array (an array is a pointer to a list of "things")So, ((char*)&param) is the first element of the array and, in fact, the 8 least significant bit of 'param' and ((char*)&param) is the second element of the array, the 8 most significant bit of 'param'.But all this might dependent on how the compiler stores a 16 bit value in memory...

author: ggchab
author_rank: Frequent Contributor
timestamp: August 25, 2020, 05:37:15 pm
content: QuoteThe more you will learn, the more you will have fun

author: asadulhuq
author_rank: Contributor
timestamp: August 26, 2020, 02:17:03 am
content: Thanks for the explanation of the top two lines. I shall omit those lines and let you know the result. Also, I shall modify my EEPROM reading and writing sub-routines. Today I have to conduct the weekly zoom online class for my undergraduate students. After completing the class I will come back to my programming session.

author: asadulhuq
author_rank: Contributor
timestamp: August 26, 2020, 04:26:53 pm
content: ggchab (Yesterday at 05:31:39 pm)<<Thank you for all your recommendations. The timer is working correctly as required. I have attached the new <timer.c>. A video of the Proteus simulation, 65MB .mp4 file is in the following link.BTW, would you give me an idea how to up/down the ON time value using 2 push buttons when the timer is ON?Please note the timer itself is a count down timer. The beginning time will be a preset time which is loaded from the EEPROM.https://drive.google.com/drive/folders/1o7E6cmL4AFLufr_B3Mo1qqayQgNUmsks?usp=sharingThanks.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 26, 2020, 07:35:11 pm
content: Why not reuse the existing time edition procedure :Always test the buttons, not only when (start == false). But you still have to test the 'start' flag to take some decisions:- if (start == false) save time in eeprom- if (start == true), stop the interrupts while updating the variables (to avoid any conflict with the interrupts function)something like this (not tested - also, I don't know what variable 'a' is doing)Code:if (!SEC_sw || !MIN_sw || !HRS_sw){Delay_ms(200);if (!SEC_sw || !MIN_sw || !HRS_sw){Delay_ms(50);if (start)INTCONbits.T0IE = 0; // Stops TMR0 interrupts (I don't know if that's the correct syntax)a = 1;if (!SEC_sw) { // SEC buton is PRESSEDif (seconds < 59) seconds++;else seconds = 0;}if (!MIN_sw) { // MIN buton is PRESSEDif (minutes < 59) minutes++;else minutes = 0;}if (!HRS_sw) { // HRS buton is PRESSEDif (hours < 99) hours++;else hours = 0;}if (!start) // Save new time if timer is not runningWrite_EEPROM();elseINTCONbits.T0IE = 1; // otherwise, re-enable TMR0 interrupts}}Something else:Each time you modify a time variable, you write the new time into the eeprom. This can make a lot of unnecessary writes ! I would add a delay (a few seconds) before writing the eeprom. This can be done with the help of your existing TMR0 interrupts function:- in your main loop: add a new counter (C) that you reset to 0 each time you update one of the time variables- add a flag (F1) that you reset to false each time you update one of the time variables- add a flag (F2) that you set to true each time you update one of the time variable and (start == false). So, you know time must be saved.- in the interrupts function, increment the counter C (about every ms). When it reaches a specific value (ex.: 5000 for about 5s), set the flag F1 to true- in your main loop, when both F1 and F2 are true, write the eeprom and then reset F2When you modify the counter and F1, you should disable TMR0 interrupts to avoid any strange behavior if an interrupt occurs while variables are updated!Just some ideas. They might have to be developed a bit more.

author: asadulhuq
author_rank: Contributor
timestamp: August 27, 2020, 03:27:30 am
content: ggchab<<Thanks for your comments on the timer. You are correct about writing to EEPROM every time I push a time setting switch. I was thinking about that. The program surely needs lot of fine tuning. I will try to accommodate your ideas regarding writing to EEPROM. However, did you notice what my new modification plan?My current flow chart of the device (in short):DC Power ON to Timer -> Heater ON with the Preset time settings loaded from EEPROM -> Count down -> Stop Heater if Time reaches to 0.I want to modify the flowchart to a new one as follows:DC Power ON to Timer -> Heater ON with the Preset time settings loaded from EEPROM -> Count down -> [increase or decrease ON time duration (if required) with push buttons while the timer is continuing counting down! (New stop time set on the go!)] -> Stop Heater (if) new set Time reaches to 0.Is above flowchart implementable? I mean, modifying time without stopping the heater and set a temporary new stop time. This is required since some family members will like more or less hot water than the preset hot water! They can increase or decrease the time with the push buttons for him/herself on the go. Also, this new personal settings will not be stored in to EEPROM. Please note, it is not good to stop the heater and then set a new time and start it again . I say this because the heater draws about 10 Amp on 220V. It is not good to ON/OFF such a large current device many times! I am not sure whether you understand what I say here!Would you say something about my new flowchart? Thanks.NB: You may please have a look on my current analog water heater count down timer video on my google drive share drive (115 MB).https://drive.google.com/drive/folders/1o7E6cmL4AFLufr_B3Mo1qqayQgNUmsks?usp=sharing

author: ggchab
author_rank: Frequent Contributor
timestamp: August 27, 2020, 07:31:59 am
content: That's what my proposal is supposed to do: while the timer is running, the variables 'hours', 'minutes' and 'seconds' may be dynamically modified with the buttons but are not saved in the eeprom. The (updated) remaining time will continue to be displayed on the second line of the LCD

author: asadulhuq
author_rank: Contributor
timestamp: August 27, 2020, 08:04:47 am
content: ggchab<<Thanks. I will change my code. Also, I have thought that I will remove hours option, since my water heater doesn't require more than 60 minutes ever. Seconds will be there in display to show that timer is counting down, but no push button for setting seconds! In addition to that current hours button will be used with the minutes button to push simultaneously to decrease seup time (minutes only). This will make settingsconvenient. Setup Minutes ++, or even -- ! Ultimately, the timer will be a 99 minute timer. Please leave a comment about my new setting method. Thanks again. I learned many aspects of Microcontroller programming from you.I am a teacher (professor) in the University of Dhaka, in Bangladesh. My department is Electrical Engineering (Research field is Digital Signal Processing). I am 60 years old. Did you imagine my age!!BTW, did you watch the video of my Analog Timer?

author: ggchab
author_rank: Frequent Contributor
timestamp: August 27, 2020, 09:24:17 am
content: Always good to have options to change a counter back and forth !Glad I could help youNice way to reuse a PC power supply caseYes, I thought you were younger

author: asadulhuq
author_rank: Contributor
timestamp: August 27, 2020, 09:36:01 am
content: ggchab<<I don't know any thing personal about you. I understand you are a good and kind person. Also you are an excellent programmer. By the way, where are you from? Thanks.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 27, 2020, 10:25:38 am
content: I live not far from Namur, a small city in Belgium.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 27, 2020, 10:28:09 am
content: Some more pictures ...

author: asadulhuq
author_rank: Contributor
timestamp: August 28, 2020, 08:25:09 am
content: ggchab<<You are lucky since you are living in a beautiful country. At the same time your city photos are eye catching. I shall also post some pictures of my city later. Thank you.

author: ggchab
author_rank: Frequent Contributor
timestamp: August 28, 2020, 09:42:59 am
content: Done with my OnePlus 7T. We had a nice summer, this yearEven a bit too hot for us !

author: asadulhuq
author_rank: Contributor
timestamp: August 28, 2020, 04:17:41 pm
content: ggchab<<Hi there.I am sorry that I am killing your time.Would you please give me an idea how to decrease time setting values? You know the program works correctly when time setting value is increased using push button. But when I try to decrease time value it does not decrease even I press push buttons (MENU_sw+HRS_sw). That means the time settings can go ++ ; bot can not go --.A partial relevant code segment is like the following-///////////////////////////////////////////////////////////////////////if (start) { // If timer is running//INTCON.T0IF = 0;if ((!MIN_sw) || (!HRS_sw)){Delay_ms(100);if ((!MIN_sw) || (!HRS_sw)){//EEPROM_Write(0x16,1);//Delay_ms(50);a = 1;if ((!MENU_sw) && (!MIN_sw)) { // MENU+MIN buttons are PRESSED, minutes value decreasesif (minutes > 0) minutes--; // This does not work. The value does not change at all !!else minutes = 0;}if (!MIN_sw) { // MIN button is PRESSED minute value increases (this works)if (minutes < 59) minutes++;else minutes = 0;} .........Current complete timer code is attached for your perusal. Please see from Line# 304 to 344.Do you notice any mistake in the program code?Thanks again.

author: asadulhuq
author_rank: Contributor
timestamp: August 28, 2020, 04:55:38 pm
content: ggchab<<How could you shoot such a wide area with the OnePlus 7T? Interesting. I have to see the specs of the device! I am a poor man and old at the same time. I am still using Samsung Galaxy S8!

author: ggchab
author_rank: Frequent Contributor
timestamp: August 28, 2020, 07:34:47 pm
content: I think that because as soon as minutes-- is executed, minutes++ is also executed because (MIN_sw == 0) is also true in the next test!minutes should only be incremented when (!MIN_sw)&&(MENU_sw)Code:if ((!MENU_sw) && (!MIN_sw)) { // MENU+MIN buton is PRESSEDif (minutes > 0) minutes--;else minutes = 0;}if ((MENU_sw) && (!MIN_sw)) { // MIN buton is PRESSED ... AND MENU IS NOT PRESSEDif (minutes < 59) minutes++;else minutes = 0;}

author: ggchab
author_rank: Frequent Contributor
timestamp: August 28, 2020, 07:44:22 pm
content: I love my OnePlus 7TI bought it end of last year.My previous smartphone was a Galaxy S6. But it was getting slower and slower and I had to charge it several times during the day ! I could not believe my eyes when I saw the responsiveness of the OnePlus.I hope 60 is not that old. I am 58

author: asadulhuq
author_rank: Contributor
timestamp: August 29, 2020, 01:41:58 am
content: ggchab<<"I hope 60 is not that old. I am 58."very strange! I thought programming was for younger people.Thanks. I will try your suggestion.

author: asadulhuq
author_rank: Contributor
timestamp: August 29, 2020, 03:12:07 am
content: ggchab<<Good morning from my end.Excellent!! You are very correct. Now -- and also ++ work perfectly. Lot of thanks.BTW, may I ask about your profession? Are you a professional programmer?

author: ggchab
author_rank: Frequent Contributor
timestamp: August 29, 2020, 08:07:12 am
content: I have a scientific background. I bought a TRS-80 when I was a student. I learned Basic and Z80 assembly.I have always worked in small IT services (help desk, system administrator, ...) where everyone has to to everything. So, I have never been a specialist in any domain but know a bit of many things ...About 15 years ago, I discovered micro-controllers and made some little hobbyist projects based on 16F84, in assembly. Then I moved to PIC18F ... still in assembly. Then, almost nothing. More recently (after some experiments with Arduino to help my son in his studies), I decided to do some projects with graphic LCD and moved to 16 bit PIC and, of course, I switched to C. That's a lot of fun

author: asadulhuq
author_rank: Contributor
timestamp: September 06, 2020, 06:52:17 am
content: ggchab<<Hi there,I have completed a prototype of the timer on breadboard. Seems that it is working. Thanks for your assistant for making it a reality! If you have some time you may please visit the following link where a small video clip of the project resides.https://drive.google.com/drive/folders/1gEundQwoAl1aE1_OfRxhJYHAy4HWFR_j?usp=sharing

author: ggchab
author_rank: Frequent Contributor
timestamp: September 06, 2020, 03:54:42 pm
content: That seems to work wellDo you plan to make a PCB ?

author: asadulhuq
author_rank: Contributor
timestamp: September 06, 2020, 06:07:39 pm
content: ggchab<<Hi there,Eventually, I intend to make the PCB. I like EasyEda. However, currently EazyEda PCBs can not reach Bangladesh in time, may be communication with China has not restored as it was before. Also, Bangladesh post offices do not work well due to Covid 19. In Bangladesh, PCB manufacturing quality is not acceptable to me. So, I am not sure what to do.Also, I tried to design the PCB with Proteus itself. Proteus is a good simulation software but in case of designing PCBs, Proteus 8 is not that good. Many footprints are not readily available in Proteus. For example some popular relay footprints are not available. In contrast, EasyEda has a big collection of devices and corresponding foot prints.So, about PCB, I am not sure what to do. May be I can make myself one (not up to the mark!).Also, a good project box will be required. It is difficult to get project box parts due to Covid here. May be, I can find PC power supply boxes like before. But that may look odd! By the way, I shall attach a SonOFF Pow device with the timer. (Just for your information, Sonoff devices are smart but can not do simple thing like a count down timer!).Thanks.

author: Lindley
author_rank: Regular Contributor
timestamp: September 06, 2020, 07:42:05 pm
content: Hi,Are you just wanting one pcb for yourself or going into production ?Once a design has been proved in simulation its always best to build a fully soldered prototype, usually just hand wired onto Vero or Dot Matrix board, so you can run the circuit for some days to fully prove it works as intended.If done neatly it can serve as your final build, as I often do for my own projects, but if going into production you need to prove your design 100% before ordering a lot of PCBs.Know quiet a few folk who rush to get a pcb done, only to find the circuit does not work becuase of their errors, so end up hacking loads of tracks !

author: asadulhuq
author_rank: Contributor
timestamp: September 07, 2020, 02:17:47 am
content: I am not going for a commercial production. I shall make one for home use. This is purely a hobby project. It will be a pleasure to use things made by myself. Nothing more than that.You are 100% correct about veroboard implementation. Currently I am using an analog count down timer with my Geyser (home water heater). That is in use for about last 1 year without any malfunction (you have seen it sitted in a PC power supply box!). That timer is built on a veroboard and working for over 1 year.So, your advice is correct. A pcb is not essential for one piece.I already ordered veroboards like you have shown in your post. Thanks for the photo.But, I need a project box. Currently I can get only a PC power supply box!Thanks again.

author: Ian.M
author_rank: Super Contributor
timestamp: September 07, 2020, 05:47:17 am
content: Before plastic instrument cases became ubiquitous, hobbyists built wooden boxes for their projects. I'd be very surprised if you cant get the materials to build such boxes locally, or even find a craftsman who can build you nicer boxes than you ever could at a reasonable price. Its often easiest to use sheet metal for the front panel for ease of mounting controls etc. which are usually only suited to a limited panel thickness.