Sunday, August 26, 2012

The Must Build Arduino Project - The Illutron B

Is there a must build Arduino project ? Something simple that can be built in minutes and tinkered with for days or weeks ?

There is now.

Presenting the Illutron B -




The Illutron B is a development of the Illutron synthesizer originally created by Nikolaj Mobius. All of the sound in the clip is being generated by the Arduino with no outside assistance or post processing - the bass notes are extraordinary.

Even more incredibly is that all of the sound is being generated using just one analog output.

How does it work ?
If you think of an analog output as a power switch, the longer it is switched on, the more power we output. By varying the duration that the power is on over time we can output a waveform, for example a sine wave.

Its a technique known as Direct Digital Synthesis. The is a good example here http://interface.khm.de/index.php/lab/experiments/arduino-dds-sinewave-generator/


Taking it further - Skip the theory if you like, or read on -
The Illutron B is a wave table synthesizer, this is a synthesizer which uses the Direct Digital Synthesis described above to generate sound waves using descriptions 'wave tables' that are stored in the memory. 

The wavetables are simply arrays, if you take the values from each of the wave header files and copy them into your favorite spreadsheet you will see the following - 


Synth designers know that as listeners we do not find endlessly repeating sine, square or triangle waves very interesting. To make the sound more musical wave table synthesizers combine the waveform with an envelope. 


The envelope describes the power or loudness of the waveform over time - think of a snare drum, its starts very powerfully and decays away to nothing very quickly - a flute can start softly, reach a level then decay softly - its the envelope that describes this. The simple trick of combining the wavetable with an envelope is responsible for the huge range of musical possibilities in wavetable synthesis.

How do we do this in software ? - It couldn't be easier, we mulitply the waveform by the envelope, as the envelope value gets smaller, so the output waveform shrinks away to nothing.

Have a look through the code, its extensively documented.

Built in envelopes - the faster the sound drops away, the more percussive (drum like) the envelope -


You can add your own envelopes, or modify the supplies ones, there is no rule that an envelop cannot start quietly and get louder - or look like a heart beat for a pulsing bass sound.


Build your own pocket night club -

How long does it take to build ? anywhere from 5 to 10 minutes, seriously, if you have two potentiometers a few capacitors and resistors you can be playing your own Illutron B in 10 minutes.

What does it do ?

While the synth is very powerful, Nikolaj has included a demonstration tune which is the basis of the clip.

In the clip I am using the Illutron B which provides control over the beats per minute and also the pitch of one of the four channels using just two potentiometers to jam with the demo tune.

This is where RCArduino comes in. When I first heard the Illutron I was blown away, it is far and away the best Arduino Audio project of all. The drum sounds are awesome, the bass is incredible, you will not get tired of exploring those low notes. I know that as a community we can make great things from this.

For this reason I have spent the past few days refactoring, optimizing and documenting the Illutron version B.

Some ideas for your own Illutron projects -

1) Hook up some peizo knock sensors for an electronic drum kit
2) Bass loop generator with push buttons for different bass drops
3) A four channel sequencer
4) Sound effects for games, installations and robots
5) Its a great basis for a Thermin or similar physical instrument.
6) Add some soft pots, cross faders or a stylus to control the pitch of the different channels

Nightclub in your pocket

My own idea is to build on the current example - Ideally I would like to see a set of beats or tunes included in a 'Night club in a box' where the user can select the beat with a push button. The user is then free to jam with the selection in the same manner as the video - Arduino, two potentiometers, one resistor, two capacitors, synched LED Light show and you have an instant pocket night club that everyone can enjoy.


In order to support the further development of Nikolaj's original concept I have refactored the original Illutron code into a more user friendly class library while at the same time taking the opportunity to do some optimizing and improve the readability of the code.

If you would prefer to use Nikolaj's original code for the Illutron Wave Table Synth, its available here - http://www.instructables.com/id/Turn-your-Arduino-into-a-4-voice-wavetable-synth-w/

The Illutron B code is being added to the Illutron repository on github I will provide a link once its uploaded,  in the meantime, you can get it from me - DuaneB on the Arduino forum.

If your a musician it should be immediately obvious how to setup and trigger the different voices, the sample sequencer is also easy to understand and modify. If like me you are not a musician, build one anyway, the demo tune is great to play with and I hope to get some new tunes included for you to upload.

Whats an Illutron ?

Its actually an art studio on a ship in Copenhagen harbour. The original Illutron synth was created by a member of the Illutron collective Nikolaj Mobius. You can find out more about Illutron and their work in light, sound, electronics and a surprising amount of fire here - http://illutron.dk/posts/54


Building your own Illutron B - 

The easy part - 
2 * 10 K Potentiometers
4 * LEDs (or eight if you like)
4 * LED Current Limiting Resistors (500 to 1000 Ohms should be fine)

The only slightly less easy part -

Jelly Beans

What are Jelly Beans and why do I need them ?

Jelly Beans are those common components that all circuits need and you should have a jar full of. If your just starting out, you might not have these, but get some, they are very cheap standard components which are widely used in all sort of circuits.

1 * 2.2K resistor (or two 1K resistors in series - anything thats close)
1 * 0.1uF capacitor - you should have hundreds of these, they are used for stopping interference from other components from reaching the sensitive parts of your circuits, if you don't have any, buy 20, they are cheap and you will use them for everything.
1 * 100uf  capacitor - again these are widely used. In this case the capacitor is there to filter out a DC voltage so that your Audio equipment only receives the alternating signal part of the Arduino output. If you don't have any of these, get 10.

Here is the Schematic -

Note : The Fritzing software used to draw the circuit labels C2 with 0.1mF, this is the 100uf capacitor, 100uf is the most common way to represent this value but 0.1mf is also correct (1uf = 0.001mf so 100uf = 0.1mf)

You can also follow the original build instructions here -http://www.instructables.com/id/Turn-your-Arduino-into-a-4-voice-wavetable-synth-w/

Here is mine as used in the video. For the nightclub in a box project I will be adding two amplifiers based on the previous rcarduino post - Adding Audio To Arduino Projects - http://rcarduino.blogspot.com/2012/08/adding-audio-to-arduino-projects.html


The final part of the build to to plug the Illutron B into your MP3 Player docking station - I used a section of head phone cable soldered to a three pin header for this -


The code is now available for download on the RCArduino downloads page here -

http://rcarduino.blogspot.ae/2014/02/rcarduino-downloads.html

If you have any problems with the download, contact me 'DuaneB' through the Arduino forum or leave a comment.

In a future post I will explore more of the capabilities of the Illutron B, the Illutron team will also be working on new Illutron synth based projects.

Stay tuned

Duane B


Tuesday, August 21, 2012

RCArduino passed 40,000 Hits Today

RCArduino has been visited 40,000 times since I bought my first Arduino and started the blog in January of this year.

So whats coming in the future ?

In no particular order-

1) An update to the serial servo library that gives the option of an additional ten servos so that now we can have 20 servos using only four pins and two 30 cent chips.
Twice the power of this - http://rcarduino.blogspot.com/2012/08/arduino-serial-servos.html Ten servos on two pins -


2) A new servo library that does not require external components but includes some novel features which will be useful in a range of applications - its currently on the desk next to me generating a servo signal from almost every single pin of my Arduino - thats right 18 Servos one from every nonessential digital pin and one from every single analog pin - thats not one of its advantages, just part of the testing process before I release it.

3)  More on the RCArduino Lap Timer build along. We have run two rounds of a lap record contest using the system at the Pro RC Track in Dubai. One of the questions everyone asks is can they have their own personal timer to take home and can they be paired with two different cars so that you can run against each other using individual boxes. This is something I am working to address, so stay tuned.

Some laps from the first contest run using the RCArduino Lap Timer - one in a box, one on breadboard both running the code published on this blog.

4) I have made a breakthrough in the design of a fast lightweight library for reading RC Receivers, in the meantime there are two optimizations I will release for the previous approach provided here - http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html - Look out for an update.

Finally if you have used the code or techniques from the RCArduino blog to build something interesting, let me know and I will post it.

Stay Tuned

Duane B

RCArduino

Sunday, August 19, 2012

Adding Audio to Arduino Projects

Sometimes a project just needs to be louder, whether its a synthesizer, alarm clock, autonomous robot or the RC Arduino lap timer.

In the case of the lap timer, I want people in the club house to know when a lap record has been broken, it all adds to the pressure and the fun of racing.

One incredibly simple solution to getting more sound from a micro controller is the LM386 series of amplifier chips. These can give project quality audio for less than a dollar.  They even make a passable one dollar MP3 docking station and are the basis of the 'little gem' guitar amplifier.


LM386-N4 Big Audio In A Tiny Package - 

Parts List - 
1 x LM386-N4
2 x 100uf Electrolytic Capacitors
1 x 0.1uf Capacitor
1 x 100Ohm Resistor
1 x 10K Potentiometer

Circuit pictured is used to drive a PC Speaker in the RCArduino Lap Timer project - See the video.


The LM386 Minimal Components Circuit

The datasheet for the LM386-N4 which I am using provides some example circuits but these require non standard capacitors - by non standard I really mean that most of us keep 'decade' capacitors meaning the tens - 0.01uf , 0.1uf, 1uf, 10uf, 100uf. The sample circuits require 250uf and 0.05 uf capacitors.

As I didn't have these values, I built the sample circuits with 100's in series and 0.1's in parallel to get 200uf and 0.05uf. After playing with the circuit for a while I removed the series and parallel capacitors leaving just a single 100uf and one 0.01 uf capacitor. This variation of the recommended circuit works perfectly well, and is now included in the built version of the RCArduino Lap Timer.

So for a super simple chip to add quality sound and volume to a project order a few LM386N4's its amazing how many projects can benefit from bigger sound when its as easy as this.


Simplified LM386N4 Circuit To Drive PC Speakers From A Micro controller

Caution : The new generation of 32 Bit ARM chips used by the Arduino Due are less able to sink and source current than the AVR Chips used in the 8-bit Arduinos. A number of users have reported burnt out DAC (Digital To Analog Converter) outputs while using the Arduino Due. It is suggested that a series current limiting resistor should be used between the Arduino Due DAC Outputs and external circuitry.

There are currently a number of topics covering the Arduino DAC outputs and pin protection in general on the Arduino Due forum - http://arduino.cc/forum/index.php/board,87.0.html

The circuit below shows a suitable circuit for 8-bit AVR Arduinos - UNO, Mega, Leonardo etc.



 Data sheet with alternative circuits and full application details -

http://www.ti.com/lit/ds/symlink/lm386.pdf

The RCArduino Five Dollar Synthesizer, Arduino audio played through the LM386 amplifier driving a PC Speaker

Project details here -
http://rcarduino.blogspot.com/2012/10/five-dollar-synthesiser.html

 


The Auduino
The five dollar synth is a great project if your up to re purposing an existing keyboard, if not, you really have to build an Auduino.

The Auduino is one of the best sounding Arduino Audio projects, it is also the easiest to build requiring only five potentiometers.
 
Update: The first video is my own Auduino, any others I post are enhanced Auduino's which for one reason of another are nicer than mine, so skip mine and have a look at what everyone else is able to get from this simple sketch through the use of clever additions -

My Own Audiuno - 
Totally standard Audiuno code with output direct to a PC Speaker using the LM386 Amplifier circuit shown in this post.


Auduino By DenkiTribe

A very musical Audiuno based jam -

The project enclosure seems to be closely related to a pizza box but we can forgive that for the very musical session. Modifications are obviously the stylus based pitch control and the addition of external echo.



Auduino By 'TheHangMansAxe'

As far as I can tell, thehangmansaxe has enhanced his auduino with two additions

1) An LED and LDR that 'gates' the output, for those of us with no audio background, gating is essentially connecting and disconnecting a signal from the output.

In DIY Projects LDRs are often used for this as they have an output which is a rough approximation to many stringed instrument where the initial note is loud but then decays away over time. LDRs initially react to light very quickly, but when the light is removed, they settle more slowly allowing the not to linger slightly.

At around the 1 minute mark the user shows the LED switching on and off through the side of the instrument.


2) Thermin style note sensing. The user does not provide any details, but I assume that the note is being controlled by infra red bouncing off the users hand. The original Audiuno design provided on tinkerkit uses five analogue inputs to control the sound, generally these are connected to puts but can also be replaced by any device capable of providing and analogue output.

UPDATE - 25/10/2012 - Added this section to explain how the Auduino works. It needs diagrams and rewritting for reduced length and increased clarity.


How does the Auduino work ?
While I am a big fan of the Auduino, its not that well documented. It is described as a 'granular synthesiser', I spent a lot of time reading up on granular synthesis and reverse engineering the code before I was able to understand exactly how the Auduino generates its particular sound.

A granular synthesizer is usually described as generating sound by rapidly repeating a small 'grain' of sound and if you read through the Auduino code you will certainly find repeated reference to grains however what and where are the grains ?

Outside of the Auduino project, the term grain is most often used to describe grains of sound which are sampled from real life speech, instruments or environmental sounds - a grain is a very short sample in the order of 1/10 to 1/10,000th of a second as opposed to the sampled vocal and drum tracks that you might be familiar with.

Pereshaped points out in the comments below that the synthesis technique used by the Auduino is closer to 'Vosim' that grain synthesis.
 
The Auduino code is actually very clever and efficient, instead of storing a grain the Auduino generates the grain in realtime using a simple counter.
The variables grainPhaseAcc and grainPhaseAcc2 are basically just counters. They count up, then down at a rate determined by grainPhaseInc and grainPhaseInc2. If you were to plot the value of these variables over time each one would give you a triangle waveform.

  // Increment the phase of the grain oscillators
  grainPhaseAcc += grainPhaseInc;
  grain2PhaseAcc += grain2PhaseInc;

The two variables grainPhaseInc and grainPhaseInc2 are directly controlled by two of the Auduino inputs. Adjust the potentiometers up and down and you will hear a frequency component of the output rise and fall in pitch as the relevant triangle wave increases and decreases in frequency.

These are not our main pitch control though, vary them up and down and while the quality of the note will change dramatically, the pitch of the note will stay the same.

The note pitch is controlled by the variable synchPhaseInc. This has an interesting job to do, it controls the rate at which yet another counter - synchPhaseAcc overflows. Whenever this counter overflows, it resets the the two triangle waveforms to an initial synchronized position. This periodic resetting of the two waveforms is what causes repetition of a repeatable 'grain' of sound. The rate of repetition gives the output its pitch.


Its actually a lot more interesting than that, what makes the Auduino sound so engaging is that as you increase or decrease the output frequency so you adjust the amount of the grain that is repeated adding additional layers of colour to the output tones.

The final stroke of genius in the Auduino design (its not my design so I am allowed to say this) is the use of the pentatonic scale. Instead of allowing you to choose any frequency you like the main pitch control is mapped to the musical scale know as the pentatonic scale. This is what gives the Auduino a kind of bluesy sound and ensures that you will never hit a duff note. For more on the pentatonic scale check out the wikipedia article.


A picture speaks a thousand works and Miro2424 has kindly posted this video of an Auduino in action on youtube. In the video you will see the two triangle waves superimposed on each other, you will see and hear how they are used to create both the pitch and the tone of the sound.


Auduino By Miro2424
I have been trying to learn how an 'addative', 'grain' or 'frequency on frequency' synthesizer like the Auduino works. This clip from Miro2424 shows the Auduino output visualised through what I am guessing is a high end PC Sound card. In the clip you can see the two triangular grains super imposed on each other and how they are used to create and vary the sound. Very happy to have found this, it makes it all easier to understand.




Everyone should have at least one Auduino, if you have a spare Arduino and 5 potentionmeters you can build one right now - http://code.google.com/p/tinkerit/wiki/Auduino

UPDATE - 01/02/2012
Here is another great variation on the Auduino by Moshang, this one also has the coolest name 'The Groovesizer' and also the best looking case of any I have seen so far.

The groovesizer extends the Auduino with a built in sixteen step sequencer.

Full details here - http://moshang.net/soundjeweler_blog/technique/groovesizer-diy-16-step-sequencer-and-synth/




UPDATE - 16/11/2012 - The Auduino is the original work of Peter Knight, the project home page appears to be inactive. RCArduino has previously reported a bug fix to the project which has not been updated. On the basis that the project is no longer active, a full version of the Auduino code including the bug fix and an added echo effect can be found on RCArduino -
http://rcarduino.blogspot.com/2012/11/auduino-with-delay.html
These two RC Arduino projects can also be built using identical hardware, upload them to your Auduino for a change of scene, you can always re upload the Auduino when your finished.

http://rcarduino.blogspot.com/2012/10/arduino-modular-synthesizer-part-one.html



Duane B

Lap Timer - Potential Coded Transponder Solution

I have just been made aware of this kickstarter project for a very small Arduino compatible device -

http://www.kickstarter.com/projects/digistump/digispark-the-tiny-arduino-enabled-usb-dev-board

One of the things that everyone wants from the RCArduino Lap Timer and that I am currently working on is the ability to run several boxes each linked to a different car.

This device looks like it could be a great solution for generating the unique signals that would pair a car to its lap timer.

Its not a recommendation, I recommend you do your own research but at first glance it looks like these and the RCArduino lap timer could work very well together.

Thanks to Kai Laborenz for suggesting the link.

Duane B

Friday, August 17, 2012

Arduino Serial Servos

Creative Commons License
RCArduinoSerialServos by DuaneB is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License.
Based on a work at rcarduino.blogspot.com.


It is possible to drive a bank of upto 10 independently controlled servos using just two Arduino pins. The concept can easily be expanded to 20 servos using only four pins.

There is very little that is new in the world and this technique definitely isn't new but here is my explanation and a ready made library and test sketch for you to try.

If you have read any of the previous posts on the RCArduino blog you will know that a servo is controlled using a pulse which is between 1000 and 2000 microseconds long.

Its all here if you need a refresher -
http://rcarduino.blogspot.com/2012/01/how-to-read-rc-receiver-with.html

At its most basic a pulse is simply setting a pin high and then setting it low again. The Servo library created by Michael Margolis does this in software, its well know, well supported and a very flexible library.

Here is a quick overview of the Servo Library
http://rcarduino.blogspot.com/2012/01/can-i-control-more-than-x-servos-with.html

Flexibility comes at a cost.

If you were to review the source code of the servo library you would see that a lot of the code is there to give users the choice of which pins to use. By moving this flexibility to hardware we can reduce the code required to generate servo signals and also reduce the Arduino resources to just two pins for each bank of ten servos. The code is also much small and faster as a result.

How does it work ?
The RCArduinoSerialServo library relies on a 4017 decade counter - its an incredibly simple chip that is often used in introductory courses to create LED Chasers.

Sample LED Chaser Using 4017 - The first line represent the clock signal, lines O0 to O9 represent the 4017 outputs. The clock switches the outputs on in sequence giving an LED chaser effect.



The chip has 10 outputs which are switched on in sequence based on a clock signal. This is very similar to what the Arduino Servo Library does in software, it sets the first servo pin high, then sets a timer to come back and set the pin low to end the pulse, at the same time, its sets the next servo pin high to begin that servos pulse, then sets the timer to come back again to end this new pulse and begin the next one.

We can achieve the same result using the 4017 Decade counter and only two Arduino pins. The pin we are most interested in is the clock pin of the 4017 Counter. When we pulse the clock pin, the 4017 will switch the current pin low and set the next pin high - effectively ending the current servo pulse and beginning a new one - just like the hardware LED Chaser above and the Servo Library does in software.

In order to control servos all we need to do is generate a clock pulse based on the required servo pulse durations.

Serial Servos - By controlling the space between clock pulses, we can control the pulse duration for each of 10 channels using only 1 Arduino pin.




Taking a closer look at the clock pulse - 

Here we can clearly see that the clock pulse itself is very short, around 1 millionth of a second. However by varying the time between clock pulses we can control the time that each channel is high - the channel pulse width. 

The second and third clock pulse are clearly closer together and this can be seen in the narrow pulse width of channel O1 and also the servo angle, in the previous image.




Here is the Timer1 Output compare servo routine where it all happens -

// if we are at then end of our ten channels - pulse the reset pin to reset the counter to channel 0 
// else pulse the clock pin to advance to the next channel
// the setOutPutTimerForPulseDuration function sets the timer1 output compare register
// so that it will trigger this function again when we need to end the current pulse and 
// begin the next one, thats it, thats all we need to do to control 10 servos with 2 pins.

void CRCArduinoSerialServos::OCR1A_ISR()
{
  if(m_sCurrentOutputChannel >= RC_CHANNEL_OUT_COUNT)
  {
    m_sCurrentOutputChannel = 0;

    PORTB|=16;

    CRCArduinoSerialServos::setOutputTimerForPulseDuration();

    PORTB^=16;
 }
 else
 {
    PORTB|=2;

    CRCArduinoSerialServos::setOutputTimerForPulseDuration();

    PORTB^=2;
  }
    m_sCurrentOutputChannel++;
}

Looking at the generated assembly code, the whole thing takes only two millionths of a second thats only slightly little longer than a single call to digitalWrite.

Here is a sample sketch which you can use to try the library, it outputs 10 channels from a digital pin 9, reset is through pin 12.

For you to be able try things for yourself, it also reads the pulse width back in using an interrupt on pin2. Each channel is set to a pulse width 100 microseconds greater than the previous channel - ie. Channel 0 = 1000, Channel 1 = 1100, Channel 9 = 1900. You can use the interrupt on pin 2 to read the pulse width back in from each of your channels and show it in the serial monitor.

Don't forge that if you want to drive servos with your Arduino you will need to provide separate power to the servos, here's why -

http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html

http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Install the CPP and .H files into a library folder named RCArduinoChannels

Here is a basic schematic, its that simple - total cost - about 30 cents.



The Sketch -

Note that if the code looks long, it isnt, its all comments, for each line of code there are many many lines of comments for you to read should you wish.

Duane B

// RCArduinoSerialServos by DuaneB is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License.
// Based on a work at rcarduino.blogspot.com.

#include <RCArduinoSerialServos.h>

volatile uint32_t ulRiseTime;
volatile uint32_t ulPulseWidth;

void setup()
{
  Serial.begin(9600);
  Serial.println("RCArduinoSerialServos");
 
  // set the channels
  for(uint16_t nChannel = 0;nChannel < RC_CHANNEL_OUT_COUNT;nChannel++)
  {
    CRCArduinoSerialServos::writeMicroseconds(nChannel,1000+(nChannel*100));
  }

  CRCArduinoSerialServos::begin();
 
  attachInterrupt(0,calcPulse,CHANGE);
}

void loop()
{
  delay(10);

  if(ulPulseWidth != 0)
  {
    // disable interrupts so that our pulse value does not get overwritten while we try and read it
    uint8_t sReg = SREG;
    cli();
   
    // take a local copy of the pulse witdth so that we can reenable interrupts as soon as possible
    uint32_t ulLocalPulseWidth = ulPulseWidth;
   
    // clear the pulse width so that we will only pick up new values written by calcPulse rather
    // than keep printing old values.
    ulPulseWidth = 0;
   
    // turn interrupts back on
    SREG = sReg;
   
    // print the pulse width
    Serial.println(ulLocalPulseWidth);
  }
 
}

// Read pulse width applied to digital pin 2 (interrupt 0)
void calcPulse()
{
  if(digitalRead(2))
  {
    ulRiseTime = micros();
  }
  else
  {
    ulPulseWidth = micros()- ulRiseTime;
  }
}




The .H File -


/*****************************************************************************************************************************
// RCArduinoChannels by DuaneB is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
//
// http://rcarduino.blogspot.com
//
*****************************************************************************************************************************/


#include "Arduino.h"

// Dont change this,
// if you do not need ten channels, just leave some of the 4017 pins disconnected.
#define RC_CHANNEL_OUT_COUNT 10

// Minimum and Maximum servo pulse widths, you could change these,
// Check the servo library and use that range if you prefer
#define RCARDUINO_SERIAL_SERVO_MIN 1000
#define RCARDUINO_SERIAL_SERVO_MAX 2000

//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// CRCArduinoSerialServos
//
// A class for generating signals in combination with a 4017 Counter
//
// Output upto 10 Servo channels using just digital pins 9 and 12
// 9 generates the clock signal and must be connected to the clock pin of the 4017
// 12 generates the reset pulse and must be connected to the master reset pin of the 4017
//
// The class uses Timer1, as this prevents use with the servo library
// The class uses pins 9 and 12
// The class does not adjust the servo frame to account for variations in pulse width,
// on the basis that many RC transmitters and receivers designed specifically to operate with servos
// output signals between 50 and 100hz, this is the same range as the library
//
// Use of an additional pin would provide for error detection, however using pin 12 to pulse master reset
// at the end of every frame means that the system is essentially self correcting
//
// Note
// This is a simplified derivative of the Arduino Servo Library created by Michael Margolis
// The simplification has been possible by moving some of the flexibility provided by the Servo library
// from software to hardware.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////

class CRCArduinoSerialServos
{
public:
    CRCArduinoSerialServos();

    // configures timer1
    static void begin();

    // called by the timer interrupt service routine, see the cpp file for details.
    static void OCR1A_ISR();

    // called to set the pulse width for a specific channel, pulse widths are in microseconds - degrees are for wimps !
    static void writeMicroseconds(uint8_t nChannel,uint16_t nMicroseconds);

protected:
    // this sets the value of the timer1 output compare register to a point in the future
    // based on the required pulse with for the current servo
    static void setOutputTimerForPulseDuration();

    // Records the current output channel values in timer ticks
    // Manually set by calling writeChannel, the function adjusts from
    // user supplied micro seconds to timer ticks
    volatile static uint16_t m_unChannelSignalOut[RC_CHANNEL_OUT_COUNT];

    // current output channel, used by the timer ISR to track which channel is being generated
    static uint8_t m_sCurrentOutputChannel;

    // two helper functions to convert between timer values and microseconds
    static uint16_t ticksToMicroseconds(uint16_t unTicks);
    static uint16_t microsecondsToTicks(uint16_t unMicroseconds);
};



The CPP File - 


/*****************************************************************************************************************************
// RCArduinoSerialServos by DuaneB is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
//
// http://rcarduino.blogspot.com
//
*****************************************************************************************************************************/

#include "arduino.h"
#include "RCArduinoSerialServos.h"

/*----------------------------------------------------------------------------------------

This is essentially a derivative of the Arduino Servo Library created by Michael Margolis

As the technique is very similar to the Servo class, it can be useful to study in order
to understand the servo class.

What does the library do ? It uses a very inexpensive and common 4017 Counter IC
To generate pulses to independently drive up to 10 servos from two Arduino Pins

As previously mentioned, the library is based on the techniques used in the Arduino Servo
library created by Michael Margolis. This means that the library uses Timer1 and Timer1 output
compare register A.

OCR1A is linked to digital pin 9 and so we use digital pin 9 to generate the clock signal
for the 4017 counter.

Pin 12 is used as the reset pin.

*/

// Timer1 Output Compare A interrupt service routine
// call out class member function OCR1A_ISR so that we can
// access out member variables
ISR(TIMER1_COMPA_vect)
{
    CRCArduinoSerialServos::OCR1A_ISR();
}

void CRCArduinoSerialServos::OCR1A_ISR()
{
    // If the channel number is >= 10, we need to reset the counter
    // and start again from zero.
    // to do this we pulse the reset pin of the counter
    // this sets output 0 of the counter high, effectivley
    // starting the first pulse of our first channel
  if(m_sCurrentOutputChannel >= RC_CHANNEL_OUT_COUNT)
  {
    // reset our current servo/output channel to 0
    m_sCurrentOutputChannel = 0;

    // pulse reset on the counter - we set it high here
    PORTB|=16;

    // set the duration of the output pulse
    CRCArduinoSerialServos::setOutputTimerForPulseDuration();

    // finish the reset pulse - we set it low here
    PORTB^=16;
 }
 else
 {
  // pulse the clock pin high
    PORTB|=2;

    // set the duration of the output pulse
    CRCArduinoSerialServos::setOutputTimerForPulseDuration();

    // finish the clock pulse - set it back to low
    PORTB^=2;
  }
    // done with this channel so move on.
    m_sCurrentOutputChannel++;
}

// After we set an output pin high, we need to set the timer to comeback for the end of the pulse
void CRCArduinoSerialServos::setOutputTimerForPulseDuration()
{
  OCR1A = TCNT1 + m_unChannelSignalOut[m_sCurrentOutputChannel];
}

// updates a channel to a new value, the class will continue to pulse the channel
// with this value for the lifetime of the sketch or until writeChannel is called
// again to update the value
void CRCArduinoSerialServos::writeMicroseconds(uint8_t nChannel,uint16_t unMicroseconds)
{
    // dont allow a write to a non existent channel
    if(nChannel > RC_CHANNEL_OUT_COUNT)
        return;

  // constraint the value just in case
  unMicroseconds = constrain(unMicroseconds,RCARDUINO_SERIAL_SERVO_MIN,RCARDUINO_SERIAL_SERVO_MAX);

  // disable interrupts while we update the multi byte value output value
  uint8_t sreg = SREG;
  cli();
 
  m_unChannelSignalOut[nChannel] = microsecondsToTicks(unMicroseconds);

  // enable interrupts
  SREG = sreg;
}

uint16_t CRCArduinoSerialServos::ticksToMicroseconds(uint16_t unTicks)
{
    return unTicks / 2;
}

uint16_t CRCArduinoSerialServos::microsecondsToTicks(uint16_t unMicroseconds)
{
 return unMicroseconds * 2;
}

void CRCArduinoSerialServos::begin()
{
    // set the pins we will to outputs
    pinMode(9,OUTPUT);
    pinMode(12,OUTPUT);

    // pulse reset
    digitalWrite(12,HIGH);
    digitalWrite(12,LOW);

    TCNT1 = 0;              // clear the timer count  

    // Initilialise Timer1
    TCCR1A = 0;             // normal counting mode
    TCCR1B = 2;     // set prescaler of 64 = 1 tick = 4us

    // ENABLE TIMER1 OC1A INTERRUPT
    TIFR1 |= _BV(OCF1A);     // clear any pending interrupts;
    TIMSK1 |=  _BV(OCIE1A) ; // enable the output compare interrupt 

    OCR1A = TCNT1 + 4000; // Start in two milli seconds
}

// See the .h file
volatile uint16_t CRCArduinoSerialServos::m_unChannelSignalOut[RC_CHANNEL_OUT_COUNT];
uint8_t CRCArduinoSerialServos::m_sCurrentOutputChannel;









Sunday, August 12, 2012

Lap Timer Build Along Part 2 - The Transponder

If you want to set up a track and test your skill in the parking lot or at the BMX Track you can with the RC Arduino Personal Lap Timer. There is no need to carry a laptop to the park or to set up sensor bridges, the lap timer is small enough to fit in your pocket, uses standard batteries and best of all can be built for around 30 dollars.

 Its a personal lap timer meaning a single car at time, but you can have a lot of fun setting hot laps and then challenging your mates to beat them, thats the model we are currently using at our club track in Dubai.

My soon to be beaten m-Chassis hot lap at the Pro RC Track in Dubai-

The single best feature of the lap timer is the big buzzer in the bottom right of the pciture, this gives instant feedback while you are driving, with 10 corners in 19 seconds theres not a lot of time to check the display, but a single beep for a new lap and a double beep for a new best is suprisingly effective and motivating !




Part One of the build shows how to build a manual version of the system on breadboard, in order to build the full automated version of the system we need to build the infrared transponder.

Part One - http://rcarduino.blogspot.com/2012/07/lap-timer-build-along-part-one.html

If you want to time an automobile or kart ask your track whether they already have an infra red beacon, if so you can skip this step.



The final version of the transponder has been tested in an RC Race car running an electrically noisey brushed motor and a noisey electronic speed controller. In most of my cars the earlier versions of the transponder were perfectly reliable however I just couldn't get the earlier designs to work in this particular car, after 20 laps or so the laptimer could not longer detect the signal. The solution used in this final design is to add a voltage regulator which prevents noise crossing from the car into the transponder or equally important -from the transponder back into the car.

The Parts List - 

The Regulator 
I have used a 7805 regulator, this takes the 8.4-7.2 volts supplied by the car battery as input and produces a steady 5volts as output. We use the 5 volt output to drive the timing components which actually produce the transponder signal.

You can replace the 7805 regulator with more modern alternatives, just ensure to use the supporting components recommended in your chosen regulators datasheet.

Regulator

1 - 7805 Voltage Regulator

Regulator Supporting  Components
2 - 100uf Electrolytic Capacitors
1 - 0.1 uf Ceramic Capacitors

Recommended Addition
1 - Diode

The diode is include to protect the rest of the circuit from accidental reverse power connection.

The Signal Timing Circuit

The timing circuit is based on two 555 timers, these are the basis of many introductory electronics projects so are widely available and inexpensive.


The 555 timers use a simple set of external components to set the timing behaviour and frequency. The type of circuit we want to build is called an 'astable' this is a circuit which has two states (on and off) but is not stable in either of them, the circuit continually alternates between the two states - on,off,on,off and so on.







Here is a nice introduction to the 555 Timer - http://www.kpsec.freeuk.com/555timer.htm

There are also many online calculators giving required component values for the frequencies you enter -
http://www.ohmslawcalculator.com/555_astable.php

For our transponder we want two on/off circuits running at different frequencies, the first is a 38Khz circuit which switches the Infra Red LED on and off 38,000 times a second. The second circuit is much slower and simply switches the first circuit on and off at 100Hz (100 times a second).

The transponder signal is the 100Hz signal, this means that in a car travelling at 60Km/h we should receive six pulses in the time it takes the car to travel one meter, this is enough for use to reliably detect an RC Car. For full size cars the detection zone is much bigger as the tracks are wider, its actually easier to detect a faster full size can than it is a fast RC Car on a narrow track.

For a great introduction to Infra Red detectors and why the 38Khz signal from the first timer is important, see the following link and tutorials -  http://learn.adafruit.com/ir-sensor

Timing Circuit Parts List - 
2 - 555 Timer ICs
1 - 1uf Electrolytic Capacitor
2 - 0.1 uf Capacitors
1 - 0.01uf Capacitor

2 - 1K Resistor
1 - 10K Resistor
1 - 220 Resistor
1 - 680 Resistor


To build the full lap timer with audio feedback you will need the following additional components -

1 - 38Khz IR Detector
1 - Peizo Buzzer of your choice
1 - NPN transistor to drive the buzzer
1 - LED

Next Step - building the transponder, stay tuned

Duane B







Monday, August 6, 2012

3-axis accelerometer motion detector project

Description:
A 3-axis accelerometer sits at the heart of this project to provide a nifty little motion detector. Want to know who is stealing from the cookie jar? Want a simple home intrusion detector? Or to test your partner's driving skills? Then have a look at this:

(Soldering required for this project)


Video:




Parts Required:


Instructions:

  1. Overlay the Seeed Studio Base Shield onto the Freetronics Eleven (or compatible Arduino).
  2. Use a Universal Cable to attach a Seeed Studio Grove Button to Analog Pin 0 on the Base Shield. The socket is located directly above the Freetronics Eleven Power plug, and next to the Reset button on the Base Shield. Please note that Analog Pin 1 is not used by the Grove Button.
  3. Use a universal Cable to attache a Seeed Studio Grove Buzzer to Analog Pin 1 on the Base Shield. This is the socket next to the one used in Step 2.
  4. Solder the female header pins to the Protoboard. Overlay the protoboard onto the Base Shield to create a third layer. I created this layer to tidy up the project and make it a little bit more portable. You could just wire up another breadboard on the side.
  5. Stick a mini-breadboard (4.5cm x 3.5cm) onto the protoboard. This allows you to use the protoboard for other projects.
  6. Solder the male headers to the 3-axis accelerometer, and then place it centrally onto the breadboard.
  7. You need 5 wires to connect:
    • GND on protoboard to GND on accelerometer
    • 5V on protoboard to     VIN on accelerometer
    • Analog Pin 3 on protoboard to X on accelerometer
    • Analog Pin 4 on protoboard to Y on accelerometer
    • Analog Pin 5 on protoboard to Z on accelerometer
  8. Connect digital pin 8 to an LED and 330 ohm resistor on the breadboard,
  9. Use a wire to connect the resistor mentioned above to GND on the protoboard
  10. Connect the USB cable from your computer to the Freetronics Eleven, and upload the Arduino Sketch to the board. 
  11. Disconnect the USB cable, and then power the Freetronics Eleven using a 9V battery and clip.
  12. When you press the button, it will sound 3 warning sounds before it becomes activated.
  13. If it detects a vibration or motion that exceeds the tolerance level, it will alarm. The alarm will continue until you either press the Grove button - which resets and reactivates the device or you can press the Reset button on the Base Shield to Stop monitoring for motion.


Sketch







Freetronics Eleven / Arduino Sketch:

 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//Motion Detector Alarm - Written by ScottC on 2/08/2012

//Global Variables and constants
const int buttonPin = A0; // button Pin connected to Analog 0
const int buzzerPin = A1; // buzzer Pin connected to Analog 1


//Accelerometer Pins
const int x = A3; // X pin connected to Analog 3
const int y = A4; // Y pin connected to Analog 4
const int z = A5; // Z pin connected to Analog 5


//Alarm LED
const int ledPin = 8; // LED connected to Digital 8



int tolerance=20; // Sensitivity of the Alarm
boolean calibrated=false; // When accelerometer is calibrated - changes to true
boolean moveDetected=false; // When motion is detected - changes to true



//Accelerometer limits
int xMin; //Minimum x Value
int xMax; //Maximum x Value
int xVal; //Current x Value

int yMin; //Minimum y Value
int yMax; //Maximum y Value
int yVal; //Current y Value

int zMin; //Minimum z Value
int zMax; //Maximum z Value
int zVal; //Current z Value



void setup(){
//Begin Serial communication
Serial.begin(38400);

//Initilise LED Pin
pinMode(ledPin, OUTPUT);

}



void loop(){
// If the button is pressed, initialise and recalibrate the Accelerometer limits.
if(analogRead(buttonPin)>500){
calibrateAccel();
}

// Once the accelerometer is calibrated - check for movement
if(calibrated){
if(checkMotion()){
moveDetected=true;
}
}

// If motion is detected - sound the alarm !
if(moveDetected){
Serial.println("ALARM");
ALARM();
delay(1000);
}

}





//This is the function used to sound the buzzer
void buzz(int reps, int rate){
for(int i=0; i<reps; i++){
analogWrite(buzzerPin,900);
delay(100);
analogWrite(buzzerPin,0);
delay(rate);
}
}




// Function used to calibrate the Accelerometer
void calibrateAccel(){
// reset alarm
moveDetected=false;

//initialise x,y,z variables
xVal = analogRead(x);
xMin = xVal;
xMax = xVal;

yVal = analogRead(y);
yMin = yVal;
yMax = yVal;

zVal = analogRead(z);
zMin = zVal;
zMax = zVal;

// Calibration sequence initialisation sound - 3 seconds before calibration begins
buzz(3,1000);

//calibrate the Accelerometer (should take about 0.5 seconds)
for (int i=0; i<50; i++){
// Calibrate X Values
xVal = analogRead(x);
if(xVal>xMax){
xMax=xVal;
}else if (xVal < xMin){
xMin=xVal;
}

// Calibrate Y Values
yVal = analogRead(y);
if(yVal>yMax){
yMax=yVal;
}else if (yVal < yMin){
yMin=yVal;
}

// Calibrate Z Values
zVal = analogRead(z);
if(zVal>zMax){
zMax=zVal;
}else if (zVal < zMin){
zMin=zVal;
}

//Delay 10msec between readings
delay(10);
}

//End of calibration sequence sound. ARMED.
buzz(3,40);
printValues(); //Only useful when connected to computer- using serial monitor.
calibrated=true;

}



//Function used to detect motion. Tolerance variable adjusts the sensitivity of movement detected.
boolean checkMotion(){
boolean tempB=false;
xVal = analogRead(x);
yVal = analogRead(y);
zVal = analogRead(z);

if(xVal >(xMax+tolerance)||xVal < (xMin-tolerance)){
tempB=true;
Serial.print("X Failed = ");
Serial.println(xVal);
}

if(yVal >(yMax+tolerance)||yVal < (yMin-tolerance)){
tempB=true;
Serial.print("Y Failed = ");
Serial.println(yVal);
}

if(zVal >(zMax+tolerance)||zVal < (zMin-tolerance)){
tempB=true;
Serial.print("Z Failed = ");
Serial.println(zVal);
}

return tempB;
}





// Prints the Sensor limits identified during Accelerometer calibration.
// Prints to the Serial monitor.
void printValues(){
Serial.print("xMin=");
Serial.print(xMin);
Serial.print(", xMax=");
Serial.print(xMax);
Serial.println();

Serial.print("yMin=");
Serial.print(yMin);
Serial.print(", yMax=");
Serial.print(yMax);
Serial.println();

Serial.print("zMin=");
Serial.print(zMin);
Serial.print(", zMax=");
Serial.print(zMax);
Serial.println();

Serial.println("------------------------");
}




//Function used to make the alarm sound, and blink the LED.
void ALARM(){

//don't check for movement until recalibrated again
calibrated=false;

// sound the alarm and blink LED
digitalWrite(ledPin, HIGH);
buzz(4,20);
digitalWrite(ledPin, LOW);
}

Saturday, August 4, 2012

Multiplexing RC Channels with Arduino

Creative Commons License
RCArduinoChannels by DuaneB is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.


RC Transmitters multiplex as many as 9 channels onto a single radio signal. Your RC Receiver decodes this single signal to obtain the individual channel signals for your servos and electronic speed controllers.


If we reverse part of this process we can read all of the incoming channels using just two Arduino Pins.


Not only does this keep our pins free for more important tasks within our projects, but it is also more efficient to read them this way, we simply need to count the pulses to know which channel we are looking at.

This is a technique I have been using in the development of the RCArduino library.


The library uses just two interrupt pins to read as many as six RC Channels. The library is also able to generate upto six RC Channel outputs in its current form. I will soon be adding the capability to drive 9 servos using only 3 Arduino digital pins. 

UPDATE : The library has been reworked so that it now supports three output modes -

1) Generate six outputs using a selected port 
2) Do not generate any outputs, but operate in a mode compatible with the existing servo library and all of the flexibility that it offers - also suitable for working with H-Bridges etc.
3) Serial servos, use less pins and less code to drive more servos - details soon.


So, if you want to be able to do more, with less, with a library that is smaller and faster than the existing general purpose libraries, read on.

The RC Arduino Channel Multiplexer
Some high end receivers offer a 'raw' output, mine don't and yours don't need to either. Instead of modifying the receiver we will simply create a small hardware 'RC Channel multiplexer'. The multiplexer is basically a single diode for each channel.

The key to the multiplexer is that we route all of the even numbered channels 0,2,4 to INT0 (digital pin 2) and all of the odd numbered channels 1,3,5 to INT1 (digital pin 3).

How does it work ?The diodes stop interference between the pulses - if one channel is high and the others are low, the low channels will sink some of the current from the high channel, this would be sufficient to stop the Arduino from detecting the pulse. However adding a diode to each channel prevents any current from the high channel sinking back into the low channels and ensures we can detect all of the channel pulses.

An RC Arduino Channel Multiplexer - 3 Channels into two pins, as simple as that.
Multiplexing the receiver channels into the two Arduino interrupts is as simple as adding a diode to each channel before connecting it to INT0 for 0 and even numbered channels and INT1 for odd numbered channels.


There is an interesting effect where a charge gets trapped between the diodes and the Arduino pins. To overcome this effect a high value resistor can be place between the point where the diodes meet and ground. I am using a 1M resistor. Picture below -.



Schematic - The even half of the channel multiplexer, the odd half is a duplicate but is connected between the odd numbered channels and INT1 (digital pin 3).



The next post in this series will be a conversion of a previous project to use the new library, as always the post will include the full source code of both the library and the project.

Duane B