I've found an inconsistency with the millis() function. I can reproduce the problem on a program for the 16F1829.
My Wife is working this holiday weekend so I've been re-writing portions of my Binary, Decimal and Hexadecimal calculator. This uses millis() to provide the timing for starting an animated "screensaver". If I compile this program using Great Cow BASIC (0.99.02 2022-02-17 (Windows 64 bit) : Build 1087) the timing provided by millis() is lengthened by a substantial amount, a two minute delay is stretched to about twenty five minutes.
Compile the same program, using the same compiler but targeting the 18F15Q40 and the millis() timing is accurate.
Changing the compiler to 0.98 (and also changing the LCD.h library to the 0.98 one) and compiling for the 16F1829 returns the timing back to the correct two minutes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Here is the calculator code I've just uploaded to the finished projects section.
If you compile it for the 18F15Q40, the line which sets the timeout for the screensaver works correctly when set to 120000 (two minutes) compile the same program but change the chip to the 16F1829 and the timeout needs to be reduced to 13000 (which should be thirteen seconds) gives the timeout of two minutes.
'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'Note there is an error within the compiler version 0.99 which requires this 'to be set to a much lower value for the 16F1829
#DefineTimeOut120000' ScreenSaver timeout in mS currently 120 Seconds, or two minutes'#Define TimeOut 13000 ' ScreenSaver timeout in mS currently 120 Seconds, or two minutes'$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
The error has also shown itself in an unrelated program for the 16F1829 using millis() at work. I'd made over fifty devices and sold quite a few before it was spotted. Rats!
It isn't an urgent problem as such, now I'm aware of it. I only posted the message, partly to (again) remind me and partly (again) to make others aware of it.
If nobody mentions these things, everybody is running blind.
It wasn't the first thing I looked for when newly compiled code didn't work. I spent some time with a code comparator trying to see if I'd made any changes that could have caused problems. I slowly became aware that the last batch I'd made was prior to me updating the compiler. Only then did I try rolling back to an earlier version of that.
As a temporary fix, I can just scale the timeouts by multiplying them by .11 (or so) which is good enough for the accuracy I need.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Try this adding this #DEFINE Millis_Default_Timer0_value 131 to the 16F code with the correct value for TimeOut
Then adapt the Millis_Default_Timer0_value until it works as expected. I am thinking the oscillator on the 16F is not actually running at the mHz is should be.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
#DEFINE Millis_Default_Timer0_value 131
#Define TimeOut 104000
' ScreenSaver timeout in mS currently 120 Seconds, or two minutes
Using the default timer definition and a timeout value of 104000 gives near identical run times. I've got one 16F1829 version and one 18F15Q40 version next to me (the 18F15Q40 I normally use at work...) and the screensaver is starting almost at the same time from a cold start.
Last edit: mkstevo 2022-04-16
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Wife home from work now, so all experimentation over for today! Don't think I've given up!
What's that you say Dear?
Yes Dear.
I'm putting it away now Dear.
I am listening Dear.
No, I heard every word you said.
Yes, I'm recycling the tortoise now Dear.
What? We've got a tortoise? And you want me to recycle it?
Well, perhaps not every word Dear...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Can you test something basic for me? I am puzzled by what is actually happening.
Take demo file C:\GCstudio\GreatCowBASIC\demos\millis_solutions\16f1938_1s.gcb and change the chip name, change the LED port to something that works for you. Program - does the LED flash every second ? If yes, then, we need to look at the program you have for the 16f.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
#chip 16F1829,32 ' Declare the Target Processor and Speed#option explicit ' Require Explicit declaration of Variables#include <millis.h> ' Include the Library#define LED PORTB.6 ' Define the LED Pin - Pin 11#define LEDRate 1000 ' Flash rate in mS' SetupDirLEDOut' Make the LED Pin an OutputLED=0DimCurMs,LstMsasword' declare working variables' Main 'Thislooprunsoverandoverforever.LstMs=0CurMs=0' Main 'Thislooprunsoverandoverforever.DoCurMs=millis()ifCurMs-LstMs>=LEDRatethen' required Time has ElapsedLED=!LED' So Toggle state of LEDLstMs=CurMs' And Record Toggle TimeendifLoopEnd
I had suspected it was related to the LCD.
This flashes once every 13 seconds or so:
#chip 16F1829,32 ' Declare the Target Processor and Speed#option explicit ' Require Explicit declaration of Variables#include <millis.h> ' Include the Library#Define LCD_IO 4#Define LCD_SPEED FAST#Define LCD_NO_RW'Port assignments#Define LCD_RS PortA.0#Define LCD_Enable PortA.1#Define LCD_DB4 PortA.2#Define LCD_DB5 PortC.0#Define LCD_DB6 PortC.1#Define LCD_DB7 PortC.2#define LED PORTB.6 ' Define the LED Pin - Pin 11#define LEDRate 1000 ' Flash rate in mS' SetupDirLEDOut' Make the LED Pin an OutputLED=0DimCurMs,LstMsasword' declare working variables' Main 'Thislooprunsoverandoverforever.LstMs=0CurMs=0' Main 'Thislooprunsoverandoverforever.DoCurMs=millis()ifCurMs-LstMs>=LEDRatethen' required Time has ElapsedLED=!LED' So Toggle state of LEDLstMs=CurMs' And Record Toggle TimeendifPrintCurMsLoopEnd
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have been having problems with this, and I've been having to compile using an older version of GCB (0.98.07 I think).
Today has been the first day in a while when I was able to sit and apply myself to researching and engineering a work around.
I decided to try and recreate a similar background function that I could use to generate a 1mS time interval. Following some of an online MicroChip tutorial and the GCB help pages whilst shamelessly stealing from the original millis() I came up with a very rough (and barely ready) solution that does work in GCB V99.
I should point out that this function will (or at least may) only work with a PIC, a PIC that at least has a 16bit Timer1, and is running at 32MHz or 64MHz. That covers most devices I use so that is where I stopped.
I tried to do away with as much as possible of the original millis() and get the function back to the minimum possible required for it to work.
Firstly, here is the code for a file that should be named as MyMillis.h:
DimMyCtr_AsLong#StartUpMyStartTimerSubMyStartTimerOnInterruptTimer1OverflowCallMyCtr_Int_HdlrLetMyCtr_=0LetMyMillis=0'The timing can be altered here or altered in SetTimer'Only 64MHz or 32MHz clocks are catered for.'^^^^^^^^^^^^ Don't adjust for both! ^^^^^^^^^^^^^^IfChipMHz=64ThenInitTimer1Osc,PS1_2'Prescaler for 64MHzEndIfIfChipMHz=32ThenInitTimer1Osc,PS1_1'Prescaler for 32MHzEndIfSetTimer_MillisStartTimer1EndSubSubMyCtr_Int_HdlrSetTimer_Millis' Reset Inital Counter valueLetMyCtr_=MyCtr_+1EndSubFunctionMyMillisasLongIntOffLetMyMillis=MyCtr_IntOnEndFunctionSubSetTimer_Millis'The timing can be altered here or altered in MyStartTimer'Only 64MHz or 32MHz clocks are catered for.'^^^^^^^^^^^^ Don't adjust for both! ^^^^^^^^^^^^^^'If ChipMHz = 32 ThenSetTimer1,57000'Preload Timer for 32MHz'End If'If ChipMHz = 64 Then' SetTimer 1, 45000 'Preload Timer for 64MHz'End IfEndSub
Here is a small program that uses it, with the option of using the original millis():
#Chip18F15Q40,64'#Chip 16F1829,32#OptionExplicit#Include<MyMillis.h>#DefineUseMyMillis'#Include <Millis.h>'#Define UseOriginalMillis#DefineLCD_IO4#DefineLCD_SPEEDFAST#DefineLCD_NO_RW'Port assignments#DefineLCD_RSPortA.0#DefineLCD_EnablePortA.1#DefineLCD_DB4PortA.2#DefineLCD_DB5PortC.0#DefineLCD_DB6PortC.1#DefineLCD_DB7PortC.2#DefineLEDPortB.6' Define the LED Pin - Pin 11#DefineLEDRate1000' Flash rate in mSDirLEDOut' Make the LED Pin an OutputDimMyLongAsLongDimMySecondsAsWordDimHighValAsLongLetHighVal=0LetMyLong=0LetMySeconds=0LetLED=0Do#IfDefUseMyMillisLetMyLong=MyMillis()#EndIf#IfDefUseOriginalMillisLetMyLong=Millis()#EndIfIfMyLong>HighValThenLetHighVal=MyLongEndIfIfMyLong>=LEDRatethen' required Time has ElapsedLetLED=!LED' So Toggle state of LEDLetMySeconds=MySeconds+1CLSLocate1,0PrintMySeconds#IfDefUseMyMillisLetMyCtr_=0#EndIf#IfDefUseOriginalMillisLetMsCtr_=0#EndIfEndIfLocate0,0#IfDefUseMyMillisPrintMyMillis()#EndIf#IfDefUseOriginalMillisPrintMillis()#EndIfLocate0,8PrintHighValLoopEnd
For a 16F1829:
Using the MyMillis file (as above) the LED changes state at close to 1 second.
Using the original millis() the LED changes state at around 10 seconds.
I didn't have time to try the 18F15Q40 with the original millis() but I did using MyMillis and it too runs at 1 second for each change of the LED.
One thing that did puzzle me was that initially I had the timer (millis) routines in the same file as the demonstration program. Once I got it working, I then moved those into a separate header file, with the intention of making it (nearly) seamlessly available to the many other programs I have used the original in. After I moved them into a separate file, the one second interval was never reached. Confused, I moved them back and they failed to work when inline. I then looked at the value returned from MyMillis and could see that it counted to 255 then stopped. Never reaching the 1000 interval. Why? The only change I had made was to the declaration of "MyCtr_" from the top of the program file and into the MyStartTimer sub. If that declaration was moved out of the sub and back into the main program, everything worked. Move it back into the sub and it only works as a byte variable.
This works:
DimMyCtr_AsLong#StartUpMyStartTimer...'Rest of program follows
This treats the MyCtr_ as a byte variable:
SubMyStartTimerDimMyCtr_AsLongOnInterruptTimer1OverflowCallMyCtr_Int_Hdlr...'Rest of Sub follows
That may not point to what may be causing the original millis() to not work, but it is repeatable.
At one point if I added 75mS delay to each section of LCD printing commands, the original millis() worked 'properly' on the 1829. Yet if I set MyLong to zero with the command:
Let MyLong = 0
it stopped working.
All very strange for someone who is not a natural programmer...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Both worked here with a 1s pulse width on the scope, noting that I have tested a 18F16Q40 not a 18F15Q40. Please change the chip name and test on your chips.
I am using GCASM not PIC-AS (as I assumed that you do not have PIC-AS installed). The ASM header (for version info is) Program compiled by Great Cow BASIC (0.99.02 2022-04-27 (Windows 64 bit) : Build 1113) for Microchip MPASM/MPLAB-X Assembler
To understand the issue I need the two chips baselined under these test conditions. These test conditions are very easy - take the code and use - report back, Pass or fail.
Give me an hour or so and I'll check those out.
To clarify, I am using 0.99.01 (which when I last checked was the latest version available as a minimal or compiler only install).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have improved the 'MyMillis' file I listed above. It will now provide a 1mS "tick" at frequencies of 64, 48, 32, 16, 8, 4, 2 and 1MHz. It will throw an error should other frequencies be set. The timer pre-load values are now more accurately calculated. Previously the timing was set by me adjusting the pre-load value until it looked about right! I've now sat and worked them out properly.
It will only work for a PIC and will not complain if any other device is selected.
I have also added a ZeroMyMillis sub which as the name might suggest, resets the counter(s) to zero.
DimMyCtr_AsLong#Script'Only 64MHz, 48MHz, 32MHz, 16MHz, 8MHz, 4MHz, 2MHz and 1MHz clocks are catered for.FrequencyIncluded=0'Only 64MHz, 48MHz, 32MHz, 16MHz, 8MHz, 4MHz, 2MHz and 1MHz clocks are catered for.'The calculation for this value can be simplified:'Assuming a 1mS interval is required (which it is)'Take the frequency of the device and divide it by 1000,'64MHz becomes 64,000'48MHz becomes 48,000'32MHz becomes 32,000'16MHz becomes 16,000' 8MHz becomes 8,000' 4MHz becomes 4,000' 2MHz becomes 2,000' 1MHz becomes 1,000'Divide this value by 4 as each program cycle takes 4 clock cycles'The result from this should then be deducted from 65,355'finally, add one to the answer'(it takes a count of 65,355 + 1 to overflow the timer)'Now we have the value for the Pre-load used by SetTimer.'Working these values out will give the correct values for the commonest frequencies'to give a 1mS tick using a pre-scaler of 1:1IfChipMHz=64ThenFrequencyIncluded=1'64,000 / 4 = 16,000'65,535 - 16,000 = 49,535'49,535 + 1 = 49,356MyPreLoad=49356'Preload Timer for 64MHzEndIfIfChipMHz=48ThenFrequencyIncluded=1'48,000 / 4 = 12,000'65,536 - 12,000 = 53,535'53,535 + 1 = 53,536MyPreLoad=53536'Preload Timer for 48MHzEndIfIfChipMHz=32ThenFrequencyIncluded=1'32,000 / 4 = 8,000'65,535 - 8,000 = 57,535'57,535 + 1 = 57,536MyPreLoad=57536'Preload Timer for 32MHzEndIfIfChipMHz=16ThenFrequencyIncluded=1'16,000 / 4 = 4,000'65,535 - 4,000 = 61,535'61,535 + 1 = 65,536MyPreLoad=61536'Preload Timer for 16MHzEndIfIfChipMHz=8ThenFrequencyIncluded=1'8,000 / 4 = 2,000'65,535 - 2,000 = 63,535'63,535 + 1 = 63,536MyPreLoad=63536'Preload Timer for 8MHzEndIfIfChipMHz=4ThenFrequencyIncluded=1'4,000 / 4 = 1,000'65,535 - 1,000 = 64,535'64,535 + 1 = 64,536MyPreLoad=64536'Preload Timer for 4MHzEndIfIfChipMHz=2ThenFrequencyIncluded=1'2,000 / 4 = 500'65,535 - 500 = 65,035'64,035 + 1 = 64,036MyPreLoad=64036'Preload Timer for 2MHzEndIfIfChipMHz=1ThenFrequencyIncluded=1'1,000 / 4 = 250'65,535 - 250 = 65,285'64,285 + 1 = 64,286MyPreLoad=65286'Preload Timer for 1MHzEndIfIfFrequencyIncluded=0ThenError"MyMillis.h reported: Invalid frequency of "ChipMHz"MHz"Error"Only 64MHz, 48MHz, 32MHz, 16MHz, 8MHz, 4MHz, 2MHz and 1MHz clocks are catered for."EndIf#EndScript#StartUpMyStartTimerSubMyStartTimerOnInterruptTimer1OverflowCallMyCtr_Int_HdlrInitTimer1Osc,PS1_1'Prescaler for 1:1ZeroMyMillisEndSubSubMyCtr_Int_HdlrSetTimer_Millis' Reset Inital Counter valueLetMyCtr_=MyCtr_+1EndSubFunctionMyMillisAsLongIntOffLetMyMillis=MyCtr_IntOnEndFunctionSubSetTimer_MillisSetTimer1,MyPreLoadEndSubSubZeroMyMillisStopTimer1LetMyCtr_=0LetMyMillis=0SetTimer_MillisStartTimer1EndSub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Yes indeed I am masking the root cause. Unfortunately I'm not clever enough to figure out the root cause and I have a few programs that make use of the millis() function that I have to program 10-20 at a time, each week. I have been cross compiling some products with the older version of the compiler (where I have to use the 16F1829), some with the newer (where I have to use the 18F15Q40). Remembering to do so, and which to use for which program has kept me on my toes. I tried to re-write much of the code to cater for both but the delays are so inconsistent I couldn't get close to timing parity.
My solution is a major fudge, but it at least gives me a working set of code that caters for both devices. Having renamed the original file to stop me from using it by mistake, I can simply refer to my replacement and go.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I bad assumption to make. If the compiler is not correctly operating on this simply capability then you may run into other issues with other capabilities.
I am concerned that the oscillator or interrupts are not working as expected.
Please complete the two tests as provided. You have the errant chip not me.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The 'base' demo works correctly for the 16F1829. (I don't have a 15Q40 at home)
As soon as I try to use the LCD within the loop, it stops working at the normal speed.
This program flashes the LED at about once every ten seconds:
#chip16F1829' Declare the Target Processor and Speed#optionexplicit' Require Explicit declaration of Variables#include<millis_do_not_use.h>' Include the Library#DefineLCD_IO4#DefineLCD_SPEEDFAST#DefineLCD_NO_RW'Port assignments#DefineLCD_RSPortA.0#DefineLCD_EnablePortA.1#DefineLCD_DB4PortA.2#DefineLCD_DB5PortC.0#DefineLCD_DB6PortC.1#DefineLCD_DB7PortC.2#DefineLEDPortB.6' Define the LED Pin - Pin 11#DefineLEDRate1000' Flash rate in mSPrintLstMs' SetupDirLEDOut' Make the LED Pin an OutputLED=0DimCurMs,LstMsasword' declare working variables' Main ' This loop runs over and over forever.LstMs=0CurMs=0' Main ' This loop runs over and over forever.DoCurMs=millis()PrintCurMsifCurMs-LstMs>=LEDRatethen' required Time has ElapsedLED=!LED' So Toggle state of LEDLstMs=CurMs' And Record Toggle TimeendifLoopEND
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Immediately after the "Print CurMs" line, the LED again flashes at very close to once per second.
So this works:
#chip16F1829' Declare the Target Processor and Speed#optionexplicit' Require Explicit declaration of Variables#include<millis_do_not_use.h>' Include the Library#DefineLCD_IO4#DefineLCD_SPEEDFAST#DefineLCD_NO_RW'Port assignments#DefineLCD_RSPortA.0#DefineLCD_EnablePortA.1#DefineLCD_DB4PortA.2#DefineLCD_DB5PortC.0#DefineLCD_DB6PortC.1#DefineLCD_DB7PortC.2#DefineLEDPortB.6' Define the LED Pin - Pin 11#DefineLEDRate1000' Flash rate in mSPrintLstMs' SetupDirLEDOut' Make the LED Pin an OutputLED=0DimCurMs,LstMsasword' declare working variables' Main ' This loop runs over and over forever.LstMs=0CurMs=0' Main ' This loop runs over and over forever.DoCurMs=millis()PrintCurMsWait75mSifCurMs-LstMs>=LEDRatethen' required Time has ElapsedLED=!LED' So Toggle state of LEDLstMs=CurMs' And Record Toggle TimeendifLoopEND
With the only change being the additional 75 mS delay.
In an earlier reply you suggested changing the default timer value. In that particular program (Bin-Hex-Dec Calculator) changing that worked reasonably well. In my programs at work, it failed to have any effect. It is this type of confusion that led me to try and come up with something rather more consistent for me.
If I use that example above (with or without the 75 mS delay included) using the MyMillis program I added above, it works completely as expected, with or without any LCD print statements or extra delays.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've found an inconsistency with the millis() function. I can reproduce the problem on a program for the 16F1829.
My Wife is working this holiday weekend so I've been re-writing portions of my Binary, Decimal and Hexadecimal calculator. This uses millis() to provide the timing for starting an animated "screensaver". If I compile this program using Great Cow BASIC (0.99.02 2022-02-17 (Windows 64 bit) : Build 1087) the timing provided by millis() is lengthened by a substantial amount, a two minute delay is stretched to about twenty five minutes.
Compile the same program, using the same compiler but targeting the 18F15Q40 and the millis() timing is accurate.
Changing the compiler to 0.98 (and also changing the LCD.h library to the 0.98 one) and compiling for the 16F1829 returns the timing back to the correct two minutes.
We need the source programs. This may be the frequency, this may be the DAT file - no idea with the errant source program.
Here is the calculator code I've just uploaded to the finished projects section.
If you compile it for the 18F15Q40, the line which sets the timeout for the screensaver works correctly when set to 120000 (two minutes) compile the same program but change the chip to the 16F1829 and the timeout needs to be reduced to 13000 (which should be thirteen seconds) gives the timeout of two minutes.
The error has also shown itself in an unrelated program for the 16F1829 using millis() at work. I'd made over fifty devices and sold quite a few before it was spotted. Rats!
Last edit: mkstevo 2022-04-16
We should fix the root cause for you. Changing the constant is a workaround and we we fix the root cause this will resolve the issue.
What frequency did the 16F run at?
The 16F1829 was run at 32MHz. With the 18F15Q40 at 64MHz.
Gotta use those Hertz...
It isn't an urgent problem as such, now I'm aware of it. I only posted the message, partly to (again) remind me and partly (again) to make others aware of it.
If nobody mentions these things, everybody is running blind.
It wasn't the first thing I looked for when newly compiled code didn't work. I spent some time with a code comparator trying to see if I'd made any changes that could have caused problems. I slowly became aware that the last batch I'd made was prior to me updating the compiler. Only then did I try rolling back to an earlier version of that.
As a temporary fix, I can just scale the timeouts by multiplying them by .11 (or so) which is good enough for the accuracy I need.
Try this adding this
#DEFINE Millis_Default_Timer0_value 131
to the 16F code with the correct value forTimeOut
Then adapt the
Millis_Default_Timer0_value
until it works as expected. I am thinking the oscillator on the 16F is not actually running at the mHz is should be.That is certainly much, much closer.
Using the default timer definition and a timeout value of 104000 gives near identical run times. I've got one 16F1829 version and one 18F15Q40 version next to me (the 18F15Q40 I normally use at work...) and the screensaver is starting almost at the same time from a cold start.
Last edit: mkstevo 2022-04-16
Wife home from work now, so all experimentation over for today! Don't think I've given up!
What's that you say Dear?
Yes Dear.
I'm putting it away now Dear.
I am listening Dear.
No, I heard every word you said.
Yes, I'm recycling the tortoise now Dear.
What? We've got a tortoise? And you want me to recycle it?
Well, perhaps not every word Dear...
Can you test something basic for me? I am puzzled by what is actually happening.
Take demo file C:\GCstudio\GreatCowBASIC\demos\millis_solutions\16f1938_1s.gcb and change the chip name, change the LED port to something that works for you. Program - does the LED flash every second ? If yes, then, we need to look at the program you have for the 16f.
Hello.
This flashes as expected at 1Hz:
I had suspected it was related to the LCD.
This flashes once every 13 seconds or so:
This is good information. Try setting LCD_SPEED OPTIMAL.
But, this gives me something to investigate.
I have been having problems with this, and I've been having to compile using an older version of GCB (0.98.07 I think).
Today has been the first day in a while when I was able to sit and apply myself to researching and engineering a work around.
I decided to try and recreate a similar background function that I could use to generate a 1mS time interval. Following some of an online MicroChip tutorial and the GCB help pages whilst shamelessly stealing from the original millis() I came up with a very rough (and barely ready) solution that does work in GCB V99.
I should point out that this function will (or at least may) only work with a PIC, a PIC that at least has a 16bit Timer1, and is running at 32MHz or 64MHz. That covers most devices I use so that is where I stopped.
I tried to do away with as much as possible of the original millis() and get the function back to the minimum possible required for it to work.
Firstly, here is the code for a file that should be named as MyMillis.h:
Here is a small program that uses it, with the option of using the original millis():
For a 16F1829:
Using the MyMillis file (as above) the LED changes state at close to 1 second.
Using the original millis() the LED changes state at around 10 seconds.
I didn't have time to try the 18F15Q40 with the original millis() but I did using MyMillis and it too runs at 1 second for each change of the LED.
One thing that did puzzle me was that initially I had the timer (millis) routines in the same file as the demonstration program. Once I got it working, I then moved those into a separate header file, with the intention of making it (nearly) seamlessly available to the many other programs I have used the original in. After I moved them into a separate file, the one second interval was never reached. Confused, I moved them back and they failed to work when inline. I then looked at the value returned from MyMillis and could see that it counted to 255 then stopped. Never reaching the 1000 interval. Why? The only change I had made was to the declaration of "MyCtr_" from the top of the program file and into the MyStartTimer sub. If that declaration was moved out of the sub and back into the main program, everything worked. Move it back into the sub and it only works as a byte variable.
This works:
This treats the MyCtr_ as a byte variable:
That may not point to what may be causing the original millis() to not work, but it is repeatable.
At one point if I added 75mS delay to each section of LCD printing commands, the original millis() worked 'properly' on the 1829. Yet if I set MyLong to zero with the command:
Let MyLong = 0
it stopped working.
All very strange for someone who is not a natural programmer...
Interesting results.
Can you try the latest build? Please use the stock build. Does millis work on both chips in this configuration ?
Here are the two demos from the installation.
18F16Q40
16F1829
Both worked here with a 1s pulse width on the scope, noting that I have tested a 18F16Q40 not a 18F15Q40. Please change the chip name and test on your chips.
I am using GCASM not PIC-AS (as I assumed that you do not have PIC-AS installed). The ASM header (for version info is) Program compiled by Great Cow BASIC (0.99.02 2022-04-27 (Windows 64 bit) : Build 1113) for Microchip MPASM/MPLAB-X Assembler
To understand the issue I need the two chips baselined under these test conditions. These test conditions are very easy - take the code and use - report back, Pass or fail.
Give me an hour or so and I'll check those out.
To clarify, I am using 0.99.01 (which when I last checked was the latest version available as a minimal or compiler only install).
I have improved the 'MyMillis' file I listed above. It will now provide a 1mS "tick" at frequencies of 64, 48, 32, 16, 8, 4, 2 and 1MHz. It will throw an error should other frequencies be set. The timer pre-load values are now more accurately calculated. Previously the timing was set by me adjusting the pre-load value until it looked about right! I've now sat and worked them out properly.
It will only work for a PIC and will not complain if any other device is selected.
I have also added a ZeroMyMillis sub which as the name might suggest, resets the counter(s) to zero.
Sorry - but, are mods are masking the root cause. Which must be identified and then resolved.
What is the root cause of the issue ?
millis() was designed to work. If there is a root cause issue then we need to fix.
Yes indeed I am masking the root cause. Unfortunately I'm not clever enough to figure out the root cause and I have a few programs that make use of the millis() function that I have to program 10-20 at a time, each week. I have been cross compiling some products with the older version of the compiler (where I have to use the 16F1829), some with the newer (where I have to use the 18F15Q40). Remembering to do so, and which to use for which program has kept me on my toes. I tried to re-write much of the code to cater for both but the delays are so inconsistent I couldn't get close to timing parity.
My solution is a major fudge, but it at least gives me a working set of code that caters for both devices. Having renamed the original file to stop me from using it by mistake, I can simply refer to my replacement and go.
I bad assumption to make. If the compiler is not correctly operating on this simply capability then you may run into other issues with other capabilities.
I am concerned that the oscillator or interrupts are not working as expected.
Please complete the two tests as provided. You have the errant chip not me.
The 'base' demo works correctly for the 16F1829. (I don't have a 15Q40 at home)
As soon as I try to use the LCD within the loop, it stops working at the normal speed.
This program flashes the LED at about once every ten seconds:
Well. That is a fail.Should be every 1 s.
If I add the line:
Immediately after the "Print CurMs" line, the LED again flashes at very close to once per second.
So this works:
With the only change being the additional 75 mS delay.
In an earlier reply you suggested changing the default timer value. In that particular program (Bin-Hex-Dec Calculator) changing that worked reasonably well. In my programs at work, it failed to have any effect. It is this type of confusion that led me to try and come up with something rather more consistent for me.
If I use that example above (with or without the 75 mS delay included) using the MyMillis program I added above, it works completely as expected, with or without any LCD print statements or extra delays.
Masking the problem again.
Revert the program to the program as posted. Change only the LED port. What is the pulse rate of the LED? I should be 1 second.
This is the test.
Putting delays in will mask the issue.