Pages: [1]   Go Down
Author Topic: suggestions for programming structure and storing of animatronic sequences  (Read 749 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm working on some animatronics for an art installation which will use several stepper motors and some high-power LEDs. In the past when I have done this sort of thing I have used a tethered computer to handle the logic and timing. For this project I would like to try making it self-contained (e.g. just the Arduino board). For Arduino hardware, I have an Arduino Mega and could expand it with an SD card shield for more storage, if need be.

I'd really welcome any ideas or suggestions on how to approach this (and am not asking for code).

For the data, essentially I would be storing cues for each stepper and each LED. And of course I would need some kind of clock or timestamp to keep track of things.

A stepper cue would be something like:

 - cue start time
 - stepper ID
 - stepper direction
 - stepper speed
 - number of steps

An LED cue would be something like:

 - cue start time
 - LED ID
 - Start brightness
 - End brightness
 - duration

So what I am wondering about:

 - ideas about a data format compact enough to store lots of cues
 - any suggestions for a clock or timestamp. (A simple counter is the obvious choice)

As for just how many cues/how much data, since I am just beginning this, I will work within whatever limits I bump up against.
Logged

Massachusetts, USA
Offline Offline
Tesla Member
***
Karma: 212
Posts: 8967
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Assuming that your cues are compile-time constants you will have much more room to work with if you keep the cues in FLASH (PROGMEM) than if you use RAM.  The ATmega328 has 32k of FLASH but only 2k of SRAM.

Figure out what units of measure you want to use and the ranges of values.  Then you can minimize the data sizes. Remember that if you usuall need less than 255 steps you can use one byte for the number of steps and chain two motions together to get one longer motion.

Logged

Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12630
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I guess that your animation sequence is likely to evolve rapidly and continually but your basic mechanism for reading and executing instructions is not. On that basis I would be inclined to go for a text file on the SD card that can be shoved into a PC and reprogrammed quickly and easily in the field without having to build and upload new software. (This also gives you an obvious way to archive your animation sequences and switch between them easily etc.)

For the text file format, the simplest format would be ASCII CSV with each record containing the sort of info you listed.

It seems unlikely that the number of cues or rate of executing cues is going to be big enough to be an issue, but if it is then figuring out how to generate those cues is going to be a far more important problem.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

the land of sun+snow
Offline Offline
Faraday Member
**
Karma: 159
Posts: 2916
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've done this sort of thing, for robotic walkers. You definitely want storage that is
easily rewritable without having to reprogram the Arduino, eg, SD card or EEPROM
chip such as 24LC256.

Then, possibly use the PC to write the sequences to the storage device, as mentioned,
or else write a little command interpreter for the Arduino, so you can insert data into
the storage devices using the Arduino terminal emulator. The latter works well, because
you can make changes and immediately test them.
Logged

0
Offline Offline
Sr. Member
****
Karma: 0
Posts: 296
Got Karma?
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So for now I have decided to roll my own simple data format in order to keep the project moving (on another forum, someone had suggested using MIDI as a data format).. I was also concerned about storing cue data in a way that doesn't eat up RAM.

Since I am using an Ardunio Mega with 128 KB of Flash memory I want to use that before resorting to an SD card. With the excellent Flash Library (http://arduiniana.org/libraries/flash/) accessing PROGMEM is very easy and I was able to rough out a test sketch in minutes.

For motor control I am using dedicated motor controller boards using serial comm. Each board controls two motors. For testing, the maximum data size I needed to send was four values: *rate, slope, x target, y target* in order to make a move so that determines my data format for motors.  This will change when I add a timestamp and board ID values.

With the Flash lib, you can define a FLASH_TABLE, store it in PROGMEM and then access it using simple array bracket access. Testing with a couple of thousand entries shows no issues.

So it becomes a simple task of pulling data out and sending it to the standalone boards or using it internally for my LEDs.

Code:
// simple example:

    #include <Flash.h>
    
    FLASH_TABLE(int, command_table, 4 /* width of table */,
        {111, 222, 333, 444},
        {1001, 900, 3210, -4567},
        {1002, 1000, 3210, -4567},
        {1003, 1100, 3210, -4567},
        {666, 777, 888, 999}
        );
        
    void setup() {
        Serial.begin(9600);
        Serial.print("Mem: "); Serial.println(availableMemory());
    
        // Determine the size of the array
        Serial.print("Rows: "); Serial.println(command_table.rows());
        Serial.print("Cols: "); Serial.println(command_table.cols());
        Serial.print("RAM: "); Serial.println(sizeof(command_table));
    
         Serial.print(command_table[8][0]);
         Serial.print("s");
         Serial.print(command_table[8][1]);
         Serial.print("r");
         Serial.print(command_table[8][2]);
         Serial.print("x");
         Serial.print(command_table[8][3]);
         Serial.print("y");
         Serial.println("gi");  
    }
    
    void loop() {
    
    
    }
    
    int availableMemory()
    {
      int size = 1024;
      byte *buf;
      while ((buf = (byte *) malloc(--size)) == NULL);
      free(buf);
      return size;
    }

« Last Edit: September 20, 2012, 10:00:47 am by roypardi » Logged

Pages: [1]   Go Up
Jump to: