The first blog was getting a little big so I decided to split it up and post updates in a new one and as it progresses have a little series on this journey if that's ok with you all. For those just catching on, you can read Part one here.
Just a highlight of what I have currently left to do:
- Rewrite the SD code to attempt to make it faster for load times etc.
- Write more functions into the LCD object to draw more graphics and handle different image drawing, as well as coming up with some alpha routines as well.
- Write a Touchscreen object to drive the Resistive touch panel on the LCD.
- Write some objects that use the data from the touch screen with positioning of paired images on the screen to make buttons, menus, sliders, etc. For a GUI interface.
- Beg people for some sound ideas to work with my Piezo buzzer to give some audio feedback as well.
- Write an object to access the font chip to utilize the text to go with the screen.
- Write some more objects and finish others to allow text to be added to them, e.g. msg boxes, labels, etc.
- Write code for the Flash chip cause I have no idea what to do with it but it was available, so by golly I'm gonna do something with it..... Just gotta figure out what :-/
- Take a tea and/or coffee break.
- Go back to same people and beg for graphics ideas.
- Set up a local Ethernet network with a switch and build a linux server.(Got the system, just need to get a hard drive for it)
- Install MQTT and some other server components that might be needed for my home automation system. The MQTT server can act as a good conduit to interface between the Interface panel, automation system, and various sensors and actuators.(Future projects planned.)
- Continue work on the Network code and program it to interface with the server and poll it for data.
- Write a sensor object to store retrieved data to utilize withe the GUI.
- Use all objects I have built up to this point to set up a GUI system to display sensor data, allow the user to make adjustments to various parameters, and make alerts to any changes or problems that should come to my attention.
- Design a case that can be 3D printed to house this screen with it's board.(I don't have a 3D printer so this part may be on hold for a while.)
I have improved on the SD code, still using the library but got it down to 3 second load time for a full 800x480 image off the SD compared to 7 before.
I have written more functions for graphics, however I still have much more I want to add, just needed a break from it. So far, I can draw points, triangles, lines, rectangles and circles. To make progress and not reinvent the wheel, I refered to the TFT GFX library for these functions. First one, I worked on was a circle, and I must say I was absolutely......Disappointed with the function. Not sure how it works on smaller screens but it says it draws circles but instead I got it to draw diamonds. So I trashed it and scoured the net for a new one. I did find one and it draws the circles beautifully. So I moved on.
I did manage to start work on the Touch Screen object, for those wondering, is an XPT2046 4 Wire Resistive Touch. It was fairly simple and strait forward to get up and going. Had some speed issues I needed to address but I finally got it spitting out valid data for the touch panel. Had to flip the x value of course as it was backwards. All I had to do now, was to convert the analog data to pixel coordinates to be useful for my code. Simple right? ........ NAH! My research showed me and everyone obviously knows this, you need calibration data for that analog data to be any use to you in regards to pixel conversion. In my research, most every high end document using resistive touch technology, used the same calibration equations. Made sense and was clearly the most accurate way to calibrate your screen. So I looked at what I would need to do to plug those into my code. To shave a little time, I decided to refer to the Arduino XPT2046 Touch library. Again, I was rather disappointed. It had absolutely nothing close to everything I've been researching. Now mind you the way it mapped the data, not sure how efficient it is at it compared to what I've already seen, heck it might even work. Dunno. Dun care. I shook my head and moved on. Spent many hours on it over the past few days, I got the equations put in, however I ended up encountering errors. Not sure if anyone else has had what I'm fixing to describe and this doesn't just count for this touch panel, this can count for anyone getting undesired figures and can't figure out why. I finally located the problem. About 1 hour ago to be precise. Anyways, it was outputting linear data for the analog touch sensing. the calibration routines was even producing valid values. However when I passed data thru the analog to pixel equation that was needed, I was getting erroneous pixel data. I'm talking positive to negative numbers based on where I touched the screen counting backwards, etc.The equation basically had me feed the values into an equation that looked like this (CoeffA * xval + CoeffB * yval + CoeffC) / CommonDivisor = XCoord, (CoeffD * xval + CoeffE * yval + CoeffF) / CommonDivisor = YCoord. Before someone scratches their heads and say umm.... believe me, if you solve those equations on paper they do work properly. the 6 different Coeffs are calibration data from the Calibration routine necessary to even get the pixels in the first place, and you need both vals to get each pixel data. This allows for scaling and rotation data if you have different screens. And you don't have to specify the screen dimensions and scale factor. You just got to tell it 3 points to calibrate to and it uses those 3 pixel data points in conjunction with their respective touch data to come up with vector coefficients stated above. Again solve the values on paper and it works. However, tell the Due to solve them and see what you get. I guarantee you the 2 numbers don't match. EVER! It frustrated the crap out of me, but there was a valid reason why it did it to, and I ended up breaking everything down to see which step it was failing at. OK enough suspense. Here's the trap. You must understand, first when dealing with an 800x480 screen and a Touch panel driver with a 12bit ADC providing you anywhere from 0-4096 on either plate, getting your coeffs get a little big. No problem a signed long holds it just fine. But when you solve the equation with the coeffs and the touch data to get your pixel, half way thru the calculation, before it gets divided by the divisor, the number gets big. I mean REALLY BIG. What is happening is the number exceeds the maximum value of the long variable and basically truncates the bits that are outside the bounds of the data type. Before the calculation is finished, your data just became invalid, producing the error I was seeing. Again, I got it fixed, but after thought, I think the only data type that would stand a chance is most likely the double data type, and that's only on the Due as it's 8 bytes long. And I'm not fixing to change and find out.There was another trick I discovered, and it rendered the divisor useless afterwards. What I ended up doing was dividing each coefficient byt the divisor individually. This drastically reduced the size of the data so instead of dividing a 100billion number by a 1million number, you were just doing the above calculations with a fraction and the touch data and it came out the same on the Due and on paper as if you performed the original calculation. Problem solved.
Little math lesson:
Here's why it works. For the sake of simplicity I will shorten the above variables.
XC = (A * X + B * Y + C) / D is the same as XC = A * X / D + B * Y / D + C / D Truthfully, it dosen't matter if you multiplied or divided first, your outcome will be the same either way. If you ever heard of Please Excuse My Dear Aunt Sally( Parentheses, Exponent, Multiply/Divide, Add/Subtract) In the order of solving your equation Multiply and divde are done in the same step, traditionally left to right, although you don't have to go left to right as long as you solve in the steps mentioned in this scheme.
So our equation now reads:XC = A * X / D + B * Y / D + C / D which you can reword to XC = A / D * X + B / D * Y + C / D. As you can see A, B, and C just became fractions. Smaller than the original equation and will not exceed the bounds of the variables you are trying to store them in. No here's also why I reversed them around. A, B, C, and D are all known at the time of calibration. X and Y are not, they are real time. If you go ahead and solve A / D, B / D, and C / D at calibration time, you end up storing it's result in A, B, C and saving you precious clock cycles when you convert the user input into screen coords a bagillion times.
Now all you are left with is:
XC = A * X + B * Y + C
Process is the same for YC with D, E, and F.
Needless to say, where I'm at right now, each time I start the Due up, it allows me to calibrate the touch, and everywhere I touch, it's providing me with pixel data. It has a little error now and again, and by that I mean when I calibrate, the outer edges might extend past the borders of the 800x480 screen datawise, but will not be noticeable anyways when you detect objects. And I figured out what I'm going to use the extra flash chip on the lcd for. It's going to store my calibration data and any other configuration I want this thing to remember when it cycles power. I hope this update will help anyone struggling with data problems that this could be a possible culprit for. These kind of errors can be frustrating and take some time to find. If I can finish this project and know that even if no one cared about why I'm doing this or the fact I'm sharing it with them, but if at least just 1 person read these articles and said AHA that's the problem I'm having, that's what I need to fix it, this just saved me a lot of time and aggravation. I'll be happy. Until next time guys
Top Comments