December 30, 2015

How to sprintf a float with Arduino

Arduino has a small limitation in sprintf function that does not print correctly float numbers.
The following test sketch demonstrates the problem

void setup()
{
  Serial.begin(115200);
}
 
void loop()
{
  float f = 123.12F;
  Serial.print("Original value: ");
  Serial.println(f);

  char str[50];
  sprintf(str, "String value: %f", f);
  Serial.println(str);
  
  Serial.println();
  delay(2000);
}

You can see from the screenshot below that the float is always formatted a question mark '?'.


Using integer trick


There is a little trick to correctly print the float value using sprintf.

sprintf(str, "String value: %d.%02d", (int)f, (int)(f*100)%100);


This trick works well only with positive numbers and formats the float with two fixed decimals.



Using dtostrf function


A better solution is to use the dtostrf function. It it is more flexible and works well also with negative numbers.
These two lines of code will write a string into the buffer with strcpy function and the append the float value using the dtostrf function.

strcpy(str, "String value using dtostrf: ");
dtostrf(f, 2, 2, &str[strlen(str)]);



December 28, 2015

Installing WiFiEsp library

The easiest way of installing the WiFiEsp library in the Arduino IDE is using the Arduino Library Manager.

Launch the Arduino IDE and select Sketch - Include Library - Manage Libraries






The Arduino Library Manager will open. All you have to do is search for 'WiFiEsp' and hit the 'Install' button.




After the library has been installed you can open one of the examples.




Alternative download

If you want to manually install the library you can dowload it from GitHub and deal yourself with the installation process.

December 27, 2015

Flashing ESP8266 firmware v1.5 using Arduino Uno

I have to admit that I had some bad experience when trying to flash new firmwares to my ESP-01 modules but today I have found an easy and reliable way to flash ESP8266 firmware v1.5 (AT v0.51) using my Arduino Uno board as an FTDI controller.

Prerequisites
You need the following items:
  • A Windows PC with Arduino IDE installed
  • An Arduino Uno board
  • A reliable connection between ESP-01 module and Arduino board. This procedure is based on my cheap Arduino WiFi shield with ESP-01


Wiring

First of all you have to build my cheap Arduino WiFi shield with ESP8266. This will provide a solid foundation for powering the ESP module and setup the communication to the Arduino board.
Ensure you are able to issue simple AT commands to the ESP-01 board before proceeding.

Now modify the wiring as follows.
  • Remove ATmega328P chip from the Arduino board. By removing the microcontroller you can use the Arduino Uno onboard FTDI interface to directly communicate with the ESP module.
  • Connect ESP' RDX pin to the RX pin of Arduino (pin 0).
  • Connect ESP's TXD pin to the TX pin of Arduino (pin 1).





Test connectivity

Open the Arduino IDE, select the correct port and open the serial monitor.
You should be able to issue AT commands and get a nice output. Try 'AT' and 'AT+GMR' commands.


If you do not get any output you can try the following.
  • The serial monitor baud rate must correspond to the ESP UART baud rate. Old modules have 9600, newer ones have 115200.
  • Try different settings for the 'Line ending' option of the serial monitor. For my ESP module I have to set it to 'Both NL & CR' as you can see in the screenshot.
Try different combinations until you are able to correctly interact with the ESP module using the serial monitor.

Download firmware and tools

Download the following files and extract them

Flash it!

To put the ESP module in flashing mode you must connect ESP's GPIO0 pin to ground.
  1. Unplug the Arduino board from the PC
  2. Put a jumper between GND and GPIO0 pin (see photo)
  3. Plug the Arduino board to the PC.


Follow these steps to flash the new firmware to the ESP-01 board.
  1. Close the Arduino IDE if still opened
  2. Launch the ESP flash download tool (ESP_DOWNLOAD_TOOL_V2.4.exe) you have previously extracted
  3. Apply the following settings
  4. Bin files (from the esp_iot_sdk extracted zip file) :
    1. bin\at\noboot\eagle.flash.bin - 0x00000
    2. bin\at\noboot\eagle.irom0text.bin - 0x40000
    3. bin\blank.bin - 0xfe000
    4. bin\blank.bin - 0x7e000
  5. Flash size: 8MBit
  6. COM port: choose your Arduino COM port
  7. Baud rate: 115200 or 345600 (this is not related to the ESP baud rate



 Now press the START button and wait for the flashing process to complete.


Now press the STOP button and close the flashing tool.

Test connectivity and set default UART speed

Before proceeding it is better to verify that the new firmware is working fine.
  1. Unplug the Arduino board from the PC
  2. Remove the jumper between GND and GPIO0 pin
  3. Plug the Arduino board to the PC
Open the Arduino IDE, select the correct COM port and open the serial monitor.
Test connectivity with 'AT' and 'AT+GMR' commands. The correct settings for the ESP firmware v1.5 are:
  • Speed: 115200
  • Line ending: Both NL & CR
If you are going to use the ESP-01 module with Arduino Uno you have to lower the default baud rate because the SoftwareSerial interface maximum speed is around 38400 bps. I suggest to set the ESP module to use 9600 or 19200 bps. To set the correct baud rate use this command:
AT+UART_DEF=9600,8,1,0,0

Now set the serial monitor speed to 9600 and test again the communication.

Rebuild your ESP WiFi shield

Remove the modifications made to the ESP shield.
  • Insert the ATmega328P chip back into the Arduino board
  • Connect ESP' RDX pin to Arduino pin 7
  • Connect ESP's TXD pin to Arduino pin 6

Compile and upload the updated sketch and you should be able to correctly interact with the ESP module.

Your ESP8266 board is now flashed with the updated firmware and ready to be used for your connected projects!

Don't forget to take a look at my WiFiEsp library for Arduino.

December 6, 2015

Cheap Arduino WiFi Shield with ESP8266-01

If you want to connect your Arduino with the internet the standard choice is the Arduino WiFi shield. However, this is too much expensive since it costs more than 80 USD. Cheaper alternatives based on CC3000 chipset are not meeting my expectations so I have decided to build my own Arduino WiFi shield.

My requirements for the shield are:
  • As much as cheap as possible (less than 10 USD)
  • Arduino library compatible with the standard Ethernet/WiFi libraries
  • Breadboard-friendly (no soldering needed)
The idea was simply to find a cheap replacement of the standard WiFi shield being able to reuse existing samples and code developed for Ethernet and WiFi shields.

The obvious choice for the WiFi module is the ESP8266-01. ESP8266-01 is great and cheap but there are some problems and limitations:
  1. Arduino boards are typically powered at 5V while ESP8266 needs a 3.3V power source. The Arduino 3.3V output pin cannot provide the power needed by the ESP (up to 250mA). This can be solved using a 3.3V voltage regulator like the LM1117, LD1117, LD33V or AMS1117. There are even more cheaper solutions but I decided to go with a AMS1117 module.
  2. ESP8266 connector is not breadboard-friendly. Using the technique described in this post is easy to plug the ESP into a breadboard with no additional hardware.
  3. ESP8266 default firmware uses AT commands and there is no good library for the ESP with a programming model similar to the WiFi library. There are some improved firmwares around but I want to use the stock firmware. I have developed my own EspWiFi library so I can use any existing Arduino WiFi sketch with few little code changes.
Components
  • ESP8266-01 module (3 USD)
  • AMS1117 module - 5V To 3.3V DC-DCPower Supply (1 USD)
  • Breadboard (2 USD)
  • Capacitor (any 10-100 uF is ok)
  • 2 or 3 resistors
  • Jumper wires
  • Arduino ProtoShield (3 USD)

All these components allows you to build a WiFi shield for less than 10 USD !


Look at this Instructable for detailed instructions about how to build the ESP WiFi shield.

After having built it you can try my WiFiEsp library to connect your Arduino projects to the Internet.

December 4, 2015

How to plug the ESP8266-01 module to a breadboard

One of the most annoying problems of the ESP8266-01 module is that it is not possible to plug it into a breadboard for fast prototyping.
Today I was discussing with another Arduino fan and we were looking at existing solutions to this common problem. All the existing solutions were complex to implement or are costing more than the ESP module itself.
I ended up with a smart and free solution with no additional hardware required.

The solution is easy and requires only a small screwdriver to remove the plastic spacers and pliers to bend the ESP's pins.
Pictures are more clear than words in this case.






May 18, 2015

ESP8266 WiFi library

After several nights spent developing and tweaking I finally have a working ESP8266 WiFi library called WiFiEsp.
The main characteristic of the WiFiEsp library is that is fully compatible with the standard library for the Arduino WiFi shield. This gives a cheap alternative to the expensive WiFi shield to connect Arduino to the Internet.
It uses hardware Serial1 if exists or emulate a second serial port on pins 6 and 7.
You can download WiFiEsp library from GitHub.
Please give it a try and tell me what you think.

Here is a small sketch that connects to a WiFi network.


#include "WiFiEsp.h"

// Emulate Serial1 on pins 7/6 if not present
#ifndef HAVE_HWSERIAL1
#include "SoftwareSerial.h"
SoftwareSerial Serial1(6, 7); // RX, TX
#endif

char ssid[] = "Twim";            // your network SSID (name)
char pass[] = "12345678";        // your network password

void setup()
{
  Serial.begin(115200);  // initialize serial for debugging
  Serial1.begin(9600);   // initialize serial for ESP
  WiFi.init(&Serial1);   // initialize ESP serial port

  if (WiFi.status() == WL_NO_SHIELD) {   // check for the presence of the shield
    Serial.println("WiFi shield not present");
    while (true);                        // don't continue:
  }
}

void loop()
{
  // attempt to connect to Wifi network:
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network:
    WiFi.begin(ssid, pass);
  }

  // you're connected now, so print out the data:
  Serial.println("You're connected to the network");
  
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  delay(10000);
}


May 2, 2015

Beating heart with Arduino and a MAX7219 8x8 LED matrix

This is a very simple project to display a beating heart using and Arduino board and a 8x8 LED matrix driven by a MAX7219 chip.



The wiring is very simple.
  • MAX7219 VCC pin > Arduino 5V pin
  • MAX7219 GND pin > Arduino GND pin
  • MAX7219 DIN pin > Arduino pin 2
  • MAX7219 CS pin > Arduino pin 3
  • MAX7219 CLOCK pin > Arduino pin 4

The Arduino sketch is not using any library so this is also good to understand how to directly drive the MAX7219 chip through registers.


int ANIMDELAY = 100;  // animation delay, deafault value is 100
int INTENSITYMIN = 0; // minimum brightness, valid range [0,15]
int INTENSITYMAX = 8; // maximum brightness, valid range [0,15]

int DIN_PIN = 2;      // data in pin
int CS_PIN = 3;       // load (CS) pin
int CLK_PIN = 4;      // clock pin

// MAX7219 registers
byte MAXREG_DECODEMODE = 0x09;
byte MAXREG_INTENSITY  = 0x0a;
byte MAXREG_SCANLIMIT  = 0x0b;
byte MAXREG_SHUTDOWN   = 0x0c;
byte MAXREG_DISPTEST   = 0x0f;

const unsigned char heart[] =
{
  B01100110,
  B11111111,
  B11111111,
  B11111111,
  B01111110,
  B00111100,
  B00011000,
  B00000000
};



void setup ()
{
  pinMode(DIN_PIN, OUTPUT);
  pinMode(CLK_PIN, OUTPUT);
  pinMode(CS_PIN, OUTPUT);

  // initialization of the MAX7219
  setRegistry(MAXREG_SCANLIMIT, 0x07);
  setRegistry(MAXREG_DECODEMODE, 0x00);  // using an led matrix (not digits)
  setRegistry(MAXREG_SHUTDOWN, 0x01);    // not in shutdown mode
  setRegistry(MAXREG_DISPTEST, 0x00);    // no display test
  setRegistry(MAXREG_INTENSITY, 0x0f & INTENSITYMIN);

  // draw hearth
  setRegistry(1, heart[0]);
  setRegistry(2, heart[1]);
  setRegistry(3, heart[2]);
  setRegistry(4, heart[3]);
  setRegistry(5, heart[4]);
  setRegistry(6, heart[5]);
  setRegistry(7, heart[6]);
  setRegistry(8, heart[7]);
}


void loop ()
{
  // second beat
  setRegistry(MAXREG_INTENSITY, 0x0f & INTENSITYMAX);
  delay(ANIMDELAY);
  
  // switch off
  setRegistry(MAXREG_INTENSITY, 0x0f & INTENSITYMIN);
  delay(ANIMDELAY);
  
  // second beat
  setRegistry(MAXREG_INTENSITY, 0x0f & INTENSITYMAX);
  delay(ANIMDELAY);
  
  // switch off
  setRegistry(MAXREG_INTENSITY, 0x0f & INTENSITYMIN);
  delay(ANIMDELAY*6);
}


void setRegistry(byte reg, byte value)
{
  digitalWrite(CS_PIN, LOW);

  putByte(reg);   // specify register
  putByte(value); // send data

  digitalWrite(CS_PIN, LOW);
  digitalWrite(CS_PIN, HIGH);
}

void putByte(byte data)
{
  byte i = 8;
  byte mask;
  while (i > 0)
  {
    mask = 0x01 << (i - 1);        // get bitmask
    digitalWrite( CLK_PIN, LOW);   // tick
    if (data & mask)               // choose bit
      digitalWrite(DIN_PIN, HIGH); // send 1
    else
      digitalWrite(DIN_PIN, LOW);  // send 0
    digitalWrite(CLK_PIN, HIGH);   // tock
    --i;                           // move to lesser bit
  }
}

April 1, 2015

ESP8266 wiring schemas

In this page I want to collect some examples (of increasing complexity) to connect the ESP8266 to Arduino boards.
All the wiring schemes and examples are based on an Arduino One and an 8-pins ESP8266 module also know as ESP-01. Arduino pins 6 and 7 will be used as a second serial port using SoftwareSerial library as described here.



Schema Power RX TX
1) Basic N N N
2) Powering with diodes Y N N
3) Powering with Zener diode Y N N
4) Powering with voltage regulator Y N N
5) RX level shifter with resistors N Y N
6) RX level shifter with diode N Y N



1) Basic

Here are the ESP-01 pins.


The most basic connection scheme is this.


Wiring
  • Arduino 3.3v power > breadboard red power rail
  • Arduino GND > breadboard black ground rail
  • ESP8266 GND > ground rail
  • ESP8266 VCC > power rail
  • ESP8266 CH_PD > power rail
  • ESP8266 TXD > Arduino Digital Pin #6 (RX pin using software serial)
  • ESP8266 RXD > Arduino Digital Pin #7 (TX pin using software serial)
  • A 100uF (or larger) capacitor helps to absorb current spikes


This schema has three main problems:
  • Power source: Arduino boards are typically powered at 5V while ESP8266 needs a 3.3V power source. The ESP can draw up to 250mA while the Arduino Uno 3.3V output pin can provide only 50mA. A capacitor can help but it's not enough.
  • RX: The 5V Arduino TX serial output needs to be shifted to the 3.3V ESP RX input. However, simple prototypes can be built without this because the ESP has a built in protection.
  • TX: The 3.3V ESP TX output should be enough for the 5V Arduino digital input. A reliable project may need a level shifter.


The next wiring schemes will show different approaches to provide a reliable 3.3V power source to the ESP.

2) Powering with diodes

Since the Arduino 5V pin can provide 200mA we can use this to power the ESP. This schema is very cheap and simple allowing to use simple and cheap diodes to convert the 5V to 3.6V. Suitable diodes are the 1N4148 (300 mA) or the 1N4007 (1 A).



3) Powering with Zener diode

An alternative cheap approach is to use a 1N5226 3.3V Zener diode to power the ESP as described here.




4) Powering with voltage regulator (LM1117/LD1117)

Several cheap 3.3V regulators are available on the market. A very common and cheap one is the LM1117 (or LD1117). With such regulator you can convert the 5V power used for Arduino to the 3.3V needed by the ESP.


An AMS1117 module is also a great choice.
A generic voltage regulator like the LM317T can be used as described in this post.


5) RX level shifter with resistors

 The 5V output from the Arduino TX pin can be shifted to 3.3V using a resistor voltage divider.
 In this schema I have used three 220 Ohm resistors for an output current of 7.5 mA.



6) RX level shifter with Diode


You can use a 1N4148 diode on the Arduino TX pin as well to lower the voltage of the signal.





Putting all together


Now pick your preferred schemes to build your perfect Arduino/ESP wiring.


References


5V to 3.3V Logic Level Shifting


March 31, 2015

ESP8266 Resources


Here is my current list of links for the ESP8266 and Arduino.



Wiring

I have collected some wiring schemes of increasing complexity in this post.
However I have developed my own wiring scheme and described it in this Instructable. I think is easier for many people to start with a solid and tested scheme.

Libraries

  • WiFiEsp : This is my own library. It is designed to be very similar to standard Arduino Ethernet and WiFi shield libraries. The idea is to be able to reuse existing sketches and projects with this cheap ESP module. You can find more information on this post.
  • ITEADLIB_Arduino_WeeESP8266 : Seems to be the most stable and reliable ESP library at the moment (Apr 2015).
  • arduino-ESP8266 : Seems a good library
  • ThaiEasyElec (TEE_ESP) : Works only with SoftwareSerial, low level functions, poor documentation, no website or GIT repository.
  • ESP8266 EasyIoT
  • Adafruit: Seems a good library, debugging functions, missing high level functions.
  • espduino : Wifi library (Chip ESP8266 Wifi soc) for Arduino using SLIP protocol (custom firmware) via serial port. Release 0.1 was based on AT commands.
  • ESP8266 : Another library. Nothing special. 
  • ESP8266_client :  A lightweight library for client connections. Nothing special.
  • ESP8266_Simple :  Well documented, works only with SoftwareSerial, few functions.

Reference documentation


Flashing the firmware

I have developed my own procedure using Arduino board for flashing the ESP.


Other resources


  • Espressif forum:
  • ESP8266 forum : This is a community forum centered around the ESP8266. Everything is here, but probably best to read this stuff after going through a complete design example.
  • Electrodragon wiki : Wiki page with multiple sets of information and links for using the ESP8266.
  • Espressif is the manufacturer of the ESP8266. Their site is pretty much a bunch of marketing hoo-hah and you'll have to "contact" them for more information. Not too useful.
  • http://blog.electrodragon.com/esp8266-gpio-test-edited-firmware/ : A demo of turning the LEDs on the ESP8266 board on/off over the Wifi link.
  • http://scargill.wordpress.com : Peter Scargill has been pretty thorough in documenting his experiences in getting the ESP8266 up and running and delving into some of the capabilities of the chip.


March 28, 2015

Debugging ESP8266 commands with Arduino Uno

I have recently received an ESP8266 that is a tiny and cheap WiFi module that can be controlled through serial interface commands. I have read several blogs and forums to understand how to make it work. I finally found my own approach of testing this little toy.

ESP8266 pins are described in this diagram.
These are few important things I have discovered:
  1. Power - The ESP8266 needs 3.3V power. The ESP can draw up to 250mA while the Arduino Uno 3.3 output pin can provide only 50mA. In serious project you need a good 3.3V power source but for playing and debugging the Arduino Uno 3.3V output pin can be enough.
  2. CH_PD pin - The CH_PD pin needs to be held high so connect it to VCC also.
  3. TX/RX -In theory you TX and RX pins accept 3.3V so you need level shifters to adapt Arduino's 5V signals. However, I found out that it just works without level shifters.
  4. Debugging - To debug the ESP's commands you need 2 serial ports. One (the default one) is used by the Arduino Serial Monitor so it can be used to debug. The ESP will be attached to the second serial port but unfortunately the Arduino Uno has just one serial port. Some approaches require additional hardware or an Arduino Mega but I have found that the Software Serial library allows to emulate a serial port so I will use this simpler approach.

Wiring



NOTE: This is not a perfect wiring scheme because it doesn't use level shifters. Use at your own risk!

Connections are:
  • Arduino 3.3v power > breadboard red power rail
  • Arduino GND > breadboard black ground rail
  • ESP8266 GND > ground rail
  • ESP8266 VCC > power rail
  • ESP8266 CH_PD > power rail
  • ESP8266 TXD > Arduino Digital Pin #6 (RX pin using software serial)
  • ESP8266 RXD > Arduino Digital Pin #7 (TX pin using software serial)

Code


#include "SoftwareSerial.h"

SoftwareSerial esp8266(6, 7); // RX, TX

void setup()
{
  Serial.begin(115200); // serial port used for debugging
  esp8266.begin(9600);  // your ESP's baud rate might be different
}
 
void loop()
{
  if(esp8266.available())  // check if the ESP is sending a message
  {
    while(esp8266.available())
    {
      char c = esp8266.read();  // read the next character.
      Serial.write(c);  // writes data to the serial monitor
    }
  }
 
  if(Serial.available())
  {
    delay(10);  // wait to let all the input command in the serial buffer

    // read the input command in a string
    String cmd = "";
    while(Serial.available())
    {
      cmd += (char)Serial.read();
    }

    // print the command and send it to the ESP
    Serial.println("---------------------");
    Serial.print(">> ");
    Serial.println(cmd);
    Serial.println("---------------------");
    esp8266.println(cmd); // send the read character to the esp8266
  }
}

Commands

Now that you have wired your ESP and uploaded the sketch to Arduino you can open the serial monitor and play with the 'AT' commands.
Remember to set the baud rate to 115200. Newer ESP modules also require to send NL & CR characters.



The main ESP8266 AT commands are listed here.
  • AT - Test
  • AT+RST - Reset
  • AT+CWLAP - List WiFi available networks
  • AT+CWJAP="SSID","PWD" - Connect to a network (change SSID and PWD to match your access point)
  • AT+CWJAP? - Check if connected successfully
For a full list of commands refer to this document.

March 5, 2015

Animation of five LEDs using Arduino PWM output pins

This example is part of the ALA (Arduino Light Animation) library and shows how to create animations using some LEDs and an Arduino board.
Checkout this small video to see how the animations look like.



Circuit

The circuit is really simple. Just five red LEDs connected to five analog output pins of the Arduino and five 220 Ohm resistors.



Code

You have to download and install the ALA library from here first.

#include <AlaLed.h>

AlaLed leds;
byte pins[] = { 5, 6, 9, 10, 11 };

AlaSeq seq[] =
{
  { ALA_FADEIN, 1000, 1000 },
  { ALA_ON, 1000, 1000 },
  { ALA_FADEOUT, 1000, 1000 },
  { ALA_BARSHIFTRIGHT, 1000, 1000 },
  { ALA_BARSHIFTLEFT, 1000, 1000 },
  { ALA_OFF, 1000, 1000 },
  { ALA_PIXELSHIFTRIGHT, 700, 1400 },
  { ALA_PIXELSHIFTLEFT, 700, 1400 },
  { ALA_BLINKALT, 500, 3000 },
  { ALA_PIXELSMOOTHSHIFTRIGHT, 1000, 4000 },
  { ALA_PIXELSMOOTHSHIFTLEFT, 1000, 4000 },
  { ALA_FADEINOUT, 1000, 4000 },
  { ALA_COMET, 1000, 4000 },
  { ALA_GLOW, 1000, 4000 },
  { ALA_STROBO, 200, 4000 },
  { ALA_ENDSEQ, 0, 0 }
};


void setup()
{
  leds.initPWM(3, pins);
  leds.setAnimation(seq);
}

void loop()
{
  leds.runAnimation();
}

I have designed the ALA library with simplicity in mind. You just need to initialize the AlaLed object in the setup function passing the number of LEDs you want to drive. Then you call the runAnimation method passing an array of triplets to describe the desired animation sequence. Finally you have to call the runAnimation method in the loop function to animate your LEDs.
The tricky part is the AlaSeq structure that is made by 3 fields:
  1. A numeric code identifying the desired animation. Valid codes are listed in the Ala.h header file.
  2. The animation loop duration in milliseconds.
  3. The animation total duration in milliseconds.
The last entry in the array must be ALA_ENDSEQ to close the animation sequence.

February 1, 2015

Fast sampling from analog input

The first part of the OScope project is to implement the Arduino sketch to read the input values from an analog pin. In this article will describe how to achieve a reliable sampling of analog signals up to 615 KHz using some advanced techniques.

Arduino provides an convenient way to read analog input this using the analogRead() function. Without going into much details the analogRead() function takes 100 microseconds leading to a theoretical sampling rate of 9600 Hz. You can read more about this topic here.

The following piece of code takes 1000 samples using the analogRead() calculates some statistics.


void setup()
{
  Serial.begin(115200);
  pinMode(A0, INPUT);
}

void loop()
{
  long t0, t;

  t0 = micros();
  for(int i=0; i<1000; i++) {
    analogRead(A0);
  }
  t = micros()-t0;  // calculate elapsed time

  Serial.print("Time per sample: ");
  Serial.println((float)t/1000);
  Serial.print("Frequency: ");
  Serial.println((float)1000*1000000/t);
  Serial.println();
  delay(2000);
}

This code gives 112us per sample for a 8928 Hz sampling rate.

So how can we increase sampling rate?

Speedup the analogRead() function


We now need a little more details. The ADC clock is 16 MHz divided by a 'prescale factor'. The prescale is set by default to 128 which leads to 16MHz/128 = 125 KHz ADC clock. Since a conversion takes 13 ADC clocks, the default sample rate is about 9600 Hz (125KHz/13).
Adding few lines of code in the setup() function we can set an ADC prescale to 16 to have a clock of 1 MHz and a sample rate of 76.8KHz.

#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))

void setup()
{
  sbi(ADCSRA, ADPS2);
  cbi(ADCSRA, ADPS1);
  cbi(ADCSRA, ADPS0);
  ...

The real frequency measured with the test program is 17us per sample for a 58.6 KHz sampling rate.

The following table shows prescale values with registers values and theoretical sample rates. Note that prescale values below 16 are not recommended because the ADC clock is rated.

Prescale ADPS2 ADPS1 ADPS0 Clock freq (MHz) Sampling rate (KHz)
2 0 0 1 8 615
4 0 1 0 4 307
8 0 1 1 2 153
16 1 0 0 1 76.8
32 1 0 1 0.5 38.4
64 1 1 0 0.25 19.2
128 1 1 1 0.125 9.6


Interrupts


A better strategy is to avoid calling the analogRead() function and use the 'ADC Free Running mode'. This is a mode in which the ADC continuously converts the input and throws an interrupt at the end of each conversion. This approach has two major advantages:
  1. Do not waste time waiting for the next sample allowing to execute additional logic in the loop function.
  2. Improve accuracy of sampling reducing jitter.
In this new test program I set the prescale to 16 as the example above getting a 76.8 KHz sampling rate.

int numSamples=0;
long t, t0;

void setup()
{
  Serial.begin(115200);

  ADCSRA = 0;             // clear ADCSRA register
  ADCSRB = 0;             // clear ADCSRB register
  ADMUX |= (0 & 0x07);    // set A0 analog input pin
  ADMUX |= (1 << REFS0);  // set reference voltage
  ADMUX |= (1 << ADLAR);  // left align ADC value to 8 bits from ADCH register

  // sampling rate is [ADC clock] / [prescaler] / [conversion clock cycles]
  // for Arduino Uno ADC clock is 16 MHz and a conversion takes 13 clock cycles
  //ADCSRA |= (1 << ADPS2) | (1 << ADPS0);    // 32 prescaler for 38.5 KHz
  ADCSRA |= (1 << ADPS2);                     // 16 prescaler for 76.9 KHz
  //ADCSRA |= (1 << ADPS1) | (1 << ADPS0);    // 8 prescaler for 153.8 KHz

  ADCSRA |= (1 << ADATE); // enable auto trigger
  ADCSRA |= (1 << ADIE);  // enable interrupts when measurement complete
  ADCSRA |= (1 << ADEN);  // enable ADC
  ADCSRA |= (1 << ADSC);  // start ADC measurements
}

ISR(ADC_vect)
{
  byte x = ADCH;  // read 8 bit value from ADC
  numSamples++;
}
  
void loop()
{
  if (numSamples>=1000)
  {
    t = micros()-t0;  // calculate elapsed time

    Serial.print("Sampling frequency: ");
    Serial.print((float)1000000/t);
    Serial.println(" KHz");
    delay(2000);
    
    // restart
    t0 = micros();
    numSamples=0;
  }
}


If you want to learn more on ADC Free Running mode and tweaking ADC register you can look at the following pages.

‎AVR Guide - Analog Inputs
Instructables - Girino - Fast Arduino Oscilloscope
Instructables - Arduino Audio Input
Arduino Forum - Faster Analog Read

January 11, 2015

Driving a LED strip with Arduino




Do you know those cheap LED strips?

These are often called "analog" LED strips because you cannot control each pixel individually like you do with "digital" strips.


Today we want to drive them using our Arduino board.



Hardware

  • Arduino Board
  • MOSFET
  • White LED strip

As MOSFET i have used I have used the IRF520 that comes with the Arduino starter kit but you can use any general purpose MOSFET (for example the popular STP16NF06).

Schematic









Code


#define PIN 11      // control pin
#define DELAY 10    // 20ms internal delay; increase for slower fades

void setup() {
  pinMode(PIN, OUTPUT);
}

void loop() {
  // fade in
  for(int i=0; i<255; i++) {
    analogWrite(PIN, i);
    delay(DELAY);
  }

  // fade out
  for(int i=0; i<255; i++) {
    analogWrite(PIN, 255-i);
    delay(DELAY);
  }
}

This is the code if you prefer a "strobo effect".

#define PIN 11      // control pin
#define DELAY 20    // 20ms internal delay; increase for slower pulse

void setup() {
  pinMode(PIN, OUTPUT);
}

void loop() {
  digitalWrite(PIN, HIGH);  // turn on
  delay(DELAY);             // wait few milliseconds
  digitalWrite(PIN, LOW);   // turn off
  delay(DELAY*10);          // wait some more time
}


References


Dimming a 12V LED Strip With an Arduino
RGB LED Strips
RGB Led Strip Controlled by an Arduino


January 10, 2015

Fading colors with an RGB LED

In this post I will explain how to make a simple fading RGB LED.
The code smoothly fades an RGB LED using PWM through 3 different basic colors (red, green and blue).

Hardware

  • Arduino Board
  • RGB LED
  • 3x Resistors 220 Ohm

Schematic

The schematic is very simple. Just connect the common cathod (+) to the GND pin. Then connect the 3 other leads to 3 PWM pins on your Arduino with a 220 Ohm resistor between.






Code


#define RED_PIN 9      // where the red pin is connected to
#define GREEN_PIN 10   // where the green pin is connected to
#define BLUE_PIN 11    // where the blue pin is connected to
#define DELAY 20       // 20ms internal delay; increase for slower fades

void setup() {
  pinMode(GREEN_PIN, OUTPUT);
  pinMode(BLUE_PIN, OUTPUT);
  pinMode(RED_PIN, OUTPUT);
}

void loop() {
  // fade from green to red
  for(int i=0; i<255; i++) {
    analogWrite(RED_PIN, i);
    analogWrite(GREEN_PIN, 255-i);
    analogWrite(BLUE_PIN, 0);
    delay(DELAY);
  }

  // fade from red to blue
  for(int i=0; i<255; i++) {
    analogWrite(RED_PIN, 255-i);
    analogWrite(GREEN_PIN, 0);
    analogWrite(BLUE_PIN, i);
    delay(DELAY);
  }

  // fade from blue to green
  for(int i=0; i<255; i++) {
    analogWrite(RED_PIN, 0);
    analogWrite(GREEN_PIN, i);
    analogWrite(BLUE_PIN, 255-i);
    delay(DELAY);
  }
}

References

Fading RGB LED (Arduino)
Arduino ColorCrossfader
RGB LEDs
Make an RGB LED Fader

January 9, 2015

LED Blink

This is the very first project of every Arduino owner... make a LED blink.


Hardware

  • Arduino Board
  • LED
  • 220 Ohm resistor

Schematic



Circuit



Code


int pinLed = 13;

void setup() {                
  pinMode(led, OUTPUT);     
}

void loop() {
  digitalWrite(pinLed, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                  // wait for a second
  digitalWrite(pinLed, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                  // wait for a second
}

References

Arduino Blink example
Instructables tutorial

https://www.sparkfun.com/tutorials/219

January 8, 2015

LED basics

A light-emitting diode (LED) is a diode which emits light when activated. To limit the current flowing into the diode, it is important to introduce a current-limiting resistor in the loop.

The value of the appropriate resistor can be calculated with the following formula:

R=(V-Vd)/Id

where Vd is the voltage drop and Id is the current you want to use on your LED, usually the forward current. Those values depends on the specs of each LED and varies depending on the color of the LED.

So… you just want to light up an LED. What resistor should you use?

We can can make some rough assumptions to simplify the calculation:
  • Common LEDs runs at 20m.
  • The voltage drop is typically around 3V.
  • Arduino runs at 5V
This lead to the following calculation:
R = (5-3)/0.02 = 100 (Ohm)

We can say that 100 Ohms is the absolute minimum resistance we need to make sure that we do not damage the LED. To be safe, it's a good idea to use something a little higher, just in case your LED has slightly different ratings that what I've used here.
I always use 220 Ohm resistors because they are a safe choice for all kind of LEDs and are easy to find.

If you know the ratings of your LED (you can find it on the LED's datasheet) and you want to do this calculation yourself or use an online calculator like this or this.

References

All about LEDS
LED resistance calculator
Arduino Blink example
Instructables tutorial
Turn on LED with 5V
LED Current Limiting Resistors