 # Bodmer

125

## Achievements

100+ Comments Earned a bronze medal
10K+ Views Earned a bronze medal
• Try this modified function. I have added a new variable vt and set the threshold for colour change to 50.int ringMeter(int value, int vmin, int vmax, int x, int y, int r, char *units, byte scheme){ // Minimum value of r is about 52 before value text intrudes on ring // drawing the text first is an option x += r; y += r; // Calculate coords of centre of ring int w = r / 4; // Width of outer ring is 1/4 of radius int angle = 150; // Half the sweep angle of meter (300 degrees) int text_colour = 0; // To hold the text colour int v = map(value, vmin, vmax, -angle, angle); // Map the value to an angle v int vt = map(50, vmin, vmax, -angle, angle); // Map the threshold value (50 in this case) byte seg = 5; // Segments are 5 degrees wide = 60 segments for 300 degrees byte inc = …

see more »

Try this modified function. I have added a new variable vt and set the threshold for colour change to 50.int ringMeter(int value, int vmin, int vmax, int x, int y, int r, char *units, byte scheme){ // Minimum value of r is about 52 before value text intrudes on ring // drawing the text first is an option x += r; y += r; // Calculate coords of centre of ring int w = r / 4; // Width of outer ring is 1/4 of radius int angle = 150; // Half the sweep angle of meter (300 degrees) int text_colour = 0; // To hold the text colour int v = map(value, vmin, vmax, -angle, angle); // Map the value to an angle v int vt = map(50, vmin, vmax, -angle, angle); // Map the threshold value (50 in this case) byte seg = 5; // Segments are 5 degrees wide = 60 segments for 300 degrees byte inc = 5; // Draw segments every 5 degrees, increase to 10 for segmented ring // Draw colour blocks every inc degrees for (int i = -angle; i < angle; i += inc) { // Choose colour int colour = ILI9341_GREEN; if (i > vt) colour = ILI9341_RED; // Calculate pair of coordinates for segment start float sx = cos((i - 90) * 0.0174532925); float sy = sin((i - 90) * 0.0174532925); uint16_t x0 = sx * (r - w) + x; uint16_t y0 = sy * (r - w) + y; uint16_t x1 = sx * r + x; uint16_t y1 = sy * r + y; // Calculate pair of coordinates for segment end float sx2 = cos((i + seg - 90) * 0.0174532925); float sy2 = sin((i + seg - 90) * 0.0174532925); int x2 = sx2 * (r - w) + x; int y2 = sy2 * (r - w) + y; int x3 = sx2 * r + x; int y3 = sy2 * r + y; if (i < v) { // Fill in coloured segments with 2 triangles tft.fillTriangle(x0, y0, x1, y1, x2, y2, colour); tft.fillTriangle(x1, y1, x2, y2, x3, y3, colour); text_colour = colour; // Save the last colour drawn } else // Fill in blank segments { tft.fillTriangle(x0, y0, x1, y1, x2, y2, ILI9341_GREY); tft.fillTriangle(x1, y1, x2, y2, x3, y3, ILI9341_GREY); } } // Convert value to a string char buf; byte len = 4; if (value > 999) len = 5; dtostrf(value, len, 0, buf); // Set the text colour to default tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); // Uncomment next line to set the text colour to the last segment value! // tft.setTextColor(text_colour, ILI9341_BLACK); // Print value, if the meter is large then use big font 6, othewise use 4 if (r > 84) tft.drawCentreString(buf, x - 5, y - 20, 6); // Value in middle else tft.drawCentreString(buf, x - 5, y - 20, 4); // Value in middle // Print units, if the meter is large then use big font 4, othewise use 2 tft.setTextColor(ILI9341_WHITE, ILI9341_BLACK); if (r > 84) tft.drawCentreString(units, x, y + 30, 4); // Units display else tft.drawCentreString(units, x, y + 5, 2); // Units display // Calculate and return right hand side x coordinate return x + r;}

• The sketch is in a zip file at the end of Step 2.

The sketch uses the SdFat library. Make sure this SdFat library is loaded and the examples run. If the display is connected when you run an SdFat example then set the TFT CS line high at the start of setup() to avoid SPI bus conflicts.

• Unfortunately there is no manual. The library uses the same functions as the Adafruit_GFX library plus some new ones associated with the fonts and text handling. It is a case of looking at the examples.

• Connect as in Step 1 for 2.2" QVGA TFT SPI display. Use this library:https://github.com/Bodmer/TFT_ILI9341

Set the foreground and background colors and the test should overwrite old values.

The library has evolved, I am not sure which variant you have adapted but the library now has two functions that should do what you want: drawNumber(value, x, y, font), drawFloat(floatNumber, number_of_decimal_places, x, y, font),

Thanks for the feedback, I had hoped folk would benefit. Hope your project is a success.

• Are you sure yiu have the v8 version from step 2 of the Instructable loaded as I can see the function exists.

• No, sorry!

That is an UNO display with 8 bit parallel interface. You could try the library here:https://github.com/prenticedavid/MCUFRIEND_kbv

Great! Thanks for the feedback!

The setTextColor() function is defined in the Adafruit_GFX_AS.h header and .cpp file so this suggests that the library is not being called in the sketch or is not being found by the Arduino IDE.

• It looks like you have switched off rendering the font text background?Use a line like:tft.setTextColor(TFT_WHITE,TFT_BLACK);

• It is in the Libraries_v7.zip file in Step 2 of the Instructable.

• Hi, the library is optimised for AVR processors so unfortunately the M0 is not supported. Thanks for your feedback.

• It looks like the screen has a different driver chip to the ST7735.I suggest you wire the Arduino barnd TFT to the UNO and follow the official Arduino site online instructions for that display and use the recommended libraries. Once that is working we can progress to one of my adapted libraries.Bodmer

• The library was not written to be compatible with Teensy boards so you have done well to convert it. The drawRightString() function should plot the text right justified. It worked with the stock Arduino boards.Hope your project is a success.

• The display is fitted with a regulator so you can connect 5V to the VCC pin. The signal lines (SCK etc) however require 3.3V logic levels, so you need those resistors as you have drawn. The resistors act as a voltage divider so the display gets the right logic levels from a 5V UNO.Some displays do not have a current limit resistor for the LED, so it best to add one:UNO +5V through a 56 Ohm resistor to display pin LED

• It should be compatible. Look at the graphicstest example and you will see the small changes needed to call up the library.

• OK, yes this RAM write coordinate frame rotation was considered and tried out but it complicates things at the rendering level and the compression benefits are small in the grand scheme of things (compared to the big improvement when using the RLE method. Also for some reason the "wiping" of text onto the screen seemed worse for visual appeal, which might seem counter-intuitive.I have used the RAM frame of reference rotation when rendering BMP images as they draw from the bottom up.I also had the intent of encoding anti-aliased fonts using a variant of the Run Length methods and using another flag bit plus a 4 bit pixel brightness. When rendering text you would then pre-calculate the 16 pixel colours based on the foreground and background colours, then the 4 bit value in the RLE…

see more »

OK, yes this RAM write coordinate frame rotation was considered and tried out but it complicates things at the rendering level and the compression benefits are small in the grand scheme of things (compared to the big improvement when using the RLE method. Also for some reason the "wiping" of text onto the screen seemed worse for visual appeal, which might seem counter-intuitive.I have used the RAM frame of reference rotation when rendering BMP images as they draw from the bottom up.I also had the intent of encoding anti-aliased fonts using a variant of the Run Length methods and using another flag bit plus a 4 bit pixel brightness. When rendering text you would then pre-calculate the 16 pixel colours based on the foreground and background colours, then the 4 bit value in the RLE values would be used to look up the pixel colour.For larger fonts yet another flag bit could be used for flagging a 8 bit or 16 bit encoded values, and yet another flag for embedded commands like swap colours, etc etcThough these possibiloities are all very interesting I only tend to work on stuff I need for my own projects, or if someone is paying me to do it!

I have not created any optimized libraries that support the HX8257D display :-(The Adafruit libraries have been written to provide generic support to as many Adafruit products as possible and have effectively been written to aid the sales of those products (would you buy a display if there was no supporting library?). Optimising for particular display+processor combinations would lead to lots of different hardware specific implementations that would need to be tested and managed. In practice a lot of users do not need a high performance, for example you might only look at a temperature reading on the display a couple of times a day once the project is built, so it depends what you want to do.

• Thanks for the feedback.Yes, I did consider that as characters have a lot of long vertical strokes, however the way the TFT's expect data is a raster scan in rows, so a horizontal encoding fits well with this scheme and allows characters to be streamed very quickly.Cheers

• A character is drawn as a raster scan within a box size of the characters width and height. The RLE format is a byte, the top bit is a flag, the least significant 7 bits are a 7 bit number (0-127). If the flag is 1 then foreground pixels are plotted, if it is 0 the background pixels are plotted. The number of pixels to plot is the 7 bit number + 1.So, for example, the encoded sequence "0x81, 0x1F" means plot 2 pixels in foreground then 32 pixels in background.A user has sent me a Java app that does the RLE encoding of various font formats but I have not tried it yet. You could manually generate a single character using some squared paper and a pencil and replace the one in the above file.

• Hi, thanks for the feedback. Good luck with your project.

• If you are still interested then I have finally got around to porting the ILI9341 library to the NodeMCU! Performance is very impressive!You can find a copy of the library here:https://github.com/Bodmer/TFT_ILI9341_ESP

• It is not easy to add new fonts due to the way they are encoded for speed.I do plan to update the ILI9341 library soon to add in the Adafruit Free Fonts.

Images of any significant size take up a lot of space so you would need to look at using an SD card to store them. I have an instructable that may help:https://www.instructables.com/Arduino-TFT-displa...

• Have you got the DS3231 connected and working with a library example?I have used the "DS3231_Simple" library so that is one I recommend:https://github.com/sleemanj/DS3231_SimpleOnce you have one of the examples running and talking to the DS3231 post back here.

• Hi, just noticed this has gone unanswered for a while...Unfortunately I can't help you on this occasion.I suggest you ask for help on the Arduino forum in the "Displays" section. On the forum describe the problem, post a link to the vendor of your display, and post photos of the front and back of your display, this will help folk identify which display driver is on your board and tell you how to get it running.TTFN

• OK, thanks.In Arduino land a char is a signed value so it works OK. Since writing the library I have moved on to using different type designations like int16_t, uint16_t etc to make the code more portable and less compiler dependent.In later variants of the library I use Run Length Coding for the larger fonts so less FLASH is needed and also to speed up rendering on windowed plot area displays, but on an STM32 you probably are not bothered about that.Good luck with your project.

• Yes, that is correct.See post here:http://forum.arduino.cc/index.php?topic=181679.msg...:-)

• A character is drawn as a raster scan within a box size of the characters width and height. The RLE format is a byte, the top bit is a flag, the least significant 7 bits are a 7 bit number (0-127). If the flag is 1 then foreground pixels are plotted, if it is 0 the background pixels are plotted. The number of pixels to plot is the 7 bit number + 1.So, for example, the encoded sequence "0x81, 0x1F" means plot 2 pixels in foreground then 32 pixels in background.

The screen in your eBay link does not have a touch controller fitted, nor is touch screen capability mentioned in the advert. Look at the back of the display, is the place for U1 populated with an integrated circuit?

OK, glad to hear it is working. Good luck with your project.