Posts | Comments

Planet Arduino

Archive for the ‘dot’ Category

Set
13

Tutorial – LM3914 Dot/Bar Display Driver IC

bar, display, dot, driver, Electronics, example, IC, LED, level, LM3914, LM3915, LM3916, TI, tronixstuff, tutorial, voltmeter Commenti disabilitati su Tutorial – LM3914 Dot/Bar Display Driver IC 

Introduction

This is the first of three tutorials that will examine the LM391x series of LED driver ICs. In this first tutorial we cover the LM3914, then the LM3915 and LM3916 will follow. The goal of these tutorials is to have you using the parts in a small amount of time and experiment with your driver ICs, from which point you can research further into their theory and application.

Although these parts have been around for many years, the LM3914 in particular is still quite popular. It offers a simple way to display a linear voltage level using one or more groups of ten LEDs with a minimum of fuss.

With a variety of external parts or circuitry these LEDs can then represent all sorts of data, or just blink for your amusement. We’ll run through a few example circuits that you can use in your own projects and hopefully give you some ideas for the future. Originally by National Semiconductor, the LM391X series is now handled by Texas Instruments.

LM3914

Getting Started

You will need the LM3914 data sheet, so please download that and keep it as a reference. So – back to basics. The LM3914 controls ten LEDs. It controls the current through the LEDs with the use of only one resistor, and the LEDs can appear in a bar graph or single ‘dot’ when in use. The LM3914 contains a ten-stage voltage divider, each stage when reached will illuminate the matching LED (and those below it in level meter mode).

Let’s consider the most basic of examples (from page two of the data sheet) – a voltmeter with a range of 0~5V:

 LM3914 5V voltmeter circuit

The Vled rail is also connected to the supply voltage in our example. Pin 9 controls the bar/dot display mode – with it connected to pin 3 the LEDs will operate in bar graph mode, leave it open for dot mode. The 2.2uF capacitor is required only when “leads to the LED supply are 6″ or longer”. We’ve hooked up the circuit above, and created a 0~5V DC source via a 10kΩ potentiometer with a multimeter to show the voltage – in the following video you can see the results of this circuit in action, in both dot and bar graph mode:

Customising the upper range and LED current

Well that was exciting, however what if you want a different reference voltage? That is you want your display to have a range of 0~3 V DC? And how do you control the current flow through each LED? With maths and resistors. Consider the following formulae:

LM3914 formulae

As you can see the LED current (Iled) is simple, our example is 12.5/1210 which returned 10.3 mA – and in real life 12.7 mA (resistor tolerance is going to affect the value of the calculations).

Now to calculate a new Ref Out voltage – for example  we’ll shoot for a 3 V meter, and keep the same current for the LEDs. This requires solving for R2 in the equation above, which results with R2 = -R1 + 0.8R1V. Substituting the values – R2 = -1210 + 0.8 x 1210 x 3 gives a value of 1694Ω for R2. Not everyone will have the E48 resistor range, so try and get something as close as possible. We found a 1.8 kΩ for R2 and show the results in the following video:

You can of course have larger display range values, but a supply voltage of no more than 25 V will need to be equal to or greater than that value. E.g. if you want a 0~10 V display, the supply voltage must be >= 10V DC.

Creating custom ranges

Now we’ll look at how to create  a lower range limit, so you can have displays that (for example) can range from a non-zero positive value. For example, you want to display levels between 3 and 5V DC. From the previous section, you know how to set the upper limit, and setting the lower limit is simple – just apply the lower voltage to pin 4 (Rlo).

You can derive this using a resistor divider or other form of supply with a common GND. When creating such circuits, remember that the tolerance of the resistors used in the voltage dividers will have an affect on the accuracy. Some may wish to fit trimpots, which after alignment can be set permanently with a blob of glue.

Finally, for more reading on this topic – download and review the TI application note.

Chaining multiple LM3914s

Two or more LM3914s can be chained together to increase the number of LEDs used to display the levels over an expanded range. The circuitry is similar to using two independent units, except the REFout (pin 7) from the first LM3914 is fed to the REFlo (pin 4) of the second LM3914 – whose REFout is set as required for the upper range limit. Consider the following example schematic which gave a real-world range of 0~3.8V DC:

LM3914

The 20~22kΩ resistor is required if you’re using dot mode (see “Dot mode carry” in page ten of the data sheet). Moving on, the circuit above results with the following:

Where to from here?

Now you can visually represent all sorts of low voltages for many purposes. There’s more example circuits and notes in the LM3914 data sheet, so have a read through and delve deeper into the operation of the LM3914. Furthermore Dave Jones from eevblog.com has made a great video whcih describes a practical application of the LM3914:

Conclusion

As always I hope you found this useful. Don’t forget to stay tuned for the second and third instalments using the LM3915 and LM3916. Full-sized images are on flickr. And if you made it this far – check out my new book “Arduino Workshop” from No Starch Press.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial – LM3914 Dot/Bar Display Driver IC appeared first on tronixstuff.

Introduction

Time for another instalment in my highly-irregular series of irregular clock projects.  In this we have “Clock Four” – a scrolling text clock. After examining some Freetronics Dot Matrix Displays in the stock, it occurred to me that it would be neat to display the time as it was spoken (or close to it) – and thus this the clock was born. It is a quick project – we give you enough to get going with the hardware and sketch, and then you can take it further to suit your needs.

Hardware

You’ll need three major items – An Arduino Uno-compatible board, a real-time clock circuit or module using either a DS1307 or DS3232 IC, and a Freetronics DMD. You might want an external power supply, but we’ll get to that later on.

The first stage is to fit your real-time clock. If you are unfamiliar with the operation of real-time clock circuits, check out the last section of this tutorial. You can build a RTC circuit onto a protoshield or if you have a Freetronics Eleven, it can all fit in the prototyping space as such:

If you have an RTC module, it will also fit in the same space, then you simply run some wires to the 5V, GND, A4 (for SDA) and A5 (for SCL):

By now I hope you’re thinking “how do you set the time?”. There’s two answers to that question. If you’re using the DS3232 just set it in the sketch (see below) as the accuracy is very good, you only need to upload the sketch with the new time twice a year to cover daylight savings (unless you live in Queensland). Otherwise add a simple user-interface – a couple of buttons could do it, just as we did with Clock Two. Finally you just need to put the hardware on the back of the DMD. There’s plenty of scope to meet your own needs, a simple solution might be to align the control board so you can access the USB socket with ease – and then stick it down with some Sugru:

With regards to powering the clock – you can run ONE DMD from the Arduino, and it runs at a good brightness for indoor use. If you want the DMD to run at full, retina-burning brightness you need to use a separate 5 V 4 A power supply. If you’re using two DMDs – that goes to 8 A, and so on. Simply connect the external power to one DMD’s terminals (connect the second or more DMDs to these terminals):

The Arduino Sketch

You can download the sketch from here. It was written only for Arduino v1.0.1. The sketch has the usual functions to set and retrieve the time from DS1307/3232 real-time clock ICs, and as usual with all our clocks you can enter the time information into the variables in void setup(), then uncomment setDateDs1307(), upload the sketch, re-comment setDateDs1307, then upload the sketch once more. Repeat that process to re-set the time if you didn’t add any hardware-based user interface.

Once the time is retrieved in void loop(), it is passed to the function createTextTime(). This function creates the text string to display by starting with “It’s “, and then determines which words to follow depending on the current time. Finally the function drawText() converts the string holding the text to display into a character variable which can be passed to the DMD.

And here it is in action:

Conclusion

This was a quick project, however I hope you found it either entertaining or useful – and another random type of clock that’s easy to reproduce or modify yourself. We’re already working on another one which is completely different, so stay tuned.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.


Introduction

Time for another instalment in my highly-irregular series of irregular clock projects.  In this we have “Clock Four” – a scrolling text clock. After examining some Freetronics Dot Matrix Displays in the stock, it occurred to me that it would be neat to display the time as it was spoken (or close to it) – and thus this the clock was born. It is a quick project – we give you enough to get going with the hardware and sketch, and then you can take it further to suit your needs.

Hardware

You’ll need three major items – An Arduino Uno-compatible board, a real-time clock circuit or module using either a DS1307 or DS3232 IC, and a Freetronics DMD. You might want an external power supply, but we’ll get to that later on.

The first stage is to fit your real-time clock. If you are unfamiliar with the operation of real-time clock circuits, check out the last section of this tutorial. You can build a RTC circuit onto a protoshield or if you have a Freetronics Eleven, it can all fit in the prototyping space as such:

If you have an RTC module, it will also fit in the same space, then you simply run some wires to the 5V, GND, A4 (for SDA) and A5 (for SCL):

By now I hope you’re thinking “how do you set the time?”. There’s two answers to that question. If you’re using the DS3232 just set it in the sketch (see below) as the accuracy is very good, you only need to upload the sketch with the new time twice a year to cover daylight savings (unless you live in Queensland). Otherwise add a simple user-interface – a couple of buttons could do it, just as we did with Clock Two. Finally you just need to put the hardware on the back of the DMD. There’s plenty of scope to meet your own needs, a simple solution might be to align the control board so you can access the USB socket with ease – and then stick it down with some Sugru:

With regards to powering the clock – you can run ONE DMD from the Arduino, and it runs at a good brightness for indoor use. If you want the DMD to run at full, retina-burning brightness you need to use a separate 5 V 4 A power supply. If you’re using two DMDs – that goes to 8 A, and so on. Simply connect the external power to one DMD’s terminals (connect the second or more DMDs to these terminals):

The Arduino Sketch

You can download the sketch from here. Please use IDE v1.0.1 . The sketch has the usual functions to set and retrieve the time from DS1307/3232 real-time clock ICs, and as usual with all our clocks you can enter the time information into the variables in void setup(), then uncomment setDateDs1307(), upload the sketch, re-comment setDateDs1307, then upload the sketch once more. Repeat that process to re-set the time if you didn’t add any hardware-based user interface.

Once the time is retrieved in void loop(), it is passed to the function createTextTime(). This function creates the text string to display by starting with “It’s “, and then determines which words to follow depending on the current time. Finally the function drawText() converts the string holding the text to display into a character variable which can be passed to the DMD.

And here it is in action:

Conclusion

This was a quick project, however I hope you found it either entertaining or useful – and another random type of clock that’s easy to reproduce or modify yourself. We’re already working on another one which is completely different, so stay tuned.

In the meanwhile have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column? And join our friendly Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Project: Clock Four – Scrolling text clock appeared first on tronixstuff.

This is a tutorial on using the MSGEQ7 Spectrum Analyser with Arduino, and chapter forty-eight of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.

Updated 30/01/2013

In this article we’re going to explain how to make simple spectrum analysers with an Arduino-style board. (Analyser? Analyzer? Take your pick).

First of all, what is a spectrum analyser? Good question. Do you remember what  this is?

It’s a mixed graphic equaliser/spectrum analyser deck for a hi-fi system. The display in the middle is the spectrum analyser, and roughly-speaking it shows the strength of  different frequencies in the music being listened to – and looked pretty awesome doing it. We can recreate displays similar to this for entertainment and also as a base for creative lighting effects. By working through this tutorial you’ll have the base knowledge to recreate these yourself.

We’ll be using the MSGEQ7 “seven band graphic equaliser IC” from Mixed Signal Integration. Here’s the MSGEQ7 data sheet (.pdf).  This little IC can accept a single audio source, analyse seven frequency bands of the audio, and output a DC representation of each frequency band. This isn’t super-accurate or calibrated in any way, but it works. You can get the IC separately, for example:


and then build your own circuit around it… or like most things in the Arduino world – get a shield. In this case, a derivative of the original Bliptronics shield by Sparkfun. It’s designed to pass through stereo audio via 3.5mm audio sockets and contains two MSGEQ7s, so we can do a stereo analyser:

As usual Sparkfun have saved a few cents by not including the stackable header sockets, so you’ll need to buy and solder those in yourself. There is also space for three header pins for direct audio input (left, right and common), which are useful – so if you can add those as well.

So now you have a shield that’s ready for use. Before moving forward let’s examine how the MSGEQ7 works for us. As mentioned earlier, it analyses seven frequency bands. These are illustrated in the following graph from the data sheet:

It will return the strengths of the audio at seven points – 63 Hz, 160 Hz, 400 Hz, 1 kHz, 2.5 kHz, 6.25 kHz and 16 kHz – and as you can see there is some overlap between the bands. The strength is returned as a DC voltage – which we can then simply measure with the Arduino’s analogue input and create a display of some sort. At this point audio purists, Sheldonites and RF people might get a little cranky, so once again – this is more for visual indication than any sort of calibration device.

However as an 8-pin IC a different approach is required to get the different levels. The IC will sequentially give out the levels for each band on pin 3- e.g. 63 Hz then 160 Hz then 400 Hz then 1 kHz then 2.5 kHz then 6.25 kHz  then 16 kHz then back to 63 Hz and so on. To start this sequence we first reset the IC by pulsing the RESET pin HIGH then low. This tells the IC to start at the first band. Next, we set the STROBE pin to LOW, take the DC reading from pin 3 with analogue input, store the value in a variable (an array), then set the STROBE pin HIGH. We repeat the strobe-measure sequence six more times to get the rest of the data, then RESET the IC and start all over again. For the visual learners consider the diagram below from the data sheet:

To demonstrate this process, consider the function

readMSGEQ7()

in the following example sketch (download):

// Example 48.1 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 
// MSGEQ7 spectrum analyser shield - basic demonstration
int strobe = 4; // strobe pins on digital 4
int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays
int right[7];
int band;
void setup()
{
 Serial.begin(115200);
 pinMode(res, OUTPUT); // reset
 pinMode(strobe, OUTPUT); // strobe
 digitalWrite(res,LOW); // reset low
 digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for(band=0; band <7; band++)
 {
 digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band 
 delayMicroseconds(30); // 
 left[band] = analogRead(0); // store left band reading
 right[band] = analogRead(1); // ... and the right
 digitalWrite(strobe,HIGH); 
 }
}
void loop()
{
 readMSGEQ7();
 // display values of left channel on serial monitor
 for (band = 0; band < 7; band++)
 {
 Serial.print(left[band]);
 Serial.print(" ");
 }
 Serial.println();
// display values of right channel on serial monitor
 for (band = 0; band < 7; band++)
 {
 Serial.print(right[band]);
 Serial.print(" ");
 }
 Serial.println();
}

If you follow through the sketch, you can see that it reads both left- and right-channel values from the two MSGEQ7s on the shield, then stores each value in the arrays left[] and right[]. These values are then sent to the serial monitor for display – for example:

If you have a function generator, connect the output to one of the channels and GND – then adjust the frequency and amplitude to see how the values change. The following video clip is a short demonstration of this – we set the generator to 1 kHz and adjust the amplitude of the signal. To make things easier to read we only measure and display the left channel:


Keep an eye on the fourth column of data – this is the analogRead() value returned by the Arduino when reading the 1khz frequency band. You can also see the affect on the other bands around 1 kHz as we increase and decrease the frequency. However that wasn’t really visually appealing – so now we’ll create a small and large graphical version.

First we’ll use an inexpensive LCD, the I2C model from akafugu reviewed previously. To save repeating myself, also review how to create custom LCD characters from here.

With the LCD with have two rows of sixteen characters. The plan is to use the top row for the levels, the left-channel’s on … the left, and the right on the right. Each character will be a little bar graph for the level. The bottom row can be for a label. We don’t have too many pixels to work with, but it’s a compact example:

We have eight rows for each character, and the results from an analogueRead() fall between 0 and 1023. So that’s 1024 possible values spread over eight sections. Thus each row of pixels in each character will represent 128 “units of analogue read” or around 0.63 V if the Arduino is running from true 5 V (remember your AREF notes?). The sketch will again read the values from the MSGEQ7, feed them into two arrays – then display the required character in each band space  on the LCD.

Here’s the resulting sketch (download):

// Example 48.2 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 
// MSGEQ7 spectrum analyser shield and I2C LCD from akafugu
// for akafugu I2C LCD
#include 
#include "TWILiquidCrystal.h"
LiquidCrystal lcd(50);
// create custom characters for LCD
byte level0[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
byte level1[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte level2[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
byte level3[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
byte level4[8] = { 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level5[8] = { 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level6[8] = { 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level7[8] = { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
int strobe = 4; // strobe pins on digital 4
int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays
int right[7];
int band;
void setup()
{
 Serial.begin(9600);
 // setup LCD and custom characters
 lcd.begin(16, 2);
 lcd.setContrast(24);
 lcd.clear();
lcd.createChar(0,level0);
 lcd.createChar(1,level1);
 lcd.createChar(2,level2);
 lcd.createChar(3,level3);
 lcd.createChar(4,level4);
 lcd.createChar(5,level5);
 lcd.createChar(6,level6);
 lcd.createChar(7,level7);
 lcd.setCursor(0,1);
 lcd.print("Left");
 lcd.setCursor(11,1);
 lcd.print("Right");
 pinMode(res, OUTPUT); // reset
 pinMode(strobe, OUTPUT); // strobe
 digitalWrite(res,LOW); // reset low
 digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for( band = 0; band < 7; band++ )
 {
 digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band 
 delayMicroseconds(30); // 
 left[band] = analogRead(0); // store left band reading
 right[band] = analogRead(1); // ... and the right
 digitalWrite(strobe,HIGH); 
 }
}
void loop()
{
 readMSGEQ7();
// display values of left channel on LCD
 for( band = 0; band < 7; band++ )
 {
 lcd.setCursor(band,0);
 if (left[band]>=895) { lcd.write(7); } else
 if (left[band]>=767) { lcd.write(6); } else
 if (left[band]>=639) { lcd.write(5); } else
 if (left[band]>=511) { lcd.write(4); } else
 if (left[band]>=383) { lcd.write(3); } else
 if (left[band]>=255) { lcd.write(2); } else
 if (left[band]>=127) { lcd.write(1); } else
 if (left[band]>=0) { lcd.write(0); }
 }
 // display values of right channel on LCD
 for( band = 0; band < 7; band++ )
 {
 lcd.setCursor(band+9,0);
 if (right[band]>=895) { lcd.write(7); } else
 if (right[band]>=767) { lcd.write(6); } else
 if (right[band]>=639) { lcd.write(5); } else
 if (right[band]>=511) { lcd.write(4); } else
 if (right[band]>=383) { lcd.write(3); } else
 if (right[band]>=255) { lcd.write(2); } else
 if (right[band]>=127) { lcd.write(1); } else
 if (right[band]>=0) { lcd.write(0); }
 }
}

If you’ve been reading through my tutorials there isn’t anything new to worry about. And now for the demo, with sound -

That would look great on the side of a Walkman, however it’s a bit small. Let’s scale it up by using a Freetronics Dot Matrix Display - you may recall these from Clock One. For some background knowledge check the review here.  Don’t forget to use a suitable power supply for the DMD – 5 V at 4 A will do nicely. The DMD contains 16 rows of 32 LEDs. This gives us twice the “resolution” to display each band level if desired. The display style is subjective, so for this example we’ll use a single column of LEDs for each frequency band, with a blank column between each one.

We use a lot of line-drawing statements to display the levels, and clear the DMD after each display. With this and the previous sketches, there could be room for efficiency – however I write these with the beginner in mind. Here’s the sketch (download):

// Example 48.3 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 
// MSGEQ7 spectrum analyser shield with a Freetronics DMD
// for DMD
#include  // for DMD
#include  // SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include  
#include "SystemFont5x7.h" // keep next two lines if you want to add some text
#include "Arial_black_16.h"
DMD dmd(1, 1); // creates instance of DMD to refer to in sketch
void ScanDMD() // necessary interrupt handler for refresh scanning of DMD
{ 
 dmd.scanDisplayBySPI();
}
int strobe = 4; // strobe pins on digital 4
int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays
int right[7];
int band;
void setup()
{
 // for DMD
 //initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
 Timer1.initialize( 5000 ); //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
 Timer1.attachInterrupt( ScanDMD ); //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI() 
 dmd.clearScreen( true ); //true is normal (all pixels off), false is negative (all pixels on)

 // for MSGEQ7
 pinMode(res, OUTPUT); // reset
 pinMode(strobe, OUTPUT); // strobe
 digitalWrite(res,LOW); // reset low
 digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for( band = 0; band < 7; band++ )
 {
 digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band 
 delayMicroseconds(30); // 
 left[band] = analogRead(0); // store left band reading
 right[band] = analogRead(1); // ... and the right
 digitalWrite(strobe,HIGH); 
 }
}
void loop()
{
 int xpos;
 readMSGEQ7();
 dmd.clearScreen( true ); 
 // display values of left channel on DMD
 for( band = 0; band < 7; band++ )
 {
 xpos = (band*2)+1;
 if (left[band]>=895) { dmd.drawLine( xpos, 15, xpos, 1, GRAPHICS_NORMAL ); } else
 if (left[band]>=767) { dmd.drawLine( xpos, 15, xpos, 3, GRAPHICS_NORMAL ); } else
 if (left[band]>=639) { dmd.drawLine( xpos, 15, xpos, 5, GRAPHICS_NORMAL ); } else
 if (left[band]>=511) { dmd.drawLine( xpos, 15, xpos, 7, GRAPHICS_NORMAL ); } else
 if (left[band]>=383) { dmd.drawLine( xpos, 15, xpos, 9, GRAPHICS_NORMAL ); } else
 if (left[band]>=255) { dmd.drawLine( xpos, 15, xpos, 11, GRAPHICS_NORMAL ); } else
 if (left[band]>=127) { dmd.drawLine( xpos, 15, xpos, 13, GRAPHICS_NORMAL ); } else
 if (left[band]>=0) { dmd.drawLine( xpos, 15, xpos, 15, GRAPHICS_NORMAL ); }
 }

 // display values of right channel on DMD
 for( band = 0; band < 7; band++ )
 {
 xpos = (band*2)+18;
 if (right[band]>=895) { dmd.drawLine( xpos, 15, xpos, 1, GRAPHICS_NORMAL ); } else
 if (right[band]>=767) { dmd.drawLine( xpos, 15, xpos, 3, GRAPHICS_NORMAL ); } else
 if (right[band]>=639) { dmd.drawLine( xpos, 15, xpos, 5, GRAPHICS_NORMAL ); } else
 if (right[band]>=511) { dmd.drawLine( xpos, 15, xpos, 7, GRAPHICS_NORMAL ); } else
 if (right[band]>=383) { dmd.drawLine( xpos, 15, xpos, 9, GRAPHICS_NORMAL ); } else
 if (right[band]>=255) { dmd.drawLine( xpos, 15, xpos, 11, GRAPHICS_NORMAL ); } else
 if (right[band]>=127) { dmd.drawLine( xpos, 15, xpos, 13, GRAPHICS_NORMAL ); } else
 if (right[band]>=0) { dmd.drawLine( xpos, 15, xpos, 15, GRAPHICS_NORMAL ); }
 }
}

… and here it is in action:

Conclusion

At this point you have the knowledge to use the MSGEQ7 ICs to create some interesting spectrum analysers for entertainment and visual appeal – now you just choose the type of display enjoy the results.

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.


This is a tutorial on using the MSGEQ7 Spectrum Analyser with Arduino, and chapter forty-eight of a series originally titled “Getting Started/Moving Forward with Arduino!” by John Boxall – A tutorial on the Arduino universe. The first chapter is here, the complete series is detailed here.

Updated 30/01/2013

In this article we’re going to explain how to make simple spectrum analysers with an Arduino-style board. (Analyser? Analyzer? Take your pick).

First of all, what is a spectrum analyser? Good question. Do you remember what  this is?

It’s a mixed graphic equaliser/spectrum analyser deck for a hi-fi system. The display in the middle is the spectrum analyser, and roughly-speaking it shows the strength of  different frequencies in the music being listened to – and looked pretty awesome doing it. We can recreate displays similar to this for entertainment and also as a base for creative lighting effects. By working through this tutorial you’ll have the base knowledge to recreate these yourself.

We’ll be using the MSGEQ7 “seven band graphic equaliser IC” from Mixed Signal Integration. Here’s the MSGEQ7 data sheet (.pdf).  This little IC can accept a single audio source, analyse seven frequency bands of the audio, and output a DC representation of each frequency band. This isn’t super-accurate or calibrated in any way, but it works. You can get the IC separately, for example:


and then build your own circuit around it… or like most things in the Arduino world – get a shield. In this case, a derivative of the original Bliptronics shield by Sparkfun. It’s designed to pass through stereo audio via 3.5mm audio sockets and contains two MSGEQ7s, so we can do a stereo analyser:

As usual Sparkfun have saved a few cents by not including the stackable header sockets, so you’ll need to buy and solder those in yourself. There is also space for three header pins for direct audio input (left, right and common), which are useful – so if you can add those as well.

So now you have a shield that’s ready for use. Before moving forward let’s examine how the MSGEQ7 works for us. As mentioned earlier, it analyses seven frequency bands. These are illustrated in the following graph from the data sheet:

freqresponse

It will return the strengths of the audio at seven points – 63 Hz, 160 Hz, 400 Hz, 1 kHz, 2.5 kHz, 6.25 kHz and 16 kHz – and as you can see there is some overlap between the bands. The strength is returned as a DC voltage – which we can then simply measure with the Arduino’s analogue input and create a display of some sort. At this point audio purists, Sheldonites and RF people might get a little cranky, so once again – this is more for visual indication than any sort of calibration device.

However as an 8-pin IC a different approach is required to get the different levels. The IC will sequentially give out the levels for each band on pin 3- e.g. 63 Hz then 160 Hz then 400 Hz then 1 kHz then 2.5 kHz then 6.25 kHz  then 16 kHz then back to 63 Hz and so on. To start this sequence we first reset the IC by pulsing the RESET pin HIGH then low. This tells the IC to start at the first band. Next, we set the STROBE pin to LOW, take the DC reading from pin 3 with analogue input, store the value in a variable (an array), then set the STROBE pin HIGH. We repeat the strobe-measure sequence six more times to get the rest of the data, then RESET the IC and start all over again. For the visual learners consider the diagram below from the data sheet:

strobing1

To demonstrate this process, consider the function

readMSGEQ7()

in the following example sketch:

// Example 48.1 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 
// MSGEQ7 spectrum analyser shield - basic demonstration
int strobe = 4; // strobe pins on digital 4
int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays
int right[7];
int band;
void setup()
{
 Serial.begin(115200);
 pinMode(res, OUTPUT); // reset
 pinMode(strobe, OUTPUT); // strobe
 digitalWrite(res,LOW); // reset low
 digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for(band=0; band <7; band++)
 {
 digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band 
 delayMicroseconds(30); // 
 left[band] = analogRead(0); // store left band reading
 right[band] = analogRead(1); // ... and the right
 digitalWrite(strobe,HIGH); 
 }
}
void loop()
{
 readMSGEQ7();
 // display values of left channel on serial monitor
 for (band = 0; band < 7; band++)
 {
 Serial.print(left[band]);
 Serial.print(" ");
 }
 Serial.println();
// display values of right channel on serial monitor
 for (band = 0; band < 7; band++)
 {
 Serial.print(right[band]);
 Serial.print(" ");
 }
 Serial.println();
}

If you follow through the sketch, you can see that it reads both left- and right-channel values from the two MSGEQ7s on the shield, then stores each value in the arrays left[] and right[]. These values are then sent to the serial monitor for display – for example:

If you have a function generator, connect the output to one of the channels and GND – then adjust the frequency and amplitude to see how the values change. The following video clip is a short demonstration of this – we set the generator to 1 kHz and adjust the amplitude of the signal. To make things easier to read we only measure and display the left channel:


Keep an eye on the fourth column of data – this is the analogRead() value returned by the Arduino when reading the 1khz frequency band. You can also see the affect on the other bands around 1 kHz as we increase and decrease the frequency. However that wasn’t really visually appealing – so now we’ll create a small and large graphical version.

First we’ll use an inexpensive LCD, the I2C model from akafugu reviewed previously. To save repeating myself, also review how to create custom LCD characters from here.

With the LCD with have two rows of sixteen characters. The plan is to use the top row for the levels, the left-channel’s on … the left, and the right on the right. Each character will be a little bar graph for the level. The bottom row can be for a label. We don’t have too many pixels to work with, but it’s a compact example:

lcdfullon

We have eight rows for each character, and the results from an analogueRead() fall between 0 and 1023. So that’s 1024 possible values spread over eight sections. Thus each row of pixels in each character will represent 128 “units of analogue read” or around 0.63 V if the Arduino is running from true 5 V (remember your AREF notes?). The sketch will again read the values from the MSGEQ7, feed them into two arrays – then display the required character in each band space  on the LCD.

Here’s the resulting sketch:

// Example 48.2 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 
// MSGEQ7 spectrum analyser shield and I2C LCD from akafugu
// for akafugu I2C LCD
#include "Wire.h"
#include "TWILiquidCrystal.h"
LiquidCrystal lcd(50);
// create custom characters for LCD
byte level0[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111};
byte level1[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111};
byte level2[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111};
byte level3[8] = { 0b00000, 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111};
byte level4[8] = { 0b00000, 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level5[8] = { 0b00000, 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level6[8] = { 0b00000, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
byte level7[8] = { 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111, 0b11111};
int strobe = 4; // strobe pins on digital 4
int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays
int right[7];
int band;
void setup()
{
 Serial.begin(9600);
 // setup LCD and custom characters
 lcd.begin(16, 2);
 lcd.setContrast(24);
 lcd.clear();
lcd.createChar(0,level0);
 lcd.createChar(1,level1);
 lcd.createChar(2,level2);
 lcd.createChar(3,level3);
 lcd.createChar(4,level4);
 lcd.createChar(5,level5);
 lcd.createChar(6,level6);
 lcd.createChar(7,level7);
 lcd.setCursor(0,1);
 lcd.print("Left");
 lcd.setCursor(11,1);
 lcd.print("Right");
 pinMode(res, OUTPUT); // reset
 pinMode(strobe, OUTPUT); // strobe
 digitalWrite(res,LOW); // reset low
 digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for( band = 0; band < 7; band++ )
 {
 digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band 
 delayMicroseconds(30); // 
 left[band] = analogRead(0); // store left band reading
 right[band] = analogRead(1); // ... and the right
 digitalWrite(strobe,HIGH); 
 }
}
void loop()
{
 readMSGEQ7();
// display values of left channel on LCD
 for( band = 0; band < 7; band++ )
 {
 lcd.setCursor(band,0);
 if (left[band]>=895) { lcd.write(7); } else
 if (left[band]>=767) { lcd.write(6); } else
 if (left[band]>=639) { lcd.write(5); } else
 if (left[band]>=511) { lcd.write(4); } else
 if (left[band]>=383) { lcd.write(3); } else
 if (left[band]>=255) { lcd.write(2); } else
 if (left[band]>=127) { lcd.write(1); } else
 if (left[band]>=0) { lcd.write(0); }
 }
 // display values of right channel on LCD
 for( band = 0; band < 7; band++ )
 {
 lcd.setCursor(band+9,0);
 if (right[band]>=895) { lcd.write(7); } else
 if (right[band]>=767) { lcd.write(6); } else
 if (right[band]>=639) { lcd.write(5); } else
 if (right[band]>=511) { lcd.write(4); } else
 if (right[band]>=383) { lcd.write(3); } else
 if (right[band]>=255) { lcd.write(2); } else
 if (right[band]>=127) { lcd.write(1); } else
 if (right[band]>=0) { lcd.write(0); }
 }
}

If you’ve been reading through my tutorials there isn’t anything new to worry about. And now for the demo, with sound -

That would look great on the side of a Walkman, however it’s a bit small. Let’s scale it up by using a Freetronics Dot Matrix Display - you may recall these from Clock One. For some background knowledge check the review here.  Don’t forget to use a suitable power supply for the DMD – 5 V at 4 A will do nicely. The DMD contains 16 rows of 32 LEDs. This gives us twice the “resolution” to display each band level if desired. The display style is subjective, so for this example we’ll use a single column of LEDs for each frequency band, with a blank column between each one.

We use a lot of line-drawing statements to display the levels, and clear the DMD after each display. With this and the previous sketches, there could be room for efficiency – however I write these with the beginner in mind. Here’s the sketch:

// Example 48.3 - tronixstuff.com/tutorials > chapter 48 - 30 Jan 2013 
// MSGEQ7 spectrum analyser shield with a Freetronics DMD
// for DMD
#include "DMD.h" // for DMD
#include "SPI.h" // SPI.h must be included as DMD is written by SPI (the IDE complains otherwise)
#include "TimerOne.h"
#include "SystemFont5x7.h" // keep next two lines if you want to add some text
#include "Arial_black_16.h"
DMD dmd(1, 1); // creates instance of DMD to refer to in sketch
void ScanDMD() // necessary interrupt handler for refresh scanning of DMD
{ 
 dmd.scanDisplayBySPI();
}
int strobe = 4; // strobe pins on digital 4
int res = 5; // reset pins on digital 5
int left[7]; // store band values in these arrays
int right[7];
int band;
void setup()
{
 // for DMD
 //initialize TimerOne's interrupt/CPU usage used to scan and refresh the display
 Timer1.initialize( 5000 ); //period in microseconds to call ScanDMD. Anything longer than 5000 (5ms) and you can see flicker.
 Timer1.attachInterrupt( ScanDMD ); //attach the Timer1 interrupt to ScanDMD which goes to dmd.scanDisplayBySPI() 
 dmd.clearScreen( true ); //true is normal (all pixels off), false is negative (all pixels on)

 // for MSGEQ7
 pinMode(res, OUTPUT); // reset
 pinMode(strobe, OUTPUT); // strobe
 digitalWrite(res,LOW); // reset low
 digitalWrite(strobe,HIGH); //pin 5 is RESET on the shield
}
void readMSGEQ7()
// Function to read 7 band equalizers
{
 digitalWrite(res, HIGH);
 digitalWrite(res, LOW);
 for( band = 0; band < 7; band++ )
 {
 digitalWrite(strobe,LOW); // strobe pin on the shield - kicks the IC up to the next band 
 delayMicroseconds(30); // 
 left[band] = analogRead(0); // store left band reading
 right[band] = analogRead(1); // ... and the right
 digitalWrite(strobe,HIGH); 
 }
}
void loop()
{
 int xpos;
 readMSGEQ7();
 dmd.clearScreen( true ); 
 // display values of left channel on DMD
 for( band = 0; band < 7; band++ )
 {
 xpos = (band*2)+1;
 if (left[band]>=895) { dmd.drawLine( xpos, 15, xpos, 1, GRAPHICS_NORMAL ); } else
 if (left[band]>=767) { dmd.drawLine( xpos, 15, xpos, 3, GRAPHICS_NORMAL ); } else
 if (left[band]>=639) { dmd.drawLine( xpos, 15, xpos, 5, GRAPHICS_NORMAL ); } else
 if (left[band]>=511) { dmd.drawLine( xpos, 15, xpos, 7, GRAPHICS_NORMAL ); } else
 if (left[band]>=383) { dmd.drawLine( xpos, 15, xpos, 9, GRAPHICS_NORMAL ); } else
 if (left[band]>=255) { dmd.drawLine( xpos, 15, xpos, 11, GRAPHICS_NORMAL ); } else
 if (left[band]>=127) { dmd.drawLine( xpos, 15, xpos, 13, GRAPHICS_NORMAL ); } else
 if (left[band]>=0) { dmd.drawLine( xpos, 15, xpos, 15, GRAPHICS_NORMAL ); }
 }

 // display values of right channel on DMD
 for( band = 0; band < 7; band++ )
 {
 xpos = (band*2)+18;
 if (right[band]>=895) { dmd.drawLine( xpos, 15, xpos, 1, GRAPHICS_NORMAL ); } else
 if (right[band]>=767) { dmd.drawLine( xpos, 15, xpos, 3, GRAPHICS_NORMAL ); } else
 if (right[band]>=639) { dmd.drawLine( xpos, 15, xpos, 5, GRAPHICS_NORMAL ); } else
 if (right[band]>=511) { dmd.drawLine( xpos, 15, xpos, 7, GRAPHICS_NORMAL ); } else
 if (right[band]>=383) { dmd.drawLine( xpos, 15, xpos, 9, GRAPHICS_NORMAL ); } else
 if (right[band]>=255) { dmd.drawLine( xpos, 15, xpos, 11, GRAPHICS_NORMAL ); } else
 if (right[band]>=127) { dmd.drawLine( xpos, 15, xpos, 13, GRAPHICS_NORMAL ); } else
 if (right[band]>=0) { dmd.drawLine( xpos, 15, xpos, 15, GRAPHICS_NORMAL ); }
 }
}

… and here it is in action:

Conclusion

At this point you have the knowledge to use the MSGEQ7 ICs to create some interesting spectrum analysers for entertainment and visual appeal – now you just choose the type of display enjoy the results.

LEDborder

Have fun and keep checking into tronixstuff.com. Why not follow things on twitterGoogle+, subscribe  for email updates or RSS using the links on the right-hand column, or join our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, helpful to each other –  and we can all learn something.

The post Tutorial: Arduino and the MSGEQ7 Spectrum Analyzer appeared first on tronixstuff.

Mag
14

April 2012 Competition Results

arduino, competition, display, DMD, dot, freetronics, giveaway, matrix, modules, Sensor, tronixstuff Commenti disabilitati su April 2012 Competition Results 

Competition over.

The post April 2012 Competition Results appeared first on tronixstuff.

Apr
03

April 2012 Competition

arduino, competition, display, DMD, dot, freetronics, giveaway, matrix, modules, Sensor, tronixstuff Commenti disabilitati su April 2012 Competition 

Competition over!

The post April 2012 Competition appeared first on tronixstuff.



  • Newsletter

    Sign up for the PlanetArduino Newsletter, which delivers the most popular articles via e-mail to your inbox every week. Just fill in the information below and submit.

  • Like Us on Facebook