Posts with «lcd display» label

Burn Some Time with this Arduino Reddit Browser

If you’re like us, you probably spend more time browsing Reddit than you’d like to admit to your friends/family/boss/therapist. A seemingly endless supply of knowledge, wisdom, and memes; getting stuck on Reddit is not unlike looking something up on Wikipedia and somehow managing to spend the next couple hours just clicking through to new pages. But we’re willing to bet that none of us love browsing Reddit quite as much as [Saad] does.

He writes in to tell us about the handheld device he constructed which lets him view random posts from the popular /r/showerthoughts sub. Each press of the big red button delivers another slice of indispensable Internet wisdom, making it a perfect desk toy to fiddle with when you need a little extra push to get you through the day. Like one of those “Word a Day” calendars, but one that you’ll actually read.

For those curious as to how [Saad] is scraping Reddit with an Arduino, the short answer is that he isn’t. Posts are pulled from Reddit using an online tool created for the project by his wife (/r/relationshipgoals/), and dumped into a text file that can be placed on the device’s SD card. With 1500 of the all-time highest rated posts from /r/showerthoughts onboard, he should be good on content for awhile.

[Saad] has done an excellent job documenting the hardware side of this build, providing plenty of pictures as well as a list of the parts he used and a few tips to help make assembly easier. Overall it’s not that complex a project, but his documentation is a big help for those who might not live and breathe this kind of thing.

For the high-level summary: it uses an Arduino Pro Mini, a ILI9341 screen, and a 3.3 V regulator to step down 5 V USB instead of using batteries. A bit of perfboard, a 3D printed case, and a suitably irresistible big red button pulls the whole thing together.

We’ve seen a similar concept done in a picture frame a couple of years back, but if that’s not interactive enough you could always build yourself a Reddit “controller”.

Better 3D Graphics On The Arduino

There are cheap LCDs available from China, and when plugged into an Arduino, these displays serve as useful interfaces or even shinier baubles for your latest project. [Michael] picked up a few of these displays in the hope of putting a few animated .GIFs on them. This is an impossible task with an ATMega microcontroller – the Arduino does not have the RAM or the processing power to play full-screen animations. It is possible to display 3D vector graphics, with an updated graphics library [Michael] wrote.

The display in question uses the ILI9341 LCD driver, found in the Adafruit library, and an optimized 3D graphics driver. Both of these drivers have noticeable flicker when the animation updates, caused by the delay between erasing a previous frame and when a new frame is drawn.

With 16-bit color and a resolution of 320×240 pixels, there simply isn’t enough memory or the processing power on an ATMega microcontroller to render anything in the time it takes to display a single frame. There isn’t enough memory to render off-screen, either. To solve this problem, [Michael] built his render library to only render pixels that are different from the previous frame.

Rendering in 3D presents its own problems, with convex surfaces that can overlap themselves. To fix this, [Michael]’s library renders objects from front to back – if the pixel doesn’t change, it doesn’t need to be rendered. This automatically handles occlusions.

In a demo application, [Michael]’s LCD and Arduino can display the Stanford bunny, a low-poly 3D face, and geometric object. It’s not a video game yet, but [Michael] thinks he can port the classic game Spectre to this platform and have it run at a decent frame rate.

Video of the demo below.

Filed under: Arduino Hacks

Master Clock Keeps Time for All Other Clocks

[Brett] just finished construction and long-term testing of this extremely accurate timepiece. It keeps such great time by periodically syncing with the atomic clock in Mainflingen, Germany.

The core of the project is an ATMega328 which uses the new DCF77 library for decoding the signal broadcast by an atomic clock. The libraries written by Udo Klein significantly increase the noise tolerance of the device reading the signal, but they will not work with any project that use a resonator rather than a crystal.

In the event of a complete signal loss from the atomic clock, the micro driving the clock also has a backup crystal that can keep the clock running to an accuracy of within 1 second per day. The clock can drive slave clocks as well, using pulses with various timings depending on what [Brett] needs them to do. The display is no slouch either: six seven-segment displays show the time and an LCD panel reads out data about the clock. It even has chimes for the hour and quarter hour, and is full of many other features to boot!

One of the most annoying things about timekeeping is daylight savings time corrections, and this clock handles that with a manual switch. This can truly take care of all of your timekeeping needs!

Filed under: clock hacks

Audio VU Meter.

Simple project, some kind of “Arduino-Wiki” for beginners.

How to do measurements right:

  1. Biasing AC input using resistor divider and scaling up / down if necessary;
  2. Sampling fast and accurately using direct access to Control Registers of ADC and Timer1;
  3. Subtract whatever was added at step #1 from result of Analog / Digital conversion and Square;
  4. Average / accumulate, filtering following VU specification;
  5. Sqrt – take square root, Log10 – transform to dB scale;
  6. Display.

 1.   Hope, you follow my advice and hack your cheap USB speakers, to get nice ( pre-assembled ! ) analog “front-end” for this project. If not, than get your soldering iron to work, minimum two resistors and 1 cap would required, assuming you already have display wired up and running.

 First things with AC measurements ( audio in this category ) on Atmel microcontroler is to get rid of negative half-wave of the input signal, and this what front-end circuitry should do. There are at least two option: rectifying AC to DC before voltage could reach arduino analog input, or biasing signal with external DC offset. Rectification, could nicely be done with help of specifically design IC, LM3914 / 15 / 16 for example. But in this article, I’d describe second alternative, as it’d be not fare to ask you to hack your speakers and than tell you to solder another board…. Here is my set-up, slightly modified version from last blog:

When AC input signal is mixed with DC offset, so it stays always in positive area, ( think about sine, which defined betseen -1 and +1, if I add +1 it always would be positive ), I only save arduino life, preventing it from destruction by negative voltage. When arduino ADC completes conversion from analog to digital form, I don’t need DC offset anymore, and it should be subtracted.

  NOTE: DC voltage was added just to pass audio through arduino ADC. 

2. Sampling subroutine is running at 40 kHz, that is more than enough for ANY application. You may decrease sampling rate to lower CPU load, with current settings VU metering consumes more than 50%. Higher sampling rate gives better linearity / precision over wide band, the same time with regular audio content even 10 kHz sampling would provide better than 1 dB accuracy. All input capture process goes in Interruption subroutine, which is configured in setup. Two channels of Timer 1 Configured to run in parallel, “A” is responsible to keep clock at 40 kHz sharp, and “B” fires start conversion event to ADC with the same speed. Restarting new conversion via hardware provides lowest phase noise compare to any other way of doing this.

     ADCSRB = ((1<<ADTS2)| // Sets Auto Trigger source – Timer/Counter1 Compare Match B

/* Set up TIMER 1 – ADC sampler */
       TCCR1A = ((1<<WGM11) | (1<<WGM10)); // Mode 15, Fast PWM
       TCCR1B = ((1<<WGM13) | (1<<WGM12)); // Mode 15, Fast PWM

       TCCR1B |= (1<<CS10); // clk/1 prescaling.
       OCR1A = SMP_TMR1;
       OCR1B = SMP_TMR1;

      TIFR1 |= (1<<OCF1B); 
      TIMSK1 |= (1<<OCIE1B);

3 .  As you can see in a code snipped below, adc_Offst is subtracted from new ADC result. Quite simple, value of DC offset ( adc_Offst ) was obtained in setup() during start up, using Arduino IDE “analogRead”. The only problem with this simple solution, is that no audio should be present at this moment ( start up ) at input, otherwise all measurements would be erroneous.

      int32_t temp = ADC – adc_Offst; 
                 temp = temp * temp;
      if ( temp > ppm_Level ) ppm_Level = ((ppm_Level * 255) + temp) >> 8;
      else ppm_Level = (ppm_Level * 16383) >> 14; 

4. The same piece of code includes VU filtering algorithm. I was trying to get as close to standard as possible, but tough timing requirements ( 25 usec ! ) doesn’t allow get full satisfaction. Attack time is very close to specification, 3 milliseconds or so. Decay, I’d estimate in 200 milliseconds, which is less than recommended 650 milliseconds for Peak Program Meter (PPM), and also less than 300 milliseconds for regular VU.  The limits come from 32-bit integer math, from one side, and high sampling rate from another.


This comparison operator     if ( temp > ppm_Level )  separates attack – when new value is bigger than stored, and decay – when new value is smaller. Now, lets me explain what this line of code does:

     ppm_Level = ((ppm_Level * 255) + temp) >> 8;
Rewriting it to:  ppm_Level = ((ppm_Level * 255) + temp) / 256;

and than:          ppm_Level = ppm_Level *  ( 255 / 256 ) + temp * ( 1 / 256 );

reveals:            ppm_Level = ppm_Level *  0.99609375 + temp * 0.00390625;

Which is simple, single pole Low Pass Filter. For more details on recursive filtering I’d refer to this book. Equation 19.2.   Trick with right shift operator (>>8) is just to improve speed of calculation. Remind you, that Arduino doesn’t have floating point CPU, and any mathematics work with floating point coefficient very slow.

Same with filtering decay process, the difference is only in coefficient value.

( >> 14) is the same as 1 / 16384,   and so   16383 / 16384 = 0.999938965.

5.   Read comments, please:

    int32_t temp;

     temp = ppm_Level;                        // Take a copy, so Real Value not affected by calculation.
     temp = sqrt(temp);

    rms_Level = 20.0 * log10(temp +1); // Calculated, available over Serial

6. Last part, drawing VU indicator on graphical display. Ones again, referring you to short hardware description of using model.  There is not much to say, all display interface based on GLCD library. The only “tweak” from my side, is that I added “if” condition in front of drawing needle subfunctions:

      if ( abs(st1 – st2) > 3 )                          //  ~1/3 dB

I discovered, that DrawLine is quite slow, 4 calls ( 2 – erase, 2 – draw, all double – to make needle thicker ) take 125 milliseconds, so it make sense not to draw anything if there is not big difference between old and new needle position. At least, new position has to be off by width of the needle itself.

Link to Arduino (UNO) sketch: download.