Tips and Tricks (Part 20)

Previous tip and trick

Acquiring data is great, sending data away is even greater. In this way, all sorts of physical measurements can be remotely read in order to capture events, record signals, trigger alarms, etc.

More and more communication solutions exist, each of them having their advantages and drawbacks. The aim of this post is not to provide an exhaustive list of them. However, let’s mention the most popular devices and protocols from the Arduino planet:

  • Xbee/ZigBee: versatile, pretty low power, from cheap to costly
  • RF12: cheap, low power, limited range and functions
  • GSM/GPRS: almost universal, power greedy, expensive

The Xbee modules have a very particular foot print which features 2x 10 pins with 2mm spaces. Many makers addressed the need for Arduino compatible shields, including the Arduino team it self (Check this thread). This particular shield features a sliding switch which allows the user to manage data exchanged between the Xbee module and the micro controller unit (MCU) or the USB cable.

switch1 switch2

But the principle of sharing Rx Tx lines from Arduino has strong limitations, mainly when you need to upload code to the Arduino board, while the shield and the Xbee module are attached to it.

Here is a very easy (almost trivial) trick which will release some of your stress. The idea is to leave the Rx Tx pins in peace with the MCU while applying no non-reversible changes to the electronics or PCB from the shield. This is how:

Take an Arduino board

UNO

Slightly bend the Rx Tx pins from the shield so that they no longer get into the Arduino board socket

shield_pins

Plug the shield on the Arduino board

assembly_pin_in_a

Place one jumper between Rx pin and digital pin 2 and one jumper between Tx pin and digital pin 3

jumpers1

Instead of using the commands from the Serial library, use the commands from any soft serial library (This one for example) and link the pin 2 and 3 to the receive and send pins.

#include <SoftwareSerial.h> // Include library
SoftwareSerial mySerial(2, 3); // Create object and declare Rx and Tx pins

void setup()  
{
    mySerial.begin(9600); // initialize comm port
}

void loop(void)
{
    mySerial.println("AT"); // Send any instruction to the comm port
    while(true); // Run once
}

That’s all! Under these conditions, the shield will perform as before and blink as it should. In addition, you re now free to use the Serial commands for debugging your application.

HTH

 

LCD direct driving (Part 1)

Part 1

Driving LCD units has been largely documented over internet, arduinoos started investigating this subject with this post.  These units look like the following one:

hex

The disassembled front panel features the following parts:

dissassembly

 

 

And the bottom panel of  the LCD unit features two controllers:

LCD_bottom_tag

These controllers handle the signals from Arduino (or any MCU) and drive the LCD matrix which is composed of two lines of 16 characters. Each character is a 5 by 8 dots matrix as illustrated below:

matrix

So the resulting matrix contains 16 lines and 80 rows. This matrix is driven by the controllers with the wiring is illustrated below:

uc_simplified_schema

For example, the controller’s may be one of KS0066, SPLC780D1 or HD74800. Carefully read the communication protocol related to each of these controllers prior to programming your own code.

 

Now we listed the leading components of an LCD unit, we will focus on only one, the liquid crystal display. The goal of this article is to show how to drive a liquid crystal display directly from Arduino, without any controller or external component. Next is a picture of a bare liquid crystal display:

LCD_3_4

 

For sake of simplicity, we will use a 7 segments display. Unlike the alphanumeric LCD units which have been detailed till now,  a character is displayed using 7 segments instead of using a 5 by 8 dots matrix. For example, displaying a ‘A’ is made as follow:

alphanum_7segments_A

The 7 segments display has 24 pins for driving 3 digits of 7 segments and 2 dots arranged as follows :

LCD_segments

Compared to a 4/8 data pins LCD units, using 24 pins may not be handy but it could be nice to use an LCD display in some use cases, for example:

  • very small packaging
  • very low cost
  • curiosity!

Technically, each pin drives one segment except one pin which is called COM (for common). The datasheet of the LCD display above gives the following segments mapping:

LCD_segs

Each digit has 7 segments called A, B…G. For example, activating the segments B2 and C2 will show a “1″ on the center digit. The datasheet provides the following pins mapping:

pin_mapping

Now we know which segment to activate to print something, we will see how to activate a segment. To be set on or off, a liquid crystal segment has to be polarized in one direction, then polarized in the other direction, call it the first and the second pass. Then the segment will keep its state (on or off) for few milliseconds if no voltage difference is applied across it. The voltage applied to a segment is the difference between its associated pin voltage and the COM pin voltage as illustrated below:

unconnected_simplified

Driving an LCD display with Arduino requires the use of the digital pins, they may be:

  • at 0V
  • at 5V
  • left unconnected

Left unconnected ? digitalWrite() does not provide it, huh ? Not directly but the following couple of lines set a pin unconnected (AKA floating or High-Z):

pinMode(pin, INPUT); /* set pin as input */
digitalWrite(pin, LOW); /* set to 0 in input mode */

For sake of simplicity, we will only use the unconnected state for the COM pin as illustrated by the following schema:

unconnected

The following table gives the voltage applied to a segment depending on its pin state and the COM pin state :

COMpinvoltage differenceusage
0V0V0Vturn off a segment (first pass)
+5V+5V0Vturn off a segment (second pass)
0V+5V+5Vturn on a segment (first pass)
+5V0V-5Vturn on a segment (second pass)
unconnected 0V or 5V nohold the last state
In other word, turning a segment off then on is done as follows:

phase

Knowing the theory, displaying a digit can be made in few steps:

  • set each segment data pin according to the  desired text to print
  • set the COM pin low and wait a short period
  • set each segment data pin to the opposite voltage from its previous state
  • set the COM pin high and wait a short period
  • make the COM pin floating

On Arduino, this can be coded as follows:

void Display(uint8_t value)
{ 
/* Set segments data */
uint8_t segments;
segments = vSegments[value];
for (uint8_t i = 0; i < 7; i++) {
digitalWrite(vDataPins[i], (segments & 0x01));
segments >>= 1;
}
/* Common pin state LOW */
pinMode(_comPin, OUTPUT);
digitalWrite(_comPin, LOW);
delay(1);
/* Set segments data */
segments = vSegments[value];
for (uint8_t i = 0; i < 7; i++) {
digitalWrite(vDataPins[i], !(segments & 0x01));
segments >>= 1;
}
/* Common pin state HIGH */
digitalWrite(_comPin, HIGH);
delay(1);
/* Common pin state HIGH-Z */
pinMode(_comPin, INPUT);
digitalWrite(_comPin, LOW);
}

Note: the liquid crystal segments may be damaged if a continuous direct current is applied to them. Take care of not keeping the same voltage across a segment for too long.

Turning on all segments of the third digit except the ‘E’ with Display(0x6F) will display the ’9′ character as illustrated below:

9

Some LCD displays have several COM inputs to manage more segments with less pins, the next post will show how to handle them.

Blog of the day

“Measure the mass of an eyelash with a DIY microbalance”, an awesome project from electronics-lab.com

electronic-lab.com

Range finder (Part 1)

Part 1

A lot has been said and written about the HC-SR04 range finder so that the aim of this post is not to rewrite the same code sample again and again. The idea here is to get one step forward by looking at this sensor in more details and to try to tidy-up some confusing points;

HC-SR04_pic1

The principle of operation of this sensor is based on the time needed for a sound to travel from a source to a destination sensor. A sound burst is generated by a piezoelectric element. This burst is made of a sine wave at 40 000 Hz. This burst travels in a sound cone of approximately 15° towards the target. As the base of the cone expends with the distance from the burst generator, the surface of the target must be large enough for echoing properly the signal. Next plot illustrates the relationship between the distance of the target and its diameter

plot

Also, while flat surfaces are ideal for reflecting the sound burst, this sound burst may slip on an irregular surface and fail to echo the signal properly. The HC-SR04 makes provision for this type of situation and a timeout prevents the module from waiting and waiting, and waiting the echo.

 Once these parameters taken into account, the module proves to be working fine and is able to accurately measure distances ranging from few centimeters to few meters. The datasheets say 2 cm to 400 cm with a resolution of 3 mm. This distance is calculated from the signal produced by the HC-SR04. It consist in a positive square pulse which rising edge occurs when the module generates the sound burst and falling edge happens when the module reads the echo. Knowing the time needed for sound to travel in free air, it is easy to calculate the distance with the following formula: d = 1/2 * burst_travel_time * speed_of_sound. The travel time is halved as the burst has to travel back and forth.

Often neglected is the real speed of sound. Most publications talk about 340 m/s in free air. In reality, the speed of sound in free air - in other words, in earth’s atmosphere – the main factor affecting the speed of sound is the temperature. Next example shows the difference in distance estimates versus temperature.

At 10°C, a signal duration of 10 ms translates in a distance of 1.68 m, while the same pulse duration at 30°C translate in a distance of 1.75 m. So that the temperature parameter will have to be taken into account for accurate measurements. At 20°C, the speed of sound is 343 m/s.

Exercising the HC-SR04 in excellent conditions (stable temperature, concrete walls used as targets, stable measuring devices), the observed performances of the devices are slightly different. Principally in terms of short distances: 10 cm seems to be the shortest distance that the module can measure accurately. Even with oversampling and averaging techniques, 3 mm resolution looks fully theoretical, and I would not advise to build a critical equipment based on this specification. Talking about a 1 cm resolution sounds more reasonable.

In theory, running the HC-SR04 looks straightforward, and it is really as long as no adverse events contradict its measuring process. The measuring procedure is as follows:

  • Send a positive pulse which duration is at least 10 µs on the trigger pin
  • Just after that wake-up signal, the emitting piezoelectric transducer sends 8 ultrasound bursts and sets the echo line to the HIGH state
  • When the receiving piezoelectric element reads the echoed signal, the echo line is set to LOW state
  • Compute distance based on speed of sound in free air

If the receiving piezoelectric element fails to receive and echo within the next 38 µs, the HC-SR04 will timeout. Also, the datasheet specifies that the cylcle time should not be less than 60 ms.

This procedure looks plain simple, and most (not to say all) code samples match this simple approach by using a digitalWrite() HIGH and LOW, followed by a pulseIn() function with an appropriate timeout. Well the reality is not as plain trivial as we will see in the next posts…

 

 

Quadcopters: small is beautiful, micro is lovely

the Harvard School of Engineering and Applied Sciences recently published works  relating to their research Biologically Inspired Engineering. These works resulted in this incredibly small and yet powerful flying robotic insects

124 years from now, Clement ADER pioneered the world in the field of aeronautics by flying the first  biologically inspired object “heavier than air”.

aviationadereole

Here is a picture of the inventor studying the motion of the wings using a “fast” camera

5118_ader01

Eole (name given to the first plane) was steam powered (Yes, steam powered! The engine was weighing 51 kg and developed 15 kW), assembled with light natural material like bamboo and controlled by an incredibly sophisticated system  made of cables and pulleys attached to 6 command handles. A copy of Eole can be seen in the Musée des Arts et Métiers in Paris / France.

The same principles have been retained by the Wiss Institute and lead to these incredibly small flying objects

A little bit more conventional is the NanoFlyer 2.0 prototype from Pial. It is so cute and yet so handy

img_2738

Pay a visit to this really cool quadcopter at Pial’s blog

 

Compiler warnings (Part 1)

Part 1

By default, when compiling a project with the Arduino IDE, the compiler will only complain if an error occurs  and quietly ignore warnings. Unlike an error, a warning will let you built an application but it may induce a bug. However, an application which contains a warning may be fully functional and  an application with no warning may be buggy! In some cases, (e.g. debugging an application), it may be useful to show warnings too.  The Arduino software will show all of the compiler output, including the warnings if you check “compilation” in File>Preferences>”show verbose output during:” as per the following illustration:

verbose

Now, the Arduino IDE shows the warnings from your projects but also from the Arduino’s built-in libraries among which the very popular HardwareSerial library. Did you ever used it? I’m almost sure that you used it a lot. Remember the  Serial object (e.g. Serial.begin(), Serial.print()…): it is part of the HardwareSerial library. This library is fully operational but using the verbose option while compiling shows  multiple warnings; and it is a little bit annoying to see the following warnings in red in a long list of warning free commands:

C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp: In function 'void store_char(unsigned char, ring_buffer*)':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp:98: warning: comparison between signed and unsigned integer expressions
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp: In function 'void __vector_18()':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp:127: warning: unused variable 'c'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp: In member function 'void HardwareSerial::begin(long unsigned int, byte)':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp:368: warning: unused variable 'current_config'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp: In member function 'virtual size_t HardwareSerial::write(uint8_t)':
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino\HardwareSerial.cpp:467: warning: comparison between signed and unsigned integer expressions

There are 2 groups of 2 warnings:

First group: 2 of them (line 98 and 467) are about a “comparison between signed and unsigned integer expressions”. The following example shows a case where it would be pertinent:

uint8_t twoHundred = 200;
int8_t twoHundredAndOne = twoHundred + 1 ; /* so greater than twoHundred, huh? */
if (twoHundred > twoHundredAndOne) {
	Serial.print("what's going on?");
}

the signed 8 bits integers range from -128 to 127 so twoHundredAndOne overflows and its actual value is -55. A warning when comparing these signed and unsigned number is a great help!

Back to the HardwareSerial source code, in HardwareSerial.cpp, at line 98, the following comparison worries the compiler:

if (i != buffer->tail)

buffer->tail is declared in a structure (HardwareSerial.cpp line 66) as follows:

volatile unsigned int tail;

and i as follows:

int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;

i is of data type int but tail is of data type unsigned int. Since none of these numbers may be negative a clean way to fix this warning is to declare i as an unsigned int:

unsigned int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;

In the same manner, the warning of the line 467 may be fixed declaring the integer i line 462 as follows:

unsigned int i = (_tx_buffer->head + 1) % SERIAL_BUFFER_SIZE;

Second group: the 2 last warnings are “unused variable”. In this case, a variable is created but never used. It could mean that the programmer has forgotten to use the variable or to remove its declaration after deleting a part of code concerning it for example. The first one, line 127

else {
      unsigned char c = UDR0;
    };

Since a variable declared as above only exists in the else scope, the else block is useless and can be safely removed.

In the same manner, the variable current_config declared in the body of the begin() function, line 368, is never used inside this function and does not exist outside, removing its declaration will remove the last warning!

Opening plaindsp.com

This quite a great and important day. After months of efforts, plaindsp.com is opening and introducing its DSP kits. You are kindly invited to pay a visit to plaindsp.com

plaindsp_website

 

Discover the first kit from the pending collection of DSP kits: This kit will allow you to capture all sorts of sounds and analyze them in order to to trigger all sorts of events, starting with easily  manageable and spectacular luminous events.

Plaindsp team is very interested in reading your comments on the forum or using the contact form.

You may also wonder about the future of Arduinoos blog… Well, no worries. Arduinoos will keep publishing information related to high tech, popular science, co-working initiatives, FabLabs and all the amazing matters usually covered at Arduinoos.

 

 

Breaking news

The content from the numerous exchange of mails and a careful analysis of visited pages on arduinoos show that many, many people from the planet of hackers, makers, learners, are very interested in advanced applications which mostly require digital signal processing functions. Not all Arduino fans had a chance to learn and practice DSP, so that many of you liked the FFT presentation on arduinoos very much. Also, many of you expressed the need for exercising, experimenting or prototyping devices which would feature DSP and FFT.

I discussed these subjects with a newly created company - HL2 group- which is focused on Embedded Systems and Machine To Machine. HL2 has an original approach of business as it covers the wide market, ranging from open-source (software and hardware) up to the most advanced industrial systems. HL2 immediately paid attention to the expressed need as it is also involved in fast prototyping and thus uses many plug and play hardware and software resources of its own, including advanced code.

And here comes the answer to the expressed need for an original solution for those who create, learn and teach !

1

The solution comes under the form of an elegantly package thematic kits which contains a 100+ pages book which contains the required knowledge for understanding the principles of the covered matter. Along with this book come a versatile shield which will allow users to reproduce all examples given in the book and start creating their own application. Last but not least, the kit will allow you to access to improved versions of the related libraries and applications which made the reputation of arduinoos.

2

On top of that, HL2 will launch the first kit from a brand new web site, featuring a blog and a forum where you will be able to get support, find ideas and technical information. The grand opening is planned for the next coming days, and we will look forward to hearing from your comments soon !

Memory (PART 7)

Part 123456, 7

The previous post shows how to store from tens to  thousands of lines in an EEPROM chip and how to print them on a LCD unit. But the sketch which stores the strings can’t exceed the memory space available : 32kB (flash memory) – 0.5kB (boot loader) = 31.5kB (On arduino UNO and compatible boards). One way to get around this issue is to type the text when the program runs instead of storing the text directly in the program. This is not a big deal with the Arduino’s serial monitor :

serial monitor

Clicking on the top-right buttons spawns a serial monitor window

The following sequence shows how to do so :

  • Initialize the EEPROM chip and the serial communication
  • Append a newly typed character in a buffer
  • Sore the buffer in EEPROM if the trailing character is a Carriage Return (CR)

The carriage return detection induces the need for … a carriage return. Making the serial monitor append a carriage return when the key “enter” is typed is easy, just select the following option :

line ending

Choose the “carriage return” line ending. Don’t forget to set the appropriate baudrate too.

In the Arduino environment, retrieving the incoming characters can be achieved in the serialEvent() function. This function is called after loop() when at least one character is available in the input buffer.

So, we brought some improvements on the original sketch described in the previous post. The initialization is performed as follows :

void setup()
{
	InitEEPROM();
	InitSerial();
}

void InitEEPROM()
{
	/* Reset all CS pins from PORTB */
	DDRB |= 0x07; /* Set PB0:2 as output ports */
	PORTB |= 0x07; /* Set PB0:2 to high */
	MEM.InitializeSPI_EEPROM(&PORTB, PINB2, SPI_EEPROM_25LC320);
	/* Compute the number of lines that can be stored depending on the flash device */
	_max_lines = MEM.Pages() * MEM.PageSize() / 16;
}

void InitSerial()
{
	Serial.begin(115200);
	Serial.print("Welcome !");
	Serial.println();
	Serial.print("Please enter an author name :");
	Serial.println();
}

And the repetitively called functions() :

void loop()
{
	/* no blocking code here (such as delay()). */
}

void serialEvent()
{
	/* defines the two possible states and the size of the buffers */
	const uint16_t author = 100;
	const uint16_t sentence = 1000;
	/* a short array to store an author name */
	static char authorBuffer[author + 1];
	/* a large array to store a  sentence */
	static char sentenceBuffer[sentence + 1];
	/* the first string to write is the author name*/
	static uint16_t state = author;
	/* points to the current buffer */
	static char* currentBuffer = authorBuffer;
	/* the temporary characters count */
	static uint16_t cursor = 0;
	
	/* process each character from the input buffer */
	while (Serial.available()) {
		char c = (char)Serial.read(); /* the returned data type of read() is int */
		if(c == '\r'){ /* the carriage return written by the monitoring software */
			currentBuffer[cursor] = '\0'; /* explicitly end the line */
			Serial.println();
			if(state == author){
				/* prepare a sentence */
				Serial.print("Please enter a sentence :");
				Serial.println();
				currentBuffer = sentenceBuffer;
				state = sentence;
			} else {
				/* actually store the sentence and its author */
				WriteSentence(authorBuffer, sentenceBuffer);
				/* print few statistics */
				Serial.print(_lines);
				Serial.print(" lines in the EEPROM. ");
				Serial.print(_lines * 100 / _max_lines);
				Serial.print(" % full");
				Serial.println();
				Serial.println();
				Serial.print("Please enter an author name:");
				Serial.println();
				/* prepare the next author */
				currentBuffer = authorBuffer;
				state = author;
			}
			cursor = 0;
		} else if(cursor < state){ /* input a regular character and avoid a buffer overflow */
			Serial.print((char)c);
			currentBuffer[cursor] = c;
			cursor += 1;
		}
	}
}

That’s it !

 

memory_7_example

Flash News: versionning

Major events are pending behind the screen of Arduinoos. A major consequence is the backlog in the answers to your code request and we are very sorry for that. A minor consequence of the pending works behind arduinoos is the new namming convention for libraries and application packages that we are happy to share.

All arduinoos libraries packages WERE nammed using the following pattern:

PlainXXX_YYYYMMDD

where:

  • XXX is a specifying suffix (e.g. DSP)
  • YYYY is the year
  • MM is the month (01 to 12)
  • DD is the day of release

All arduinoos libraries packages ARE NOW named using the following pattern:

PlainXXX_NumberLetter

where:

  • XXX is a specifying suffix (e.g. DSP)
  • Number is a sequentially attributed number starting at 1 (Major version)
  • Letter is a sequentially attributed letter starting at a (Minor version)

e.g. plainDSP_1a

All minor versions belonging to the same major version shall be compatible. In other words, minor versions will contain bug corrections (if any…) and small improvements. On the other hand, major versions will contain new functions, changes in structures. Major versions may not be backward compatible.

e.g. PlainDSP_1a functions WILL BE COMPATIBLE with Plain_DSP_1z while PlainDSP_2a functions MAY NOT BE  COMPATIBLE with Plain_DSP_1z

Congratulations Cesar, you are the first recipient of the newly named packages (actually PlainPWM_1a).

g3802

This is what you got today: a zip file featuring the new naming convention (circled in red). This zip file contains a directory (circled in blue) which it self contains code, examples and documentation (circled in green).

HTH