Showing posts with label advanced. Show all posts
Showing posts with label advanced. Show all posts

June 3, 2016

Raspberry PI - Arduino communication over USB serial

The Raspberry Pi is a fine little computer board with a lot of features and very good connectivity especially on version 3 with the integrated WiFi.
However, when dealing with I/O and sensors has a lot of limitations and is lacking the reliability of Arduino board and availability of libraries to interface it with any kind of device or sensor.

That's why I have decided to develop my own approach to integrate the two famous boards to fulfill my own set of requirements:
  • Use Raspberry Pi as a master device to develop the main application and connect to the Internet.
  • Use Java on the Raspberry Pi. This may sound a strange choice but I'm planning to use it to build an OSGi application for IoT.
  • Use Arduino board as a slave device to interact with several sensors.
  • Use a simple USB cable to power the Arduino board and exchange data.


This tutorial explains how to connect Arduino board to a Raspberry PI using a simple USB cable. This will power the Arduino and provide a serial communication between the two little boards.


Arduino


First step is to load and test the Arduino sketch to allow to retrieve the current milliseconds and toggle the on-board LED as described in this article.



Raspberry PI 

First step is to free the serial interface on the RasPI disabling shell and kernel messages via UART.
Run raspi-conf utility from the command prompt:

$ sudo raspi-config

Identify the Serial option and disable it. If is in the advanced menu in recent versions of Raspbian (9, A8).



Enter the following command to reboot your Raspberry Pi board:

$ sudo reboot


Install RxTx library

On the Raspberry PI side we will use the RxTx library. Install it with the following command:

sudo apt-get install librxtx-java

You can see that the native libraries are installed into the /usr/lib/jni directory and the java client is installed in /usr/share/java.

ls -la /usr/lib/jni/librxtx*
ls -la /usr/share/java/RXTX*


Java app

Import this Java project into Eclipse and build it. It is a slightly improved version of the official RxTx sample.
Now copy the three generated class files to your Raspberry Pi device into the /home/pi directory and run the following command:

java -Djava.library.path=/usr/lib/jni -cp /usr/share/java/RXTXcomm.jar:. ArduRasPi /dev/ttyUSB0 9600

This will run the ArduRasPi program connecting to Arduino on the /dev/ttyUSB0 port and 9600 baud.

You should now be able to issue commands to Arduino and receive the correct answer.





References

Arduino Vs. Raspberry Pi: Which Is The Right DIY Platform For You?
Control an Arduino from Java
Raspberry PI reads and writes data from Arduino, in Java
Arduino and Java

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.

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