Go Down

Topic: Standalone Atmega328 locking up (Read 564 times) previous topic - next topic

Plystire

Hello,

Still very new to arduino, but have made enough progress to move onto creating a PCB for my project. To get to that, I needed to bring the Atmega chip to a standalone breadboard and make sure everything works without the arduino board. When I hook it up, it appears to function properly for a split second and then locks up. Resetting (via button) the Atmega will make it work for a split second again before freezing.

I figure the problem may be code... but the program works fine with the chip hooked up in the arduino board, so I don't know how much different the program will run when standalone.

To hook up the Atmega on the breadboard, I followed the guide on this site... and for hooking up AVCC, I have a 100ohm res to power and a 0.1uF cap to ground. To be honest, I have no clue how well that works for what I'm doing. Still an electronics noob :smiley-roll-sweat:

Here's the sketch, maybe someone can find something wrong with it?
Code: [Select]
#include <BassFilter.c>
#include <BassFilter.h>

//The number of samples to buffer before analyzing them
int samplesN = 75;

int transSpd = 5;
float trans = 0;

int micPin = 0;
int potPin = 1;
int jackPin = 2;
int redPin = 6;
int greenPin = 5;
int bluePin = 3;
int redClr = 128;
int greenClr = 128;
int blueClr = 128;
float clrInt = 1.0;
int bassThresh = 750;
int quietThresh = 10;

int clrs[18];
int clr = 0;

BassFilter* filter;

void setup(){
  Serial.begin(9600);
  //randomSeed(analogRead(0));
  filter = new BassFilter();
  BassFilter_init(filter);
  pinMode(micPin, INPUT);
  pinMode(potPin, INPUT);
  pinMode(jackPin, INPUT);
  clrs[0] = 255;
  clrs[1] = 0;
  clrs[2] = 0;
 
  clrs[3] = 255;
  clrs[4] = 255;
  clrs[5] = 0;
 
  clrs[6] = 0;
  clrs[7] = 255;
  clrs[8] = 0;
 
  clrs[9] = 0;
  clrs[10] = 255;
  clrs[11] = 255;
 
  clrs[12] = 0;
  clrs[13] = 0;
  clrs[14] = 255;
 
  clrs[15] = 255;
  clrs[16] = 0;
  clrs[17] = 255;
  newColor();
}

void newColor() {
  clr++;
  int ind = clr*3 % 18;
  redClr = clrs[ind]; //random(0.25*(float)clrs[ind],clrs[ind]);
  greenClr = clrs[ind+1]; //random(0.25*(float)clrs[ind+1],clrs[ind+1]);
  blueClr = clrs[ind+2]; //random(0.25*(float)clrs[ind+2],clrs[ind+2]);
}

void colorIntensity(float intensity) {
  int m = 0;
  float tr = 0;
  int ind = clr*3 % 18;
  clrInt = intensity;
  tr = trans * (float)clrs[(ind+3) % 18];
  if (clrs[ind] > 0 && clrs[(ind+3) % 18] < 255)
    tr = trans * -255.0;
  m = round((float)redClr + intensity * 255.0);
  m = m + tr;
  if (m > 255)
    m = 255;
  if (m < 0)
    m = 0;
  analogWrite(redPin, m);
  tr = trans * (float)clrs[(ind+4) % 18];
  if (clrs[ind+1] > 0 && clrs[(ind+4) % 18] < 255)
    tr = trans * -255.0;
  m = round((float)greenClr + intensity * 255.0);
  m += tr;
  if (m > 255)
    m = 255;
  if (m < 0)
    m = 0;
  analogWrite(greenPin, m);
  tr = trans * (float)clrs[(ind+5) % 18];
  if (clrs[ind+2] > 0 && clrs[(ind+5) % 18] < 255)
    tr = trans * -255.0;
  m = round((float)blueClr + intensity * 255.0);
  m += tr;
  if (m > 255)
    m = 255;
  if (m < 0)
    m = 0;
  analogWrite(bluePin, m);
}

int maxpeak = 0 ;
int minPeak = 1023;
int sndMax = 0;
int sndMin = 1023;
long sndOut = 0;
int sndFil[3];
int sndCt = 0;

int sndDamp = 10;

long minPow = 1023;
long maxPow = 0;

void loop(){
  int peak = 0;
  //bassThresh = analogRead(1);
 
  sndOut = 0;
  float pow = 0;

  for(int k=0; k<samplesN; k++){
    int val = analogRead(jackPin);
    BassFilter_put(filter, val);
   
    int filtered = BassFilter_get(filter);
    peak = max(peak, filtered);
    pow += (float)filtered / (float)samplesN;
  } 
  maxpeak = max(maxpeak, peak);
  minPeak = min(minPeak, peak);
  pow = abs(pow);
  minPow = min(minPow, pow);
  maxPow = max(maxPow, pow);
  if (sndCt > 1000 && peak > quietThresh) {
    minPow = 1023;
    maxPow = 0;
    minPeak = 1023;
    maxpeak = 0;
    sndCt = 0;
  }
  sndCt++;
  pow = map(pow, minPow, maxPow, 0, 1023) - analogRead(potPin);
  if (pow < 0)
    pow = 0;
  colorIntensity((float)pow / 1023.0);

  int lvl = map(peak, minPeak, maxpeak, 0, 1023);
  int comp = map((float)bassThresh / 1023.0 * (float)maxpeak, minPeak, maxpeak, 0, 1023);
 
  if (lvl > comp) {
    newColor();
  }
 
  trans += (float)transSpd / 255.0;
  if (trans >= 1.0) {
    newColor();
    trans = 0;
  }
}


If anyone can help, I would really appreciate it.  :.

~Plystire

Coding Badly


Plystire



clr is unbounded.



Ah, thanks! I corrected that and hooked it back up to the breadboard. It appeared to work for the most part for much longer, however it's still freezing. And it slowly got worse until it's freezing almost right away again. :(

Coding Badly


Did you bound clr correctly or are you still overrunning the array?

Quote
...and for hooking up AVCC, I have a 100ohm res to power and a 0.1uF cap to ground...


What?

Plystire

Code: [Select]
void newColor() {
  clr++;
  if (clr > 5)
    clr = 0;
  int ind = clr*3 % 18;
  redClr = clrs[ind];
  greenClr = clrs[ind+1];
  blueClr = clrs[ind+2];
}


Yes, it shouldn't be out of bounds in the array anymore.

And, the Atmega has an "AVcc" pin on it... I was following http://arduino.cc/en/Main/Standalone. When it talks about hooking up pin 20, it mentions needing a low pass filter for analog.  :smiley-roll-sweat:

Coding Badly

And, the Atmega has an "AVcc" pin on it...


Uh huh.

Quote
When it talks about hooking up pin 20, it mentions needing a low pass filter for analog.


Low pass filter on pin 20?  Are you certain?

Quote
I was following http://arduino.cc/en/Main/Standalone.


Read it again.

Plystire

Maybe I'm misinterpreting this:
Quote
Pin 20 - AVcc - Suppply voltage for the ADC converter. Needs to be connected to power if ADC isn't being used and to power via a low-pass filter if it is (a low pass filter is a circuit that reduces noise from the power source. This example isn't using one)


I wasn't entirely sure if my code required the analog to digital converter or not, so I figured I would hook it up for use just in case. :S

Coding Badly


I apologize.  It does say that.

Remove your "low-pass filter" from pin 20.  Connect pin 20 directly to power.  Exactly the same as you have VCC (pin 7) connect.

Both GND pins need to be connected to ground (pin 8 and pin 22).

You need to have a 0.1 uF capacitor connected between VCC and GND (pins 7 & 8) as close to the processor as possible.

You need to have a 0.1 uF capacitor connected between AVCC and GND (pins 20 & 22) as close to the processor as possible.

This document has more details if you are interested.

Plystire

Amazing. Making that change seems to have fixed it! I really wish I knew more about electronics to understand why that fixed it.  :~

Thanks very much!

~Plystire

Coding Badly


Even an expert may have trouble determining exactly why the resistor would cause problems.  As simple as it is, compared to a modern PC processor, an AVR processor is still a very complicated device.

You are welcome.  Glad to know you have it working.

Plystire

One of the confusing things to me is that now I see 3 different capacitors connecting between the power rail and the ground rail. What does an extra capacitor do that the other capacitors aren't doing? :~
I have lots of questions like this when it comes to electronics... being a programmer, making the shift to hardware is difficult.

Coding Badly


In a house, insulation in the walls separates the interior of the house from the outside.  The capacitors act like somewhat like house insulation; electrically separating (isolating) what is on one side from what is on the other side.  I assume the capacitors you are seeing are different sizes.  The different sizes provide isolation at different frequencies.

The 0.1 uF capacitors near the processor are a great example.  The processor is electrically fairly quiet until the system clock ticks.  At that moment there is a flurry of activity resulting in the processor drawing significantly more current ("significantly more" being several milliamps).  If the power supply and power delivery was perfect, those oscillations between quiet and flurry would not matter.  But neither is perfect.  The result is that the oscillations show up in other parts of the circuit were they could cause problems.  The 0.1 uF capacitors help to isolate the oscillations to just the part of the circuit that includes the processor.

Chagrin

There's a separate cap between AVCC and GND and VCC and GND to help keep the noise from the digital side of the chip and circuit from interfering with the analog readings that are being handled on the analog side of the chip. It's not a necessity but it's important where you require premium accuracy from your analog readings. It's rare to see it but sometimes you'll also see designers building boards where the analog GND and digital GND are kept completely separate and only connect right near the power source.


Go Up