[SOLVED] Shuffle a char array?

Example of accessing table data in PROGMEM through indexes…

/* Yet Another Modified Blink Without Delay 
 
 Turns on and off a light emitting diode(LED) connected to a digital  
 pin, without using the delay() function.  This means that other code
 can run at the same time without being interrupted by the LED code.
 
 This particular version blinks in a PROGMEM sinewave-table-driven pattern.
 
 The circuit:
 * LED attached from pin 13 to ground.
 * Note: on most Arduinos, there is already an LED on the board
 that's attached to pin 13, so no hardware is needed for this example.
 
 
 created 2005
 by David A. Mellis
 modified 8 Feb 2010
 by Paul Stoffregen
 fixed and modified more than once 2013-2014
 by GodForSmoke
 
 This example code is in the public domain.

 Here's the original, but use the Example code in your IDE under File->Examples 
 http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
 */

// constants won't change. Used here to 
// set pin numbers:
const byte ledPin =  13;      // the number of the LED pin

byte ledState = LOW;          // ledState used to set the LED
char degree = 0;              // can be negative, char range is -128 to 127
char goDirection = 1;         // degrees go 0 to 89 to 0 to 89 ...

// the follow variables is an unsigned long because the time, in miliseconds,
// returned by mills() is an unsigned long and you don't want to mix variable types.
unsigned long intervalMillis;
unsigned long previousMillis = 0;        // will store last time LED was updated

const word PROGMEM sineTbl[ 90 ] = { 
   0,    9,   17,   26,   35,   44,   52,   61,   70,   78,
  87,   95,  104,  112,  121,  129,  138,  146,  155,  163, 
 171,  179,  187,  195,  203,  211,  219,  227,  235,  242, 
 250,  258,  265,  272,  280,  287,  294,  301,  308,  315, 
 321,  328,  335,  341,  347,  354,  360,  366,  372,  377, 
 383,  389,  394,  399,  405,  410,  415,  419,  424,  429, 
 433,  437,  441,  446,  449,  453,  457,  460,  464,  467, 
 470,  473,  476,  478,  481,  483,  485,  487,  489,  491, 
 492,  494,  495,  496,  497,  498,  499,  499,  500,  500 
};

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);

  Serial.begin( 57600 );  
  
  intervalMillis = (unsigned long) pgm_read_word( sineTbl[ degree ] );    

  Serial.println( intervalMillis );
}

void loop()
{
  // check to see if it's time to blink the LED; that is, if the 
  // difference between the current time and last time you blinked 
  // the LED is bigger than the interval at which you want to 
  // blink the LED.
  unsigned long currentMillis = millis();

  if ( currentMillis - previousMillis >= intervalMillis ) 
  {
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    // if the LED is off turn it on and vice-versa:
    ledState = !ledState; // ! is logical not, opposite

      // set the LED with the ledState of the variable:
    digitalWrite( ledPin, ledState );
    
    degree += goDirection;
    if (( degree < 1 ) || ( degree > 88 ))
    {
      goDirection *= -1;
    }  
    
    intervalMillis = (unsigned long) pgm_read_word( sineTbl[ degree ] );    

    Serial.println( intervalMillis );
  }

}

Aha.

PROGMEM function (or fix) is quite counter intuitive, but I understand.

But I do not understand why to get rid of Strings? I mean, with strings you have lower chances of making a mistake. It's more easier to take care of memory. Or is it because Arduino doesn't have much RAM memory?

Yes.

Doc

Strings use more RAM (a byte or two IIRC) just for starts.

Add a char to a String and it copies itself with the new char added then deletes the old copy and does whatever heap management is needed to be able to use the deallocated space -- since that was fixed in the IDE a while ago now. Add another char and the new copy won't fit where the first one did so you get a bigger hole in the heap but good news, the next one will fit in the hole but the one after that may not if you have other dynamic allocation objects doing their 'fits on a PC' behavior.

None of that is cycle-free. What's going to happen if you are trying to use tight, fast code with Strings? If you're real careful then you can get away with it and say you did. Is that worth using the things on an MCU?

Dynamic allocation is not a bright idea in a limited RAM environment. You can do it but it is going to limit the scope of what you do. C++ has lots of classes that use automatic dynamic allocation. It is best to avoid them regardless of the convenience.

I sure don't need conveniences like that. I make what buffers I need and stick to them.