Blog of the day

skywired

Skywired is a “must visit” blog which contains high quality posts on various subjects, mostly DSP and ham radio.

PlainDSP (Part 4)

Part 1234

Here is the autonomous version of the sound meter which principle is described in PlainDSP (Part 3). The picture below shows the full schematics of the device

Micro_DB_MTR_LCD

 

And here is the code of MicroSNDMTR_LCD, which includes the auto-ranging algorithm

/*

	MicroSNDMTR_LCD: Micro sound meter connected to LCD 2x16 display
	Exemple of use of the PlainDSP and PlainLCD libraries
	Tested with ATmega328 powered Arduino
	Copyright (C) 2012-2013 Didier Longueville

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <PlainDSP.h> /* Include DSP library */
#include <PlainLCD.h> /* Include LCD library */

/* Create objects */
PlainDSP DSP; 
PlainLCD LCD; 

/* Acquisition parameters */
const uint16_t _samples = 128; /* Max value depends upon available memory space */
const double _samplingFrequency = 22100.0; /* From 0.125 Hz to 80 kHz */
const uint16_t _defAdcChannel = 0; /* From 0 to 5 on ATmega328 powered Arduinos */
const uint16_t _refVoltage = DSP_REF_VOL_EXTERNAL; /* External: 3.3V */
const uint8_t _options = (DSP_OPT_DIS_TIM_0 | DSP_OPT_DIS_TIM_2 | DSP_OPT_NOI_CANCELLER);
uint8_t _adcChannel;
const float _refPressure = 20E-6;
/* Custom data */
const float _vGains[] = {50.0, 10.0, 10.0}; /* gain of first stage on first place and so on */
const float _microphoneSensitivity = 2.5; /* unit Pa/mV, read from microphone datasheet */

/* Control led parameters */
#define LED_PORT &PORTB
#define LED_PIN PINB5

void setup()
{
	/* Initialize LCD: pins must belong to the same port in the order:
	data4, data5, data6, data7, reg_select, chip_enable, port 
	connect the R/W pin to ground
	Attach contrast pin to trim pot	*/
	LCD.InitializeLCD(2, 3, 4, 5, 6, 7, &PORTD);
	LCD.ClearDisplay();
	/* Align. scale: 1234567890123456 */
	LCD.PrintString("* MICRO DB MTR *", 1);
	/* Set data acquisition parameters */
	DSP.SetAcquisitionEngine(_defAdcChannel, _refVoltage,  _samplingFrequency, _samples, _options);	
};

void loop() 
{		
	/* Start reading the most amplified signal from 3d stage */
	_adcChannel = 3;
	uint8_t saturated = 1;
	/* Reads preamlifier stages sequentially, starting from the highest gain */
	do  {
		/* Set channel */
		_adcChannel -= 1;
		/* Set channel */
		DSP.Channel(_adcChannel);
		/* Acquire data */
		DSP.GetScanData();
		/* Check signal */
		if ((DSP.Min() >= 1.0) && (DSP.Max() <= 1023.0)) {
			saturated = 0;
		}
	} while (saturated && (_adcChannel != 0));
	/* Compute gain factor */
	float gain = 1.0;
	for (uint8_t i = 0; i <= _adcChannel; i++) {
		gain *= _vGains[i];
	}
	/* Compute scaling factor for mV */
	float scalingFactor = (3.3 / (1.024 * gain));
	/* Reset offset */
	DSP.ResetOffset();
	/* Rescale data */
	DSP.Gain(scalingFactor);
	/* Compute and print statictics */
	float rmsSignal = DSP.RMS();
	float rmsPressure = (20 * log10(rmsSignal / (_refPressure * _microphoneSensitivity)));
	/* Print RMS in dB */
	LCD.ClearBuffer();
	LCD.InsertFloat(rmsPressure, 1, 4, LCD_ALI_RIGHT);
	LCD.InsertString("dB RMS", 5, LCD_ALI_LEFT);
	LCD.InsertString("[g:", 12, LCD_ALI_LEFT);
	LCD.InsertInteger((_adcChannel + 1), 15, LCD_ALI_RIGHT);
	LCD.InsertString("]", 16, LCD_ALI_LEFT);
	LCD.PrintBuffer(1);
	/* Print RMS in mV */
	LCD.ClearBuffer();
	LCD.InsertFloat(rmsSignal, 3, 5, LCD_ALI_RIGHT);
	LCD.InsertString("mV RMS", 6, LCD_ALI_LEFT);
	LCD.PrintBuffer(2);
	/* Uncomment next lines as appropriate */
	// while(true); /* Run Once */
	delay(1000); /* Repeat after delay */
};

Here are two pictures of the device. The device features an Arduino UNO board as well as a protoshield fitted with a small breadboard which receives the analog components. The LCD is wired to the shield too. The device is powered by a pack of batteries for autonomous operation.

Micro_DB_MTR_02

 

On the first line of the display is printed the sound signal strength expressed in dB RMS. At the end of the line is an indicator of the number of gain stages involved. On the second line is the signal strength expressed in mV RMS.

The next picture is a closer look at the breadboard. Although it may look messy, the principle of wiring keeps the connexions short and the circuit is compact.

Micro_DB_MTR_01

 

 

Fast prototyping

Some of you might be familiar with lean management, less may have heard about the emerging concept of lean startups! As there are probably as many startups as variations of this new concept, I will not try to precisely define lean startups. However I can give multiple examples drawn from my own experience to illustrate some fundamental principles of this concept. Arduino plays a major part in this concept as it is not only a piece of electronics, but also a simple suite of applications packed in one simple interface that most call the IDE. More than this, Arduino is this extraordinary large, rich, fast pacing community of designers, makers, technicians and even scientists who enrich the concept with their creativity, knowledge and good will.

Ahem, except one, who tried to spoil this community after stealing code, using a little makeup before re appropriating it in perfect violation of the GNU licenses. I will get back to you Mr. L.B. so that you learn your lessons a better way, whoever you are, whatever your position.

Back to nicer things. As I was working on a top priority project, I deadly needed to exercise various types of vibration sensors. In this domain, the setup of the sensor is at least as important as its electronics and the related data management. Problem is that the active elements of these sensors have various sizes and must be placed at certain positions. Some are heavy some are light, some other ones do not include the least means of fastening.  Not so easy. So far, you would have to spend hours in your workshop, trying to find some convenient parts from the scrap box and designing a fine but mostly ugly part.

Except if you are a visionary person who perceived that the crazy 3D printing technology could be of any help to your awesome projects! And it does!

Taking the example of the sensor holders, I took me no more than an hour between the moment when I decided to make a sensor holder and the exact exciting moment when you take it hot from the oven. That’s one of the most exciting experience for whoever is dreaming at making as you think. Software was eligible to this principle, it is now time for hardware to get in this principle too. Although 3D printers are still missing the “Cancel” key which would rewind the ABS wire on its cartridge, changing some sizes and shapes and printing again last few minutes and costs less than sending new plans, placing a new order and waiting for a new part.

The printed parts are surprisingly strong and their shapes rely well on the expected sizes. Here is an oversimplified sketch of the part making sequence:

Get the part, check sizes.

P1130647

Draw part using a 3D drawing tool. I personally use ProIng. Save part as an STL file

P1130650

Convert File to G format. The ultimate Makerware revision locks up my computer so that I must run Replicator G. Convert to x3g format and copy file to the SD card

P1130653

Insert SD Card in the 3D printer and launch a “print from card”. And here it is!

P1130648

Mount the sensor…

P1130640

Clean! Isn’t it?

Here is another example of use which involves a geophone sensor

P1130651

 

P1130645

Just fine!

Flash news

Siegfried BURGEOT, Project Manager at the CRIJ – Poitou Charente invites the fans of high tech, open source, hackers, geeks at a …

Meeting at the EESI (École Européene Supérieure de l’Image) Espace Scénique 1st floor

21 May from 13:00 to 18:00

26 Rue Jean Alexandre, 86000 Poitiers – France / +33.5.45.92.66.02

(In case of trouble, call Siegfried +33.6.80.62.76.61)

Program, workshops :

  • 3D Printers / Guillaume Brunet from PING
  • Arduino / Julien Rat from Les Petits débrouillards
  • Makey Makey / Espace Mendès France (to be confirmed)
  • Processing / Hervé Jolly from the EESI

Register (2 workshops each, 10 participants max. per workshop)

Agenda:

13h00 – 13h30 – Welcome
13h30 – 15h00 – Workshops
15h00 – 15h30 – Break/Tchat/Cigarettes/Coffee
15h30 – 17h00 - Workshops
17h00 – 17h30 – Tchat/Tidyup
18h00 – End

Bring your computers and download the following software

PlainDSP (Part 3)

Part 12, 3, 4

This post contains an application of the data acquisition and analysis from the PlainDSP library.

The credit of the idea goes to Preston who is currently busy at deadening his truck. In his mail of PlainDSP library request, Preston explained to me his current project, and I found it fun and for some reasons, it is related to one of my current domains of interest (from the pro side). So… here it is. Enjoy and have fun!

Preston needs a simple, affordable and portable real time Sound Level Meter in order to perform relative measurements of noise levels inside the cabin of his truck, before and after installing damping material or replacing parts which are suspected to contribute to the noise.

Although PlainDSP could allow much more sophisticated measurements (e.g. Performing targeted measurements at certain frequencies), I decided to stick to Preston’s request. Let’s firstly talk about the electronics. As I have no real idea about the noise level of Preston’s truck (I understand that is significantly above the noise from inside a Cadillac ;-) ), I decided to design an auto-ranging preamplifier. The first stage will raise the level from the microphone to 50 times its original level. Two more amplifying stages are cascaded in order to achieve gains of  200  (20 * 10)  up to 2000  (20 * 10 * 10).

Micro_DB_MTR

The autoranging preamplifier is built around a TS924 quad op amp. IC1C is wired as a voltage follower which copies the voltage on its non inverting pin (10) to its buffered output pin (8). The input signal is taken from the midpoint of the voltage divider bridge R1 R2 (20k each)  which is decoupled by C3 (10µF). The output voltage (half 3.3V) is used as a virtual ground for the three amplifying stages (IC1A, B and D).

R7 (1k) biases D1 and D2, and this reference voltage is decoupled by C2 (10µF). The microphone cell (electret type) is biased from this reference voltage through R8 (1k). The signal from the microphone is decoupled by C1 (1µF) and the gain (x50) of the first amplifying stage is set by R3 (1k) and R4 (20k). Then two identical amplifying stages are mounted in series with the first stage, each of them having a gain of 10 set by R5 and R10 (1k each) and R6 and R9 (10k each)

Note:  The gain values can be changed, but you will have to change the gain settings in the code.

The signal from each amplifying stage is wired to the analog ports of Arduino: IC1A pin 1 goes to A0, IC1B pin 7 goes to A1, IC1D pin 14 goes to A2. Connect VCC to the 3.3V AND to Vref of Arduino and GND to GND (Not represented on schematics]. That’s it.

Here is an illustration of the prototype that I built using an Arduino Nano and a middle size breadboard

MicroSND_MTR_01

 

I am using a lot preassembled passive components which allow to “cable as you think”.

MicroSND_MTR_02

Thanks to some minimal normalization (e.g. Diodes use yellow wires and the live tip is the cathode), the chances of mixing up components is very low. In addition to quick wiring, the use of insulated extension wires prevents short circuits and allows compact wiring. In the present case, keeping wire lengths short is mandatory for avoiding to pick up noise. In the same spirit, if the microphone is to be used out of the board, consider using a shielded extension cable.

Time for coding. Here is the sketch which will allow repetitive prints of some interesting information:

  • Selected overall gain (for information)
  • Pic to pic noise (in mV)
  • Root Mean  Square of noise (in mV)
  • Sound Pressure Levels (in dB)

Note: Although the three first results were enough for Preston, I think that adding the SPL gives an additional interesting information that one can relate to the following table which gives examples of sound sources (noise)

  •  Jet aircraft, 50 m away: 140 dB
  • Threshold of pain: 130 dB
  • Threshold of discomfort: 120 dB
  • Chainsaw, 1 m distance: 110 dB
  • Disco, 1 m from speaker: 100 dB
  • Diesel truck, 10 m away: 90 dB
  • Kerbside of busy road, 5 m: 80 dB
  • Vacuum cleaner, distance 1 m: 70 dB
  • Conversational speech, 1 m: 60 dB
  • Average home: 50 dB
  • Quiet library: 40 dB
  • Quiet bedroom at night: 30 dB
  • Background in TV studio: 20 dB
  • Rustling leaves in the distance: 10 dB
  • Hearing threshold: 0 dB

For those who want to learn more about measurement of sounds, please check this excellent site (English version available)

/*

	MicroSNDMTR: Micro sound meter
	Exemple of use of the PlainDSP library
	Tested with ATmega328 powered Arduino
	Copyright (C) 2012-2013 Didier Longueville

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <PlainDSP.h>

/* Create objects */
PlainDSP DSP; 

/* Acquisition parameters */
const uint16_t _samples = 128; /* Max value depends upon available memory space */
const double _samplingFrequency = 22100.0; /* From 0.125 Hz to 80 kHz */
const uint16_t _defAdcChannel = 0; /* From 0 to 5 on ATmega328 powered Arduinos */
const uint16_t _refVoltage = DSP_REF_VOL_EXTERNAL; /* External: 3.3V */
const uint8_t _options = (DSP_OPT_DIS_TIM_0 | DSP_OPT_DIS_TIM_2 | DSP_OPT_NOI_CANCELLER);
uint8_t _adcChannel;
const float _refPressure = 20E-6;
/* Custom data */
const float _vGains[] = {50.0, 10.0, 10.0}; /* gain of first stage on first place and so on */
const float _microphoneSensitivity = 2.5; /* unit Pa/mV, read from moicrophone datasheet */

/* Control led parameters */
#define LED_PORT &PORTB
#define LED_PIN PINB5

void setup()
{
	/* Initialize serial comm port */
	Serial.begin(115200); 
	/* Set data acquisition parameters */
	DSP.SetAcquisitionEngine(_defAdcChannel, _refVoltage,  _samplingFrequency, _samples, _options);	
	/* Mark event */
	BlinkLed(3);
};

void loop() 
{		
	/* Start reading the most amplified signal from 3d stage */
	_adcChannel = 3;
	uint8_t saturated = 1;
	/* Reads preamlifier stages sequentially, starting from the highest gain */
	do  {
		/* Set channel */
		_adcChannel -= 1;
		/* Set channel */
		DSP.Channel(_adcChannel);
		/* Acquire data */
		DSP.GetScanData();
		/* Check signal */
		if ((DSP.Min() >= 1.0) && (DSP.Max() <= 1023.0)) {
			saturated = 0;
		}
	} while ((saturated == 1) && (_adcChannel != 0));
	/* Compute gain factor */
	float gain = 1.0;
	for (uint8_t i = 0; i <= _adcChannel; i++) {
		gain *= _vGains[i];
	}
	/* Compute scaling factor for mV */
	float scalingFactor = (3.3 / (1.024 * gain));
	/* Reset offset */
	DSP.ResetOffset();
	/* Rescale data */
	DSP.Gain(scalingFactor);
	/* Compute and print statictics */
	float rmsSignal = DSP.RMS();
	float rmsPressure = (20 * log10(rmsSignal / (_refPressure * _microphoneSensitivity)));
	Serial.print("G: ");
	Serial.print(uint16_t(gain));
	Serial.print(", ");
	Serial.print("P/P: ");
	Serial.print((DSP.Max() - DSP.Min()), 3);
	Serial.print(" mV");
	Serial.print(", ");
	Serial.print("RMS: ");
	Serial.print(rmsSignal, 3);
	Serial.print(" mV");
	Serial.print(", ");
	Serial.print("SPL: "); /* Sound pressure level */
	Serial.print(int16_t(rmsPressure));
	Serial.print(" dB");
	Serial.println();
	/* Print raw data */
	// PrintData(); /* Uncomment as appropriate */
	/* Mark event */
	BlinkLed(1);
	/* Uncomment next lines as appropriate */
	// while(true); /* Run Once */
	delay(1000); /* Repeat after delay */
};

void PrintData() 
{
	for (uint16_t i = 0; i < _samples; i++) {
		double abscissa = (i / _samplingFrequency);
		Serial.print(abscissa, 6);
		Serial.print("\t");
		double ordinate = DSP.ReadData(i);
		Serial.print(ordinate , 6);
		Serial.println();
	}
	Serial.println();
}

void BlinkLed(uint16_t cycles) 
/* Blink control led */
{
	/* Make the led pin an output pin */
	*(LED_PORT - 1) |= (1 << LED_PIN);
	/* Reset pin state */
	*LED_PORT &= ~(1 << LED_PIN); /* Turn control led off */
	for (uint8_t i = 0; i < (cycles << 1); i++)	{
		delay(200);
		*LED_PORT ^= (1 << LED_PIN);
	}
};

Except for the SPL calculation, PlainDSP contains all the functions required to make this application work.

Do not expect to get down to 0dB using a breadboard assembled module! The measured noise on the illustrated assembly shows a background RMS noise of 0.006 mV, leading to 40dB SPL!

Important: Please do not test the equipment next to loud noises without ear protections. I will accept no complains from those who will try it next to a rocket launch pad. :-(

Coming next: same as before with LCD for portable applications.

PlainDSP (Part 2)

Part 1234

The next lines of code illustrate how PlainDSP simplifies the combination of data acquisition and data analysis. You no longer need to worry about the vectors of data. PlainDSP creates dynamically  and transparently the required vectors. On the other hand you must keep in mind that they exist and take 8 times the number of samples… So that no more that 128 samples shall be used when PlainDSP is running on an arduino UNO.

The first part of the code contains the instruction for including PlainDDS library and the creation of the DSP object. Then come the data acquisition parameters. Note that PlainDSP allows you to selectively deactivate the unused timers in order to improve the sampling rate stability, along with the activation of the noise canceler function. The sampling rate is now limited to 80kHz, which is the price to pay for the simplification of use of the library. On the other hand, this limit is far above the 44.1kHz sampling rate required for achieving CD sound quality

#include <PlainDSP.h>
/* Create objects */
PlainDSP DSP; /* Create DSP object */
/* Acquisition parameters */
const uint16_t _samples = 128; /* Max value depends upon available memory space */
const float _samplingFrequency = 2000.0; /* From 0.125 Hz to 80 kHz */
const uint16_t _adcChannel = 0; /* From 0 to 5 on ATmega328 powered Arduinos */
const uint16_t _refVoltage = DSP_REF_VOL_DEFAULT; /* VCC: 5V */
const uint8_t _options = (DSP_OPT_DIS_TIM_0 | DSP_OPT_DIS_TIM_2 | DSP_OPT_NOI_CANCELLER);
const float _targetPeakFrequency = 10000.0;
/* Local scale constants */
#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02

The second part deals with the set up section of the code. This is where the data acquisition parameters are set: adc channel index (0 to 5 for arduino UNO), reference voltage, sampling rate frequency (0.125Hz to 80kHz), samples (1 to 128 for arduino UNO) and noise reduction options.

void setup()
{
	/* Initialize serial comm port */
	Serial.begin(115200); 
	/* Set data acquisition parameters and get memory location of data */
	DSP.SetAcquisitionEngine(_adcChannel, _refVoltage, _samplingFrequency, _samples, _options);	
};

The third part deals with the loop section of the code. This is where the data acquisition and data analysis take place. Acquiring data is as simple as GetScanData(). Once executed, data can be read using the ReadData() function. Again, no need to care about where and how data is strored. In the example, some additional functions are used prior to applying FFT: ResetOffset() which nulls the offset of a periodic (e.g. sinusoidal) signal. The Rescale() function converts the ordinate scale so that 1024 counts translate to 5V. Use the  PrintVector() function in order to visualize the signal on completion of the successive steps. The ClearVector() function must be used to erase the content of the vector which contains the imaginary data. Failing to do so may lead to unexpected results.

Note: This vector is not automatically cleared in order to allow the reversal use of FFT, in the context of denoising function.

Use the ComputeFFT()  function with appropriate argument, depending upon the the nature of the original signal. Finally execute the Complex to real function in order to get the frequency domain data, so as to say, the frequency spectrum.

Both MajorPeak() and TargetPeak() which perform automatic peak picking and peak quantification (apex location, interpolated peak apex location, peak height). Once again, you do not have to worry about the location of data

 

void loop() 
{
	/* Acquire data */
	DSP.GetScanData();
	/* Null offset */
	DSP.ResetOffset();
	/* Rescale signal */
	DSP.Rescale((5.0 / 1024.0), 0);
	/* Print raw data */
	PrintVector(SCL_TIME); /* Comment line if not needed */
	/* Weigh data */
	DSP.Windowing(DSP_WIN_TYP_HANN, DSP_FORWARD);	
	PrintVector(SCL_TIME); /* Comment line if not needed */
	/* Compute FFT */
	DSP.ClearVector(DSP_IMG_DATA);
	DSP.ComputeFFT(DSP_FORWARD);	
	/* Print real and imag data */
	PrintVector(SCL_INDEX); /* Comment line if not needed */
	/* Compute magnitudes */
	DSP.ComplexToReal(DSP_SCL_TYP_AMPLITUDE);
	/* Print frequency spectrum */
	PrintVector(SCL_FREQUENCY); /* Comment line if not needed */
	/* Find major peak */
	struct strPeakProperties majorPeak;
	DSP.MajorPeak(_targetPeakFrequency - (_targetPeakFrequency * .5), _targetPeakFrequency + (_targetPeakFrequency * .5), &majorPeak);
	Serial.print("Major peak ");
	Serial.print("bin: ");
	Serial.print(majorPeak.bin);	
	Serial.print(", feq.: ");
	Serial.print(majorPeak.position, 6);	
	Serial.print(", height: ");
	Serial.print(majorPeak.height, 6);	
	Serial.println();
	/* Find target peak */
	struct strPeakProperties targetPeak;
	DSP.TargetPeak(_targetPeakFrequency, (_targetPeakFrequency * 0.1), &targetPeak);
	Serial.print("Target peak ");
	Serial.print("bin: ");
	Serial.print(targetPeak.bin);	
	Serial.print(", feq.: ");
	Serial.print(targetPeak.position, 6);	
	Serial.print(", height: ");
	Serial.print(targetPeak.height, 6);	
	Serial.println();
	/* Mark event */
	BlinkLed(1);
	while(true); /* Run Once */
	// delay(3000); /* Repeat after delay */
};

Ultimately, the PrintVector() function allows the export of abscissa and ordinate data taken from the time domain and frequency domain.

void PrintVector(uint8_t scaleType)
{	
	uint16_t bufferSize = _samples;
	if (scaleType == SCL_FREQUENCY) {
		bufferSize >>= 1;
	}
	for (uint16_t i = 0; i < bufferSize; i++) {
		float abscissa;
		/* Print abscissa value */
		switch (scaleType) {
		case SCL_INDEX:
			abscissa = float(i);
			break;
		case SCL_TIME:
			abscissa = (i / _samplingFrequency);
			break;
		case SCL_FREQUENCY:
			abscissa = ((i * _samplingFrequency) / _samples);
			break;
		}
		Serial.print(abscissa, 6);
		Serial.print('\t');
		/* Print ordinate */
		Serial.print(DSP.ReadData(i), 6);
		Serial.println();
	}
	Serial.println();
};

 

April fool ! Really ?

I cannot resist to the temptation of reproducing this letter that I picked up from the blog of a veteran analog guru, fan of oscilloscopes and vintage electronics.

hp-letter

 

I was just a project in the sparkling eyes of my parents at the time this letter was written, and I understand that computers where far from the short term preoccupations of Bill and Dave. What’s incredible is that “02″ (nickname of the “computer” division at the time I joined HP) overlapped, not to say vampirized, the whole company which was “01″ mainly for years (“01″ was the “measure” division). I am not sure neither Bill nor Dave were big fans of computers, except for those who were designed for driving their ultimate measuring devices.

I got a chance to get to Page Mill road while I was working at the “Analytical Chemistry Division” (“04″). Actually I missed my way on the first time I visited SID (Scientific Instruments Division), one road ahead in California Avenue! These times are long gone now, memories remain: the smell of hot insulation material, the hiss of crashing hard disk drives, the crackling of short circuits… That reminds me of the b….y A26, (in)famous switching controller board which could blow up the whole boards from the first micro controlled gas chromatograph from HP. Oh noooooooooo. That happened to best of us!

PlainDSP (Part 1)

Part 1234

dsp

Among the most popular subjects covered in this blog, FFT is far ahead any other subject (22%!), followed by data acquisition functions. I got many, many requests for PlainFFT and PlainADC libraries and thanks to your explicit messages, I have a quite good understanding of who is using them and for which type of application. It is now clear to me that most of PlainFFT and PlainADC users have an average level in math and that they do not feel comfortable with advanced DSP functions. On the other hand, these advanced functions are extremely useful for building awesome applications, mainly in the field of arts, or should I say, interactive arts.

Based on this review, I decided to pack all the DSP functions that you like and need the most in a single, compact, fit for purpose library. The code has been optimized in order to simplify the use of the functions, e.g. unless you wish to do so, you do not have to care about vectors of data, you just use some nicknames such as DATA, REAL or IMAGINARY to name them, if you need to do so, do you?.  The PlainDSP performances have been optimized for speed, although it is not quick enough to allow real time processing. When run on an Arduino UNO, the data acquisition engine allows 0.125Hz to 80kHz sampling rates, and it does not take any longer than 75ms to acquire data and compute a 64 bins frequency spectra out of signal captured at a sampling rate of 44.1kHz. The maximum number of samples is limited to 128 when run on the Arduino UNO which includes 2kB; under these conditions, 1k is used for data storage. How come? 128 samples for real data, 128 samples for imaginary data, 4 bytes each samples (32 bits floats) = 2 x 128 x 4 = 1024 bytes. CQFD.

Here is a list of the public functions from the PlainDSP library:

Average();
ClearVector(dataType);
ComplexToReal(scaleType);
Compute(dir);
GetDataAddress(dataType);
GetScanData();
MajorPeak(*result);
MajorPeak(loFrequency, upFrequency, *result); 
Max(); 
Min(); 
Normalize(normalizingValue); 
ReadData(index);	
ReadData(dataType, index);	
ReleaseAcquisitionEngine();
ReleaseVector(dataType);
Rescale(offset, gain);
ResetOffset();
RMS();
SetAcquisitionEngine(adcChannel, refVoltage, samplingFrequency, samples, options);
SizeVector(dataType);
SizeVector(*vData, samples);
TargetPeak(targetPosition, tolerance, *result);
Windowing(windowType, dir); 
WriteData(index, data);
WriteData(dataType, index, data);

 

Power Supplies (Part 1)

As long as you want to blink leds, everything’s fine with the power supplied by the USB cable. Here is a nice clean shield which could help you in fulfilling most power supply requirements.

power-shield-DFR0105

 

The input voltage must lie in the 4.5 et 35 V range, and its output swings from 1.25 to 12V under 3A. It features a simple switcher Power Converter 150kHz, 3A Step-Down VRegulator [Datasheet]. The power supply output can be redirected to the blue terminal or to the Vin pin from the Arduino board to which it is connected. The power supply can be controlled by digital pin 13 and also redirected to Analog pin 0 for voltage control. Clever. And it is affordable: less than 20€ as far as I can read from some vendors.

 

Quadcopters

This post could be named at “Quadcopters and the magic wand” or ”Quadcopters and the flying batons”. While watching this incredible new video, I was dreaming at a new ball game played with quadcopters, where quadcopter would flap a soft ball a little bit like volley ball, and throw it in a basket like in basket ball…

A must see!

Some more information

http://goo.gl/GPjt0 

http://goo.gl/1YIHO

Enjoy