Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 22:21 17 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Blit and Gauges

     Page 1 of 3    
Author Message
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 10:46pm 19 Feb 2017
Copy link to clipboard 
Print this post

I've been studying the Blit command in the manual in relation to gauges
What I really want is someone to explain in detain exactly how the gauge program on this page works.
I can't get my head round understanding what is happening to make the needle in the first place, and also how to make it move,
Then I need to understand how the BLIT command works in order to incorporate both together.
I've spent hours studying the program but I cannot get it into my head how it works

For example, these 2 lines of code
Dim integer ntb=9 'Number of triangles being updated in dialset 1
Dim integer xx0b(ntb*2-1),yy0b(ntb*2-1),xx1b(ntb*2-1),yy1b(ntb*2-1),xx2b(ntb*2-1),yy2b(ntb*2-1),tcolb(ntb*2-1)

How is the number of triangles 9? is a triangle the actual needle of the gauge?
I also can't figure out the 2nd line what it is/does


Then there are these lines
'Initialise dialset 1
dial(1,0,0,d4,82,320,124,-135,135,0,50,"MPH") 'speed
dial(1,1,0,d5,82,518,125,-155,155,500,2000,"mb") 'pressure
dial(1,2,0,d6,82,320,378,-135,135,0,50,"MPH") 'av speed
dial(1,3,0,d7,82,511,383,-135,135,0,100,"Percent") 'humidity
dial(1,4,0,d8,82,696,380,-180,180,0,360) 'direction

I can see the relate to the actual dials but I have no idea/understanding of what the numbers are or what they mean

Then
I really can't get my head round what the numbers after the word dial mean or do, I know they are obviously making the needle move? but how!

' Update dialset 1
dial(1,0,1,d4,82,320,124,-135,135,0,50,"MPH") 'speed
dial(1,1,1,d5,82,518,125,-155,155,500,2000,"mb") 'pressure
dial(1,2,1,d6,82,320,378,-135,135,0,50,"MPH") 'av speed
dial(1,3,1,d7,82,511,383,-135,135,0,100,"Percent") 'humidity
dial(1,4,1,d8,82,696,380,-180,180,0,360) 'direction
bar_Thermometer(1,5,1,d9,145,646,185,-10,50,"",3)
bar_Thermometer(1,7,1,d9,145,727,185,-10,50,"",3)
i=triangles(ntb*2, buffb() , tcolb(), xx0b(), yy0b(), xx1b(), yy1b(), xx2b(), yy2b())
end if


Then

There is the actual subroutine for the triangles
Do I need to understand how this sub works in order to understand how to make a gauge, or do I just take it that it works and I don't need to understand it?

I get that it's defining X0 Y0 S1 Y1 X2 and Y2 as integers however I can't see them in the actual program

Sub rotatetriangle(grp as INTEGER,n As integer, col As integer, angle As float, x As integer, y As integer, x0 As integer, y0 As integer, x1 As integer, y1 As integer, x2 As integer, y2 As integer)
Local float sine=Sin(Rad(angle)),cosine=Cos(Rad(angle))
Local integer x0a,y0a,x1a,y1a,x2a,y2a
x0a= x0*cosine - y0 * sine + x
y0a= y0*cosine + x0 * sine + y
x1a= x1*cosine - y1 * sine + x
y1a= y1*cosine + x1 * sine + y
x2a= x2*cosine - y2 * sine + x
y2a= y2*cosine + x2 * sine + y
if grp=0 then
xx0a(n)=xx0a(n+nta)
yy0a(n)=yy0a(n+nta)
xx1a(n)=xx1a(n+nta)
yy1a(n)=yy1a(n+nta)
xx2a(n)=xx2a(n+nta)
yy2a(n)=yy2a(n+nta)
xx0a(n+nta)=x0a
yy0a(n+nta)=y0a
xx1a(n+nta)=x1a
yy1a(n+nta)=y1a
xx2a(n+nta)=x2a
yy2a(n+nta)=y2a
tcola(n)=-1
tcola(n+nta)=col
ELSEif grp=1 then
xx0b(n)=xx0b(n+ntb)
yy0b(n)=yy0b(n+ntb)
xx1b(n)=xx1b(n+ntb)
yy1b(n)=yy1b(n+ntb)
xx2b(n)=xx2b(n+ntb)
yy2b(n)=yy2b(n+ntb)
xx0b(n+ntb)=x0a
yy0b(n+ntb)=y0a
xx1b(n+ntb)=x1a
yy1b(n+ntb)=y1a
xx2b(n+ntb)=x2a
yy2b(n+ntb)=y2a
tcolb(n)=-1
tcolb(n+ntb)=col
end if
End Sub


Once Ive understood all that I THEN have to try and work out how the BLIT command works in relation to the gauges
I have read that BLIT means
[quote]BLIT READ [#]b, x, y, w, h
BLIT WRITE [#]b, x, y, w, h
BLIT CLOSE [#]b

Copy one section of the display screen to or from a memory buffer.
BLIT READ will copy a portion of the display to the memory buffer '#b'. The
source coordinate is 'x' and 'y' and the width of the display area to copy is 'w'
and the height is 'h'. When this command is used the memory buffer is
automatically created and sufficient memory allocated. This buffer can be
freed and the memory recovered with the BLIT CLOSE command.
BLIT WRITE will copy the memory buffer '#b' to the display. The destination
coordinate is 'x' and 'y' and the width/height of the buffer to copy is 'w' and 'h'.
BLIT CLOSE will close the memory buffer '#b' to allow it to be used for
another BLIT READ operation and recover the memory used.
Notes:
 Eight buffers are available ranging from #1 to #8.
 When specifying the buffer number the # symbol is optional.
 All other arguments are in pixels.[/quote]
But unfortunately I really don't understand what it is doing, or how it works

Does it copy a section of the picture to memory and then do something with it?
What if you have the background as one large picture that covers the whole of the 7" screen?
How could I get it to work with this so the gauges work properly?

Sorry for so many "stupid" questions, but I've now spent about 4 weeks trying to get my head round and understand this and really cannot understand any of it.


I have read the manuals but what I need is someone to try and explain it as if I was a child learning about programming and put in a way I'll understand it

What I want to end up doing is understand how the gauges actually work so I can add or delete gauges if I change the program/dials and also how to get the gauges to display the information I am going to send them

For example some of the gauges I will need to move 360°
some will need so move around 240° or maybe a bit more
You can get an idea of what I need from the picture below




IF anyone has the patience to try and explain it please.........




btw I know the last 2 dials are bar graphs in a semi circle and would be colours bars that move... I've no idea whatsoever how to do those (yet) I may end up changing them to needle gauges if it works out easier




Edited by lew247 2017-02-21
 
oldtimer
Newbie

Joined: 02/12/2016
Location: Australia
Posts: 18
Posted: 06:13pm 21 Feb 2017
Copy link to clipboard 
Print this post

LEW 247
I hope someone can answer your query re BLIT- in really simple terms- and advise on how to get the needles to move on your gauges - Im having the same problem understanding how one gets the information from a sensor - as in the case of a temp sensor - to drive the needle of - say - the OAT section of the cluster of 6 gauges as in matherps coding - its fascinating watching the needles flick back and forth but attaching then to something would be a much more useful exercise - Ive been following your posts re your weather station with attached big ben clock and thought you had solved most of the problems associated with getting suitably sized BMP images- held on an SD card to display behind a set of moving hands- apparently not

Im also finding it hard to deal with the reams of cfunction code that seem to be necessary to achieve the triangles making up the hands - when an error is returned- - without any access to the original uncompiled code or - in my case no understanding of cfunctions anyway - one must accept the code as listed and if it doesn't work - move on to something else- sort of defeats the object of BASIC - unless one is a cfunction guru

my own small successes - Ive managed to get Big Ben - complete with moving hands - functioning on an explore 100 - I then substituted an ILI 9341 panel for the 5 inch one - which- with a lot of playing around - produced a 240 by 240 image - but without hands - I suspect the lack of a RD pin in the small panel is causing the problem - still a work in progress !!!!!
I will follow your post with interest
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8604
Posted: 11:16pm 21 Feb 2017
Copy link to clipboard 
Print this post

Lets forget CFunctions, we don't need them anymore, and make sure you have 5.3.02 loaded on a MM+. BLIT is then available on both the SSD1963 and ILI9341 displays if wired correctly (see the manual)

Make sure this is the case by loading an image and then typing

BLIT 0,0,100,100,100,100


The 100 by 100 square at the top left of the picture should now be replicated diagonally below and to the right

If this isn't the case you have a wiring issue.

Now study the attached program but also reference this thread which shows how a pointer is constructed from a series of triangles. Why triangles? Because you can draw a filled triangle in any orientation and of any shape.

A rectangular pointer is comprised of just two triangles like the centre two in the diagram in the previous thread. The example below uses four to make a more complex shape.

I've commented the program so it should be easy to follow what I am doing. At the simplest level adding multiple gauges and pointers is just a matter of replicating the code and data structures. In this case you would use a different BLIT buffer number for each pointer so they can be updated independently.

option explicit
option default none
'
const Y_top = 0 'Y coordinate of top of the image file on the screen
const X_left = 0 'X coordinate of left of the image file on the screen
const Y_point = 220 'Y coordinate of the centre of the pointer relative to the image top
const X_point = 160 'X coordinate of the centre of the pointer relative to the image left
'
'
' Now we define the pointer as the X,Y coordinates of a number of triangles with the rotation point at 0,0
' It is simplest to define this in the 12-oclock position which means the Y-coordinates at the top of the pointer will be negative
' The order of data elements in the array is:
' t1x1,t1y1,t1x2,t1y2,t1x3,t1y3, t2x1,t2y1,t2x2,t2y2,t2x3,t2y3,...tntx1,tnty1,tntx2,tnty2,tntx3,tnty3
'
dim integer nt=4 'Number of triangles used to define the pointer
dim integer ptr(5,nt-1)=(-4,-35, -4,-110, 4,-35, -4,-110, 4,-110, 4,-35, -4,-35,-8,-35,-4,-110, 4,-35,8,-35,4,-110)
DIM INTEGER pcolour=rgb(red) 'define the colour of the pointer
const pivot=35 'diameter in pixels of the fulcrum of the pointer
'
dim integer xx0(nt-1),yy0(nt-1),xx1(nt-1),yy1(nt-1),xx2(nt-1),yy2(nt-1),tcol(nt-1)
dim integer i
dim integer x,y,w,h
'
cls
'
' load the background image, it can be anything
'
load image "tiger.bmp",X_left,Y_top
'
' take the coordinates of the set of triangles and rotate them into the starting position
'
dim float startangle=-45
for i=0 to nt-1 'load the coordinate arrays
rotatetriangle(i,pcolour,startangle,X_point+X_left,Y_point+Y_top,ptr(0,i),ptr(1,i),ptr(2,i),ptr(3,i),ptr(4,i),ptr(5,i)) 'rotate the pointer into the drawing array
next i
'
' Now calculate the box on the screen that covers all of the triangles
'
getlimits(x, y, w, h)
'
' save the box so that we can restore it later
'
blit read #1, x, y, w, h
'
' write out the initial set of triangles to the screen
'
for i=0 to 3
triangle xx0(i), yy0(i), xx1(i), yy1(i), xx2(i), yy2(i), tcol(i),tcol(i)
next i
'
' Main loop' Here we would read in some real world value and convert it to an angle
' so for example a temperature ,0-100 degrees could be scaled -45 to 45 degress
'
dim float temperature = 0
do
do
drawpointer(temperature/100*90-45)
pause 50
temperature=temperature+1
loop while temperature <=100
do
drawpointer(temperature/100*90-45)
pause 50
temperature=temperature-1
loop while temperature >=0
loop
'
' Subroutine that:
' 1: calculates the coordinates of the triangles making up the new pointer
' 2: calculates the screen area that will cover the new pointer
' 3: erases the last pointer by restoring the background
' 4: saves the screen area that will be written to by the new pointer
' 5: draws the new pointer
'

Sub drawpointer(angle as float)
local integer last_x=x, last_y=y, last_w=w, last_h=h, i
for i=0 to nt-1
rotatetriangle(i,pcolour,angle,X_point+X_left,Y_point+Y_top,ptr(0,i),ptr(1,i),ptr(2,i),ptr(3,i),ptr(4,i),ptr(5,i)) 'rotate the pointer into the drawing array
next i
getlimits(x, y, w, h)
blit WRITE #1, last_x, last_y, last_w, last_h
blit close #1
blit read #1, x, y, w, h
for i=0 to 3
triangle xx0(i), yy0(i), xx1(i), yy1(i), xx2(i), yy2(i), tcol(i),tcol(i)
next i
End Sub

'
' Routine to find the coordinates of the area to be saved by BLIT READ
'
sub getlimits(x as integer, y as integer, w as integer, h as integer)
Local integer i,max_x=0,min_x=MM.HRES,max_y=0,min_y=MM.VRES
for i=0 to nt-1
if(xx0(i)>max_x)then max_x=xx0(i)
if(xx1(i)>max_x)then max_x=xx1(i)
if(xx2(i)>max_x)then max_x=xx2(i)
if(xx0(i)<min_x)then min_x=xx0(i)
if(xx1(i)<min_x)then min_x=xx1(i)
if(xx2(i)<min_x)then min_x=xx2(i)
if(yy0(i)>max_y)then max_y=yy0(i)
if(yy1(i)>max_y)then max_y=yy1(i)
if(yy2(i)>max_y)then max_y=yy2(i)
if(yy0(i)<min_y)then min_y=yy0(i)
if(yy1(i)<min_y)then min_y=yy1(i)
if(yy2(i)<min_y)then min_y=yy2(i)
next i
x=min_x
y=min_y
w=max_x-min_x+1
h=max_y-min_y+1
end sub
'
' Simple trig to rotate the vertices of a triangle
' specified as x0,y0,x1,y1,x2,x2 relative to coordinate 0,0
' by the angle specified
' and then translate them about the supplied real centre x,y
' the calculated coordinates are then placed into element n of a set of coordinate arrays
'
sub rotatetriangle(n as integer, col as integer, angle as float, x as integer, y as integer, x0 as integer, y0 as integer, x1 as integer, y1 as integer, x2 as integer, y2 as integer)
local float sine=sin(rad(angle)),cosine=cos(rad(angle))
local integer x0a,y0a,x1a,y1a,x2a,y2a
x0a= x0*cosine - y0 * sine + x
y0a= y0*cosine + x0 * sine + y
x1a= x1*cosine - y1 * sine + x
y1a= y1*cosine + x1 * sine + y
x2a= x2*cosine - y2 * sine + x
y2a= y2*cosine + x2 * sine + y
xx0(n)=x0a
yy0(n)=y0a
xx1(n)=x1a
yy1(n)=y1a
xx2(n)=x2a
yy2(n)=y2a
tcol(n)=col
end sub

end sub
Edited by matherp 2017-02-23
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 844
Posted: 02:06am 22 Feb 2017
Copy link to clipboard 
Print this post

Peter,
A question about the relative memory usage of using BLIT in comparison to the triangles() CFunction.

In the case of a gauge's needle(s) being made of multiple triangles (e.g. clock or your 4 triangle needle) is it the case that the triangles() function will save a rectangles to enclose each individual triangle to memory and the BLIT will save a single rectangle to memory that encloses all the triangles.

(I looked at the C code but am not really sure if its doing each triangle separately.)

If my understanding is correct BLIT would be more efficient on memory usage in most cases if you can manage with 8 BLIT areas.

Hope this makes sense,

Thanks
Gerry


Latest F4 Latest H7
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8604
Posted: 03:12am 22 Feb 2017
Copy link to clipboard 
Print this post

Gerry

It isn't as easy as that - is it ever

You are correct about the CFunction storing each triangle in turn. If they overlap then there will be wastage of memory. It stores triangles not rectangles so this is very efficient on memory but less so on processing.

BLIT stores rectangles, take the example of a thin pointer comprised of two triangles that is upright - say 5 pixels by 50. In this case the rectangle is perfect in memory usage: 5 * 50 * 3 = 750 bytes.

However, if that pointer is at 45-degrees then the rectangle is something slightly greater than 50 *0.707 * 50 * 0.707 * 3 = 3675 bytes.

For large pointers at angles near 45 degrees the Basic code may need to split the save into smaller areas. In the example if we split it into two the memory usage becomes 2 * 25 *0.707 * 25 * 0.707 * 3 = 1874 bytes.

For the purposes of the OP lets ignore this as it just confuses (me anyway)Edited by matherp 2017-02-23
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 11:05pm 13 Aug 2017
Copy link to clipboard 
Print this post

Peter
Could you explain what this means please?

I know (think*) this is the bit that makes the pointer move
but I don't understand it

I know (hope) if I change the dim statement to 360 then it should rotate 360°

dim float startangle=-0 would make the start angle of the pointer the 12 o clock position?

This is the bit I don't understand
drawpointer(temperature/100*90-45)

Why /100*90-45

Am I right in assuming if I put drawpointer 10 it would draw the pointer 10 degrees from the top and

What happens when I get to 181° do any of the figures go negative? or am I "understanding" totally wrong?


[code]' Main loop' Here we would read in some real world value and convert it to an angle
' so for example a temperature ,0-100 degrees could be scaled -45 to 45 degress
'
dim float temperature = 0
do
do
drawpointer(temperature/100*90-45)
pause 50
temperature=temperature+1
loop while temperature <=100
do
drawpointer(temperature/100*90-45)
pause 50
temperature=temperature-1
loop while temperature >=0
loop [/code]

I also don't understand this line
[code] for i=0 to nt-1
rotatetriangle(i,pcolour,angle,X_point+X_left,Y_point+Y_top,ptr(0,i),ptr(1,i),ptr(2,i),ptr(3,i),ptr(4,i),ptr(5,i)) 'rotate the pointer into the drawing array
next i [/code]
Edited by lew247 2017-08-15
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8604
Posted: 11:12pm 13 Aug 2017
Copy link to clipboard 
Print this post

  Quote  Why /100*90-45


  Quote  ' Main loop' Here we would read in some real world value and convert it to an angle
' so for example a temperature ,0-100 degrees could be scaled -45 to 45 degress
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 05:55am 14 Aug 2017
Copy link to clipboard 
Print this post

I've got the dial working the way I want
However I have 2 problems

1: the dial "shrinks widthwise after a few seconds)
2: out of memory error after the gauge moves around 300 steps

















The out of error message when the pointer stops moving is this
[code][115] Blit read #1, x, y, w, h
Error: Not enough memory
>
[/code]


Gauge (YouTube Link) showing the gauge working (no background picture at the moment*

This is the code
[code]
'*****Thanks to Matherp for the original code from which this was extracted from*****
option explicit
option default none
CLS
const Y_top = 0 'Y coordinate of top of the image file on the screen
const X_left = 267 'X coordinate of left of the image file on the screen
const Y_point = 130 'Y coordinate of the centre of the pointer relative to the image top
const X_point = 110 'X coordinate of the centre of the pointer relative to the image left

const buffersize = 2000 'used to store the image data behind the pointer
dim integer buff(buffersize)

dim integer nt=1 'Number of triangles used to define the pointer
dim integer ptr(5)=(-8,0, 8,0, 0,-100) ' define size of the pointers
DIM INTEGER pcolour)=(rgb(RED)) 'define the colour of the pointer
DIM float heading
const pivot=8 'diameter in pixels of the fulcrum of the pointer '
' Global Variable definitions
'
dim integer b
dim integer xx0,yy0,xx1,yy1,xx2,yy2,tcol
dim integer lc
dim integer x,y,w,h, xp1, yp1, wp1, hp1
cls rgb(white)

rotatetriangle(lc,pcolour,heading,X_point+X_left,Y_point+Y_top,ptr(0),ptr(1),ptr(2),ptr(3),ptr(4),ptr(5)) 'rotate the pointer into the drawing array
getlimits(x, y, w, h)
drawpivot(0)
blit read #1, x, y, w, h
triangle xx0, yy0, xx1, yy1, xx2, yy2, tcol,tcol

' Main program
'
for b = 1 to 360
pause 100
heading = heading+1
drawpointer(heading) 'draw the pointer 1 deg clockwise to what it was previously
next b

end
'
'Sub drawpointer(angle as float, offset as integer)
local integer last_x, last_y, last_w, last_h, i

rotatetriangle '(i,pcolour(i),angle,X_point+X_left,Y_point+Y_top,ptr(0,i),ptr(1,i),ptr(2,i),ptr(3,i),ptr(4,i),ptr(5,i)) 'rotate the pointer into the drawing array

if(offset=0) then
last_x=x: last_y=y: last_w=w: last_h=h
getlimits(x, y, w, h)
blit WRITE #1, last_x, last_y, last_w, last_h
blit close #1
blit read #1, x, y, w, h
else
last_x=xp1: last_y=yp1: last_w=wp1: last_h=hp1
getlimits(xp1, yp1, wp1, hp1)
blit WRITE #2, last_x, last_y+offset, last_w, last_h
blit close #2
blit read #2, xp1, yp1+offset, wp1, hp1
endif
for i=0 to nt-1
triangle xx0(i), yy0(i)+offset, xx1(i), yy1(i)+offset, xx2(i), yy2(i)+offset, tcol(i),tcol(i)
next i
drawpivot(offset)
End Sub

sub getlimits(x as integer, y as integer, w as integer, h as integer)
Local integer i,max_x=0,min_x=MM.HRES,max_y=0,min_y=MM.VRES
for i=0 to nt-1
if(xx0(i)>max_x)then max_x=xx0(i)
if(xx1(i)>max_x)then max_x=xx1(i)
if(xx2(i)>max_x)then max_x=xx2(i)
if(xx0(i)<min_x)then min_x=xx0(i)
if(xx1(i)<min_x)then min_x=xx1(i)
if(xx2(i)<min_x)then min_x=xx2(i)
if(yy0(i)>max_y)then max_y=yy0(i)
if(yy1(i)>max_y)then max_y=yy1(i)
if(yy2(i)>max_y)then max_y=yy2(i)
if(yy0(i)<min_y)then min_y=yy0(i)
if(yy1(i)<min_y)then min_y=yy1(i)
if(yy2(i)<min_y)then min_y=yy2(i)
next i
x=min_x
y=min_y
w=max_x-min_x+1
h=max_y-min_y+1
end sub

sub rotatetriangle(n as integer, col as integer, angle as float, x as integer, y as integer, x0 as integer, y0 as integer, x1 as integer, y1 as integer, x2 as integer, y2 as integer)
local float sine=sin(rad(angle)),cosine=cos(rad(angle))
local integer x0a,y0a,x1a,y1a,x2a,y2a
x0a= x0*cosine - y0 * sine + x
y0a= y0*cosine + x0 * sine + y
x1a= x1*cosine - y1 * sine + x
y1a= y1*cosine + x1 * sine + y
x2a= x2*cosine - y2 * sine + x
y2a= y2*cosine + x2 * sine + y
xx0(n)=x0a
yy0(n)=y0a
xx1(n)=x1a
yy1(n)=y1a
xx2(n)=x2a
yy2(n)=y2a
tcol(n)=col
end sub

Sub drawpointer(angle as float, offset as integer)
local integer last_x, last_y, last_w, last_h, i
for i=0 to nt-1
rotatetriangle(i,pcolour,angle,X_point+X_left,Y_point+Y_top,ptr(0),ptr(1),ptr(2),ptr(3),ptr(4),ptr(5)) 'rotate the pointer into the drawing array
next i
if(offset=0) then
last_x=x: last_y=y: last_w=w: last_h=h
getlimits(x, y, w, h)
blit WRITE #1, last_x, last_y, last_w, last_h
blit close #1
blit read #1, x, y, w, h
else
last_x=xp1: last_y=yp1: last_w=wp1: last_h=hp1
getlimits(xp1, yp1, wp1, hp1)
blit WRITE #2, last_x, last_y+offset, last_w, last_h
blit close #2
blit read #2, xp1, yp1+offset, wp1, hp1
endif
for i=0 to nt-1
triangle xx0(i), yy0(i)+offset, xx1(i), yy1(i)+offset, xx2(i), yy2(i)+offset, tcol(i),tcol(i)
next i
drawpivot(offset)
End Sub

sub drawpivot(offset%) 'put anything you like here to draw the fulcrum as you wish
circle X_point+X_left,Y_point+Y_top+offset%,pivot,0,,,rgb(RED)
end sub [/code]

Anyone able to tell me why both errors are happening?Edited by lew247 2017-08-15
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8604
Posted: 07:05am 14 Aug 2017
Copy link to clipboard 
Print this post

You've got two versions of drawpointer in the code, one of which you seem to have tried to simplify to only dealing with one triangle but bits of it still expect arrays and getlimits still expects arrays. It needs a lot more editing to make it just deal with one triangle. Easier would be to define the pointer as two triangles and go back to the original code
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 08:22am 14 Aug 2017
Copy link to clipboard 
Print this post

Thanks Peter I've modified the code again so it's definitely only using one "drawpointer"

The pointer crashes after moving 314 times
[quote][93] Sub drawpivot(offset%) 'put anything you like here to draw the fulcrum as you wish
Error: Not enough memory
>[/quote]

I still don't know why the pointer shrinks width wise after moving 28 times *****

I've shrunk the program down to the bare limits (I think) and I have kept it to one pointer rather than the compass double pointer I started off using as this fits perfectly with the wind vane direction picture I have ready to use*

I'm "very" close to what I need, I just need to know
1: Why it crashes on reaching 314 steps (movements)
2: Why the pointer shrinks after 28 steps


This is obviously extremely simple for most of you but because of my memory problems due to brain surgery it's extremely hard for me to comprehend.


[code]option explicit
option default none
CLS
const Y_top = 0 'Y coordinate of top of the image file on the screen
const X_left = 267 'X coordinate of left of the image file on the screen
const Y_point = 130 'Y coordinate of the centre of the pointer relative to the image top
const X_point = 110 'X coordinate of the centre of the pointer relative to the image left
const buffersize = 2000 'used to store the image data behind the pointer
dim integer buff(buffersize)

dim integer nt=1 'Number of triangles used to define the pointer
dim integer ptr(5)=(-5,0, 5,0, 0,-60) ' define size of the pointers
DIM INTEGER pcolour=(rgb(RED)) 'define the colour of the pointer
DIM float heading
const pivot=7 'diameter in pixels of the fulcrum of the pointer '
' Global Variable definitions
'
dim integer b
dim integer xx0,yy0,xx1,yy1,xx2,yy2,tcol
dim integer lc
dim integer x,y,w,h, xp1, yp1, wp1, hp1
cls rgb(white)

getlimits(x, y, w, h)
blit read #1, x, y, w, h

' Main program
for b = 1 to 360 'so I can see the pointer move one complete revolution
pause 100 'delay of 100mS so I can see the pointer steps
heading = heading+1 'increment the heading 1 degree clockwise
drawpointer(heading) 'draw the pointer
print b 'so I can see how many times the pointer moves before it crashes
next b
end

sub getlimits(x as integer, y as integer, w as integer, h as integer)
Local integer i,max_x=0,min_x=MM.HRES,max_y=0,min_y=MM.VRES
for i=0 to nt-1
if(xx0(i)>max_x)then max_x=xx0(i)
if(xx1(i)>max_x)then max_x=xx1(i)
if(xx2(i)>max_x)then max_x=xx2(i)
if(xx0(i)<min_x)then min_x=xx0(i)
if(xx1(i)<min_x)then min_x=xx1(i)
if(xx2(i)<min_x)then min_x=xx2(i)
if(yy0(i)>max_y)then max_y=yy0(i)
if(yy1(i)>max_y)then max_y=yy1(i)
if(yy2(i)>max_y)then max_y=yy2(i)
if(yy0(i)<min_y)then min_y=yy0(i)
if(yy1(i)<min_y)then min_y=yy1(i)
if(yy2(i)<min_y)then min_y=yy2(i)
next i
x=min_x
y=min_y
w=max_x-min_x+1
h=max_y-min_y+1
end sub

sub rotatetriangle(n as integer, col as integer, angle as float, x as integer, y as integer, x0 as integer, y0 as integer, x1 as integer, y1 as integer, x2 as integer, y2 as integer)
local float sine=sin(rad(angle)),cosine=cos(rad(angle))
local integer x0a,y0a,x1a,y1a,x2a,y2a
x0a= x0*cosine - y0 * sine + x
y0a= y0*cosine + x0 * sine + y
x1a= x1*cosine - y1 * sine + x
y1a= y1*cosine + x1 * sine + y
x2a= x2*cosine - y2 * sine + x
y2a= y2*cosine + x2 * sine + y
xx0(n)=x0a
yy0(n)=y0a
xx1(n)=x1a
yy1(n)=y1a
xx2(n)=x2a
yy2(n)=y2a
tcol(n)=col
end sub

Sub drawpointer(angle as float, offset as integer)
local integer last_x, last_y, last_w, last_h, i
rotatetriangle(i,pcolour,angle,X_point+X_left,Y_point+Y_top,ptr(0),ptr(1),ptr(2),ptr(3),ptr(4),ptr(5)) 'rotate the pointer into the drawing array
last_x=x: last_y=y: last_w=w: last_h=h
getlimits(x, y, w, h)
blit WRITE #1, last_x, last_y, last_w, last_h
blit close #1
blit read #1, x, y, w, h
triangle xx0(i), yy0(i)+offset, xx1(i), yy1(i)+offset, xx2(i), yy2(i)+offset, tcol(i),tcol(i)
drawpivot(offset)
End Sub

sub drawpivot(offset%) 'put anything you like here to draw the fulcrum as you wish
circle 377,130,pivot,0,,,rgb(54,54,54)
end sub [/code]
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8604
Posted: 09:56am 14 Aug 2017
Copy link to clipboard 
Print this post

You haven't modified getlimits and rotatetriangle. I'm amazed it works at all.

dim integer xx0,yy0,xx1,yy1,xx2,yy2,tcol


if(xx0(i)>max_x)then max_x=xx0(i)
if(xx1(i)>max_x)then max_x=xx1(i)
if(xx2(i)>max_x)then max_x=xx2(i)
if(xx0(i)<min_x)then min_x=xx0(i)
if(xx1(i)<min_x)then min_x=xx1(i)
if(xx2(i)<min_x)then min_x=xx2(i)
if(yy0(i)>max_y)then max_y=yy0(i)
if(yy1(i)>max_y)then max_y=yy1(i)
if(yy2(i)>max_y)then max_y=yy2(i)
if(yy0(i)<min_y)then min_y=yy0(i)
if(yy1(i)<min_y)then min_y=yy1(i)
if(yy2(i)<min_y)then min_y=yy2(i)


yy0(n)=y0a
xx1(n)=x1a
yy1(n)=y1a
xx2(n)=x2a
yy2(n)=y2a
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 10:04am 14 Aug 2017
Copy link to clipboard 
Print this post

  matherp said   You haven't modified getlimits and rotatetriangle. I'm amazed it works at all.


Because I didn't (still don't) have a clue what they mean or how they work

I'll try and figure it out
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 10:53pm 14 Aug 2017
Copy link to clipboard 
Print this post

If I want the dial to rotate 360 degrees then I won't need to set limits will I?
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 844
Posted: 12:14am 15 Aug 2017
Copy link to clipboard 
Print this post

Hi Lewis,

The getlimits() function is about determining the size of the rectangle that will enclose the defined triangle you need to save to memory. Currently its using variables you have not defined.

If you make the change as below you get a bit closer, seems to run for me.
i.e. remark out the line
dim integer xx0,yy0,xx1,yy1,xx2,yy2,tcol
and use instead.
dim integer xx0(nt),yy0(nt),xx1(nt),yy1(nt),xx2(nt),yy2(nt),tcol(nt)



'dim integer xx0,yy0,xx1,yy1,xx2,yy2,tcol
dim integer xx0(nt),yy0(nt),xx1(nt),yy1(nt),xx2(nt),yy2(nt),tcol(nt)


Regards
Gerry
Latest F4 Latest H7
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 12:33am 15 Aug 2017
Copy link to clipboard 
Print this post

  disco4now said   Hi Lewis,
The getlimits() function is about determining the size of the rectangle that will enclose the defined triangle you need to save to memory. Currently its using variables you have not defined.

If you make the change as below you get a bit closer, seems to run for me.

'dim integer xx0,yy0,xx1,yy1,xx2,yy2,tcol
dim integer xx0(nt),yy0(nt),xx1(nt),yy1(nt),xx2(nt),yy2(nt),tcol(nt)

Regards
Gerry


Gerry your a genius
Thank you so much, that does exactly what I need it to do
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 11:00am 15 Aug 2017
Copy link to clipboard 
Print this post

Gauge test on YouTube

Just uploaded a test of the gauge, I like how it works and looks, I'd be grateful if someone could take a look and tell me if it looks ok.

One problem I noticed is the time doesn't update while the test is running, thats because it's the only thing the MM is doing at that moment.
In real life it will only update with a wind direction change
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1994
Posted: 06:30pm 15 Aug 2017
Copy link to clipboard 
Print this post

@lew247

I like the whole thing - nice clean interface - it's going to be superb!

this sort of stuff never stops blowing me away - how, with persistence and work, you can end up with something so professional looking that you did in your own worksop. My stuff is rarely "visual" -I am just naturally drawn to process & control, stuff that happens in the dark and it is always good for me to see what can be done at the human interface level.

nice.Edited by CaptainBoing 2017-08-17
 
lew247

Guru

Joined: 23/12/2015
Location: United Kingdom
Posts: 1676
Posted: 09:26pm 15 Aug 2017
Copy link to clipboard 
Print this post

@matherp @disco4now or anyone really

I found one "slight" problem

The needle on the gauge works perfectly, however while running the test overnight where I do a simple loop test ie the needle goes through all 360° and then runs again doing the exact thing
I end up with 2 needles
The original stuck on the North position 360° and the "new" needle doing what it's meant to do - moving 1 step at a time till it reaches north again

Anyone got any ideas why this is happening? or even better telling me how to clear the original needle before it starts drawing the new needle

I "think" it's to do with the "blit read" but not sure
I tried moving this into the loop where the needle gets drawn but it doesn't work there. (it says "buffer in use")

I'd like to solve this as it will probably cause a problem with the direction gauge when I finish the weather display properly

example picture


Edited by lew247 2017-08-17
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 844
Posted: 01:56am 16 Aug 2017
Copy link to clipboard 
Print this post

Hi Lewis,
The initial

getlimits(x, y, w, h)
blit read #1, x, y, w, h

lines should only be run once I think. You might have to show how your are repeatedly call the code. The method below seems to work OK for me.



getlimits(x, y, w, h)
blit read #1, x, y, w, h
do
' Main program
for b = 1 to 360 'so I can see the pointer move one complete revolution
pause 10 'delay of 100mS so I can see the pointer steps
heading = heading+1 'increment the heading 1 degree clockwise
drawpointer(heading) 'draw the pointer
'print b 'so I can see how many times the pointer moves before it crashes
next b
loop
end



Also a modified drawpointer. i is used as an index. You are getting away with not setting it as you only have one triangle so the default value of 0 is working, but really should be set explicitly based on iterating through the number of triangles, I have added the for i=0 to nt-1 loops where required.
I have also added a loop using the getscanline() function in an attempt to reduce flicker on the screen


Sub drawpointer(angle as float, offset as integer)
local integer last_x, last_y, last_w, last_h, i
  for i=0 to nt-1
'rotate the pointer into the drawing array for each triangle
rotatetriangle(i,pcolour,angle,X_point+X_left,Y_point+Y_top,ptr(0),ptr(1),ptr(2),ptr(3),ptr(4),ptr(5))
NEXT i
last_x=x: last_y=y: last_w=w: last_h=h
getlimits(x, y, w, h)
blit WRITE #1, last_x, last_y, last_w, last_h 'update old rectangle with saved data
blit close #1 'free buffer
blit read #1, x, y, w, h 'save the new rectangle to memory
local integer k
do
k=getscanline()
loop while (k>200 AND k<350)
for i=0 to nt-1
'write new triangle for each triangle
triangle xx0(i), yy0(i)+offset, xx1(i), yy1(i)+offset, xx2(i), yy2(i)+offset, tcol(i),tcol(i)
NEXT i
drawpivot(offset)
End Sub



Latest F4 Latest H7
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9081
Posted: 01:36pm 16 Aug 2017
Copy link to clipboard 
Print this post

[Quote=lew247]This is obviously extremely simple for most of you but because of my memory problems due to brain surgery it's extremely hard for me to comprehend.[/Quote]

I very much doubt that. I have been following this thread, but all the maths in these blit controls totally baffles me, and I am 100% lost with all that array manipulation. You are one-up on me in so far as you are trying to work them out. Me, I just elect not to use those commands in order to save what little remains of my sanity these days.
Smoke makes things work. When the smoke gets out, it stops!
 
     Page 1 of 3    
Print this page
© JAQ Software 2024