Aother speed-up...don't use logic.
You're testing if it's 116 OR it's 117 (2 tests) when testing if it's <118 is faster. (1 test)
Maybe the scale function would be better than many tests.
if scale_volts_akku=115 then percents_akku=10:goto done if scale_volts_akku=116 OR scale_volts_akku =117 then percents_akku=20:goto done
if scale_volts_akku=118 then percents_akku=30:goto done
if scale_volts_akku <118 then percents_akku=20:goto done
Last edit: stan cartwright 2019-01-05
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hallo, Friends!
Well, I've almost finished the code, but there is one big problem. I can't solve it. The problem is with the visualization on the display. When the voltage is applied, the display operates normally for a while, but after some time it starts to display abnormally. Time may vary.
At first this part was under the main:
''============== CAPACITY INDIKACIJA
if capacity_akku<>capacity_akku_disp then
capacity_akku_string=str(capacity_akku)
if capacity_akku=>10 then GLCDPrint(90, 45, capacity_akku_string + "Ah"): goto next_3
if capacity_akku<10 then GLCDPrint(90, 45, capacity_akku_string + "Ah ")
next_3:
end if
capacity_akku_disp=capacity_akku
=============================
Then the display hangs when you had to change Ah (about 2-3min). This part of the code I stayed under the interrupt subroutines sub Timer_3. In this case, the hangs time increased (~ 5 -10min). Code and photo have been added. Code comments in mixed language :)
Do this. Before all the GLCD commands, including GLCDCLS, place INTOFF, then after the GLCD commands use INTON.
Why? Thhe GLCD is time sensitive. You are sending lots of data, one of the many interrupts fires... then, you get data changes, lines change (I could not tell). So, INTOFF/INTON will protect the GLCD.
scan++... I would look at the new millis. How often are you calling all that code commencing at line 109? millis would enable you to stop the hammering of the ADCs.
The code commencing at line 298. That looks like table data to me. Just do a table look-up.
But, the code is readable. I like it. And, it does prove that you can do some very robust coding!!
:-)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So, so many things that could be wrong with the software. When I have run into non functioning code I suspect, among other things, that the ProgramCounter(PC) has gotten lost to where it is not supposed to be; Or, that the conditional logic is not doing what you think it is doing.
Your Timer3Overflow is rolling over 122 times to get your 1 second interval. Why not reduce that down to 4 or 10 rollovers as previously discussed? You do that by increasing the prescaler, like PS_8, then preload the timer3 registers in the interrupt to get the smaller rollover.
Here is some code that I used for the previously discussed state machine, with 1/10 sec rollovers, adjust to your clock speed accordingly. A quick check with the DVM and that 16 bit timer will home right in on the target value.
Lots of goto's being used. Some binary operations could be handled with a simple if:else:endif. More choices or conditions required, then use nested if's. Less PC problems that way?
All the glcd boxes, triangles and so forth is just eye candy. Comment that stuff out till you get things working properly with just string output. Get back to the basics first. Better yet, just turn on some green, yellow, red leds for indicators. Reduce, Reduce, Reduce..........
I see that only one adc value is be taken, so why not take multiples and average? I like to do the maths myself, so I don't, or haven't, used scale or linearize functions. Take control of your environment, add back when it works as expected.
Lots of things could be wrong with the hardware too. Since you are having problems when incr/decr the amps, we could go back to the button debouncing again. looks like you have a relay involved, and with that going on and off we could be getting major spikes?, so are the input lines protected or filtered?
The wheels keep turning, everything is suspect, try different things.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Kent! All the glcd boxes, triangles and so forth is just eye candy. Comment that stuff out till you get things working properly with just string output. Get back to the basics first. Better yet, just turn on some green, yellow, red leds for indicators. Reduce, Reduce, Reduce..........
Of course, the function of the charger itself is simple. And I can use 2x16 LCD. But my thing is I wants to make something using GLCD. For Eyes pleasant charger :). Why are the GCB included files for the GLCD? For real use :)
Lots of goto? I take note of your suggestions. It was recommended by stan cartwright.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Janis!
Yes you should be able to use the glcd. But when troubleshooting, tests need to be performed that the most basic operations and assumptions are correct. You have indentified that the glcd code is causing problems. But this is not the glcd.h problem as backed up by Anobium.
Early on we talked about completing glcd operations before being interrupted by the timer interrupt https://sourceforge.net/p/gcbasic/discussion/579126/thread/cd26558c64/#8789
I made suggestions on how to split up those glcd functions by creating a state machine, so that they complete before the next interrupt. Or udate all the glcd every second?, that could be done by dropping the intosc speed back a notch or two(i.e. 16MHz or 8MHz) if need be, and preload the timers as suggested. This should work.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Janis. the key thing is the INTON and INTOFF. Do this fist.
The GLCD send more data than you think, and, if an interrupt fires you need to ensure the GLCD completes its task. The GLCD libraries are robust but you need to ensure the GLCD update process completes.
Case. The GLCD is completing a write operation, but, to do this the GLCD does need to read the screen. An interrupt happens... the screen gets updated or a some temporary system variable is changed.. GLCD gets corrupted.
Case. The GLCD you has defaults. Try increasing the delay value - this will help.
#define KS0108ReadDelay 3 ; 2 normal usage, 3 for 32 mhz!
' #define KS0108WriteDelay 1 ; 1 normal usage, 0 works
' #define KS0108ClockDelay 1 ; 1 normal usage, 0 works
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anobium, I'll try to increase the delay values. But what are the values, how big?
From Help : KS0108ReadDelay
Read delay
Default is 9
Can be set to improve overall performance.
KS0108WriteDelay
Write delay
Default is 1
Can be set to improve performance.
KS0108ClockDelay
Clock Delay
Default is 1
Can be set to improve performance.
How to properly use IntOn and IntOff for GLCD? Please write a small example of code.
Thanks
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Those delays when lower improve performance, but, when the delays are too small you will get screen corruption. So, increase the delays to improve stability.
See attached for INTOFF/INTON. Essentially, wrap a lot of commands with INTOFF and INTON because you have GLCD commands within the interrupts and therefore things will get messed up.
It takes at least a 1/2 sec to update all the glcd prints. Get any glcd prints out of the interrupt like Anobium says. Set the timer interrupt for max prescale of PS_8 , update a2d and print glcd, wait for next interrupt and repeat. Maybe that will work?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I agree with Kent. Remove the GLCD commands from the interrupt by setting a flag than you can use within the main program to carry out the desired action. Those GLCD command will impact the main code GLCD commands.
Last edit: Anobium 2019-01-11
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hallo! Good evening gyus!
I changed timer 3 prescaler, InitTimer3 osc , PS3_8. Ynow Timer3Overflow is rolling 15 times in 1 second interval. Then I did experiments to figure out which GLCD instructions in the program section hang the display. Problems are caused by running arrow and capacitance indication.
sub charge_triangle
.......
..........
and
''============== CAPACITY INDIKACIJA (Ah)
if capacity_akku<>capacity_akku_disp then
capacity_akku_string=str(capacity_akku)
if capacity_akku=>10 then GLCDPrint(90, 45, capacity_akku_string + "Ah"): goto next_3
if capacity_akku<10 then GLCDPrint(90, 45, capacity_akku_string + "Ah ")
next_3:
end if
capacity_akku_disp=capacity_akku
''============== CAPACITY INDIKACIJA is in the Interruption subroutine**subTimer_3** .
When this parts of program are removed from the program processing, this program works and the display is ok.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So the experiment shows that you have to do what you suggested to me. Get any glcd prints out of the interrupt like Anobium says. Set the timer interrupt for max prescale of PS_8 , update a2d and print glcd, wait for next interrupt and repeat. Maybe explain with an example how to understand it?
But what to do with the dynamic display in the subprogram sub charge_triangle ?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
if capacity_akku=>10 then GLCDPrint(90, 45, capacity_akku_string + "Ah"): goto next_3
if capacity_akku<10 then GLCDPrint(90, 45, capacity_akku_string + "Ah ")
it will always GLCDPrint(90, 45, capacity_akku_string + "Ah ")
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I forget that these newer PIC's have a much more enhanced TMR0. It has a giant prescaler, up to 1:32678! Use it in 8bit mode or 16 bit mode to get Much larger rollovers from the TMR0 interrupt. It is explained well in Help.
Getting more efficient and readable code is the joy of discovery.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Oops.
Shifted for looks? Tidiness?
The displays I use are fast but sampling 2 inputs and displaying "both" is not working.
I'm making an "Octopus component tracker". Supposed to use an oscilloscope but thought use glcd. (and I haven't powered it, ie signal, off ac yet)
Display update speed is fast enough. sampling data needs a filter...or summat.
Last edit: stan cartwright 2019-01-13
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry! However, the problem is related to the timer interruption. I turned off the timer, I made seconds for the variables in the test program (sec++) and the whole program and display worked for half a day.
Before that I tried Anobium and Kent suggestions - display delay, timer prescaler, INTOFF.
It is now clear that the timer interruption interferes with the GLCD commands.
Oops, I need an exact second pulse, without a timer I can't do it .
Maybe GLCD commands can be operated using timer interrupt?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I want to let you know that I did so - that only 1 variable is being processed in the interruption subprogram, which make seconds , so the subprogram is small. Other time calculations are done by the main program. It looks like it works. I'll report the results.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As I said, I'll publish the code when my battery charger is ready. It's ready and working. I'm checking out today. It is designed for 10A charging. The power side is based on the Mean Well 15V 10A power supply, werei output voltage is controlled using TL341. and I give voltage reference for TL341 With PWM 0-5V . In my case, the charger output voltage is between 10.8-15.5V.
Aother speed-up...don't use logic.
You're testing if it's 116 OR it's 117 (2 tests) when testing if it's <118 is faster. (1 test)
Maybe the scale function would be better than many tests.
if scale_volts_akku=115 then percents_akku=10:goto done
if scale_volts_akku=116 OR scale_volts_akku =117 then percents_akku=20:goto done
if scale_volts_akku=118 then percents_akku=30:goto done
if scale_volts_akku <118 then percents_akku=20:goto done
Last edit: stan cartwright 2019-01-05
Hallo, Friends!
Well, I've almost finished the code, but there is one big problem. I can't solve it. The problem is with the visualization on the display. When the voltage is applied, the display operates normally for a while, but after some time it starts to display abnormally. Time may vary.
At first this part was under the main:
''============== CAPACITY INDIKACIJA
if capacity_akku<>capacity_akku_disp then
capacity_akku_string=str(capacity_akku)
if capacity_akku=>10 then GLCDPrint(90, 45, capacity_akku_string + "Ah"): goto next_3
if capacity_akku<10 then GLCDPrint(90, 45, capacity_akku_string + "Ah ")
next_3:
end if
capacity_akku_disp=capacity_akku
=============================
Then the display hangs when you had to change Ah (about 2-3min). This part of the code I stayed under the interrupt subroutines sub Timer_3. In this case, the hangs time increased (~ 5 -10min). Code and photo have been added. Code comments in mixed language :)
OK~ 5 min
It looks like a hanging display.
Sorry, see https://sourceforge.net/p/gcbasic/discussion/579126/thread/cd26558c64/#8349
I did say that there was something wrong with the approach. The code loops and loops and I could not work out what is was doing. :-(
Yes, Anobium, I understand. But I don't know how to fix something. The bad programming style is for me :(
OK.
Do this. Before all the GLCD commands, including GLCDCLS, place INTOFF, then after the GLCD commands use INTON.
Why? Thhe GLCD is time sensitive. You are sending lots of data, one of the many interrupts fires... then, you get data changes, lines change (I could not tell). So, INTOFF/INTON will protect the GLCD.
scan++... I would look at the new millis. How often are you calling all that code commencing at line 109? millis would enable you to stop the hammering of the ADCs.
The code commencing at line 298. That looks like table data to me. Just do a table look-up.
But, the code is readable. I like it. And, it does prove that you can do some very robust coding!!
:-)
So, so many things that could be wrong with the software. When I have run into non functioning code I suspect, among other things, that the ProgramCounter(PC) has gotten lost to where it is not supposed to be; Or, that the conditional logic is not doing what you think it is doing.
Your Timer3Overflow is rolling over 122 times to get your 1 second interval. Why not reduce that down to 4 or 10 rollovers as previously discussed? You do that by increasing the prescaler, like PS_8, then preload the timer3 registers in the interrupt to get the smaller rollover.
Here is some code that I used for the previously discussed state machine, with 1/10 sec rollovers, adjust to your clock speed accordingly. A quick check with the DVM and that 16 bit timer will home right in on the target value.
Lots of goto's being used. Some binary operations could be handled with a simple if:else:endif. More choices or conditions required, then use nested if's. Less PC problems that way?
All the glcd boxes, triangles and so forth is just eye candy. Comment that stuff out till you get things working properly with just string output. Get back to the basics first. Better yet, just turn on some green, yellow, red leds for indicators. Reduce, Reduce, Reduce..........
I see that only one adc value is be taken, so why not take multiples and average? I like to do the maths myself, so I don't, or haven't, used scale or linearize functions. Take control of your environment, add back when it works as expected.
Lots of things could be wrong with the hardware too. Since you are having problems when incr/decr the amps, we could go back to the button debouncing again. looks like you have a relay involved, and with that going on and off we could be getting major spikes?, so are the input lines protected or filtered?
The wheels keep turning, everything is suspect, try different things.
Kent!
All the glcd boxes, triangles and so forth is just eye candy. Comment that stuff out till you get things working properly with just string output. Get back to the basics first. Better yet, just turn on some green, yellow, red leds for indicators. Reduce, Reduce, Reduce..........
Of course, the function of the charger itself is simple. And I can use 2x16 LCD. But my thing is I wants to make something using GLCD. For Eyes pleasant charger :). Why are the GCB included files for the GLCD? For real use :)
Lots of goto? I take note of your suggestions. It was recommended by stan cartwright.
Janis!
Yes you should be able to use the glcd. But when troubleshooting, tests need to be performed that the most basic operations and assumptions are correct. You have indentified that the glcd code is causing problems. But this is not the glcd.h problem as backed up by Anobium.
Early on we talked about completing glcd operations before being interrupted by the timer interrupt https://sourceforge.net/p/gcbasic/discussion/579126/thread/cd26558c64/#8789
I made suggestions on how to split up those glcd functions by creating a state machine, so that they complete before the next interrupt. Or udate all the glcd every second?, that could be done by dropping the intosc speed back a notch or two(i.e. 16MHz or 8MHz) if need be, and preload the timers as suggested. This should work.
Janis. the key thing is the INTON and INTOFF. Do this fist.
The GLCD send more data than you think, and, if an interrupt fires you need to ensure the GLCD completes its task. The GLCD libraries are robust but you need to ensure the GLCD update process completes.
Case. The GLCD is completing a write operation, but, to do this the GLCD does need to read the screen. An interrupt happens... the screen gets updated or a some temporary system variable is changed.. GLCD gets corrupted.
Case. The GLCD you has defaults. Try increasing the delay value - this will help.
' #define KS0108WriteDelay 1 ; 1 normal usage, 0 works
' #define KS0108ClockDelay 1 ; 1 normal usage, 0 works
Anobium, I'll try to increase the delay values. But what are the values, how big?
From Help :
KS0108ReadDelay
Read delay
Default is 9
Can be set to improve overall performance.
KS0108WriteDelay
Write delay
Default is 1
Can be set to improve performance.
KS0108ClockDelay
Clock Delay
Default is 1
Can be set to improve performance.
How to properly use IntOn and IntOff for GLCD? Please write a small example of code.
Thanks
Those delays when lower improve performance, but, when the delays are too small you will get screen corruption. So, increase the delays to improve stability.
See attached for INTOFF/INTON. Essentially, wrap a lot of commands with INTOFF and INTON because you have GLCD commands within the interrupts and therefore things will get messed up.
So, I tried, no. Intoff and inton fail ... using this command in a couple of instructions, the program cycle processing is slowed down or stopped.
It takes at least a 1/2 sec to update all the glcd prints. Get any glcd prints out of the interrupt like Anobium says. Set the timer interrupt for max prescale of PS_8 , update a2d and print glcd, wait for next interrupt and repeat. Maybe that will work?
I agree with Kent. Remove the GLCD commands from the interrupt by setting a flag than you can use within the main program to carry out the desired action. Those GLCD command will impact the main code GLCD commands.
Last edit: Anobium 2019-01-11
Hallo! Good evening gyus!
I changed timer 3 prescaler, InitTimer3 osc , PS3_8. Ynow Timer3Overflow is rolling 15 times in 1 second interval. Then I did experiments to figure out which GLCD instructions in the program section hang the display. Problems are caused by running arrow and capacitance indication.
sub charge_triangle
.......
..........
and
''============== CAPACITY INDIKACIJA (Ah)
if capacity_akku<>capacity_akku_disp then
capacity_akku_string=str(capacity_akku)
if capacity_akku=>10 then GLCDPrint(90, 45, capacity_akku_string + "Ah"): goto next_3
if capacity_akku<10 then GLCDPrint(90, 45, capacity_akku_string + "Ah ")
next_3:
end if
capacity_akku_disp=capacity_akku
So the experiment shows that you have to do what you suggested to me.
Get any glcd prints out of the interrupt like Anobium says. Set the timer interrupt for max prescale of PS_8 , update a2d and print glcd, wait for next interrupt and repeat. Maybe explain with an example how to understand it?
But what to do with the dynamic display in the subprogram sub charge_triangle ?
I forget that these newer PIC's have a much more enhanced TMR0. It has a giant prescaler, up to 1:32678! Use it in 8bit mode or 16 bit mode to get Much larger rollovers from the TMR0 interrupt. It is explained well in Help.
Getting more efficient and readable code is the joy of discovery.
stan cartwright - no, the difference is that the string is shifted and if no space is left at the end, then 2 pieces of h are indicated. ("Ah ")
Oops.
Shifted for looks? Tidiness?
The displays I use are fast but sampling 2 inputs and displaying "both" is not working.
I'm making an "Octopus component tracker". Supposed to use an oscilloscope but thought use glcd. (and I haven't powered it, ie signal, off ac yet)
Display update speed is fast enough. sampling data needs a filter...or summat.
Last edit: stan cartwright 2019-01-13
Sorry! However, the problem is related to the timer interruption. I turned off the timer, I made seconds for the variables in the test program (sec++) and the whole program and display worked for half a day.
Before that I tried Anobium and Kent suggestions - display delay, timer prescaler, INTOFF.
It is now clear that the timer interruption interferes with the GLCD commands.
Oops, I need an exact second pulse, without a timer I can't do it .
Maybe GLCD commands can be operated using timer interrupt?
I want to let you know that I did so - that only 1 variable is being processed in the interruption subprogram, which make seconds , so the subprogram is small. Other time calculations are done by the main program. It looks like it works. I'll report the results.
Hello!
As I said, I'll publish the code when my battery charger is ready. It's ready and working. I'm checking out today. It is designed for 10A charging. The power side is based on the Mean Well 15V 10A power supply, werei output voltage is controlled using TL341. and I give voltage reference for TL341 With PWM 0-5V . In my case, the charger output voltage is between 10.8-15.5V.