Arduino equivilent for Stamp Basic "DATA", "READ"

This started in a discussion in the NEWS section, but now that we're getting into nitty gritty details I'm trying to move it here under software/development...

In the end, I don't care about WRITE (the values won't change at run time). Most of my programs these days have to do with prop control, a LOT for Halloween, and as I'm an actor in LA and know a bunch of FX guys I help them, too. A lot of props use a simple sequencer template for the BSI that stores records like this:

EEPROM (%00000000, 0)

The first byte is what to put on the output pins, the second is how long (in timing units, usually 100 ms) to hold that state. In effect, it's a digital player piano. I'd like to duplicate this in the Ardunio -- it it's possible within the constraints of the language. What I'm really after is a named constant array that I can index through as the program runs.

A named constant array is pretty easy; the question is how much it should look like the equivalent PBASIC statements. I mean, here's ugly raw C that does it:

struct {int index; unsigned char data[];} playdata =
   {0, {
       0x81, 1,
       0x42, 1,
       0x24, 1,
       0x18, 2
   }
};

#define PLAYER_READ(pd) (pd.data[pd.index++])
#define PLAYER_RESET(pd) pd.index = 0;

void loop()
{
    unsigned char bits, time;

    PLAYER_RESET(playdata);
    bits = PLAYER_READ(playdata);
    time = PLAYER_READ(playdata);
    setport(bits);
    delay(time);
}

getting it to more exactly match the semantics of PBASIC READ (what to do after all the data is read, for instance) is harder, and hiding C ugliness (" What's "struct" do? It's not in the arduino manual!"), using EEPROM or flash to save ram space, and so on, are all ... additional effort.

(I always wanted to write an "LED blinking" language a lot like your "digital player piano." Alas, it tends to quickly suffer from feature bloat...)

[Question for the arduino experts: if I use the gcc primitives for putting data in EEPROM, does the arduino utility load the EEPROM when downloading a sketch?]

A "problem" with arduino is that it's SO different in architecture from a stamp that there are TOO MANY different ways of accomplishing the same sorts of things. A basic stamp is a brilliant example of cramming a lot of functionality into a tiny microprocessor. An Ardino isn't tiny, and one doesn't need to "cram." For instance, I can think of three different places to put the data from a DATA-like statement (RAM, FLASH, EEPROM) and two different times to put it there (download time vs runtime (in setup.)) And if the main idea is to implement a pin-driving scripting language, it's equally possible to think about doing that in an entirely different way that might have some interesting advantages (for instance, consider multiple "scripts" running simultaneously, each with a bitmask of which pins it was responsible for...)

(heh. If a "creative commons, with attribution, etc" bit of open source hardware/software makes it into a movie, does the whole Arduino community get mentioned in the credits ? Sorta like now with effects groups "janitor for Snazzy Titles Inc: John Doe." It'd be "Obnoxious but helpful comments in Arduino Forums: WestfW" - Maybe you're better off sticking with commercial products!)

The problem I see is that Arduino is embedding a language that wasn't designed to be embedded; not that BASIC was, but when Parallax created the Basic Stamp they looked at the issues with embedded control and tweaked PBASIC to solve those problems; that seems to have happened only minimally with the Arduino.

Still, I continue to try to learn the language on its on merits and make it work for the kinds of projects that me and my customers are interested in.

Thanks for the assist.

I dunno; the original PDP11s that C was developed for weren't a whole lot more powerful (or even bigger, memory wise) than an AVR. (scary thought, that.) (they were rather exclusively RAM-based, though.)

A lot of props use a simple sequencer template for the BSI that stores records like this:

EEPROM (%00000000, 0)

The first byte is what to put on the output pins, the second is how long (in timing units, usually 100 ms) to hold that state.

I may be missing something, but this looks like the equivalent of PORTB=x; delay(y); where x and y are appropriate constants. If we throw in a function (or #define) to map arduino pin assignments to hardware pins across all three ports/20 Arduino pins, we get a loop() function that looks like

setoutputs(0x1234); delay(100);
setoutputs(0x5678); delay(200);
setoutputs(0x9abc); delay(100);
...

Which results in code a [u]lot[/u] cleaner than DATA/READ. It also uses program/flash memory and RAM instead of EEPROM, which is larger and bypasses all the questions of how to get the data into and out of EEPROM.

This is assuming the program's sole purpose is to toggle pins at the right time, and doesn't have any real processing to do otherwise.

-j

That's a good point. The "DATA" based "player piano" structure is largely a consequence of limited program space on things like the BS1 (a whopping 256 bytes!). With a full 14k of program space, you could easily just put all the commands into program space, and a little macro magic would let you do things like:

PINON(1, 2);   /* turn on pin 1 for 20ms */
PINOFF(1, 0); /* turn off pin 1 */
PINON(2, 2);  /* and turn pin 2 on for 20ms */
PINOFF(2,0);
SERIAL("S12P100\r");  /* send some command to a serial device */
SERVO(1, 100);  /* Use the servo library */
DTICKS(2);  /* wait 20ms */

There is another issue for me. I have GUI that I use now to create a template program for the BASIC Stamp (1 and 2) that allows an non-programmer to "paint" a sequence output. The "engine" for the sequencer has options like starting audio, waiting on an input (at a specicif level, etc.) and this core simply wants to read from a table -- again, VERY easy with the BASIC Stamp that uses a language specifically designed for embedded control. I was hoping to translate the "engine" to the Arduino and create tables as I do now with the Stamp versions of the sequencer.

If it can't be done cleanly (my version of "cleanly" may differ from yours), I'll give up and use the Arduino for other projects. I only picked up the Arduino because several of my customers (I'm a partner in EFX-TEK) asked about connecting to our serial peripherals.

If I understand correctly, this program generates some tables that you (using some other app?) translate to BASIC for the stamp?

If so, it shouldn't be too difficult to translate from this intermediate table to some C code for the Arduino.

Are these home-grown apps, or what? It sounds sufficiently interesting that I'd like to take a peek.

-j

The details are that we use Vixen (www.vixenlights.com) as a GUI for creating a sequence of digital outputs that can be sync'd with audio (Vixen makes this part easy). A custom add-in for Vixen translates the Vixen data to a PBASIC program; that add-in can even launch the BASIC Stamp IDE so the program can be downloaded.

"Under the hood" are a couple of template files that I created with HTML-like tags that the Vixen add-in replaces with user data. Our customers how haven't learned how to program yet have absolutely loved this, especially in the Halloween industry where we have the most presence with our products.

You can read about this stuff here: -- http://www.efx-tek.com/php/smf/index.php?topic=140.0

I'm working on an advanced version of this setup for our Prop-SX controller; it will contain a custom program that will allow the user to PWM any of the lower eight outputs (P0 - P7) and run servos on P8 - P11 (P12 - P15) are reserved for inputs and serial coms with other devices. The Prop-SX has an onboard 32K EEPROM that will hold the advanced sequence data. While I've only got a couple weeks of experience with the Arduino I was kind of hoping to do something similar with it -- but as I often counsel my customers: it's best to start simple, so that's what's I'm doing. I can program circles around the BASIC Stamp and SX, but I'm still getting comfortable with the Arduino.

OK, so no way to take a quick look without a windows machine. :( I was half-hoping for a text formatted intermediate file I could poke at with a perl script.

Do you control the stamp with Vixen via an attached PC, or do you configure the stamp up front then run untethered? I suspect the latter, but Vixen seems to be geared toward the former.

I suspect you could generate C with about the same amount of effort it took you to generate BASIC. It would seem worth the effort, since the arduino hardware is 1/3 the price of the stamp, and much more capable to boot.

-j

For that particular project we use the controller stand-alone, though we do have a bit of firmware that lets the Stamp run as a slave from Vixen. Note that we're not running generic Stamps, either, they're purpose-built controller boards for the prop industry (Prop-1 and Prop-2). Nothing fancy or exotic, mind you, but pretty convenient that for those that build props for Halloween, Christmas, museums, amusement parks, etc. And, unlike other companies in our category, our customers get me -- that means I'll write custom code for them if they just give me the specifics; this is particularly appreciated in the Halloween industry, though a MAJOR amusement park (they won't let me use their name) is also on the bandwagon theses day because they couldn't get 1/10th the service from a company who charges 5x for similar products.

The Arduino, as is, is no more convenient for prop builders -- from an electrical and mechanical standpoint -- than the generic BASIC Stamp. Capability is really not the issue here as many of our customers want a straight digital sequencer; this is why the Vixen project has been a huge success with the Prop-1 (BS1 core). At $35 (qty 1) it does essentially the same thing as a $150 sequencer from a well-known Hollywood controls company -- and the Prop-1 comes with customer service.

If I get comfortable enough with the Arduino I may build a prototype using the Arduino processor that has the same form-factor as our Prop-2 and Prop-SX controllers. This will give us a prop controller board with analog inputs (handy in some cases).

Here's the output created by Vixen for a Prop-2 with the data table trimmed down. Real easy. Real reliable in the ugly [electrical] environments of a professional haunted house (where a good percentage of our products end up).

IsActive CON 1 IsNotActive CON 0

IsOn CON 1 IsOff CON 0

EventDelay CON 25

' -----[ Variables ]-------------------------------------------------------

showBits VAR Word ' output + control bits endOfShow VAR showBits.BIT15 ' 1 = stop when timer done

record VAR Word ' current sequence record tix VAR Byte ' timing for record

' -----[ Initialization ]--------------------------------------------------

Reset: OUTS = $0000 ' clear pins DIRS = $3FFF ' P0..P13 are outputs

Audio_Reset: ' no audio device selected

' -----[ Program Code ]----------------------------------------------------

Main: record = 0 ' point to start of show IF (Trigger = IsNotActive) THEN Main ' wait for trigger

Start_Audio: ' no audio device selected

Play_Show: READ (record * 3), Word showBits, tix ' get outputs & timing OUTS = showBits & $3FFF ' update outputs

Timer: IF tix = 0 THEN Next_Step ' timer expired? PAUSE EventDelay ' no, time one "tic" tix = tix - 1 ' decrement timer GOTO Timer ' check again

Next_Step: IF (endOfShow = IsOn) THEN Reset ' done? record = record + 1 ' no, point to next GOTO Play_Show ' and keep going

' -----[ Subroutines ]-----------------------------------------------------

' -----[ EEPROM Data ]-----------------------------------------------------

Show_Data: ' +-------------------- end of show bit ' | ' | +------------------ OUT14 ' | | ' | | +----- OUT0 ' | | | ' | | | +-- timing multiplier (1 to 255) ' | | | | DATA Word %0000000000000001, 4 DATA Word %0011100101100100, 4 DATA Word %0010101010110001, 4 DATA Word %0001000010110111, 4 DATA Word %0000001011110011, 4 DATA Word %0010101000110110, 4 DATA Word %0001100101101001, 4 DATA Word %0010010001111001, 4 DATA Word %0001111000001110, 4 DATA Word %0011010111000001, 4 DATA Word %1000000000000000, 80

So would it make sense to just do a vixen add-in (or whatever) that generated arduino code?

You should be able to make an equivalent program for Arduino pretty easily. The only thing that's not so easy is setting all the outputs at once (there's no equivalent of the OUTS command).

BTW, can you say a bit more about what you mean when you say that Arduino as a language isn't designed for embedded systems? C was designed to be a language for running on fairly low powered hardware, with fairly easy access to its low-level systems. Naively, it seems more suited to embedded systems than Basic. Are there specific features or functions you'd like to see added to Arduino?

I agree that a vixen Add-In could be created to generate native Arduino code; I was hoping to keep things architecturally consistent with my other programs (that helps the guy who writes the Vixen drivers/add-ins for me) -- but I don't have to do that and may give up on that desire. By the way, OUTS is a PBASIC alias for the output ports (that map to RB and RC on the PIC/SX) -- I understand that for outputs wider than eight bits this would take two instructions.

I'd love to see direct bit-level access of any variable in the Arduino, something I consider very important to the embedded program that isn't part of standard C (so far as I can tell, anyway, and -- as ever -- I reserve the right to be wrong). Not part of standard BASIC either, I understand, but specialty BASIC derivatives like PBASIC and SX/B (a product I help create, so I have some biases) do include this. Yes, I understand that these to lines of code are functionally equivalent:

xByte = xByte | 0x80 xByte.7 = 1

The issue is that on most (not all) processors, the second line will generate less assembly code -- something I consider VERY important. Again, I started programming with small microcontrollers so [the maniacal] conservation of resources is just part of my make-up.