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 : Cartesian graphics pack nears completion
Author | Message | ||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2075 |
Evening forum. just wanted to share a little progress with you. I wrote a tiddly cartesian graphics pack a while ago (it's on FotS), but one aspect that I felt was always missing was a graphics window with scaling and proper boundaries (so you can't draw outside of the window) I got a suitable dev system up and runnng at last and I have been busy, see the tiddly graphic window on the screen below. The new ORIGIN command sets the X,Y position (0,0 can be anywhere on the screen), sets seperate scaling factors for both X & Y axis (so you can have a window a million pixels wide and still draw sensibly in it) and sets the boundaries for the window so it can occupy any portion of the screen... e.g. you could have a window at Native position 120,130 with it's 0,0 centred and scaled so the X axis was -273 to +100 and plot those coordinates in it without the sytem "cropping" the position of pixels/line you set... oh and the window could be just 20 pixels wide if you like. A picture paints a thousand words so an example of what I mean is below and shows the temperature/power curves (with dummy data) on my 3D printer heated bed controller: the drawable window is 80 X 30 pixels, but the X is scaled (in that 80 pixels) to show 400 points and the Y for 0 to 130. Note how the negative values do not plot out of the window and proportion is maintained. It isn't ready quite yet but I hope to be able to publish the finished pack soon. h Edited 2024-06-02 06:21 by CaptainBoing |
||||
Andrew_G Guru Joined: 18/10/2016 Location: AustraliaPosts: 847 |
Hi Cap'n, Just what I was looking for. I want to plot temperature over several days. Will it: 1) build from the left until it gets to xmax and then drop of the left most value 2) allow you to move y up and down (for different ranges of values) without losing data? I'm OK with the GUI controls bit of it - just having a mental block with the graphics. Cheers, Andrew |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2075 |
it doesn't make any association with data, it's a scaled bit of graph paper - what you draw on it is down to you so you'd still have to manage your data in an array or something and plot/draw the data points, which isn't hard really. For this demo, I have an array of 2x70 integers. You'd would just have your array big enough to hold what you want. If you want to compress the data I have a logger routine which packs 2-byte words into a single integer if that helps. In that screen grab, the little white rectangle reresents 0-130 on the Y (0-130C and 0-130W... convenient as my build plate has a 122W heater with a mximum heat of 110C) and 0-400 on the X even though it is only 30 pixels high and 70 wide. But I don't have to take the physical dimensions into account when I draw my lines. In the native graphics, if I did LINE 0,0 - 319,239 I get a line from the top left to bottom right, drawing all over anything else on the screen. Doing the same in the cartesian GFX pack; MOVE 0,0: DRAW 319,239 I would get a line from the bottom left of the white rectangle going off into nowhere about half way along (because 239 is beyond the boundary of the graphics window), but it would not corrupt anything else on the screen. With the scaling, I could literally have the window 86400 "pixels" wide which provides plot points for every second in a day, all in a space 70 "real" pixels wide. Of course there is a loss of granularity, but it works really great for a quick look at trends etc. and you can still do 1:1 scaling if you just want the graphic sindow with boundaries. In the pic above, there is no real detail in the graph (coz it is miniscule), but I can easily see what the temperature and power curves look like. The measurements are seperately output to the console so I can scrape that and put it into something like Excel if i need to analyze the real stuff. As for managng the data, I have an array where I store coordinates (so I don't do the scaling every time I need to re-draw the line) and I scroll it left as the diagram extends by clearing the window and re-drawing (which is surprisingly fast even on little mites) Addressing your specific questions: 1) build from the left until it gets to xmax and then drop of the left most value I do precisely this but it depends on your code. I have an array and a pointer to the next "entry" and I draw lines up to the pointer. When the pointer reaches the end of the array, I shuffle everything down one place and leave the pointer pointing to the last place. So in the above illustration, I only ever have 400 X plot points. When the shuffle happens, I clear the window and re-draw both lines so it gives a very pleasant scrolling-to-the-left effect, but its my prog that does this, not the GFX pack. Scrolling the window as a command is difficult because of the large variation in displays and their abilities - e.g. it would be easy on a CMM2 to use BLIT to move the rectangle, but how would you do it on a ILI9341 where the communication is largely one-way? 2) allow you to move y up and down (for different ranges of values) without losing data? same answer really. if you want to scroll, you have to manage how it's done because of the variation in displays and how they do it. h Edited 2024-06-02 23:15 by CaptainBoing |
||||
Amnesie Guru Joined: 30/06/2020 Location: GermanyPosts: 396 |
Hello, what an interesting idea! Fo what platform will it be? PicoMite? Geetings Daniel |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2075 |
Hi Daniel The GFX pack is all MMBasic and underneath are the normal MMBasic drawing primitives (LINE, PIXEL etc), no CSUBS or anything. the only requirements are the code (tiny) and a few global variables I see no reason it shouldn't work on any device with a graphics display. I am developing it on a MicroMite eXtreme with VGA display, but the first "real" target will be a Mk2 with ILI9341 - hence the Heated Bed Controller software in the pix/vid |
||||
Andrew_G Guru Joined: 18/10/2016 Location: AustraliaPosts: 847 |
Hi again. Thanks for that. Your video is exactly what I want to do. You have given me several pointers (pun intended) that I can now work through. Cheers, Andrew |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2075 |
glad to help - sorry about the awful quality of the vid... interference between scanlines. The code to manage the data (for me) is quite simple. define the storage for the data - 2 tracks, 70 points (I am using option base 0) Dim Integer Graph(69,1),ptr then the code to add the individual elements to the array and draw the graph... this also shuffles the data down and redraw the window if required. If ptr>69 Then ' shuffle the plot point down For n=1 To 69 Graph(n-1,gP)=Graph(n,gP) Graph(n-1,gT)=Graph(n,gT) Next ptr=69 Move 10,120'point to the first place Box Gx,Gy,70,-30,,RGB(White),RGB(White)' and clear the window EndIf Graph(ptr,gP)=Map(iCal,0,130,120,149)' scale data and store as pixel (Y) in the current places in the array Graph(ptr,gT)=Map(tmpC,0,120,120,149) For m=gP To gT' draw the trace for each data store Move 10,Graph(0,m)'puts us in the right place to start If m Then Colour RGB(BLUE) Else Colour RGB(RED)' choose the colour for the trace For n=1 To 69' just moved to 0 so start from 1'... and draw them all If n<=ptr Then Draw n+10,Graph(n,m) Next Next ptr=ptr+1' point to the next place in the store I have a few variables defined but you can work that out. Note I store pixel positions (not the actual data) in Graph() - this means I don't have to scale when I draw the line as a whole (when scrolling) - the array already contains what I need and it speeds thing up for the display - if you are going to want that raw data, make arrangements to keep it... It also uses the cartesian GFX pack and my version of the Map() function. This deceptively powerful function is responsible for the scaling. Map takes a value in a given linear range and returns the proportional counterpart in another range - so I could say I have a value 0-86399, return me that counterpart in the range of 0-69. e.g. supposing my value is 21600 (25% through a day) > Print Map(21600,0,86399,0,69) 17.25019966 so 17.2 is a quarter of the way to 69, in the same way 21600 is a quarter of the way to 86399 - it is the "proportional counterpart" in the range. Besides doing this, Map() also constrains the data to the ranges, so it is also responsible for enforcing the window boundaries - all in one small function. I have used it for so many things When I have it all working, the MAP will be handled in the new GFX pack, but I give it here so you get the idea of how the scaling works h Edited 2024-06-03 18:13 by CaptainBoing |
||||
phil99 Guru Joined: 11/02/2018 Location: AustraliaPosts: 2135 |
A while ago Peter introduced:- Which does a similar thing. There are a number of other new MATH commands and functions to help with data manipulation. Edit Noticed a typo in the description, replace Optionally, it can also return the minimum and maximum values found in the original data (“minin” and “minout”). with Optionally, it can also return the minimum and maximum values found in the original data (“minin” and “maxin”). Edited 2024-06-03 18:47 by phil99 |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2075 |
Yes that looks very nice and I think you are right it would provide the required functionality. I am designing for MicroMites which are never going to get such updates as the firmware space is full and they are considered "complete". Major bugs with no work-around may get some Pete time, but I would be seriously surprised if any such problems surfaced now... so I tend to be a bit biased on my "angle". I have three RPi2040s gathering dust in my storage. Whereas I am currently using an up-to-date MMX as my development rig, because of the target CPU for many of my projects, I stick to core MMBasic functions in the name of code transportability. If anyone wants to tweak it, feel free. h |
||||
Martin H. Guru Joined: 04/06/2022 Location: GermanyPosts: 1113 |
Just out of curiosity Is this just monitoring the sensors for 3D printers or are you rewriting Marlin in MM-Basic? 'no comment |
||||
CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2075 |
I don't know what marlin is. EDIT. Ah right. No I am not challenging Marlin's territory The 3D printer thing is just an aside to this thread - which is really about a scalable graphics window and associated drawing commands. I used my Heated Bed Controller as a container because it is a direct consumer of this work. The above screen is (will be) an update to my heated bed controller. That controls the heaters under the build plate to the settings in the display. With my printer, the heated bed controller is my own work and neither the printer or the controller know of each other's existence (My printer didn't have a heated bed originally). h Edited 2024-06-04 18:13 by CaptainBoing |
||||
Print this page |