defragster
Senior Member+
My code is still in flux - so many numbers to see
NOTE: I went to F_BUS 60 back to 120 and redid the Auto Adjust - now the text is properly left justified to the true edge? Register() should draw lines not triangles because the side points are blobs not points.
<edit> I found another number out of 1,000,000 Us/sec the:: RunTime:746854 is the time spent outside the loop that does VGA update with 60Hz 'full' screen writes with beamWait(), doing only one third update each of 60 Hz gives RunTime:879384. Also I found there are worse places/ways to reset the elapsedMicros.
I took out the always printing Register lines- just 5 seconds in setup. With all the rectangles drawing most all the screen at 60 Hz ( one small gap on bottom third ) the draw time looks to be 3.1ms, and I am keying off of waitBeam() [ not waitSync() ] -it looks good (no waitBeam() is UGLY) and using elapsedMicros to control update I end up waiting 934 Us on average for the Beam to go off. Using waitSync() takes over 12 ms and limits refresh to 30 Hz - which looks smoother because 60 Hz is unnaturally fast to follow doubling POV - unless you follow with your eyes.
There is one tear/fold in the upper right corner - that is that same 60Hz w/waitBeam or 30 Hz w/waitSync. Also the same F_BUS at 60 or 120. And with bars static or moving.
Above numbers at F_BUS=60 as indicated - here is the same series at F_BUS =120
The TimeSumxxxx is a loop average of 10 times of waitBeam or waitSync - the Sync measures faster with the F_BUS=120, DrawTime is the same - but my funny math to adjust TimeSumSyncVar for elapsedMicros gets worse for F_BUS=120 - so that needs to be improved.
I am using Raw_HID for serial SPEW and I see NO JITTER (set doXXX()'s param 3 to zero) - I added some test code to watch for Hid ( !Serial ) to come online - it takes over 6 seconds with TyCommander. I want to add keyboard input to allow changes without having to recompile.
Here is the code - anything useful?:
NOTE: I went to F_BUS 60 back to 120 and redid the Auto Adjust - now the text is properly left justified to the true edge? Register() should draw lines not triangles because the side points are blobs not points.
<edit> I found another number out of 1,000,000 Us/sec the:: RunTime:746854 is the time spent outside the loop that does VGA update with 60Hz 'full' screen writes with beamWait(), doing only one third update each of 60 Hz gives RunTime:879384. Also I found there are worse places/ways to reset the elapsedMicros.
I took out the always printing Register lines- just 5 seconds in setup. With all the rectangles drawing most all the screen at 60 Hz ( one small gap on bottom third ) the draw time looks to be 3.1ms, and I am keying off of waitBeam() [ not waitSync() ] -it looks good (no waitBeam() is UGLY) and using elapsedMicros to control update I end up waiting 934 Us on average for the Beam to go off. Using waitSync() takes over 12 ms and limits refresh to 30 Hz - which looks smoother because 60 Hz is unnaturally fast to follow doubling POV - unless you follow with your eyes.
millis::22758 F_CPU:240000000 F_BUS:60000000 fb_height:300 fb_width:703
TimeSumBeam:1646
TimeSumSync:15183
DrawTime:3173
TimeBeamWait:934
TimeSumSyncVar:15670
DrawHz:60
There is one tear/fold in the upper right corner - that is that same 60Hz w/waitBeam or 30 Hz w/waitSync. Also the same F_BUS at 60 or 120. And with bars static or moving.
Above numbers at F_BUS=60 as indicated - here is the same series at F_BUS =120
millis::136820 F_CPU:240000000 F_BUS:120000000 fb_height:300 fb_width:703
TimeSumBeam:1646
TimeSumSync:15012
DrawTime:3173
TimeBeamWait:1046
TimeSumSyncVar:15555
DrawHz:60
The TimeSumxxxx is a loop average of 10 times of waitBeam or waitSync - the Sync measures faster with the F_BUS=120, DrawTime is the same - but my funny math to adjust TimeSumSyncVar for elapsedMicros gets worse for F_BUS=120 - so that needs to be improved.
I am using Raw_HID for serial SPEW and I see NO JITTER (set doXXX()'s param 3 to zero) - I added some test code to watch for Hid ( !Serial ) to come online - it takes over 6 seconds with TyCommander. I want to add keyboard input to allow changes without having to recompile.
Here is the code - anything useful?:
Code:
// Lines and Color wiring test
// Do lines not triangles in Register()
// Keyboard input - show Register(), [stop start advance] rotate of bars, change refresh limitation <60 Hz
#include <uVGA.h>
void yield(void){};
// Prep for USB input adjust : First use -- Send Enter to toggle
bool DrawAll = HIGH; // Draw All three bands each time - or not then just one in turn
bool DrawReg = HIGH; // Draw Registration lines each time - or not
uVGA uvga;
#define UVGA_DEFAULT_REZ
#include <uVGA_valid_settings.h>
const byte cmap[] =
{
0b00000000, 0b11100000, 0b11100100, 0b11101000, 0b11101100, 0b11110000, 0b11110100, 0b11111000, 0b11111100,
0b11011100, 0b10111100, 0b10011100, 0b01111100, 0b01011100, 0b00111100, 0b00011100, 0b00011101, 0b00011110,
0b00011111, 0b00011011, 0b00010111, 0b00010011, 0b00001111, 0b00001011, 0b00000111, 0b00000011, 0b00100011,
0b01000011, 0b01100011, 0b10000011, 0b10100011, 0b11000011, 0b11100011, 0b11100010, 0b11100001, 0b11100000, 0b00000000
};
const byte cmap2[] =
{ 0b00000000,
0b11100000, 0b11000000, 0b10100000, 0b10000000, 0b01100000, 0b01000000, 0b00100000,
0b00011100, 0b00011000, 0b00010100, 0b00010000, 0b00001100, 0b00001000, 0b00000100,
0b00000011, 0b00000010, 0b00000001
};
int fb_width, fb_height;
elapsedMicros TimeTest = 0;
uint32_t TimeSumSync = 0;
uint32_t TimeSumBeam = 0;
uint32_t TimeSumSyncVar = 0;
uint32_t TimeSumBeamVar = 0;
uint32_t TimeBeamWait = 0;
uint32_t TimeBeamWaitCnt = 1;
uint32_t DrawTime = 0;
uint32_t DrawHz = 0;
uint32_t RunTime = 0;
void setup()
{
int ret;
int Snot = 0;
Serial.begin( 1200 );
ret = uvga.begin(&modeline);
if (ret != 0)
while (1) {
if ( !Snot && Serial ) {
Serial.println("fatal error");
Snot = 1;
}
}
uvga.get_frame_buffer_size(&fb_width, &fb_height);
doRegister( fb_width, fb_height, 5000 );
TimeSumSync = 0;
for ( int ii = 0; ii < 10; ii++ ) {
TimeTest = 0;
uvga.waitSync();
TimeSumSync += TimeTest;
}
TimeSumSync /= 10;
TimeSumSyncVar = TimeSumSync;
TimeSumBeam = 0;
for ( int ii = 0; ii < 10; ii++ ) {
uvga.waitBeam();
delayMicroseconds(15);
TimeTest = 0;
uvga.waitBeam();
TimeSumBeam += TimeTest;
}
TimeSumBeam /= 10;
TimeSumBeamVar = TimeSumBeam;
testPrint();
}
int Snot = 0;
elapsedMicros DoScreen = 0;
elapsedMillis DoUpdate = 0;
void loop()
{
if ( DoScreen >= TimeSumSyncVar )
{
TimeTest = 0;
// uvga.waitSync();
uvga.waitBeam();
TimeBeamWait += TimeTest;
TimeBeamWaitCnt++;
DoScreen = 0; // BAD >> -= TimeSumSync; // = 0;
DrawHz++;
doLines( fb_width, fb_height, -1 ); // disable draw lines with negative wait on param 3
// uvga.clear(0);
// uvga.clear(0b11111111);
// these each take a third of the screen given H and W, Param 3 is bar +/-/0 indexing between draws, Param 4 is time to delay before return
if ( ( DrawHz % 3 ) || DrawAll )
doCmap( fb_width, fb_height, 1, 0 );
if ( ( DrawHz % 3 ) || DrawAll )
doPCmap( fb_width, fb_height, -1, 0 );
if ( ( DrawHz % 3 ) || DrawAll )
doColors( fb_width, fb_height, 1, 0 );
if ( DrawReg )
doRegister( fb_width, fb_height, 0 );
DrawTime += DoScreen;
RunTime += TimeTest;
}
if ( DoUpdate >= 1000 && Serial ) {
DoUpdate = 0;
testPrint();
if ( !Snot) {
Serial.print("\n WE HAVE SERIAL ");
Snot = 1;
}
}
if ( !Serial ) {
Snot = 0;
}
}
void doCmap( int fb_width, int fb_height, int Nshift, int dtime ) {
int col;
static uint16_t pre_adv = 0;
pre_adv += Nshift;
uint16_t adv = pre_adv;
int xx = fb_width / sizeof(cmap);
int yy = (fb_height - 1) / 3;
for (col = 0; col < sizeof(cmap); col++) {
uvga.fillRect(col * xx, 0, (col * xx) + xx - 1, yy - 1, cmap[(col + adv) % sizeof(cmap)]);
}
delay( dtime );
}
void doPCmap( int fb_width, int fb_height, int Nshift, int dtime ) {
int col;
static uint16_t pre_adv = 0;
pre_adv += Nshift;
uint16_t adv = pre_adv;
int xx = fb_width / sizeof(cmap);
int yy = (fb_height - 1) / 3;
for (col = 0; col < sizeof(cmap); col++) {
uvga.fillRect(col * xx, yy, (col * xx) + xx - 1, 2 * (yy) - 1, 0xff - cmap[(col + adv) % sizeof(cmap)]);
}
delay( dtime );
}
void doColors( int fb_width, int fb_height, int Nshift, int dtime ) {
int col;
static uint16_t pre_adv = 0;
pre_adv += Nshift;
uint16_t adv = pre_adv;
int yy = (fb_height - 1) / 3;
int xx = fb_width / (sizeof(cmap2) * 2);
int bb = fb_width - (xx * sizeof(cmap2) * 2); // put the unused space in the center
for (col = 0; col < sizeof(cmap2); col++) {
uvga.fillRect(col * xx, 2 * yy, (col * xx) + xx - 1, fb_height - 1, cmap2[(col + adv) % sizeof(cmap2)]);
uvga.fillRect(bb + sizeof(cmap2)*xx + (col * xx), 2 * yy, bb + sizeof(cmap2)*xx + ((col * xx) + xx - 1), fb_height - 1, 0xff - cmap2[(col + adv) % sizeof(cmap2)]);
}
delay( dtime );
}
void doLines( int fb_width, int fb_height, int dtime ) {
int col;
if ( 0 > dtime ) return;
// uvga.waitSync();
//uvga.clear(0b11111111);
for (col = 0; col < fb_width; col += 18) {
uvga.drawLine(col, 0, col, fb_height, 0b00011100);
uvga.drawLine(col + 9, 0, col + 9, fb_height, 0b00000011);
Serial.print(".");
}
delay( dtime );
}
void doRegister( int fb_width, int fb_height, int dtime ) {
if ( 0 > dtime ) return;
fb_width--;
fb_height--;
uvga.drawTri(fb_width, fb_height / 2, 0, fb_height / 2, fb_width / 2, 0, 0b01101111);
uvga.drawTri(fb_width, fb_height / 2 + 1, 0, fb_height / 2 + 1, fb_width / 2, fb_height, 0b10010001);
uvga.drawRect( 0, 0, fb_width, fb_height, 0b10010010);
uvga.drawLine( 0, 0, fb_width, fb_height, 0b10011111 );
uvga.drawLine( 0, fb_height, fb_width, 0, 0b10011111 );
if ( dtime > 99 ) {
uvga.print("\nF_CPU: ");
uvga.println(F_CPU);
uvga.print("\tF_BUS: ");
uvga.println(F_BUS);
uvga.print("\tfb_height: ");
uvga.println(fb_height + 1);
uvga.print("\tfb_width: ");
uvga.println(fb_width + 1);
uvga.print("A234567890B234567890C234567890D234567890E234567890F234567890G234567890H234567890I234567890xyz");
uvga.print("\n.............................................................................................");
}
delay( dtime );
}
void testPrint() {
// doRegister( fb_width, fb_height, 0 );
// int fb_width, fb_height;
// uvga.get_frame_buffer_size(&fb_width, &fb_height);
Serial.print("\n millis::");
Serial.print(millis());
Serial.print(" F_CPU:");
Serial.print(F_CPU / 1000000);
Serial.print(" F_BUS:");
Serial.print(F_BUS / 1000000);
Serial.print(" fb_ht:");
Serial.print(fb_height);
Serial.print(" fb_wid:");
Serial.println(fb_width);
Serial.print(" TimeSumBeam:");
Serial.println(TimeSumBeam);
Serial.print(" TimeSumSync:");
Serial.println(TimeSumSync);
TimeBeamWait /= TimeBeamWaitCnt;
DrawTime /= TimeBeamWaitCnt;
Serial.print(" DrawTime:");
Serial.println(DrawTime);
TimeBeamWaitCnt = 0;
Serial.print(" TimeBeamWait:");
Serial.println(TimeBeamWait);
// Adjust 60 Hz wait to update time
// TimeSumSyncVar = TimeSumSync + TimeBeamWait / 2 + 20; // for F_BUS=60 at cpu=240 yields: TimeBeamWait:934
if ( TimeBeamWait > 100 )
TimeSumSyncVar = TimeSumSync + TimeBeamWait;// // for F_BUS=120 at cpu=240 yields: TimeBeamWait: 1 or 2 Us
Serial.print(" TimeSumSyncVar:");
Serial.println(TimeSumSyncVar);
Serial.print(" DrawHz:");
Serial.println(DrawHz);
DrawHz = 0;
Serial.print(" RunTime:");
Serial.println(1000000 - RunTime);
RunTime = 0;
int doSwap = 0;
while ( Serial.available() ) {
doSwap = 1;
Serial.read();
}
if ( doSwap ) {
DrawAll = !DrawAll;
DrawReg = !DrawReg;
}
}
Last edited: