Spiro Rainbow Pattern Generator




Another project using an Arduino UNO and a 2.2" TFT graphics display. This sketch just generates pretty patterns using epicycles.

Have a look at my other instructables for some of the development background.

Teacher Notes

Teachers! Did you use this instructable in your classroom?
Add a Teacher Note to share how you incorporated it into your lesson.

Step 1: Connecting Up the UNO to the TFT Screen

The UNO is connected to the ILI9241 2.2" TFT display like this:

    • UNO +5V to display pin 1 (VCC)
    • UNO +5V through a 56 Ohm resistor to display pin 8 (LED)
    • UNO 0V (GND) to display pin 2 (GND)
    • UNO digital pin 7 through a 1K2 resistor to display pin 4 (RESET), add a 1K8 resistor from display pin 4 to GND
    • UNO digital pin 9 through a 1K2 resistor to display pin 5 (DC/RS), add a 1K8 resistor from display pin 5 to GND
    • UNO digital pin 10 through a 1K2 resistor to display pin 3 (CS), add a 1K8 resistor from display pin 3 to GND
    • UNO digital pin 11 through a 1K2 resistor to display pin 6 (SDI/MOSI), add a 1K8 resistor from display pin 6 to GND
    • UNO digital pin 13 through a 1K2 resistor to display pin 7 (SCK), add a 1K8 resistor from display pin 7 to GND

    It is important to include the 1K8 resistors to GND with this 2.2" display as otherwise it will not work. The 1K2 and 1K8 resistors are a "potential divider", acting as a logic level shifter so that the logic level at the display is reduced from 5V to around 3V. Pin 9 of the display does not need to be connected up.

    Step 2: Spiro Sketch and Libraries

    The graphics libraries needed are in the attached zip file. The Spiro sketch is within the examples of the "Adafruit_ILI9341_AS" library.

    The libraries are the latest version superseding the version here. Some more enhancements have been made to improve drawing speeds.

    Step 3: Pattern Algorithm

    The patterns are produced by drawing single coloured pixels at the tip of a rotating vector, the centre of this vector is also rotating about the centre of the screen. Various parameters (radii and ratios) are changed at random before each pattern is drawn, in this way thousands of different patterns are generated. The pixel drawn changes through the colours of the rainbow, generating some nice aliasing effects.

    The pictures presented are deliberately blurred slightly as this is the only way that my webcam can capture the vibrant colours properly.

    Step 4: Your Patterns?

    If you have created a sketch that generates amazing coloured patterns using the hardware setup and libraries in this instructable, then it would be great if you post the sketch below. Thanks and have fun!

    Be the First to Share


      • Made with Math Contest

        Made with Math Contest
      • Multi-Discipline Contest

        Multi-Discipline Contest
      • Robotics Contest

        Robotics Contest

      10 Discussions

      Nice work - I've been looking at graphics libraries for the 9341 that will fit on the smaller arduinos (Uno / Pro Mini); the UTFT and ucgLib libs are good, but BIG, and I think your libs are the best compromise between size and aesthetics.

      1 reply

      Reply 4 years ago on Introduction

      Thank you. Reducing the size of the compiled sketch to fit in the UNO and Mini Pro was the prime reason for adapting and developing the libraries. I have reduced the compiled size even more by Run Length Encoding the larger fonts (size 4 upwards), a new library will be released in a couple of week when I have migrated my test code to drive the 9341 based display.


      5 months ago

      I realize this is an old instruct-able, and I imagine there are some updates. I tried to load this on a pro-mini and the Arduino compiler returned an error that it was too large. Is there an updated version?


      Reply 4 years ago on Introduction

      great job, thank you very much
      i use a 9340 2.2 tft, it works unless i can't change pins cs rst and dc
      in your sketch can we change these pins ? with using a tft 9341 of course.
      my tft doesn't work with adafruit_9341 lib but ok with adafruit_9340 and choice free of dc,rst,cs, so i think it's a 9340 driver, it looks like yours
      but not matter it's ok for me
      cheers from belgium


      Reply 4 years ago on Introduction

      You can change the pins but then you must comment out the line:

      #define F_AS_T

      in the library file "Adafruit_ILI9241_FAST.h" within the library. It will then run more slowly as direct port access for the control signals is not used. Not sure the library will work if you have a ILI9340 chip in your display.


      Reply 3 years ago

      Hi again Bodmer, just a quick question - if you want to use a Arduino MEGA how would you set the pins for this, as I know that the MEGA's use hardware SPI on pins 51(MOSI) and 52(SCK) instead of the Uno's 12 and 13. Is this an easy change to make? I have reached the memory limit of my Uno that's all! Thanks!


      Reply 3 years ago

      Sorry for the delay in replying. Yes, the library should work fine with a Mega. As you say just use the pins 51 and 52 instead. Have you tried this?


      4 years ago on Introduction

      Replace the loop() with the text below and you will see an image produced from part of the Mandlebrot set (due to the maths involved drawing is slow!):

      void loop()
      for (int px = 1; px < 320; px++)
      for (int py = 0; py < 240; py++)
      float x0 = (map(px, 0, 320, -250000/2, -237500/2)) / 100000.0; //scaled x coordinate of pixel (scaled to lie in the Mandelbrot X scale (-2.5, 1))
      float y0 = (map(py, 0, 240, -75000/4, -56000/4)) / 100000.0; //scaled y coordinate of pixel (scaled to lie in the Mandelbrot Y scale (-1, 1))
      float xx = 0.0;
      float yy = 0.0;
      int iteration = 0;
      int max_iteration = 128;
      while ( ((xx * xx + yy * yy) < 4) && (iteration < max_iteration) )
      float xtemp = xx * xx - yy * yy + x0;
      yy = 2 * xx * yy + y0;
      xx = xtemp;
      int color = rainbow((3*iteration+64)%128);
      tft.drawPixel(px, py, color);