running out of ram?

Here’s briefly what i’m trying to do! What i’m making is an LFO(low frequency oscillator) so I have a few waveforms (sine, ramp etc.) stored in arrays. There are two pots, one controls the tempo, the other is used as the waveform selector (the pot is divided into 4 quadrants each one corresponding to a particular waveform). Then i use analogWrite to attach an LED to the output.

So the problem is it’s running fine apart from the last waveform, it goes all jittery for no reason. It’s the exact same code as the other waveforms so I know that’s not the problem. Using a free ram function it returned 1830? And i’m using a 328 which has 2k … so have I run out?

I already figured out I have to store my arrays in program memory, and have done?(hopefully) But I still seem to be running out of ram. Have I somehow done something wrong with putting the arrays in program memory? Or is my code just over-consuming ram somehow?

#include <avr/pgmspace.h>                 //needed to write arrays to program memory.
void setup() {
  TCCR1B = TCCR1B & 0b11111000 | 0x01;    //set PWM really really fast.
  pinMode(2, OUTPUT);
  Serial.begin(57600);
}

const byte rampTable[] PROGMEM = {0, 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, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, \
230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, \
244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};

const byte logrampTable[] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4,
...........................................................................blah blah blah 3 more tables as above.


  int pot1=0;                    //waveSelect Potentiometer
  int const ledPin = 9;     //LED output
  int waveSelect = 0;      //which waveform is selected?
  int delayT = 0;             //delay time, us
  
void loop() {
  
  pot1 = analogRead(5);                    
  waveSelect = map(pot1, 0, 1023, 0, 3);    //see what waveform is selected.
  
  int x=0;                                  //counter
  
  while (waveSelect ==0)                    //wave= RAMP
   {
     x++;                                   //increment x counter
      int ramp = pgm_read_byte(&rampTable[x]);         //read table from program memory
     analogWrite(9, ramp);                            //PWM the read value

     delayT=map(analogRead(4), 0, 1023, 128, 16384);  //maps delay time to useful values
     delayMicroseconds(delayT); 

     pot1 = analogRead(5);                          //check if the waveform select has been changed?
    waveSelect = map(pot1, 0, 1023, 0, 3);

      if (x==255)                          //reset counter to repeat 255 samples for each waveform.
       {
           x=0;
         }
       
     }
     
     while (waveSelect ==1)                    //code repeats for different waveforms. see above.
   {
     x++;
       if (x==256)
         {
           x=0;
         }
     int logramp = pgm_read_byte(&logrampTable[x]); 
     analogWrite(9, logramp);
     delayT=map(analogRead(4), 0, 1023, 128, 16384);
     delayMicroseconds(delayT);
     pot1 = analogRead(5);
     waveSelect = map(pot1, 0, 1023, 0, 3);
   
     }
  
    while (waveSelect == 2)
    .................
    same repeated as above twice for a total of 4 different waveforms.

    }
}

There is no need for a lookup table for your ramp function, its just f(x)=x...

True, but I also have sine etc and would like to be able to use 4 or more from a table. I’m only using 4k program memory, but still running out of ram. I should be able to do this, but not sure why i’m running out of ram…

here’s the complete code if anyone can see anything wrong…

#include <avr/pgmspace.h> 

void setup() {
  // put your setup code here, to run once:
  TCCR1B = TCCR1B & 0b11111000 | 0x01;
  pinMode(2, OUTPUT);
  Serial.begin(57600);
}

const byte rampTable[] PROGMEM = {0, 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, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, \
230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, \
244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};

const byte logrampTable[] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, \
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, \
5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 9, \
9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, \
13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 17, 18, 18, 19, \
19, 19, 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27, \
27, 28, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 35, 36, 37, 38, \
38, 39, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, \
54, 55, 56, 58, 59, 60, 61, 62, 64, 65, 66, 68, 69, 70, 72, 73, 75, \
76, 78, 79, 81, 83, 84, 86, 88, 89, 91, 93, 95, 97, 99, 101, 103, \
105, 107, 109, 111, 114, 116, 118, 120, 123, 125, 128, 130, 133, 136, \
138, 141, 144, 147, 150, 153, 156, 159, 162, 165, 169, 172, 175, 179, \
182, 186, 190, 194, 197, 201, 205, 209, 214, 218, 222, 227, 231, 236,
  240, 245, 250, 255};
  
const byte sineTable[] PROGMEM = {128, 131, 134, 137, 141, 144, 147, 150, 153, 156, 159, 162, 165, \
168, 171, 174, 177, 180, 183, 186, 188, 191, 194, 196, 199, 202, 204, \
207, 209, 212, 214, 216, 219, 221, 223, 225, 227, 229, 231, 233, 234, \
236, 238, 239, 241, 242, 244, 245, 246, 247, 249, 250, 250, 251, 252, \
253, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
255, 255, 254, 254, 253, 252, 251, 250, 250, 249, 247, 246, 245, 244, \
242, 241, 239, 238, 236, 234, 233, 231, 229, 227, 225, 223, 221, 219, \
216, 214, 212, 209, 207, 204, 202, 199, 196, 194, 191, 188, 186, 183, \
180, 177, 174, 171, 168, 165, 162, 159, 156, 153, 150, 147, 144, 141, \
137, 134, 131, 128, 125, 122, 119, 115, 112, 109, 106, 103, 100, 97, \
94, 91, 88, 85, 82, 79, 76, 73, 70, 68, 65, 62, 60, 57, 54, 52, 49, \
47, 44, 42, 40, 37, 35, 33, 31, 29, 27, 25, 23, 22, 20, 18, 17, 15, \
14, 12, 11, 10, 9, 7, 6, 6, 5, 4, 3, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, \
0, 1, 1, 1, 2, 2, 3, 4, 5, 6, 6, 7, 9, 10, 11, 12, 14, 15, 17, 18, \
20, 22, 23, 25, 27, 29, 31, 33, 35, 37, 40, 42, 44, 47, 49, 52, 54, \
57, 60, 62, 65, 68, 70, 73, 76, 79, 82, 85, 88, 91, 94, 97, 100, 103, \
106, 109, 112, 115, 119, 122, 125, 128};

const byte logsineTable[] PROGMEM ={255, 220, 185, 165, 151, 140, 130, 123, 116, 110, 105, 100, 96, 92, \
88, 85, 82, 79, 76, 73, 71, 68, 66, 64, 62, 60, 58, 56, 54, 53, 51, \
50, 48, 47, 45, 44, 42, 41, 40, 39, 38, 36, 35, 34, 33, 32, 31, 30, \
29, 28, 28, 27, 26, 25, 24, 24, 23, 22, 21, 21, 20, 19, 19, 18, 17, \
17, 16, 16, 15, 14, 14, 13, 13, 12, 12, 11, 11, 11, 10, 10, 9, 9, 8, \
8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, \
2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, \
2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, \
9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 16, 17, 17, \
18, 19, 19, 20, 21, 21, 22, 23, 24, 24, 25, 26, 27, 28, 28, 29, 30, \
31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 44, 45, 47, 48, 50, 51, \
53, 54, 56, 58, 60, 62, 64, 66, 68, 71, 73, 76, 79, 82, 85, 88, 92, \
96, 100, 105, 110, 116, 123, 130, 140, 151, 165, 185, 220, 255};

  int pot1=0;
  int ledPin = 9;
  int waveSelect = 0;
  int delayT = 0;
  
void loop() {
  
  pot1 = analogRead(5);
  waveSelect = map(pot1, 0, 1023, 0, 3);
  
  int x=0;
  while (waveSelect ==0)
   {
     x++;
       if (x==256)
         {
           x=0;
         }
     int ramp = pgm_read_byte(&rampTable[x]); 
     analogWrite(9, ramp);
     delayT=map(analogRead(4), 0, 1023, 128, 16384);
     delayMicroseconds(delayT);
       pot1 = analogRead(5);
  waveSelect = map(pot1, 0, 1023, 0, 3);
      Serial.print(memoryFree()); // print the free memory
      Serial.print(' '); // print a space
      delay(1000);

       
     }
     
     while (waveSelect ==1)
   {
     x++;
       if (x==256)
         {
           x=0;
         }
     int logramp = pgm_read_byte(&logrampTable[x]); 
     analogWrite(9, logramp);
     delayT=map(analogRead(4), 0, 1023, 128, 16384);
     delayMicroseconds(delayT);
     pot1 = analogRead(5);
     waveSelect = map(pot1, 0, 1023, 0, 3);
   
     }
  
    while (waveSelect == 2)
    
   {
     x++;
       if (x==256)
         {
           x=0;
           waveSelect=5;
         }
     int sine = pgm_read_byte(&sineTable[x]); 
     analogWrite(9, sine);
     delayT=map(analogRead(4), 0, 1023, 128, 16384);
     delayMicroseconds(delayT);
     
      pot1 = analogRead(5);
      waveSelect = map(pot1, 0, 1023, 0, 3);
      

      
    }
    
    while (waveSelect == 3)
    
   {
     x++;
       if (x==256)
         {
           x=0;
           waveSelect=5;
         }
     int logsine = pgm_read_byte(&logsineTable[x]); 
     analogWrite(9, logsine);
     delayT=map(analogRead(4), 0, 1023, 128, 16384);
     delayMicroseconds(delayT);
     
      pot1 = analogRead(5);
      waveSelect = map(pot1, 0, 1023, 0, 3);
 
    }
    
    while (waveSelect == 5)
    {
     analogWrite(9, 255);
    }
     
}

a faster sin() is here - http://arduino.cc/forum/index.php?topic=69723.0 -

and as cos(x) = sin(x+90) that one is solved too tan(x) = sin(x) / cos(x) ; but requires two look ups this way

In general all functions can be done in a similar way, just use enough points in the lookuptable and interpolate between them.

See also the approximation of functions with multimap() - http://arduino.cc/playground/Main/MultiMap -

It's hard to check whether you have exactly 256 elements in each of the tables. I suggest you remove the trailing \ characters in them (they are not necessary), and put the same number of values on each line, split into blocks and lined up. For example, 16 lines each containing 2 blocks of 8 values. Also declare them as:

const byte ramptable[256] PROGMEM = { ... }

so that the compiler will warn if you provide more than 256 entries, and pad out with zeros if you provide fewer than 256.

I can't see any reason why you should be running out of RAM, and if the free ram function says you have 1830 bytes free, that confirms it is OK.

When you say it goes jittery, what exactly do you mean?

robtillaart: a faster sin() is here - http://arduino.cc/forum/index.php?topic=69723.0 -

and as cos(x) = sin(x+90) that one is solved too tan(x) = sin(x) / cos(x) ; but requires two look ups this way

In general all functions can be done in a similar way, just use enough points in the lookuptable and interpolate between them.

See also the approximation of functions with multimap() - http://arduino.cc/playground/Main/MultiMap -

Okay that could help, but I would like to be able to use my own waveforms that I can make in mathematica. I don't want to use standard sine, ramps etc. I just really need to adjust them myself. I'm going to try re-writing a bit better and see if that helps..

dc42: It's hard to check whether you have exactly 256 elements in each of the tables. I suggest you remove the trailing \ characters in them (they are not necessary), and put the same number of values on each line, split into blocks and lined up. For example, 16 lines each containing 2 blocks of 8 values. Also declare them as:

const byte ramptable[256] PROGMEM = { ... }

so that the compiler will warn if you provide more than 256 entries, and pad out with zeros if you provide fewer than 256.

I can't see any reason why you should be running out of RAM, and if the free ram function says you have 1830 bytes free, that confirms it is OK.

When you say it goes jittery, what exactly do you mean?

Ohhhhh right ... it returns how much free ram you have XD, I thought it returned how much ram you had used for some reason lol.

By jittery I mean, it's sort of random, jumping all over the place. I used serial com,to see what was happening and where I have the x counter it would count up to about ~50(this number wan't the same every time) then reset. I'll do some more messing around with this, I guess it's not a ram problem afterall? Thanks for the help!

This may be a problem:

       if (x==256)

Safer is:

       if (x>=256)

Also, you could probably fold those while loops into a switch to read and act on your pots, followed by common code to generate the wave form in loop, without the need for additional loop constructs. Might make it easier to find your bug.

wildbill: This may be a problem:

       if (x==256)

Safer is:

       if (x>=256)

Also, you could probably fold those while loops into a switch to read and act on your pots, followed by common code to generate the wave form in loop, without the need for additional loop constructs. Might make it easier to find your bug.

Yip true, my codes a bit of a mess, if x gets to 257 i'm screwed haha. But I think I found the problems, and after all it's my crappy breadboard it turns out. Seems one of the wires didn't make a good connection/ or I need some more capacitance on the input. So it just kept slipping on and off the other waveform and so reseting x randomly. Got it working pretty well now. Thanks for all the help everyone.