Showing posts with label ATmega. Show all posts
Showing posts with label ATmega. Show all posts

Thursday, February 27, 2014

Arduino Micro (Leonardo): Detecting if you are still plugged into USB

   I'm a fan of the Arduino Micro's direct USB interface. It's so simple you just plug in your baud rate and you're ready to send and receive serial data from your computer using Serial commands.

/***************************************************\
|Name: Example of detecting USB Serial              |
|Programmer: Michael James Salino-Hugg              |
|Date: February 27,2014                             |
|Description: Turns on pin 13 LED when USB Serial   |
|             is connected and prints out "Serial   |
|             is connected" every second.           | 
|             Turns pin 13 LED off when there is no |
|             USB Serial connection.                |
\***************************************************/
void setup(){
   pinMode(13,OUTPUT);
   USBCON|=(1<<OTGPADE); //enables VBUS pad
   Serial.begin(9600);
}

void loop(){
   if(Serial){  //checks state of VBUS
      digitalWrite(13,HIGH);
      Serial.println("Serial is connected");
   }
   else {
      digitalWrite(13,LOW);
   }
   delay(1000);
}

   However, I have run into one problem with this USB connection. It is as follows. You have your Arduino setup to run one algorithm when it is connected to a computer through USB serial connection and another algorithm when it is not connected to the serial connection. You currently have it connected to the USB and what to disconnect and return to the other algorithm. There are 3 possible scenarios for disconnecting the Arduino from the computer.

  1. The user uses the Serial.end() command the Arduino to terminate the connection. It recognizes that connection is no longer set up using an returns to the correct algorithm.
  2. The user uses their terminal emulator (or terminal) to disconnect the connection. The Arduino recognizes that the connection has been terminated and returns to the correct algorithm.
  3. The user just pulls out the USB cable from either the computer or the Arduino. The Arduino never gets the notice that the connection is being terminated and just keeps running the algorithm it runs when it is connected to the computer despite the fact that it's not.
I would have to say that scenario 3 (the only one with the problem) is the most likely for an average user. I even end up doing this one all the time, and I know very well that I shouldn't. How can you prevent this? You can test this third scenario with the code above. When you unplug the Arduino Micro's USB cable after having a USB Serial connection the pin 13 light will stay on.

   One possible solution is very simple but only if you know your way around the ATMega32U4 (the microprocessor on Arduino Micro) datasheet and Arduino Micro circuit schematic. 

   Looking at the schematic for the Micro, we see that the 5V line from the USB (VUSB) connects directly to the microprocessor at a pin labeled VBUS. Time to pull up the datasheet!

On page 262-263, section 21.11 we see that VBUS can be used to detect if that line is above 1.4 volts This is exactly what we need. We can detect whether we're plugged into a USB port since this pin will be provided 5Vs if it is connected.

To use this we must first enable the VBUS Pad. From section 21.12 of the datasheet we see that OTGPADE (bit 4) of register USBCON. Then we can check VBUS (bit 0) in register USBSTA to see if this line is high or low.

The following code turns on the LED on the top of the Arduino when connected to a USB port, and off when only powered through its VIN or 5V pins:
/***************************************************\
|Name: Detecting VBUS                               |
|Programmer: Michael James Salino-Hugg              |
|Date: February 27,2014                             |
|Description: Turns on pin 13 LED, establishes a    |
|             serial connection, and prints "Serial |
|             is connected" every second when VBUS  |
|             is high. It also ends the serial      |
|             connection and turns off the pin 13   |
|             LED when VBUS is low.                 |
\***************************************************/

void setup(){
   pinMode(13,OUTPUT);
   USBCON|=(1<<OTGPADE); //enables VBUS pad
}

void loop(){
   if(USBSTA&(1<<VBUS)){  //checks state of VBUS
      if(!Serial)
         Serial.begin(9600);
      digitalWrite(13,HIGH);
      Serial.println("Serial is connected");
   }
   else {
      if(Serial)
         Serial.end();
      digitalWrite(13,LOW);
   }
   delay(1000);
}

Test this code out the same way. It will always recognize that it's no longer connected to the USB port and end its USB Serial communication.

Saturday, June 29, 2013

Embedded Systems Final Project: Programmable IIR/FIR Digital Filter

For my final project in Embedded Systems I designed a reprogrammable  infinite impulse response (IIR) / finite impulse response (FIR) filter.

This project used a ATmega88pa (a little bit overkill, but it was readily available to us) with a 8 MHz clock, and an 8-bit DAC (AD557JN).  An anti-aliasing lowpass filter before the microcontroller's ADC and an analog reconstruction lowpass filter after the DAC to remove the "stair step" output of the DAC were planned to be implemented.

The program was designed to follow the flow graph shown below. The signal coming in is added to scaled versions of values stored in a circular buffer. This feedback from the buffer creates the IIR part of filter. This value is then stored as the head of the circular buffer. Scaled versions of all the saved values in the buffer are then added together and sent to the DAC as output.


Different filters could be programmed into the filter by simply changing the scaling coefficients stored in the program. These coefficients were determined using MATLAB. We were able to implement the all main types filters (highpass, lowpass, bandpass, notch) with this design.

To ensure that the program would be fast enough to process meaningful signals, the entire project was programmed in assembly. Counting the cycles of the main loop of the program the minimum clock cycles needed for a first order filter was 108 each cycle. With an 8 MHz crystal the theoretical fastest sampling rate was about 37 kHz. That's really good considering that I was hoping to filter signals in the 60-120 Hz range and you can accurately reproduce audio with a sampling rate greater than about 40 kHz.

Unfortunately, I left the anti-aliasing and reconstruction filter design to my partner for this project. They never actually worked. However, using a function generator to create a fairly clean signal we were able to not worry about aliasing for testing purposes, and we were able to use the averaging function on the oscilloscope as an FIR low-pass reconstruction filter. The following oscilloscope screen captures are of a 60 Hz notch filter with a sampling rate of  400 samples per second.

The top plot is the input composed of signals at 42 Hz and 60Hz.
The bottom plot is the 42 Hz output from the 60 Hz notch filter.

The top plot is the input to the filter composed of 130 Hz and 60Hz Signals.
The bottom plot is the output of the 60Hz notch filter.

With a 60 Hz bandpass filter, we measured a bandwidth of about 3 Hz. This corresponds with a Q of about 20 which is really pretty good. We were running short on time and did not get around to monitoring the systems power consumption.

Overall, the programming and idea of the filter worked out great. Here is a picture of the system. It's not pretty. The DAC was soldered to the underside of the board (where all the yellow wires are running to). You will notice we didn't remove the unused USART section from our development board. Ideally the system would be a subsystem of a larger system, and won't need it's own power supply either.

Finished Prototype


The main change I would make to this project would be using 16-bit or 32-bit values rather than 8-bit values throughout the entire project. The inaccuracy in the values made it hard to design for a specific frequency and bandwidth at higher sampling rates. A wider range of frequencies the system can process results in each bit representing an wider range of frequencies. Also it would have been nice to have had the anti-aliasing and reconstruction filters working, and measured the power consumption of the system.